Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsync')
-rw-r--r--src/libsync/account.h2
-rw-r--r--src/libsync/configfile.cpp13
-rw-r--r--src/libsync/configfile.h3
-rw-r--r--src/libsync/logger.cpp104
-rw-r--r--src/libsync/logger.h21
-rw-r--r--src/libsync/networkjobs.cpp2
-rw-r--r--src/libsync/owncloudpropagator.cpp8
-rw-r--r--src/libsync/owncloudpropagator.h2
-rw-r--r--src/libsync/owncloudtheme.cpp66
-rw-r--r--src/libsync/owncloudtheme.h12
-rw-r--r--src/libsync/propagateupload.cpp10
-rw-r--r--src/libsync/propagateupload.h2
-rw-r--r--src/libsync/propagateuploadng.cpp19
-rw-r--r--src/libsync/propagateuploadv1.cpp19
-rw-r--r--src/libsync/syncengine.cpp6
-rw-r--r--src/libsync/syncengine.h4
-rw-r--r--src/libsync/syncfileitem.h5
-rw-r--r--src/libsync/theme.cpp47
-rw-r--r--src/libsync/theme.h15
19 files changed, 209 insertions, 151 deletions
diff --git a/src/libsync/account.h b/src/libsync/account.h
index 025dca907..a7879f4d0 100644
--- a/src/libsync/account.h
+++ b/src/libsync/account.h
@@ -218,7 +218,7 @@ public:
/** Detects a specific bug in older server versions */
bool rootEtagChangesNotOnlySubFolderEtags();
- /** True when the server supports HTTP2 */
+ /** True when the server connection is using HTTP2 */
bool isHttp2Supported() { return _http2Supported; }
void setHttp2Supported(bool value) { _http2Supported = value; }
diff --git a/src/libsync/configfile.cpp b/src/libsync/configfile.cpp
index 82c2bc5f3..d0dadbf0f 100644
--- a/src/libsync/configfile.cpp
+++ b/src/libsync/configfile.cpp
@@ -64,6 +64,7 @@ static const char chunkSizeC[] = "chunkSize";
static const char minChunkSizeC[] = "minChunkSize";
static const char maxChunkSizeC[] = "maxChunkSize";
static const char targetChunkUploadDurationC[] = "targetChunkUploadDuration";
+static const char automaticLogDirC[] = "logToTemporaryLogDir";
static const char showExperimentalOptionsC[] = "showExperimentalOptions";
static const char proxyHostC[] = "Proxy/host";
@@ -737,6 +738,18 @@ void ConfigFile::setCrashReporter(bool enabled)
settings.setValue(QLatin1String(crashReporterC), enabled);
}
+bool ConfigFile::automaticLogDir() const
+{
+ QSettings settings(configFile(), QSettings::IniFormat);
+ return settings.value(QLatin1String(automaticLogDirC), false).toBool();
+}
+
+void ConfigFile::setAutomaticLogDir(bool enabled)
+{
+ QSettings settings(configFile(), QSettings::IniFormat);
+ settings.setValue(QLatin1String(automaticLogDirC), enabled);
+}
+
bool ConfigFile::showExperimentalOptions() const
{
QSettings settings(configFile(), QSettings::IniFormat);
diff --git a/src/libsync/configfile.h b/src/libsync/configfile.h
index 8877bb6dc..99aa6d5f1 100644
--- a/src/libsync/configfile.h
+++ b/src/libsync/configfile.h
@@ -89,6 +89,9 @@ public:
bool crashReporter() const;
void setCrashReporter(bool enabled);
+ bool automaticLogDir() const;
+ void setAutomaticLogDir(bool enabled);
+
// Whether experimental UI options should be shown
bool showExperimentalOptions() const;
diff --git a/src/libsync/logger.cpp b/src/libsync/logger.cpp
index cfba000ed..7033bd851 100644
--- a/src/libsync/logger.cpp
+++ b/src/libsync/logger.cpp
@@ -14,11 +14,15 @@
#include "logger.h"
+#include "config.h"
+
#include <QDir>
#include <QStringList>
#include <QThread>
#include <qmetaobject.h>
+#include <zlib.h>
+
namespace OCC {
static void mirallLogCatcher(QtMsgType type, const QMessageLogContext &ctx, const QString &message)
@@ -95,10 +99,15 @@ void Logger::log(Log log)
*/
bool Logger::isNoop() const
{
- QMutexLocker lock(const_cast<QMutex *>(&_mutex));
+ QMutexLocker lock(&_mutex);
return !_logstream && !_logWindowActivated;
}
+bool Logger::isLoggingToFile() const
+{
+ QMutexLocker lock(&_mutex);
+ return _logstream;
+}
void Logger::doLog(const QString &msg)
{
@@ -181,34 +190,99 @@ void Logger::setLogDebug(bool debug)
_logDebug = debug;
}
+QString Logger::temporaryFolderLogDirPath() const
+{
+ QString dirName = APPLICATION_SHORTNAME + QString("-logdir");
+ return QDir::temp().filePath(dirName);
+}
+
+void Logger::setupTemporaryFolderLogDir()
+{
+ auto dir = temporaryFolderLogDirPath();
+ if (!QDir().mkpath(dir))
+ return;
+ setLogDebug(true);
+ setLogExpire(4 /*hours*/);
+ setLogDir(dir);
+ _temporaryFolderLogDir = true;
+}
+
+void Logger::disableTemporaryFolderLogDir()
+{
+ if (!_temporaryFolderLogDir)
+ return;
+
+ enterNextLogFile();
+ setLogDir(QString());
+ setLogDebug(false);
+ setLogFile(QString());
+ _temporaryFolderLogDir = false;
+}
+
+static bool compressLog(const QString &originalName, const QString &targetName)
+{
+ QFile original(originalName);
+ if (!original.open(QIODevice::ReadOnly))
+ return false;
+ auto compressed = gzopen(targetName.toUtf8(), "wb");
+ if (!compressed) {
+ return false;
+ }
+
+ while (!original.atEnd()) {
+ auto data = original.read(1024 * 1024);
+ auto written = gzwrite(compressed, data.data(), data.size());
+ if (written != data.size()) {
+ gzclose(compressed);
+ return false;
+ }
+ }
+ gzclose(compressed);
+ return true;
+}
+
void Logger::enterNextLogFile()
{
if (!_logDirectory.isEmpty()) {
+
QDir dir(_logDirectory);
if (!dir.exists()) {
dir.mkpath(".");
}
- // Find out what is the file with the highest number if any
- QStringList files = dir.entryList(QStringList("owncloud.log.*"),
+ // Tentative new log name, will be adjusted if one like this already exists
+ QDateTime now = QDateTime::currentDateTime();
+ QString newLogName = now.toString("yyyyMMdd_HHmm") + "_owncloud.log";
+
+ // Expire old log files and deal with conflicts
+ QStringList files = dir.entryList(QStringList("*owncloud.log.*"),
QDir::Files);
- QRegExp rx("owncloud.log.(\\d+)");
- uint maxNumber = 0;
- QDateTime now = QDateTime::currentDateTimeUtc();
+ QRegExp rx(R"(.*owncloud\.log\.(\d+).*)");
+ int maxNumber = -1;
foreach (const QString &s, files) {
- if (rx.exactMatch(s)) {
- maxNumber = qMax(maxNumber, rx.cap(1).toUInt());
- if (_logExpire > 0) {
- QFileInfo fileInfo = dir.absoluteFilePath(s);
- if (fileInfo.lastModified().addSecs(60 * 60 * _logExpire) < now) {
- dir.remove(s);
- }
+ if (_logExpire > 0) {
+ QFileInfo fileInfo(dir.absoluteFilePath(s));
+ if (fileInfo.lastModified().addSecs(60 * 60 * _logExpire) < now) {
+ dir.remove(s);
}
}
+ if (s.startsWith(newLogName) && rx.exactMatch(s)) {
+ maxNumber = qMax(maxNumber, rx.cap(1).toInt());
+ }
}
+ newLogName.append("." + QString::number(maxNumber + 1));
- QString filename = _logDirectory + "/owncloud.log." + QString::number(maxNumber + 1);
- setLogFile(filename);
+ auto previousLog = _logFile.fileName();
+ setLogFile(dir.filePath(newLogName));
+
+ if (!previousLog.isEmpty()) {
+ QString compressedName = previousLog + ".gz";
+ if (compressLog(previousLog, compressedName)) {
+ QFile::remove(previousLog);
+ } else {
+ QFile::remove(compressedName);
+ }
+ }
}
}
diff --git a/src/libsync/logger.h b/src/libsync/logger.h
index 9d6ef6b26..7ae278e49 100644
--- a/src/libsync/logger.h
+++ b/src/libsync/logger.h
@@ -43,6 +43,8 @@ class OWNCLOUDSYNC_EXPORT Logger : public QObject
Q_OBJECT
public:
bool isNoop() const;
+ bool isLoggingToFile() const;
+
void log(Log log);
void doLog(const QString &log);
@@ -65,6 +67,22 @@ public:
bool logDebug() const { return _logDebug; }
void setLogDebug(bool debug);
+ /** Returns where the automatic logdir would be */
+ QString temporaryFolderLogDirPath() const;
+
+ /** Sets up default dir log setup.
+ *
+ * logdir: a temporary folder
+ * logexpire: 4 hours
+ * logdebug: true
+ *
+ * Used in conjunction with ConfigFile::automaticLogDir
+ */
+ void setupTemporaryFolderLogDir();
+
+ /** For switching off via logwindow */
+ void disableTemporaryFolderLogDir();
+
signals:
void logWindowLog(const QString &);
@@ -86,8 +104,9 @@ private:
int _logExpire;
bool _logDebug;
QScopedPointer<QTextStream> _logstream;
- QMutex _mutex;
+ mutable QMutex _mutex;
QString _logDirectory;
+ bool _temporaryFolderLogDir = false;
};
} // namespace OCC
diff --git a/src/libsync/networkjobs.cpp b/src/libsync/networkjobs.cpp
index a3881cd48..44fdc4553 100644
--- a/src/libsync/networkjobs.cpp
+++ b/src/libsync/networkjobs.cpp
@@ -879,6 +879,8 @@ void DetermineAuthTypeJob::start()
get->setFollowRedirects(false);
}
#else
+ Q_UNUSED(this)
+ Q_UNUSED(get)
Q_UNUSED(target)
#endif
});
diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp
index dafaec99c..3cd8ab0be 100644
--- a/src/libsync/owncloudpropagator.cpp
+++ b/src/libsync/owncloudpropagator.cpp
@@ -517,8 +517,7 @@ bool OwncloudPropagator::localFileNameClash(const QString &relFile)
re = false;
qCWarning(lcPropagator) << "No valid fileinfo";
} else {
- // Need to normalize to composited form because of
- // https://bugreports.qt-project.org/browse/QTBUG-39622
+ // Need to normalize to composited form because of QTBUG-39622/QTBUG-55896
const QString cName = fileInfo.canonicalFilePath().normalized(QString::NormalizationForm_C);
bool equal = (file == cName);
re = (!equal && !cName.endsWith(relFile, Qt::CaseSensitive));
@@ -840,10 +839,13 @@ void PropagatorCompositeJob::slotSubJobFinished(SyncFileItem::Status status)
ASSERT(i >= 0);
_runningJobs.remove(i);
+ // Any sub job error will cause the whole composite to fail. This is important
+ // for knowing whether to update the etag in PropagateDirectory, for example.
if (status == SyncFileItem::FatalError
|| status == SyncFileItem::NormalError
|| status == SyncFileItem::SoftError
- || status == SyncFileItem::DetailError) {
+ || status == SyncFileItem::DetailError
+ || status == SyncFileItem::BlacklistedError) {
_hasError = status;
}
diff --git a/src/libsync/owncloudpropagator.h b/src/libsync/owncloudpropagator.h
index c272a06d2..b4bc470d2 100644
--- a/src/libsync/owncloudpropagator.h
+++ b/src/libsync/owncloudpropagator.h
@@ -156,7 +156,7 @@ class PropagateItemJob : public PropagatorJob
{
Q_OBJECT
protected:
- void done(SyncFileItem::Status status, const QString &errorString = QString());
+ virtual void done(SyncFileItem::Status status, const QString &errorString = QString());
/*
* set a custom restore job message that is used if the restore job succeeded.
diff --git a/src/libsync/owncloudtheme.cpp b/src/libsync/owncloudtheme.cpp
index 873257c19..1e142b962 100644
--- a/src/libsync/owncloudtheme.cpp
+++ b/src/libsync/owncloudtheme.cpp
@@ -19,8 +19,6 @@
#ifndef TOKEN_AUTH_ONLY
#include <QPixmap>
#include <QIcon>
-#include <QStyle>
-#include <QApplication>
#endif
#include <QCoreApplication>
@@ -35,63 +33,13 @@ ownCloudTheme::ownCloudTheme()
{
}
-QString ownCloudTheme::configFileName() const
-{
- return QLatin1String("owncloud.cfg");
-}
-
-QString ownCloudTheme::about() const
-{
- QString devString;
- devString = tr("<p>Version %2. For more information visit <a href=\"%3\">https://%4</a></p>"
- "<p>For known issues and help, please visit: <a href=\"https://central.owncloud.org/c/desktop-client\">https://central.owncloud.org</a></p>"
- "<p><small>By Klaas Freitag, Daniel Molkentin, Olivier Goffart, Markus Götz, "
- " Jan-Christoph Borchardt, and others.</small></p>"
- "<p>Copyright ownCloud GmbH</p>"
- "<p>Licensed under the GNU General Public License (GPL) Version 2.0<br/>"
- "ownCloud and the ownCloud Logo are registered trademarks of ownCloud GmbH "
- "in the United States, other countries, or both.</p>")
- .arg(Utility::escape(MIRALL_VERSION_STRING),
- Utility::escape("https://" MIRALL_STRINGIFY(APPLICATION_DOMAIN)),
- Utility::escape(MIRALL_STRINGIFY(APPLICATION_DOMAIN)));
-
- devString += gitSHA1();
- return devString;
-}
-
#ifndef TOKEN_AUTH_ONLY
-QIcon ownCloudTheme::trayFolderIcon(const QString &) const
-{
- QPixmap fallback = qApp->style()->standardPixmap(QStyle::SP_FileDialogNewFolder);
- return QIcon::fromTheme("folder", fallback);
-}
-
-QIcon ownCloudTheme::applicationIcon() const
-{
- return themeIcon(QLatin1String("owncloud-icon"));
-}
-
-
-QVariant ownCloudTheme::customMedia(Theme::CustomMediaType type)
+QVariant ownCloudTheme::customMedia(CustomMediaType)
{
- if (type == Theme::oCSetupTop) {
- // return QCoreApplication::translate("ownCloudTheme",
- // "If you don't have an ownCloud server yet, "
- // "see <a href=\"https://owncloud.com\">owncloud.com</a> for more info.",
- // "Top text in setup wizard. Keep short!");
- return QVariant();
- } else {
- return QVariant();
- }
+ return QVariant();
}
-
#endif
-QString ownCloudTheme::helpUrl() const
-{
- return QString::fromLatin1("https://doc.owncloud.org/desktop/%1.%2/").arg(MIRALL_VERSION_MAJOR).arg(MIRALL_VERSION_MINOR);
-}
-
#ifndef TOKEN_AUTH_ONLY
QColor ownCloudTheme::wizardHeaderBackgroundColor() const
{
@@ -109,14 +57,4 @@ QPixmap ownCloudTheme::wizardHeaderLogo() const
}
#endif
-
-QString ownCloudTheme::appName() const
-{
- return QLatin1String("ownCloud");
-}
-
-QString ownCloudTheme::appNameGUI() const
-{
- return QLatin1String("ownCloud");
-}
}
diff --git a/src/libsync/owncloudtheme.h b/src/libsync/owncloudtheme.h
index 327c96e5f..99143fe93 100644
--- a/src/libsync/owncloudtheme.h
+++ b/src/libsync/owncloudtheme.h
@@ -28,18 +28,6 @@ class ownCloudTheme : public Theme
Q_OBJECT
public:
ownCloudTheme();
-
- QString configFileName() const Q_DECL_OVERRIDE;
- QString about() const Q_DECL_OVERRIDE;
-
-#ifndef TOKEN_AUTH_ONLY
- QIcon trayFolderIcon(const QString &) const Q_DECL_OVERRIDE;
- QIcon applicationIcon() const Q_DECL_OVERRIDE;
-#endif
- QString appName() const Q_DECL_OVERRIDE;
- QString appNameGUI() const Q_DECL_OVERRIDE;
-
- QString helpUrl() const Q_DECL_OVERRIDE;
#ifndef TOKEN_AUTH_ONLY
QVariant customMedia(CustomMediaType type) Q_DECL_OVERRIDE;
diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp
index 4579139ce..155eed8cc 100644
--- a/src/libsync/propagateupload.cpp
+++ b/src/libsync/propagateupload.cpp
@@ -471,7 +471,6 @@ void PropagateUploadFileCommon::slotPollFinished()
propagator()->_activeJobList.removeOne(this);
if (job->_item->_status != SyncFileItem::Success) {
- _finished = true;
done(job->_item->_status, job->_item->_errorString);
return;
}
@@ -479,6 +478,12 @@ void PropagateUploadFileCommon::slotPollFinished()
finalize();
}
+void PropagateUploadFileCommon::done(SyncFileItem::Status status, const QString &errorString)
+{
+ _finished = true;
+ PropagateItemJob::done(status, errorString);
+}
+
void PropagateUploadFileCommon::checkResettingErrors()
{
if (_item->_httpErrorCode == 412
@@ -561,7 +566,6 @@ void PropagateUploadFileCommon::abort(PropagatorJob::AbortType abortType)
// This function is used whenever there is an error occuring and jobs might be in progress
void PropagateUploadFileCommon::abortWithError(SyncFileItem::Status status, const QString &error)
{
- _finished = true;
abort(AbortType::Synchronous);
done(status, error);
}
@@ -610,8 +614,6 @@ QMap<QByteArray, QByteArray> PropagateUploadFileCommon::headers()
void PropagateUploadFileCommon::finalize()
{
- _finished = true;
-
// Update the quota, if known
auto quotaIt = propagator()->_folderQuota.find(QFileInfo(_item->_file).path());
if (quotaIt != propagator()->_folderQuota.end())
diff --git a/src/libsync/propagateupload.h b/src/libsync/propagateupload.h
index fbbbc14f1..c7e8b4854 100644
--- a/src/libsync/propagateupload.h
+++ b/src/libsync/propagateupload.h
@@ -257,6 +257,8 @@ private slots:
void slotPollFinished();
protected:
+ void done(SyncFileItem::Status status, const QString &errorString = QString()) override;
+
/**
* Prepares the abort e.g. connects proper signals and slots
* to the subjobs to abort asynchronously
diff --git a/src/libsync/propagateuploadng.cpp b/src/libsync/propagateuploadng.cpp
index a679887a5..13dfe513b 100644
--- a/src/libsync/propagateuploadng.cpp
+++ b/src/libsync/propagateuploadng.cpp
@@ -83,7 +83,7 @@ void PropagateUploadFileNG::doStartUpload()
propagator()->_activeJobList.append(this);
const SyncJournalDb::UploadInfo progressInfo = propagator()->_journal->getUploadInfo(_item->_file);
- if (progressInfo._valid && progressInfo._modtime == _item->_modtime) {
+ if (progressInfo._valid && progressInfo.isChunked() && progressInfo._modtime == _item->_modtime) {
_transferId = progressInfo._transferid;
auto url = chunkUrl();
auto job = new LsColJob(propagator()->account(), url, this);
@@ -98,7 +98,7 @@ void PropagateUploadFileNG::doStartUpload()
this, &PropagateUploadFileNG::slotPropfindIterate);
job->start();
return;
- } else if (progressInfo._valid) {
+ } else if (progressInfo._valid && progressInfo.isChunked()) {
// The upload info is stale. remove the stale chunks on the server
_transferId = progressInfo._transferid;
// Fire and forget. Any error will be ignored.
@@ -143,6 +143,12 @@ void PropagateUploadFileNG::slotPropfindFinished()
qCCritical(lcPropagateUpload) << "Inconsistency while resuming " << _item->_file
<< ": the size on the server (" << _sent << ") is bigger than the size of the file ("
<< _item->_size << ")";
+
+ // Wipe the old chunking data.
+ // Fire and forget. Any error will be ignored.
+ (new DeleteJob(propagator()->account(), chunkUrl(), this))->start();
+
+ propagator()->_activeJobList.append(this);
startNewUpload();
return;
}
@@ -274,6 +280,7 @@ void PropagateUploadFileNG::startNextChunk()
if (_currentChunkSize == 0) {
Q_ASSERT(_jobs.isEmpty()); // There should be no running job anymore
_finished = true;
+
// Finish with a MOVE
QString destination = QDir::cleanPath(propagator()->account()->url().path() + QLatin1Char('/')
+ propagator()->account()->davPath() + propagator()->_remoteFolder + _item->_file);
@@ -389,12 +396,12 @@ void PropagateUploadFileNG::slotPutFinished()
<< propagator()->_chunkSize << "bytes";
}
- bool finished = _sent == _item->_size;
+ _finished = _sent == _item->_size;
// Check if the file still exists
const QString fullFilePath(propagator()->getFilePath(_item->_file));
if (!FileSystem::fileExists(fullFilePath)) {
- if (!finished) {
+ if (!_finished) {
abortWithError(SyncFileItem::SoftError, tr("The local file was removed during sync."));
return;
} else {
@@ -405,13 +412,13 @@ void PropagateUploadFileNG::slotPutFinished()
// Check whether the file changed since discovery.
if (!FileSystem::verifyFileUnchanged(fullFilePath, _item->_size, _item->_modtime)) {
propagator()->_anotherSyncNeeded = true;
- if (!finished) {
+ if (!_finished) {
abortWithError(SyncFileItem::SoftError, tr("Local file changed during sync."));
return;
}
}
- if (!finished) {
+ if (!_finished) {
// Deletes an existing blacklist entry on successful chunk upload
if (_item->_hasBlacklistEntry) {
propagator()->_journal->wipeErrorBlacklistEntry(_item->_file);
diff --git a/src/libsync/propagateuploadv1.cpp b/src/libsync/propagateuploadv1.cpp
index 062b17634..8bd9489f5 100644
--- a/src/libsync/propagateuploadv1.cpp
+++ b/src/libsync/propagateuploadv1.cpp
@@ -43,7 +43,7 @@ void PropagateUploadFileV1::doStartUpload()
const SyncJournalDb::UploadInfo progressInfo = propagator()->_journal->getUploadInfo(_item->_file);
- if (progressInfo._valid && progressInfo._modtime == _item->_modtime
+ if (progressInfo._valid && progressInfo.isChunked() && progressInfo._modtime == _item->_modtime
&& (progressInfo._contentChecksum == _item->_checksumHeader || progressInfo._contentChecksum.isEmpty() || _item->_checksumHeader.isEmpty())) {
_startChunk = progressInfo._chunk;
_transferId = progressInfo._transferid;
@@ -55,7 +55,7 @@ void PropagateUploadFileV1::doStartUpload()
SyncJournalDb::UploadInfo pi;
pi._valid = true;
pi._chunk = 0;
- pi._transferid = _transferId;
+ pi._transferid = 0; // We set a null transfer id because it is not chunked.
pi._modtime = _item->_modtime;
pi._errorCount = 0;
pi._contentChecksum = _item->_checksumHeader;
@@ -206,12 +206,12 @@ void PropagateUploadFileV1::slotPutFinished()
// The server needs some time to process the request and provide us with a poll URL
if (_item->_httpErrorCode == 202) {
- _finished = true;
QString path = QString::fromUtf8(job->reply()->rawHeader("OC-Finish-Poll"));
if (path.isEmpty()) {
done(SyncFileItem::NormalError, tr("Poll URL missing"));
return;
}
+ _finished = true;
startPollJob(path);
return;
}
@@ -226,12 +226,12 @@ void PropagateUploadFileV1::slotPutFinished()
// yet, the upload can be stopped and an error can be displayed, because
// the server hasn't registered the new file yet.
QByteArray etag = getEtagFromReply(job->reply());
- bool finished = etag.length() > 0;
+ _finished = etag.length() > 0;
// Check if the file still exists
const QString fullFilePath(propagator()->getFilePath(_item->_file));
if (!FileSystem::fileExists(fullFilePath)) {
- if (!finished) {
+ if (!_finished) {
abortWithError(SyncFileItem::SoftError, tr("The local file was removed during sync."));
return;
} else {
@@ -242,7 +242,7 @@ void PropagateUploadFileV1::slotPutFinished()
// Check whether the file changed since discovery.
if (!FileSystem::verifyFileUnchanged(fullFilePath, _item->_size, _item->_modtime)) {
propagator()->_anotherSyncNeeded = true;
- if (!finished) {
+ if (!_finished) {
abortWithError(SyncFileItem::SoftError, tr("Local file changed during sync."));
// FIXME: the legacy code was retrying for a few seconds.
// and also checking that after the last chunk, and removed the file in case of INSTRUCTION_NEW
@@ -250,14 +250,13 @@ void PropagateUploadFileV1::slotPutFinished()
}
}
- if (!finished) {
+ if (!_finished) {
// Proceed to next chunk.
if (_currentChunk >= _chunkCount) {
if (!_jobs.empty()) {
// just wait for the other job to finish.
return;
}
- _finished = true;
done(SyncFileItem::NormalError, tr("The server did not acknowledge the last chunk. (No e-tag was present)"));
return;
}
@@ -287,9 +286,8 @@ void PropagateUploadFileV1::slotPutFinished()
startNextChunk();
return;
}
-
// the following code only happens after all chunks were uploaded.
- _finished = true;
+
// the file id should only be empty for new files up- or downloaded
QByteArray fid = job->reply()->rawHeader("OC-FileID");
if (!fid.isEmpty()) {
@@ -309,6 +307,7 @@ void PropagateUploadFileV1::slotPutFinished()
qCWarning(lcPropagateUpload) << "Server does not support X-OC-MTime" << job->reply()->rawHeader("X-OC-MTime");
// Well, the mtime was not set
done(SyncFileItem::SoftError, "Server does not support X-OC-MTime");
+ return;
}
finalize();
diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp
index 0f9907ca4..64481ca60 100644
--- a/src/libsync/syncengine.cpp
+++ b/src/libsync/syncengine.cpp
@@ -303,6 +303,8 @@ void SyncEngine::deleteStaleUploadInfos(const SyncFileItemVector &syncItems)
// Delete the stales chunk on the server.
if (account()->capabilities().chunkingNg()) {
foreach (uint transferId, ids) {
+ if (!transferId)
+ continue; // Was not a chunked upload
QUrl url = Utility::concatUrlPath(account()->url(), QLatin1String("remote.php/dav/uploads/") + account()->davUser() + QLatin1Char('/') + QString::number(transferId));
(new DeleteJob(account(), url, this))->start();
}
@@ -1630,10 +1632,10 @@ AccountPtr SyncEngine::account() const
return _account;
}
-void SyncEngine::setLocalDiscoveryOptions(LocalDiscoveryStyle style, std::set<QByteArray> dirs)
+void SyncEngine::setLocalDiscoveryOptions(LocalDiscoveryStyle style, std::set<QByteArray> paths)
{
_localDiscoveryStyle = style;
- _localDiscoveryPaths = std::move(dirs);
+ _localDiscoveryPaths = std::move(paths);
}
bool SyncEngine::shouldDiscoverLocally(const QByteArray &path) const
diff --git a/src/libsync/syncengine.h b/src/libsync/syncengine.h
index f43e2f26b..e00034f4d 100644
--- a/src/libsync/syncengine.h
+++ b/src/libsync/syncengine.h
@@ -104,7 +104,7 @@ public:
/**
* Control whether local discovery should read from filesystem or db.
*
- * If style is DatabaseAndFilesystem, dirs a set of file paths relative to
+ * If style is DatabaseAndFilesystem, paths a set of file paths relative to
* the synced folder. All the parent directories of these paths will not
* be read from the db and scanned on the filesystem.
*
@@ -112,7 +112,7 @@ public:
* revert afterwards. Use _lastLocalDiscoveryStyle to discover the last
* sync's style.
*/
- void setLocalDiscoveryOptions(LocalDiscoveryStyle style, std::set<QByteArray> dirs = {});
+ void setLocalDiscoveryOptions(LocalDiscoveryStyle style, std::set<QByteArray> paths = {});
/**
* Returns whether the given folder-relative path should be locally discovered
diff --git a/src/libsync/syncfileitem.h b/src/libsync/syncfileitem.h
index 4272bf9e5..88421c39d 100644
--- a/src/libsync/syncfileitem.h
+++ b/src/libsync/syncfileitem.h
@@ -75,10 +75,9 @@ public:
/** For files whose errors were blacklisted
*
* If an file is blacklisted due to an error it isn't even reattempted. These
- * errors should appear in the issues tab, but not on the account settings and
- * should not cause the sync run to fail.
+ * errors should appear in the issues tab but should be silent otherwise.
*
- * A DetailError that doesn't cause sync failure.
+ * A SoftError caused by blacklisting.
*/
BlacklistedError
};
diff --git a/src/libsync/theme.cpp b/src/libsync/theme.cpp
index e9e389fd6..da6e28344 100644
--- a/src/libsync/theme.cpp
+++ b/src/libsync/theme.cpp
@@ -20,6 +20,8 @@
#include <QtCore>
#ifndef TOKEN_AUTH_ONLY
#include <QtGui>
+#include <QStyle>
+#include <QApplication>
#endif
#include <QSslSocket>
@@ -105,12 +107,16 @@ QString Theme::version() const
return MIRALL_VERSION_STRING;
}
+QString Theme::configFileName() const
+{
+ return QStringLiteral(APPLICATION_EXECUTABLE ".cfg");
+}
+
#ifndef TOKEN_AUTH_ONLY
-QIcon Theme::trayFolderIcon(const QString &backend) const
+QIcon Theme::applicationIcon() const
{
- Q_UNUSED(backend)
- return applicationIcon();
+ return themeIcon(QStringLiteral(APPLICATION_ICON_NAME "-icon"));
}
/*
@@ -217,6 +223,11 @@ QString Theme::defaultServerFolder() const
return QLatin1String("/");
}
+QString Theme::helpUrl() const
+{
+ return QString::fromLatin1("https://doc.owncloud.org/desktop/%1.%2/").arg(MIRALL_VERSION_MAJOR).arg(MIRALL_VERSION_MINOR);
+}
+
QString Theme::overrideServerUrl() const
{
return QString();
@@ -311,21 +322,21 @@ QString Theme::gitSHA1() const
QString Theme::about() const
{
- QString re;
- re = tr("<p>Version %1. For more information please visit <a href='%2'>%3</a>.</p>")
- .arg(MIRALL_VERSION_STRING)
- .arg("http://" MIRALL_STRINGIFY(APPLICATION_DOMAIN))
- .arg(MIRALL_STRINGIFY(APPLICATION_DOMAIN));
-
- re += tr("<p>Copyright ownCloud GmbH</p>");
- re += tr("<p>Distributed by %1 and licensed under the GNU General Public License (GPL) Version 2.0.<br/>"
- "%2 and the %2 logo are registered trademarks of %1 in the "
- "United States, other countries, or both.</p>")
- .arg(APPLICATION_VENDOR)
- .arg(APPLICATION_NAME);
-
- re += gitSHA1();
- return re;
+ QString devString;
+ devString = tr("<p>Version %2. For more information visit <a href=\"%3\">https://%4</a></p>"
+ "<p>For known issues and help, please visit: <a href=\"https://central.owncloud.org/c/desktop-client\">https://central.owncloud.org</a></p>"
+ "<p><small>By Klaas Freitag, Daniel Molkentin, Olivier Goffart, Markus Götz, "
+ " Jan-Christoph Borchardt, and others.</small></p>"
+ "<p>Copyright ownCloud GmbH</p>"
+ "<p>Licensed under the GNU General Public License (GPL) Version 2.0<br/>"
+ "ownCloud and the ownCloud Logo are registered trademarks of ownCloud GmbH "
+ "in the United States, other countries, or both.</p>")
+ .arg(Utility::escape(MIRALL_VERSION_STRING),
+ Utility::escape("https://" MIRALL_STRINGIFY(APPLICATION_DOMAIN)),
+ Utility::escape(MIRALL_STRINGIFY(APPLICATION_DOMAIN)));
+
+ devString += gitSHA1();
+ return devString;
}
#ifndef TOKEN_AUTH_ONLY
diff --git a/src/libsync/theme.h b/src/libsync/theme.h
index c2cd4922f..90ddd7ef1 100644
--- a/src/libsync/theme.h
+++ b/src/libsync/theme.h
@@ -84,24 +84,19 @@ public:
* @brief configFileName
* @return the name of the config file.
*/
- virtual QString configFileName() const = 0;
+ virtual QString configFileName() const;
#ifndef TOKEN_AUTH_ONLY
static QString hidpiFileName(const QString &fileName, QPaintDevice *dev = 0);
/**
- * the icon that is shown in the tray context menu left of the folder name
- */
- virtual QIcon trayFolderIcon(const QString &) const;
-
- /**
* get an sync state icon
*/
virtual QIcon syncStateIcon(SyncResult::Status, bool sysTray = false, bool sysTrayMenuVisible = false) const;
virtual QIcon folderDisabledIcon() const;
virtual QIcon folderOfflineIcon(bool sysTray = false, bool sysTrayMenuVisible = false) const;
- virtual QIcon applicationIcon() const = 0;
+ virtual QIcon applicationIcon() const;
#endif
virtual QString statusHeaderText(SyncResult::Status) const;
@@ -118,9 +113,11 @@ public:
virtual bool multiAccount() const;
/**
- * URL to help file
+ * URL to documentation.
+ * This is opened in the browser when the "Help" action is selected from the tray menu.
+ * (If it is an empty stringn the action is removed from the menu. Defaults to ownCloud's help)
*/
- virtual QString helpUrl() const { return QString(); }
+ virtual QString helpUrl() const;
/**
* Setting a value here will pre-define the server url.