summaryrefslogtreecommitdiffstats
path: root/kftpgrabber/src/kftpqueue.h
blob: d85f163e9ae491902e3b88ffd27d7063c62e6e9d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
/*
 * This file is part of the KFTPGrabber project
 *
 * Copyright (C) 2003-2004 by the KFTPGrabber developers
 * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
 * NON-INFRINGEMENT.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 * You must obey the GNU General Public License in all respects
 * for all of the code used other than OpenSSL.  If you modify
 * file(s) with this exception, you may extend this exception to your
 * version of the file(s), but you are not obligated to do so.  If you
 * do not wish to do so, delete this exception statement from your
 * version.  If you delete this exception statement from all source
 * files in the program, then also delete it here.
 */

#ifndef KFTPQUEUE_H
#define KFTPQUEUE_H

#include <tqstring.h>
#include <tqvaluelist.h>
#include <tqtimer.h>
#include <tqcache.h>
#include <tqmap.h>
#include <tqpair.h>

#include <kurl.h>
#include <kurldrag.h>
#include <kprocess.h>

#include "kftpqueueprocessor.h"
#include "kftpqueueconverter.h"
#include "kftpfileexistsactions.h"
#include "misc.h"

#include "engine/directorylisting.h"
#include "engine/event.h"

#include "directoryscanner.h"
#include "kftptransfer.h"
#include "kftptransferfile.h"
#include "kftptransferdir.h"
#include "site.h"

using namespace KFTPGrabberBase;

namespace KFTPSession {
  class Session;
  class Connection;
}

class KFTPQueueConverter;

typedef TQPtrList<KFTPQueue::Transfer> KFTPQueueTransfers;

namespace KFTPQueue {

class FailedTransfer;

/**
 * This class represents an opened remote file. The file is stored locally
 * while its being displayed to the user.
 *
 * @author Jernej Kos <kostko@unimatrix-one.org>
 */
class OpenedFile {
public:
    OpenedFile() {}
    
    /**
     * Creates a new OpenedFile object.
     *
     * @param transfer The transfer used to transfer the file
     */
    OpenedFile(TransferFile *transfer);
    
    /**
     * Get file's source (remote).
     *
     * @return File's remote source URL
     */
    KURL source() { return m_source; }
    
    /**
     * Get file's destination (local).
     *
     * @return File's local destination URL
     */
    KURL destination() { return m_dest; }
    
    /**
     * Has the file changed since the transfer ?
     *
     * @return True if the file has been changed since being transfered
     */
    bool hasChanged();
private:
    KURL m_source;
    KURL m_dest;
    
    TQString m_hash;
};

/**
 * This class represents a request for "file already exists" dialog
 * display request.
 *
 * @author Jernej Kos <kostko@unimatrix-one.org>
 */
class UserDialogRequest {
public:
    /**
     * Class constructor.
     */
    UserDialogRequest(TransferFile *transfer, filesize_t srcSize, time_t srcTime,
                      filesize_t dstSize, time_t dstTime);
    
    /**
     * Sends a response to this request.
     *
     * @param event A valid file exists wakeup event
     */
    void sendResponse(KFTPEngine::FileExistsWakeupEvent *event);
    
    /**
     * Returns the transfer that initiated the request.
     */
    TransferFile *getTransfer() const { return m_transfer; }
    
    /**
     * Returns source file size.
     */
    filesize_t sourceSize() const { return m_srcSize; }
    
    /**
     * Returns source file time.
     */
    time_t sourceTime() const { return m_srcTime; }
    
    /**
     * Returns destination file size.
     */
    filesize_t destinationSize() const { return m_dstSize; }
    
    /**
     * Returns destination file time.
     */
    time_t destinationTime() const { return m_dstTime; }
private:
    TransferFile *m_transfer;
    filesize_t m_srcSize;
    time_t m_srcTime;
    filesize_t m_dstSize;
    time_t m_dstTime;
};

/**
 * This class is responsible for managing the complete queue hierarchy. All
 * queued items descend from QueueObject and are contained in a simple tree
 * model. Statistics and abort requests propagate from bottom to top and exec
 * requests go in the other direction.
 *
 * @author Jernej Kos <kostko@unimatrix-one.org>
 */
class Manager : public TQObject {
Q_OBJECT
friend class KFTPSession::Session;
friend class KFTPSession::Connection;
friend class ::KFTPQueueConverter;
friend class DirectoryScanner::ScannerThread;
friend class KFTPQueue::FailedTransfer;
public:
    /**
     * Returns the global manager instance.
     */
    static Manager *self();
    
    /**
     * Class destructor.
     */
    ~Manager();
    
    /**
     * Stop all queued transfers.
     */
    void stopAllTransfers();
    
    /**
     * Get the toplevel queue object. The direct children of this object are different
     * KFTPQueue::Site objects that represent separate sites.
     *
     * @return A QueueObject representing the toplevel object
     */
    QueueObject *topLevelObject() const { return m_topLevel; }
    
    /**
     * Queues a new transfer by looking at the URL drag data.
     * 
     * @param drag The drag data
     */
    void insertTransfer(KURLDrag *drag);
    
    /**
     * Queues a new transfer. This method will create the site if one doesn't exist yet
     * for this transfer. The object will be reparented under the assigned site.
     *
     * @param transfer The transfer to be queued
     */
    void insertTransfer(Transfer *transfer);
    
    /**
     * Remove a transfer from the queue. The faceDestruction method will be called on the
     * transfer object before removal. After calling this method, you shouldn't use the
     * object anymore!
     *
     * @param transfer The transfer to be removed from queue
     * @param abortSession If true any session that this transfer is using is aborted
     */
    void removeTransfer(Transfer *transfer, bool abortSession = true);
    
    /**
     * This method removes all the transfers from the queue.
     */
    void clearQueue();
    
    /**
     * Check if the transfer is under the correct site and move it if not.
     *
     * @param transfer The transfer to check
     */
    void revalidateTransfer(Transfer *transfer);
    
    /**
     * Finds a transfer by its id.
     *
     * @param id The transfer's id
     * @return The transfer object
     */
    Transfer *findTransfer(long id);
    
    /**
     * Finds a site by its URL.
     *
     * @param url The site's URL
     * @param noCreate If set to true the site will not be created when not found
     *                 and NULL will be returned
     * @return The site object
     */
    Site *findSite(KURL url, bool noCreate = false);
    
    /**
     * Remove a failed transfer from the list.
     *
     * @param transfer The failed transfer object to be removed
     */
    void removeFailedTransfer(FailedTransfer *transfer);
    
    /**
     * Remove all failed transfers from the list. This method actually calls the
     * removeFailedTransfer for every failed transfer present.
     */
    void clearFailedTransferList();
    
    /**
     * Moves the specified transfer up in the queue.
     *
     * @param object The queue object to be moved
     */
    void moveTransferUp(QueueObject *object);
    
    /**
     * Moves the specified transfer down in the queue.
     *
     * @param object The queue object to be moved
     */
    void moveTransferDown(QueueObject *object);
    
    /**
     * Moves the specified transfer to the top of the queue (only within the
     * parent boundaries).
     *
     * @param object The queue object to be moved
     */
    void moveTransferTop(QueueObject *object);
    
    /**
     * Moves the specified transfer to the bottom of the queue (only within the
     * parent boundaries).
     *
     * @param object The queue object to be moved
     */
    void moveTransferBottom(QueueObject *object);
    
    /**
     * Can the transfer be moved up ?
     *
     * @param object The queue object to be moved
     * @return True if the transfer can be moved
     */
    bool canBeMovedUp(QueueObject *object);
    
    /**
     * Can the transfer be moved down ?
     *
     * @param object The queue object to be moved
     * @return True if the transfer can be moved
     */
    bool canBeMovedDown(QueueObject *object);
    
    /**
     * Returns the list of failed transfers.
     *
     * @return The TQPtrList of FailedTransfer objects
     */
    TQPtrList<KFTPQueue::FailedTransfer> *getFailedTransferList() { return &m_failedTransfers; }
    
    /**
     * Return the queue converter (exporter).
     *
     * @return the KFTPQueueConverter object
     */
    KFTPQueueConverter *getConverter() const { return m_converter; }
    
    /**
     * Opens the file with the registred application for it's MIME type and waits
     * for the process to exit (then it will reupload the file if it has changed).
     *
     * @param transfer The transfer whose destination should be opened
     */
    void openAfterTransfer(TransferFile *transfer);
    
    /**
     * Should the update() be emitted on changes ?
     *
     * @param value True if the value should be emitted, false otherwise
     */
    void setEmitUpdate(bool value) { m_emitUpdate = value; }
    
    /**
     * Does a global queue update and removes all transfers that have the "delete me"
     * variable set.
     */
    void doEmitUpdate();

    /**
     * Get the current download speed.
     *
     * @return The current download speed
     */
    filesize_t getDownloadSpeed() const { return m_curDownSpeed; }
    
    /**
     * Get the current upload speed.
     *
     * @return The current upload speed
     */
    filesize_t getUploadSpeed() const { return m_curUpSpeed; }
    
    /**
     * Get the percentage of the queue's completion.
     *
     * @return The percentage of the queue's completion
     */
    int getTransferPercentage();
    
    /**
     * Get the number of currently running transfers.
     *
     * @param onlyDirs Should only directories be counted
     * @return The number of currently running transfers
     */
    int getNumRunning(bool onlyDirs = false);
    
    /**
     * Get the number of currently running transfers under a specific
     * site.
     *
     * @param url The remote URL
     * @return The number of currently running transfers
     */
    int getNumRunning(const KURL &remoteUrl);
    
    /**
     * Start the queue processing.
     */
    void start();
    
    /**
     * Abort the queue processing.
     */
    void abort();
    
    /**
     * Is the queue being processed ?
     *
     * @return True if the queue is being processed, false otherwise
     */
    bool isProcessing() { return m_queueProc->isRunning(); }
    
    /**
     * Return the next available transfer id and reserve it.
     *
     * @return The next available transfer id
     */
    long nextTransferId() { return m_lastTQID++; }
    
    /**
     * Set a default action to take when encountering an existing file situation. Note that
     * the action set here will override any preconfigured user actions unless set to the
     * value of FE_DISABLE_ACT.
     *
     * @param action The action to take
     */
    void setDefaultFileExistsAction(FEAction action = FE_DISABLE_ACT) { m_defaultFeAction = action; }
    
    /**
     * Get the default action preset for situations where a file already exists.
     *
     * @return A valid FEAction
     */
    FEAction getDefaultFileExistsAction() const { return m_defaultFeAction; }
    
    /**
     * Decides what to do with the existing file. It will return a valid wakeup event to
     * dispatch. It will first consider the pre-configured "on file exists" action matrix.
     *
     * @param transfer The transfer object
     * @param srcStat Source file information (if remote)
     * @param dstStat Destination file information (if remote)
     * @return A FileExistsWakeupEvent that will be sent to the engine
     */
    KFTPEngine::FileExistsWakeupEvent *fileExistsAction(KFTPQueue::TransferFile *transfer,
                                                        TQValueList<KFTPEngine::DirectoryEntry> stat);
    
    /**
     * Spawn a new transfer.
     *
     * @param sourceUrl Source URL
     * @param destinationUrl Destination URL
     * @param size Filesize
     * @param dir True if this transfer represents a directory
     * @param ignoreSkip Ignore skiplist for this transfer
     * @param insertToQueue Should the new transfer be queued
     * @param parent Optional parent object
     * @param noScan True if directory transfers shouldn't be scanned
     * @return A valid KFTPQueue::Transfer instance
     */
    KFTPQueue::Transfer *spawnTransfer(KURL sourceUrl, KURL destinationUrl, filesize_t size, bool dir,
                                       bool ignoreSkip = false, bool insertToQueue = true, TQObject *parent = 0L, bool noScan = false);
protected:
    /**
     * Global class instance.
     */
    static Manager *m_self;
    
    /**
     * Class constructor.
     */
    Manager();
    
    /**
     * Appends a new user dialog request.
     *
     * @param request Request instance
     */
    void appendUserDialogRequest(UserDialogRequest *request);
    
    /**
     * Processes the top user dialog request by opening the desired "file
     * already exists" dialog.
     */
    void processUserDialogRequest();
private:
    QueueObject *m_topLevel;
    TQCache<QueueObject> m_queueObjectCache;
    
    TQMap<pid_t, OpenedFile> m_editProcessList;
    TQPtrList<KFTPQueue::FailedTransfer> m_failedTransfers;
    KFTPQueueProcessor *m_queueProc;
    KFTPQueueConverter *m_converter;
    
    long m_lastTQID;
    bool m_emitUpdate;
    bool m_processingQueue;

    filesize_t m_curDownSpeed;
    filesize_t m_curUpSpeed;
    
    bool m_feDialogOpen;
    FEAction m_defaultFeAction;
    TQPtrList<UserDialogRequest> m_userDialogRequests;
private slots:
    void slotQueueProcessingComplete();
    void slotQueueProcessingAborted();
    
    void slotEditProcessTerminated(TDEProcess *p);
signals:
    void newSite(KFTPQueue::Site*);
    void newTransfer(KFTPQueue::Transfer*);
    
    void transferRemoved(long);
    void siteRemoved(long);
    
    void queueUpdate();
    
    void failedTransferNew(KFTPQueue::FailedTransfer*);
    void failedTransferRemoved(long);
};

}

#endif