syncengine.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
  3. * Copyright (C) by Klaas Freitag <freitag@owncloud.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. * for more details.
  14. */
  15. #ifndef CSYNCTHREAD_H
  16. #define CSYNCTHREAD_H
  17. #include <stdint.h>
  18. #include <QMutex>
  19. #include <QThread>
  20. #include <QString>
  21. #include <QSet>
  22. #include <QMap>
  23. #include <QStringList>
  24. #include <QSharedPointer>
  25. #include <csync.h>
  26. // when do we go away with this private/public separation?
  27. #include <csync_private.h>
  28. #include "syncfileitem.h"
  29. #include "progressdispatcher.h"
  30. #include "utility.h"
  31. #include "syncfilestatus.h"
  32. #include "accountfwd.h"
  33. #include "discoveryphase.h"
  34. #include "transmissionchecksumvalidator.h"
  35. class QProcess;
  36. namespace OCC {
  37. class SyncJournalFileRecord;
  38. class SyncJournalDb;
  39. class OwncloudPropagator;
  40. class PropagatorJob;
  41. /**
  42. * @brief The SyncEngine class
  43. * @ingroup libsync
  44. */
  45. class OWNCLOUDSYNC_EXPORT SyncEngine : public QObject
  46. {
  47. Q_OBJECT
  48. public:
  49. SyncEngine(AccountPtr account, CSYNC *, const QString &localPath,
  50. const QString &remoteURL, const QString &remotePath, SyncJournalDb *journal);
  51. ~SyncEngine();
  52. static QString csyncErrorToString( CSYNC_STATUS);
  53. Q_INVOKABLE void startSync();
  54. void setNetworkLimits(int upload, int download);
  55. /* Abort the sync. Called from the main thread */
  56. void abort();
  57. /* Set the maximum size a folder can have without asking for confirmation
  58. * -1 means infinite
  59. */
  60. void setNewBigFolderSizeLimit(qint64 limit) { _newBigFolderSizeLimit = limit; }
  61. Utility::StopWatch &stopWatch() { return _stopWatch; }
  62. /* Return true if we detected that another sync is needed to complete the sync */
  63. bool isAnotherSyncNeeded() { return _anotherSyncNeeded; }
  64. bool estimateState(QString fn, csync_ftw_type_e t, SyncFileStatus* s);
  65. /** Get the ms since a file was touched, or -1 if it wasn't.
  66. *
  67. * Thread-safe.
  68. */
  69. qint64 timeSinceFileTouched(const QString& fn) const;
  70. AccountPtr account() const;
  71. SyncJournalDb *journal() const { return _journal; }
  72. /**
  73. * Minimum age, in milisecond, of a file that can be uploaded.
  74. * Files more recent than that are not going to be uploaeded as they are considered
  75. * too young and possibly still changing
  76. */
  77. static qint64 minimumFileAgeForUpload; // in ms
  78. signals:
  79. void csyncError( const QString& );
  80. void csyncUnavailable();
  81. // During update, before reconcile
  82. void rootEtag(QString);
  83. void folderDiscovered(bool local, const QString &folderUrl);
  84. // before actual syncing (after update+reconcile) for each item
  85. void syncItemDiscovered(const SyncFileItem&);
  86. // after the above signals. with the items that actually need propagating
  87. void aboutToPropagate(SyncFileItemVector&);
  88. // after each item completed by a job (successful or not)
  89. void itemCompleted(const SyncFileItem&, const PropagatorJob&);
  90. // after sync is done
  91. void treeWalkResult(const SyncFileItemVector&);
  92. void transmissionProgress( const ProgressInfo& progress );
  93. void finished(bool success);
  94. void started();
  95. void aboutToRemoveAllFiles(SyncFileItem::Direction direction, bool *cancel);
  96. // A new folder was discovered and was not synced because of the confirmation feature
  97. void newBigFolder(const QString &folder);
  98. private slots:
  99. void slotRootEtagReceived(const QString &);
  100. void slotItemCompleted(const SyncFileItem& item, const PropagatorJob & job);
  101. void slotFinished();
  102. void slotProgress(const SyncFileItem& item, quint64 curent);
  103. void slotDiscoveryJobFinished(int updateResult);
  104. void slotCleanPollsJobAborted(const QString &error);
  105. private:
  106. void handleSyncError(CSYNC *ctx, const char *state);
  107. static int treewalkLocal( TREE_WALK_FILE*, void *);
  108. static int treewalkRemote( TREE_WALK_FILE*, void *);
  109. int treewalkFile( TREE_WALK_FILE*, bool );
  110. bool checkErrorBlacklisting( SyncFileItem &item );
  111. // Cleans up unnecessary downloadinfo entries in the journal as well
  112. // as their temporary files.
  113. void deleteStaleDownloadInfos();
  114. // Removes stale uploadinfos from the journal.
  115. void deleteStaleUploadInfos();
  116. // Removes stale error blacklist entries from the journal.
  117. void deleteStaleErrorBlacklistEntries();
  118. // cleanup and emit the finished signal
  119. void finalize(bool success);
  120. static bool _syncRunning; //true when one sync is running somewhere (for debugging)
  121. // Must only be acessed during update and reconcile
  122. QMap<QString, SyncFileItemPtr> _syncItemMap;
  123. // should be called _syncItems (present tense). It's the items from the _syncItemMap but
  124. // sorted and re-adjusted based on permissions.
  125. SyncFileItemVector _syncedItems;
  126. AccountPtr _account;
  127. CSYNC *_csync_ctx;
  128. bool _needsUpdate;
  129. QString _localPath;
  130. QString _remoteUrl;
  131. QString _remotePath;
  132. QString _remoteRootEtag;
  133. SyncJournalDb *_journal;
  134. QPointer<DiscoveryMainThread> _discoveryMainThread;
  135. QSharedPointer <OwncloudPropagator> _propagator;
  136. QString _lastDeleted; // if the last item was a path and it has been deleted
  137. // After a sync, only the syncdb entries whose filenames appear in this
  138. // set will be kept. See _temporarilyUnavailablePaths.
  139. QSet<QString> _seenFiles;
  140. // Some paths might be temporarily unavailable on the server, for
  141. // example due to 503 Storage not available. Deleting information
  142. // about the files from the database in these cases would lead to
  143. // incorrect synchronization.
  144. // Therefore all syncdb entries whose filename starts with one of
  145. // the paths in this set will be kept.
  146. // The specific case that fails otherwise is deleting a local file
  147. // while the remote says storage not available.
  148. QSet<QString> _temporarilyUnavailablePaths;
  149. QThread _thread;
  150. QScopedPointer<ProgressInfo> _progressInfo;
  151. Utility::StopWatch _stopWatch;
  152. // maps the origin and the target of the folders that have been renamed
  153. QHash<QString, QString> _renamedFolders;
  154. QString adjustRenamedPath(const QString &original);
  155. /**
  156. * check if we are allowed to propagate everything, and if we are not, adjust the instructions
  157. * to recover
  158. */
  159. void checkForPermission();
  160. QByteArray getPermissions(const QString& file) const;
  161. bool _hasNoneFiles; // true if there is at least one file with instruction NONE
  162. bool _hasRemoveFile; // true if there is at leasr one file with instruction REMOVE
  163. int _uploadLimit;
  164. int _downloadLimit;
  165. /* maximum size a folder can have without asking for confirmation: -1 means infinite */
  166. qint64 _newBigFolderSizeLimit;
  167. // hash containing the permissions on the remote directory
  168. QHash<QString, QByteArray> _remotePerms;
  169. /// Hook for computing checksums from csync_update
  170. CSyncChecksumHook _checksum_hook;
  171. bool _anotherSyncNeeded;
  172. };
  173. }
  174. #endif // CSYNCTHREAD_H