void SyncEngine::slotJobCompleted(const SyncFileItem &item) { qDebug() << Q_FUNC_INFO << item._file << item._status << item._errorString; /* Update the _syncedItems vector */ int idx = _syncedItems.indexOf(item); if (idx >= 0) { _syncedItems[idx]._instruction = item._instruction; _syncedItems[idx]._errorString = item._errorString; _syncedItems[idx]._status = item._status; _syncedItems[idx]._requestDuration = item._requestDuration; _syncedItems[idx]._responseTimeStamp = item._responseTimeStamp; } else { qWarning() << Q_FUNC_INFO << "Could not find index in synced items!"; } _progressInfo.setProgressComplete(item); if (item._status == SyncFileItem::FatalError) { emit csyncError(item._errorString); } emit transmissionProgress(_progressInfo); emit jobCompleted(item); }
void SyncEngine::slotItemCompleted(const SyncFileItem &item, const PropagatorJob &job) { const char * instruction_str = csync_instruction_str(item._instruction); qDebug() << Q_FUNC_INFO << item._file << instruction_str << item._status << item._errorString; _progressInfo->setProgressComplete(item); if (item._status == SyncFileItem::FatalError) { emit csyncError(item._errorString); } emit transmissionProgress(*_progressInfo); emit itemCompleted(item, job); }
void CSyncThread::slotProgress(Progress::Kind kind, const QString &file, quint64 curr, quint64 total) { Progress::Info pInfo = _progressInfo; pInfo.kind = kind; pInfo.current_file = file; pInfo.file_size = total; pInfo.current_file_bytes = curr; pInfo.overall_current_bytes += curr; pInfo.timestamp = QDateTime::currentDateTime(); // Connect to something in folder! transmissionProgress( pInfo ); }
void CSyncThread::slotProgress(Progress::Kind kind, const SyncFileItem& item, quint64 curr, quint64 total) { if( Progress::isErrorKind(kind) ) { progressProblem(kind, item); return; } if( kind == Progress::StartSync ) { _currentFileNo = 0; _lastOverallBytes = 0; } if( kind == Progress::StartDelete || kind == Progress::StartDownload || kind == Progress::StartRename || kind == Progress::StartUpload ) { int indx = _syncedItems.indexOf(item); if( _previousIndex != indx ) { _currentFileNo += 1; _previousIndex = indx; } curr = 0; } if( kind == Progress::EndUpload || kind == Progress::EndDownload) { _lastOverallBytes += total; } Progress::Info pInfo(_progressInfo); pInfo.kind = kind; pInfo.current_file = item._file; pInfo.rename_target = item._renameTarget; pInfo.file_size = total; pInfo.current_file_bytes = curr; pInfo.current_file_no = _currentFileNo; pInfo.timestamp = QDateTime::currentDateTime(); pInfo.overall_current_bytes = _lastOverallBytes + curr; // Connect to something in folder! emit transmissionProgress( pInfo ); }
void SyncEngine::slotProgress(const SyncFileItem& item, quint64 current) { _progressInfo->setProgressItem(item, current); emit transmissionProgress(*_progressInfo); }
void SyncEngine::slotDiscoveryJobFinished(int discoveryResult) { // To clean the progress info emit folderDiscovered(false, QString()); if (discoveryResult < 0 ) { handleSyncError(_csync_ctx, "csync_update"); return; } qDebug() << "<<#### Discovery end #################################################### " << _stopWatch.addLapTime(QLatin1String("Discovery Finished")); // Sanity check if (!_journal->isConnected()) { qDebug() << "Bailing out, DB failure"; emit csyncError(tr("Cannot open the sync journal")); finalize(false); return; } else { // Commits a possibly existing (should not though) transaction and starts a new one for the propagate phase _journal->commitIfNeededAndStartNewTransaction("Post discovery"); } if( csync_reconcile(_csync_ctx) < 0 ) { handleSyncError(_csync_ctx, "csync_reconcile"); return; } qDebug() << "<<#### Reconcile end #################################################### " << _stopWatch.addLapTime(QLatin1String("Reconcile Finished")); _hasNoneFiles = false; _hasRemoveFile = false; bool walkOk = true; _seenFiles.clear(); _temporarilyUnavailablePaths.clear(); if( csync_walk_local_tree(_csync_ctx, &treewalkLocal, 0) < 0 ) { qDebug() << "Error in local treewalk."; walkOk = false; } if( walkOk && csync_walk_remote_tree(_csync_ctx, &treewalkRemote, 0) < 0 ) { qDebug() << "Error in remote treewalk."; } if (_csync_ctx->remote.root_perms) { _remotePerms[QLatin1String("")] = _csync_ctx->remote.root_perms; qDebug() << "Permissions of the root folder: " << _remotePerms[QLatin1String("")]; } // Re-init the csync context to free memory csync_commit(_csync_ctx); // The map was used for merging trees, convert it to a list: _syncedItems = _syncItemMap.values().toVector(); _syncItemMap.clear(); // free memory // Adjust the paths for the renames. for (SyncFileItemVector::iterator it = _syncedItems.begin(); it != _syncedItems.end(); ++it) { (*it)->_file = adjustRenamedPath((*it)->_file); } // Sort items per destination std::sort(_syncedItems.begin(), _syncedItems.end()); // make sure everything is allowed checkForPermission(); // To announce the beginning of the sync emit aboutToPropagate(_syncedItems); // it's important to do this before ProgressInfo::start(), to announce start of new sync emit transmissionProgress(*_progressInfo); _progressInfo->start(); if (!_hasNoneFiles && _hasRemoveFile) { qDebug() << Q_FUNC_INFO << "All the files are going to be changed, asking the user"; bool cancel = false; emit aboutToRemoveAllFiles(_syncedItems.first()->_direction, &cancel); if (cancel) { qDebug() << Q_FUNC_INFO << "Abort sync"; finalize(false); return; } } // post update phase script: allow to tweak stuff by a custom script in debug mode. if( !qgetenv("OWNCLOUD_POST_UPDATE_SCRIPT").isEmpty() ) { #ifndef NDEBUG QString script = qgetenv("OWNCLOUD_POST_UPDATE_SCRIPT"); qDebug() << "OOO => Post Update Script: " << script; QProcess::execute(script.toUtf8()); #else qWarning() << "**** Attention: POST_UPDATE_SCRIPT installed, but not executed because compiled with NDEBUG"; #endif } // do a database commit _journal->commit("post treewalk"); _propagator = QSharedPointer<OwncloudPropagator>( new OwncloudPropagator (_account, _localPath, _remoteUrl, _remotePath, _journal)); connect(_propagator.data(), SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)), this, SLOT(slotItemCompleted(const SyncFileItem &, const PropagatorJob &))); connect(_propagator.data(), SIGNAL(progress(const SyncFileItem &,quint64)), this, SLOT(slotProgress(const SyncFileItem &,quint64))); connect(_propagator.data(), SIGNAL(finished()), this, SLOT(slotFinished()), Qt::QueuedConnection); // apply the network limits to the propagator setNetworkLimits(_uploadLimit, _downloadLimit); deleteStaleDownloadInfos(); deleteStaleUploadInfos(); deleteStaleErrorBlacklistEntries(); _journal->commit("post stale entry removal"); // Emit the started signal only after the propagator has been set up. if (_needsUpdate) emit(started()); _propagator->start(_syncedItems); qDebug() << "<<#### Post-Reconcile end #################################################### " << _stopWatch.addLapTime(QLatin1String("Post-Reconcile Finished")); }
void SyncEngine::slotUpdateFinished(int updateResult) { if (updateResult < 0 ) { handleSyncError(_csync_ctx, "csync_update"); return; } qDebug() << "<<#### Update end #################################################### " << _stopWatch.addLapTime(QLatin1String("Update Finished")); if( csync_reconcile(_csync_ctx) < 0 ) { handleSyncError(_csync_ctx, "csync_reconcile"); return; } _stopWatch.addLapTime(QLatin1String("Reconcile Finished")); _progressInfo = Progress::Info(); _hasFiles = false; bool walkOk = true; _seenFiles.clear(); if( csync_walk_local_tree(_csync_ctx, &treewalkLocal, 0) < 0 ) { qDebug() << "Error in local treewalk."; walkOk = false; } if( walkOk && csync_walk_remote_tree(_csync_ctx, &treewalkRemote, 0) < 0 ) { qDebug() << "Error in remote treewalk."; } // Adjust the paths for the renames. for (SyncFileItemVector::iterator it = _syncedItems.begin(); it != _syncedItems.end(); ++it) { it->_file = adjustRenamedPath(it->_file); } // Sanity check if (!_journal->isConnected()) { qDebug() << "Bailing out, DB failure"; emit csyncError(tr("Cannot open the sync journal")); finalize(); return; } // To announce the beginning of the sync emit aboutToPropagate(_syncedItems); emit transmissionProgress(_progressInfo); if (!_hasFiles && !_syncedItems.isEmpty()) { qDebug() << Q_FUNC_INFO << "All the files are going to be removed, asking the user"; bool cancel = false; emit aboutToRemoveAllFiles(_syncedItems.first()._direction, &cancel); if (cancel) { qDebug() << Q_FUNC_INFO << "Abort sync"; finalize(); return; } } if (_needsUpdate) emit(started()); ne_session_s *session = 0; // that call to set property actually is a get which will return the session csync_set_module_property(_csync_ctx, "get_dav_session", &session); Q_ASSERT(session); _propagator.reset(new OwncloudPropagator (session, _localPath, _remoteUrl, _remotePath, _journal, &_thread)); connect(_propagator.data(), SIGNAL(completed(SyncFileItem)), this, SLOT(slotJobCompleted(SyncFileItem))); connect(_propagator.data(), SIGNAL(progress(SyncFileItem,quint64)), this, SLOT(slotProgress(SyncFileItem,quint64))); connect(_propagator.data(), SIGNAL(adjustTotalTransmissionSize(qint64)), this, SLOT(slotAdjustTotalTransmissionSize(qint64))); connect(_propagator.data(), SIGNAL(finished()), this, SLOT(slotFinished()), Qt::QueuedConnection); // apply the network limits to the propagator setNetworkLimits(_uploadLimit, _downloadLimit); _propagator->start(_syncedItems); }
void Folder::startSync(const QStringList &pathList) { Q_ASSERT(_accountState); Q_UNUSED(pathList) if (!_csync_ctx) { // no _csync_ctx yet, initialize it. init(); if (!_csync_ctx) { qDebug() << Q_FUNC_INFO << "init failed."; // the error should already be set QMetaObject::invokeMethod(this, "slotSyncFinished", Qt::QueuedConnection); return; } } else if (proxyDirty()) { setProxyDirty(false); } csync_set_log_level( Logger::instance()->isNoop() ? 0 : 11 ); if (isBusy()) { qCritical() << "* ERROR csync is still running and new sync requested."; return; } _errors.clear(); _csyncError = false; _csyncUnavail = false; _timeSinceLastSyncStart.restart(); _syncResult.clearErrors(); _syncResult.setStatus( SyncResult::SyncPrepare ); _syncResult.setSyncFileItemVector(SyncFileItemVector()); emit syncStateChange(); qDebug() << "*** Start syncing " << alias() << " - client version" << qPrintable(Theme::instance()->version()); if (! setIgnoredFiles()) { slotSyncError(tr("Could not read system exclude file")); QMetaObject::invokeMethod(this, "slotSyncFinished", Qt::QueuedConnection); return; } // pass the setting if hidden files are to be ignored, will be read in csync_update _csync_ctx->ignore_hidden_files = _definition.ignoreHiddenFiles; _engine.reset(new SyncEngine( _accountState->account(), _csync_ctx, path(), remoteUrl().path(), remotePath(), &_journal)); qRegisterMetaType<SyncFileItemVector>("SyncFileItemVector"); qRegisterMetaType<SyncFileItem::Direction>("SyncFileItem::Direction"); connect(_engine.data(), SIGNAL(rootEtag(QString)), this, SLOT(etagRetreivedFromSyncEngine(QString))); connect( _engine.data(), SIGNAL(treeWalkResult(const SyncFileItemVector&)), this, SLOT(slotThreadTreeWalkResult(const SyncFileItemVector&)), Qt::QueuedConnection); connect( _engine.data(), SIGNAL(aboutToPropagate(SyncFileItemVector&)), this, SLOT(slotAboutToPropagate(SyncFileItemVector&))); connect(_engine.data(), SIGNAL(started()), SLOT(slotSyncStarted()), Qt::QueuedConnection); connect(_engine.data(), SIGNAL(finished(bool)), SLOT(slotSyncFinished(bool)), Qt::QueuedConnection); connect(_engine.data(), SIGNAL(csyncError(QString)), SLOT(slotSyncError(QString)), Qt::QueuedConnection); connect(_engine.data(), SIGNAL(csyncUnavailable()), SLOT(slotCsyncUnavailable()), Qt::QueuedConnection); //direct connection so the message box is blocking the sync. connect(_engine.data(), SIGNAL(aboutToRemoveAllFiles(SyncFileItem::Direction,bool*)), SLOT(slotAboutToRemoveAllFiles(SyncFileItem::Direction,bool*))); connect(_engine.data(), SIGNAL(folderDiscovered(bool,QString)), this, SLOT(slotFolderDiscovered(bool,QString))); connect(_engine.data(), SIGNAL(transmissionProgress(ProgressInfo)), this, SLOT(slotTransmissionProgress(ProgressInfo))); connect(_engine.data(), SIGNAL(itemCompleted(const SyncFileItem &, const PropagatorJob &)), this, SLOT(slotItemCompleted(const SyncFileItem &, const PropagatorJob &))); connect(_engine.data(), SIGNAL(syncItemDiscovered(const SyncFileItem &)), this, SLOT(slotSyncItemDiscovered(const SyncFileItem &))); connect(_engine.data(), SIGNAL(newBigFolder(QString)), this, SLOT(slotNewBigFolderDiscovered(QString))); setDirtyNetworkLimits(); ConfigFile cfgFile; auto newFolderLimit = cfgFile.newBigFolderSizeLimit(); quint64 limit = newFolderLimit.first ? newFolderLimit.second * 1000 * 1000 : -1; // convert from MB to B _engine->setNewBigFolderSizeLimit(limit); QMetaObject::invokeMethod(_engine.data(), "startSync", Qt::QueuedConnection); // disable events until syncing is done // _watcher->setEventsEnabled(false); emit syncStarted(); }
void SyncEngine::slotDiscoveryJobFinished(int discoveryResult) { // To clean the progress info emit folderDiscovered(false, QString()); if (discoveryResult < 0 ) { handleSyncError(_csync_ctx, "csync_update"); return; } qDebug() << "<<#### Discovery end #################################################### " << _stopWatch.addLapTime(QLatin1String("Discovery Finished")); // Sanity check if (!_journal->isConnected()) { qDebug() << "Bailing out, DB failure"; emit csyncError(tr("Cannot open the sync journal")); finalize(); return; } else { // Commits a possibly existing (should not though) transaction and starts a new one for the propagate phase _journal->commitIfNeededAndStartNewTransaction("Post discovery"); } if( csync_reconcile(_csync_ctx) < 0 ) { handleSyncError(_csync_ctx, "csync_reconcile"); return; } _stopWatch.addLapTime(QLatin1String("Reconcile Finished")); _progressInfo = Progress::Info(); _hasNoneFiles = false; _hasRemoveFile = false; bool walkOk = true; _seenFiles.clear(); if( csync_walk_local_tree(_csync_ctx, &treewalkLocal, 0) < 0 ) { qDebug() << "Error in local treewalk."; walkOk = false; } if( walkOk && csync_walk_remote_tree(_csync_ctx, &treewalkRemote, 0) < 0 ) { qDebug() << "Error in remote treewalk."; } // The map was used for merging trees, convert it to a list: _syncedItems = _syncItemMap.values().toVector(); // Adjust the paths for the renames. for (SyncFileItemVector::iterator it = _syncedItems.begin(); it != _syncedItems.end(); ++it) { it->_file = adjustRenamedPath(it->_file); } // Sort items per destination std::sort(_syncedItems.begin(), _syncedItems.end()); // make sure everything is allowed checkForPermission(); // To announce the beginning of the sync emit aboutToPropagate(_syncedItems); _progressInfo._completedFileCount = ULLONG_MAX; // indicate the start with max emit transmissionProgress(_progressInfo); _progressInfo._completedFileCount = 0; if (!_hasNoneFiles && _hasRemoveFile) { qDebug() << Q_FUNC_INFO << "All the files are going to be changed, asking the user"; bool cancel = false; emit aboutToRemoveAllFiles(_syncedItems.first()._direction, &cancel); if (cancel) { qDebug() << Q_FUNC_INFO << "Abort sync"; finalize(); return; } } if (_needsUpdate) emit(started()); ne_session_s *session = 0; // that call to set property actually is a get which will return the session csync_set_module_property(_csync_ctx, "get_dav_session", &session); Q_ASSERT(session); // post update phase script: allow to tweak stuff by a custom script in debug mode. if( !qgetenv("OWNCLOUD_POST_UPDATE_SCRIPT").isEmpty() ) { #ifndef NDEBUG QString script = qgetenv("OWNCLOUD_POST_UPDATE_SCRIPT"); qDebug() << "OOO => Post Update Script: " << script; QProcess::execute(script.toUtf8()); #else qDebug() << "**** Attention: POST_UPDATE_SCRIPT installed, but not executed because compiled with NDEBUG"; #endif } // do a database commit _journal->commit("post treewalk"); _propagator.reset(new OwncloudPropagator (session, _localPath, _remoteUrl, _remotePath, _journal, &_thread)); connect(_propagator.data(), SIGNAL(completed(SyncFileItem)), this, SLOT(slotJobCompleted(SyncFileItem))); connect(_propagator.data(), SIGNAL(progress(SyncFileItem,quint64)), this, SLOT(slotProgress(SyncFileItem,quint64))); connect(_propagator.data(), SIGNAL(adjustTotalTransmissionSize(qint64)), this, SLOT(slotAdjustTotalTransmissionSize(qint64))); connect(_propagator.data(), SIGNAL(finished()), this, SLOT(slotFinished()), Qt::QueuedConnection); // apply the network limits to the propagator setNetworkLimits(_uploadLimit, _downloadLimit); deleteStaleDownloadInfos(); deleteStaleUploadInfos(); deleteStaleBlacklistEntries(); _journal->commit("post stale entry removal"); _propagator->start(_syncedItems); }