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>
|
|
|
|
|
2016-02-10 23:55:16 +03:00
|
|
|
#include "excludedfiles.h"
|
2014-07-11 02:31:24 +04:00
|
|
|
#include "syncfileitem.h"
|
|
|
|
#include "progressdispatcher.h"
|
|
|
|
#include "utility.h"
|
2016-03-17 14:26:44 +03:00
|
|
|
#include "syncfilestatustracker.h"
|
2014-12-18 14:09:48 +03:00
|
|
|
#include "accountfwd.h"
|
2014-12-02 14:25:51 +03:00
|
|
|
#include "discoveryphase.h"
|
2015-11-23 14:09:25 +03:00
|
|
|
#include "checksums.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;
|
|
|
|
|
2016-12-06 15:18:59 +03:00
|
|
|
enum AnotherSyncNeeded
|
|
|
|
{
|
|
|
|
NoFollowUpSync,
|
|
|
|
ImmediateFollowUp, // schedule this again immediately (limited amount of times)
|
|
|
|
DelayedFollowUp // regularly schedule this folder again (around 1/minute, unlimited)
|
|
|
|
};
|
|
|
|
|
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:
|
2016-02-10 23:55:16 +03:00
|
|
|
SyncEngine(AccountPtr account, const QString &localPath,
|
2016-11-15 20:47:04 +03:00
|
|
|
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();
|
|
|
|
|
2016-03-09 19:53:18 +03:00
|
|
|
bool isSyncRunning() const { return _syncRunning; }
|
|
|
|
|
2017-01-24 12:16:10 +03:00
|
|
|
void setSyncOptions(const SyncOptions &options) { _syncOptions = options; }
|
2016-03-17 14:26:44 +03:00
|
|
|
bool ignoreHiddenFiles() const { return _csync_ctx->ignore_hidden_files; }
|
2016-02-10 23:55:16 +03:00
|
|
|
void setIgnoreHiddenFiles(bool ignore) { _csync_ctx->ignore_hidden_files = ignore; }
|
2015-05-26 15:41:01 +03:00
|
|
|
|
2016-02-10 23:55:16 +03:00
|
|
|
ExcludedFiles &excludedFiles() { return *_excludedFiles; }
|
2014-03-28 12:39:32 +04:00
|
|
|
Utility::StopWatch &stopWatch() { return _stopWatch; }
|
2016-03-17 14:26:44 +03:00
|
|
|
SyncFileStatusTracker &syncFileStatusTracker() { return *_syncFileStatusTracker; }
|
2014-03-26 21:06:25 +04:00
|
|
|
|
2016-12-06 15:18:59 +03:00
|
|
|
/* Returns whether another sync is needed to complete the sync */
|
|
|
|
AnotherSyncNeeded isAnotherSyncNeeded() { return _anotherSyncNeeded; }
|
2014-08-11 20:41:42 +04:00
|
|
|
|
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; }
|
2016-03-17 14:26:44 +03:00
|
|
|
QString localPath() const { return _localPath; }
|
2015-11-20 17:14:22 +03:00
|
|
|
/**
|
|
|
|
* Minimum age, in milisecond, of a file that can be uploaded.
|
|
|
|
* Files more recent than that are not going to be uploaeded as they are considered
|
|
|
|
* too young and possibly still changing
|
|
|
|
*/
|
|
|
|
static qint64 minimumFileAgeForUpload; // in ms
|
|
|
|
|
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)
|
2017-01-25 13:12:38 +03:00
|
|
|
void itemCompleted(const SyncFileItemPtr&);
|
2014-03-21 20:13:02 +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();
|
|
|
|
|
2016-01-05 13:47:17 +03:00
|
|
|
/**
|
|
|
|
* Emited when the sync engine detects that all the files have been removed or change.
|
|
|
|
* This usually happen when the server was reset or something.
|
|
|
|
* Set *cancel to true in a slot connected from this signal to abort the sync.
|
|
|
|
*/
|
2013-06-10 17:57:23 +04:00
|
|
|
void aboutToRemoveAllFiles(SyncFileItem::Direction direction, bool *cancel);
|
2016-01-05 13:47:17 +03:00
|
|
|
/**
|
|
|
|
* Emited when the sync engine detects that all the files are changed to dates in the past.
|
|
|
|
* This usually happen when a backup was restored on the server from an earlier date.
|
|
|
|
* Set *restore to true in a slot connected from this signal to re-upload all files.
|
|
|
|
*/
|
|
|
|
void aboutToRestoreBackup(bool *restore);
|
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
|
2017-01-26 11:03:01 +03:00
|
|
|
void newBigFolder(const QString &folder, bool isExternal);
|
2015-05-21 15:50:30 +03:00
|
|
|
|
2016-04-29 17:14:18 +03:00
|
|
|
/** Emitted when propagation has problems with a locked file.
|
|
|
|
*
|
|
|
|
* Forwarded from OwncloudPropagator::seenLockedFile.
|
|
|
|
*/
|
|
|
|
void seenLockedFile(const QString &fileName);
|
|
|
|
|
2013-05-16 15:54:22 +04:00
|
|
|
private slots:
|
2015-10-29 17:01:29 +03:00
|
|
|
void slotRootEtagReceived(const QString &);
|
2017-01-25 13:12:38 +03:00
|
|
|
void slotItemCompleted(const SyncFileItemPtr& item);
|
2016-08-02 11:30:49 +03:00
|
|
|
void slotFinished(bool success);
|
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
|
|
|
|
2016-06-09 13:07:18 +03:00
|
|
|
/** Records that a file was touched by a job. */
|
|
|
|
void slotAddTouchedFile(const QString& fn);
|
|
|
|
|
|
|
|
/** Wipes the _touchedFiles hash */
|
|
|
|
void slotClearTouchedFiles();
|
|
|
|
|
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
|
|
|
|
2016-09-02 17:12:43 +03:00
|
|
|
QString journalDbFilePath() const;
|
|
|
|
|
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.
|
2017-01-25 13:28:18 +03:00
|
|
|
void deleteStaleDownloadInfos(const SyncFileItemVector &syncItems);
|
2014-09-03 14:11:03 +04:00
|
|
|
|
|
|
|
// Removes stale uploadinfos from the journal.
|
2017-01-25 13:28:18 +03:00
|
|
|
void deleteStaleUploadInfos(const SyncFileItemVector &syncItems);
|
2014-09-03 14:11:03 +04:00
|
|
|
|
2015-01-16 12:17:19 +03:00
|
|
|
// Removes stale error blacklist entries from the journal.
|
2017-01-25 13:28:18 +03:00
|
|
|
void deleteStaleErrorBlacklistEntries(const SyncFileItemVector &syncItems);
|
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
|
|
|
|
2016-03-09 19:53:18 +03:00
|
|
|
static bool s_anySyncRunning; //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
|
|
|
|
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;
|
2016-03-09 19:53:18 +03:00
|
|
|
bool _syncRunning;
|
2013-05-03 21:11:00 +04:00
|
|
|
QString _localPath;
|
|
|
|
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;
|
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
|
|
|
|
2016-02-10 23:55:16 +03:00
|
|
|
QScopedPointer<ExcludedFiles> _excludedFiles;
|
2016-03-17 14:26:44 +03:00
|
|
|
QScopedPointer<SyncFileStatusTracker> _syncFileStatusTracker;
|
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
|
|
|
|
*/
|
2017-01-25 13:28:18 +03:00
|
|
|
void checkForPermission(SyncFileItemVector &syncItems);
|
2014-06-17 16:50:24 +04:00
|
|
|
QByteArray getPermissions(const QString& file) const;
|
2014-06-07 13:49:46 +04:00
|
|
|
|
2016-01-05 13:47:17 +03:00
|
|
|
/**
|
|
|
|
* Instead of downloading files from the server, upload the files to the server
|
|
|
|
*/
|
2017-01-25 13:28:18 +03:00
|
|
|
void restoreOldFiles(SyncFileItemVector &syncItems);
|
2016-01-05 13:47:17 +03:00
|
|
|
|
|
|
|
bool _hasNoneFiles; // true if there is at least one file which was not changed on the server
|
2014-07-15 13:22:16 +04:00
|
|
|
bool _hasRemoveFile; // true if there is at leasr one file with instruction REMOVE
|
2016-01-05 13:47:17 +03:00
|
|
|
bool _hasForwardInTimeFiles; // true if there is at least one file from the server that goes forward in time
|
|
|
|
int _backInTimeFiles; // number of files which goes back in time from the server
|
|
|
|
|
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;
|
2017-01-24 12:16:10 +03:00
|
|
|
SyncOptions _syncOptions;
|
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
|
|
|
|
2015-11-23 13:53:06 +03:00
|
|
|
/// Hook for computing checksums from csync_update
|
|
|
|
CSyncChecksumHook _checksum_hook;
|
|
|
|
|
2016-12-06 15:18:59 +03:00
|
|
|
AnotherSyncNeeded _anotherSyncNeeded;
|
2016-06-09 13:07:18 +03:00
|
|
|
|
|
|
|
/** Stores the time since a job touched a file. */
|
|
|
|
QHash<QString, QElapsedTimer> _touchedFiles;
|
|
|
|
|
|
|
|
/** For clearing the _touchedFiles variable after sync finished */
|
|
|
|
QTimer _clearTouchedFilesTimer;
|
2014-02-05 23:18:03 +04:00
|
|
|
};
|
|
|
|
|
2012-02-15 12:30:37 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // CSYNCTHREAD_H
|