~ubuntu-branches/ubuntu/natty/bluedevil/natty

« back to all changes in this revision

Viewing changes to src/kio/obexftp/kio_obexftp.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2010-09-16 14:53:24 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100916145324-0gj8ss49ja9wgt4j
Tags: 1.0~rc4-0ubuntu1
* New upstream release
  - Build against libbluedevil-dev 1.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 ***************************************************************************/
22
22
 
23
23
#include "kio_obexftp.h"
24
 
#include "obexftpmanager.h"
25
 
#include "obexftpsession.h"
 
24
#include "kdedobexftp.h"
26
25
 
27
26
#include <KDebug>
28
27
#include <KComponentData>
29
28
#include <KCmdLineArgs>
30
29
#include <KAboutData>
31
30
#include <KLocale>
 
31
#include <KTemporaryFile>
 
32
#include <KMimeType>
32
33
#include <KApplication>
33
34
 
34
 
#define ENSURE_SESSION_CREATED(url) if (!m_session) {       \
35
 
                                        if  (!createSession(url)) { \
36
 
                                            return;\
37
 
                                        }\
38
 
                                    }
39
 
 
40
35
extern "C" int KDE_EXPORT kdemain(int argc, char **argv)
41
36
{
42
37
    KAboutData about("kioobexftp","kioobexftp", ki18n("kioobexftp"), 0);
55
50
}
56
51
 
57
52
KioFtp::KioFtp(const QByteArray &pool, const QByteArray &app)
58
 
    : SlaveBase("obexftp", pool, app), m_manager(0), m_session(0)
 
53
    : SlaveBase("obexftp", pool, app)
59
54
{
 
55
    m_settingHost = false;
 
56
 
60
57
    m_timer = new QTimer();
61
58
    m_timer->setInterval(100);
62
 
    connect(m_timer, SIGNAL(timeout()), this, SLOT(updateProcess()));
 
59
 
 
60
    m_kded = new org::kde::ObexFtp("org.kde.kded", "/modules/obexftpdaemon", QDBusConnection::sessionBus(), 0);
 
61
    connect(m_kded, SIGNAL(sessionConnected(QString)), SLOT(sessionConnected(QString)));
63
62
}
64
63
 
65
64
KioFtp::~KioFtp()
66
65
{
67
 
    m_session->Disconnect().waitForFinished();
68
 
    m_session->Close().waitForFinished();
69
 
    delete m_manager;
70
 
    delete m_session;
71
 
}
72
 
 
73
 
bool KioFtp::createSession(const KUrl &address)
74
 
{
75
 
    if (address.host().isEmpty()) {
76
 
        kDebug() << "No host";
77
 
        error (KIO::ERR_UNKNOWN_HOST, address.prettyUrl());
78
 
        return false;
79
 
    }
80
 
 
81
 
    infoMessage(i18n("Connecting to the remote device..."));
82
 
 
83
 
    launchProgressBar();
84
 
    m_address = address.host();
85
 
    kDebug() << "Got address: " << m_address;
86
 
 
87
 
    m_manager = new org::openobex::Manager("org.openobex", "/org/openobex", QDBusConnection::sessionBus(), 0);
88
 
    connect(m_manager, SIGNAL(SessionConnected(QDBusObjectPath)), this, SLOT(sessionCreated(QDBusObjectPath)));
89
 
 
90
 
    kDebug() << "Creaing the bluetooth session: ";
91
 
    QDBusPendingReply <QDBusObjectPath > rep = m_manager->CreateBluetoothSession(QString(m_address).replace("-", ":"), "00:00:00:00:00:00", "ftp");
92
 
 
93
 
    m_eventLoop.exec();
94
 
 
95
 
    kDebug() << "SessionError: " << rep.error().message();
96
 
    kDebug() << "SessionPath: " << rep.value().path();
97
 
 
98
 
    const QString sessioPath = rep.value().path();
99
 
    m_session = new org::openobex::Session("org.openobex", sessioPath, QDBusConnection::sessionBus(), 0);
100
 
 
101
 
    kDebug() << "Create session ends";
102
 
    return true;
103
 
}
104
 
 
105
 
void KioFtp::changeDirectory(const KUrl& url)
106
 
{
107
 
    kDebug() << "ChangeUrl: " << url.path();
108
 
    QStringList list = url.path().split("/");
109
 
 
110
 
    kDebug() << "List of itens: " << list;
111
 
 
112
 
    m_session->ChangeCurrentFolderToRoot().waitForFinished();
113
 
    kDebug() << "We're in root now";
114
 
 
115
 
    Q_FOREACH(const QString &dir, list) {
116
 
        if (!dir.isEmpty() && dir != m_address) {
117
 
            kDebug() << "Changing to: " << dir;
118
 
            QDBusPendingReply <void > a = m_session->ChangeCurrentFolder(dir);
119
 
            a.waitForFinished();
120
 
            kDebug()  << "Change Error: " << a.error().message();
121
 
        } else {
122
 
            kDebug() << "Skyping" << dir;
123
 
        }
124
 
    }
 
66
    delete m_kded;
125
67
}
126
68
 
127
69
void KioFtp::launchProgressBar()
128
70
{
 
71
    connect(m_timer, SIGNAL(timeout()), this, SLOT(updateProcess()));
129
72
    totalSize(50);
130
73
    m_counter = 0;
131
74
    m_timer->start();
134
77
void KioFtp::updateProcess()
135
78
{
136
79
    if (m_counter == 49) {
 
80
        disconnect(m_timer, SIGNAL(timeout()), this, SLOT(updateProcess()));
137
81
        m_timer->stop();
138
82
        return;
139
83
    }
 
84
 
140
85
    processedSize(m_counter);
141
86
    m_counter++;
142
87
}
145
90
void KioFtp::listDir(const KUrl &url)
146
91
{
147
92
    kDebug() << "listdir: " << url;
148
 
    ENSURE_SESSION_CREATED(url)
149
93
 
150
94
    infoMessage(i18n("Retrieving information from remote device..."));
151
95
 
152
 
    if (url.fileName() != "/" && !url.fileName().isEmpty()) {
153
 
        changeDirectory(url);
154
 
    }
155
 
 
156
 
    QDBusPendingReply<QString> folder = m_session->RetrieveFolderListing();
 
96
    blockUntilNotBusy(url.host());
 
97
    QDBusPendingReply<QString> folder = m_kded->listDir(url.host(), url.path());
157
98
    folder.waitForFinished();
158
99
 
159
100
    kDebug() << folder.value();
170
111
    Q_UNUSED(flags)
171
112
 
172
113
    kDebug() << "copy: " << src.url() << " to " << dest.url();
173
 
    connect(m_session, SIGNAL(TransferProgress(qulonglong)), this, SLOT(TransferProgress(qulonglong)));
174
 
    connect(m_session, SIGNAL(TransferCompleted()), this, SLOT(TransferCompleted()));
175
 
    connect(m_session, SIGNAL(ErrorOccurred(QString,QString)), this, SLOT(ErrorOccurred(QString,QString)));
176
 
 
177
 
    if (src.scheme() == "obexftp") {
178
 
        if (m_statMap.contains(src.prettyUrl())) {
179
 
            if (m_statMap.value(src.prettyUrl()).isDir()) {
180
 
                kDebug() << "Skipping to copy: " << src.prettyUrl();
181
 
                error( KIO::ERR_IS_DIRECTORY, src.prettyUrl());
182
 
                disconnect(m_session, SIGNAL(TransferProgress(qulonglong)), this, SLOT(TransferProgress(qulonglong)));
183
 
                disconnect(m_session, SIGNAL(TransferCompleted()), this, SLOT(TransferCompleted()));
184
 
                disconnect(m_session, SIGNAL(ErrorOccurred(QString,QString)), this, SLOT(ErrorOccurred(QString,QString)));
185
 
                return;
186
 
            }
187
 
        }
188
 
        ENSURE_SESSION_CREATED(src)
189
 
        changeDirectory(src.directory());
190
 
        kDebug() << "CopyingRemoteFile....";
191
 
        m_session->CopyRemoteFile(src.fileName(), dest.path());
192
 
        kDebug() << "Copied";
193
 
    } else if (dest.scheme() == "obexftp") {
194
 
        ENSURE_SESSION_CREATED(dest)
195
 
        changeDirectory(dest.directory());
196
 
        kDebug() << "Sendingfile....";
197
 
        m_session->SendFile(src.path());
198
 
        kDebug() << "Copied";
199
 
    }
200
 
 
201
 
    m_eventLoop.exec();
 
114
 
 
115
    copyHelper(src, dest);
202
116
 
203
117
    finished();
204
118
}
213
127
    finished();
214
128
}
215
129
 
 
130
void KioFtp::get(const KUrl& url)
 
131
{
 
132
    KTemporaryFile tempFile;
 
133
    tempFile.setSuffix(url.fileName());
 
134
    tempFile.open();//Create the file
 
135
    kDebug() << tempFile.fileName();
 
136
 
 
137
    copyHelper(url, KUrl(tempFile.fileName()));
 
138
 
 
139
    kDebug() << "Getting mimetype";
 
140
    KMimeType::Ptr mime = KMimeType::findByPath(tempFile.fileName());
 
141
    mimeType(mime->name());
 
142
    kDebug() << "Mime: " << mime->name();
 
143
 
 
144
    kDebug() << tempFile.size();
 
145
    totalSize(tempFile.size());
 
146
 
 
147
    data(tempFile.readAll());
 
148
 
 
149
    finished();
 
150
}
 
151
 
216
152
 
217
153
void KioFtp::setHost(const QString &host, quint16 port, const QString &user, const QString &pass)
218
154
{
221
157
    Q_UNUSED(pass)
222
158
 
223
159
    kDebug() << "setHost: " << host;
 
160
 
 
161
    m_kded->stablishConnection(host);
 
162
    kDebug() << "Waiting to stablish the connection";
 
163
    m_settingHost = true;
 
164
    launchProgressBar();
 
165
    m_eventLoop.exec();
 
166
 
 
167
    m_settingHost = false;
 
168
    m_address = host;
224
169
    m_statMap.clear();
225
170
}
226
171
 
229
174
    Q_UNUSED(isfile)
230
175
 
231
176
    kDebug() << "Del: " << url.url();
232
 
    ENSURE_SESSION_CREATED(url)
233
 
    changeDirectory(url.directory());
234
 
    m_session->DeleteRemoteFile(url.fileName()).waitForFinished();
 
177
    blockUntilNotBusy(url.host());
 
178
    m_kded->deleteRemoteFile(url.host(),  url.path()).waitForFinished();
235
179
    finished();
236
180
}
237
181
 
240
184
    Q_UNUSED(permissions)
241
185
 
242
186
    kDebug() << "MkDir: " << url.url();
243
 
    ENSURE_SESSION_CREATED(url)
244
 
    changeDirectory(url.directory());
245
 
    m_session->CreateFolder(url.fileName()).waitForFinished();
 
187
    blockUntilNotBusy(url.host());
 
188
    m_kded->createFolder(url.host(), url.path()).waitForFinished();
246
189
    finished();
247
190
}
248
191
 
249
 
void KioFtp::slave_status()
250
 
{
251
 
    kDebug() << "Slave status";
252
 
    KIO::SlaveBase::slave_status();
253
 
}
254
 
 
255
192
void KioFtp::stat(const KUrl &url)
256
193
{
257
194
    kDebug() << "Stat: " << url.url();
258
195
    kDebug() << "Stat Dir: " << url.directory();
259
196
    kDebug() << "Stat File: " << url.fileName();
260
 
    ENSURE_SESSION_CREATED(url)
261
 
    if (url.directory() == "/" && url.fileName().isEmpty()) {
 
197
    kDebug() << "Empty Dir: " << url.directory().isEmpty();
 
198
 
 
199
    if ((url.directory() == "/" || url.directory().isEmpty()) && url.fileName().isEmpty()) {
 
200
        kDebug() << "Url is root";
262
201
        KIO::UDSEntry entry;
263
202
        entry.insert(KIO::UDSEntry::UDS_NAME, QString::fromLatin1("/"));
264
203
        entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
274
213
 
275
214
        } else {
276
215
            kDebug() << "statMap NOT contains the url";
277
 
            changeDirectory(url.directory());
278
216
 
279
217
            kDebug() << "RetrieveFolderListing";
280
 
            QDBusPendingReply<QString> folder = m_session->RetrieveFolderListing();
 
218
            blockUntilNotBusy(url.host());
 
219
            QDBusPendingReply<QString> folder = m_kded->listDir(url.host(), url.directory());
281
220
            kDebug() << "retireve called";
282
221
            folder.waitForFinished();
283
222
            kDebug() << "RetrieveError: " << folder.error().message();
284
223
            kDebug() << folder.value();
285
224
 
286
 
            processXmlEntries(url, folder.value(), "statCallback");
 
225
            processXmlEntries(url.upUrl(), folder.value(), "statCallback");
287
226
        }
288
227
    }
289
228
 
 
229
    kDebug() << "Finished";
290
230
    finished();
291
231
}
292
232
 
355
295
    }
356
296
}
357
297
 
358
 
void KioFtp::sessionCreated(const QDBusObjectPath& path)
359
 
{
360
 
    Q_UNUSED(path)
361
 
    kDebug() << "session Created!";
362
 
    disconnect(m_manager, SIGNAL(SessionConnected(QDBusObjectPath)), this, SLOT(sessionCreated(QDBusObjectPath)));
363
 
    m_eventLoop.exit();
364
 
}
365
 
 
366
298
void KioFtp::TransferProgress(qulonglong transfered)
367
299
{
368
300
    processedSize(transfered);
 
301
    wasKilledCheck();
369
302
    kDebug() << "TransferProgress: ";
370
303
}
371
304
 
372
305
void KioFtp::TransferCompleted()
373
306
{
374
307
    kDebug() << "TransferCompleted: ";
375
 
    disconnect(m_session, SIGNAL(TransferProgress(qulonglong)), this, SLOT(TransferProgress(qulonglong)));
376
 
    disconnect(m_session, SIGNAL(TransferCompleted()), this, SLOT(TransferCompleted()));
377
 
    disconnect(m_session, SIGNAL(ErrorOccurred(QString,QString)), this, SLOT(ErrorOccurred(QString,QString)));
378
 
    m_eventLoop.exit();
379
 
}
 
308
    disconnect(m_kded, SIGNAL(Cancelled()), this, SLOT(TransferCancelled()));
 
309
    disconnect(m_kded, SIGNAL(transferProgress(qulonglong)), this, SLOT(TransferProgress(qulonglong)));
 
310
    disconnect(m_kded, SIGNAL(transferCompleted()), this, SLOT(TransferCompleted()));
 
311
    disconnect(m_kded, SIGNAL(errorOccurred(QString,QString)), this, SLOT(ErrorOccurred(QString,QString)));
 
312
    finished();
 
313
    m_eventLoop.exit();
 
314
}
 
315
 
 
316
void KioFtp::TransferCancelled()
 
317
{
 
318
    kDebug() << "TransferCancelled";
 
319
    disconnect(m_kded, SIGNAL(Cancelled()), this, SLOT(TransferCancelled()));
 
320
    disconnect(m_kded, SIGNAL(transferProgress(qulonglong)), this, SLOT(TransferProgress(qulonglong)));
 
321
    disconnect(m_kded, SIGNAL(transferCompleted()), this, SLOT(TransferCompleted()));
 
322
    disconnect(m_kded, SIGNAL(errorOccurred(QString,QString)), this, SLOT(ErrorOccurred(QString,QString)));
 
323
    error(KIO::ERR_USER_CANCELED, "");
 
324
    m_eventLoop.exit();
 
325
}
 
326
 
380
327
 
381
328
void KioFtp::ErrorOccurred(const QString &name, const QString &msg)
382
329
{
383
 
    disconnect(m_session, SIGNAL(TransferProgress(qulonglong)), this, SLOT(TransferProgress(qulonglong)));
384
 
    disconnect(m_session, SIGNAL(TransferCompleted()), this, SLOT(TransferCompleted()));
385
 
    disconnect(m_session, SIGNAL(ErrorOccurred(QString,QString)), this, SLOT(ErrorOccurred(QString,QString)));
 
330
//     disconnect(m_session, SIGNAL(TransferProgress(qulonglong)), this, SLOT(TransferProgress(qulonglong)));
 
331
//     disconnect(m_session, SIGNAL(TransferCompleted()), this, SLOT(TransferCompleted()));
 
332
//     disconnect(m_session, SIGNAL(ErrorOccurred(QString,QString)), this, SLOT(ErrorOccurred(QString,QString)));
386
333
 
387
334
    kDebug() << "ERROR ERROR: " << name;
388
335
    kDebug() << "ERROR ERROR: " << msg;
392
339
        m_eventLoop.exit();
393
340
    }
394
341
}
 
342
 
 
343
void KioFtp::sessionConnected(QString address)
 
344
{
 
345
    kDebug() << "Session connected: " << address;
 
346
 
 
347
    if (m_settingHost) {
 
348
        m_eventLoop.exit();
 
349
    }
 
350
}
 
351
 
 
352
void KioFtp::copyHelper(const KUrl& src, const KUrl& dest)
 
353
{
 
354
    connect(m_kded, SIGNAL(Cancelled()), this, SLOT(TransferCancelled()));
 
355
    connect(m_kded, SIGNAL(transferProgress(qulonglong)), this, SLOT(TransferProgress(qulonglong)));
 
356
    connect(m_kded, SIGNAL(transferCompleted()), this, SLOT(TransferCompleted()));
 
357
    connect(m_kded, SIGNAL(errorOccurred(QString,QString)), this, SLOT(ErrorOccurred(QString,QString)));
 
358
 
 
359
    if (src.scheme() == "obexftp" && dest.scheme() == "obexftp") {
 
360
        error(KIO::ERR_UNSUPPORTED_ACTION, src.prettyUrl());
 
361
        return;
 
362
    }
 
363
 
 
364
    if (src.scheme() == "obexftp") {
 
365
        kDebug() << "scheme is obexftp";
 
366
        kDebug() << src.prettyUrl();
 
367
        //Just in case the url is not in the stat, some times happens...
 
368
        if (!m_statMap.contains(src.prettyUrl())) {
 
369
            kDebug() << "The url is not in the cache, stating it";
 
370
            stat(src);
 
371
        }
 
372
 
 
373
        if (m_statMap.value(src.prettyUrl()).isDir()) {
 
374
            kDebug() << "Skipping to copy: " << src.prettyUrl();
 
375
            error( KIO::ERR_IS_DIRECTORY, src.prettyUrl());
 
376
            disconnect(m_kded, SIGNAL(Cancelled()), this, SLOT(TransferCancelled()));
 
377
            disconnect(m_kded, SIGNAL(transferProgress(qulonglong)), this, SLOT(TransferProgress(qulonglong)));
 
378
            disconnect(m_kded, SIGNAL(transferCompleted()), this, SLOT(TransferCompleted()));
 
379
            disconnect(m_kded, SIGNAL(errorOccurred(QString,QString)), this, SLOT(ErrorOccurred(QString,QString)));
 
380
            return;
 
381
        }
 
382
 
 
383
        kDebug() << "CopyingRemoteFile....";
 
384
        blockUntilNotBusy(src.host());
 
385
        m_kded->copyRemoteFile(src.host(), src.path(), dest.path());
 
386
    } else if (dest.scheme() == "obexftp") {
 
387
        kDebug() << "Sendingfile....";
 
388
        blockUntilNotBusy(dest.host());
 
389
        m_kded->sendFile(dest.host(), src.path(), dest.directory());
 
390
    }
 
391
 
 
392
    m_eventLoop.exec();
 
393
    kDebug() << "Copy end";
 
394
}
 
395
 
 
396
 
 
397
void KioFtp::blockUntilNotBusy(QString address)
 
398
{
 
399
    if (m_kded->isBusy(address).value()) {
 
400
        infoMessage(i18n("The device is busy, waiting..."));
 
401
        while (m_kded->isBusy(address).value() == true) {
 
402
            kDebug() << "Blocking, kded is busy";
 
403
            sleep(1);
 
404
        }
 
405
    }
 
406
    kDebug() << "kded is free";
 
407
}
 
408
 
 
409
void KioFtp::wasKilledCheck()
 
410
{
 
411
    if (wasKilled()) {
 
412
        kDebug() << "slave was killed!";
 
413
        m_kded->Cancel(m_address).waitForFinished();;
 
414
        m_eventLoop.exit();
 
415
    }
 
416
    kDebug() << "Slave is alive";
 
417
}