2012-02-15 12:30:37 +04:00
|
|
|
/*
|
|
|
|
* Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
|
|
|
|
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
|
|
|
*
|
|
|
|
* 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
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*/
|
|
|
|
|
2013-02-13 20:13:25 +04:00
|
|
|
#ifndef CSYNCTHREAD_H
|
|
|
|
#define CSYNCTHREAD_H
|
|
|
|
|
2012-03-01 19:11:56 +04:00
|
|
|
#include <stdint.h>
|
|
|
|
|
2012-02-15 12:30:37 +04:00
|
|
|
#include <QMutex>
|
2014-02-05 23:18:03 +04:00
|
|
|
#include <QThread>
|
2012-02-15 12:30:37 +04:00
|
|
|
#include <QString>
|
2014-06-17 18:29:38 +04:00
|
|
|
#include <QSet>
|
2014-08-07 12:14:14 +04:00
|
|
|
#include <QMap>
|
2014-08-11 20:41:42 +04:00
|
|
|
#include <QStringList>
|
2014-12-11 17:08:13 +03:00
|
|
|
#include <QSharedPointer>
|
2012-02-15 12:30:37 +04:00
|
|
|
|
2012-04-14 14:16:30 +04:00
|
|
|
#include <csync.h>
|
2012-03-21 21:03:49 +04:00
|
|
|
|
2014-08-15 17:00:10 +04:00
|
|
|
// when do we go away with this private/public separation?
|
|
|
|
#include <csync_private.h>
|
|
|
|
|
2014-07-11 02:31:24 +04:00
|
|
|
#include "syncfileitem.h"
|
|
|
|
#include "progressdispatcher.h"
|
|
|
|
#include "utility.h"
|
2014-10-22 12:20:38 +04:00
|
|
|
#include "syncfilestatus.h"
|
2014-12-18 14:09:48 +03:00
|
|
|
#include "accountfwd.h"
|
2014-12-02 14:25:51 +03:00
|
|
|
#include "discoveryphase.h"
|
2013-01-15 23:41:52 +04:00
|
|
|
|
2012-02-15 12:30:37 +04:00
|
|
|
class QProcess;
|
|
|
|
|
2014-11-10 00:34:07 +03:00
|
|
|
namespace OCC {
|
2012-02-15 12:30:37 +04:00
|
|
|
|
2013-10-03 22:00:58 +04:00
|
|
|
class SyncJournalFileRecord;
|
|
|
|
class SyncJournalDb;
|
2013-05-16 15:54:22 +04:00
|
|
|
class OwncloudPropagator;
|
2015-08-11 14:31:19 +03:00
|
|
|
class PropagatorJob;
|
2013-05-16 15:54:22 +04:00
|
|
|
|
2015-06-29 19:56:09 +03:00
|
|
|
/**
|
|
|
|
* @brief The SyncEngine class
|
|
|
|
* @ingroup libsync
|
2015-06-26 18:07:47 +03:00
|
|
|
*/
|
2014-04-25 01:45:20 +04:00
|
|
|
class OWNCLOUDSYNC_EXPORT SyncEngine : public QObject
|
2012-02-15 12:30:37 +04:00
|
|
|
{
|
2012-03-21 21:03:49 +04:00
|
|
|
Q_OBJECT
|
2012-02-15 12:30:37 +04:00
|
|
|
public:
|
2014-12-18 14:09:48 +03:00
|
|
|
SyncEngine(AccountPtr account, CSYNC *, const QString &localPath,
|
|
|
|
const QString &remoteURL, const QString &remotePath, SyncJournalDb *journal);
|
2014-03-17 14:34:51 +04:00
|
|
|
~SyncEngine();
|
2012-02-15 12:30:37 +04:00
|
|
|
|
2013-08-21 15:19:02 +04:00
|
|
|
static QString csyncErrorToString( CSYNC_STATUS);
|
2012-12-06 22:05:03 +04:00
|
|
|
|
2012-08-26 13:47:45 +04:00
|
|
|
Q_INVOKABLE void startSync();
|
2014-06-07 13:49:41 +04:00
|
|
|
void setNetworkLimits(int upload, int download);
|
2012-08-26 13:47:45 +04:00
|
|
|
|
2013-10-02 21:41:17 +04:00
|
|
|
/* Abort the sync. Called from the main thread */
|
|
|
|
void abort();
|
|
|
|
|
2015-07-27 10:54:20 +03:00
|
|
|
/* Set the maximum size a folder can have without asking for confirmation
|
2015-05-26 15:41:01 +03:00
|
|
|
* -1 means infinite
|
|
|
|
*/
|
2015-07-27 10:54:20 +03:00
|
|
|
void setNewBigFolderSizeLimit(qint64 limit) { _newBigFolderSizeLimit = limit; }
|
2015-05-26 15:41:01 +03:00
|
|
|
|
2014-03-28 12:39:32 +04:00
|
|
|
Utility::StopWatch &stopWatch() { return _stopWatch; }
|
2014-03-26 21:06:25 +04:00
|
|
|
|
2014-09-10 19:25:13 +04:00
|
|
|
/* Return true if we detected that another sync is needed to complete the sync */
|
|
|
|
bool isAnotherSyncNeeded() { return _anotherSyncNeeded; }
|
2014-08-11 20:41:42 +04:00
|
|
|
|
2014-10-13 19:23:42 +04:00
|
|
|
bool estimateState(QString fn, csync_ftw_type_e t, SyncFileStatus* s);
|
|
|
|
|
2014-11-07 13:41:21 +03:00
|
|
|
/** Get the ms since a file was touched, or -1 if it wasn't.
|
|
|
|
*
|
|
|
|
* Thread-safe.
|
|
|
|
*/
|
|
|
|
qint64 timeSinceFileTouched(const QString& fn) const;
|
|
|
|
|
2014-12-18 17:39:20 +03:00
|
|
|
AccountPtr account() const;
|
2015-02-16 18:59:21 +03:00
|
|
|
SyncJournalDb *journal() const { return _journal; }
|
2014-12-18 17:39:20 +03:00
|
|
|
|
2012-03-21 21:03:49 +04:00
|
|
|
signals:
|
2012-06-11 12:10:07 +04:00
|
|
|
void csyncError( const QString& );
|
2013-01-16 17:39:43 +04:00
|
|
|
void csyncUnavailable();
|
2014-03-14 17:08:32 +04:00
|
|
|
|
2014-08-15 17:00:10 +04:00
|
|
|
// During update, before reconcile
|
2015-01-23 17:30:00 +03:00
|
|
|
void rootEtag(QString);
|
2015-10-29 17:01:29 +03:00
|
|
|
void folderDiscovered(bool local, const QString &folderUrl);
|
2014-08-15 17:00:10 +04:00
|
|
|
|
2014-03-27 20:04:31 +04:00
|
|
|
// before actual syncing (after update+reconcile) for each item
|
2014-03-27 18:19:02 +04:00
|
|
|
void syncItemDiscovered(const SyncFileItem&);
|
2014-03-27 20:04:31 +04:00
|
|
|
// after the above signals. with the items that actually need propagating
|
2015-02-16 18:31:49 +03:00
|
|
|
void aboutToPropagate(SyncFileItemVector&);
|
2014-03-14 17:08:32 +04:00
|
|
|
|
2015-08-11 14:45:02 +03:00
|
|
|
// after each item completed by a job (successful or not)
|
|
|
|
void itemCompleted(const SyncFileItem&, const PropagatorJob&);
|
2014-03-21 20:13:02 +04:00
|
|
|
|
2014-03-14 17:08:32 +04:00
|
|
|
// after sync is done
|
2013-01-15 23:41:52 +04:00
|
|
|
void treeWalkResult(const SyncFileItemVector&);
|
2012-06-11 12:10:07 +04:00
|
|
|
|
2015-01-30 15:36:20 +03:00
|
|
|
void transmissionProgress( const ProgressInfo& progress );
|
2013-11-25 19:16:33 +04:00
|
|
|
|
2015-10-29 18:43:30 +03:00
|
|
|
void finished(bool success);
|
2012-08-26 13:47:45 +04:00
|
|
|
void started();
|
|
|
|
|
2013-06-10 17:57:23 +04:00
|
|
|
void aboutToRemoveAllFiles(SyncFileItem::Direction direction, bool *cancel);
|
2013-06-08 17:40:45 +04:00
|
|
|
|
2015-07-27 10:54:20 +03:00
|
|
|
// A new folder was discovered and was not synced because of the confirmation feature
|
|
|
|
void newBigFolder(const QString &folder);
|
2015-05-21 15:50:30 +03:00
|
|
|
|
2013-05-16 15:54:22 +04:00
|
|
|
private slots:
|
2015-10-29 17:01:29 +03:00
|
|
|
void slotRootEtagReceived(const QString &);
|
2015-08-11 14:45:02 +03:00
|
|
|
void slotItemCompleted(const SyncFileItem& item, const PropagatorJob & job);
|
2013-10-28 13:47:10 +04:00
|
|
|
void slotFinished();
|
2014-03-14 16:03:16 +04:00
|
|
|
void slotProgress(const SyncFileItem& item, quint64 curent);
|
2014-08-11 19:47:16 +04:00
|
|
|
void slotDiscoveryJobFinished(int updateResult);
|
2014-07-29 17:51:22 +04:00
|
|
|
void slotCleanPollsJobAborted(const QString &error);
|
2013-05-16 15:54:22 +04:00
|
|
|
|
2012-02-15 12:30:37 +04:00
|
|
|
private:
|
2013-02-15 22:29:27 +04:00
|
|
|
void handleSyncError(CSYNC *ctx, const char *state);
|
2013-07-26 15:44:38 +04:00
|
|
|
|
2013-01-15 23:41:52 +04:00
|
|
|
static int treewalkLocal( TREE_WALK_FILE*, void *);
|
|
|
|
static int treewalkRemote( TREE_WALK_FILE*, void *);
|
|
|
|
int treewalkFile( TREE_WALK_FILE*, bool );
|
2015-04-15 16:19:11 +03:00
|
|
|
bool checkErrorBlacklisting( SyncFileItem &item );
|
2013-01-15 23:41:52 +04:00
|
|
|
|
2014-09-03 14:11:03 +04:00
|
|
|
// Cleans up unnecessary downloadinfo entries in the journal as well
|
|
|
|
// as their temporary files.
|
|
|
|
void deleteStaleDownloadInfos();
|
|
|
|
|
|
|
|
// Removes stale uploadinfos from the journal.
|
|
|
|
void deleteStaleUploadInfos();
|
|
|
|
|
2015-01-16 12:17:19 +03:00
|
|
|
// Removes stale error blacklist entries from the journal.
|
|
|
|
void deleteStaleErrorBlacklistEntries();
|
2014-09-03 14:11:03 +04:00
|
|
|
|
2014-05-20 14:28:55 +04:00
|
|
|
// cleanup and emit the finished signal
|
2015-10-29 18:43:30 +03:00
|
|
|
void finalize(bool success);
|
2014-05-20 14:28:55 +04:00
|
|
|
|
2014-05-29 13:34:25 +04:00
|
|
|
static bool _syncRunning; //true when one sync is running somewhere (for debugging)
|
2014-10-13 19:23:42 +04:00
|
|
|
|
2015-03-02 17:08:21 +03:00
|
|
|
// Must only be acessed during update and reconcile
|
2015-04-15 16:19:11 +03:00
|
|
|
QMap<QString, SyncFileItemPtr> _syncItemMap;
|
2014-10-13 19:23:42 +04:00
|
|
|
|
|
|
|
// should be called _syncItems (present tense). It's the items from the _syncItemMap but
|
|
|
|
// sorted and re-adjusted based on permissions.
|
2013-01-15 23:41:52 +04:00
|
|
|
SyncFileItemVector _syncedItems;
|
2013-05-03 21:11:00 +04:00
|
|
|
|
2014-12-18 14:09:48 +03:00
|
|
|
AccountPtr _account;
|
2013-04-20 14:15:27 +04:00
|
|
|
CSYNC *_csync_ctx;
|
2013-02-14 19:25:00 +04:00
|
|
|
bool _needsUpdate;
|
2013-05-03 21:11:00 +04:00
|
|
|
QString _localPath;
|
2014-02-17 20:31:03 +04:00
|
|
|
QString _remoteUrl;
|
2013-05-03 21:11:00 +04:00
|
|
|
QString _remotePath;
|
2015-01-23 17:30:00 +03:00
|
|
|
QString _remoteRootEtag;
|
2013-10-03 22:00:58 +04:00
|
|
|
SyncJournalDb *_journal;
|
2014-12-02 14:25:51 +03:00
|
|
|
QPointer<DiscoveryMainThread> _discoveryMainThread;
|
2014-11-07 13:41:21 +03:00
|
|
|
QSharedPointer <OwncloudPropagator> _propagator;
|
2013-05-16 15:54:22 +04:00
|
|
|
QString _lastDeleted; // if the last item was a path and it has been deleted
|
2015-04-08 11:50:08 +03:00
|
|
|
|
|
|
|
// After a sync, only the syncdb entries whose filenames appear in this
|
|
|
|
// set will be kept. See _temporarilyUnavailablePaths.
|
2014-06-17 18:29:38 +04:00
|
|
|
QSet<QString> _seenFiles;
|
2015-04-08 11:50:08 +03:00
|
|
|
|
|
|
|
// Some paths might be temporarily unavailable on the server, for
|
|
|
|
// example due to 503 Storage not available. Deleting information
|
|
|
|
// about the files from the database in these cases would lead to
|
|
|
|
// incorrect synchronization.
|
|
|
|
// Therefore all syncdb entries whose filename starts with one of
|
|
|
|
// the paths in this set will be kept.
|
|
|
|
// The specific case that fails otherwise is deleting a local file
|
|
|
|
// while the remote says storage not available.
|
|
|
|
QSet<QString> _temporarilyUnavailablePaths;
|
|
|
|
|
2014-02-05 23:18:03 +04:00
|
|
|
QThread _thread;
|
2013-05-16 15:54:22 +04:00
|
|
|
|
2015-01-30 15:36:20 +03:00
|
|
|
QScopedPointer<ProgressInfo> _progressInfo;
|
2013-02-15 22:29:27 +04:00
|
|
|
|
2014-03-26 21:06:25 +04:00
|
|
|
Utility::StopWatch _stopWatch;
|
|
|
|
|
2013-05-15 17:22:20 +04:00
|
|
|
// maps the origin and the target of the folders that have been renamed
|
|
|
|
QHash<QString, QString> _renamedFolders;
|
|
|
|
QString adjustRenamedPath(const QString &original);
|
|
|
|
|
2014-06-07 13:49:46 +04:00
|
|
|
/**
|
|
|
|
* check if we are allowed to propagate everything, and if we are not, adjust the instructions
|
|
|
|
* to recover
|
|
|
|
*/
|
|
|
|
void checkForPermission();
|
2014-06-17 16:50:24 +04:00
|
|
|
QByteArray getPermissions(const QString& file) const;
|
2014-06-07 13:49:46 +04:00
|
|
|
|
2014-07-15 13:22:16 +04:00
|
|
|
bool _hasNoneFiles; // true if there is at least one file with instruction NONE
|
|
|
|
bool _hasRemoveFile; // true if there is at leasr one file with instruction REMOVE
|
2014-03-14 16:03:16 +04:00
|
|
|
|
2013-08-14 21:59:16 +04:00
|
|
|
int _uploadLimit;
|
2014-06-07 14:20:54 +04:00
|
|
|
int _downloadLimit;
|
2015-07-27 10:54:20 +03:00
|
|
|
/* maximum size a folder can have without asking for confirmation: -1 means infinite */
|
|
|
|
qint64 _newBigFolderSizeLimit;
|
2014-06-17 16:50:24 +04:00
|
|
|
|
|
|
|
// hash containing the permissions on the remote directory
|
|
|
|
QHash<QString, QByteArray> _remotePerms;
|
2014-02-05 23:18:03 +04:00
|
|
|
|
2014-09-10 19:25:13 +04:00
|
|
|
bool _anotherSyncNeeded;
|
2014-02-05 23:18:03 +04:00
|
|
|
};
|
|
|
|
|
2012-02-15 12:30:37 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // CSYNCTHREAD_H
|