From c917251e9ebeeaf798ebe2096b9f86af6d8040c6 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 9 Apr 2015 15:06:48 +0200 Subject: [PATCH 01/30] Reconcile: Fix clang warning csync_reconcile.c:159:26: warning: address of array 'tmp->path' will always evaluate to 'true' [-Wpointer-bool-conversion] if( tmp->path ) { ~~ ~~~~~^~~~ csync_file_stat_s::path is an array so it is never null What was meant here is to check if the string was not empty --- csync/src/csync_reconcile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csync/src/csync_reconcile.c b/csync/src/csync_reconcile.c index 8ceb8577b..861910f5d 100644 --- a/csync/src/csync_reconcile.c +++ b/csync/src/csync_reconcile.c @@ -156,8 +156,8 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) { } if( tmp ) { - if( tmp->path ) { - len = strlen( tmp->path ); + len = strlen( tmp->path ); + if( len > 0 ) { h = c_jhash64((uint8_t *) tmp->path, len, 0); /* First, check that the file is NOT in our tree (another file with the same name was added) */ node = c_rbtree_find(ctx->current == REMOTE_REPLICA ? ctx->remote.tree : ctx->local.tree, &h); From d9ea6936ab83b88f4bd3f93734119fdeb6018725 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Thu, 9 Apr 2015 13:38:52 +0200 Subject: [PATCH 02/30] Handle redirect of auth request. #3082 --- src/gui/owncloudsetupwizard.cpp | 54 ++++++++++++++++++++++++++++++--- src/gui/owncloudsetupwizard.h | 5 +-- src/libsync/networkjobs.h | 3 ++ 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/gui/owncloudsetupwizard.cpp b/src/gui/owncloudsetupwizard.cpp index 509b26293..4b06f2f1f 100644 --- a/src/gui/owncloudsetupwizard.cpp +++ b/src/gui/owncloudsetupwizard.cpp @@ -217,11 +217,53 @@ void OwncloudSetupWizard::testOwnCloudConnect() auto *job = new PropfindJob(account, "/", this); job->setIgnoreCredentialFailure(true); job->setProperties(QList() << "getlastmodified"); - connect(job, SIGNAL(result(QVariantMap)), _ocWizard, SLOT(successfulStep())); - connect(job, SIGNAL(networkError(QNetworkReply*)), this, SLOT(slotConnectionCheck(QNetworkReply*))); + connect(job, SIGNAL(result(QVariantMap)), _ocWizard, SLOT(successfulStep())); + connect(job, SIGNAL(finishedWithError()), this, SLOT(slotAuthError())); + connect(job, SIGNAL(networkError(QNetworkReply*)), this, SLOT(slotAuthNetworkError(QNetworkReply*))); job->start(); } +void OwncloudSetupWizard::slotAuthError() +{ + QString errorMsg; + + PropfindJob* job = qobject_cast(sender()); + if (!job) { + qWarning() << "Can't check for authed redirects. This slot should be invoked from PropfindJob!"; + return; + } + + // If there were redirects on the *authed* requests, also store + // the updated server URL, similar to redirects on status.php. + QUrl redirectUrl = job->reply()->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + if (!redirectUrl.isEmpty()) { + qDebug() << "authed request was redirected to" << redirectUrl.toString(); + + // strip the expected path + QString path = redirectUrl.path(); + static QString expectedPath = "/remote.php/webdav/"; + if (path.endsWith(expectedPath)) { + path.chop(expectedPath.size()); + redirectUrl.setPath(path); + + qDebug() << "setting account url to" << redirectUrl.toString(); + _ocWizard->account()->setUrl(redirectUrl); + testOwnCloudConnect(); + return; + } else { + errorMsg = tr("The authenticated request to the server was redirected to " + "'%1'. The URL is bad, the server is misconfigured.") + .arg(redirectUrl.toString()); + } + } + + if (errorMsg.isEmpty()) { + errorMsg = tr("There was an invalid response to an authenticated webdav request"); + } + _ocWizard->displayError(errorMsg, false); + _ocWizard->show(); +} + bool OwncloudSetupWizard::checkDowngradeAdvised(QNetworkReply* reply) { if(reply->url().scheme() != QLatin1String("https")) { @@ -245,7 +287,7 @@ bool OwncloudSetupWizard::checkDowngradeAdvised(QNetworkReply* reply) return true; } -void OwncloudSetupWizard::slotConnectionCheck(QNetworkReply* reply) +void OwncloudSetupWizard::slotAuthNetworkError(QNetworkReply* reply) { QString msg = reply->errorString(); switch (reply->error()) { @@ -294,7 +336,7 @@ void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFo } if (nextStep) { EntityExistsJob *job = new EntityExistsJob(_ocWizard->account(), _ocWizard->account()->davPath() + remoteFolder, this); - connect(job, SIGNAL(exists(QNetworkReply*)), SLOT(slotAuthCheckReply(QNetworkReply*))); + connect(job, SIGNAL(exists(QNetworkReply*)), SLOT(slotRemoteFolderExists(QNetworkReply*))); job->start(); } else { finalizeSetup( false ); @@ -302,7 +344,7 @@ void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFo } // ### TODO move into EntityExistsJob once we decide if/how to return gui strings from jobs -void OwncloudSetupWizard::slotAuthCheckReply(QNetworkReply *reply) +void OwncloudSetupWizard::slotRemoteFolderExists(QNetworkReply *reply) { bool ok = true; QString error; @@ -522,8 +564,10 @@ bool DetermineAuthTypeJob::finished() } else if (redirection.toString().endsWith(account()->davPath())) { // do a new run _redirects++; + resetTimeout(); setReply(getRequest(redirection)); setupConnections(reply()); + return false; // don't discard } else { QRegExp shibbolethyWords("SAML|wayf"); diff --git a/src/gui/owncloudsetupwizard.h b/src/gui/owncloudsetupwizard.h index 961d63f00..9bbb69ddc 100644 --- a/src/gui/owncloudsetupwizard.h +++ b/src/gui/owncloudsetupwizard.h @@ -62,10 +62,11 @@ private slots: void slotNoOwnCloudFoundAuthTimeout(const QUrl&url); void slotConnectToOCUrl(const QString&); - void slotConnectionCheck(QNetworkReply*); + void slotAuthNetworkError(QNetworkReply*); + void slotAuthError(); void slotCreateLocalAndRemoteFolders(const QString&, const QString&); - void slotAuthCheckReply(QNetworkReply*); + void slotRemoteFolderExists(QNetworkReply*); void slotCreateRemoteFolderFinished(QNetworkReply::NetworkError); void slotAssistantFinished( int ); void slotSkipFolderConfiguration(); diff --git a/src/libsync/networkjobs.h b/src/libsync/networkjobs.h index 155e5195a..13f966516 100644 --- a/src/libsync/networkjobs.h +++ b/src/libsync/networkjobs.h @@ -94,6 +94,9 @@ protected: QElapsedTimer _durationTimer; quint64 _duration; bool _timedout; // set to true when the timeout slot is recieved + + // Automatically follows redirects. Note that this only works for + // GET requests that don't set up any HTTP body or other flags. bool _followRedirects; private slots: From 57ac1d9ea2688d3f362b23b0e8bfb0e2b19ac7b4 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 10 Apr 2015 09:24:25 +0200 Subject: [PATCH 03/30] AuthRedirect: Use the configured DAV path. #3082 --- src/gui/owncloudsetupwizard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/owncloudsetupwizard.cpp b/src/gui/owncloudsetupwizard.cpp index 4b06f2f1f..e5759b94a 100644 --- a/src/gui/owncloudsetupwizard.cpp +++ b/src/gui/owncloudsetupwizard.cpp @@ -241,7 +241,7 @@ void OwncloudSetupWizard::slotAuthError() // strip the expected path QString path = redirectUrl.path(); - static QString expectedPath = "/remote.php/webdav/"; + static QString expectedPath = "/" + _ocWizard->account()->davPath(); if (path.endsWith(expectedPath)) { path.chop(expectedPath.size()); redirectUrl.setPath(path); From 9d8fc4aa4d1a69a95909ebeed0a903353baa02f0 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 10 Apr 2015 12:11:35 +0200 Subject: [PATCH 04/30] ProtocolWidget: Fix adding of seconds. #2535 --- src/gui/protocolwidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/protocolwidget.cpp b/src/gui/protocolwidget.cpp index d4b6c2bfa..85e3f4102 100644 --- a/src/gui/protocolwidget.cpp +++ b/src/gui/protocolwidget.cpp @@ -169,8 +169,8 @@ QString ProtocolWidget::timeString(QDateTime dt, QLocale::FormatType format) con { const QLocale loc = QLocale::system(); QString dtFormat = loc.dateTimeFormat(format); - static const QRegExp re("HH:mm(?!:ss)"); - dtFormat.replace(re, "HH:mm:ss"); + static const QRegExp re("(HH|H|hh|h):mm(?!:s)"); + dtFormat.replace(re, "\\1:mm:ss"); return loc.toString(dt, dtFormat); } From 785b59e6d1cef30f0185276b5538eb616d50b2b0 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Sat, 11 Apr 2015 02:18:26 -0400 Subject: [PATCH 05/30] [tx-robot] updated from transifex --- translations/mirall_en.ts | 56 +++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/translations/mirall_en.ts b/translations/mirall_en.ts index 27983eaea..8f6ae119d 100644 --- a/translations/mirall_en.ts +++ b/translations/mirall_en.ts @@ -1232,109 +1232,119 @@ It is not advisable to use it. - + + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. + + + + + There was an invalid response to an authenticated webdav request + + + + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> - + Creating local sync folder %1... - + ok - + failed. - + Could not create local folder %1 - + No remote folder specified! - + Error: %1 - + creating folder on ownCloud: %1 - + Remote folder %1 created successfully. - + The remote folder %1 already exists. Connecting it for syncing. - - + + The folder creation resulted in HTTP error code %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. - + Successfully connected to %1! - + Connection to %1 could not be established. Please check again. - + Folder rename failed - + Can't remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> From 454d5b575c1e73c822b8cd096f268da1b3ba5645 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Sun, 12 Apr 2015 02:18:27 -0400 Subject: [PATCH 06/30] [tx-robot] updated from transifex --- translations/client_el.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/translations/client_el.ts b/translations/client_el.ts index 3b2f37c4f..e72c2c14f 100644 --- a/translations/client_el.ts +++ b/translations/client_el.ts @@ -1362,7 +1362,7 @@ It is not advisable to use it. Invalid JSON reply from the poll URL - + Λανθασμένη απάντηση JSON από την ιστοσελίδα poll @@ -1552,7 +1552,7 @@ It is not advisable to use it. Poll URL missing - + Η διεύθυνση poll URL λείπει From ec81cdefb0c133d2cc8f6fac27dad60b258bd430 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Sun, 12 Apr 2015 12:35:40 +0200 Subject: [PATCH 07/30] Networkjobs: Only log a subset of the account url. This avoids disclosing of user and password in the logfile which can happen in some cases. --- binary | 2 +- src/libsync/networkjobs.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/binary b/binary index 01d73965d..139acd195 160000 --- a/binary +++ b/binary @@ -1 +1 @@ -Subproject commit 01d73965dc8b862d1b2310d3ef801c297b697ec7 +Subproject commit 139acd195bd74f69ff93d37cba7eec62fec77287 diff --git a/src/libsync/networkjobs.cpp b/src/libsync/networkjobs.cpp index 5bd4144be..96edf8ddd 100644 --- a/src/libsync/networkjobs.cpp +++ b/src/libsync/networkjobs.cpp @@ -223,7 +223,10 @@ void AbstractNetworkJob::start() _durationTimer.start(); _duration = 0; - qDebug() << "!!!" << metaObject()->className() << "created for" << account()->url() << "querying" << path(); + const QUrl url = account()->url(); + const QString displayUrl = QString( "%1://%2%3").arg(url.scheme()).arg(url.host()).arg(url.path()); + + qDebug() << "!!!" << metaObject()->className() << "created for" << displayUrl << "+" << path(); } void AbstractNetworkJob::slotTimeout() From 7b99877c68c9ebedd5bd1bceece415e9cd64bd56 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Sun, 12 Apr 2015 12:59:25 +0200 Subject: [PATCH 08/30] owncloudcmd: Filter out empty lines in selectivesync --- src/cmd/cmd.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cmd/cmd.cpp b/src/cmd/cmd.cpp index 0b8636bea..55d924b6e 100644 --- a/src/cmd/cmd.cpp +++ b/src/cmd/cmd.cpp @@ -445,7 +445,9 @@ restart_sync: if (!f.open(QFile::ReadOnly)) { qCritical() << "Could not open file containing the list of unsynced folders: " << options.unsyncedfolders; } else { - selectiveSyncList = QString::fromUtf8(f.readAll()).split('\n'); + // filter out empty lines and comments + selectiveSyncList = QString::fromUtf8(f.readAll()).split('\n').filter(QRegExp("\\S+")).filter(QRegExp("^[^#]")); + for (int i = 0; i < selectiveSyncList.count(); ++i) { if (!selectiveSyncList.at(i).endsWith(QLatin1Char('/'))) { selectiveSyncList[i].append(QLatin1Char('/')); From 9d88ef543282c63d89bf9d17bba674e0968f650e Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 13 Apr 2015 13:03:46 +0200 Subject: [PATCH 09/30] Restore submodule --- binary | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/binary b/binary index 139acd195..1fb9ddfa9 160000 --- a/binary +++ b/binary @@ -1 +1 @@ -Subproject commit 139acd195bd74f69ff93d37cba7eec62fec77287 +Subproject commit 1fb9ddfa9a9a1b4dbc447eee10dbed89172d968a From fa80a006b85cf1274ef700eaf2e7e5b0fc4947c2 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 13 Apr 2015 14:58:25 +0200 Subject: [PATCH 10/30] CSync: Log if file_id is too long --- csync/src/vio/csync_vio_file_stat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/csync/src/vio/csync_vio_file_stat.c b/csync/src/vio/csync_vio_file_stat.c index ffbd102fc..7b640159b 100644 --- a/csync/src/vio/csync_vio_file_stat.c +++ b/csync/src/vio/csync_vio_file_stat.c @@ -20,6 +20,7 @@ #include "c_lib.h" #include "csync.h" +#include "csync_log.h" csync_vio_file_stat_t *csync_vio_file_stat_new(void) { csync_vio_file_stat_t *file_stat = (csync_vio_file_stat_t *) c_malloc(sizeof(csync_vio_file_stat_t)); @@ -70,6 +71,7 @@ void csync_vio_file_stat_set_file_id( csync_vio_file_stat_t *dst, const char* sr void csync_vio_set_file_id( char* dst, const char *src ) { if( src && dst ) { if( strlen(src) > FILE_ID_BUF_SIZE ) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Ignoring file_id because it is too long: %s", src); strcpy(dst, ""); } else { strcpy(dst, src); From 0634a4d0c6eec0ff14f1c9df4d72f73ad809250d Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 13 Apr 2015 15:10:04 +0200 Subject: [PATCH 11/30] Discovery: Add a sanity check when results are parsed --- src/libsync/discoveryphase.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp index b8c580a12..9c36c1286 100644 --- a/src/libsync/discoveryphase.cpp +++ b/src/libsync/discoveryphase.cpp @@ -285,6 +285,13 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(QString file,QMap void DiscoverySingleDirectoryJob::lsJobFinishedWithoutErrorSlot() { + if (!_ignoredFirst) { + // This is a sanity check, if we haven't _ignoredFirst then it means we never received any directoryListingIteratedSlot + // which means somehow the server XML was bogus + emit finishedWithError(ERRNO_WRONG_CONTENT, QLatin1String("Server error: PROPFIND reply is not XML formatted!")); + deleteLater(); + return; + } emit etagConcatenation(_etagConcatenation); emit finishedWithResult(_results); deleteLater(); From 2dbd27af76f748ebfdcbcd7954005075c878b2da Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 13 Apr 2015 15:36:07 +0200 Subject: [PATCH 12/30] Discovery: Initialize error with EIO --- src/libsync/discoveryphase.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp index 9c36c1286..2d3981e21 100644 --- a/src/libsync/discoveryphase.cpp +++ b/src/libsync/discoveryphase.cpp @@ -303,7 +303,7 @@ void DiscoverySingleDirectoryJob::lsJobFinishedWithErrorSlot(QNetworkReply *r) int httpCode = r->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); QString httpReason = r->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(); QString msg = r->errorString(); - int errnoCode = 0; + int errnoCode = EIO; // Something went wrong qDebug() << Q_FUNC_INFO << r->errorString() << httpCode << r->error(); if (httpCode != 0 && httpCode != 207) { errnoCode = get_errno_from_http_errcode(httpCode, httpReason); @@ -312,6 +312,8 @@ void DiscoverySingleDirectoryJob::lsJobFinishedWithErrorSlot(QNetworkReply *r) } else if (!contentType.contains("application/xml; charset=utf-8")) { msg = QLatin1String("Server error: PROPFIND reply is not XML formatted!"); errnoCode = ERRNO_WRONG_CONTENT; + } else { + // Default keep at EIO, see above } emit finishedWithError(errnoCode, msg); From 9d5f5ea3bc10772f6a803aa4c1e66b5a0105e242 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 13 Apr 2015 15:49:33 +0200 Subject: [PATCH 13/30] Discovery: Initialize error with EIO in constructor This is safer, initializing it in remote_vio_opendir_hook was enough though. --- src/libsync/discoveryphase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsync/discoveryphase.h b/src/libsync/discoveryphase.h index 5ceb477e3..43dd644b6 100644 --- a/src/libsync/discoveryphase.h +++ b/src/libsync/discoveryphase.h @@ -63,7 +63,7 @@ struct DiscoveryDirectoryResult { int code; QList list; int listIndex; - DiscoveryDirectoryResult() : code(0), listIndex(0) { } + DiscoveryDirectoryResult() : code(EIO), listIndex(0) { } }; // Run in the main thread, reporting to the DiscoveryJobMainThread object From 9ffacd4ecdb60f5146cc628bf53acf74b9264dd4 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 13 Apr 2015 16:04:24 +0200 Subject: [PATCH 14/30] Discovery: Explicitly check for XML parser errors ..instead of relying that our state machine does not do anything in that case. --- src/libsync/networkjobs.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/libsync/networkjobs.cpp b/src/libsync/networkjobs.cpp index 96edf8ddd..e8a571a34 100644 --- a/src/libsync/networkjobs.cpp +++ b/src/libsync/networkjobs.cpp @@ -400,6 +400,9 @@ static QString readContentsAsString(QXmlStreamReader &reader) { return result; } +// TODO: Instead of doing all in this slot, we should iteratively parse in readyRead(). This +// would allow us to be more asynchronous in processing while data is coming from the network, +// not in all in one big blobb at the end. bool LsColJob::finished() { QString contentType = reply()->header(QNetworkRequest::ContentTypeHeader).toString(); @@ -479,13 +482,20 @@ bool LsColJob::finished() } } } - emit directoryListingSubfolders(folders); - emit finishedWithoutError(); + + if (reader.hasError()) { + // XML Parser error? Whatever had been emitted before will come as directoryListingIterated + qDebug() << "ERROR" << reader.errorString(); + emit finishedWithError(reply()); + } else { + emit directoryListingSubfolders(folders); + emit finishedWithoutError(); + } } else if (httpCode == 207) { // wrong content type emit finishedWithError(reply()); } else { - // wrong HTTP code + // wrong HTTP code or any other network error emit finishedWithError(reply()); } return true; From 21594e9aa9b6ec38cca127763051d091283111c8 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 13 Apr 2015 18:27:28 +0200 Subject: [PATCH 15/30] Translations: Try to add Serbian #3083 --- translations/client_sr.ts | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 translations/client_sr.ts diff --git a/translations/client_sr.ts b/translations/client_sr.ts new file mode 100644 index 000000000..5b95e89fb --- /dev/null +++ b/translations/client_sr.ts @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 88488c695cebcbe385589c0b7c88ec215d0ea25b Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Tue, 14 Apr 2015 02:18:33 -0400 Subject: [PATCH 16/30] [tx-robot] updated from transifex --- translations/client_sv.ts | 8 ++++---- translations/mirall_en.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/translations/client_sv.ts b/translations/client_sv.ts index ea489bbf1..acaa8b659 100644 --- a/translations/client_sv.ts +++ b/translations/client_sv.ts @@ -668,7 +668,7 @@ Detta kan bero på att konfigurationen för mappen ändrats, eller att alla file Choose What to Sync: You can optionally deselect remote subfolders you do not wish to synchronize. - + Välj Vad du vill Synka: Du har även möjlighet att avmarkera mappar på servern som du ej vill synkronisera. @@ -733,7 +733,7 @@ Detta kan bero på att konfigurationen för mappen ändrats, eller att alla file Show crash reporter - + Visa kraschrapporteringsverktyg @@ -1420,7 +1420,7 @@ Det är inte lämpligt använda den. Continue blacklisting: - + Fortsätt svartlista: @@ -1477,7 +1477,7 @@ Det är inte lämpligt använda den. Wrong HTTP code returned by server. Expected 204, but recieved "%1 %2". - + Fel HTTP-kod returnerades av servern. Förväntade 204, men tog emot "%1 %2". diff --git a/translations/mirall_en.ts b/translations/mirall_en.ts index 8f6ae119d..a1ebcf8f3 100644 --- a/translations/mirall_en.ts +++ b/translations/mirall_en.ts @@ -341,7 +341,7 @@ Total time left %5 OCC::DiscoveryMainThread - + Aborted by the user From c579069071ec55a4d3a2d2174fa48bac96cde9d4 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Tue, 14 Apr 2015 13:41:51 +0200 Subject: [PATCH 17/30] LsColXMLParser: let parse return bool. --- src/libsync/networkjobs.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/libsync/networkjobs.h b/src/libsync/networkjobs.h index 13f966516..f3bc5d1bf 100644 --- a/src/libsync/networkjobs.h +++ b/src/libsync/networkjobs.h @@ -132,6 +132,21 @@ private slots: /** * @brief The LsColJob class */ +class OWNCLOUDSYNC_EXPORT LsColXMLParser : public QObject { + Q_OBJECT +public: + explicit LsColXMLParser(); + + bool parse(const QByteArray &xml, QHash *sizes); + +signals: + void directoryListingSubfolders(const QStringList &items); + void directoryListingIterated(const QString &name, const QMap &properties); + void finishedWithError(QNetworkReply *reply); + void finishedWithoutError(); + +}; + class OWNCLOUDSYNC_EXPORT LsColJob : public AbstractNetworkJob { Q_OBJECT public: From 4283ab3b44e8801a9707ff24baf2dd7b1d6e09b8 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Tue, 14 Apr 2015 08:36:17 +0200 Subject: [PATCH 18/30] LsColJob: Create a XML parser object for better unit testability. --- src/libsync/networkjobs.cpp | 233 ++++++++++++++++++++---------------- 1 file changed, 130 insertions(+), 103 deletions(-) diff --git a/src/libsync/networkjobs.cpp b/src/libsync/networkjobs.cpp index e8a571a34..18837ea8b 100644 --- a/src/libsync/networkjobs.cpp +++ b/src/libsync/networkjobs.cpp @@ -320,6 +320,124 @@ bool MkColJob::finished() return true; } +/*********************************************************************************************/ +// supposed to read when pointing to .. +static QString readContentsAsString(QXmlStreamReader &reader) { + QString result; + int level = 0; + do { + QXmlStreamReader::TokenType type = reader.readNext(); + if (type == QXmlStreamReader::StartElement) { + level++; + result += "<" + reader.name().toString() + ">"; + } else if (type == QXmlStreamReader::Characters) { + result += reader.text(); + } else if (type == QXmlStreamReader::EndElement) { + level--; + if (level < 0) { + break; + } + result += ""; + } + + } while (!reader.atEnd()); + return result; +} + + +LsColXMLParser::LsColXMLParser() +{ + +} + +bool LsColXMLParser::parse( const QByteArray& xml, QHash *sizes) +{ + // Parse DAV response + QXmlStreamReader reader(xml); + reader.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("d", "DAV:")); + + QStringList folders; + QString currentHref; + QMap currentTmpProperties; + QMap currentHttp200Properties; + bool currentPropsHaveHttp200 = false; + bool insidePropstat = false; + bool insideProp = false; + + while (!reader.atEnd()) { + QXmlStreamReader::TokenType type = reader.readNext(); + QString name = reader.name().toString(); + // Start elements with DAV: + if (type == QXmlStreamReader::StartElement && reader.namespaceUri() == QLatin1String("DAV:")) { + if (name == QLatin1String("href")) { + currentHref = QUrl::fromPercentEncoding(reader.readElementText().toUtf8()); + } else if (name == QLatin1String("response")) { + } else if (name == QLatin1String("propstat")) { + insidePropstat = true; + } else if (name == QLatin1String("status") && insidePropstat) { + QString httpStatus = reader.readElementText(); + if (httpStatus.startsWith("HTTP/1.1 200")) { + currentPropsHaveHttp200 = true; + } else { + currentPropsHaveHttp200 = false; + } + } else if (name == QLatin1String("prop")) { + insideProp = true; + continue; + } + } + + if (type == QXmlStreamReader::StartElement && insidePropstat && insideProp) { + // All those elements are properties + QString propertyContent = readContentsAsString(reader); + if (name == QLatin1String("resourcetype") && propertyContent.contains("collection")) { + folders.append(currentHref); + } else if (name == QLatin1String("quota-used-bytes")) { + bool ok = false; + auto s = propertyContent.toLongLong(&ok); + if (ok && sizes) { + sizes->insert(currentHref, s); + } + } + currentTmpProperties.insert(reader.name().toString(), propertyContent); + } + + // End elements with DAV: + if (type == QXmlStreamReader::EndElement) { + if (reader.namespaceUri() == QLatin1String("DAV:")) { + if (reader.name() == "response") { + if (currentHref.endsWith('/')) { + currentHref.chop(1); + } + emit directoryListingIterated(currentHref, currentHttp200Properties); + currentHref.clear(); + currentHttp200Properties.clear(); + } else if (reader.name() == "propstat") { + insidePropstat = false; + if (currentPropsHaveHttp200) { + currentHttp200Properties = QMap(currentTmpProperties); + } + currentTmpProperties.clear(); + currentPropsHaveHttp200 = false; + } else if (reader.name() == "prop") { + insideProp = false; + } + } + } + } + + if (reader.hasError()) { + // XML Parser error? Whatever had been emitted before will come as directoryListingIterated + qDebug() << "ERROR" << reader.errorString(); + return false; + } else { + emit directoryListingSubfolders(folders); + emit finishedWithoutError(); + } + return true; + +} + /*********************************************************************************************/ LsColJob::LsColJob(AccountPtr account, const QString &path, QObject *parent) @@ -377,29 +495,6 @@ void LsColJob::start() AbstractNetworkJob::start(); } -// supposed to read when pointing to .. -static QString readContentsAsString(QXmlStreamReader &reader) { - QString result; - int level = 0; - do { - QXmlStreamReader::TokenType type = reader.readNext(); - if (type == QXmlStreamReader::StartElement) { - level++; - result += "<" + reader.name().toString() + ">"; - } else if (type == QXmlStreamReader::Characters) { - result += reader.text(); - } else if (type == QXmlStreamReader::EndElement) { - level--; - if (level < 0) { - break; - } - result += ""; - } - - } while (!reader.atEnd()); - return result; -} - // TODO: Instead of doing all in this slot, we should iteratively parse in readyRead(). This // would allow us to be more asynchronous in processing while data is coming from the network, // not in all in one big blobb at the end. @@ -408,88 +503,19 @@ bool LsColJob::finished() QString contentType = reply()->header(QNetworkRequest::ContentTypeHeader).toString(); int httpCode = reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (httpCode == 207 && contentType.contains("application/xml; charset=utf-8")) { - // Parse DAV response - QByteArray xml = reply()->readAll(); - QXmlStreamReader reader(xml); - reader.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("d", "DAV:")); + LsColXMLParser parser; + connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)), + this, SIGNAL(directoryListingSubfolders(const QStringList&)) ); + connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap&)), + this, SIGNAL(directoryListingIterated(const QString&, const QMap&)) ); + connect( &parser, SIGNAL(finishedWithError(QNetworkReply *)), + this, SIGNAL(finishedWithError(QNetworkReply *)) ); + connect( &parser, SIGNAL(finishedWithoutError()), + this, SIGNAL(finishedWithoutError()) ); - QStringList folders; - QString currentHref; - QMap currentTmpProperties; - QMap currentHttp200Properties; - bool currentPropsHaveHttp200 = false; - bool insidePropstat = false; - bool insideProp = false; - - while (!reader.atEnd()) { - QXmlStreamReader::TokenType type = reader.readNext(); - QString name = reader.name().toString(); - // Start elements with DAV: - if (type == QXmlStreamReader::StartElement && reader.namespaceUri() == QLatin1String("DAV:")) { - if (name == QLatin1String("href")) { - currentHref = QUrl::fromPercentEncoding(reader.readElementText().toUtf8()); - } else if (name == QLatin1String("response")) { - } else if (name == QLatin1String("propstat")) { - insidePropstat = true; - } else if (name == QLatin1String("status") && insidePropstat) { - QString httpStatus = reader.readElementText(); - if (httpStatus.startsWith("HTTP/1.1 200")) { - currentPropsHaveHttp200 = true; - } else { - currentPropsHaveHttp200 = false; - } - } else if (name == QLatin1String("prop")) { - insideProp = true; - continue; - } - } - - if (type == QXmlStreamReader::StartElement && insidePropstat && insideProp) { - // All those elements are properties - QString propertyContent = readContentsAsString(reader); - if (name == QLatin1String("resourcetype") && propertyContent.contains("collection")) { - folders.append(currentHref); - } else if (name == QLatin1String("quota-used-bytes")) { - bool ok = false; - auto s = propertyContent.toLongLong(&ok); - if (ok) { - _sizes[currentHref] = s; - } - } - currentTmpProperties.insert(reader.name().toString(), propertyContent); - } - - // End elements with DAV: - if (type == QXmlStreamReader::EndElement) { - if (reader.namespaceUri() == QLatin1String("DAV:")) { - if (reader.name() == "response") { - if (currentHref.endsWith('/')) { - currentHref.chop(1); - } - emit directoryListingIterated(currentHref, currentHttp200Properties); - currentHref.clear(); - currentHttp200Properties.clear(); - } else if (reader.name() == "propstat") { - insidePropstat = false; - if (currentPropsHaveHttp200) { - currentHttp200Properties = QMap(currentTmpProperties); - } - currentTmpProperties.clear(); - currentPropsHaveHttp200 = false; - } else if (reader.name() == "prop") { - insideProp = false; - } - } - } - } - - if (reader.hasError()) { - // XML Parser error? Whatever had been emitted before will come as directoryListingIterated - qDebug() << "ERROR" << reader.errorString(); + if( !parser.parse( reply()->readAll(), &_sizes ) ) { + // XML parse error emit finishedWithError(reply()); - } else { - emit directoryListingSubfolders(folders); - emit finishedWithoutError(); } } else if (httpCode == 207) { // wrong content type @@ -498,6 +524,7 @@ bool LsColJob::finished() // wrong HTTP code or any other network error emit finishedWithError(reply()); } + return true; } From d2bae21b14f1c8f1ed5c83904038d4d4cb6507e6 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Tue, 14 Apr 2015 08:37:06 +0200 Subject: [PATCH 19/30] Added unit test for XML Parser class. --- test/CMakeLists.txt | 2 +- test/testxmlparse.h | 125 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 test/testxmlparse.h diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 62acf37c8..f1d44061b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -32,5 +32,5 @@ owncloud_add_test(SyncJournalDB "") owncloud_add_test(SyncFileItem "") owncloud_add_test(ConcatUrl "") - +owncloud_add_test(XmlParse "") diff --git a/test/testxmlparse.h b/test/testxmlparse.h new file mode 100644 index 000000000..78f2db0a3 --- /dev/null +++ b/test/testxmlparse.h @@ -0,0 +1,125 @@ +/* + * This software is in the public domain, furnished "as is", without technical + * support, and with no warranty, express or implied, as to its usefulness for + * any purpose. + * */ + +#ifndef MIRALL_TESTXMLPARSE_H +#define MIRALL_TESTXMLPARSE_H + +#include + +#include "networkjobs.h" + +using namespace OCC; + +class TestXmlParse : public QObject +{ + Q_OBJECT + +private: + bool _success; + QStringList _subdirs; + QStringList _items; + +private slots: + void initTestCase() { + _success = false; + } + + void cleanupTestCase() { + } + + void slotDirectoryListingSubFolders(const QStringList& list) + { + qDebug() << "subfolders: " << list; + _subdirs.append(list); + } + + void slotDirectoryListingIterated(const QString& item, const QMap& ) + { + qDebug() << " item: " << item; + _items.append(item); + } + + void slotFinishedSuccessfully() + { + _success = true; + } + + void testParser1() { + const QByteArray testXml = "" + "" + "" + "/oc/remote.php/webdav/sharefolder/" + "" + "" + "00004213ocobzus5kn6s" + "RDNVCK" + "121780" + "\"5527beb0400b0\"" + "" + "" + "" + "Fri, 06 Feb 2015 13:49:55 GMT" + "" + "HTTP/1.1 200 OK" + "" + "" + "" + "" + "" + "" + "" + "HTTP/1.1 404 Not Found" + "" + "" + "" + "/oc/remote.php/webdav/sharefolder/quitte.pdf" + "" + "" + "00004215ocobzus5kn6s" + "RDNVW" + "\"2fa2f0d9ed49ea0c3e409d49e652dea0\"" + "" + "Fri, 06 Feb 2015 13:49:55 GMT" + "121780" + "" + "HTTP/1.1 200 OK" + "" + "" + "" + "" + "" + "" + "HTTP/1.1 404 Not Found" + "" + "" + ""; + + + LsColXMLParser parser; + + connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)), + this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) ); + connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap&)), + this, SLOT(slotDirectoryListingIterated(const QString&, const QMap&)) ); + connect( &parser, SIGNAL(finishedWithoutError()), + this, SLOT(slotFinishedSuccessfully()) ); + + QHash sizes; + parser.parse( testXml, &sizes ); + + QVERIFY(_success); + QVERIFY(sizes.size() == 0 ); // No quota info in the XML + + QVERIFY(_items.contains("/oc/remote.php/webdav/sharefolder/quitte.pdf")); + QVERIFY(_items.contains("/oc/remote.php/webdav/sharefolder")); + QVERIFY(_items.size() == 2 ); + + QVERIFY(_subdirs.contains("/oc/remote.php/webdav/sharefolder/")); + QVERIFY(_subdirs.size() == 1); + } +}; + +#endif From d212ac7d16a7cf9c21f93fe85ca280ab79529707 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Tue, 14 Apr 2015 13:45:09 +0200 Subject: [PATCH 20/30] test xmlparser: Verify call to parse() --- test/testxmlparse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testxmlparse.h b/test/testxmlparse.h index 78f2db0a3..4e871902c 100644 --- a/test/testxmlparse.h +++ b/test/testxmlparse.h @@ -108,7 +108,7 @@ private slots: this, SLOT(slotFinishedSuccessfully()) ); QHash sizes; - parser.parse( testXml, &sizes ); + QVERIFY(parser.parse( testXml, &sizes )); QVERIFY(_success); QVERIFY(sizes.size() == 0 ); // No quota info in the XML From 2074bdbb195b36d14db600734ffa7f86b478dc29 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 14 Apr 2015 14:41:48 +0200 Subject: [PATCH 21/30] LsColXMLParser: More testing --- test/testxmlparse.h | 134 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 116 insertions(+), 18 deletions(-) diff --git a/test/testxmlparse.h b/test/testxmlparse.h index 4e871902c..065d5cf6d 100644 --- a/test/testxmlparse.h +++ b/test/testxmlparse.h @@ -22,30 +22,35 @@ private: QStringList _subdirs; QStringList _items; +public slots: + void slotDirectoryListingSubFolders(const QStringList& list) + { + qDebug() << "subfolders: " << list; + _subdirs.append(list); + } + + void slotDirectoryListingIterated(const QString& item, const QMap& ) + { + qDebug() << " item: " << item; + _items.append(item); + } + + void slotFinishedSuccessfully() + { + _success = true; + } + private slots: - void initTestCase() { + void init() { + qDebug() << Q_FUNC_INFO; _success = false; + _subdirs.clear(); + _items.clear(); } - void cleanupTestCase() { + void cleanup() { } - void slotDirectoryListingSubFolders(const QStringList& list) - { - qDebug() << "subfolders: " << list; - _subdirs.append(list); - } - - void slotDirectoryListingIterated(const QString& item, const QMap& ) - { - qDebug() << " item: " << item; - _items.append(item); - } - - void slotFinishedSuccessfully() - { - _success = true; - } void testParser1() { const QByteArray testXml = "" @@ -120,6 +125,99 @@ private slots: QVERIFY(_subdirs.contains("/oc/remote.php/webdav/sharefolder/")); QVERIFY(_subdirs.size() == 1); } + + void testParserBrokenXml() { + const QByteArray testXml = "X" + "" + "" + "/oc/remote.php/webdav/sharefolder/" + "" + "" + "00004213ocobzus5kn6s" + "RDNVCK" + "121780" + "\"5527beb0400b0\"" + "" + "" + "" + "Fri, 06 Feb 2015 13:49:55 GMT" + "" + "HTTP/1.1 200 OK" + "" + "" + "" + "" + "" + "" + "" + "HTTP/1.1 404 Not Found" + "" + "" + "" + "/oc/remote.php/webdav/sharefolder/quitte.pdf" + "" + "" + "00004215ocobzus5kn6s" + "RDNVW" + "\"2fa2f0d9ed49ea0c3e409d49e652dea0\"" + "" + "Fri, 06 Feb 2015 13:49:55 GMT" + "121780" + "" + "HTTP/1.1 200 OK" + "" + "" + "" + "" + "" + "" + "HTTP/1.1 404 Not Found" + "" + "" + ""; + + + LsColXMLParser parser; + + connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)), + this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) ); + connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap&)), + this, SLOT(slotDirectoryListingIterated(const QString&, const QMap&)) ); + connect( &parser, SIGNAL(finishedWithoutError()), + this, SLOT(slotFinishedSuccessfully()) ); + + QHash sizes; + QVERIFY(false == parser.parse( testXml, &sizes )); // verify false + + QVERIFY(!_success); + QVERIFY(sizes.size() == 0 ); // No quota info in the XML + + QVERIFY(_items.size() == 0 ); // FIXME: We should change the parser to not emit during parsing but at the end + + QVERIFY(_subdirs.size() == 0); + } + + void testParserEmptyXml() { + const QByteArray testXml = ""; + + LsColXMLParser parser; + + connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)), + this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) ); + connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap&)), + this, SLOT(slotDirectoryListingIterated(const QString&, const QMap&)) ); + connect( &parser, SIGNAL(finishedWithoutError()), + this, SLOT(slotFinishedSuccessfully()) ); + + QHash sizes; + QVERIFY(false == parser.parse( testXml, &sizes )); // verify false + + QVERIFY(!_success); + QVERIFY(sizes.size() == 0 ); // No quota info in the XML + + QVERIFY(_items.size() == 0 ); // FIXME: We should change the parser to not emit during parsing but at the end + QVERIFY(_subdirs.size() == 0); + } }; #endif From 2866e56c5186c19ff0d373cc624d70fb87651514 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 14 Apr 2015 14:56:25 +0200 Subject: [PATCH 22/30] LsColXMLParser: More testing 2 --- src/libsync/networkjobs.cpp | 9 ++++++++- test/testxmlparse.h | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/libsync/networkjobs.cpp b/src/libsync/networkjobs.cpp index 18837ea8b..7e92d96c1 100644 --- a/src/libsync/networkjobs.cpp +++ b/src/libsync/networkjobs.cpp @@ -363,6 +363,7 @@ bool LsColXMLParser::parse( const QByteArray& xml, QHash *sizes bool currentPropsHaveHttp200 = false; bool insidePropstat = false; bool insideProp = false; + bool insideMultiStatus = false; while (!reader.atEnd()) { QXmlStreamReader::TokenType type = reader.readNext(); @@ -384,6 +385,9 @@ bool LsColXMLParser::parse( const QByteArray& xml, QHash *sizes } else if (name == QLatin1String("prop")) { insideProp = true; continue; + } else if (name == QLatin1String("multistatus")) { + insideMultiStatus = true; + continue; } } @@ -428,7 +432,10 @@ bool LsColXMLParser::parse( const QByteArray& xml, QHash *sizes if (reader.hasError()) { // XML Parser error? Whatever had been emitted before will come as directoryListingIterated - qDebug() << "ERROR" << reader.errorString(); + qDebug() << "ERROR" << reader.errorString() << xml; + return false; + } else if (!insideMultiStatus) { + qDebug() << "ERROR no WebDAV response?" << xml; return false; } else { emit directoryListingSubfolders(folders); diff --git a/test/testxmlparse.h b/test/testxmlparse.h index 065d5cf6d..add06cdd8 100644 --- a/test/testxmlparse.h +++ b/test/testxmlparse.h @@ -197,6 +197,28 @@ private slots: QVERIFY(_subdirs.size() == 0); } + void testParserEmptyXmlNoDav() { + const QByteArray testXml = "I am under construction"; + + LsColXMLParser parser; + + connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)), + this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) ); + connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap&)), + this, SLOT(slotDirectoryListingIterated(const QString&, const QMap&)) ); + connect( &parser, SIGNAL(finishedWithoutError()), + this, SLOT(slotFinishedSuccessfully()) ); + + QHash sizes; + QVERIFY(false == parser.parse( testXml, &sizes )); // verify false + + QVERIFY(!_success); + QVERIFY(sizes.size() == 0 ); // No quota info in the XML + + QVERIFY(_items.size() == 0 ); // FIXME: We should change the parser to not emit during parsing but at the end + QVERIFY(_subdirs.size() == 0); + } + void testParserEmptyXml() { const QByteArray testXml = ""; From ed80a712abe1de27d0719bc53c07d3fd6648491a Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Tue, 14 Apr 2015 20:00:42 +0200 Subject: [PATCH 23/30] Sort folder sizes SelectiveSyncTreeView numerically Fixes #3112 --- src/gui/selectivesyncdialog.cpp | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/gui/selectivesyncdialog.cpp b/src/gui/selectivesyncdialog.cpp index 70348472b..429fe9804 100644 --- a/src/gui/selectivesyncdialog.cpp +++ b/src/gui/selectivesyncdialog.cpp @@ -26,10 +26,33 @@ #include #include #include +#include #include namespace OCC { + +class SelectiveSyncTreeViewItem : public QTreeWidgetItem { +public: + SelectiveSyncTreeViewItem(int type = QTreeWidgetItem::Type) + : QTreeWidgetItem(type) { } + SelectiveSyncTreeViewItem(const QStringList &strings, int type = QTreeWidgetItem::Type) + : QTreeWidgetItem(strings, type) { } + SelectiveSyncTreeViewItem(QTreeWidget *view, int type = QTreeWidgetItem::Type) + : QTreeWidgetItem(view, type) { } + SelectiveSyncTreeViewItem(QTreeWidgetItem *parent, int type = QTreeWidgetItem::Type) + : QTreeWidgetItem(parent, type) { } + +private: + bool operator<(const QTreeWidgetItem &other)const { + int column = treeWidget()->sortColumn(); + if (column == 1) { + return data(1, Qt::UserRole).toLongLong() < other.data(1, Qt::UserRole).toLongLong(); + } + return QTreeWidgetItem::operator <(other); + } +}; + SelectiveSyncTreeView::SelectiveSyncTreeView(AccountPtr account, QWidget* parent) : QTreeWidget(parent), _inserting(false), _account(account) { @@ -101,9 +124,9 @@ void SelectiveSyncTreeView::recursiveInsert(QTreeWidgetItem* parent, QStringList parent->setToolTip(0, path); parent->setData(0, Qt::UserRole, path); } else { - QTreeWidgetItem *item = findFirstChild(parent, pathTrail.first()); + SelectiveSyncTreeViewItem *item = static_cast(findFirstChild(parent, pathTrail.first())); if (!item) { - item = new QTreeWidgetItem(parent); + item = new SelectiveSyncTreeViewItem(parent); if (parent->checkState(0) == Qt::Checked || parent->checkState(0) == Qt::PartiallyChecked) { item->setCheckState(0, Qt::Checked); @@ -138,7 +161,7 @@ void SelectiveSyncTreeView::slotUpdateDirectories(const QStringList&list) QScopedValueRollback isInserting(_inserting); _inserting = true; - QTreeWidgetItem *root = topLevelItem(0); + SelectiveSyncTreeViewItem *root = static_cast(topLevelItem(0)); if (!root && list.size() <= 1) { _loading->setText(tr("No subfolders currently on the server.")); @@ -149,7 +172,7 @@ void SelectiveSyncTreeView::slotUpdateDirectories(const QStringList&list) } if (!root) { - root = new QTreeWidgetItem(this); + root = new SelectiveSyncTreeViewItem(this); root->setText(0, _rootName); root->setIcon(0, Theme::instance()->applicationIcon()); root->setData(0, Qt::UserRole, QString()); From b8e7555977a51013edfd49fc4501e0336f4ca41d Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Wed, 15 Apr 2015 02:18:35 -0400 Subject: [PATCH 24/30] [tx-robot] updated from transifex --- translations/client_fr.ts | 46 +++++++++++++++++++-------------------- translations/client_ja.ts | 8 +++---- translations/mirall_en.ts | 20 ++++++++--------- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/translations/client_fr.ts b/translations/client_fr.ts index a643f7e08..0deb2ecde 100644 --- a/translations/client_fr.ts +++ b/translations/client_fr.ts @@ -809,22 +809,22 @@ Les motifs cochés seront également supprimés s'ils empêchent la suppres Add a new ignore pattern: - Ajouter un nouveau modèle à ignorer : + Ajoutez un nouveau motif à ignorer : Edit Ignore Pattern - Éditer le modèle + Modifier le motif Edit ignore pattern: - Éditer le modèle : + Éditer le motif : This entry is provided by the system at '%1' and cannot be modified in this view. - Cette entrée est fournie par le système à '%1' et ne peut être modifiée dans cette vue. + Cette entrée est fournie par le système dans '%1' et ne peut être modifiée dans cette vue. @@ -2123,7 +2123,7 @@ Il est déconseillé de l'utiliser. CSync failed to load or create the journal file. Make sure you have read and write permissions in the local sync directory. - CSync n’a pu charger ou créer le fichier de journalisation. Veuillez vérifier que vous possédez les droits en lecture/écriture dans le répertoire de synchronisation local. + CSync n’a pu charger ou créer le fichier de journalisation. Veuillez vérifier que vous possédez les droits en lecture et écriture dans le répertoire de synchronisation local. @@ -2158,17 +2158,17 @@ Il est déconseillé de l'utiliser. CSync processing step reconcile failed. - Erreur CSync lors de l'opération d'harmonisation + Erreur CSync lors de l'opération de réconciliation CSync could not authenticate at the proxy. - CSync ne peut s'authentifier auprès du proxy. + CSync n'a pu s'authentifier auprès du proxy. CSync failed to lookup proxy or server. - CSync n'a pu trouver un proxy ou serveur auquel se connecter. + CSync n'a pu trouver le proxy ou serveur auquel se connecter. @@ -2183,7 +2183,7 @@ Il est déconseillé de l'utiliser. A network connection timeout happened. - Le délai d'attente pour la connexion réseau a été dépassé. + Le délai d'attente de la connexion réseau a été dépassé. @@ -2198,7 +2198,7 @@ Il est déconseillé de l'utiliser. CSync failed to access - Echec de CSync pour accéder + CSync n'a pu accéder à @@ -2279,7 +2279,7 @@ Il est déconseillé de l'utiliser. Ignored because of the "choose what to sync" blacklist - Ignoré à cause de la liste noire du contenu à synchroniser. + Ignoré à cause de la liste noire "Choisir le contenu à synchroniser". @@ -2404,7 +2404,7 @@ Il est déconseillé de l'utiliser. Managed Folders: - Répertoires suivis : + Répertoires configurés : @@ -2464,7 +2464,7 @@ Il est déconseillé de l'utiliser. Quota n/a - Quota n/a + Quota non disponible ou non applicable @@ -2474,7 +2474,7 @@ Il est déconseillé de l'utiliser. No items synced recently - Aucun item synchronisé récemment + Aucun élément synchronisé récemment @@ -2484,12 +2484,12 @@ Il est déconseillé de l'utiliser. Syncing %1 of %2 (%3 left) - Synchronisation %1 de %2 (%3 restant) + Synchronisation de %1 sur %2 (%3 restant) Syncing %1 (%2 left) - Synchronisation %1 (%2 restant) + Synchronisation de %1 (%2 restant) @@ -2566,7 +2566,7 @@ Il est déconseillé de l'utiliser. S&ync everything from server - Synchroniser tout le contenu depuis le serveur + S&ynchroniser tout le contenu depuis le serveur @@ -2584,17 +2584,17 @@ Il est déconseillé de l'utiliser. <html><head/><body><p>Failed to connect to the secure server address specified. How do you wish to proceed?</p></body></html> - <html><head/><body><p>Impossible de se connecter au serveur via l'adresse sécurisée indiquée. Comment voulez-vous procéder ?</p></body></html> + <html><head/><body><p>Impossible de se connecter au serveur via l'adresse sécurisée indiquée. Que souhaitez-vous faire ?</p></body></html> Select a different URL - Sélectionner un URL différent + Sélectionner une URL différente Retry unencrypted over HTTP (insecure) - Réessayer en clair sur HTTP (non sécurisé) + Essayer en clair sur HTTP (non sécurisé) @@ -2604,7 +2604,7 @@ Il est déconseillé de l'utiliser. <html><head/><body><p>Failed to connect to the secure server address <em>%1</em>. How do you wish to proceed?</p></body></html> - <html><head/><body><p>Impossible de se connecter à l'adresse sécurisée du serveur <em>%1</em>. Comment voulez-vous procéder ?</p></body></html> + <html><head/><body><p>Impossible de se connecter à l'adresse sécurisée <em>%1</em>. Que souhaitez-vous faire ?</p></body></html> @@ -2696,7 +2696,7 @@ Il est déconseillé de l'utiliser. &Do not store password on local machine - &Ne pas mémoriser le mot de passe sur la machine locale + Ne &pas mémoriser le mot de passe sur la machine locale @@ -2786,7 +2786,7 @@ Il est déconseillé de l'utiliser. %1 requires on a working system tray. If you are running XFCE, please follow <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">these instructions</a>. Otherwise, please install a system tray application such as 'trayer' and try again. - %1 nécessite la présence d'une zone de notification système (system tray). Si vous utilisez XFCE, veuillez suivre <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">ces instructions</a>. Sinon, installez une application mettant en place une zone de notification, telle que 'trayer', et essayez à nouveau. + %1 nécessite la présence d'une zone de notification système. Si vous utilisez XFCE, veuillez suivre <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">ces instructions</a>. Sinon, installez une application mettant en place une zone de notification, telle que 'trayer', et essayez à nouveau. diff --git a/translations/client_ja.ts b/translations/client_ja.ts index f5c871c34..de99bfdc2 100644 --- a/translations/client_ja.ts +++ b/translations/client_ja.ts @@ -1210,7 +1210,7 @@ It is not advisable to use it. Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. - サーバからアクセスが拒否されました。適切なアクセス権の検証には、<a href="%1">ここをクリック</a>してブラウザからサービスにアクセスしてください。 + サーバーによってアクセスが拒否されています。適切なアクセス権があるか検証するには、<a href="%1">ここをクリック</a>してブラウザーでサービスにアクセスしてください。 @@ -1828,12 +1828,12 @@ It is not advisable to use it. There is no sync folder configured. - 同期フォルダが設定されていません。 + 同期フォルダーが設定されていません。 Can not find an folder to upload to. - アップロード先のフォルダが見つけられません。 + アップロード先のフォルダーが見つかりません。 @@ -2237,7 +2237,7 @@ It is not advisable to use it. Symbolic links are not supported in syncing. - 同期機能は、シンボリックリンクをサポートしていません。 + 同期機能はシンボリックリンクをサポートしていません。 diff --git a/translations/mirall_en.ts b/translations/mirall_en.ts index a1ebcf8f3..0bc05a9d6 100644 --- a/translations/mirall_en.ts +++ b/translations/mirall_en.ts @@ -1690,22 +1690,22 @@ It is not advisable to use it. OCC::SelectiveSyncDialog - + Unchecked folders will be <b>removed</b> from your local file system and will not be synchronized to this computer anymore - + Choose What to Sync: Select remote subfolders you wish to synchronize. - + Choose What to Sync: Deselect remote subfolders you do not wish to synchronize. - + Choose What to Sync @@ -1713,28 +1713,28 @@ It is not advisable to use it. OCC::SelectiveSyncTreeView - + Loading ... - + Name - + Size - - + + No subfolders currently on the server. - + An error occured while loading the list of sub folders. From 996223197cc81bbbc200780b43ba17d65ca5dc35 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 15 Apr 2015 12:31:08 +0200 Subject: [PATCH 25/30] Translations: Attempt two for Serbian #3083 --- translations/.tx/config | 1 + 1 file changed, 1 insertion(+) diff --git a/translations/.tx/config b/translations/.tx/config index 59b888e65..15d83057f 100644 --- a/translations/.tx/config +++ b/translations/.tx/config @@ -22,6 +22,7 @@ trans.pt_BR = client_pt_BR.ts trans.ru = client_ru.ts trans.sl = client_sl.ts trans.sv = client_sv.ts +trans.sr = client_sr.ts trans.tr = client_tr.ts trans.uk = client_uk.ts trans.zh_TW = client_zh_TW.ts From 7c9cffa5ae2685612489342f5e7628afdc233846 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 15 Apr 2015 14:58:27 +0200 Subject: [PATCH 26/30] ConfigFile: Remove unused functions --- src/libsync/configfile.cpp | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/libsync/configfile.cpp b/src/libsync/configfile.cpp index e7e3738b5..d8a3bf3f6 100644 --- a/src/libsync/configfile.cpp +++ b/src/libsync/configfile.cpp @@ -40,7 +40,7 @@ namespace OCC { -static const char caCertsKeyC[] = "CaCertificates"; +//static const char caCertsKeyC[] = "CaCertificates"; only used from account.cpp static const char remotePollIntervalC[] = "remotePollInterval"; static const char forceSyncIntervalC[] = "forceSyncInterval"; static const char monoIconsC[] = "monoIcons"; @@ -317,20 +317,6 @@ bool ConfigFile::dataExists(const QString& group, const QString& key) const return settings.contains(key); } -QByteArray ConfigFile::caCerts( ) -{ - QSettings settings(configFile(), QSettings::IniFormat); - return settings.value( QLatin1String(caCertsKeyC) ).toByteArray(); -} - -void ConfigFile::setCaCerts( const QByteArray & certs ) -{ - QSettings settings(configFile(), QSettings::IniFormat); - - settings.setValue( QLatin1String(caCertsKeyC), certs ); - settings.sync(); -} - int ConfigFile::remotePollInterval( const QString& connection ) const { QString con( connection ); From 3f3f27d4d3aa76fe46ab95d0f2310406a39226f3 Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Wed, 15 Apr 2015 15:33:17 +0200 Subject: [PATCH 27/30] 1.8.1 beta 1 --- VERSION.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION.cmake b/VERSION.cmake index 1b409e51f..d8956e71f 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -1,10 +1,10 @@ set( MIRALL_VERSION_MAJOR 1 ) set( MIRALL_VERSION_MINOR 8 ) -set( MIRALL_VERSION_PATCH 0 ) +set( MIRALL_VERSION_PATCH 1 ) set( MIRALL_SOVERSION 0 ) if ( NOT DEFINED MIRALL_VERSION_SUFFIX ) - set( MIRALL_VERSION_SUFFIX "") #e.g. beta1, beta2, rc1 + set( MIRALL_VERSION_SUFFIX "beta1") #e.g. beta1, beta2, rc1 endif( NOT DEFINED MIRALL_VERSION_SUFFIX ) if( NOT DEFINED MIRALL_VERSION_BUILD ) From 458f336405e3b5e1837076cb53170db83dbf874a Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 15 Apr 2015 15:31:47 +0200 Subject: [PATCH 28/30] PropagateDownload: Read the mtime from the file system after writing it Because file system like FAT only have two second accuracy and would result in a upload if the mtime in the database is not the same as the one that was downloaded Issue #3103 --- src/libsync/propagatedownload.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index e19ee7f6b..98a78b45d 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -519,10 +519,14 @@ void PropagateDownloadFileQNAM::downloadFinished() _tmpFile.setPermissions(existingFile.permissions()); } - FileSystem::setFileHidden(_tmpFile.fileName(), false); + FileSystem::setModTime(_tmpFile.fileName(), _item._modtime); + // We need to fetch the time again because some file system such as FAT have a less than a second + // Accuracy, and we really need the time from the file system. (#3103) + _item._modtime = FileSystem::getModTime(_tmpFile.fileName()); QString error; _propagator->addTouchedFile(fn); + FileSystem::setFileHidden(_tmpFile.fileName(), false); if (!FileSystem::renameReplace(_tmpFile.fileName(), fn, &error)) { qDebug() << Q_FUNC_INFO << QString("Rename failed: %1 => %2").arg(_tmpFile.fileName()).arg(fn); // If we moved away the original file due to a conflict but can't @@ -543,7 +547,6 @@ void PropagateDownloadFileQNAM::downloadFinished() // Maybe we downloaded a newer version of the file than we thought we would... // Get up to date information for the journal. - FileSystem::setModTime(fn, _item._modtime); _item._size = FileSystem::getSize(fn); _propagator->_journal->setFileRecord(SyncJournalFileRecord(_item, fn)); From df0df76b513975296a6e1d908f9f98d782acc7c1 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Thu, 16 Apr 2015 02:18:36 -0400 Subject: [PATCH 29/30] [tx-robot] updated from transifex --- translations/client_pl.ts | 18 +- translations/client_sr.ts | 2930 ++++++++++++++++++++++++++++++++++++- 2 files changed, 2936 insertions(+), 12 deletions(-) diff --git a/translations/client_pl.ts b/translations/client_pl.ts index dad7b9833..5a527e83c 100644 --- a/translations/client_pl.ts +++ b/translations/client_pl.ts @@ -166,7 +166,7 @@ Discovering '%1' - + Rozpoznaję '%1' @@ -1446,12 +1446,12 @@ Niezalecane jest jego użycie. Error removing '%1': %2; - + Błąd usuwania '%1': %2; Could not remove directory '%1'; - + Nie mogę usunąć katalogu '%1'; @@ -1535,7 +1535,7 @@ Niezalecane jest jego użycie. File Removed - + Usunięto plik @@ -2473,7 +2473,7 @@ Niezalecane jest jego użycie. Discovering '%1' - + Rozpoznaję '%1' @@ -2748,22 +2748,22 @@ Kliknij %L1 TiB - + %L1 TiB %L1 GiB - + %L1 GiB %L1 MiB - + %L1 MiB %L1 KiB - + %L1 KiB diff --git a/translations/client_sr.ts b/translations/client_sr.ts index 5b95e89fb..b3a3eb80f 100644 --- a/translations/client_sr.ts +++ b/translations/client_sr.ts @@ -1,4 +1,2928 @@ - - - + + + FolderWizardSourcePage + + + Form + Образац + + + + Pick a local folder on your computer to sync + Изаберите локалну фасциклу за синхронизацију + + + + &Choose... + &Изабери… + + + + &Directory alias name: + &Алијас директоријума: + + + + FolderWizardTargetPage + + + Form + Образац + + + + Select a remote destination folder + Изаберите удаљену одредишну фасциклу + + + + Create Folder + Направи фасциклу + + + + Refresh + Освежи + + + + Folders + Фасцикле + + + + TextLabel + Текст ознака + + + + OCC::AccountSettings + + + Form + Образац + + + + Account to Synchronize + Налог за синхронизацију + + + + Connected with <server> as <user> + Повезан са <server> као <user> + + + + Add Folder... + Додај фасциклу... + + + + + Pause + Паузирај + + + + Remove + Уклони + + + + Choose What to Sync + Изаберите шта синхронизовати + + + + Storage Usage + Заузетост складишта + + + + Retrieving usage information... + Добављам податке о заузећу... + + + + <b>Note:</b> Some folders, including network mounted or shared folders, might have different limits. + <b>Напомена:</b> Неке фасцикле, укључујући монтиране или дељене фасцикле, могу имати различита ограничења. + + + + Account Maintenance + Одржавање налога + + + + Edit Ignored Files + Уреди игнорисане фајлове + + + + Modify Account + Измени налог + + + + No account configured. + Није подешен налог. + + + + Resume + Настави + + + + Confirm Folder Remove + Потврда уклањања фасцикле + + + + <p>Do you really want to stop syncing the folder <i>%1</i>?</p><p><b>Note:</b> This will not remove the files from your client.</p> + <p>Заиста желите да престанете са синхронизацијом фасцикле <i>%1</i>?</p><p><b>Напомена:</b> Ово неће уклонити фајлове из вашег клијента.</p> + + + + Confirm Folder Reset + Потврда ресетовања фасцикле + + + + <p>Do you really want to reset folder <i>%1</i> and rebuild your client database?</p><p><b>Note:</b> This function is designed for maintenance purposes only. No files will be removed, but this can cause significant data traffic and take several minutes or hours to complete, depending on the size of the folder. Only use this option if advised by your administrator.</p> + <p>Заиста желите да ресетујете фасциклу <i>%1</i> и поново изградите базу клијента?</p><p><b>Напомена:</b> Ова функција је намењена за сврху одржавања. Фајлови неће бити уклоњени, али ово може узроковати значајан пренос података и може трајати неколико минута или сати док се заврши, зависно од величине фасцикле. Користите ову опцију само ако вам је тако саветовао администратор.</p> + + + + Sync Running + Синхронизација у току + + + + The syncing operation is running.<br/>Do you want to terminate it? + Синхронизација је у току.<br/>Желите ли да је прекинете? + + + + Discovering '%1' + Откривам „%1“ + + + + %1 %2 (%3 of %4) %5 left at a rate of %6/s + Example text: "uploading foobar.png (1MB of 2MB) time left 2 minutes at a rate of 24Kb/s" + %1 %2 (%3 од %4) %5 преостало при брзини од %6/s + + + + %1 %2 (%3 of %4) + Example text: "uploading foobar.png (2MB of 2MB)" + %1 %2 (%3 од %4) + + + + %1 %2 + Example text: "uploading foobar.png" + %1 %2 + + + + %1 of %2, file %3 of %4 +Total time left %5 + %1 од %2, фајл %3 од %4 +Укупно преостало %5 + + + + file %1 of %2 + фајл %1 од %2 + + + + %1 (%3%) of %2 server space in use. + %1 (%3%) од %2 простора искоришћено. + + + + Currently there is no storage usage information available. + Тренутно нема доступних података о заузећу складишта. + + + + Connected to <a href="%1">%2</a>. + Повезан на <a href="%1">%2</a>. + + + + Connected to <a href="%1">%2</a> as <i>%3</i>. + Повезан на <a href="%1">%2</a> као <i>%3</i>. + + + + No connection to %1 at <a href="%2">%3</a>. + Нема везе са %1 на <a href="%2">%3</a>. + + + + No %1 connection configured. + Нема подешене %1 везе. + + + + OCC::AddCertificateDialog + + + SSL client certificate authentication + Аутентификација сертификата ССЛ клијента + + + + This server probably requires a SSL client certificate. + Овај сервер вероватно захтева сертификат ССЛ клијента. + + + + Certificate : + Сертификат: + + + + Browse... + Прегледај... + + + + Certificate password : + Лозинка сертификата: + + + + Select a certificate + Изаберите сертификат + + + + Certificate files (*.p12 *.pfx) + Фајлови сертификата (*.p12 *.pfx) + + + + OCC::AuthenticationDialog + + + Authentication Required + Потребна аутентификација + + + + Enter username and password for '%1' at %2. + Унесите корисничко име и лозинку за „%1“ на %2. + + + + &User: + &Корисник: + + + + &Password: + &Лозинка: + + + + OCC::ConnectionValidator + + + No ownCloud account configured + Нема подешеног ОунКлауд налога + + + + The configured server for this client is too old + Подешени сервер је сувише стар за ову верзију клијента + + + + Please update to the latest server and restart the client. + Ажурирајте сервер и поново покрените клијента. + + + + + Unable to connect to %1 + Не могу да се повежем са %1 + + + + timeout + истек времена + + + + The provided credentials are not correct + Дати акредитиви нису исправни + + + + OCC::DeleteJob + + + Connection timed out + Време повезивања истекло + + + + OCC::Folder + + + Unable to create csync-context + Не могу да направим „csync“ контекст + + + + Local folder %1 does not exist. + Локална фасцикла %1 не постоји. + + + + %1 should be a directory but is not. + %1 би требало да је директоријум али није. + + + + %1 is not readable. + %1 није читљив. + + + + %1: %2 + %1: %2 + + + + %1 and %2 other files have been removed. + %1 names a file. + %1 и још %2 фајлова је уклоњено. + + + + %1 has been removed. + %1 names a file. + %1 је уклоњен. + + + + %1 and %2 other files have been downloaded. + %1 names a file. + %1 и још %2 је преузето. + + + + %1 has been downloaded. + %1 names a file. + %1 је преузет. + + + + %1 and %2 other files have been updated. + %1 и још %2 је ажурирано. + + + + %1 has been updated. + %1 names a file. + %1 је ажуриран. + + + + %1 has been renamed to %2 and %3 other files have been renamed. + %1 је преименован у %2 и још %3 је преименовано. + + + + %1 has been renamed to %2. + %1 and %2 name files. + %1 је преименован у %2. + + + + %1 has been moved to %2 and %3 other files have been moved. + %1 је премештен у %2 и још %3 је премештено. + + + + %1 has been moved to %2. + %1 је премештен у %2. + + + + %1 and %2 other files could not be synced due to errors. See the log for details. + %1 names a file. + %1 и још %2 није могло бити синхронизовано због грешака. Погледајте записник за детаље. + + + + %1 could not be synced due to an error. See the log for details. + %1 није синхронизован због грешке. Погледајте записник за детаље. + + + + Sync Activity + Активност синхронизације + + + + Could not read system exclude file + Не могу да прочитам списак за игнорисање + + + + This sync would remove all the files in the sync folder '%1'. +This might be because the folder was silently reconfigured, or that all the file were manually removed. +Are you sure you want to perform this operation? + Синхронизација ће уклонити све фајлове у фасцикли „%1“ +Или је фасцикла тихо преподешена или су сви фајлови ручно уклоњени. +Да ли заиста желите да обавите ову радњу? + + + + Remove All Files? + Уклонити све фајлове? + + + + Remove all files + Уклони све фајлове + + + + Keep files + Остави фајлове + + + + OCC::FolderMan + + + Could not reset folder state + Не могу да ресетујем стање фасцикле + + + + An old sync journal '%1' was found, but could not be removed. Please make sure that no application is currently using it. + Пронађен је стари журнал синхронизације „%1“ али се не може уклонити. Проверите да га нека апликација тренутно не користи. + + + + Undefined State. + Неодређено стање. + + + + Waits to start syncing. + Чекам почетак синхронизације. + + + + Preparing for sync. + Припремам синхронизацију. + + + + Sync is running. + Синхронизација у току. + + + + Last Sync was successful. + Последња синхронизација је била успешна. + + + + Last Sync was successful, but with warnings on individual files. + Последња синхронизација је била успешна али са упозорењима за поједине фајлове. + + + + Setup Error. + Грешка подешавања. + + + + User Abort. + Корисник прекинуо. + + + + Sync is paused. + Синхронизација је паузирана. + + + + %1 (Sync is paused) + %1 (синхронизација паузирана) + + + + OCC::FolderStatusDelegate + + + + File + Фајл + + + + Syncing all files in your account with + Синхронизујем све фајлове вашег налога са + + + + Remote path: %1 + Удаљена путања: %1 + + + + OCC::FolderWizard + + + + Add Folder + Додај фасциклу + + + + OCC::FolderWizardLocalPath + + + Click to select a local folder to sync. + Клик за избор локалне фасцикле за синхронизацију. + + + + Enter the path to the local folder. + Унесите путању до локалне фасцикле. + + + + The directory alias is a descriptive name for this sync connection. + Алијас директоријума је описно име за ову везу синхронизације. + + + + No valid local folder selected! + Није изабрана исправна локална фасцикла! + + + + You have no permission to write to the selected folder! + Немате дозволе за упис у изабрану фасциклу! + + + + The local path %1 is already an upload folder. Please pick another one! + Локална путања %1 је већ фасцикла отпремања. Изаберите другу! + + + + An already configured folder is contained in the current entry. + Већ подешена фасцикла се налази у тренутном уносу. + + + + The selected folder is a symbolic link. An already configured folder is contained in the folder this link is pointing to. + Изабрана фасцикла је симболичка веза. Већ подешена фасцикла се налази у фасцикли на коју упућује ова веза. + + + + An already configured folder contains the currently entered folder. + Већ подешена фасцикла садржи тренутно унесену фасциклу. + + + + The selected folder is a symbolic link. An already configured folder is the parent of the current selected contains the folder this link is pointing to. + Изабрана фасцикла је симболичка веза. Већ подешена фасцикла садржи тренутно изабрану фасциклу на коју упућује ова веза. + + + + The alias can not be empty. Please provide a descriptive alias word. + Алијас не може бити празан. Дајте неки описни назив. + + + + The alias <i>%1</i> is already in use. Please pick another alias. + Алијас <i>%1</i> је већ у употреби. Изаберите неки други. + + + + Select the source folder + Изаберите изворну фасциклу + + + + OCC::FolderWizardRemotePath + + + Create Remote Folder + Прављење удаљене фасцикле + + + + Enter the name of the new folder to be created below '%1': + Унесите назив нове фасцикле која ће бити направљена у %1: + + + + Folder was successfully created on %1. + Фасцикла је успешно направљена на %1 + + + + Failed to create the folder on %1. Please check manually. + Нисам успео да направим фасциклу на %1. Проверите ручно. + + + + Choose this to sync the entire account + Ово изаберите да синхронизујете целокупан налог + + + + This folder is already being synced. + Ова фасцикла се већ синхронизује. + + + + You are already syncing <i>%1</i>, which is a parent folder of <i>%2</i>. + Већ синхронизујете <i>%1</i>, која садржи фасциклу <i>%2</i>. + + + + You are already syncing all your files. Syncing another folder is <b>not</b> supported. If you want to sync multiple folders, please remove the currently configured root folder sync. + Већ синхронизујете све ваше фајлове. Синхронизација других фасцикли <b>није</b> подржана. Ако желите синхронизацију више фасцикли, уклоните тренутно подешену корену фасциклу. + + + + OCC::FolderWizardSelectiveSync + + + Choose What to Sync: You can optionally deselect remote subfolders you do not wish to synchronize. + Изаберите шта синхронизујете. Опционо, можете избацити удаљене фасцикле које не желите да синхронизујете. + + + + OCC::FormatWarningsWizardPage + + + + <b>Warning:</b> + <b>Упозорење:</b> + + + + OCC::GETFileJob + + + No E-Tag received from server, check Proxy/Gateway + Ниједна е-етикета није примљена са сервера, проверите Proxy/Gateway + + + + We received a different E-Tag for resuming. Retrying next time. + Добили смо различиту е-етикету за наставак. Покушајте поново касније. + + + + Server returned wrong content-range + Сервер је вратио погрешан опсег садржаја + + + + Connection Timeout + Време за повезивање је истекло + + + + OCC::GeneralSettings + + + Form + Образац + + + + General Settings + Опште поставке + + + + Launch on System Startup + Покрени при покретању система + + + + Show Desktop Notifications + Прикажи обавештења + + + + Use Monochrome Icons + Користи једнобојне иконе + + + + Show crash reporter + Прикажи извештај о паду + + + + + About + О програму + + + + Updates + Ажурирања + + + + &Restart && Update + &Поново покрени и ажурирај + + + + OCC::HttpCredentialsGui + + + Enter Password + Унесите лозинку + + + + Please enter %1 password for user '%2': + Унесите %1 лозинку за корисника „%2“: + + + + OCC::IgnoreListEditor + + + Ignored Files Editor + Уредник фајлова за игнорисање + + + + Add + Додај + + + + Remove + Уклони + + + + Files or directories matching a pattern will not be synchronized. + +Checked items will also be deleted if they prevent a directory from being removed. This is useful for meta data. + Ставке које се поклапају са шаблоном неће бити синхронизоване. + +Означене ставке ће такође бити уклоњене ако заостану приликом уклањања директоријума. Ово је корисно за мета-податке. + + + + Could not open file + Не могу да отворим фајл + + + + Cannot write changes to '%1'. + Не могу да упишем измене у „%1“ + + + + Add Ignore Pattern + Додавање шаблона за игнорисање + + + + Add a new ignore pattern: + Додај нови шаблон за игнорисање: + + + + Edit Ignore Pattern + Уређивање шаблона за игнорисање + + + + Edit ignore pattern: + Уреди шаблон за игнорисање: + + + + This entry is provided by the system at '%1' and cannot be modified in this view. + Овај унос је са система на „%1“ и не може се овде изменити. + + + + OCC::LogBrowser + + + Log Output + Бележи излаз + + + + &Search: + &Тражи: + + + + &Find + &Нађи + + + + Clear + Очисти + + + + Clear the log display. + Очисти приказ записника. + + + + S&ave + С&ачувај + + + + Save the log file to a file on disk for debugging. + Сачувајте фајл записника на диску. + + + + Save log file + Сачувај фајл записника + + + + Error + Грешка + + + + Could not write to log file + Не могу да упишем фајл записника + + + + OCC::Logger + + + Error + Грешка + + + + <nobr>File '%1'<br/>cannot be opened for writing.<br/><br/>The log output can <b>not</b> be saved!</nobr> + <nobr>Фајл „%1“<br/>није уписив.<br/><br/>Записник се <b>не може</b> сачувати!</nobr> + + + + OCC::MoveJob + + + Connection timed out + Време повезивања истекло + + + + OCC::NSISUpdater + + + New Version Available + Нова верзија је доступна + + + + <p>A new version of the %1 Client is available.</p><p><b>%2</b> is available for download. The installed version is %3.</p> + <p>Нова верзија %1 клијента је доступна.</p><p><b>%2</b> је доступна за преузимање. Инсталирана је %3.</p> + + + + Skip this version + Прескочи ову верзију + + + + Skip this time + Прескочи сада + + + + Get update + Ажурирај + + + + OCC::NetworkSettings + + + Form + Образац + + + + Proxy Settings + Поставке проксија + + + + No Proxy + Без проксија + + + + Use system proxy + Системски прокси + + + + Specify proxy manually as + Ручно наведи прокси + + + + Host + Домаћин + + + + : + : + + + + Proxy server requires authentication + Прокси захтева аутентификацију + + + + Download Bandwidth + Брзина преузимања + + + + + Limit to + Ограничи на + + + + + KBytes/s + KB/s + + + + + No limit + Без ограничења + + + + Upload Bandwidth + Брзина отпремања + + + + Limit automatically + Сам ограничи + + + + Hostname of proxy server + Назив прокси сервера + + + + Username for proxy server + Корисничко име за прокси + + + + Password for proxy server + Лозинка за прокси + + + + HTTP(S) proxy + ХТТП(С) прокси + + + + SOCKS5 proxy + СОКС-5 прокси + + + + OCC::OCUpdater + + + New Update Ready + Ново ажурирање је спремно + + + + A new update is about to be installed. The updater may ask +for additional privileges during the process. + Спремна је инсталација новог ажурирања. Током ажурирања +могу бити затражена додатна овлашћења. + + + + Downloading version %1. Please wait... + Преузимам верзију %1. Сачекајте... + + + + Version %1 available. Restart application to start the update. + Верзија %1 је доступна. Поново покрените апликацију да почнете ажурирање. + + + + Could not download update. Please click <a href='%1'>here</a> to download the update manually. + Не могу да преузмем ажурирање. Кликните <a href='%1'>овде</a> да бисте га преузели ручно. + + + + Could not check for new updates. + Не могу да проверим нова ажурирања. + + + + New version %1 available. Please use the system's update tool to install it. + Нова верзија %1 је доступна. Употребите системски алат за ажурирање да је инсталирате. + + + + Checking update server... + Проверавам сервер ажурирања... + + + + Update status is unknown: Did not check for new updates. + Стање ажурирања је непознато. Нисам проверио нова ажурирања. + + + + No updates available. Your installation is at the latest version. + Нема доступних ажурирања. Имате последњу верзију. + + + + OCC::OwncloudAdvancedSetupPage + + + Connect to %1 + Повежи се са %1 + + + + Setup local folder options + Опције поставке локалне фасцикле + + + + Connect... + Повежи се... + + + + %1 folder '%2' is synced to local folder '%3' + %1 фасцикла „%2“ је сингронизована са локалном „%3“ + + + + <p><small><strong>Warning:</strong> You currently have multiple folders configured. If you continue with the current settings, the folder configurations will be discarded and a single root folder sync will be created!</small></p> + <p><small><strong>Упозорење:</strong> Тренутно имате више конфигурисаних фасцикли. Ако наставите са тренутним поставкама, подешавања фасцикли ће бити одбачена и биће формирана синхронизација за појединачну основну фасциклу!</small></p> + + + + <p><small><strong>Warning:</strong> The local directory is not empty. Pick a resolution!</small></p> + <p><small><strong>Упозорење:</strong> Локални директоријум није празан. Изаберите решење!</small></p> + + + + Local Sync Folder + Синхронизација локалне фасцикле + + + + Update advanced setup + Освежи напредна подешавања + + + + + (%1) + (%1) + + + + OCC::OwncloudHttpCredsPage + + + Connect to %1 + Повежи се са %1 + + + + Enter user credentials + Унесите корисничке акредитиве + + + + Update user credentials + Ажурирај корисничке акредитиве + + + + OCC::OwncloudSetupPage + + + Connect to %1 + Повежи се са %1 + + + + Setup %1 server + Подеси %1 сервер + + + + This url is NOT secure as it is not encrypted. +It is not advisable to use it. + Ова адреса НИЈЕ безбедна јер није шифрована. +Не препоручује се њено коришћење. + + + + This url is secure. You can use it. + Ова адреса је безбедна. Можете је користити. + + + + &Next > + &Следеће > + + + + Update %1 server + Ажурирај %1 сервер + + + + OCC::OwncloudSetupWizard + + + <font color="green">Successfully connected to %1: %2 version %3 (%4)</font><br/><br/> + <font color="green">Успешно повезан са %1: %2 верзија %3 (%4)</font><br/><br/> + + + + Failed to connect to %1 at %2:<br/>%3 + Неуспешно повезивање са %1 на %2:<br/>%3 + + + + Timeout while trying to connect to %1 at %2. + Време је истекло у покушају повезивања са %1 на %2. + + + + Trying to connect to %1 at %2... + Покушавам да се повежем са %1 на %2... + + + + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. + Сервер није дозволио приступ. Да проверите имате ли исправан приступ, <a href="%1">кликните овде</a> да бисте приступили услузи из прегледача. + + + + Local sync folder %1 already exists, setting it up for sync.<br/><br/> + Локална фасцикла %1 већ постоји, одређујем је за синхронизацију.<br/><br/> + + + + Creating local sync folder %1... + Правим локалну фасциклу за синхронизацију %1 ... + + + + ok + у реду + + + + failed. + неуспешно + + + + Could not create local folder %1 + Не могу да направим локалну фасциклу %1 + + + + No remote folder specified! + Није наведена удаљена фасцикла! + + + + Error: %1 + Грешка: %1 + + + + creating folder on ownCloud: %1 + правим фасциклу на ОунКлауду: % 1 + + + + Remote folder %1 created successfully. + Удаљена фасцикла %1 је успешно направљена. + + + + The remote folder %1 already exists. Connecting it for syncing. + Удаљена фасцикла %1 већ постоји. Повезујем се ради синхронизовања. + + + + + The folder creation resulted in HTTP error code %1 + Креирање фасцикле довело је до ХТТП грешке са кодом %1 + + + + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> + Креирање удаљене фасцикле није успело због погрешних акредитива.<br/>Вратите се назад и проверите ваше акредитиве.</p> + + + + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> + <p><font color="red">Креирање удаљене фасцикле није успело због погрешних акредитива.</font><br/>Вратите се назад и проверите ваше акредитиве.</p> + + + + + Remote folder %1 creation failed with error <tt>%2</tt>. + Креирање удаљене фасцикле %1 није успело због грешке <tt>%2</tt>. + + + + A sync connection from %1 to remote directory %2 was set up. + Веза за синхронизацију од %1 до удаљеног директоријума %2 је подешена. + + + + Successfully connected to %1! + Успешно повезан са %1! + + + + Connection to %1 could not be established. Please check again. + Не може се успоставити веза са %1. Проверите поново. + + + + Folder rename failed + Преименовање није успело + + + + Can't remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. + Не могу уклонити и направити резервну копију фасцикле јер су фасцикла или фајл у њој отворени у неком другом програму. Молимо вас да затворите фасциклу или фајл и покушате поново или откажите процедуру подешавања. + + + + <font color="green"><b>Local sync folder %1 successfully created!</b></font> + <font color="green"><b>Локална фасцикла за синхронизовање %1 је успешно креирана!</b></font> + + + + OCC::OwncloudWizard + + + %1 Connection Wizard + %1 чаробњак повезивања + + + + Skip folders configuration + Прескочи подешавање фасцикли + + + + OCC::OwncloudWizardResultPage + + + Everything set up! + Све је подешено! + + + + Open Local Folder + Отвори локалну фасциклу + + + + Open %1 in Browser + Отвори %1 у прегледачу + + + + OCC::PUTFileJob + + + Connection Timeout + Веза је истекла + + + + OCC::PollJob + + + Invalid JSON reply from the poll URL + Неисправан ЈСОН одговор са адресе упита + + + + OCC::PropagateDownloadFileLegacy + + + Sync was aborted by user. + Корисник је прекинуо синхронизацију. + + + + No E-Tag received from server, check Proxy/Gateway + Ниједна е-етикета није примљена са сервера, проверите Proxy/Gateway + + + + We received a different E-Tag for resuming. Retrying next time. + Добили смо различиту е-етикету за наставак. Покушајте поново касније. + + + + Server returned wrong content-range + Сервер је вратио погрешан опсег садржаја + + + + File %1 can not be downloaded because of a local file name clash! + Фајл %1 се не може преузети јер се судара са називом локалног фајла! + + + + OCC::PropagateDownloadFileQNAM + + + File %1 can not be downloaded because of a local file name clash! + Фајл %1 се не може преузети јер се судара са називом локалног фајла! + + + + The file could not be downloaded completely. + Фајл није могао бити преузет у потпуности. + + + + File %1 cannot be saved because of a local file name clash! + Фајл %1 се не може сачувати јер се судара са називом локалног фајла! + + + + OCC::PropagateItemJob + + + ; Restoration Failed: + ; рестаурација неуспешна: + + + + Continue blacklisting: + Настави са коришћењем црне листе: + + + + A file or directory was removed from a read only share, but restoring failed: %1 + Датотека или директоријум су уклоњени из дељења које је само за читање, али враћење није успело: %1 + + + + OCC::PropagateLocalMkdir + + + Attention, possible case sensitivity clash with %1 + Пажња! Могуће сударање због величине слова са %1 + + + + could not create directory %1 + не могу да направим директоријум %1 + + + + OCC::PropagateLocalRemove + + + Error removing '%1': %2; + Грешка при уклањању „%1“: %2; + + + + Could not remove directory '%1'; + Не могу да уклоним директоријум „%1“; + + + + Could not remove %1 because of a local file name clash + Не могу да уклоним %1 због сударања са називом локалног фајла + + + + OCC::PropagateLocalRename + + + File %1 can not be renamed to %2 because of a local file name clash + Фајл %1 се не може преименовати у %2 због сударања са називом локалног фајла + + + + OCC::PropagateRemoteDelete + + + The file has been removed from a read only share. It was restored. + Фајл је уклоњен из дељења које је само за читање. Зато је враћен. + + + + Wrong HTTP code returned by server. Expected 204, but recieved "%1 %2". + Погрешан ХТТП код враћен са сервера. Очекиван 204, али је добијен "%1 %2". + + + + OCC::PropagateRemoteMkdir + + + Wrong HTTP code returned by server. Expected 201, but recieved "%1 %2". + Погрешан ХТТП код враћен са сервера. Очекиван 201, али је добијен "%1 %2". + + + + OCC::PropagateRemoteMove + + + This folder must not be renamed. It is renamed back to its original name. + Ова фасцикла се не сме преименовати. Зато је враћен првобитни назив. + + + + This folder must not be renamed. Please name it back to Shared. + Ова фасцикла се не сме преименовати. Молим вас вратите назив у Дељени. + + + + The file was renamed but is part of a read only share. The original file was restored. + Фајл је био преименован али је део дељења које је само за читање. Оригинални фајл је враћен. + + + + Wrong HTTP code returned by server. Expected 201, but recieved "%1 %2". + Погрешан ХТТП код враћен са сервера. Очекиван 201, али је добијен "%1 %2". + + + + OCC::PropagateUploadFileLegacy + + + + Local file changed during sync, syncing once it arrived completely + Локални фајл је промењен током синхронизације, поново синхронизујте фајлове + + + + Sync was aborted by user. + Корисник је прекинуо синхронизацију. + + + + The file was edited locally but is part of a read only share. It is restored and your edit is in the conflict file. + Фајл је измењен локално али је у саставу дељења које је само за читање. Враћен је у претходно стање а измене су у фајлу сукоба. + + + + OCC::PropagateUploadFileQNAM + + + File Removed + Фајл уклоњен + + + + + Local file changed during sync. + Локални фајл измењен током синхронизације. + + + + The file was edited locally but is part of a read only share. It is restored and your edit is in the conflict file. + Фајл је измењен локално али је у саставу дељења које је само за читање. Враћен је у претходно стање а измене су у фајлу сукоба. + + + + Poll URL missing + Адреса упита недостаје + + + + The local file was removed during sync. + Локални фајл је уклоњен током синхронизације. + + + + The server did not acknowledge the last chunk. (No e-tag were present) + Сервер није потврдио последње парче. (није било е-ознаке) + + + + OCC::ProtocolWidget + + + Form + Образац + + + + Sync Activity + Активност синхронизације + + + + 3 + 3 + + + + 4 + 4 + + + + Time + Време + + + + File + Фајл + + + + Folder + Фасцикла + + + + Action + Радња + + + + Size + Величина + + + + Retry Sync + Понови синхронизацију + + + + Copy + Копирај + + + + Copy the activity list to the clipboard. + Копирај активност у клипборд. + + + + Copied to clipboard + Копирано у клипборд + + + + The sync status has been copied to the clipboard. + Стање синхронизације је копирано у клипборд. + + + + Currently no files are ignored because of previous errors and no downloads are in progress. + Тренутно се, због претходних грешака, ништа не игнорише и нема преузимања у току. + + + + %n files are ignored because of previous errors. + + %n фајл је игнорисан због претходних грешака. +%n фајла су игнорисана због претходних грешака. +%n фајлова је игнорисано због претходних грешака. + + + + + %n files are partially downloaded. + + %n фајл је делимично преузет. +%n фајла су делимично преузета. +%n фајлова је делимично преузето. + + + + + Try to sync these again. + Покушајте да их синхронизујете поново. + + + + OCC::SelectiveSyncDialog + + + Unchecked folders will be <b>removed</b> from your local file system and will not be synchronized to this computer anymore + Неозначене фасцикле биће <b>уклоњене</b> из локалног фајл-система и више се неће синхронизовати на овом рачунару + + + + Choose What to Sync: Select remote subfolders you wish to synchronize. + Изаберите шта синхронизујете. Изаберите удаљене фасцикле које желите да синхронизујете. + + + + Choose What to Sync: Deselect remote subfolders you do not wish to synchronize. + Изаберите шта синхронизујете. Избаците удаљене фасцикле које не желите да синхронизујете. + + + + Choose What to Sync + Изаберите шта синхронизовати + + + + OCC::SelectiveSyncTreeView + + + Loading ... + Учитавам ... + + + + Name + Назив + + + + Size + Величина + + + + OCC::SettingsDialog + + + Settings + Поставке + + + + Account + Налог + + + + Activity + Активност + + + + General + Опште + + + + Network + Мрежа + + + + OCC::SettingsDialogMac + + + %1 + %1 + + + + Account + Налог + + + + Activity + Активност + + + + General + Опште + + + + Network + Мрежа + + + + OCC::ShareDialog + + + Share NewDocument.odt + Подели NewDocument.odt + + + + Share Info + Подаци дељења + + + + + TextLabel + Текст ознака + + + + share label + ознака дељења + + + + OwnCloud Path: + ОунКлауд путања: + + + + Share link + Веза дељења + + + + Set password + Постави лозинку + + + + Set expiry date + Постави датум истека + + + + + %1 path: %2 + %1 путања: %2 + + + + %1 Sharing + %1 Дељење + + + + Password Protected + Заштићено лозинком + + + + Choose a password for the public link + Одредите лозинку за јавну везу + + + + OCS API error code: %1 + OCS API код грешке: %1 + + + + There is no sync folder configured. + Фасцикла за синхронизацију није подешена. + + + + Can not find an folder to upload to. + Не могу да пронађем фасциклу за отпремање. + + + + Sharing of external directories is not yet working. + Дељење спољних директоријума још увек не ради. + + + + A sync file with the same name exists. The file can not be registered to sync. + Датотека за синхронизацију под истим именом већ постоји. Датотека не може вити регистрована за синхронизацију. + + + + Waiting to upload... + Чекам отпремање... + + + + Unable to register in sync space. + Није могуће регистровати се у простору за синхронизацију. + + + + The file can not be synced. + Фајл не може бити синхронизован. + + + + Sync of registered file was not successful yet. + Синхронизација регистроване датотеке још увек није успела. + + + + OCC::ShibbolethCredentials + + + Login Error + Грешка пријављивања + + + + You must sign in as user %1 + Морате се пријавити као %1 + + + + OCC::ShibbolethWebView + + + %1 - Authenticate + %1 - аутентификација + + + + Reauthentication required + Неопходна поновна аутентификација + + + + Your session has expired. You need to re-login to continue to use the client. + Ваша сесија је истекла. Поново се пријавите да бисте наставили да користите клијент. + + + + %1 - %2 + %1 - %2 + + + + OCC::SocketApi + + + Share with %1 + parameter is ownCloud + Подели са %1 + + + + OCC::SslButton + + + <h3>Certificate Details</h3> + <h3>Детаљи сертификата</h3> + + + + Common Name (CN): + Уобичајено име: + + + + Subject Alternative Names: + Алтернативно име: + + + + Organization (O): + Организација: + + + + Organizational Unit (OU): + Организациона јединица: + + + + State/Province: + Покрајина/провинција: + + + + Country: + Земља: + + + + Serial: + Серијски број: + + + + <h3>Issuer</h3> + <h3>Издавач</h3> + + + + Issuer: + Издавач: + + + + Issued on: + Издат: + + + + Expires on: + Истиче: + + + + <h3>Fingerprints</h3> + <h3>Отисци</h3> + + + + MD 5: + MD 5: + + + + SHA-256: + SHA-256: + + + + SHA-1: + SHA-1: + + + + <p><b>Note:</b> This certificate was manually approved</p> + <p><b>Напомена:</b> Овај сертификат је ручно одобрен</p> + + + + %1 (self-signed) + %1 (самопотписан) + + + + %1 + %1 + + + + This connection is encrypted using %1 bit %2. + + Ова веза је шифрована коришћењем %1 бита %2. + + + + + Certificate information: + Подаци о сертификату: + + + + This connection is NOT secure as it is not encrypted. + + Ова веза НИЈЕ безбедна јер није шифрована. + + + + + OCC::SslErrorDialog + + + Form + Образац + + + + Trust this certificate anyway + Сертификат је свакако поуздан + + + + + SSL Connection + SSL веза + + + + Warnings about current SSL Connection: + Упозорења о тренутној SSL вези: + + + + with Certificate %1 + са Сертификатом %1 + + + + + + &lt;not specified&gt; + &lt;није наведено&gt; + + + + + Organization: %1 + Организација: %1 + + + + + Unit: %1 + Јединица: %1 + + + + + Country: %1 + Држава: %1 + + + + Fingerprint (MD5): <tt>%1</tt> + Отисак (MD5): <tt>%1</tt> + + + + Fingerprint (SHA1): <tt>%1</tt> + Отисак (SHA1): <tt>%1</tt> + + + + Effective Date: %1 + Датум ступања: %1 + + + + Expiration Date: %1 + Истиче : %1 + + + + Issuer: %1 + Издавач: %1 + + + + OCC::SyncEngine + + + Success. + Успешно. + + + + CSync failed to load or create the journal file. Make sure you have read and write permissions in the local sync directory. + CSync није успео да креира фајл дневника. Проверите да ли имате дозволе за читање и уписивање у локалном директоријуму за синхронизацију. + + + + CSync failed to load the journal file. The journal file is corrupted. + CSync није успео да учита фајл дневника. Фајл дневника је оштећен. + + + + <p>The %1 plugin for csync could not be loaded.<br/>Please verify the installation!</p> + <p>Додатна компонента %1 за csync не може бити учитана.<br/>Проверите инсталацију!</p> + + + + CSync got an error while processing internal trees. + CSync има грешку при обради интерног стабла. + + + + CSync failed to reserve memory. + CSync није успео да резервише меморију. + + + + CSync fatal parameter error. + CSync фатална грешка параметара. + + + + CSync processing step update failed. + CSync није успео да ажурира корак процесирања. + + + + CSync processing step reconcile failed. + CSync није успео да усклади корак процесирања. + + + + CSync could not authenticate at the proxy. + CSync није могао потврдити идентитет на проксију. + + + + CSync failed to lookup proxy or server. + CSync није успео да потражи прокси или сервер. + + + + CSync failed to authenticate at the %1 server. + CSync није успео да потврди идентитет на %1 серверу. + + + + CSync failed to connect to the network. + CSync није успео да приступи мрежи. + + + + A network connection timeout happened. + Истекло је време за мрежно повезивање. + + + + A HTTP transmission error happened. + Дошло је до грешке ХТТП преноса. + + + + CSync failed due to not handled permission deniend. + CSync није успео због одбијања дозвола којим се не управља. + + + + CSync failed to access + CSync није успео да приступи + + + + CSync tried to create a directory that already exists. + CSync покушао да креира директоријум који већ постоји. + + + + CSync: No space on %1 server available. + CSync: Нема простора на серверу %1. + + + + CSync unspecified error. + CSync недефинисана грешка. + + + + Aborted by the user + Прекинуо корисник + + + + The mounted directory is temporarily not available on the server + Монтирани директоријум тренутно није доступан на серверу + + + + An error opening a directory happened + Грешка при отварању директоријума + + + + An internal error number %1 happened. + Интерна грешка број %1 + + + + The item is not synced because of previous errors: %1 + Ставка није синхронизована због ранијих грешака: %1 + + + + Symbolic links are not supported in syncing. + Симболичке везе нису подржане за синхронизовање. + + + + Hard links are not supported in syncing. + Чврсте везе нису подржане за синхронизовање. + + + + File is listed on the ignore list. + Фајл се налази на листи за игнорисање. + + + + File contains invalid characters that can not be synced cross platform. + Фајл садржи неисправне знакове који се не могу синхронизовати на различитим платформама. + + + + Filename encoding is not valid + Кодирање назива фајла није исправно + + + + Unable to initialize a sync journal. + Није могуће покренути у синхронизацију журнала. + + + + Cannot open the sync journal + Не могу да отворим журнал синхронизације + + + + + Ignored because of the "choose what to sync" blacklist + Игнорисано због "Изабери шта синхронизујеш" црне листе + + + + Not allowed because you don't have permission to add sub-directories in that directory + Није дозвољено зато што немате дозволу да додајете поддиректоријуме у тај директоријум + + + + Not allowed because you don't have permission to add parent directory + Није дозвољено зато што немате дозволу да додајете датотеке у тај директоријум + + + + Not allowed because you don't have permission to add files in that directory + Није дозвољено зато што немате дозволу да додајете фајлове у тај директоријум + + + + Not allowed to upload this file because it is read-only on the server, restoring + Није дозвољено отпремање ове датотеке зато што је само за читање на серверу, враћам + + + + + Not allowed to remove, restoring + Уклањање није дозвољено, враћам + + + + Local files and share folder removed. + Локални фајлови и дељена фасцикла су уклоњени. + + + + Move not allowed, item restored + Премештање није дозвољено. Ставка је враћена + + + + Move not allowed because %1 is read-only + Премештање није дозвољено јер %1 је само за читање + + + + the destination + одредиште + + + + the source + извор + + + + OCC::Systray + + + %1: %2 + %1: %2 + + + + OCC::Theme + + + <p>Version %1. For more information please visit <a href='%2'>%3</a>.</p> + <p>Верзија %1. За више информација посетите <a href='%2'>%3</a>.</p> + + + + <p>Copyright ownCloud, Incorporated</p> + <p>Ауторска права ОунКлауд (ownCloud), корпорација</p> + + + + <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> + <p>Дистрибуирано %1 и лиценцирано под GNU општом јавном лиценцом (GPL) верзија 2.0.<br/>%2 и %2 лого су регистроване марке %1 у САД и осталим земљама.</p> + + + + OCC::ownCloudGui + + + Please sign in + Пријавите се + + + + Disconnected from server + Исључен са сервера + + + + Folder %1: %2 + Фасцикла %1: %2 + + + + No sync folders configured. + Нема подешених фасцикли за синхронизацију. + + + + There are no sync folders configured. + Нема подешених фасцикли за синхронизацију. + + + + None. + Ништа. + + + + Recent Changes + Недавне измене + + + + Open %1 folder + Отвори фасциклу %1 + + + + Managed Folders: + Управљане фасцикле: + + + + Open folder '%1' + Отвори фасциклу „%1“ + + + + Open %1 in browser + Отвори %1 у прегледачу + + + + Calculating quota... + Рачунам квоту... + + + + Unknown status + Непознато стање + + + + Settings... + Поставке... + + + + Details... + Детаљи... + + + + Help + Помоћ + + + + Quit %1 + Напусти %1 + + + + Sign in... + Пријави се... + + + + Sign out + Одјави се + + + + Crash now + Падови сада + + + + Quota n/a + Квота н/о + + + + %1% of %2 in use + %1% од %2 искоришћено + + + + No items synced recently + Ништа није недавно синхронизовано + + + + Discovering '%1' + Откривам „%1“ + + + + Syncing %1 of %2 (%3 left) + Синхронизујем %1 од %2 (преостало %3) + + + + Syncing %1 (%2 left) + Синхронизујем %1 (преостало %2) + + + + %1 (%2, %3) + %1 (%2, %3) + + + + Up to date + Ажурно + + + + OCC::ownCloudTheme + + + <p>Version %2. For more information visit <a href="%3">%4</a></p><p><small>By Klaas Freitag, Daniel Molkentin, Jan-Christoph Borchardt, Olivier Goffart, Markus Götz and others.</small></p><p>Copyright ownCloud, Inc.</p><p>Licensed under the GNU General Public License (GPL) Version 2.0<br/>ownCloud and the ownCloud Logo are registered trademarks of ownCloud, Inc. in the United States, other countries, or both.</p> + <p>Верзија %2. За више информација посетите <a href="%3">%4</a></p><p><small>Клас Фрајтаг (Klaas Freitag), Данијел Мелкентин (Daniel Molkentin), Жан-Кристоф Боршар (Jan-Christoph Borchardt), Оливије Гофар (Olivier Goffart), Маркус Гец (Markus Götz) и остали.</small></p><p>Ауторска права ownCloud, Inc.</p><p>Лиценцирано под ГНУ Општом јавном лиценцом ОЈЛ (GPL) верзије 2.0<br/>оунКлауд и оунКлауд логотип су регистроване робне марке ownCloud, Inc. у САД, другим земљама, или обоје.</p> + + + + OwncloudAdvancedSetupPage + + + Form + Образац + + + + + + + + + + TextLabel + Текст ознака + + + + Server + Сервер + + + + Choose what to sync + Изаберите шта синхронизовати + + + + &Local Folder + &Локална фасцикла + + + + &Start a clean sync (Erases the local folder!) + &Почни чисту синхронизацију (брише локалну фасциклу!) + + + + pbSelectLocalFolder + pbSelectLocalFolder + + + + &Keep local data + &Остави локалне податке + + + + <html><head/><body><p>If this box is checked, existing content in the local directory will be erased to start a clean sync from the server.</p><p>Do not check this if the local content should be uploaded to the servers directory.</p></body></html> + <html><head/><body><p>Ако је ово поље штриклирано, постојећи садржај у локалном директоријуму ће бити обрисани да би започео нову синхронизацију са сервера.</p><p>Немојте ово штриклирати ако требате отпремити локални садржај на директоријуме сервера.</p></body></html> + + + + S&ync everything from server + Син&хронизуј све са сервера + + + + Status message + Порука стања + + + + OwncloudConnectionMethodDialog + + + Connection failed + Неуспешно повезивање + + + + <html><head/><body><p>Failed to connect to the secure server address specified. How do you wish to proceed?</p></body></html> + <html><head/><body><p>Не могу да се повежем на наведену сигурну адресу сервера. Како желите да наставите?</p></body></html> + + + + Select a different URL + Изабери други УРЛ + + + + Retry unencrypted over HTTP (insecure) + Покушај нешифровано преко ХТТП (несигурно) + + + + Configure client-side TLS certificate + Подеси клијентски ТЛС сертификат + + + + <html><head/><body><p>Failed to connect to the secure server address <em>%1</em>. How do you wish to proceed?</p></body></html> + <html><head/><body><p>Не могу да се повежем на сигурну адресу сервера <em>%1</em>. Како желите да наставите?</p></body></html> + + + + OwncloudHttpCredsPage + + + Form + Образац + + + + &Username + &Корисничко име + + + + &Password + &Лозинка + + + + Error Label + Ознака грешке + + + + + TextLabel + Текст ознака + + + + OwncloudSetupPage + + + + Form + Образац + + + + Server &address: + &Адреса сервера: + + + + + + + + TextLabel + Текст ознака + + + + Use &secure connection + Користи &безбедну везу + + + + CheckBox + Кућица + + + + &Username: + &Корисничко име: + + + + Enter the ownCloud username. + Унесите ОунКлауд корисничко име. + + + + &Password: + &Лозинка: + + + + Enter the ownCloud password. + Унесите ОунКлауд лозинку. + + + + Do not allow the local storage of the password. + Не дозволи локално смештање лозинке. + + + + &Do not store password on local machine + &Не смештај лозинку на локалној машини + + + + https:// + https:// + + + + Enter the url of the ownCloud you want to connect to (without http or https). + Унесите адресу ОунКлауда са којим желите да се повежете (без http или https) + + + + Server &Address + &Адреса сервера + + + + https://... + https://... + + + + Error Label + Ознака грешке + + + + OwncloudWizardResultPage + + + Form + Образац + + + + TextLabel + Текст ознака + + + + Your entire account is synced to the local folder + Целокупан налог је синхронизован са локалном фасциклом + + + + + PushButton + ПритисниТастер + + + + Utility + + + %L1 TiB + %L1 TiB + + + + %L1 GiB + %L1 GiB + + + + %L1 MiB + %L1 MiB + + + + %L1 KiB + %L1 KiB + + + + %L1 B + %L1 B + + + + main.cpp + + + System Tray not available + Системска касета није доступна + + + + %1 requires on a working system tray. If you are running XFCE, please follow <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">these instructions</a>. Otherwise, please install a system tray application such as 'trayer' and try again. + %1 захтева системску касету. Ако сте у ИксФЦЕ, испратите <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">ова упутства</a>, или инсталирајте апликацију системске касете и покушајте поново. + + + + ownCloudTheme::about() + + + <p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5.</small></p> + <p><small>Створено од ГИТ ревизије <a href="%1">%2</a> на %3, %4 помоћу КуТ %5.</small></p> + + + + progress + + + Downloaded + Преузето + + + + Uploaded + Отпремљено + + + + Deleted + Обрисано + + + + Moved to %1 + Премештено у %1 + + + + Ignored + Игнорисано + + + + Filesystem access error + Грешка приступа фајл-систему + + + + Error + Грешка + + + + + Unknown + Непознато + + + + downloading + преузимам + + + + uploading + отпремам + + + + deleting + бришем + + + + moving + премештам + + + + ignoring + игноришем + + + + + error + грешка + + + + theme + + + Status undefined + Неодређено стање + + + + Waiting to start sync + Чекам почетак синхронизације + + + + Sync is running + Синхронизација у току + + + + Sync Success + Успешна синхронизација + + + + Sync Success, some files were ignored. + Синхронизација успешна. Неки фајлови су игнорисани. + + + + Sync Error + Грешка синхронизације + + + + Setup Error + Грешка подешавања + + + + Preparing to sync + Припремам синхронизацију + + + + Aborting... + Прекидам... + + + + Sync is paused + Синхронизација паузирана + + \ No newline at end of file From 8bb4af067a1fbb5173324137d23bd4323d5d4b4f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 16 Apr 2015 11:21:39 +0200 Subject: [PATCH 30/30] Propagate download: Fix restoring files for which the conflict file exists For issue #3106 1) Always use the actual timestamp from the file in the file system to create the conflict file. This is important because if one edit a file several time, they should have different name. Also it makes more sens to have the mtime of the modified file. 2) Give the correct size to the job so we know when the temporary file is complete in case of resuming. --- src/libsync/propagator_legacy.cpp | 3 ++- src/libsync/syncengine.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libsync/propagator_legacy.cpp b/src/libsync/propagator_legacy.cpp index dc714b607..b9dc7e8cd 100644 --- a/src/libsync/propagator_legacy.cpp +++ b/src/libsync/propagator_legacy.cpp @@ -695,7 +695,8 @@ void PropagateDownloadFileLegacy::start() && !FileSystem::fileEquals(fn, tmpFile.fileName()); // compare the files to see if there was an actual conflict. //In case of conflict, make a backup of the old file if (isConflict) { - QString conflictFileName = makeConflictFileName(fn, Utility::qDateTimeFromTime_t(_item._modtime)); + auto conflictDate = FileSystem::fileExists(fn) ? FileSystem::getModTime(fn) : _item._modtime; + QString conflictFileName = makeConflictFileName(fn, Utility::qDateTimeFromTime_t(conflictDate)); QString renameError; if (!FileSystem::rename(fn, conflictFileName, &renameError)) { //If the rename fails, don't replace it. diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index d8fa74a89..81d087297 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -999,8 +999,8 @@ void SyncEngine::checkForPermission() it->_direction = SyncFileItem::Down; it->_isRestoration = true; // take the things to write to the db from the "other" node (i.e: info from server) - // ^^ FIXME This might not be needed anymore since we merge the info in treewalkFile it->_modtime = it->log._other_modtime; + it->_size = it->log._other_size; it->_fileId = it->log._other_fileId; it->_etag = it->log._other_etag; it->_errorString = tr("Not allowed to upload this file because it is read-only on the server, restoring");