From 1b2a8ba6b06f3ff0699b252ca8e98a283673fae4 Mon Sep 17 00:00:00 2001 From: rockihack Date: Sun, 10 Dec 2017 17:03:19 +0100 Subject: [PATCH 001/138] Enable stack-protector-strong on Windows and macOS. (cherry picked from commit 586fd346ead9aaa21aace8b2ffd616f0cc249a9e) --- src/CMakeLists.txt | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f2802b624..d0fa8c704 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,19 +8,10 @@ if(NOT TOKEN_AUTH_ONLY) find_package(Qt5Keychain REQUIRED) endif() -if(WIN32) - # Enable DEP & ASLR - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--nxcompat -Wl,--dynamicbase") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--nxcompat -Wl,--dynamicbase") -elseif(UNIX AND NOT APPLE) - if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") - if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong") - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector --param=ssp-buffer-size=4") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector --param=ssp-buffer-size=4") - endif() +if(NOT MSVC) + if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector --param=ssp-buffer-size=4") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector --param=ssp-buffer-size=4") else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong") @@ -31,7 +22,13 @@ elseif(UNIX AND NOT APPLE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FORTIFY_SOURCE=2") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2") endif() +endif() +if(WIN32) + # Enable DEP & ASLR + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--nxcompat -Wl,--dynamicbase") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--nxcompat -Wl,--dynamicbase") +elseif(UNIX AND NOT APPLE) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,now") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,now") endif() From 5cc3b526e855604830c56a619e8ce66bc55c8cfe Mon Sep 17 00:00:00 2001 From: rockihack Date: Mon, 11 Dec 2017 15:18:30 +0100 Subject: [PATCH 002/138] stack-protector is not supported on hppa. (cherry picked from commit 8a963a67f25fe9226d8700ceaf119e2010c8738c) --- src/CMakeLists.txt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d0fa8c704..172422988 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,12 +9,14 @@ if(NOT TOKEN_AUTH_ONLY) endif() if(NOT MSVC) - if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector --param=ssp-buffer-size=4") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector --param=ssp-buffer-size=4") - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong") + if(NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "^(parisc|hppa)")) + if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector --param=ssp-buffer-size=4") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector --param=ssp-buffer-size=4") + else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong") + endif() endif() string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) From b357003a95da989070c562f4afe4f7955301269d Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Thu, 14 Dec 2017 02:18:37 +0100 Subject: [PATCH 003/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_ca.ts | 26 +++++++++++++++++--------- translations/client_cs.ts | 26 +++++++++++++++++--------- translations/client_de.ts | 26 +++++++++++++++++--------- translations/client_el.ts | 26 +++++++++++++++++--------- translations/client_en.ts | 26 +++++++++++++++++--------- translations/client_es.ts | 26 +++++++++++++++++--------- translations/client_es_AR.ts | 26 +++++++++++++++++--------- translations/client_et.ts | 26 +++++++++++++++++--------- translations/client_eu.ts | 26 +++++++++++++++++--------- translations/client_fa.ts | 26 +++++++++++++++++--------- translations/client_fi.ts | 26 +++++++++++++++++--------- translations/client_fr.ts | 26 +++++++++++++++++--------- translations/client_gl.ts | 26 +++++++++++++++++--------- translations/client_hu.ts | 26 +++++++++++++++++--------- translations/client_it.ts | 26 +++++++++++++++++--------- translations/client_ja.ts | 26 +++++++++++++++++--------- translations/client_nb_NO.ts | 26 +++++++++++++++++--------- translations/client_nl.ts | 26 +++++++++++++++++--------- translations/client_pl.ts | 26 +++++++++++++++++--------- translations/client_pt.ts | 26 +++++++++++++++++--------- translations/client_pt_BR.ts | 26 +++++++++++++++++--------- translations/client_ru.ts | 26 +++++++++++++++++--------- translations/client_sk.ts | 26 +++++++++++++++++--------- translations/client_sl.ts | 26 +++++++++++++++++--------- translations/client_sr.ts | 26 +++++++++++++++++--------- translations/client_sv.ts | 26 +++++++++++++++++--------- translations/client_th.ts | 26 +++++++++++++++++--------- translations/client_tr.ts | 26 +++++++++++++++++--------- translations/client_uk.ts | 26 +++++++++++++++++--------- translations/client_zh_CN.ts | 26 +++++++++++++++++--------- translations/client_zh_TW.ts | 26 +++++++++++++++++--------- 32 files changed, 530 insertions(+), 279 deletions(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index 79b65d54b..a57124e37 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -77,6 +77,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_ca.ts b/translations/client_ca.ts index b7c4490e9..3dd48576a 100644 --- a/translations/client_ca.ts +++ b/translations/client_ca.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Activitat del servidor - + Sync Protocol Protocol de sincronització - + Not Synced No sincronitzat - + Not Synced (%1) %1 is the number of not synced files. No sincronitzat (%1) - + The server activity list has been copied to the clipboard. La llista de l'activitat del servidor s'ha copiat al porta-retalls. - + The sync activity list has been copied to the clipboard. La llista d'activitat de sincronització s'ha copiat al porta-retalls - + The list of unsynced items has been copied to the clipboard. S'ha copiat una llista d'elements no sincronitzats al porta-retalls. - + Copied to clipboard S'ha copiat al porta-retalls @@ -2497,6 +2497,14 @@ No és aconsellada usar-la. S'ha produit un error en carregar la llista de subcarpetes. + + OCC::ServerNotificationHandler + + + Dismiss + + + OCC::SettingsDialog diff --git a/translations/client_cs.ts b/translations/client_cs.ts index 6c73f1bae..909f61a03 100644 --- a/translations/client_cs.ts +++ b/translations/client_cs.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Aktivita serveru - + Sync Protocol Protokol synchronizace - + Not Synced Nesesynchronizováno - + Not Synced (%1) %1 is the number of not synced files. Nesesynchronizováno (%1) - + The server activity list has been copied to the clipboard. Výpis aktivity serveru byl zkopírován do schránky. - + The sync activity list has been copied to the clipboard. Výpis aktivity synchronizace byl zkopírován do schránky. - + The list of unsynced items has been copied to the clipboard. Seznam nesynchronizovaných položek byl zkopírován do schránky. - + Copied to clipboard Zkopírováno do schránky @@ -2500,6 +2500,14 @@ Nedoporučuje se jí používat. Došlo k chybě v průběhu načítání seznamu podadresářů. + + OCC::ServerNotificationHandler + + + Dismiss + Zamítnout + + OCC::SettingsDialog diff --git a/translations/client_de.ts b/translations/client_de.ts index 40ef6dd31..3f75f5db7 100644 --- a/translations/client_de.ts +++ b/translations/client_de.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Serveraktivität - + Sync Protocol Synchronisationsprotokoll - + Not Synced nicht synchronisiert - + Not Synced (%1) %1 is the number of not synced files. nicht synchronisiert (%1) - + The server activity list has been copied to the clipboard. Die Server-Aktivitätsliste wurde in die Zwischenablage kopiert. - + The sync activity list has been copied to the clipboard. Die Synchronisationsliste wurde in die Zwischenablage kopiert. - + The list of unsynced items has been copied to the clipboard. Die Liste der unsynchronisierten Dateien wurde in die Zwischenablage kopiert. - + Copied to clipboard In die Zwischenablage kopiert @@ -2501,6 +2501,14 @@ Es ist nicht ratsam, diese zu benutzen. Ein Fehler ist aufgetreten, während die Liste der Unterordner geladen wurde. + + OCC::ServerNotificationHandler + + + Dismiss + Ausblenden + + OCC::SettingsDialog diff --git a/translations/client_el.ts b/translations/client_el.ts index c4ed10508..54d65ec3c 100644 --- a/translations/client_el.ts +++ b/translations/client_el.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Δραστηριότητα διακομιστή - + Sync Protocol Προτοκολο συγχρονισμου - + Not Synced Δεν είναι συγχρονισμένα - + Not Synced (%1) %1 is the number of not synced files. Δεν είναι συγχρονισμένα (%1) - + The server activity list has been copied to the clipboard. Ο κατάλογος δραστηριοτήτων του διακομιστή έχει αντιγραφθεί στο Πρόχειρο - + The sync activity list has been copied to the clipboard. Ο κατάλογος της δραστηριότητας συγχρονισμού έχει αντιγραφθεί στο Πρόχειρο - + The list of unsynced items has been copied to the clipboard. Η λίστα των μη συγχρονισμένων αντικειμένων έχει αντιγραφεί στο πρόχειρο - + Copied to clipboard Αντιγράφηκε στο πρόχειρο @@ -2502,6 +2502,14 @@ It is not advisable to use it. Παρουσιάστηκε σφάλμα κατά την φόρτωση της λίστας των υπο-φακέλων + + OCC::ServerNotificationHandler + + + Dismiss + Απόρριψη + + OCC::SettingsDialog diff --git a/translations/client_en.ts b/translations/client_en.ts index b5288470d..9c59d700e 100644 --- a/translations/client_en.ts +++ b/translations/client_en.ts @@ -414,44 +414,44 @@ OCC::ActivitySettings - - + + Server Activity - + Sync Protocol - + Not Synced - + Not Synced (%1) %1 is the number of not synced files. - + The server activity list has been copied to the clipboard. - + The sync activity list has been copied to the clipboard. - + The list of unsynced items has been copied to the clipboard. - + Copied to clipboard @@ -2521,6 +2521,14 @@ It is not advisable to use it. + + OCC::ServerNotificationHandler + + + Dismiss + + + OCC::SettingsDialog diff --git a/translations/client_es.ts b/translations/client_es.ts index f5588ea94..0d468b8bc 100644 --- a/translations/client_es.ts +++ b/translations/client_es.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Actividad del servidor - + Sync Protocol Protocolo de Sincronización - + Not Synced No sincronizado - + Not Synced (%1) %1 is the number of not synced files. No Sincronizado (%1) - + The server activity list has been copied to the clipboard. La lista de la actividad del servidor se ha copiado en el portapapeles. - + The sync activity list has been copied to the clipboard. La lista de actividades de sincronización se ha copiado en el portapapeles. - + The list of unsynced items has been copied to the clipboard. La lista de elementos sin sincronizar, ha sido copiada al portapapeles. - + Copied to clipboard Copiado al portapapeles @@ -2501,6 +2501,14 @@ No se recomienda usarla. Ha ocurrido un error mientras cargaba la lista de carpetas. + + OCC::ServerNotificationHandler + + + Dismiss + Descartar + + OCC::SettingsDialog diff --git a/translations/client_es_AR.ts b/translations/client_es_AR.ts index 5663831ad..193786e30 100644 --- a/translations/client_es_AR.ts +++ b/translations/client_es_AR.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Actividad de Servidor - + Sync Protocol Protocolo de Sincronización - + Not Synced No Sincronizado - + Not Synced (%1) %1 is the number of not synced files. No Sincronizado (%1) - + The server activity list has been copied to the clipboard. - + The sync activity list has been copied to the clipboard. - + The list of unsynced items has been copied to the clipboard. - + Copied to clipboard Copiado al portapapeles @@ -2489,6 +2489,14 @@ It is not advisable to use it. + + OCC::ServerNotificationHandler + + + Dismiss + + + OCC::SettingsDialog diff --git a/translations/client_et.ts b/translations/client_et.ts index 8830831a6..8a687f3a9 100644 --- a/translations/client_et.ts +++ b/translations/client_et.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Serveri aktiivsus - + Sync Protocol Sünkroniseerimisprotokoll - + Not Synced Pole sünkroonitud - + Not Synced (%1) %1 is the number of not synced files. - + The server activity list has been copied to the clipboard. - + The sync activity list has been copied to the clipboard. - + The list of unsynced items has been copied to the clipboard. - + Copied to clipboard Kopeeritud lõikepuhvrisse @@ -2490,6 +2490,14 @@ Selle kasutamine pole soovitatav. + + OCC::ServerNotificationHandler + + + Dismiss + Jäta vahele + + OCC::SettingsDialog diff --git a/translations/client_eu.ts b/translations/client_eu.ts index cf37af90a..8361c94c4 100644 --- a/translations/client_eu.ts +++ b/translations/client_eu.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Zerbitzariaren Jarduera - + Sync Protocol Sinkronizazio protokoloa - + Not Synced Sinkronizatu gabekoak - + Not Synced (%1) %1 is the number of not synced files. - + The server activity list has been copied to the clipboard. - + The sync activity list has been copied to the clipboard. - + The list of unsynced items has been copied to the clipboard. - + Copied to clipboard Arbelera kopiatua @@ -2492,6 +2492,14 @@ Ez da gomendagarria erabltzea. + + OCC::ServerNotificationHandler + + + Dismiss + + + OCC::SettingsDialog diff --git a/translations/client_fa.ts b/translations/client_fa.ts index cdc94a553..c240d8875 100644 --- a/translations/client_fa.ts +++ b/translations/client_fa.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity فعالیت سرور - + Sync Protocol پروتکل همگام سازی - + Not Synced - + Not Synced (%1) %1 is the number of not synced files. - + The server activity list has been copied to the clipboard. - + The sync activity list has been copied to the clipboard. - + The list of unsynced items has been copied to the clipboard. - + Copied to clipboard کپی به کلیپ بورد @@ -2489,6 +2489,14 @@ It is not advisable to use it. + + OCC::ServerNotificationHandler + + + Dismiss + پنهان کن + + OCC::SettingsDialog diff --git a/translations/client_fi.ts b/translations/client_fi.ts index 1d1138c10..a8ac165ac 100644 --- a/translations/client_fi.ts +++ b/translations/client_fi.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Palvelimen toimet - + Sync Protocol Synkronointiprotokolla - + Not Synced Ei synkronoitu - + Not Synced (%1) %1 is the number of not synced files. Ei synkronoitu (%1) - + The server activity list has been copied to the clipboard. - + The sync activity list has been copied to the clipboard. - + The list of unsynced items has been copied to the clipboard. - + Copied to clipboard Kopioitu leikepöydälle @@ -2492,6 +2492,14 @@ Osoitteen käyttäminen ei ole suositeltavaa. Alikansioluetteloa ladatessa tapahtui virhe. + + OCC::ServerNotificationHandler + + + Dismiss + Hylkää + + OCC::SettingsDialog diff --git a/translations/client_fr.ts b/translations/client_fr.ts index c436a0661..f475f7c23 100644 --- a/translations/client_fr.ts +++ b/translations/client_fr.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Activité serveur - + Sync Protocol Activité de synchronisation - + Not Synced Fichiers non synchronisés - + Not Synced (%1) %1 is the number of not synced files. Non Synchronisé (%1) - + The server activity list has been copied to the clipboard. L'historique des opérations sur le serveur a été copié dans le presse-papier. - + The sync activity list has been copied to the clipboard. L'historique des opérations locales a été copié dans le presse-papier. - + The list of unsynced items has been copied to the clipboard. La liste des éléments non synchronisés a été copiée dans le presse-papier. - + Copied to clipboard Copié dans le presse-papier @@ -2503,6 +2503,14 @@ Il est déconseillé de l'utiliser. Une erreur est survenue lors du chargement de la liste des sous-dossiers. + + OCC::ServerNotificationHandler + + + Dismiss + Ignorer + + OCC::SettingsDialog diff --git a/translations/client_gl.ts b/translations/client_gl.ts index bd0fbd54a..7ec393444 100644 --- a/translations/client_gl.ts +++ b/translations/client_gl.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Actividade do servidor - + Sync Protocol Protocolo de sincronización - + Not Synced Non sincronizado - + Not Synced (%1) %1 is the number of not synced files. Non sincronizado (%1) - + The server activity list has been copied to the clipboard. A lista de actividade do servidor copiouse no portapapeis. - + The sync activity list has been copied to the clipboard. A lista de actividade de sincronización foi copiada ao portapapeis. - + The list of unsynced items has been copied to the clipboard. A lista de elementos non sincronizados foi copiada ao portapapeis. - + Copied to clipboard Copiado no portapapeis. @@ -2491,6 +2491,14 @@ Recomendámoslle que non o use. + + OCC::ServerNotificationHandler + + + Dismiss + Desbotar + + OCC::SettingsDialog diff --git a/translations/client_hu.ts b/translations/client_hu.ts index decde9b8c..f1cde2944 100644 --- a/translations/client_hu.ts +++ b/translations/client_hu.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Szerver aktivitás - + Sync Protocol Szinkronizációs protokoll - + Not Synced Nincs szinkronizálva - + Not Synced (%1) %1 is the number of not synced files. Nincs szinkronizálva (%1) - + The server activity list has been copied to the clipboard. A szerver aktivitási lista a vágólapra másolva. - + The sync activity list has been copied to the clipboard. A szinkronizációs aktivitási lista a vágólapra másolva. - + The list of unsynced items has been copied to the clipboard. - + Copied to clipboard Másolva a vágólapra @@ -2489,6 +2489,14 @@ It is not advisable to use it. + + OCC::ServerNotificationHandler + + + Dismiss + Elutasít + + OCC::SettingsDialog diff --git a/translations/client_it.ts b/translations/client_it.ts index 50cd825f9..7ee834788 100644 --- a/translations/client_it.ts +++ b/translations/client_it.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Attività del server - + Sync Protocol Protocollo di sincronizzazione - + Not Synced Non sincronizzata - + Not Synced (%1) %1 is the number of not synced files. Non sincronizzata (%1) - + The server activity list has been copied to the clipboard. L'elenco di attività del server è stato copiato negli appunti. - + The sync activity list has been copied to the clipboard. L'elenco di attività di sincronizzazione è stato copiato negli appunti. - + The list of unsynced items has been copied to the clipboard. L'elenco di elementi non sincronizzati è stato copiato negli appunti. - + Copied to clipboard Copiato negli appunti @@ -2497,6 +2497,14 @@ Non è consigliabile utilizzarlo. Si è verificato un errore durante il caricamento dell'elenco delle sottocartelle. + + OCC::ServerNotificationHandler + + + Dismiss + Annulla + + OCC::SettingsDialog diff --git a/translations/client_ja.ts b/translations/client_ja.ts index 4d509b624..b96ed51eb 100644 --- a/translations/client_ja.ts +++ b/translations/client_ja.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity サーバーアクティビティ - + Sync Protocol 同期状況 - + Not Synced 同期対象外 - + Not Synced (%1) %1 is the number of not synced files. 未同期 (%1) - + The server activity list has been copied to the clipboard. サーバーアクティビティリストをクリップボードにコピーしました。 - + The sync activity list has been copied to the clipboard. 同期状況をクリップボードにコピーしました。 - + The list of unsynced items has been copied to the clipboard. 同期されていないアイテムのリストがクリップボードにコピーされました。 - + Copied to clipboard クリップボードにコピー @@ -2498,6 +2498,14 @@ It is not advisable to use it. サーバーからフォルダーのリスト取得時にエラーが発生しました。 + + OCC::ServerNotificationHandler + + + Dismiss + 閉じる + + OCC::SettingsDialog diff --git a/translations/client_nb_NO.ts b/translations/client_nb_NO.ts index 42c272b95..0487ff954 100644 --- a/translations/client_nb_NO.ts +++ b/translations/client_nb_NO.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Server-aktivitet - + Sync Protocol Synkroniseringsprotokoll - + Not Synced Ikke synkronisert - + Not Synced (%1) %1 is the number of not synced files. Ikke synkronisert (%1) - + The server activity list has been copied to the clipboard. Server-aktivitetslisten er kopiert til utklippstavlen. - + The sync activity list has been copied to the clipboard. Synkroniserings-aktivitetslisten er kopiert til utklippstavlen. - + The list of unsynced items has been copied to the clipboard. Listen med usynkroniserte elementer ble kopiert til utklippstavlen. - + Copied to clipboard Kopiert til utklippstavlen @@ -2501,6 +2501,14 @@ Det er ikke tilrådelig å bruke den. Det oppstod en feil ved lasting av liten med undermapper. + + OCC::ServerNotificationHandler + + + Dismiss + Forkast + + OCC::SettingsDialog diff --git a/translations/client_nl.ts b/translations/client_nl.ts index 7aff8a8c8..9488dacdd 100644 --- a/translations/client_nl.ts +++ b/translations/client_nl.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Serveractiviteit - + Sync Protocol Synchronisatiegeschiedenis - + Not Synced Niet gesynchroniseerd - + Not Synced (%1) %1 is the number of not synced files. Niet gesynchroniseerd (%1) - + The server activity list has been copied to the clipboard. De server activiteitenlijst is gekopieerd naar het klembord. - + The sync activity list has been copied to the clipboard. De sync activiteitenlijst is gekopieerd naar het klembord. - + The list of unsynced items has been copied to the clipboard. De lijst met niet gesyncte objecten is gekopieerd naar het klembord. - + Copied to clipboard Gekopieerd naar het klembord @@ -2506,6 +2506,14 @@ We adviseren deze site niet te gebruiken. Er trad een fout op bij het laden van de lijst met submappen. + + OCC::ServerNotificationHandler + + + Dismiss + Terzijde leggen + + OCC::SettingsDialog diff --git a/translations/client_pl.ts b/translations/client_pl.ts index 515acd5b2..cd205f306 100644 --- a/translations/client_pl.ts +++ b/translations/client_pl.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Aktywność serwera - + Sync Protocol Protokół synchronizacji - + Not Synced Niezsynchronizowany - + Not Synced (%1) %1 is the number of not synced files. Niezsynchronizowany (%1) - + The server activity list has been copied to the clipboard. Log aktywności serwera został skopiowany do schowka. - + The sync activity list has been copied to the clipboard. Przebieg synchronizacji został skopiowany do schowka. - + The list of unsynced items has been copied to the clipboard. Lista niezsynchronizowanych elementów została skopiowana do schowka - + Copied to clipboard Skopiuj do schowka @@ -2498,6 +2498,14 @@ Niezalecane jest jego użycie. Wystąpił błąd podczas wczytywania listy podfolderów + + OCC::ServerNotificationHandler + + + Dismiss + Anuluj + + OCC::SettingsDialog diff --git a/translations/client_pt.ts b/translations/client_pt.ts index fad3f1776..35705b34f 100644 --- a/translations/client_pt.ts +++ b/translations/client_pt.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Atividade do Servidor - + Sync Protocol Protocolo de Sincronização - + Not Synced Não Sincronizado - + Not Synced (%1) %1 is the number of not synced files. Não Sincronizado (%1) - + The server activity list has been copied to the clipboard. A lista de atividades do servidor foi copiada para a área de transferência. - + The sync activity list has been copied to the clipboard. A lista de atividades de sincronização foi copiada para a área de transferência. - + The list of unsynced items has been copied to the clipboard. A lista de itens não sincronizados foi copiada para a área de transferência. - + Copied to clipboard Copiado para a área de transferência @@ -2502,6 +2502,14 @@ Não é aconselhada a sua utilização. Ocorreu um erro ao carregar a lista das sub pastas. + + OCC::ServerNotificationHandler + + + Dismiss + Rejeitar + + OCC::SettingsDialog diff --git a/translations/client_pt_BR.ts b/translations/client_pt_BR.ts index 6dbcd008f..e6c5c7608 100644 --- a/translations/client_pt_BR.ts +++ b/translations/client_pt_BR.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Atividade do Servidor - + Sync Protocol Protocolo de Sincronização - + Not Synced Não Sincronizado - + Not Synced (%1) %1 is the number of not synced files. Não sincronizada (%1) - + The server activity list has been copied to the clipboard. A lista de atividades do servidor tem sido copiados para o clipboard. - + The sync activity list has been copied to the clipboard. A lista de atividades do servidor foi copiada para a área de transferência. - + The list of unsynced items has been copied to the clipboard. A lista de itens não sincronizados foi copiada para a área de transferência. - + Copied to clipboard Copiado para área de transferência @@ -2499,6 +2499,14 @@ It is not advisable to use it. Ocorreu um erro enquanto carregava a lista de subpastas. + + OCC::ServerNotificationHandler + + + Dismiss + Dispensar + + OCC::SettingsDialog diff --git a/translations/client_ru.ts b/translations/client_ru.ts index ba0d719f6..944313b65 100644 --- a/translations/client_ru.ts +++ b/translations/client_ru.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Действия Сервера - + Sync Protocol Протокол синхронизации - + Not Synced Не синхронизировано - + Not Synced (%1) %1 is the number of not synced files. Не синхронизировано (%1) - + The server activity list has been copied to the clipboard. Список активности сервера скопирован в буфер обмена. - + The sync activity list has been copied to the clipboard. Список активности синхронизации скопирован в буфер обмена. - + The list of unsynced items has been copied to the clipboard. Список несинхронизированных элементов скопирован в буфер обмена. - + Copied to clipboard Скопировано в буфер обмена @@ -2499,6 +2499,14 @@ It is not advisable to use it. Произошла ошибка во время загрузки списка подпапок. + + OCC::ServerNotificationHandler + + + Dismiss + Убрать + + OCC::SettingsDialog diff --git a/translations/client_sk.ts b/translations/client_sk.ts index 1db2d935f..4d32078af 100644 --- a/translations/client_sk.ts +++ b/translations/client_sk.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Aktivita servera - + Sync Protocol Záznam synchronizácie - + Not Synced Nezosynchronizované - + Not Synced (%1) %1 is the number of not synced files. Nezosynchronizované (%1) - + The server activity list has been copied to the clipboard. Zoznam aktivít servera bol skopírovaný do schránky. - + The sync activity list has been copied to the clipboard. Zoznam aktivít synchronizácie bol skopírovaný do schránky. - + The list of unsynced items has been copied to the clipboard. - + Copied to clipboard Skopírované do schránky @@ -2491,6 +2491,14 @@ Nie je vhodné ju používať. + + OCC::ServerNotificationHandler + + + Dismiss + Odmietnuť + + OCC::SettingsDialog diff --git a/translations/client_sl.ts b/translations/client_sl.ts index 8911d5ab7..d0819235d 100644 --- a/translations/client_sl.ts +++ b/translations/client_sl.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Dejavnost strežnika - + Sync Protocol Protokol usklajevanja - + Not Synced Ni usklajeno - + Not Synced (%1) %1 is the number of not synced files. Ni usklajeno (%1) - + The server activity list has been copied to the clipboard. Seznam opravil strežnika je kopiran v odložišče. - + The sync activity list has been copied to the clipboard. Seznam opravil usklajevanja je kopiran v odložišče. - + The list of unsynced items has been copied to the clipboard. Seznam neusklajenih predmetov je kopiran v odložišče. - + Copied to clipboard Kopirano v odložišče @@ -2502,6 +2502,14 @@ Uporaba ni priporočljiva. Prišlo je do napake med nalaganjem seznama podrejenih map. + + OCC::ServerNotificationHandler + + + Dismiss + Opusti + + OCC::SettingsDialog diff --git a/translations/client_sr.ts b/translations/client_sr.ts index 2f2b30b57..a039d862e 100644 --- a/translations/client_sr.ts +++ b/translations/client_sr.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Активност сервера - + Sync Protocol Протокол синхронизације - + Not Synced Несинхронизовано - + Not Synced (%1) %1 is the number of not synced files. - + The server activity list has been copied to the clipboard. - + The sync activity list has been copied to the clipboard. - + The list of unsynced items has been copied to the clipboard. - + Copied to clipboard Копирано у клипборд @@ -2491,6 +2491,14 @@ It is not advisable to use it. + + OCC::ServerNotificationHandler + + + Dismiss + Откажи + + OCC::SettingsDialog diff --git a/translations/client_sv.ts b/translations/client_sv.ts index 9d7462f6a..14c99f75c 100644 --- a/translations/client_sv.ts +++ b/translations/client_sv.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Serveraktivitet - + Sync Protocol Synkprotokoll - + Not Synced Inte synkroniserad - + Not Synced (%1) %1 is the number of not synced files. Inte synkad (%1) - + The server activity list has been copied to the clipboard. Listan på serveraktivitet har kopierats till urklipp. - + The sync activity list has been copied to the clipboard. Listan på synkaktivitet har kopierats till urklipp. - + The list of unsynced items has been copied to the clipboard. Listan över ej synkroniserat har kopierats till klippbordet. - + Copied to clipboard Kopierat till urklipp @@ -2497,6 +2497,14 @@ Det är inte lämpligt använda den. Ett fel uppstod när listan för submappar laddades. + + OCC::ServerNotificationHandler + + + Dismiss + Avfärda + + OCC::SettingsDialog diff --git a/translations/client_th.ts b/translations/client_th.ts index de8224547..713eafbd2 100644 --- a/translations/client_th.ts +++ b/translations/client_th.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity กิจกรรมของเซิร์ฟเวอร์ - + Sync Protocol โปรโตคอลที่ใช้ในการผสานข้อมูล - + Not Synced ไม่ถูกประสานข้อมูลให้ตรงกัน - + Not Synced (%1) %1 is the number of not synced files. ไม่ถูกประสานข้อมูล (%1) - + The server activity list has been copied to the clipboard. รายการกิจกรรมเซิร์ฟเวอร์ได้ถูกคัดลอกไปยังคลิปบอร์ด - + The sync activity list has been copied to the clipboard. รายการกิจกรรมการประสานข้อมูลได้ถูกคัดลอกไปยังคลิปบอร์ด - + The list of unsynced items has been copied to the clipboard. รายชื่อของรายการที่ไม่ได้ประสานข้อมูล ได้ถูกคัดลอกไปยังคลิปบอร์ด - + Copied to clipboard คัดลอกไปยังคลิปบอร์ด @@ -2503,6 +2503,14 @@ It is not advisable to use it. เกิดข้อผิดพลาดขณะโหลดรายชื่อของโฟลเดอร์ย่อย + + OCC::ServerNotificationHandler + + + Dismiss + ยกเลิก + + OCC::SettingsDialog diff --git a/translations/client_tr.ts b/translations/client_tr.ts index fce128ea4..266abee13 100644 --- a/translations/client_tr.ts +++ b/translations/client_tr.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Sunucu Etkinliği - + Sync Protocol Eşitleme Protokolü - + Not Synced Eşitlenmedi - + Not Synced (%1) %1 is the number of not synced files. Eşitlenmedi (%1) - + The server activity list has been copied to the clipboard. Sunucu etkinlik listesi panoya kopyalandı. - + The sync activity list has been copied to the clipboard. Eşitleme etkinlik listesi panoya kopyalandı. - + The list of unsynced items has been copied to the clipboard. Eşitlenmemiş ögelerin listesi panoya kopyalandı. - + Copied to clipboard Panoya kopyalandı @@ -2492,6 +2492,14 @@ Kullanmanız önerilmez. Alt klasör listesi alınırken bir hata oluştu. + + OCC::ServerNotificationHandler + + + Dismiss + İptal et + + OCC::SettingsDialog diff --git a/translations/client_uk.ts b/translations/client_uk.ts index fe97e9135..7e365b745 100644 --- a/translations/client_uk.ts +++ b/translations/client_uk.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity Серверна активність - + Sync Protocol Протокол Синхронізації - + Not Synced Не синхронізовано - + Not Synced (%1) %1 is the number of not synced files. Not Synced (%1) - + The server activity list has been copied to the clipboard. Список серверних операцій скопійовано до буферу обміну. - + The sync activity list has been copied to the clipboard. - + The list of unsynced items has been copied to the clipboard. - + Copied to clipboard Скопійовано в буфер обміну @@ -2490,6 +2490,14 @@ It is not advisable to use it. + + OCC::ServerNotificationHandler + + + Dismiss + Припинити + + OCC::SettingsDialog diff --git a/translations/client_zh_CN.ts b/translations/client_zh_CN.ts index 962e0b0a0..b1dcf38da 100644 --- a/translations/client_zh_CN.ts +++ b/translations/client_zh_CN.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity 服务器动态 - + Sync Protocol 同步协议 - + Not Synced 未同步 - + Not Synced (%1) %1 is the number of not synced files. 未同步 (%1) - + The server activity list has been copied to the clipboard. 服务器动态已被复制到剪贴板。 - + The sync activity list has been copied to the clipboard. 同步动态已被复制到剪贴板。 - + The list of unsynced items has been copied to the clipboard. 未同步列表已复制到剪贴板。 - + Copied to clipboard 复制到剪贴板 @@ -2501,6 +2501,14 @@ It is not advisable to use it. 载入子文件夹列表时发生错误。 + + OCC::ServerNotificationHandler + + + Dismiss + 忽略 + + OCC::SettingsDialog diff --git a/translations/client_zh_TW.ts b/translations/client_zh_TW.ts index cdc167a94..42ed3d14b 100644 --- a/translations/client_zh_TW.ts +++ b/translations/client_zh_TW.ts @@ -412,44 +412,44 @@ OCC::ActivitySettings - - + + Server Activity 伺服器活動 - + Sync Protocol 同步協定 - + Not Synced 尚未同步 - + Not Synced (%1) %1 is the number of not synced files. 未同步(%1) - + The server activity list has been copied to the clipboard. 伺服器活動列表已經被複製到剪貼簿。 - + The sync activity list has been copied to the clipboard. 同步活動列表已經被複製到剪貼簿。 - + The list of unsynced items has been copied to the clipboard. 未同步的清單已經被複製到剪貼簿。 - + Copied to clipboard 複製至剪貼簿中 @@ -2493,6 +2493,14 @@ It is not advisable to use it. + + OCC::ServerNotificationHandler + + + Dismiss + + + OCC::SettingsDialog From d8707297090592a8178289848adea18e3c565a04 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Thu, 14 Dec 2017 11:31:30 +0100 Subject: [PATCH 004/138] Require Qt >= 5.6 #6241 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a628ed780..9975452f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -223,7 +223,7 @@ setup_qt() if (${Qt5Core_VERSION_MAJOR} EQUAL "5") if (${Qt5Core_VERSION_MINOR} EQUAL "6" OR ${Qt5Core_VERSION_MINOR} GREATER 6) else() - message(STATUS "If possible compile me with Qt 5.6 or higher.") + message(FATAL_ERROR "Qt 5.6 or higher is required.") endif() if (${Qt5Core_VERSION_MINOR} EQUAL "9" OR ${Qt5Core_VERSION_MINOR} GREATER 9) else() From 4369853ddb21525a9b83f83ef3d44dd838a17d8d Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 11 Dec 2017 17:03:24 +0100 Subject: [PATCH 005/138] TestSystem: Add QIODevice in the serverOverride function, and add a DelayedReply Preparing to add test that needs the QIODevice. Also make the DelayedReply so we can generalize the existing delay on FakeChunkMoveReply to any reply. --- test/syncenginetestutils.h | 38 +++++++++++++++++++++++++++++++------- test/testchunkingng.cpp | 10 +++++----- test/testoauth.cpp | 2 +- test/testsyncengine.cpp | 6 +++--- test/testsyncmove.cpp | 6 +++--- 5 files changed, 43 insertions(+), 19 deletions(-) diff --git a/test/syncenginetestutils.h b/test/syncenginetestutils.h index c9f4e088a..9122040be 100644 --- a/test/syncenginetestutils.h +++ b/test/syncenginetestutils.h @@ -441,7 +441,8 @@ public: QMetaObject::invokeMethod(this, "respond", Qt::QueuedConnection); } - Q_INVOKABLE void respond() { + Q_INVOKABLE virtual void respond() + { emit uploadProgress(fileInfo->size, fileInfo->size); setRawHeader("OC-ETag", fileInfo->etag.toLatin1()); setRawHeader("ETag", fileInfo->etag.toLatin1()); @@ -615,7 +616,7 @@ class FakeChunkMoveReply : public QNetworkReply public: FakeChunkMoveReply(FileInfo &uploadsFileInfo, FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op, const QNetworkRequest &request, - quint64 delayMs, QObject *parent) + QObject *parent) : QNetworkReply{ parent } { setRequest(request); @@ -675,10 +676,11 @@ public: fileInfo->lastModified = OCC::Utility::qDateTimeFromTime_t(request.rawHeader("X-OC-Mtime").toLongLong()); remoteRootFileInfo.find(fileName, /*invalidate_etags=*/true); - QTimer::singleShot(delayMs, this, &FakeChunkMoveReply::respond); + QTimer::singleShot(0, this, &FakeChunkMoveReply::respond); } - Q_INVOKABLE void respond() { + Q_INVOKABLE virtual void respond() + { setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 201); setRawHeader("OC-ETag", fileInfo->etag.toLatin1()); setRawHeader("ETag", fileInfo->etag.toLatin1()); @@ -744,10 +746,32 @@ public: qint64 readData(char *, qint64) override { return 0; } }; +// A delayed reply +template +class DelayedReply : public OriginalReply +{ +public: + template + explicit DelayedReply(quint64 delayMS, Args &&... args) + : OriginalReply(std::forward(args)...) + , _delayMs(delayMS) + { + } + quint64 _delayMs; + + void respond() override + { + QTimer::singleShot(_delayMs, static_cast(this), [this] { + // Explicit call to bases's respond(); + this->OriginalReply::respond(); + }); + } +}; + class FakeQNAM : public QNetworkAccessManager { public: - using Override = std::function; + using Override = std::function; private: FileInfo _remoteRootFileInfo; @@ -770,7 +794,7 @@ protected: QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0) { if (_override) { - if (auto reply = _override(op, request)) + if (auto reply = _override(op, request, outgoingData)) return reply; } const QString fileName = getFilePathFromUrl(request.url()); @@ -796,7 +820,7 @@ protected: else if (verb == QLatin1String("MOVE") && !isUpload) return new FakeMoveReply{info, op, request, this}; else if (verb == QLatin1String("MOVE") && isUpload) - return new FakeChunkMoveReply{ info, _remoteRootFileInfo, op, request, 0, this }; + return new FakeChunkMoveReply{ info, _remoteRootFileInfo, op, request, this }; else { qDebug() << verb << outgoingData; Q_UNREACHABLE(); diff --git a/test/testchunkingng.cpp b/test/testchunkingng.cpp index 78003b295..a61bdc15d 100644 --- a/test/testchunkingng.cpp +++ b/test/testchunkingng.cpp @@ -79,7 +79,7 @@ private slots: // Add a fake file to make sure it gets deleted fakeFolder.uploadState().children.first().insert("10000", size); - fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request) -> QNetworkReply * { + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *) -> QNetworkReply * { if (op == QNetworkAccessManager::PutOperation) { // Test that we properly resuming and are not sending past data again. Q_ASSERT(request.rawHeader("OC-Chunk-Offset").toULongLong() >= uploadedSize); @@ -109,11 +109,11 @@ private slots: QByteArray moveChecksumHeader; int nGET = 0; int responseDelay = 10000; // bigger than abort-wait timeout - fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request) -> QNetworkReply * { + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *) -> QNetworkReply * { if (request.attribute(QNetworkRequest::CustomVerbAttribute) == "MOVE") { QTimer::singleShot(50, parent, [&]() { fakeFolder.syncEngine().abort(); }); moveChecksumHeader = request.rawHeader("OC-Checksum"); - return new FakeChunkMoveReply(fakeFolder.uploadState(), fakeFolder.remoteModifier(), op, request, responseDelay, parent); + return new DelayedReply(responseDelay, fakeFolder.uploadState(), fakeFolder.remoteModifier(), op, request, parent); } else if (op == QNetworkAccessManager::GetOperation) { nGET++; } @@ -203,11 +203,11 @@ private slots: QByteArray moveChecksumHeader; int nGET = 0; int responseDelay = 2000; // smaller than abort-wait timeout - fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request) -> QNetworkReply * { + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *) -> QNetworkReply * { if (request.attribute(QNetworkRequest::CustomVerbAttribute) == "MOVE") { QTimer::singleShot(50, parent, [&]() { fakeFolder.syncEngine().abort(); }); moveChecksumHeader = request.rawHeader("OC-Checksum"); - return new FakeChunkMoveReply(fakeFolder.uploadState(), fakeFolder.remoteModifier(), op, request, responseDelay, parent); + return new DelayedReply(responseDelay, fakeFolder.uploadState(), fakeFolder.remoteModifier(), op, request, parent); } else if (op == QNetworkAccessManager::GetOperation) { nGET++; } diff --git a/test/testoauth.cpp b/test/testoauth.cpp index 76dbb3bc5..49eb3ce6c 100644 --- a/test/testoauth.cpp +++ b/test/testoauth.cpp @@ -111,7 +111,7 @@ public: account->setUrl(sOAuthTestServer); account->setCredentials(new FakeCredentials{fakeQnam}); fakeQnam->setParent(this); - fakeQnam->setOverride([this] (QNetworkAccessManager::Operation op, const QNetworkRequest &req) { + fakeQnam->setOverride([this](QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *) { return this->tokenReply(op, req); }); diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp index e5dccd939..744835efe 100644 --- a/test/testsyncengine.cpp +++ b/test/testsyncengine.cpp @@ -301,7 +301,7 @@ private slots: FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; int nGET = 0; - fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &) { + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &, QIODevice *) { if (op == QNetworkAccessManager::GetOperation) ++nGET; return nullptr; @@ -431,7 +431,7 @@ private slots: int remoteQuota = 1000; int n507 = 0, nPUT = 0; auto parent = new QObject; - fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request) -> QNetworkReply * { + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *) -> QNetworkReply * { if (op == QNetworkAccessManager::PutOperation) { nPUT++; if (request.rawHeader("OC-Total-Length").toInt() > remoteQuota) { @@ -472,7 +472,7 @@ private slots: QByteArray checksumValue; QByteArray contentMd5Value; - fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request) -> QNetworkReply * { + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *) -> QNetworkReply * { if (op == QNetworkAccessManager::GetOperation) { auto reply = new FakeGetReply(fakeFolder.remoteModifier(), op, request, &parent); if (!checksumValue.isNull()) diff --git a/test/testsyncmove.cpp b/test/testsyncmove.cpp index 5049b019a..67d3c22be 100644 --- a/test/testsyncmove.cpp +++ b/test/testsyncmove.cpp @@ -158,7 +158,7 @@ private slots: int nPUT = 0; int nDELETE = 0; - fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &) { + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &, QIODevice *) { if (op == QNetworkAccessManager::PutOperation) ++nPUT; if (op == QNetworkAccessManager::DeleteOperation) @@ -268,7 +268,7 @@ private slots: QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); int nGET = 0; - fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &) { + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &, QIODevice *) { if (op == QNetworkAccessManager::GetOperation) ++nGET; return nullptr; @@ -313,7 +313,7 @@ private slots: int nPUT = 0; int nMOVE = 0; int nDELETE = 0; - fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &req) { + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *) { if (op == QNetworkAccessManager::GetOperation) ++nGET; if (op == QNetworkAccessManager::PutOperation) From 4dc49ff3b01f196dfac0ac928688d90a001b49e8 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 11 Dec 2017 19:25:51 +0100 Subject: [PATCH 006/138] SyncEngine: Recover when the PUT reply (or chunkin's MOVE) is lost This can happen if the upload of a file is finished, but we just got disconnected right before recieving the reply containing the etag. So nothing was save din the DB, and we are not sure if the server recieved the file properly or not. Further local update of the file will cause a conflict. In order to fix this, store the checksum of the uploading file in the uploadinfo table of the local db (even if there is no chunking involved). And when we have a conflict, check that it is not because of this situation by checking the entry in the uploadinfo table. Issue #5106 --- src/common/syncjournaldb.cpp | 22 ++++++++-- src/common/syncjournaldb.h | 1 + src/csync/csync_reconcile.cpp | 30 +++++++++++++ src/libsync/propagateuploadng.cpp | 1 + src/libsync/propagateuploadv1.cpp | 17 +++++++- test/syncenginetestutils.h | 13 +++++- test/testchunkingng.cpp | 70 ++++++++++++++++++++++++++----- 7 files changed, 136 insertions(+), 18 deletions(-) diff --git a/src/common/syncjournaldb.cpp b/src/common/syncjournaldb.cpp index 3710f36d3..fa609089e 100644 --- a/src/common/syncjournaldb.cpp +++ b/src/common/syncjournaldb.cpp @@ -389,6 +389,7 @@ bool SyncJournalDb::checkConnect() "errorcount INTEGER," "size INTEGER(8)," "modtime INTEGER(8)," + "contentChecksum TEXT," "PRIMARY KEY(path)" ");"); @@ -611,15 +612,15 @@ bool SyncJournalDb::checkConnect() } _getUploadInfoQuery.reset(new SqlQuery(_db)); - if (_getUploadInfoQuery->prepare("SELECT chunk, transferid, errorcount, size, modtime FROM " + if (_getUploadInfoQuery->prepare("SELECT chunk, transferid, errorcount, size, modtime, contentChecksum FROM " "uploadinfo WHERE path=?1")) { return sqlFail("prepare _getUploadInfoQuery", *_getUploadInfoQuery); } _setUploadInfoQuery.reset(new SqlQuery(_db)); if (_setUploadInfoQuery->prepare("INSERT OR REPLACE INTO uploadinfo " - "(path, chunk, transferid, errorcount, size, modtime) " - "VALUES ( ?1 , ?2, ?3 , ?4 , ?5, ?6 )")) { + "(path, chunk, transferid, errorcount, size, modtime, contentChecksum) " + "VALUES ( ?1 , ?2, ?3 , ?4 , ?5, ?6 , ?7 )")) { return sqlFail("prepare _setUploadInfoQuery", *_setUploadInfoQuery); } @@ -849,6 +850,16 @@ bool SyncJournalDb::updateMetadataTableStructure() commitInternal("update database structure: add contentChecksumTypeId col"); } + if (!tableColumns("uploadinfo").contains("contentChecksum")) { + SqlQuery query(_db); + query.prepare("ALTER TABLE uploadinfo ADD COLUMN contentChecksum TEXT;"); + if (!query.exec()) { + sqlFail("updateMetadataTableStructure: add contentChecksum column", query); + re = false; + } + commitInternal("update database structure: add contentChecksum col for uploadinfo"); + } + return re; } @@ -1472,6 +1483,7 @@ SyncJournalDb::UploadInfo SyncJournalDb::getUploadInfo(const QString &file) res._errorCount = _getUploadInfoQuery->intValue(2); res._size = _getUploadInfoQuery->int64Value(3); res._modtime = _getUploadInfoQuery->int64Value(4); + res._contentChecksum = _getUploadInfoQuery->baValue(5); res._valid = ok; } } @@ -1494,6 +1506,7 @@ void SyncJournalDb::setUploadInfo(const QString &file, const SyncJournalDb::Uplo _setUploadInfoQuery->bindValue(4, i._errorCount); _setUploadInfoQuery->bindValue(5, i._size); _setUploadInfoQuery->bindValue(6, i._modtime); + _setUploadInfoQuery->bindValue(7, i._contentChecksum); if (!_setUploadInfoQuery->exec()) { return; @@ -2001,7 +2014,8 @@ bool operator==(const SyncJournalDb::UploadInfo &lhs, && lhs._modtime == rhs._modtime && lhs._valid == rhs._valid && lhs._size == rhs._size - && lhs._transferid == rhs._transferid; + && lhs._transferid == rhs._transferid + && lhs._contentChecksum == rhs._contentChecksum; } } // namespace OCC diff --git a/src/common/syncjournaldb.h b/src/common/syncjournaldb.h index ad61a6ad2..dc650ffa3 100644 --- a/src/common/syncjournaldb.h +++ b/src/common/syncjournaldb.h @@ -112,6 +112,7 @@ public: qint64 _modtime; int _errorCount; bool _valid; + QByteArray _contentChecksum; }; struct PollInfo diff --git a/src/csync/csync_reconcile.cpp b/src/csync/csync_reconcile.cpp index 97863fb8b..daad534ae 100644 --- a/src/csync/csync_reconcile.cpp +++ b/src/csync/csync_reconcile.cpp @@ -27,6 +27,7 @@ #include "csync_rename.h" #include "common/c_jhash.h" #include "common/asserts.h" +#include "common/syncjournalfilerecord.h" #include Q_LOGGING_CATEGORY(lcReconcile, "sync.csync.reconciler", QtInfoMsg) @@ -316,6 +317,35 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) { (ctx->current == REMOTE_REPLICA ? cur->checksumHeader : other->checksumHeader); if (!remoteChecksumHeader.isEmpty()) { is_conflict = true; + + // Do we have an UploadInfo for this? + // Maybe the Upload was completed, but the connection was broken just before + // we recieved the etag (Issue #5106) + auto up = ctx->statedb->getUploadInfo(cur->path); + if (up._valid && up._contentChecksum == remoteChecksumHeader) { + // Solve the conflict into an upload, or nothing + auto remoteNode = ctx->current == REMOTE_REPLICA ? cur : other; + auto localNode = ctx->current == REMOTE_REPLICA ? other : cur; + remoteNode->instruction = CSYNC_INSTRUCTION_NONE; + localNode->instruction = up._modtime == localNode->modtime ? CSYNC_INSTRUCTION_UPDATE_METADATA : CSYNC_INSTRUCTION_SYNC; + + // Update the etag and other server metadata in the journal already + // (We can't use a typical CSYNC_INSTRUCTION_UPDATE_METADATA because + // we must not store the size/modtime from the file system) + OCC::SyncJournalFileRecord rec; + if (ctx->statedb->getFileRecord(remoteNode->path, &rec)) { + rec._path = remoteNode->path; + rec._etag = remoteNode->etag; + rec._fileId = remoteNode->file_id; + rec._modtime = remoteNode->modtime; + rec._type = remoteNode->type; + rec._fileSize = remoteNode->size; + rec._remotePerm = remoteNode->remotePerm; + rec._checksumHeader = remoteNode->checksumHeader; + ctx->statedb->setFileRecordMetadata(rec); + } + break; + } } // SO: If there is no checksum, we can have !is_conflict here diff --git a/src/libsync/propagateuploadng.cpp b/src/libsync/propagateuploadng.cpp index fa16a4abe..0b2c14295 100644 --- a/src/libsync/propagateuploadng.cpp +++ b/src/libsync/propagateuploadng.cpp @@ -230,6 +230,7 @@ void PropagateUploadFileNG::startNewUpload() pi._valid = true; pi._transferid = _transferId; pi._modtime = _item->_modtime; + pi._contentChecksum = _item->_checksumHeader; propagator()->_journal->setUploadInfo(_item->_file, pi); propagator()->_journal->commit("Upload info"); QMap headers; diff --git a/src/libsync/propagateuploadv1.cpp b/src/libsync/propagateuploadv1.cpp index 8ebdd3786..91aa16098 100644 --- a/src/libsync/propagateuploadv1.cpp +++ b/src/libsync/propagateuploadv1.cpp @@ -43,10 +43,24 @@ void PropagateUploadFileV1::doStartUpload() const SyncJournalDb::UploadInfo progressInfo = propagator()->_journal->getUploadInfo(_item->_file); - if (progressInfo._valid && progressInfo._modtime == _item->_modtime) { + if (progressInfo._valid && progressInfo._modtime == _item->_modtime + && (progressInfo._contentChecksum == _item->_checksumHeader || progressInfo._contentChecksum.isEmpty() || _item->_checksumHeader.isEmpty())) { _startChunk = progressInfo._chunk; _transferId = progressInfo._transferid; qCInfo(lcPropagateUpload) << _item->_file << ": Resuming from chunk " << _startChunk; + } else if (_chunkCount <= 1 && !_item->_checksumHeader.isEmpty()) { + // If there is only one chunk, write the checksum in the database, so if the PUT is sent + // to the server, but the connection drops before we get the etag, we can check the checksum + // in reconcile (issue #5106) + SyncJournalDb::UploadInfo pi; + pi._valid = true; + pi._chunk = 0; + pi._transferid = _transferId; + pi._modtime = _item->_modtime; + pi._errorCount = 0; + pi._contentChecksum = _item->_checksumHeader; + propagator()->_journal->setUploadInfo(_item->_file, pi); + propagator()->_journal->commit("Upload info"); } _currentChunk = 0; @@ -274,6 +288,7 @@ void PropagateUploadFileV1::slotPutFinished() pi._transferid = _transferId; pi._modtime = _item->_modtime; pi._errorCount = 0; // successful chunk upload resets + pi._contentChecksum = _item->_checksumHeader; propagator()->_journal->setUploadInfo(_item->_file, pi); propagator()->_journal->commit("Upload info"); startNextChunk(); diff --git a/test/syncenginetestutils.h b/test/syncenginetestutils.h index 9122040be..f7cf4eb46 100644 --- a/test/syncenginetestutils.h +++ b/test/syncenginetestutils.h @@ -452,7 +452,11 @@ public: emit finished(); } - void abort() override { } + void abort() override + { + setError(OperationCanceledError, "abort"); + emit finished(); + } qint64 readData(char *, qint64) override { return 0; } }; @@ -696,7 +700,12 @@ public: emit finished(); } - void abort() override { } + void abort() override + { + setError(OperationCanceledError, "abort"); + emit finished(); + } + qint64 readData(char *, qint64) override { return 0; } }; diff --git a/test/testchunkingng.cpp b/test/testchunkingng.cpp index a61bdc15d..ce7880537 100644 --- a/test/testchunkingng.cpp +++ b/test/testchunkingng.cpp @@ -161,17 +161,6 @@ private slots: QVERIFY(!moveChecksumHeader.isEmpty()); fakeFolder.remoteModifier().find("A/a0")->checksums = moveChecksumHeader; - // This time it's a real conflict, we have a remote checksum! - connection = connect(&fakeFolder.syncEngine(), &SyncEngine::aboutToPropagate, [&](SyncFileItemVector &items) { - SyncFileItemPtr a0; - for (auto &item : items) { - if (item->_file == "A/a0") - a0 = item; - } - - QVERIFY(a0); - QCOMPARE(a0->_instruction, CSYNC_INSTRUCTION_CONFLICT); - }); QVERIFY(fakeFolder.syncOnce()); disconnect(connection); QCOMPARE(nGET, 0); // no new download, just a metadata update! @@ -378,6 +367,65 @@ private slots: QVERIFY(fakeFolder.uploadState().children.first().name != chunkingId); } + // Check what happens when the connection is dropped on the PUT (non-chunking) or MOVE (chunking) + // for on the issue #5106 + void connectionDroppedBeforeEtagRecieved_data() + { + QTest::addColumn("chunking"); + QTest::newRow("big file") << true; + QTest::newRow("small file") << false; + } + void connectionDroppedBeforeEtagRecieved() + { + QFETCH(bool, chunking); + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + fakeFolder.syncEngine().account()->setCapabilities({ { "dav", QVariantMap{ { "chunking", "1.0" } } }, { "checksums", QVariantMap{ { "supportedTypes", QStringList() << "SHA1" } } } }); + const int size = chunking ? 150 * 1000 * 1000 : 300; + + // Make the MOVE never reply, but trigger a client-abort and apply the change remotely + QByteArray checksumHeader; + int nGET = 0; + QScopedValueRollback setHttpTimeout(AbstractNetworkJob::httpTimeout, 1); + int responseDelay = AbstractNetworkJob::httpTimeout * 1000 * 1000; // much bigger than http timeout (so a timeout will occur) + // This will perform the operation on the server, but the reply will not come to the client + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData) -> QNetworkReply * { + if (!chunking && op == QNetworkAccessManager::PutOperation) { + checksumHeader = request.rawHeader("OC-Checksum"); + return new DelayedReply(responseDelay, fakeFolder.remoteModifier(), op, request, outgoingData->readAll(), &fakeFolder.syncEngine()); + } else if (chunking && request.attribute(QNetworkRequest::CustomVerbAttribute) == "MOVE") { + checksumHeader = request.rawHeader("OC-Checksum"); + return new DelayedReply(responseDelay, fakeFolder.uploadState(), fakeFolder.remoteModifier(), op, request, &fakeFolder.syncEngine()); + } else if (op == QNetworkAccessManager::GetOperation) { + nGET++; + } + return nullptr; + }); + + + // Test 1: a NEW file + fakeFolder.localModifier().insert("A/a0", size); + QVERIFY(!fakeFolder.syncOnce()); // timeout! + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); // but the upload succeeded + QVERIFY(!checksumHeader.isEmpty()); + fakeFolder.remoteModifier().find("A/a0")->checksums = checksumHeader; // The test system don't do that automatically + // Should be resolved properly + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(nGET, 0); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + // Test 2: Modify the file further + fakeFolder.localModifier().appendByte("A/a0"); + QVERIFY(!fakeFolder.syncOnce()); // timeout! + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); // but the upload succeeded + fakeFolder.remoteModifier().find("A/a0")->checksums = checksumHeader; + // modify again, should not cause conflict + fakeFolder.localModifier().appendByte("A/a0"); + QVERIFY(!fakeFolder.syncOnce()); // now it's trying to upload the modified file + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + fakeFolder.remoteModifier().find("A/a0")->checksums = checksumHeader; + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(nGET, 0); + } }; QTEST_GUILESS_MAIN(TestChunkingNG) From 8d5afff0a43470a5196175f197c23fb3b0edb8d6 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 14 Dec 2017 20:07:14 +0100 Subject: [PATCH 007/138] Update ChangeLog for 2.4.0 --- ChangeLog | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f470b78bf..20e5b546e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,7 +2,7 @@ ChangeLog ========= version 2.4.0 (2017-12-XX) -* If you're using 2.4.0 alpha1, please upgrade as the alpha1 had an issue with hidden files! +* If you're using 2.4.0 alpha1, please upgrade as previous alphas/rcs had an issue with hidden files and renames! * OAuth2 authentication support by opening external browser (#5668) * Shibboleth: Change to use OAuth2 if supported (#6198) * Sharing: Add support for multiple public link shares (#5655) @@ -66,7 +66,7 @@ version 2.4.0 (2017-12-XX) * Sync: Upload conflict files if OWNCLOUD_UPLOAD_CONFLICT_FILES environment variable is set (#6038) * Sync: Blacklist: Don't let errors become warnings (#5516) * Sync: Check etag again after active sync (#4116) -* Sync: Rename handling fixes: duplicate file ids (#6096) +* Sync: Rename handling fixes: duplicate file ids (#6096, #6212) * Sync: Rename handling fixes: File size must be equal * Sync: Rename handling: Fix duplicate files on abort/resume sync (#5949) * Sync: Add capability for invalid filename regexes (#6092) @@ -80,6 +80,7 @@ version 2.4.0 (2017-12-XX) * Crash fixes * Test improvements * Small UI layout fixes +* Performance improvements * Maintenance Mode: Detect maintenance mode (#4485) * Maintenance Mode: Add a 1 to 5 min reconnection delay (#5872) * HTTP: Send a unique X-Request-ID with each request (#5853) @@ -95,6 +96,7 @@ version 2.4.0 (2017-12-XX) * Compilation: Remove Qt 4 code (#6025, #5702, #5505) * Harmonize source code style with clang-format (#5732) * Switch over to Qt 5 function pointer signal/slot syntax (#6041) +* Compile with stack-smashing protection * Updater: Rudimentary support for beta channel (#6048) version 2.3.4 (2017-11-02) @@ -110,6 +112,7 @@ version 2.3.3 (2017-08-29) * Overlay Icons: Fix potential hangs on Windows * SyncJournalDB: Don't use ._ as filename pattern if that does not work because of SMB storage settings (#5844) * SyncJournalDB: Log reason for sqlite3 opening errors +* Notifications: Proapgate "Dismiss" button action to server (#5922) * Switch Linux build also to Qt 5.6.2 (#5470) * Stopped maintaining Qt 4 buildability From 79dd8e90744f4ed6037128ac249863d9b01e8e56 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Fri, 15 Dec 2017 02:18:52 +0100 Subject: [PATCH 008/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index a57124e37..597ac8a90 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -80,6 +80,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From 298f1ab57000afd7acb8c0ddbddca8a1fc6cd92a Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 15 Dec 2017 09:16:59 +0100 Subject: [PATCH 009/138] Disable stack protection for mingw win32 builds in 2.4 Mingw builds could have it enabled! But we need to ship libssp and test this more. For the upcoming 2.4 release it should be disabled. --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 172422988..70c66acc4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,7 +8,7 @@ if(NOT TOKEN_AUTH_ONLY) find_package(Qt5Keychain REQUIRED) endif() -if(NOT MSVC) +if(NOT WIN32) if(NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "^(parisc|hppa)")) if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector --param=ssp-buffer-size=4") From 3b96097cf6f99dee1b84098b197e047ba2f88578 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Wed, 22 Nov 2017 19:10:37 +0100 Subject: [PATCH 010/138] Config: Look for exclude file in a relative path. If the application binary is not installed in /usr/bin the client with this patch considers to check the relative location ../../etc/owncloud-client/ to find the system exclude. This is an important bit for AppImage based packages of the client, as this runs from a temporar mountpoint and the system file can not be found under /etc. --- src/libsync/configfile.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/libsync/configfile.cpp b/src/libsync/configfile.cpp index 8aff35b3b..295fafc17 100644 --- a/src/libsync/configfile.cpp +++ b/src/libsync/configfile.cpp @@ -306,6 +306,19 @@ QString ConfigFile::excludeFileFromSystem() QFileInfo nextToBinary(QCoreApplication::applicationDirPath(), exclFile); if (nextToBinary.exists()) { fi = nextToBinary; + } else { + // For AppImage, the file might reside under a temporary mount path + QDir d(QCoreApplication::applicationDirPath()); // supposed to be /tmp/mount.xyz/usr/bin + d.cdUp(); // go out of bin + d.cdUp(); // go out of usr + if (!d.isRoot()) { // it is really a mountpoint + if (d.cd("etc") && d.cd(Theme::instance()->appName())) { + QFileInfo inMountDir(d, exclFile); + if (inMountDir.exists()) { + fi = inMountDir; + } + }; + } } } #endif From b10edfecfc847e31252df0c60c0db47faf6e94ce Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 15 Dec 2017 14:15:32 +0100 Subject: [PATCH 011/138] Workaround MSVC bug with enum in bitfield MSVC stores the enum as signed in the bitfield (contrary to the C++ spec) Which means that once we store a value such as SyncFileItem::DetailError in a bitfield, we get a negative value back, then of course, further comparison fails. --- src/csync/csync.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/csync/csync.h b/src/csync/csync.h index 8c59f1707..753688cdb 100644 --- a/src/csync/csync.h +++ b/src/csync/csync.h @@ -48,6 +48,9 @@ #if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG) && (__GNUC__ * 100 + __GNUC_MINOR__ < 408) // openSuse 12.3 didn't like enum bitfields. #define BITFIELD(size) +#elif defined(Q_CC_MSVC) +// MSVC stores enum and bool as signed, so we need to add a bit for the sign +#define BITFIELD(size) :(size+1) #else #define BITFIELD(size) :size #endif From 482ee875a19029242ec8290e5f21e64dab341c5f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 15 Dec 2017 14:34:36 +0100 Subject: [PATCH 012/138] Fix TestSyncEngine on windows --- test/testsyncengine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp index 744835efe..54e3a11cb 100644 --- a/test/testsyncengine.cpp +++ b/test/testsyncengine.cpp @@ -536,6 +536,7 @@ private slots: { FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; +#ifndef Q_OS_WIN // We can't have local file with these character // For current servers, no characters are forbidden fakeFolder.syncEngine().account()->setServerVersion("10.0.0"); fakeFolder.localModifier().insert("A/\\:?*\"<>|.txt"); @@ -547,6 +548,7 @@ private slots: fakeFolder.localModifier().insert("B/\\:?*\"<>|.txt"); QVERIFY(fakeFolder.syncOnce()); QVERIFY(!fakeFolder.currentRemoteState().find("B/\\:?*\"<>|.txt")); +#endif // We can override that by setting the capability fakeFolder.syncEngine().account()->setCapabilities({ { "dav", QVariantMap{ { "invalidFilenameRegex", "" } } } }); From ee366df58f3eaf88c7775367d766d3f98647554e Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 15 Dec 2017 14:50:41 +0100 Subject: [PATCH 013/138] Fix the TestFolderMan on Windows --- test/testfolderman.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/testfolderman.cpp b/test/testfolderman.cpp index 39c657a05..15f044ba1 100644 --- a/test/testfolderman.cpp +++ b/test/testfolderman.cpp @@ -107,7 +107,7 @@ private slots: QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1/folder").isNull()); QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1/folder/f").isNull()); - +#ifndef Q_OS_WIN // no links on windows, no permissions // make a bunch of links QVERIFY(QFile::link(dirPath + "/sub/free", dirPath + "/link1")); QVERIFY(QFile::link(dirPath + "/sub", dirPath + "/link2")); @@ -129,7 +129,6 @@ private slots: QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/link4").isNull()); QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/link3/folder").isNull()); - // test some non existing sub path (error) QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1/some/sub/path").isNull()); QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/ownCloud2/blublu").isNull()); @@ -140,12 +139,13 @@ private slots: QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + "/link1/subfolder").isNull()); QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + "/link2/free/subfolder").isNull()); - // Invalid paths - QVERIFY(!folderman->checkPathValidityForNewFolder("").isNull()); - // Should not have the rights QVERIFY(!folderman->checkPathValidityForNewFolder("/").isNull()); QVERIFY(!folderman->checkPathValidityForNewFolder("/usr/bin/somefolder").isNull()); +#endif + + // Invalid paths + QVERIFY(!folderman->checkPathValidityForNewFolder("").isNull()); } void testFindGoodPathForNewSyncFolder() From 8eebc5372880287e09cc1156a987f239465d7bf5 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Thu, 14 Dec 2017 15:08:53 +0100 Subject: [PATCH 014/138] Unify item type enum Previously, there was csync_ftw_type_e and SyncFileItem::Type. Having two enums lead to a bug where Type::Unknown == Type::File that went unnoticed for a good while. This patch keeps only a single enum. --- src/common/syncjournaldb.cpp | 4 +- src/common/syncjournalfilerecord.cpp | 2 +- src/common/syncjournalfilerecord.h | 3 +- src/csync/csync.cpp | 17 +++++++++ src/csync/csync.h | 37 +++++++------------ src/csync/csync_exclude.cpp | 18 ++++----- src/csync/csync_exclude.h | 8 ++-- src/csync/csync_private.h | 2 +- src/csync/csync_reconcile.cpp | 12 +++--- src/csync/csync_update.cpp | 32 ++++++++-------- src/csync/vio/csync_vio_local_unix.cpp | 14 +++---- src/csync/vio/csync_vio_local_win.cpp | 12 +++--- src/libsync/discoveryphase.cpp | 4 +- src/libsync/syncengine.cpp | 20 ++-------- src/libsync/syncfileitem.cpp | 2 +- src/libsync/syncfileitem.h | 13 ++----- .../csync/csync_tests/check_csync_exclude.cpp | 8 ++-- test/csync/csync_tests/check_csync_update.cpp | 2 +- test/csync/vio_tests/check_vio_ext.cpp | 2 +- test/testsyncjournaldb.cpp | 4 +- 20 files changed, 104 insertions(+), 112 deletions(-) diff --git a/src/common/syncjournaldb.cpp b/src/common/syncjournaldb.cpp index fa609089e..b2d348af8 100644 --- a/src/common/syncjournaldb.cpp +++ b/src/common/syncjournaldb.cpp @@ -47,7 +47,7 @@ static void fillFileRecordFromGetQuery(SyncJournalFileRecord &rec, SqlQuery &que rec._path = query.baValue(0); rec._inode = query.int64Value(1); rec._modtime = query.int64Value(2); - rec._type = query.intValue(3); + rec._type = static_cast(query.intValue(3)); rec._etag = query.baValue(4); rec._fileId = query.baValue(5); rec._remotePerm = RemotePermissions(query.baValue(6).constData()); @@ -1840,7 +1840,7 @@ void SyncJournalDb::avoidReadFromDbOnNextSync(const QByteArray &fileName) SqlQuery query(_db); // This query will match entries for which the path is a prefix of fileName - // Note: CSYNC_FTW_TYPE_DIR == 2 + // Note: ItemTypeDirectory == 2 query.prepare("UPDATE metadata SET md5='_invalid_' WHERE ?1 LIKE(path||'/%') AND type == 2;"); query.bindValue(1, fileName); query.exec(); diff --git a/src/common/syncjournalfilerecord.cpp b/src/common/syncjournalfilerecord.cpp index 226c25d6c..607d2e6db 100644 --- a/src/common/syncjournalfilerecord.cpp +++ b/src/common/syncjournalfilerecord.cpp @@ -23,7 +23,7 @@ namespace OCC { SyncJournalFileRecord::SyncJournalFileRecord() : _inode(0) - , _type(0) + , _type(ItemTypeSkip) , _fileSize(0) , _serverHasIgnoredFiles(false) { diff --git a/src/common/syncjournalfilerecord.h b/src/common/syncjournalfilerecord.h index bc34ef135..76fd4cdbe 100644 --- a/src/common/syncjournalfilerecord.h +++ b/src/common/syncjournalfilerecord.h @@ -22,6 +22,7 @@ #include #include +#include "csync.h" #include "ocsynclib.h" #include "remotepermissions.h" #include "common/utility.h" @@ -56,7 +57,7 @@ public: QByteArray _path; quint64 _inode; qint64 _modtime; - int _type; + ItemType _type; QByteArray _etag; QByteArray _fileId; qint64 _fileSize; diff --git a/src/csync/csync.cpp b/src/csync/csync.cpp index f80d4d4d2..fdbe5886f 100644 --- a/src/csync/csync.cpp +++ b/src/csync/csync.cpp @@ -49,6 +49,7 @@ #include "csync_log.h" #include "csync_rename.h" #include "common/c_jhash.h" +#include "common/syncjournalfilerecord.h" csync_s::csync_s(const char *localUri, OCC::SyncJournalDb *statedb) @@ -402,3 +403,19 @@ int csync_abort_requested(CSYNC *ctx) return (1 == 0); } } + +std::unique_ptr csync_file_stat_s::fromSyncJournalFileRecord(const OCC::SyncJournalFileRecord &rec) +{ + std::unique_ptr st(new csync_file_stat_t); + st->path = rec._path; + st->inode = rec._inode; + st->modtime = rec._modtime; + st->type = static_cast(rec._type); + st->etag = rec._etag; + st->file_id = rec._fileId; + st->remotePerm = rec._remotePerm; + st->size = rec._fileSize; + st->has_ignored_files = rec._serverHasIgnoredFiles; + st->checksumHeader = rec._checksumHeader; + return st; +} diff --git a/src/csync/csync.h b/src/csync/csync.h index 753688cdb..3a1d8d584 100644 --- a/src/csync/csync.h +++ b/src/csync/csync.h @@ -34,7 +34,6 @@ #include "std/c_private.h" #include "ocsynclib.h" -#include "common/syncjournalfilerecord.h" #include #include @@ -45,6 +44,10 @@ #include #include "common/remotepermissions.h" +namespace OCC { +class SyncJournalFileRecord; +} + #if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG) && (__GNUC__ * 100 + __GNUC_MINOR__ < 408) // openSuse 12.3 didn't like enum bitfields. #define BITFIELD(size) @@ -151,11 +154,13 @@ enum csync_instructions_e { but without any propagation (UPDATE|RECONCILE) */ }; -enum csync_ftw_type_e { - CSYNC_FTW_TYPE_FILE, - CSYNC_FTW_TYPE_SLINK, - CSYNC_FTW_TYPE_DIR, - CSYNC_FTW_TYPE_SKIP +// This enum is used with BITFIELD(3) and BITFIELD(4) in several places. +// Also, this value is stored in the database, so beware of value changes. +enum ItemType { + ItemTypeFile = 0, + ItemTypeSoftLink = 1, + ItemTypeDirectory = 2, + ItemTypeSkip = 3 }; @@ -172,7 +177,7 @@ struct OCSYNC_EXPORT csync_file_stat_s { uint64_t inode; OCC::RemotePermissions remotePerm; - enum csync_ftw_type_e type BITFIELD(4); + ItemType type BITFIELD(4); bool child_modified BITFIELD(1); bool has_ignored_files BITFIELD(1); // Specify that a directory, or child directory contains ignored files. bool is_hidden BITFIELD(1); // Not saved in the DB, only used during discovery for local files. @@ -199,7 +204,7 @@ struct OCSYNC_EXPORT csync_file_stat_s { : modtime(0) , size(0) , inode(0) - , type(CSYNC_FTW_TYPE_SKIP) + , type(ItemTypeSkip) , child_modified(false) , has_ignored_files(false) , is_hidden(false) @@ -207,21 +212,7 @@ struct OCSYNC_EXPORT csync_file_stat_s { , instruction(CSYNC_INSTRUCTION_NONE) { } - static std::unique_ptr fromSyncJournalFileRecord(const OCC::SyncJournalFileRecord &rec) - { - std::unique_ptr st(new csync_file_stat_t); - st->path = rec._path; - st->inode = rec._inode; - st->modtime = rec._modtime; - st->type = static_cast(rec._type); - st->etag = rec._etag; - st->file_id = rec._fileId; - st->remotePerm = rec._remotePerm; - st->size = rec._fileSize; - st->has_ignored_files = rec._serverHasIgnoredFiles; - st->checksumHeader = rec._checksumHeader; - return st; - } + static std::unique_ptr fromSyncJournalFileRecord(const OCC::SyncJournalFileRecord &rec); }; /** diff --git a/src/csync/csync_exclude.cpp b/src/csync/csync_exclude.cpp index c090b1f1a..762a8eae4 100644 --- a/src/csync/csync_exclude.cpp +++ b/src/csync/csync_exclude.cpp @@ -393,9 +393,9 @@ bool ExcludedFiles::isExcluded( } QFileInfo fi(filePath); - csync_ftw_type_e type = CSYNC_FTW_TYPE_FILE; + ItemType type = ItemTypeFile; if (fi.isDir()) { - type = CSYNC_FTW_TYPE_DIR; + type = ItemTypeDirectory; } QString relativePath = filePath.mid(basePath.size()); @@ -406,7 +406,7 @@ bool ExcludedFiles::isExcluded( return fullPatternMatch(relativePath.toUtf8(), type) != CSYNC_NOT_EXCLUDED; } -CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, int filetype) const +CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, ItemType filetype) const { auto match = _csync_excluded_common(path); if (match != CSYNC_NOT_EXCLUDED) @@ -426,7 +426,7 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, int fi QString bnameStr = QString::fromUtf8(bname); QRegularExpressionMatch m; - if (filetype == CSYNC_FTW_TYPE_DIR) { + if (filetype == ItemTypeDirectory) { m = _bnameActivationRegexDir.match(bnameStr); } else { m = _bnameActivationRegexFile.match(bnameStr); @@ -437,7 +437,7 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, int fi // Now run the full match QString pathStr = QString::fromUtf8(path); - if (filetype == CSYNC_FTW_TYPE_DIR) { + if (filetype == ItemTypeDirectory) { m = _fullRegexDir.match(pathStr); } else { m = _fullRegexFile.match(pathStr); @@ -452,7 +452,7 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, int fi return match; } -CSYNC_EXCLUDE_TYPE ExcludedFiles::fullPatternMatch(const char *path, int filetype) const +CSYNC_EXCLUDE_TYPE ExcludedFiles::fullPatternMatch(const char *path, ItemType filetype) const { auto match = _csync_excluded_common(path); if (match != CSYNC_NOT_EXCLUDED) @@ -462,7 +462,7 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::fullPatternMatch(const char *path, int filetyp QString p = QString::fromUtf8(path); QRegularExpressionMatch m; - if (filetype == CSYNC_FTW_TYPE_DIR) { + if (filetype == ItemTypeDirectory) { m = _fullRegexDir.match(p); } else { m = _fullRegexFile.match(p); @@ -478,9 +478,9 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::fullPatternMatch(const char *path, int filetyp } auto ExcludedFiles::csyncTraversalMatchFun() const - -> std::function + -> std::function { - return [this](const char *path, int filetype) { return this->traversalPatternMatch(path, filetype); }; + return [this](const char *path, ItemType filetype) { return this->traversalPatternMatch(path, filetype); }; } static QString convertToRegexpSyntax(QString exclude) diff --git a/src/csync/csync_exclude.h b/src/csync/csync_exclude.h index f2c14a767..9f1c544d7 100644 --- a/src/csync/csync_exclude.h +++ b/src/csync/csync_exclude.h @@ -30,6 +30,8 @@ #include #include +#include + enum csync_exclude_type_e { CSYNC_NOT_EXCLUDED = 0, CSYNC_FILE_SILENTLY_EXCLUDED, @@ -108,7 +110,7 @@ public: * ExcludedFiles instance stays alive. */ auto csyncTraversalMatchFun() const - -> std::function; + -> std::function; public slots: /** @@ -125,7 +127,7 @@ private: * Note that this only matches patterns. It does not check whether the file * or directory pointed to is hidden (or whether it even exists). */ - CSYNC_EXCLUDE_TYPE fullPatternMatch(const char *path, int filetype) const; + CSYNC_EXCLUDE_TYPE fullPatternMatch(const char *path, ItemType filetype) const; /** * @brief Check if the given path should be excluded in a traversal situation. @@ -142,7 +144,7 @@ private: * Note that this only matches patterns. It does not check whether the file * or directory pointed to is hidden (or whether it even exists). */ - CSYNC_EXCLUDE_TYPE traversalPatternMatch(const char *path, int filetype) const; + CSYNC_EXCLUDE_TYPE traversalPatternMatch(const char *path, ItemType filetype) const; /** * Generate optimized regular expressions for the exclude patterns. diff --git a/src/csync/csync_private.h b/src/csync/csync_private.h index e692e7ba1..9a0276507 100644 --- a/src/csync/csync_private.h +++ b/src/csync/csync_private.h @@ -153,7 +153,7 @@ struct OCSYNC_EXPORT csync_s { * * See ExcludedFiles in csync_exclude. */ - std::function exclude_traversal_fn; + std::function exclude_traversal_fn; struct { std::unordered_map folder_renamed_to; // map from->to diff --git a/src/csync/csync_reconcile.cpp b/src/csync/csync_reconcile.cpp index daad534ae..f7e30785e 100644 --- a/src/csync/csync_reconcile.cpp +++ b/src/csync/csync_reconcile.cpp @@ -178,7 +178,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) { // other is found as well? qCDebug(lcReconcile, "Other has already been renamed to %s", other->rename_path.constData()); - } else if (cur->type == CSYNC_FTW_TYPE_DIR + } else if (cur->type == ItemTypeDirectory // The local replica is reconciled first, so the remote tree would // have either NONE or UPDATE_METADATA if the remote file is safe to // move. @@ -297,8 +297,8 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) { /* file on other replica is changed or new */ case CSYNC_INSTRUCTION_NEW: case CSYNC_INSTRUCTION_EVAL: - if (other->type == CSYNC_FTW_TYPE_DIR && - cur->type == CSYNC_FTW_TYPE_DIR) { + if (other->type == ItemTypeDirectory && + cur->type == ItemTypeDirectory) { // Folders of the same path are always considered equals is_conflict = false; } else { @@ -375,7 +375,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) { // needs to delete the other entity first. cur->instruction = CSYNC_INSTRUCTION_TYPE_CHANGE; other->instruction = CSYNC_INSTRUCTION_NONE; - } else if (cur->type == CSYNC_FTW_TYPE_DIR) { + } else if (cur->type == ItemTypeDirectory) { cur->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA; other->instruction = CSYNC_INSTRUCTION_NONE; } else { @@ -408,7 +408,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) { const char *repo = ctx->current == REMOTE_REPLICA ? "server" : "client"; if(cur->instruction ==CSYNC_INSTRUCTION_NONE) { - if(cur->type == CSYNC_FTW_TYPE_DIR) + if(cur->type == ItemTypeDirectory) { qCDebug(lcReconcile, "%-30s %s dir: %s", @@ -427,7 +427,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) { } else { - if(cur->type == CSYNC_FTW_TYPE_DIR) + if(cur->type == ItemTypeDirectory) { qCInfo(lcReconcile, "%-30s %s dir: %s", diff --git a/src/csync/csync_update.cpp b/src/csync/csync_update.cpp index ae7efba77..ad58ef5b6 100644 --- a/src/csync/csync_update.cpp +++ b/src/csync/csync_update.cpp @@ -117,7 +117,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr f return -1; } - if (fs->type == CSYNC_FTW_TYPE_SKIP) { + if (fs->type == ItemTypeSkip) { excluded =CSYNC_FILE_EXCLUDE_STAT_FAILED; } else { /* Check if file is excluded */ @@ -159,13 +159,13 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr f } } - if (fs->type == CSYNC_FTW_TYPE_FILE ) { + if (fs->type == ItemTypeFile ) { if (fs->modtime == 0) { qCDebug(lcUpdate, "file: %s - mtime is zero!", fs->path.constData()); } } - if (excluded > CSYNC_NOT_EXCLUDED || fs->type == CSYNC_FTW_TYPE_SLINK) { + if (excluded > CSYNC_NOT_EXCLUDED || fs->type == ItemTypeSoftLink) { fs->instruction = CSYNC_INSTRUCTION_IGNORE; if (ctx->current_fs) { ctx->current_fs->has_ignored_files = true; @@ -238,7 +238,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr f bool metadata_differ = (ctx->current == REMOTE_REPLICA && (fs->file_id != base._fileId || fs->remotePerm != base._remotePerm)) || (ctx->current == LOCAL_REPLICA && fs->inode != base._inode); - if (fs->type == CSYNC_FTW_TYPE_DIR && ctx->current == REMOTE_REPLICA + if (fs->type == ItemTypeDirectory && ctx->current == REMOTE_REPLICA && !metadata_differ && ctx->read_remote_from_db) { /* If both etag and file id are equal for a directory, read all contents from * the database. @@ -277,7 +277,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr f bool isRename = base.isValid() && base._type == fs->type - && ((base._modtime == fs->modtime && base._fileSize == fs->size) || fs->type == CSYNC_FTW_TYPE_DIR) + && ((base._modtime == fs->modtime && base._fileSize == fs->size) || fs->type == ItemTypeDirectory) #ifdef NO_RENAME_EXTENSION && _csync_sameextension(base._path, fs->path) #endif @@ -286,7 +286,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr f // Verify the checksum where possible if (isRename && !base._checksumHeader.isEmpty() && ctx->callbacks.checksum_hook - && fs->type == CSYNC_FTW_TYPE_FILE) { + && fs->type == ItemTypeFile) { fs->checksumHeader = ctx->callbacks.checksum_hook( _rel_to_abs(ctx, fs->path), base._checksumHeader, ctx->callbacks.checksum_userdata); @@ -300,7 +300,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr f qCDebug(lcUpdate, "pot rename detected based on inode # %" PRId64 "", (uint64_t) fs->inode); /* inode found so the file has been renamed */ fs->instruction = CSYNC_INSTRUCTION_EVAL_RENAME; - if (fs->type == CSYNC_FTW_TYPE_DIR) { + if (fs->type == ItemTypeDirectory) { csync_rename_record(ctx, base._path, fs->path); } } @@ -325,7 +325,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr f done = true; return; } - if (fs->type != CSYNC_FTW_TYPE_DIR && base._etag != fs->etag) { + if (fs->type != ItemTypeDirectory && base._etag != fs->etag) { /* File with different etag, don't do a rename, but download the file again */ qCWarning(lcUpdate, "file etag different, not a rename"); done = true; @@ -333,7 +333,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr f } // Record directory renames - if (fs->type == CSYNC_FTW_TYPE_DIR) { + if (fs->type == ItemTypeDirectory) { // If the same folder was already renamed by a different entry, // skip to the next candidate if (ctx->renames.folder_renamed_to.count(base._path) > 0) { @@ -354,7 +354,7 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr f } if (fs->instruction == CSYNC_INSTRUCTION_NEW - && fs->type == CSYNC_FTW_TYPE_DIR + && fs->type == ItemTypeDirectory && ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncNewFolderHook) { if (ctx->callbacks.checkSelectiveSyncNewFolderHook(ctx->callbacks.update_callback_userdata, fs->path, fs->remotePerm)) { @@ -369,7 +369,7 @@ out: /* Set the ignored error string. */ if (fs->instruction == CSYNC_INSTRUCTION_IGNORE) { - if( fs->type == CSYNC_FTW_TYPE_SLINK ) { + if( fs->type == ItemTypeSoftLink ) { fs->error_status = CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK; /* Symbolic links are ignored. */ } else { if (excluded == CSYNC_FILE_EXCLUDE_LIST) { @@ -394,7 +394,7 @@ out: if (fs->instruction != CSYNC_INSTRUCTION_NONE && fs->instruction != CSYNC_INSTRUCTION_IGNORE && fs->instruction != CSYNC_INSTRUCTION_UPDATE_METADATA - && fs->type != CSYNC_FTW_TYPE_DIR) { + && fs->type != ItemTypeDirectory) { fs->child_modified = true; } @@ -436,21 +436,21 @@ int csync_walker(CSYNC *ctx, std::unique_ptr fs) { } switch (fs->type) { - case CSYNC_FTW_TYPE_FILE: + case ItemTypeFile: if (ctx->current == REMOTE_REPLICA) { qCDebug(lcUpdate, "file: %s [file_id=%s size=%" PRIu64 "]", fs->path.constData(), fs->file_id.constData(), fs->size); } else { qCDebug(lcUpdate, "file: %s [inode=%" PRIu64 " size=%" PRIu64 "]", fs->path.constData(), fs->inode, fs->size); } break; - case CSYNC_FTW_TYPE_DIR: /* enter directory */ + case ItemTypeDirectory: /* enter directory */ if (ctx->current == REMOTE_REPLICA) { qCDebug(lcUpdate, "directory: %s [file_id=%s]", fs->path.constData(), fs->file_id.constData()); } else { qCDebug(lcUpdate, "directory: %s [inode=%" PRIu64 "]", fs->path.constData(), fs->inode); } break; - case CSYNC_FTW_TYPE_SLINK: + case ItemTypeSoftLink: qCDebug(lcUpdate, "symlink: %s - not supported", fs->path.constData()); break; default: @@ -690,7 +690,7 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn, } previous_fs = ctx->current_fs; - bool recurse = dirent->type == CSYNC_FTW_TYPE_DIR; + bool recurse = dirent->type == ItemTypeDirectory; /* Call walker function for each file */ rc = fn(ctx, std::move(dirent)); diff --git a/src/csync/vio/csync_vio_local_unix.cpp b/src/csync/vio/csync_vio_local_unix.cpp index b60fe99ce..c65e21d9f 100644 --- a/src/csync/vio/csync_vio_local_unix.cpp +++ b/src/csync/vio/csync_vio_local_unix.cpp @@ -120,9 +120,9 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *d case DT_DIR: case DT_REG: if (dirent->d_type == DT_DIR) { - file_stat->type = CSYNC_FTW_TYPE_DIR; + file_stat->type = ItemTypeDirectory; } else { - file_stat->type = CSYNC_FTW_TYPE_FILE; + file_stat->type = ItemTypeFile; } break; default: @@ -135,7 +135,7 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *d if (_csync_vio_local_stat_mb(fullPath.constData(), file_stat.get()) < 0) { // Will get excluded by _csync_detect_update. - file_stat->type = CSYNC_FTW_TYPE_SKIP; + file_stat->type = ItemTypeSkip; } return file_stat; } @@ -160,17 +160,17 @@ static int _csync_vio_local_stat_mb(const mbchar_t *wuri, csync_file_stat_t *buf switch (sb.st_mode & S_IFMT) { case S_IFDIR: - buf->type = CSYNC_FTW_TYPE_DIR; + buf->type = ItemTypeDirectory; break; case S_IFREG: - buf->type = CSYNC_FTW_TYPE_FILE; + buf->type = ItemTypeFile; break; case S_IFLNK: case S_IFSOCK: - buf->type = CSYNC_FTW_TYPE_SLINK; + buf->type = ItemTypeSoftLink; break; default: - buf->type = CSYNC_FTW_TYPE_SKIP; + buf->type = ItemTypeSkip; break; } diff --git a/src/csync/vio/csync_vio_local_win.cpp b/src/csync/vio/csync_vio_local_win.cpp index 588575ed1..3b94550bb 100644 --- a/src/csync/vio/csync_vio_local_win.cpp +++ b/src/csync/vio/csync_vio_local_win.cpp @@ -172,21 +172,21 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *d // Detect symlinks, and treat junctions as symlinks too. if (handle->ffd.dwReserved0 == IO_REPARSE_TAG_SYMLINK || handle->ffd.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT) { - file_stat->type = CSYNC_FTW_TYPE_SLINK; + file_stat->type = ItemTypeSoftLink; } else { // The SIS and DEDUP reparse points should be treated as // regular files. We don't know about the other ones yet, // but will also treat them normally for now. - file_stat->type = CSYNC_FTW_TYPE_FILE; + file_stat->type = ItemTypeFile; } } else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE || handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE || handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) { - file_stat->type = CSYNC_FTW_TYPE_SKIP; + file_stat->type = ItemTypeSkip; } else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - file_stat->type = CSYNC_FTW_TYPE_DIR; + file_stat->type = ItemTypeDirectory; } else { - file_stat->type = CSYNC_FTW_TYPE_FILE; + file_stat->type = ItemTypeFile; } /* Check for the hidden flag */ @@ -204,7 +204,7 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *d if (_csync_vio_local_stat_mb(fullPath.data(), file_stat.get()) < 0) { // Will get excluded by _csync_detect_update. - file_stat->type = CSYNC_FTW_TYPE_SKIP; + file_stat->type = ItemTypeSkip; } return file_stat; diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp index 4657e0488..eb0ce8d3e 100644 --- a/src/libsync/discoveryphase.cpp +++ b/src/libsync/discoveryphase.cpp @@ -310,9 +310,9 @@ static std::unique_ptr propertyMapToFileStat(const QMaptype = CSYNC_FTW_TYPE_DIR; + file_stat->type = ItemTypeDirectory; } else { - file_stat->type = CSYNC_FTW_TYPE_FILE; + file_stat->type = ItemTypeFile; } } else if (property == "getlastmodified") { file_stat->modtime = oc_httpdate_parse(value.toUtf8()); diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 6dc571c72..5e387921c 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -278,7 +278,7 @@ void SyncEngine::deleteStaleDownloadInfos(const SyncFileItemVector &syncItems) QSet download_file_paths; foreach (const SyncFileItemPtr &it, syncItems) { if (it->_direction == SyncFileItem::Down - && it->_type == SyncFileItem::File) { + && it->_type == ItemTypeFile) { download_file_paths.insert(it->_file); } } @@ -299,7 +299,7 @@ void SyncEngine::deleteStaleUploadInfos(const SyncFileItemVector &syncItems) QSet upload_file_paths; foreach (const SyncFileItemPtr &it, syncItems) { if (it->_direction == SyncFileItem::Up - && it->_type == SyncFileItem::File) { + && it->_type == ItemTypeFile) { upload_file_paths.insert(it->_file); } } @@ -529,7 +529,7 @@ int SyncEngine::treewalkFile(csync_file_stat_t *file, csync_file_stat_t *other, item->_errorString = tr("Filename encoding is not valid"); } - bool isDirectory = file->type == CSYNC_FTW_TYPE_DIR; + bool isDirectory = file->type == ItemTypeDirectory; if (!file->etag.isEmpty()) { item->_etag = file->etag; @@ -540,19 +540,7 @@ int SyncEngine::treewalkFile(csync_file_stat_t *file, csync_file_stat_t *other, item->_inode = file->inode; } - switch (file->type) { - case CSYNC_FTW_TYPE_DIR: - item->_type = SyncFileItem::Directory; - break; - case CSYNC_FTW_TYPE_FILE: - item->_type = SyncFileItem::File; - break; - case CSYNC_FTW_TYPE_SLINK: - item->_type = SyncFileItem::SoftLink; - break; - default: - item->_type = SyncFileItem::UnknownType; - } + item->_type = file->type; SyncFileItem::Direction dir = SyncFileItem::None; diff --git a/src/libsync/syncfileitem.cpp b/src/libsync/syncfileitem.cpp index bfea07163..832feefde 100644 --- a/src/libsync/syncfileitem.cpp +++ b/src/libsync/syncfileitem.cpp @@ -58,7 +58,7 @@ SyncFileItemPtr SyncFileItem::fromSyncJournalFileRecord(const SyncJournalFileRec item->_file = rec._path; item->_inode = rec._inode; item->_modtime = rec._modtime; - item->_type = static_cast(rec._type); + item->_type = rec._type; item->_etag = rec._etag; item->_fileId = rec._fileId; item->_size = rec._fileSize; diff --git a/src/libsync/syncfileitem.h b/src/libsync/syncfileitem.h index dd364ae43..aac2bd48d 100644 --- a/src/libsync/syncfileitem.h +++ b/src/libsync/syncfileitem.h @@ -42,13 +42,6 @@ public: Down }; - enum Type { - UnknownType = 0, - File = CSYNC_FTW_TYPE_FILE, - Directory = CSYNC_FTW_TYPE_DIR, - SoftLink = CSYNC_FTW_TYPE_SLINK - }; - enum Status { // stored in 4 bits NoStatus, @@ -101,7 +94,7 @@ public: SyncFileItem() - : _type(UnknownType) + : _type(ItemTypeSkip) , _direction(None) , _serverHasIgnoredFiles(false) , _hasBlacklistEntry(false) @@ -173,7 +166,7 @@ public: bool isDirectory() const { - return _type == SyncFileItem::Directory; + return _type == ItemTypeDirectory; } /** @@ -195,7 +188,7 @@ public: // Variables useful for everybody QString _file; QString _renameTarget; - Type _type BITFIELD(3); + ItemType _type BITFIELD(3); Direction _direction BITFIELD(3); bool _serverHasIgnoredFiles BITFIELD(1); diff --git a/test/csync/csync_tests/check_csync_exclude.cpp b/test/csync/csync_tests/check_csync_exclude.cpp index b01f4cdc8..7c64ce5de 100644 --- a/test/csync/csync_tests/check_csync_exclude.cpp +++ b/test/csync/csync_tests/check_csync_exclude.cpp @@ -90,22 +90,22 @@ static int teardown(void **state) { static int check_file_full(const char *path) { - return excludedFiles->fullPatternMatch(path, CSYNC_FTW_TYPE_FILE); + return excludedFiles->fullPatternMatch(path, ItemTypeFile); } static int check_dir_full(const char *path) { - return excludedFiles->fullPatternMatch(path, CSYNC_FTW_TYPE_DIR); + return excludedFiles->fullPatternMatch(path, ItemTypeDirectory); } static int check_file_traversal(const char *path) { - return excludedFiles->traversalPatternMatch(path, CSYNC_FTW_TYPE_FILE); + return excludedFiles->traversalPatternMatch(path, ItemTypeFile); } static int check_dir_traversal(const char *path) { - return excludedFiles->traversalPatternMatch(path, CSYNC_FTW_TYPE_DIR); + return excludedFiles->traversalPatternMatch(path, ItemTypeDirectory); } static void check_csync_exclude_add(void **) diff --git a/test/csync/csync_tests/check_csync_update.cpp b/test/csync/csync_tests/check_csync_update.cpp index db6819907..01681b7de 100644 --- a/test/csync/csync_tests/check_csync_update.cpp +++ b/test/csync/csync_tests/check_csync_update.cpp @@ -184,7 +184,7 @@ static std::unique_ptr create_fstat(const char *name, fs->path = "file.txt"; } - fs->type = CSYNC_FTW_TYPE_FILE; + fs->type = ItemTypeFile; if (inode == 0) { fs->inode = 619070; diff --git a/test/csync/vio_tests/check_vio_ext.cpp b/test/csync/vio_tests/check_vio_ext.cpp index f86ce9591..f0e772956 100644 --- a/test/csync/vio_tests/check_vio_ext.cpp +++ b/test/csync/vio_tests/check_vio_ext.cpp @@ -218,7 +218,7 @@ static void traverse_dir(void **state, const char *dir, int *cnt) continue; } - is_dir = (dirent->type == CSYNC_FTW_TYPE_DIR) ? 1:0; + is_dir = (dirent->type == ItemTypeDirectory) ? 1:0; assert_int_not_equal( asprintf( &subdir, "%s/%s", dir, dirent->path.constData() ), -1 ); diff --git a/test/testsyncjournaldb.cpp b/test/testsyncjournaldb.cpp index cb86a1655..389dcec5d 100644 --- a/test/testsyncjournaldb.cpp +++ b/test/testsyncjournaldb.cpp @@ -54,7 +54,7 @@ private slots: // signed int being cast to uint64 either (like uint64::max would be) record._inode = std::numeric_limits::max() + 12ull; record._modtime = dropMsecs(QDateTime::currentDateTime()); - record._type = 5; + record._type = ItemTypeDirectory; record._etag = "789789"; record._fileId = "abcd"; record._remotePerm = RemotePermissions("RW"); @@ -76,7 +76,7 @@ private slots: record._modtime = dropMsecs(QDateTime::currentDateTime().addDays(1)); // try a value that only fits uint64, not int64 record._inode = std::numeric_limits::max() - std::numeric_limits::max() - 1; - record._type = 7; + record._type = ItemTypeFile; record._etag = "789FFF"; record._fileId = "efg"; record._remotePerm = RemotePermissions("NV"); From 7ae8ba35de0ce5977c0a5cb65e8d52ead8518081 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 15 Dec 2017 09:41:08 +0100 Subject: [PATCH 015/138] Remove unused csync test file Now found at test/csync/csync_tests/check_csync_update.cpp --- .../tests/csync_tests/check_csync_update.cpp | 460 ------------------ 1 file changed, 460 deletions(-) delete mode 100644 csync/tests/csync_tests/check_csync_update.cpp diff --git a/csync/tests/csync_tests/check_csync_update.cpp b/csync/tests/csync_tests/check_csync_update.cpp deleted file mode 100644 index cc11bad83..000000000 --- a/csync/tests/csync_tests/check_csync_update.cpp +++ /dev/null @@ -1,460 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2008-2013 by Andreas Schneider - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "csync_update.cpp" - -extern "C" { - -#include "torture.h" - -#define TESTDB "/tmp/check_csync/journal.db" - -static int firstrun = 1; - -static void statedb_create_metadata_table(sqlite3 *db) -{ - int rc = 0; - - if( db ) { - const char *sql = "CREATE TABLE IF NOT EXISTS metadata(" - "phash INTEGER(8)," - "pathlen INTEGER," - "path VARCHAR(4096)," - "inode INTEGER," - "uid INTEGER," - "gid INTEGER," - "mode INTEGER," - "modtime INTEGER(8)," - "type INTEGER," - "md5 VARCHAR(32)," - "fileid VARCHAR(128)," - "remotePerm VARCHAR(128)," - "filesize BIGINT," - "ignoredChildrenRemote INT," - "contentChecksum TEXT," - "contentChecksumTypeId INTEGER," - "PRIMARY KEY(phash));"; - - rc = sqlite3_exec(db, sql, NULL, NULL, NULL); - //const char *msg = sqlite3_errmsg(db); - assert_int_equal( rc, SQLITE_OK ); - - sql = "CREATE TABLE IF NOT EXISTS checksumtype(" - "id INTEGER PRIMARY KEY," - "name TEXT UNIQUE" - ");"; - rc = sqlite3_exec(db, sql, NULL, NULL, NULL); - assert_int_equal( rc, SQLITE_OK ); - } -} - -static void statedb_insert_metadata(sqlite3 *db) -{ - int rc = 0; - - if( db ) { - char *stmt = sqlite3_mprintf("INSERT INTO metadata" - "(phash, pathlen, path, inode, uid, gid, mode, modtime,type,md5) VALUES" - "(%lld, %d, '%q', %d, %d, %d, %d, %lld, %d, '%q');", - (long long signed int)42, - 42, - "I_was_wurst_before_I_became_wurstsalat", - 619070, - 42, - 42, - 42, - (long long signed int)42, - 0, - "4711"); - - char *errmsg; - rc = sqlite3_exec(db, stmt, NULL, NULL, &errmsg); - sqlite3_free(stmt); - assert_int_equal( rc, SQLITE_OK ); - } -} - -static int setup(void **state) -{ - CSYNC *csync; - int rc; - - unlink(TESTDB); - rc = system("mkdir -p /tmp/check_csync"); - assert_int_equal(rc, 0); - rc = system("mkdir -p /tmp/check_csync1"); - assert_int_equal(rc, 0); - csync_create(&csync, "/tmp/check_csync1"); - csync_init(csync, TESTDB); - - /* Create a new db with metadata */ - sqlite3 *db; - csync->statedb.file = c_strdup(TESTDB); - rc = sqlite3_open(csync->statedb.file, &db); - statedb_create_metadata_table(db); - if( firstrun ) { - statedb_insert_metadata(db); - firstrun = 0; - } - sqlite3_close(db); - - rc = csync_statedb_load(csync, TESTDB, &csync->statedb.db); - assert_int_equal(rc, 0); - - *state = csync; - - return 0; -} - -static int setup_ftw(void **state) -{ - CSYNC *csync; - int rc; - - rc = system("mkdir -p /tmp/check_csync"); - assert_int_equal(rc, 0); - rc = system("mkdir -p /tmp/check_csync1"); - assert_int_equal(rc, 0); - csync_create(&csync, "/tmp"); - csync_init(csync, TESTDB); - - sqlite3 *db = NULL; - rc = sqlite3_open_v2(TESTDB, &db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL); - assert_int_equal(rc, SQLITE_OK); - statedb_create_metadata_table(db); - rc = sqlite3_close(db); - assert_int_equal(rc, SQLITE_OK); - - rc = csync_statedb_load(csync, TESTDB, &csync->statedb.db); - assert_int_equal(rc, 0); - - csync->statedb.file = c_strdup( TESTDB ); - *state = csync; - - return 0; -} - -static int teardown(void **state) -{ - CSYNC *csync = (CSYNC*)*state; - int rc; - - unlink( csync->statedb.file); - rc = csync_destroy(csync); - assert_int_equal(rc, 0); - - *state = NULL; - - return 0; -} - -static int teardown_rm(void **state) { - int rc; - - teardown(state); - - rc = system("rm -rf /tmp/check_csync"); - assert_int_equal(rc, 0); - rc = system("rm -rf /tmp/check_csync1"); - assert_int_equal(rc, 0); - - return 0; -} - -/* create a file stat, caller must free memory */ -static csync_vio_file_stat_t* create_fstat(const char *name, - ino_t inode, - time_t mtime) -{ - csync_vio_file_stat_t *fs = NULL; - time_t t; - - fs = csync_vio_file_stat_new(); - if (fs == NULL) { - return NULL; - } - - if (name && *name) { - fs->name = c_strdup(name); - } else { - fs->name = c_strdup("file.txt"); - } - - if (fs->name == NULL) { - csync_vio_file_stat_destroy(fs); - return NULL; - } - - fs->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; - - fs->type = CSYNC_VIO_FILE_TYPE_REGULAR; - fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; - - - if (inode == 0) { - fs->inode = 619070; - } else { - fs->inode = inode; - } - fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE; - - - fs->size = 157459; - fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; - - - - if (mtime == 0) { - fs->atime = fs->ctime = fs->mtime = time(&t); - } else { - fs->atime = fs->ctime = fs->mtime = mtime; - } - fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME; - fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME; - fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME; - - return fs; -} - -static int failing_fn(CSYNC *ctx, - const char *file, - const csync_vio_file_stat_t *fs, - int flag) -{ - (void) ctx; - (void) file; - (void) fs; - (void) flag; - - return -1; -} - -/* detect a new file */ -static void check_csync_detect_update(void **state) -{ - CSYNC *csync = (CSYNC*)*state; - csync_file_stat_t *st; - csync_vio_file_stat_t *fs; - int rc; - - fs = create_fstat("file.txt", 0, 1217597845); - assert_non_null(fs); - - rc = _csync_detect_update(csync, - "/tmp/check_csync1/file.txt", - fs, - CSYNC_FTW_TYPE_FILE); - assert_int_equal(rc, 0); - - /* the instruction should be set to new */ - st = (csync_file_stat_t*)c_rbtree_node_data(csync->local.tree->root); - assert_int_equal(st->instruction, CSYNC_INSTRUCTION_NEW); - - /* create a statedb */ - csync_set_status(csync, 0xFFFF); - - csync_vio_file_stat_destroy(fs); -} - -/* Test behaviour in case no db is there. For that its important that the - * test before this one uses teardown_rm. - */ -static void check_csync_detect_update_db_none(void **state) -{ - CSYNC *csync = (CSYNC*)*state; - csync_file_stat_t *st; - csync_vio_file_stat_t *fs; - int rc; - - fs = create_fstat("file.txt", 0, 1217597845); - assert_non_null(fs); - - rc = _csync_detect_update(csync, - "/tmp/check_csync1/file.txt", - fs, - CSYNC_FTW_TYPE_FILE); - assert_int_equal(rc, 0); - - /* the instruction should be set to new */ - st = (csync_file_stat_t*)c_rbtree_node_data(csync->local.tree->root); - assert_int_equal(st->instruction, CSYNC_INSTRUCTION_NEW); - - - /* create a statedb */ - csync_set_status(csync, 0xFFFF); - - csync_vio_file_stat_destroy(fs); -} - -static void check_csync_detect_update_db_eval(void **state) -{ - CSYNC *csync = (CSYNC*)*state; - csync_file_stat_t *st; - csync_vio_file_stat_t *fs; - int rc; - - fs = create_fstat("file.txt", 0, 42); - assert_non_null(fs); - - rc = _csync_detect_update(csync, - "/tmp/check_csync1/file.txt", - fs, - CSYNC_FTW_TYPE_FILE); - assert_int_equal(rc, 0); - - /* the instruction should be set to new */ - st = (csync_file_stat_t*)c_rbtree_node_data(csync->local.tree->root); - assert_int_equal(st->instruction, CSYNC_INSTRUCTION_NEW); - - /* create a statedb */ - csync_set_status(csync, 0xFFFF); - - csync_vio_file_stat_destroy(fs); -} - - -static void check_csync_detect_update_db_rename(void **state) -{ - CSYNC *csync = (CSYNC*)*state; - // csync_file_stat_t *st; - - csync_vio_file_stat_t *fs; - int rc = 0; - - fs = create_fstat("wurst.txt", 0, 42); - assert_non_null(fs); - csync_set_statedb_exists(csync, 1); - - rc = _csync_detect_update(csync, - "/tmp/check_csync1/wurst.txt", - fs, - CSYNC_FTW_TYPE_FILE); - assert_int_equal(rc, 0); - - /* the instruction should be set to rename */ - /* - * temporarily broken. - st = (csync_file_stat_t*)c_rbtree_node_data(csync->local.tree->root); - assert_int_equal(st->instruction, CSYNC_INSTRUCTION_RENAME); - - st->instruction = CSYNC_INSTRUCTION_UPDATED; - */ - /* create a statedb */ - csync_set_status(csync, 0xFFFF); - - csync_vio_file_stat_destroy(fs); -} - -static void check_csync_detect_update_db_new(void **state) -{ - CSYNC *csync = (CSYNC*)*state; - csync_file_stat_t *st; - csync_vio_file_stat_t *fs; - int rc; - - fs = create_fstat("file.txt", 42000, 0); - assert_non_null(fs); - - rc = _csync_detect_update(csync, - "/tmp/check_csync1/file.txt", - fs, - CSYNC_FTW_TYPE_FILE); - assert_int_equal(rc, 0); - - /* the instruction should be set to new */ - st = (csync_file_stat_t*)c_rbtree_node_data(csync->local.tree->root); - assert_int_equal(st->instruction, CSYNC_INSTRUCTION_NEW); - - - /* create a statedb */ - csync_set_status(csync, 0xFFFF); - - csync_vio_file_stat_destroy(fs); -} - -static void check_csync_detect_update_null(void **state) -{ - CSYNC *csync = (CSYNC*)*state; - csync_vio_file_stat_t *fs; - int rc; - - fs = create_fstat("file.txt", 0, 0); - assert_non_null(fs); - - rc = _csync_detect_update(csync, - NULL, - fs, - CSYNC_FTW_TYPE_FILE); - assert_int_equal(rc, -1); - - rc = _csync_detect_update(csync, - "/tmp/check_csync1/file.txt", - NULL, - CSYNC_FTW_TYPE_FILE); - assert_int_equal(rc, -1); - - csync_vio_file_stat_destroy(fs); -} - -static void check_csync_ftw(void **state) -{ - CSYNC *csync = (CSYNC*)*state; - int rc; - - rc = csync_ftw(csync, "/tmp", csync_walker, MAX_DEPTH); - assert_int_equal(rc, 0); -} - -static void check_csync_ftw_empty_uri(void **state) -{ - CSYNC *csync = (CSYNC*)*state; - int rc; - - rc = csync_ftw(csync, "", csync_walker, MAX_DEPTH); - assert_int_equal(rc, -1); -} - -static void check_csync_ftw_failing_fn(void **state) -{ - CSYNC *csync = (CSYNC*)*state; - int rc; - - rc = csync_ftw(csync, "/tmp", failing_fn, MAX_DEPTH); - assert_int_equal(rc, -1); -} - -int torture_run_tests(void) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(check_csync_detect_update, setup, teardown_rm), - cmocka_unit_test_setup_teardown(check_csync_detect_update_db_none, setup, teardown), - cmocka_unit_test_setup_teardown(check_csync_detect_update_db_eval, setup, teardown), - cmocka_unit_test_setup_teardown(check_csync_detect_update_db_rename, setup, teardown), - cmocka_unit_test_setup_teardown(check_csync_detect_update_db_new, setup, teardown_rm), - cmocka_unit_test_setup_teardown(check_csync_detect_update_null, setup, teardown_rm), - - cmocka_unit_test_setup_teardown(check_csync_ftw, setup_ftw, teardown_rm), - cmocka_unit_test_setup_teardown(check_csync_ftw_empty_uri, setup_ftw, teardown_rm), - cmocka_unit_test_setup_teardown(check_csync_ftw_failing_fn, setup_ftw, teardown_rm), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} - -} From a7c0cfc8ebcf109161e14de130f110d115a3ef31 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Sat, 2 Dec 2017 11:40:43 +0100 Subject: [PATCH 016/138] Upload conflict files #4557 If the server has the 'uploadConflictFiles' capability conflict files will be uploaded instead of ignored. Uploaded conflict files have the following headers set during upload OC-Conflict: 1 OC-ConflictBaseFileId: 172489174instanceid OC-ConflictBaseMtime: 1235789213 OC-ConflictBaseEtag: myetag when the data is available. Downloads accept the same headers in return when downloading a conflict file. In the absence of server support clients will identify conflict files through the file name pattern and attempt to deduce the base fileid. Base etag and mtime can't be deduced though. The upload job for a new conflict file will be triggered directly from the job that created the conflict file now. No second sync run is necessary anymore. This commit does not yet introduce a 'username' like identifier that automatically gets added to conflict file filenames (to name the files foo_conflict-Fred-1345.txt instead of just foo_conflict-1345.txt). --- src/common/filesystembase.cpp | 21 -- src/common/filesystembase.h | 5 - src/common/syncjournaldb.cpp | 99 +++++++- src/common/syncjournaldb.h | 19 ++ src/common/syncjournalfilerecord.h | 37 +++ src/common/utility.cpp | 62 +++-- src/common/utility.h | 16 +- src/csync/csync_exclude.cpp | 19 +- src/csync/csync_exclude.h | 9 + src/csync/csync_private.h | 2 + src/csync/csync_update.cpp | 2 +- src/libsync/capabilities.cpp | 11 + src/libsync/capabilities.h | 5 + src/libsync/owncloudpropagator.cpp | 27 ++- src/libsync/owncloudpropagator.h | 23 +- src/libsync/propagatedownload.cpp | 66 +++++- src/libsync/propagatedownload.h | 1 + src/libsync/propagateupload.cpp | 13 ++ src/libsync/syncengine.cpp | 58 ++++- src/libsync/syncengine.h | 12 + test/CMakeLists.txt | 1 + test/testsyncconflict.cpp | 351 +++++++++++++++++++++++++++++ test/testsyncjournaldb.cpp | 22 ++ 23 files changed, 793 insertions(+), 88 deletions(-) create mode 100644 test/testsyncconflict.cpp diff --git a/src/common/filesystembase.cpp b/src/common/filesystembase.cpp index 1d95e3918..8de47312e 100644 --- a/src/common/filesystembase.cpp +++ b/src/common/filesystembase.cpp @@ -403,27 +403,6 @@ QByteArray FileSystem::calcAdler32(const QString &filename) } #endif -QString FileSystem::makeConflictFileName(const QString &fn, const QDateTime &dt) -{ - QString conflictFileName(fn); - // Add _conflict-XXXX before the extension. - int dotLocation = conflictFileName.lastIndexOf('.'); - // If no extension, add it at the end (take care of cases like foo/.hidden or foo.bar/file) - if (dotLocation <= conflictFileName.lastIndexOf('/') + 1) { - dotLocation = conflictFileName.size(); - } - QString timeString = dt.toString("yyyyMMdd-hhmmss"); - - // Additional marker - QByteArray conflictFileUserName = qgetenv("CSYNC_CONFLICT_FILE_USERNAME"); - if (conflictFileUserName.isEmpty()) - conflictFileName.insert(dotLocation, "_conflict-" + timeString); - else - conflictFileName.insert(dotLocation, "_conflict_" + QString::fromUtf8(conflictFileUserName) + "-" + timeString); - - return conflictFileName; -} - bool FileSystem::remove(const QString &fileName, QString *errorString) { #ifdef Q_OS_WIN diff --git a/src/common/filesystembase.h b/src/common/filesystembase.h index 9568dac12..e7c7672b1 100644 --- a/src/common/filesystembase.h +++ b/src/common/filesystembase.h @@ -131,11 +131,6 @@ namespace FileSystem { QByteArray OCSYNC_EXPORT calcAdler32(const QString &fileName); #endif - /** - * Returns a file name based on \a fn that's suitable for a conflict. - */ - QString OCSYNC_EXPORT makeConflictFileName(const QString &fn, const QDateTime &dt); - /** * Returns true when a file is locked. (Windows only) */ diff --git a/src/common/syncjournaldb.cpp b/src/common/syncjournaldb.cpp index b2d348af8..a40149d3a 100644 --- a/src/common/syncjournaldb.cpp +++ b/src/common/syncjournaldb.cpp @@ -438,7 +438,7 @@ bool SyncJournalDb::checkConnect() return sqlFail("Create table version", createQuery); } - // create the checksumtype table. + // create the datafingerprint table. createQuery.prepare("CREATE TABLE IF NOT EXISTS datafingerprint(" "fingerprint TEXT UNIQUE" ");"); @@ -446,6 +446,17 @@ bool SyncJournalDb::checkConnect() return sqlFail("Create table datafingerprint", createQuery); } + // create the conflicts table. + createQuery.prepare("CREATE TABLE IF NOT EXISTS conflicts(" + "path TEXT PRIMARY KEY," + "baseFileId TEXT," + "baseEtag TEXT," + "baseModtime INTEGER" + ");"); + if (!createQuery.exec()) { + return sqlFail("Create table conflicts", createQuery); + } + createQuery.prepare("CREATE TABLE IF NOT EXISTS version(" "major INTEGER(8)," "minor INTEGER(8)," @@ -693,6 +704,23 @@ bool SyncJournalDb::checkConnect() return sqlFail("prepare _setDataFingerprintQuery2", *_setDataFingerprintQuery2); } + _getConflictRecordQuery.reset(new SqlQuery(_db)); + if (_getConflictRecordQuery->prepare("SELECT baseFileId, baseModtime, baseEtag FROM conflicts WHERE path=?1;")) { + return sqlFail("prepare _getConflictRecordQuery", *_getConflictRecordQuery); + } + + _setConflictRecordQuery.reset(new SqlQuery(_db)); + if (_setConflictRecordQuery->prepare("INSERT OR REPLACE INTO conflicts " + "(path, baseFileId, baseModtime, baseEtag) " + "VALUES (?1, ?2, ?3, ?4);")) { + return sqlFail("prepare _setConflictRecordQuery", *_setConflictRecordQuery); + } + + _deleteConflictRecordQuery.reset(new SqlQuery(_db)); + if (_deleteConflictRecordQuery->prepare("DELETE FROM conflicts WHERE path=?1;")) { + return sqlFail("prepare _deleteConflictRecordQuery", *_deleteConflictRecordQuery); + } + // don't start a new transaction now commitInternal(QString("checkConnect End"), false); @@ -741,6 +769,9 @@ void SyncJournalDb::close() _getDataFingerprintQuery.reset(0); _setDataFingerprintQuery1.reset(0); _setDataFingerprintQuery2.reset(0); + _getConflictRecordQuery.reset(0); + _setConflictRecordQuery.reset(0); + _deleteConflictRecordQuery.reset(0); _db.close(); _avoidReadFromDbOnNextSyncFilter.clear(); @@ -1951,6 +1982,72 @@ void SyncJournalDb::setDataFingerprint(const QByteArray &dataFingerprint) _setDataFingerprintQuery2->exec(); } +void SyncJournalDb::setConflictRecord(const ConflictRecord &record) +{ + QMutexLocker locker(&_mutex); + if (!checkConnect()) + return; + + auto &query = *_setConflictRecordQuery; + query.reset_and_clear_bindings(); + query.bindValue(1, record.path); + query.bindValue(2, record.baseFileId); + query.bindValue(3, record.baseModtime); + query.bindValue(4, record.baseEtag); + ASSERT(query.exec()); +} + +ConflictRecord SyncJournalDb::conflictRecord(const QByteArray &path) +{ + ConflictRecord entry; + + QMutexLocker locker(&_mutex); + if (!checkConnect()) + return entry; + + auto &query = *_getConflictRecordQuery; + query.reset_and_clear_bindings(); + query.bindValue(1, path); + ASSERT(query.exec()); + if (!query.next()) + return entry; + + entry.path = path; + entry.baseFileId = query.baValue(0); + entry.baseModtime = query.int64Value(1); + entry.baseEtag = query.baValue(2); + return entry; +} + +void SyncJournalDb::deleteConflictRecord(const QByteArray &path) +{ + QMutexLocker locker(&_mutex); + if (!checkConnect()) + return; + + auto &query = *_deleteConflictRecordQuery; + query.reset_and_clear_bindings(); + query.bindValue(1, path); + ASSERT(query.exec()); +} + +QByteArrayList SyncJournalDb::conflictRecordPaths() +{ + QMutexLocker locker(&_mutex); + if (!checkConnect()) + return {}; + + SqlQuery query(_db); + query.prepare("SELECT path FROM conflicts"); + ASSERT(query.exec()); + + QByteArrayList paths; + while (query.next()) + paths.append(query.baValue(0)); + + return paths; +} + void SyncJournalDb::clearFileTable() { QMutexLocker lock(&_mutex); diff --git a/src/common/syncjournaldb.h b/src/common/syncjournaldb.h index dc650ffa3..aa30d349c 100644 --- a/src/common/syncjournaldb.h +++ b/src/common/syncjournaldb.h @@ -207,6 +207,22 @@ public: void setDataFingerprint(const QByteArray &dataFingerprint); QByteArray dataFingerprint(); + + // Conflict record functions + + /// Store a new or updated record in the database + void setConflictRecord(const ConflictRecord &record); + + /// Retrieve a conflict record by path of the _conflict- file + ConflictRecord conflictRecord(const QByteArray &path); + + /// Delete a conflict record by path of the _conflict- file + void deleteConflictRecord(const QByteArray &path); + + /// Return all paths of _conflict- files with records in the db + QByteArrayList conflictRecordPaths(); + + /** * Delete any file entry. This will force the next sync to re-sync everything as if it was new, * restoring everyfile on every remote. If a file is there both on the client and server side, @@ -266,6 +282,9 @@ private: QScopedPointer _getDataFingerprintQuery; QScopedPointer _setDataFingerprintQuery1; QScopedPointer _setDataFingerprintQuery2; + QScopedPointer _getConflictRecordQuery; + QScopedPointer _setConflictRecordQuery; + QScopedPointer _deleteConflictRecordQuery; /* This is the list of paths we called avoidReadFromDbOnNextSync on. * It means that they should not be written to the DB in any case since doing diff --git a/src/common/syncjournalfilerecord.h b/src/common/syncjournalfilerecord.h index 76fd4cdbe..b09006365 100644 --- a/src/common/syncjournalfilerecord.h +++ b/src/common/syncjournalfilerecord.h @@ -111,6 +111,43 @@ public: bool isValid() const; }; + +/** Represents a conflict in the conflicts table. + * + * In the following the "conflict file" is the file with the "_conflict-" + * tag and the base file is the file that its a conflict for. So if + * a/foo.txt is the base file, its conflict file could be + * a/foo_conflict-1234.txt. + */ +class OCSYNC_EXPORT ConflictRecord +{ +public: + /** Path to the _conflict- file + * + * So if a/foo.txt has a conflict, this path would point to + * a/foo_conflict-1234.txt. + * + * The path is sync-folder relative. + */ + QByteArray path; + + /// File id of the base file + QByteArray baseFileId; + + /** Modtime of the base file + * + * may not be available and be -1 + */ + qint64 baseModtime = -1; + + /** Etag of the base file + * + * may not be available and empty + */ + QByteArray baseEtag; + + bool isValid() const { return !path.isEmpty(); } +}; } #endif // SYNCJOURNALFILERECORD_H diff --git a/src/common/utility.cpp b/src/common/utility.cpp index bdf603515..29308ea84 100644 --- a/src/common/utility.cpp +++ b/src/common/utility.cpp @@ -542,6 +542,21 @@ QUrl Utility::concatUrlPath(const QUrl &url, const QString &concatPath, return tmpUrl; } +QString Utility::makeConflictFileName(const QString &fn, const QDateTime &dt) +{ + QString conflictFileName(fn); + // Add _conflict-XXXX before the extension. + int dotLocation = conflictFileName.lastIndexOf('.'); + // If no extension, add it at the end (take care of cases like foo/.hidden or foo.bar/file) + if (dotLocation <= conflictFileName.lastIndexOf('/') + 1) { + dotLocation = conflictFileName.size(); + } + QString timeString = dt.toString("yyyyMMdd-hhmmss"); + + conflictFileName.insert(dotLocation, "_conflict-" + timeString); + return conflictFileName; +} + bool Utility::isConflictFile(const char *name) { const char *bname = std::strrchr(name, '/'); @@ -551,32 +566,33 @@ bool Utility::isConflictFile(const char *name) bname = name; } - if (std::strstr(bname, "_conflict-")) - return true; - - if (shouldUploadConflictFiles()) { - // For uploads, we want to consider files with any kind of username tag - // as conflict files. (pattern *_conflict_*-) - const char *startOfMarker = std::strstr(bname, "_conflict_"); - if (startOfMarker && std::strchr(startOfMarker, '-')) - return true; - } else { - // Old behavior: optionally, files with the specific string in the env variable - // appended are also considered conflict files. - static auto conflictFileUsername = qgetenv("CSYNC_CONFLICT_FILE_USERNAME"); - static auto usernameConflictId = QByteArray("_conflict_" + conflictFileUsername + "-"); - if (!conflictFileUsername.isEmpty() && std::strstr(bname, usernameConflictId.constData())) { - return true; - } - } - - return false; + return std::strstr(bname, "_conflict-"); } -bool Utility::shouldUploadConflictFiles() +bool Utility::isConflictFile(const QString &name) { - static bool uploadConflictFiles = qEnvironmentVariableIntValue("OWNCLOUD_UPLOAD_CONFLICT_FILES") != 0; - return uploadConflictFiles; + auto bname = name.midRef(name.lastIndexOf('/') + 1); + return bname.contains("_conflict-", Utility::fsCasePreserving() ? Qt::CaseInsensitive : Qt::CaseSensitive); +} + +QByteArray Utility::conflictFileBaseName(const QByteArray &conflictName) +{ + // This function must be able to deal with conflict files for conflict files. + // To do this, we scan backwards, for the outermost conflict marker and + // strip only that to generate the conflict file base name. + int from = conflictName.size(); + while (from != -1) { + auto start = conflictName.lastIndexOf("_conflict-", from); + if (start == -1) + return ""; + from = start - 1; + + auto end = conflictName.indexOf('.', start); + if (end == -1) + end = conflictName.size(); + return conflictName.left(start) + conflictName.mid(end); + } + return ""; } } // namespace OCC diff --git a/src/common/utility.h b/src/common/utility.h index 666e44cfd..7247673ce 100644 --- a/src/common/utility.h +++ b/src/common/utility.h @@ -182,17 +182,23 @@ namespace Utility { with the given parent. If no parent is specified, the caller must destroy the settings */ OCSYNC_EXPORT std::unique_ptr settingsWithGroup(const QString &group, QObject *parent = 0); + /** Returns a file name based on \a fn that's suitable for a conflict. + */ + OCSYNC_EXPORT QString makeConflictFileName(const QString &fn, const QDateTime &dt); + /** Returns whether a file name indicates a conflict file - * - * See FileSystem::makeConflictFileName. */ OCSYNC_EXPORT bool isConflictFile(const char *name); + OCSYNC_EXPORT bool isConflictFile(const QString &name); - /** Returns whether conflict files should be uploaded. + /** Find the base name for a conflict file name * - * Experimental! Real feature planned for 2.5. + * Will return an empty string if it's not a conflict file. + * + * Prefer to use the data from the conflicts table in the journal to determine + * a conflict's base file. */ - OCSYNC_EXPORT bool shouldUploadConflictFiles(); + OCSYNC_EXPORT QByteArray conflictFileBaseName(const QByteArray &conflictName); #ifdef Q_OS_WIN OCSYNC_EXPORT QVariant registryGetKeyValue(HKEY hRootKey, const QString &subKey, const QString &valueName); diff --git a/src/csync/csync_exclude.cpp b/src/csync/csync_exclude.cpp index 762a8eae4..f113a354e 100644 --- a/src/csync/csync_exclude.cpp +++ b/src/csync/csync_exclude.cpp @@ -218,7 +218,7 @@ bool csync_is_windows_reserved_word(const char *filename) return false; } -static CSYNC_EXCLUDE_TYPE _csync_excluded_common(const char *path) +static CSYNC_EXCLUDE_TYPE _csync_excluded_common(const char *path, bool excludeConflictFiles) { const char *bname = NULL; size_t blen = 0; @@ -313,11 +313,9 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(const char *path) } } - if (!OCC::Utility::shouldUploadConflictFiles()) { - if (OCC::Utility::isConflictFile(bname)) { - match = CSYNC_FILE_EXCLUDE_CONFLICT; - goto out; - } + if (excludeConflictFiles && OCC::Utility::isConflictFile(bname)) { + match = CSYNC_FILE_EXCLUDE_CONFLICT; + goto out; } out: @@ -341,6 +339,11 @@ void ExcludedFiles::addExcludeFilePath(const QString &path) _excludeFiles.insert(path); } +void ExcludedFiles::setExcludeConflictFiles(bool onoff) +{ + _excludeConflictFiles = onoff; +} + void ExcludedFiles::addManualExclude(const QByteArray &expr) { _manualExcludes.append(expr); @@ -408,7 +411,7 @@ bool ExcludedFiles::isExcluded( CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, ItemType filetype) const { - auto match = _csync_excluded_common(path); + auto match = _csync_excluded_common(path, _excludeConflictFiles); if (match != CSYNC_NOT_EXCLUDED) return match; if (_allExcludes.isEmpty()) @@ -454,7 +457,7 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, ItemTy CSYNC_EXCLUDE_TYPE ExcludedFiles::fullPatternMatch(const char *path, ItemType filetype) const { - auto match = _csync_excluded_common(path); + auto match = _csync_excluded_common(path, _excludeConflictFiles); if (match != CSYNC_NOT_EXCLUDED) return match; if (_allExcludes.isEmpty()) diff --git a/src/csync/csync_exclude.h b/src/csync/csync_exclude.h index 9f1c544d7..6f53e64a0 100644 --- a/src/csync/csync_exclude.h +++ b/src/csync/csync_exclude.h @@ -76,6 +76,13 @@ public: */ void addExcludeFilePath(const QString &path); + /** + * Whether conflict files shall be excluded. + * + * Defaults to true. + */ + void setExcludeConflictFiles(bool onoff); + /** * Checks whether a file or directory should be excluded. * @@ -191,6 +198,8 @@ private: QRegularExpression _fullRegexFile; QRegularExpression _fullRegexDir; + bool _excludeConflictFiles = true; + friend class ExcludedFilesTest; }; diff --git a/src/csync/csync_private.h b/src/csync/csync_private.h index 9a0276507..5463b7e40 100644 --- a/src/csync/csync_private.h +++ b/src/csync/csync_private.h @@ -203,6 +203,8 @@ struct OCSYNC_EXPORT csync_s { bool ignore_hidden_files = true; + bool upload_conflict_files = false; + csync_s(const char *localUri, OCC::SyncJournalDb *statedb); ~csync_s(); int reinitialize(); diff --git a/src/csync/csync_update.cpp b/src/csync/csync_update.cpp index ad58ef5b6..2a96faeff 100644 --- a/src/csync/csync_update.cpp +++ b/src/csync/csync_update.cpp @@ -400,7 +400,7 @@ out: // If conflict files are uploaded, they won't be marked as IGNORE / CSYNC_FILE_EXCLUDE_CONFLICT // but we still want them marked! - if (OCC::Utility::shouldUploadConflictFiles()) { + if (ctx->upload_conflict_files) { if (OCC::Utility::isConflictFile(fs->path.constData())) { fs->error_status = CSYNC_STATUS_INDIVIDUAL_IS_CONFLICT_FILE; } diff --git a/src/libsync/capabilities.cpp b/src/libsync/capabilities.cpp index 333410373..08c1e45ff 100644 --- a/src/libsync/capabilities.cpp +++ b/src/libsync/capabilities.cpp @@ -15,6 +15,7 @@ #include "capabilities.h" #include +#include namespace OCC { @@ -148,4 +149,14 @@ QString Capabilities::invalidFilenameRegex() const { return _capabilities["dav"].toMap()["invalidFilenameRegex"].toString(); } + +bool Capabilities::uploadConflictFiles() const +{ + static auto envIsSet = !qEnvironmentVariableIsEmpty("OWNCLOUD_UPLOAD_CONFLICT_FILES"); + static int envValue = qEnvironmentVariableIntValue("OWNCLOUD_UPLOAD_CONFLICT_FILES"); + if (envIsSet) + return envValue != 0; + + return _capabilities["uploadConflictFiles"].toBool(); +} } diff --git a/src/libsync/capabilities.h b/src/libsync/capabilities.h index f9f6614a4..63a59d6c0 100644 --- a/src/libsync/capabilities.h +++ b/src/libsync/capabilities.h @@ -116,6 +116,11 @@ public: */ QString invalidFilenameRegex() const; + /** + * Whether conflict files should remain local (default) or should be uploaded. + */ + bool uploadConflictFiles() const; + private: QVariantMap _capabilities; }; diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp index e1d081141..d960b4a2d 100644 --- a/src/libsync/owncloudpropagator.cpp +++ b/src/libsync/owncloudpropagator.cpp @@ -739,6 +739,12 @@ void PropagatorCompositeJob::slotSubJobAbortFinished() } } +void PropagatorCompositeJob::appendJob(PropagatorJob *job) +{ + job->setCompositeParent(this); + _jobsToDo.append(job); +} + bool PropagatorCompositeJob::scheduleSelfOrChild() { if (_state == Finished) { @@ -767,13 +773,8 @@ bool PropagatorCompositeJob::scheduleSelfOrChild() } // Now it's our turn, check if we have something left to do. - if (!_jobsToDo.isEmpty()) { - PropagatorJob *nextJob = _jobsToDo.first(); - _jobsToDo.remove(0); - _runningJobs.append(nextJob); - return possiblyRunNextJob(nextJob); - } - while (!_tasksToDo.isEmpty()) { + // First, convert a task to a job if necessary + while (_jobsToDo.isEmpty() && !_tasksToDo.isEmpty()) { SyncFileItemPtr nextTask = _tasksToDo.first(); _tasksToDo.remove(0); PropagatorJob *job = propagator()->createJob(nextTask); @@ -781,9 +782,15 @@ bool PropagatorCompositeJob::scheduleSelfOrChild() qCWarning(lcDirectory) << "Useless task found for file" << nextTask->destination() << "instruction" << nextTask->_instruction; continue; } - - _runningJobs.append(job); - return possiblyRunNextJob(job); + appendJob(job); + break; + } + // Then run the next job + if (!_jobsToDo.isEmpty()) { + PropagatorJob *nextJob = _jobsToDo.first(); + _jobsToDo.remove(0); + _runningJobs.append(nextJob); + return possiblyRunNextJob(nextJob); } // If neither us or our children had stuff left to do we could hang. Make sure diff --git a/src/libsync/owncloudpropagator.h b/src/libsync/owncloudpropagator.h index 062b3825e..4abe8eb03 100644 --- a/src/libsync/owncloudpropagator.h +++ b/src/libsync/owncloudpropagator.h @@ -49,6 +49,7 @@ qint64 freeSpaceLimit(); class SyncJournalDb; class OwncloudPropagator; +class PropagatorCompositeJob; /** * @brief the base class of propagator jobs @@ -102,6 +103,12 @@ public: */ virtual qint64 committedDiskSpace() const { return 0; } + /** Set the composite parent job + * + * Used only from PropagatorCompositeJob itself, when a job is added. + */ + void setCompositeParent(PropagatorCompositeJob *job) { _compositeParent = job; } + public slots: /* * Asynchronous abort requires emit of abortFinished() signal, @@ -128,6 +135,13 @@ signals: void abortFinished(SyncFileItem::Status status = SyncFileItem::NormalError); protected: OwncloudPropagator *propagator() const; + + /** If this job gets added to a composite job, this will point to the parent. + * + * That can be useful for jobs that want to spawn follow-up jobs without + * becoming composite jobs themselves. + */ + PropagatorCompositeJob *_compositeParent = nullptr; }; /* @@ -214,10 +228,7 @@ public: qDeleteAll(_runningJobs); } - void appendJob(PropagatorJob *job) - { - _jobsToDo.append(job); - } + void appendJob(PropagatorJob *job); void appendTask(const SyncFileItemPtr &item) { _tasksToDo.append(item); @@ -439,7 +450,10 @@ public: QString getFilePath(const QString &tmp_file_name) const; + /** Creates the job for an item. + */ PropagateItemJob *createJob(const SyncFileItemPtr &item); + void scheduleNextJob(); void reportProgress(const SyncFileItem &, quint64 bytes); @@ -497,6 +511,7 @@ private slots: void scheduleNextJobImpl(); signals: + void newItem(const SyncFileItemPtr &); void itemCompleted(const SyncFileItemPtr &); void progress(const SyncFileItem &, quint64 bytes); void finished(bool success); diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index 2efc537ea..2f37ca304 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -525,7 +525,7 @@ void PropagateDownloadFile::slotGetFinished() { propagator()->_activeJobList.removeOne(this); - GETFileJob *job = qobject_cast(sender()); + GETFileJob *job = _job; ASSERT(job); QNetworkReply::NetworkError err = job->reply()->error(); @@ -639,6 +639,26 @@ void PropagateDownloadFile::slotGetFinished() return; } + // Did the file come with conflict headers? If so, store them now! + // If we download conflict files but the server doesn't send conflict + // headers, the record will be established by SyncEngine::conflictRecordMaintenance. + // (we can't reliably determine the file id of the base file here, + // it might still be downloaded in a parallel job and not exist in + // the database yet!) + if (job->reply()->rawHeader("OC-Conflict") == "1") { + _conflictRecord.path = _item->_file.toUtf8(); + _conflictRecord.baseFileId = job->reply()->rawHeader("OC-ConflictBaseFileId"); + _conflictRecord.baseEtag = _job->reply()->rawHeader("OC-ConflictBaseEtag"); + + auto mtimeHeader = _job->reply()->rawHeader("OC-ConflictBaseMtime"); + if (!mtimeHeader.isEmpty()) + _conflictRecord.baseModtime = mtimeHeader.toLongLong(); + + // We don't set it yet. That will only be done when the download finished + // successfully, much further down. Here we just grab the headers because the + // job will be deleted later. + } + // Do checksum validation for the download. If there is no checksum header, the validator // will also emit the validated() signal to continue the flow in slot transmissionChecksumValidated() // as this is (still) also correct. @@ -677,7 +697,7 @@ void PropagateDownloadFile::deleteExistingFolder() // on error, just try to move it away... } - QString conflictDir = FileSystem::makeConflictFileName( + QString conflictDir = Utility::makeConflictFileName( existingDir, Utility::qDateTimeFromTime_t(FileSystem::getModTime(existingDir))); emit propagator()->touchedFile(existingDir); @@ -805,9 +825,11 @@ void PropagateDownloadFile::downloadFinished() && !FileSystem::fileEquals(fn, _tmpFile.fileName()); if (isConflict) { QString renameError; - QString conflictFileName = FileSystem::makeConflictFileName( - fn, Utility::qDateTimeFromTime_t(FileSystem::getModTime(fn))); - if (!FileSystem::rename(fn, conflictFileName, &renameError)) { + auto conflictModTime = FileSystem::getModTime(fn); + QString conflictFileName = Utility::makeConflictFileName( + _item->_file, Utility::qDateTimeFromTime_t(conflictModTime)); + QString conflictFilePath = propagator()->getFilePath(conflictFileName); + if (!FileSystem::rename(fn, conflictFilePath, &renameError)) { // If the rename fails, don't replace it. // If the file is locked, we want to retry this sync when it @@ -820,6 +842,35 @@ void PropagateDownloadFile::downloadFinished() return; } qCInfo(lcPropagateDownload) << "Created conflict file" << fn << "->" << conflictFileName; + + // Create a new conflict record. To get the base etag, we need to read it from the db. + ConflictRecord conflictRecord; + conflictRecord.path = conflictFileName.toUtf8(); + conflictRecord.baseModtime = _item->_previousModtime; + + SyncJournalFileRecord baseRecord; + if (propagator()->_journal->getFileRecord(_item->_originalFile, &baseRecord) && baseRecord.isValid()) { + conflictRecord.baseEtag = baseRecord._etag; + conflictRecord.baseFileId = baseRecord._fileId; + } else { + // We might very well end up with no fileid/etag for new/new conflicts + } + + propagator()->_journal->setConflictRecord(conflictRecord); + + // Create a new upload job if the new conflict file should be uploaded + if (propagator()->account()->capabilities().uploadConflictFiles()) { + SyncFileItemPtr conflictItem = SyncFileItemPtr(new SyncFileItem); + conflictItem->_file = conflictFileName; + conflictItem->_type = SyncFileItem::File; + conflictItem->_direction = SyncFileItem::Up; + conflictItem->_instruction = CSYNC_INSTRUCTION_NEW; + conflictItem->_modtime = conflictModTime; + conflictItem->_size = _item->_previousSize; + ASSERT(_compositeParent); + emit propagator()->newItem(conflictItem); + _compositeParent->appendTask(conflictItem); + } } FileSystem::setModTime(_tmpFile.fileName(), _item->_modtime); @@ -886,6 +937,11 @@ void PropagateDownloadFile::downloadFinished() // Get up to date information for the journal. _item->_size = FileSystem::getSize(fn); + // Maybe what we downloaded was a conflict file? If so, set a conflict record. + // (the data was prepared in slotGetFinished above) + if (_conflictRecord.isValid()) + propagator()->_journal->setConflictRecord(_conflictRecord); + updateMetadata(isConflict); } diff --git a/src/libsync/propagatedownload.h b/src/libsync/propagatedownload.h index 4b8988b65..632cb0c79 100644 --- a/src/libsync/propagatedownload.h +++ b/src/libsync/propagatedownload.h @@ -202,6 +202,7 @@ private: QPointer _job; QFile _tmpFile; bool _deleteExisting; + ConflictRecord _conflictRecord; QElapsedTimer _stopwatch; }; diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp index 6de6316af..1b5bcc0c8 100644 --- a/src/libsync/propagateupload.cpp +++ b/src/libsync/propagateupload.cpp @@ -605,6 +605,19 @@ QMap PropagateUploadFileCommon::headers() // csync_owncloud.c's owncloud_file_id always strips the quotes. headers["If-Match"] = '"' + _item->_etag + '"'; } + + // Set up a conflict file header pointing to the original file + auto conflictRecord = propagator()->_journal->conflictRecord(_item->_file.toUtf8()); + if (conflictRecord.isValid()) { + headers["OC-Conflict"] = "1"; + if (!conflictRecord.baseFileId.isEmpty()) + headers["OC-ConflictBaseFileId"] = conflictRecord.baseFileId; + if (conflictRecord.baseModtime != -1) + headers["OC-ConflictBaseMtime"] = QByteArray::number(conflictRecord.baseModtime); + if (!conflictRecord.baseEtag.isEmpty()) + headers["OC-ConflictBaseEtag"] = conflictRecord.baseEtag; + } + return headers; } diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 5e387921c..31338f4f6 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -329,6 +329,45 @@ void SyncEngine::deleteStaleErrorBlacklistEntries(const SyncFileItemVector &sync _journal->deleteStaleErrorBlacklistEntries(blacklist_file_paths); } +void SyncEngine::conflictRecordMaintenance() +{ + // Remove stale conflict entries from the database + // by checking which files still exist and removing the + // missing ones. + auto conflictRecordPaths = _journal->conflictRecordPaths(); + for (const auto &path : conflictRecordPaths) { + auto fsPath = _propagator->getFilePath(QString::fromUtf8(path)); + if (!QFileInfo(fsPath).exists()) { + _journal->deleteConflictRecord(path); + } + } + + // Did the sync see any conflict files that don't yet have records? + // If so, add them now. + // + // This happens when the conflicts table is new or when conflict files + // are downlaoded but the server doesn't send conflict headers. + for (const auto &path : _seenFiles) { + if (!Utility::isConflictFile(path)) + continue; + + auto bapath = path.toUtf8(); + if (!conflictRecordPaths.contains(bapath)) { + ConflictRecord record; + record.path = bapath; + + // Determine fileid of target file + auto basePath = Utility::conflictFileBaseName(bapath); + SyncJournalFileRecord baseRecord; + if (_journal->getFileRecord(basePath, &baseRecord) && baseRecord.isValid()) { + record.baseFileId = baseRecord._fileId; + } + + _journal->setConflictRecord(record); + } + } +} + int SyncEngine::treewalkLocal(csync_file_stat_t *file, csync_file_stat_t *other, void *data) { return static_cast(data)->treewalkFile(file, other, false); @@ -483,7 +522,7 @@ int SyncEngine::treewalkFile(csync_file_stat_t *file, csync_file_stat_t *other, break; case CSYNC_STATUS_INDIVIDUAL_IS_CONFLICT_FILE: item->_status = SyncFileItem::Conflict; - if (Utility::shouldUploadConflictFiles()) { + if (account()->capabilities().uploadConflictFiles()) { // For uploaded conflict files, files with no action performed on them should // be displayed: but we mustn't overwrite the instruction if something happens // to the file! @@ -552,7 +591,7 @@ int SyncEngine::treewalkFile(csync_file_stat_t *file, csync_file_stat_t *other, _hasNoneFiles = true; } // Put none-instruction conflict files into the syncfileitem list - if (Utility::shouldUploadConflictFiles() + if (account()->capabilities().uploadConflictFiles() && file->error_status == CSYNC_STATUS_INDIVIDUAL_IS_CONFLICT_FILE && item->_instruction == CSYNC_INSTRUCTION_IGNORE) { break; @@ -668,8 +707,6 @@ int SyncEngine::treewalkFile(csync_file_stat_t *file, csync_file_stat_t *other, checkErrorBlacklisting(*item); } - _progressInfo->adjustTotalsForFile(*item); - _needsUpdate = true; if (other) { @@ -677,6 +714,7 @@ int SyncEngine::treewalkFile(csync_file_stat_t *file, csync_file_stat_t *other, item->_previousSize = other->size; } + slotNewItem(item); _syncItemMap.insert(key, item); return re; } @@ -805,6 +843,9 @@ void SyncEngine::startSync() // database creation error! } + _csync_ctx->upload_conflict_files = _account->capabilities().uploadConflictFiles(); + _excludedFiles->setExcludeConflictFiles(!_account->capabilities().uploadConflictFiles()); + _csync_ctx->read_remote_from_db = true; _lastLocalDiscoveryStyle = _csync_ctx->local_discovery_style; @@ -894,6 +935,11 @@ void SyncEngine::slotRootEtagReceived(const QString &e) } } +void SyncEngine::slotNewItem(const SyncFileItemPtr &item) +{ + _progressInfo->adjustTotalsForFile(*item); +} + void SyncEngine::slotDiscoveryJobFinished(int discoveryResult) { if (discoveryResult < 0) { @@ -1051,6 +1097,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult) connect(_propagator.data(), &OwncloudPropagator::touchedFile, this, &SyncEngine::slotAddTouchedFile); connect(_propagator.data(), &OwncloudPropagator::insufficientLocalStorage, this, &SyncEngine::slotInsufficientLocalStorage); connect(_propagator.data(), &OwncloudPropagator::insufficientRemoteStorage, this, &SyncEngine::slotInsufficientRemoteStorage); + connect(_propagator.data(), &OwncloudPropagator::newItem, this, &SyncEngine::slotNewItem); // apply the network limits to the propagator setNetworkLimits(_uploadLimit, _downloadLimit); @@ -1116,11 +1163,12 @@ void SyncEngine::slotFinished(bool success) _journal->setDataFingerprint(_discoveryMainThread->_dataFingerprint); } - // emit the treewalk results. if (!_journal->postSyncCleanup(_seenFiles, _temporarilyUnavailablePaths)) { qCDebug(lcEngine) << "Cleaning of synced "; } + conflictRecordMaintenance(); + _journal->commit("All Finished.", false); // Send final progress information even if no diff --git a/src/libsync/syncengine.h b/src/libsync/syncengine.h index 8be936e38..5ae335b42 100644 --- a/src/libsync/syncengine.h +++ b/src/libsync/syncengine.h @@ -161,6 +161,15 @@ signals: private slots: void slotFolderDiscovered(bool local, const QString &folder); void slotRootEtagReceived(const QString &); + + /** Called when a SyncFileItem gets accepted for a sync. + * + * Mostly done in initial creation inside treewalkFile but + * can also be called via the propagator for items that are + * created during propagation. + */ + void slotNewItem(const SyncFileItemPtr &item); + void slotItemCompleted(const SyncFileItemPtr &item); void slotFinished(bool success); void slotProgress(const SyncFileItem &item, quint64 curent); @@ -200,6 +209,9 @@ private: // Removes stale error blacklist entries from the journal. void deleteStaleErrorBlacklistEntries(const SyncFileItemVector &syncItems); + // Removes stale and adds missing conflict records after sync + void conflictRecordMaintenance(); + // cleanup and emit the finished signal void finalize(bool success); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b62a6ee01..b23678543 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -47,6 +47,7 @@ owncloud_add_test(FileSystem "") owncloud_add_test(Utility "") owncloud_add_test(SyncEngine "syncenginetestutils.h") owncloud_add_test(SyncMove "syncenginetestutils.h") +owncloud_add_test(SyncConflict "syncenginetestutils.h") owncloud_add_test(SyncFileStatusTracker "syncenginetestutils.h") owncloud_add_test(ChunkingNg "syncenginetestutils.h") owncloud_add_test(UploadReset "syncenginetestutils.h") diff --git a/test/testsyncconflict.cpp b/test/testsyncconflict.cpp new file mode 100644 index 000000000..0a15bb9e9 --- /dev/null +++ b/test/testsyncconflict.cpp @@ -0,0 +1,351 @@ +/* + * 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. + * + */ + +#include +#include "syncenginetestutils.h" +#include + +using namespace OCC; + +SyncFileItemPtr findItem(const QSignalSpy &spy, const QString &path) +{ + for (const QList &args : spy) { + auto item = args[0].value(); + if (item->destination() == path) + return item; + } + return SyncFileItemPtr(new SyncFileItem); +} + +bool itemSuccessful(const QSignalSpy &spy, const QString &path, const csync_instructions_e instr) +{ + auto item = findItem(spy, path); + return item->_status == SyncFileItem::Success && item->_instruction == instr; +} + +bool itemConflict(const QSignalSpy &spy, const QString &path) +{ + auto item = findItem(spy, path); + return item->_status == SyncFileItem::Conflict && item->_instruction == CSYNC_INSTRUCTION_CONFLICT; +} + +bool itemSuccessfulMove(const QSignalSpy &spy, const QString &path) +{ + return itemSuccessful(spy, path, CSYNC_INSTRUCTION_RENAME); +} + +QStringList findConflicts(const FileInfo &dir) +{ + QStringList conflicts; + for (const auto &item : dir.children) { + if (item.name.contains("conflict")) { + conflicts.append(item.path()); + } + } + return conflicts; +} + +bool expectAndWipeConflict(FileModifier &local, FileInfo state, const QString path) +{ + PathComponents pathComponents(path); + auto base = state.find(pathComponents.parentDirComponents()); + if (!base) + return false; + for (const auto &item : base->children) { + if (item.name.startsWith(pathComponents.fileName()) && item.name.contains("_conflict")) { + local.remove(item.path()); + return true; + } + } + return false; +} + +class TestSyncConflict : public QObject +{ + Q_OBJECT + +private slots: + void testNoUpload() + { + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + fakeFolder.localModifier().setContents("A/a1", 'L'); + fakeFolder.remoteModifier().setContents("A/a1", 'R'); + fakeFolder.localModifier().appendByte("A/a2"); + fakeFolder.remoteModifier().appendByte("A/a2"); + fakeFolder.remoteModifier().appendByte("A/a2"); + QVERIFY(fakeFolder.syncOnce()); + QVERIFY(expectAndWipeConflict(fakeFolder.localModifier(), fakeFolder.currentLocalState(), "A/a1")); + QVERIFY(expectAndWipeConflict(fakeFolder.localModifier(), fakeFolder.currentLocalState(), "A/a2")); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + } + + void testUploadAfterDownload() + { + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + fakeFolder.syncEngine().account()->setCapabilities({ { "uploadConflictFiles", true } }); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + QMap conflictMap; + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *) -> QNetworkReply * { + if (op == QNetworkAccessManager::PutOperation) { + auto baseFileId = request.rawHeader("OC-ConflictBaseFileId"); + if (!baseFileId.isEmpty()) { + auto components = request.url().toString().split('/'); + QString conflictFile = components.mid(components.size() - 2).join('/'); + conflictMap[baseFileId] = conflictFile; + } + } + return nullptr; + }); + + fakeFolder.localModifier().setContents("A/a1", 'L'); + fakeFolder.remoteModifier().setContents("A/a1", 'R'); + fakeFolder.localModifier().appendByte("A/a2"); + fakeFolder.remoteModifier().appendByte("A/a2"); + fakeFolder.remoteModifier().appendByte("A/a2"); + QVERIFY(fakeFolder.syncOnce()); + auto local = fakeFolder.currentLocalState(); + auto remote = fakeFolder.currentRemoteState(); + QCOMPARE(local, remote); + + auto a1FileId = fakeFolder.remoteModifier().find("A/a1")->fileId; + auto a2FileId = fakeFolder.remoteModifier().find("A/a2")->fileId; + QVERIFY(conflictMap.contains(a1FileId)); + QVERIFY(conflictMap.contains(a2FileId)); + QCOMPARE(conflictMap.size(), 2); + QCOMPARE(Utility::conflictFileBaseName(conflictMap[a1FileId].toUtf8()), QByteArray("A/a1")); + + QCOMPARE(remote.find(conflictMap[a1FileId])->contentChar, 'L'); + QCOMPARE(remote.find("A/a1")->contentChar, 'R'); + + QCOMPARE(remote.find(conflictMap[a2FileId])->size, 5); + QCOMPARE(remote.find("A/a2")->size, 6); + } + + void testSeparateUpload() + { + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + fakeFolder.syncEngine().account()->setCapabilities({ { "uploadConflictFiles", true } }); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + QMap conflictMap; + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *) -> QNetworkReply * { + if (op == QNetworkAccessManager::PutOperation) { + auto baseFileId = request.rawHeader("OC-ConflictBaseFileId"); + if (!baseFileId.isEmpty()) { + auto components = request.url().toString().split('/'); + QString conflictFile = components.mid(components.size() - 2).join('/'); + conflictMap[baseFileId] = conflictFile; + } + } + return nullptr; + }); + + // Explicitly add a conflict file to simulate the case where the upload of the + // file didn't finish in the same sync run that the conflict was created. + // To do that we need to create a mock conflict record. + auto a1FileId = fakeFolder.remoteModifier().find("A/a1")->fileId; + QString conflictName = QLatin1String("A/a1_conflict-me-1234"); + fakeFolder.localModifier().insert(conflictName, 64, 'L'); + ConflictRecord conflictRecord; + conflictRecord.path = conflictName.toUtf8(); + conflictRecord.baseFileId = a1FileId; + fakeFolder.syncJournal().setConflictRecord(conflictRecord); + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + QCOMPARE(conflictMap.size(), 1); + QCOMPARE(conflictMap[a1FileId], conflictName); + QCOMPARE(fakeFolder.currentRemoteState().find(conflictMap[a1FileId])->contentChar, 'L'); + conflictMap.clear(); + + // Now the user can locally alter the conflict file and it will be uploaded + // as usual. + fakeFolder.localModifier().setContents(conflictName, 'P'); + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(conflictMap.size(), 1); + QCOMPARE(conflictMap[a1FileId], conflictName); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + conflictMap.clear(); + + // Similarly, remote modifications of conflict files get propagated downwards + fakeFolder.remoteModifier().setContents(conflictName, 'Q'); + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + QVERIFY(conflictMap.isEmpty()); + + // Conflict files for conflict files! + auto a1ConflictFileId = fakeFolder.remoteModifier().find(conflictName)->fileId; + fakeFolder.remoteModifier().appendByte(conflictName); + fakeFolder.remoteModifier().appendByte(conflictName); + fakeFolder.localModifier().appendByte(conflictName); + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + QCOMPARE(conflictMap.size(), 1); + QVERIFY(conflictMap.contains(a1ConflictFileId)); + QCOMPARE(fakeFolder.currentRemoteState().find(conflictName)->size, 66); + QCOMPARE(fakeFolder.currentRemoteState().find(conflictMap[a1ConflictFileId])->size, 65); + conflictMap.clear(); + } + + // What happens if we download a conflict file? Is the metadata set up correctly? + void testDownloadingConflictFile() + { + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + fakeFolder.syncEngine().account()->setCapabilities({ { "uploadConflictFiles", true } }); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + // With no headers from the server + fakeFolder.remoteModifier().insert("A/a1_conflict-1234"); + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + auto conflictRecord = fakeFolder.syncJournal().conflictRecord("A/a1_conflict-1234"); + QVERIFY(conflictRecord.isValid()); + QCOMPARE(conflictRecord.baseFileId, fakeFolder.remoteModifier().find("A/a1")->fileId); + + // Now with server headers + QObject parent; + auto a2FileId = fakeFolder.remoteModifier().find("A/a2")->fileId; + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *) -> QNetworkReply * { + if (op == QNetworkAccessManager::GetOperation) { + auto reply = new FakeGetReply(fakeFolder.remoteModifier(), op, request, &parent); + reply->setRawHeader("OC-Conflict", "1"); + reply->setRawHeader("OC-ConflictBaseFileId", a2FileId); + reply->setRawHeader("OC-ConflictBaseMtime", "1234"); + reply->setRawHeader("OC-ConflictBaseEtag", "etag"); + return reply; + } + return nullptr; + }); + fakeFolder.remoteModifier().insert("A/really-a-conflict"); // doesn't look like a conflict, but headers say it is + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + conflictRecord = fakeFolder.syncJournal().conflictRecord("A/really-a-conflict"); + QVERIFY(conflictRecord.isValid()); + QCOMPARE(conflictRecord.baseFileId, a2FileId); + QCOMPARE(conflictRecord.baseModtime, 1234); + QCOMPARE(conflictRecord.baseEtag, QByteArray("etag")); + } + + // Check that conflict records are removed when the file is gone + void testConflictRecordRemoval1() + { + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + fakeFolder.syncEngine().account()->setCapabilities({ { "uploadConflictFiles", true } }); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + // Make conflict records + ConflictRecord conflictRecord; + conflictRecord.path = "A/a1"; + fakeFolder.syncJournal().setConflictRecord(conflictRecord); + conflictRecord.path = "A/a2"; + fakeFolder.syncJournal().setConflictRecord(conflictRecord); + + // A nothing-to-sync keeps them alive + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + QVERIFY(fakeFolder.syncJournal().conflictRecord("A/a1").isValid()); + QVERIFY(fakeFolder.syncJournal().conflictRecord("A/a2").isValid()); + + // When the file is removed, the record is removed too + fakeFolder.localModifier().remove("A/a2"); + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + QVERIFY(fakeFolder.syncJournal().conflictRecord("A/a1").isValid()); + QVERIFY(!fakeFolder.syncJournal().conflictRecord("A/a2").isValid()); + } + + // Same test, but with uploadConflictFiles == false + void testConflictRecordRemoval2() + { + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + fakeFolder.syncEngine().account()->setCapabilities({ { "uploadConflictFiles", false } }); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + // Create two conflicts + fakeFolder.localModifier().appendByte("A/a1"); + fakeFolder.localModifier().appendByte("A/a1"); + fakeFolder.remoteModifier().appendByte("A/a1"); + fakeFolder.localModifier().appendByte("A/a2"); + fakeFolder.localModifier().appendByte("A/a2"); + fakeFolder.remoteModifier().appendByte("A/a2"); + QVERIFY(fakeFolder.syncOnce()); + + auto conflicts = findConflicts(fakeFolder.currentLocalState().children["A"]); + QByteArray a1conflict; + QByteArray a2conflict; + for (const auto & conflict : conflicts) { + if (conflict.contains("a1")) + a1conflict = conflict.toUtf8(); + if (conflict.contains("a2")) + a2conflict = conflict.toUtf8(); + } + + // A nothing-to-sync keeps them alive + QVERIFY(fakeFolder.syncOnce()); + QVERIFY(fakeFolder.syncJournal().conflictRecord(a1conflict).isValid()); + QVERIFY(fakeFolder.syncJournal().conflictRecord(a2conflict).isValid()); + + // When the file is removed, the record is removed too + fakeFolder.localModifier().remove(a2conflict); + QVERIFY(fakeFolder.syncOnce()); + QVERIFY(fakeFolder.syncJournal().conflictRecord(a1conflict).isValid()); + QVERIFY(!fakeFolder.syncJournal().conflictRecord(a2conflict).isValid()); + } + + void testConflictFileBaseName_data() + { + QTest::addColumn("input"); + QTest::addColumn("output"); + + QTest::newRow("") + << "a/b/foo" + << ""; + QTest::newRow("") + << "a/b/foo.txt" + << ""; + QTest::newRow("") + << "a/b/foo_conflict" + << ""; + QTest::newRow("") + << "a/b/foo_conflict.txt" + << ""; + + QTest::newRow("") + << "a/b/foo_conflict-123.txt" + << "a/b/foo.txt"; + QTest::newRow("") + << "a/b/foo_conflict-foo-123.txt" + << "a/b/foo.txt"; + + QTest::newRow("") + << "a/b/foo_conflict-123" + << "a/b/foo"; + QTest::newRow("") + << "a/b/foo_conflict-foo-123" + << "a/b/foo"; + + // double conflict files + QTest::newRow("") + << "a/b/foo_conflict-123_conflict-456.txt" + << "a/b/foo_conflict-123.txt"; + QTest::newRow("") + << "a/b/foo_conflict-foo-123_conflict-bar-456.txt" + << "a/b/foo_conflict-foo-123.txt"; + } + + void testConflictFileBaseName() + { + QFETCH(QString, input); + QFETCH(QString, output); + QCOMPARE(Utility::conflictFileBaseName(input.toUtf8()), output.toUtf8()); + } +}; + +QTEST_GUILESS_MAIN(TestSyncConflict) +#include "testsyncconflict.moc" diff --git a/test/testsyncjournaldb.cpp b/test/testsyncjournaldb.cpp index 389dcec5d..389330ffa 100644 --- a/test/testsyncjournaldb.cpp +++ b/test/testsyncjournaldb.cpp @@ -183,6 +183,28 @@ private slots: QCOMPARE(record.numericFileId(), QByteArray("123456789")); } + void testConflictRecord() + { + ConflictRecord record; + record.path = "abc"; + record.baseFileId = "def"; + record.baseModtime = 1234; + record.baseEtag = "ghi"; + + QVERIFY(!_db.conflictRecord(record.path).isValid()); + + _db.setConflictRecord(record); + auto newRecord = _db.conflictRecord(record.path); + QVERIFY(newRecord.isValid()); + QCOMPARE(newRecord.path, record.path); + QCOMPARE(newRecord.baseFileId, record.baseFileId); + QCOMPARE(newRecord.baseModtime, record.baseModtime); + QCOMPARE(newRecord.baseEtag, record.baseEtag); + + _db.deleteConflictRecord(record.path); + QVERIFY(!_db.conflictRecord(record.path).isValid()); + } + private: SyncJournalDb _db; }; From 83e94c3ec72b0f9c097f825d58875a5df282874a Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 15 Dec 2017 18:05:44 +0100 Subject: [PATCH 017/138] Fix compile after rebase --- src/libsync/propagatedownload.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index 2f37ca304..2b7bd7640 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -862,7 +862,7 @@ void PropagateDownloadFile::downloadFinished() if (propagator()->account()->capabilities().uploadConflictFiles()) { SyncFileItemPtr conflictItem = SyncFileItemPtr(new SyncFileItem); conflictItem->_file = conflictFileName; - conflictItem->_type = SyncFileItem::File; + conflictItem->_type = ItemTypeFile; conflictItem->_direction = SyncFileItem::Up; conflictItem->_instruction = CSYNC_INSTRUCTION_NEW; conflictItem->_modtime = conflictModTime; From 1940c2f9bfb8458fb7f5f822bf40561a082b3b3a Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 15 Dec 2017 13:00:50 +0100 Subject: [PATCH 018/138] Exclude: Use Qt to load the exclude file fopen does not work well with relative path tand forward slashes on windows This fix the windows textexcludedfiles test. And also make the code simpler. Note that the 'trimmed' might be a behavior change, but i think it is ok --- src/csync/csync_exclude.cpp | 143 ++++-------------- .../csync/csync_tests/check_csync_exclude.cpp | 20 ++- test/testexcludedfiles.cpp | 2 +- 3 files changed, 43 insertions(+), 122 deletions(-) diff --git a/src/csync/csync_exclude.cpp b/src/csync/csync_exclude.cpp index f113a354e..be3d80ae8 100644 --- a/src/csync/csync_exclude.cpp +++ b/src/csync/csync_exclude.cpp @@ -23,11 +23,6 @@ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif -#include - -#include -#include -#include #include "c_lib.h" #include "c_private.h" @@ -42,125 +37,43 @@ #include #include -#ifdef _WIN32 -#include -#else -#include -#endif -#define CSYNC_LOG_CATEGORY_NAME "csync.exclude" -#include "csync_log.h" - -/** Expands C-like escape sequences. - * - * The returned string is heap-allocated and owned by the caller. +/** Expands C-like escape sequences (in place) */ -static const char *csync_exclude_expand_escapes(const char * input) +static void csync_exclude_expand_escapes(QByteArray &input) { - size_t i_len = strlen(input) + 1; - char *out = (char*)c_malloc(i_len); // out can only be shorter - - size_t i = 0; size_t o = 0; - for (; i < i_len; ++i) { - if (input[i] == '\\') { + char *line = input.data(); + auto len = input.size(); + for (int i = 0; i < len; ++i) { + if (line[i] == '\\') { // at worst input[i+1] is \0 - switch (input[i+1]) { - case '\'': out[o++] = '\''; break; - case '"': out[o++] = '"'; break; - case '?': out[o++] = '?'; break; - case '#': out[o++] = '#'; break; - case 'a': out[o++] = '\a'; break; - case 'b': out[o++] = '\b'; break; - case 'f': out[o++] = '\f'; break; - case 'n': out[o++] = '\n'; break; - case 'r': out[o++] = '\r'; break; - case 't': out[o++] = '\t'; break; - case 'v': out[o++] = '\v'; break; + switch (line[i+1]) { + case '\'': line[o++] = '\''; break; + case '"': line[o++] = '"'; break; + case '?': line[o++] = '?'; break; + case '#': line[o++] = '#'; break; + case 'a': line[o++] = '\a'; break; + case 'b': line[o++] = '\b'; break; + case 'f': line[o++] = '\f'; break; + case 'n': line[o++] = '\n'; break; + case 'r': line[o++] = '\r'; break; + case 't': line[o++] = '\t'; break; + case 'v': line[o++] = '\v'; break; default: // '\*' '\?' '\[' '\\' will be processed during regex translation // '\\' is intentionally not expanded here (to avoid '\\*' and '\*' // ending up meaning the same thing) - out[o++] = input[i]; - out[o++] = input[i+1]; + line[o++] = line[i]; + line[o++] = line[i + 1]; break; } ++i; } else { - out[o++] = input[i]; + line[o++] = line[i]; } } - return out; -} - -/** Loads patterns from a file and adds them to excludes */ -int csync_exclude_load(const char *fname, QList *excludes) { - int fd = -1; - int i = 0; - int rc = -1; - int64_t size; - char *buf = NULL; - char *entry = NULL; - mbchar_t *w_fname; - - if (fname == NULL) { - return -1; - } - -#ifdef _WIN32 - _fmode = _O_BINARY; -#endif - - w_fname = c_utf8_path_to_locale(fname); - if (w_fname == NULL) { - return -1; - } - - fd = _topen(w_fname, O_RDONLY); - c_free_locale_string(w_fname); - if (fd < 0) { - return -1; - } - - size = lseek(fd, 0, SEEK_END); - if (size < 0) { - rc = -1; - goto out; - } - lseek(fd, 0, SEEK_SET); - if (size == 0) { - rc = 0; - goto out; - } - buf = (char*)c_malloc(size + 1); - if (read(fd, buf, size) != size) { - rc = -1; - goto out; - } - buf[size] = '\0'; - - /* FIXME: Use fgets and don't add duplicates */ - entry = buf; - for (i = 0; i < size; i++) { - if (buf[i] == '\n' || buf[i] == '\r') { - if (entry != buf + i) { - buf[i] = '\0'; - if (*entry != '#') { - const char *unescaped = csync_exclude_expand_escapes(entry); - excludes->append(unescaped); - CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", unescaped); - SAFE_FREE(unescaped); - } - } - entry = buf + i + 1; - } - } - - rc = 0; -out: - SAFE_FREE(buf); - close(fd); - return rc; + input.resize(o); } // See http://support.microsoft.com/kb/74496 and @@ -362,8 +275,18 @@ bool ExcludedFiles::reloadExcludeFiles() _allExcludes.clear(); bool success = true; foreach (const QString &file, _excludeFiles) { - if (csync_exclude_load(file.toUtf8(), &_allExcludes) < 0) + QFile f(file); + if (!f.open(QIODevice::ReadOnly)) { success = false; + continue; + } + while (!f.atEnd()) { + QByteArray line = f.readLine().trimmed(); + if (line.isEmpty() || line.startsWith('#')) + continue; + csync_exclude_expand_escapes(line); + _allExcludes.append(line); + } } _allExcludes.append(_manualExcludes); prepare(); diff --git a/test/csync/csync_tests/check_csync_exclude.cpp b/test/csync/csync_tests/check_csync_exclude.cpp index 7c64ce5de..0062c2a39 100644 --- a/test/csync/csync_tests/check_csync_exclude.cpp +++ b/test/csync/csync_tests/check_csync_exclude.cpp @@ -512,19 +512,17 @@ static void check_csync_exclude_expand_escapes(void **state) { (void)state; - const char *str = csync_exclude_expand_escapes( - "keep \\' \\\" \\? \\\\ \\a \\b \\f \\n \\r \\t \\v \\z \\#"); - assert_true(0 == strcmp( - str, "keep ' \" ? \\\\ \a \b \f \n \r \t \v \\z #")); - SAFE_FREE(str); + QByteArray line = "keep \\' \\\" \\? \\\\ \\a \\b \\f \\n \\r \\t \\v \\z \\#"; + csync_exclude_expand_escapes(line); + assert_true(0 == strcmp(line.constData(), "keep ' \" ? \\\\ \a \b \f \n \r \t \v \\z #")); - str = csync_exclude_expand_escapes(""); - assert_true(0 == strcmp(str, "")); - SAFE_FREE(str); + line = ""; + csync_exclude_expand_escapes(line); + assert_true(0 == strcmp(line.constData(), "")); - str = csync_exclude_expand_escapes("\\"); - assert_true(0 == strcmp(str, "\\")); - SAFE_FREE(str); + line = "\\"; + csync_exclude_expand_escapes(line); + assert_true(0 == strcmp(line.constData(), "\\")); } }; // class ExcludedFilesTest diff --git a/test/testexcludedfiles.cpp b/test/testexcludedfiles.cpp index b743ffd81..5043768ec 100644 --- a/test/testexcludedfiles.cpp +++ b/test/testexcludedfiles.cpp @@ -11,7 +11,7 @@ using namespace OCC; -#define EXCLUDE_LIST_FILE SOURCEDIR"/../../sync-exclude.lst" +#define EXCLUDE_LIST_FILE SOURCEDIR "/../../sync-exclude.lst" class TestExcludedFiles: public QObject { From 46e796303e31bf1da66bb5cfcaa51798f81d8e90 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Sat, 16 Dec 2017 02:18:35 +0100 Subject: [PATCH 019/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_zh_CN.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index 597ac8a90..353a29e34 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -83,6 +83,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_zh_CN.ts b/translations/client_zh_CN.ts index b1dcf38da..764c31d8e 100644 --- a/translations/client_zh_CN.ts +++ b/translations/client_zh_CN.ts @@ -1770,7 +1770,7 @@ for additional privileges during the process. No updates available. Your installation is at the latest version. - 亲,你使用的已经是最新的版本了 + 没有可用更新。您的安装已为最新版本。 From 69e81e8f65d3fbd9a09f1bcea87bdb0937738235 Mon Sep 17 00:00:00 2001 From: Hefee Date: Sat, 16 Dec 2017 14:03:59 +0100 Subject: [PATCH 020/138] Also disable fstack-protector for alpha plattform. This fixes #6211. --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 70c66acc4..894f93e4c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,7 +9,7 @@ if(NOT TOKEN_AUTH_ONLY) endif() if(NOT WIN32) - if(NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "^(parisc|hppa)")) + if(NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "^(alpha|parisc|hppa)")) if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector --param=ssp-buffer-size=4") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector --param=ssp-buffer-size=4") From 844e03d000232c716eeb907236d27bfb867857a9 Mon Sep 17 00:00:00 2001 From: Hefee Date: Sat, 16 Dec 2017 14:03:59 +0100 Subject: [PATCH 021/138] Also disable fstack-protector for alpha plattform. This fixes #6211. (cherry picked from commit 69e81e8f65d3fbd9a09f1bcea87bdb0937738235) --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 172422988..aba13a9f4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,7 +9,7 @@ if(NOT TOKEN_AUTH_ONLY) endif() if(NOT MSVC) - if(NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "^(parisc|hppa)")) + if(NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "^(alpha|parisc|hppa)")) if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector --param=ssp-buffer-size=4") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector --param=ssp-buffer-size=4") From ab37856a91ed26c7e21e0be71b9471b9f97c2fc1 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Sun, 17 Dec 2017 02:18:35 +0100 Subject: [PATCH 022/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 353a29e34..97ba91e87 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -86,6 +86,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From 8fb191afcf46965d2942fa8ada6d348f34ed40a2 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Mon, 18 Dec 2017 02:18:34 +0100 Subject: [PATCH 023/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_nl.ts | 26 +++++++++++++------------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index 97ba91e87..1ee8f2cfb 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -89,6 +89,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_nl.ts b/translations/client_nl.ts index 9488dacdd..94ae28719 100644 --- a/translations/client_nl.ts +++ b/translations/client_nl.ts @@ -88,7 +88,7 @@ Server replied "%1 %2" to "%3 %4" - + Server antwoordde "%1 %2" naar "%3 %4" @@ -258,7 +258,7 @@ Connecting to %1... - + Verbinden met %1... @@ -373,7 +373,7 @@ Maintenance mode - + Onderhoudsmodus @@ -1413,7 +1413,7 @@ Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een ma <no filter> - + <no filter> @@ -1424,7 +1424,7 @@ Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een ma Show warnings - + Tonen waarschuwingen @@ -1454,7 +1454,7 @@ Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een ma Issue - + Probleem @@ -1714,7 +1714,7 @@ Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een ma <h1>Login Error</h1><p>%1</p> - + <h1>Inlog fout<p>%1</p> @@ -2710,7 +2710,7 @@ We adviseren deze site niet te gebruiken. %1 link - + %1 link @@ -2731,7 +2731,7 @@ We adviseren deze site niet te gebruiken. Open link in browser - + Openen link in browser @@ -2814,7 +2814,7 @@ We adviseren deze site niet te gebruiken. Open link in browser - + Openen link in browser @@ -2834,7 +2834,7 @@ We adviseren deze site niet te gebruiken. I shared something with you - + Ik deelde iets met u @@ -2927,12 +2927,12 @@ We adviseren deze site niet te gebruiken. I shared something with you - + Ik deelde iets met u Share... - + Delen... From 3fbd156c835f4badce6dc64d75a72045242a025c Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Tue, 19 Dec 2017 02:18:35 +0100 Subject: [PATCH 024/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 1ee8f2cfb..cfa06d33b 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -92,6 +92,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From 79065ba5c631b0f722c1843cf740beaf10393066 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Wed, 20 Dec 2017 02:18:53 +0100 Subject: [PATCH 025/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index cfa06d33b..1d9f259e7 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -95,6 +95,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From 067508c0829744b8b4d995d842ca0d7e1eac8e42 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 20 Dec 2017 16:03:35 +0100 Subject: [PATCH 026/138] VERSION.cmake: This branch is now 2.4.1 --- VERSION.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.cmake b/VERSION.cmake index 043aacc84..f02e76249 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -1,6 +1,6 @@ set( MIRALL_VERSION_MAJOR 2 ) set( MIRALL_VERSION_MINOR 4 ) -set( MIRALL_VERSION_PATCH 0 ) +set( MIRALL_VERSION_PATCH 1 ) set( MIRALL_VERSION_YEAR 2017 ) set( MIRALL_SOVERSION 0 ) From 8c7ea616235a67f88947a8727b167bfc35503f9b Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Thu, 21 Dec 2017 02:18:35 +0100 Subject: [PATCH 027/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 1d9f259e7..985a02945 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -98,6 +98,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From 6af823b36ac1ecb8bd6da3daf47fb9435097d627 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Fri, 22 Dec 2017 02:18:56 +0100 Subject: [PATCH 028/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 985a02945..72c70d2f3 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -101,6 +101,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From 6ee48c8f1506da912dfa478336e7de97e88fd2ce Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Sat, 23 Dec 2017 02:18:34 +0100 Subject: [PATCH 029/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 72c70d2f3..701f99ef8 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -104,6 +104,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From d59c609a73308fb0fa5408a2e05cbecb3c0d1451 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Sun, 24 Dec 2017 02:18:35 +0100 Subject: [PATCH 030/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 701f99ef8..e308584e9 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -107,6 +107,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From 6c9026e330cfc994e24412ffcbe7c54ea4671374 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Mon, 25 Dec 2017 02:18:36 +0100 Subject: [PATCH 031/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_nl.ts | 14 +++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index e308584e9..4696b7f08 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -110,6 +110,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_nl.ts b/translations/client_nl.ts index 94ae28719..f34aa1dc0 100644 --- a/translations/client_nl.ts +++ b/translations/client_nl.ts @@ -1402,7 +1402,7 @@ Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een ma List of issues - + Lijst met problemen @@ -1429,7 +1429,7 @@ Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een ma Show ignored files - + Tonen genegeerde bestanden @@ -1694,7 +1694,7 @@ Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een ma Error returned from the server: <em>%1</em> - + Fout gemeld door de server: <em>%1</em> @@ -2674,7 +2674,7 @@ We adviseren deze site niet te gebruiken. Link properties: - + Link eigenschappen: @@ -2736,7 +2736,7 @@ We adviseren deze site niet te gebruiken. Copy link to clipboard - + Kopiëren link naar klembord @@ -2819,7 +2819,7 @@ We adviseren deze site niet te gebruiken. Copy link to clipboard - + Kopiëren link naar klembord @@ -2937,7 +2937,7 @@ We adviseren deze site niet te gebruiken. Copy private link to clipboard - + Kopiëren privé-link naar klembord From 47a70001215ec4821f0073f69ba49027b3076025 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Tue, 26 Dec 2017 02:18:36 +0100 Subject: [PATCH 032/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 4696b7f08..012ffaa51 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -113,6 +113,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From 93c9f4316bfa7b2db40038ed8c3839c0494e61e3 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Wed, 27 Dec 2017 02:18:35 +0100 Subject: [PATCH 033/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 012ffaa51..f03cc3042 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -116,6 +116,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From 6e445033c7dba3642bc190f6f26da48b7462beb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Weigert?= Date: Wed, 27 Dec 2017 12:37:02 +0100 Subject: [PATCH 034/138] OBS publishing details added OBS has two pubishing swithces: one per package and one per project, we always only switch per project! we have too many dependency packages to keep that in sync manually! --- .github/release_template.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/release_template.md b/.github/release_template.md index 9ea1221e5..e3bd20ac0 100644 --- a/.github/release_template.md +++ b/.github/release_template.md @@ -78,11 +78,11 @@ On Release Day (for final release): * [ ] Win: Perform smoke test (Install, make sure it does not explode, and check if all version indicators are correct) * [ ] Linux: Smoke test of one distro package (Install, make sure it does not explode, and check if all version indicators are correct) * [ ] Linux: Run @SamuAlfageme 's magic Linux-test-all-packages-script -* [ ] Linux: Re-enable OBS publishing (or copy from testing to real release?) - * Let obs build and publish exactly once. then - * [ ] disable publishing and rebuild for the owncloud-client package and all its dependencies. - * [ ] double-check that there are no _aggregatepac from other projects, if so disable rebuilding there too. -* [ ] Create a signed tag using ```git tag -u E94E7B37 tagname``` (https://github.com/owncloud/enterprise/wiki/Desktop-Signing-Knowledge) +* [ ] Linux: Re-enable OBS publishing on the project (check for accidentially disabled packages too) +* Let obs build and publish exactly once. then + * [ ] disable publishing (on the obs project!) and rebuild the owncloud-client package and all its dependencies. + * [ ] double-check that there are no _aggregatepac from other projects + * [ ] Create a signed tag using ```git tag -u E94E7B37 tagname``` (https://github.com/owncloud/enterprise/wiki/Desktop-Signing-Knowledge) * [ ] Copy builds from ```testing``` to ```stable``` on download.owncloud.com, double check the download links. (make sure the .asc is there too) * [ ] Create a pull request to the owncloud.org repository to update the install page (strings.php, page-desktop.php). From now on download packages from the staging webserver. * [ ] Announce on https://central.owncloud.org From e3e38f3eac35bd3e541012aca1521c994a589104 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Thu, 28 Dec 2017 02:18:36 +0100 Subject: [PATCH 035/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index f03cc3042..081f526bf 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -119,6 +119,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From b80ba971544e18687385b692d31279b0f311a97c Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Fri, 29 Dec 2017 02:18:34 +0100 Subject: [PATCH 036/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 081f526bf..d2bdf1d10 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -122,6 +122,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From 504e11b5bb824c2a5a4472c135c0d9fd3b475785 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Sat, 30 Dec 2017 02:18:36 +0100 Subject: [PATCH 037/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index d2bdf1d10..6a952ed1c 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -125,6 +125,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From 3bac06d6e58e90278e462981a7bdb0a38eba24b7 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Sun, 31 Dec 2017 02:18:36 +0100 Subject: [PATCH 038/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 + translations/client_fa.ts | 437 +++++++++++++++++++------------------- 2 files changed, 227 insertions(+), 213 deletions(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index 6a952ed1c..8f77b12d5 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -128,6 +128,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_fa.ts b/translations/client_fa.ts index c240d8875..433442066 100644 --- a/translations/client_fa.ts +++ b/translations/client_fa.ts @@ -78,17 +78,17 @@ Connection timed out - + زمان ارتباط تمام شد Unknown error: network reply was deleted - + خطای ناشناخته: پاسخ شبکه پاک شد Server replied "%1 %2" to "%3 %4" - + سرور "1% 2%" به "3% 4%" پاسخ داد @@ -101,7 +101,7 @@ ... - + ... @@ -111,7 +111,7 @@ Unchecked folders will be <b>removed</b> from your local file system and will not be synchronized to this computer anymore - + پوشه های بررسی نشده از سیستم فایل محلی شما <b>حذف</b> خواهد شد و دیگر در این کامپیوتر همگام سازی نخواهد شد. @@ -121,7 +121,7 @@ Synchronize none - + همگام سازی هیچ @@ -153,7 +153,7 @@ Add new - + اضافه کردن جدید @@ -178,32 +178,32 @@ Restart sync - + راه اندازی مجدد همگام سازی Remove folder sync connection - + حذف اتصال همگام سازی پوشه Folder creation failed - + ساخت پوشه ناموفق <p>Could not create local folder <i>%1</i>. - + <p>ناتوانی در ساخت پوشه محلی <i>1%</i> Confirm Folder Sync Connection Removal - + تأیید حذف اتصال همگام سازی پوشه Remove Folder Sync Connection - + حذف اتصال همگام سازی پوشه @@ -218,17 +218,17 @@ %1 in use - + 1% در استفاده %1 as <i>%2</i> - + 1% به عنوان <i>2%</i> The server version %1 is old and unsupported! Proceed at your own risk. - + نسخه سرور 1% قدیمی است و پشتیبانی نشده است! مسئولیت با خود شماست. @@ -243,17 +243,17 @@ Server %1 is currently in maintenance mode. - + سرور 1% اکنون در حالت تعمیر است. Signed out from %1. - + از 1% خارج شد. Obtaining authorization from the browser. <a href='%1'>Click here</a> to re-open the browser. - + دریافت مجوز از مرورگر. <a href='%1'>اینجا کلیک کنید</a> تا مرورگر دوباره باز شود. @@ -263,7 +263,7 @@ No connection to %1 at %2. - + اتصال به 1% در 2% وجود ندارد. @@ -273,17 +273,17 @@ There are folders that were not synchronized because they are too big: - + پوشه‌هایی وجود دارند که همگام سازی نشده اند زیرا آن ها بسیار بزرگ هستند: There are folders that were not synchronized because they are external storages: - + پوشه‌هایی وجود دارند که همگام سازی نشده اند زیرا آن ها مخازن خارجی هستند: There are folders that were not synchronized because they are too big or external storages: - + پوشه‌هایی وجود دارند که همگام سازی نشده اند زیرا آن ها بسیار بزرگ یا مخازن خارجی هستند: @@ -293,7 +293,7 @@ <p>Do you really want to remove the connection to the account <i>%1</i>?</p><p><b>Note:</b> This will <b>not</b> delete any files.</p> - + <p>آیا شما واقعا می خواهید اتصال به حساب <i>1%</i>را حذف کنید؟</p> <p><b>توجه:</b> این هیچ فایلی را حذف نخواهد کرد.</p> @@ -325,22 +325,22 @@ <p>Do you really want to stop syncing the folder <i>%1</i>?</p><p><b>Note:</b> This will <b>not</b> delete any files.</p> - + <p>آیا شما واقعا می خواهید همگام سازی پوشه <i>1%</i> را متوقف نمایید؟</p><p><b>توجه:</b>این هیچ فایلی را حذف <b>نخواهد</b> کرد. </p> %1 (%3%) of %2 in use. Some folders, including network mounted or shared folders, might have different limits. - + 1% (%3%) از 2% در استفاده. برخی پوشه‌ها، شامل شبکه نصب شده یا پوشه های مشترک، ممکن است محدودیت های متفاوت داشته باشند. %1 of %2 in use - + 1% از 2% در استفاده Currently there is no storage usage information available. - + در حال حاضر هیچ اطلاعات کاربرد ذخیره سازی در دسترس نیست. @@ -358,7 +358,7 @@ Disconnected - + قطع شده @@ -373,7 +373,7 @@ Maintenance mode - + حالت تعمیر @@ -383,17 +383,17 @@ Configuration error - + خطای پیکربندی Asking Credentials - + درخواست مجوزها Unknown account state - + وضعیت حساب ناشناخته @@ -401,12 +401,12 @@ %1 on %2 - + 1% روی 2% %1 on %2 (disconnected) - + 1% روی 2% (قطع شده) @@ -425,28 +425,28 @@ Not Synced - + همگام سازی نشده Not Synced (%1) %1 is the number of not synced files. - + همگام سازی نشده (1%) The server activity list has been copied to the clipboard. - + لیست فعالیت سرور در کلیپ بورد کپی شده است. The sync activity list has been copied to the clipboard. - + لیست فعالیت همگام سازی در کلیپ بورد کپی شده است. The list of unsynced items has been copied to the clipboard. - + لیست موارد همگام سازی نشده در کلیپ بورد کپی شده است. @@ -481,37 +481,37 @@ Copy the activity list to the clipboard. - + لیست فعالیت را در کلیپ بورد کپی کنید. Action Required: Notifications - + عمل لازم: اطلاعیه ها <br/>Account %1 does not have activities enabled. - + <br/>فعالیت های حساب 1% فعال نیست. You received %n new notification(s) from %2. - + شما n% هشدار جدید از 2% دریافت کردید. You received %n new notification(s) from %1 and %2. - + شما n% هشدار جدید از 1% و 2% دریافت کردید. You received new notifications from %1, %2 and other accounts. - + شما هشدارهای جدیدی از 1%، 2% و سایر حساب ها دریافت کردید. %1 Notifications - Action Required - + 1% هشدارها - عمل لازم @@ -519,37 +519,37 @@ SSL client certificate authentication - + تأیید اعتبار گواهی‌نامه مشتری SSL This server probably requires a SSL client certificate. - + سرور احتمالا نیاز به گواهی‌نامه مشتری SSL دارد. Certificate & Key (pkcs12) : - + گواهی‌نامه و کلید (pkcs12) : Browse... - + مرور... Certificate password : - + گواهی‌نامه رمز عبور : Select a certificate - + انتخاب یک گواهی‌نامه Certificate files (*.p12 *.pfx) - + گواهی‌نامه فایل های (p12 *.pfx.*) @@ -557,12 +557,12 @@ Error accessing the configuration file - + خطای دسترسی به پرونده پیکربندی There was an error while accessing the configuration file at %1. - + خطایی هنگام دسترسی به پرونده پیکربندی در 1% وحود دارد. @@ -575,12 +575,12 @@ Authentication Required - + نیازمند تاییدیه Enter username and password for '%1' at %2. - + نام کاربری و رمز عبور را برای '1%' در 2% وارد کنید. @@ -606,32 +606,32 @@ No ownCloud account configured - + هیچ حساب ownCloud پیکربندی نشده است The configured server for this client is too old - + پیکربندی سرور برای این مشتری بسیار قدیمی است. Please update to the latest server and restart the client. - + لطفا به آخرین سرور به روز رسانی کنید و مشتری را مجددا راه اندازی نمایید. Authentication error: Either username or password are wrong. - + خطای تأیید: نام کاربری یا رمز عبور اشتباه است. timeout - + وقفه The provided credentials are not correct - + مدارک ارائه شده صحیح نیستند @@ -652,7 +652,7 @@ %1 should be a folder but is not. - + 1% باید یک پوشه باشد اما نیست. @@ -691,27 +691,27 @@ %1 and %n other file(s) have been removed. - + 1% و n% پرونده های دیگر حذف شده اند. %1 and %n other file(s) have been downloaded. - + 1% و n% پرونده های دیگر دانلود شده اند. %1 and %n other file(s) have been updated. - + 1% و n% پرونده های دیگر به روز رسانی شده اند. %1 has been renamed to %2 and %n other file(s) have been renamed. - + 1% به 2% تغییر نام داده شده و n% پرونده های دیگر تغییر نام داده شده اند. %1 has been moved to %2 and %n other file(s) have been moved. - + 1% به 2% منتقل شده و n% پرونده های دیگر منتقل شده اند. @@ -721,17 +721,17 @@ %1 has a sync conflict. Please check the conflict file! - + 1% داراری ناسازگاری همگام است. لطفا پرونده ناسازگار را بررسی نمایید. %1 and %n other file(s) could not be synced due to errors. See the log for details. - + 1% و n% سایر پرونده ها به دلیل خطاها نمی توانند همگام سازی شوند. برای جزییات log را مشاهده کنید. %1 could not be synced due to an error. See the log for details. - + 1% به دلیل خطاها نمی تواند همگام سازی شود. برای جزییات log را مشاهده کنید. @@ -741,24 +741,26 @@ Could not read system exclude file - + نمی توان پرونده خارجی سیستم را خواند. A new folder larger than %1 MB has been added: %2. - + یک پوشه جدید بزرگتر از 1% MB اضافه شده است: 2%. + A folder from an external storage has been added. - + یک پوشه از یک مخزن خارجی اضافه شده است. + Please go in the settings to select it if you wish to download it. - + اگر می خواهید این را دانلود کنید لطفا به تنظیمات بروید تا آن را انتخاب کنید. @@ -766,14 +768,19 @@ These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to keep the files, they will be re-synced with the server if you have rights to do so. If you decide to delete the files, they will be unavailable to you, unless you are the owner. - + تمامی پرونده های پوشه همگام ساز پوشه '1%' در سرور حذف شد. +این حذف ها با پوشه همگام ساز محلی شما هماهنگ خواهند شد، ساخت چنین پرونده هایی در دسترس نیستند مگر اینکه حق بازگرداندن داشته باشید. +اگر شما تصمیم بگیرید پرونده ها را نگهداری کنید، آن ها با سرور مجددا همگام سازی می شوند در صورتی که شما حق انجام آن را داشته باشید. +اگر شما تصمیم بگیرید پرونده ها را حذف کنید، آن ها در دسترس شما نخواهند بود، مگر اینکه مالک باشید. All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. - + تمامی پرونده های پوشه همگام ساز '1%' در سرور حذف شد. این حذف ها با پوشه همگام ساز محلی شما هماهنگ خواهند شد، ساخت چنین پرونده هایی در دسترس نیستند مگر اینکه حق بازگرداندن داشته باشید. +آیا شما اطمینان دارید که می خواهید آن اعمال را با سرور همگام نمایید؟ +اگر این یک اتفاق بوده و شما تصمیم دارید پرونده هایتان را نگه دارید، آن ها از سرور مجددا همگام سازی خواهند شد. @@ -795,22 +802,24 @@ If this was an accident and you decide to keep your files, they will be re-synce This sync would reset the files to an earlier time in the sync folder '%1'. This might be because a backup was restored on the server. Continuing the sync as normal will cause all your files to be overwritten by an older file in an earlier state. Do you want to keep your local most recent files as conflict files? - + این همگام سازی پرونده ها را به زمان قبلی در پوشه همگام ساز 1% مجددا تنظیم می کند. +این ممکن است به این دلیل باشد که یک پشتیبان در سرور بازسازی شده است. +ادامه همگام سازی به طور معمول سبب خواهد شد که تمام پرونده های شما توسط یک فایل قدیمی تر در یک وضعیت جدیدتر بازنویسی شوند. آیا شما می خواهید پرونده های اخیر محلیتان را به عنوان پرونده های ناسازگار نگهداری کنید؟ Backup detected - + پشتیبان شناسایی شد Normal Synchronisation - + همگام سازی معمول Keep Local Files as Conflict - + پرونده های محلی را به عنوان ناسازگار نگه دارید @@ -823,7 +832,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an An old sync journal '%1' was found, but could not be removed. Please make sure that no application is currently using it. - + یک مجله همگام قدیمی '1%' پیدا شد، اما حذف نمی شود. لطفا مطمئن شوید که هیچ برنامه ای در حال حاضر از آن استفاده نمی کند. @@ -863,7 +872,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Last Sync was successful, but with warnings on individual files. - + اخرین همگام سازی موفق بود، اما با هشدارهایی در پرونده های مجزا همراه بود. @@ -893,7 +902,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an The selected path is not a folder! - + مسیر انتخاب شده یک پوشه نیست! @@ -903,27 +912,27 @@ Continuing the sync as normal will cause all your files to be overwritten by an The local folder %1 contains a symbolic link. The link target contains an already synced folder Please pick another one! - + پوشه محلی 1% شامل یک پیوند نمادین می باشد. پیوند مقصد در حال حاضر شامل پوشه ای همگام سازی شده است، لطفا یکی دیگر را انتخاب کنید! There is already a sync from the server to this local folder. Please pick another local folder! - + در حال حاضر یک همگام سازی از سرور به این پوشه محلی وجود دارد. لطفا یک پوشه محلی دیگر را انتخاب کنید! The local folder %1 already contains a folder used in a folder sync connection. Please pick another one! - + پوشه محلی 1% از قبل شامل یک پوشه استفاده شده در یک اتصال همگام سازی پوشه است. لطفا یکی دیگر را انتخاب کنید! The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one! - + پوشه محلی 1% از قبل یک پوشه استفاده شده در یک اتصال همگام سازی پوشه دارد. لطفا یکی دیگر را انتخاب کنید! The local folder %1 is a symbolic link. The link target is already contained in a folder used in a folder sync connection. Please pick another one! - + پوشه محلی 1% شامل یک پیوند نمادین می باشد. پیوند مقصد در حال حاضر در یک پوشه استفاده شده در اتصال همگام پوشه موجود است. لطفا یکی دیگر را انتخاب کنید! @@ -931,7 +940,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Add Folder Sync Connection - + افزودن اتصال همگام سازی پوشه @@ -949,7 +958,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an You need to be connected to add a folder - + شما باید متصل باشید تا پوشه ای را اضافه کنید @@ -966,7 +975,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Error while loading the list of folders from the server. - + خطای هنگام بارگذاری لیست پوشه‌ها از سرور. @@ -976,28 +985,28 @@ Continuing the sync as normal will cause all your files to be overwritten by an Fetching folder list from server... - + آوردن لیست پوشه از سرور... There are unresolved conflicts. Click for details. - + ناسازگاری های حل نشده ای وجود دارد. برای جزییات کلیک نمایید. Checking for changes in '%1' - + بررسی تغییرات در '1%' Reconciling changes - + تطبیق تغییرات , '%1' Build a list of file names - + ، '1%' @@ -1055,13 +1064,13 @@ Continuing the sync as normal will cause all your files to be overwritten by an %5 left, %1 of %2, file %3 of %4 Example text: "5 minutes left, 12 MB of 345 MB, file 6 of 7" - + 5% باقی ماند، 1% از 2%، پرونده 3% از 4% %1 of %2, file %3 of %4 Example text: "12 MB of 345 MB, file 6 of 7" - + 1% از 2%، پرونده 3% از 4% @@ -1089,12 +1098,12 @@ Continuing the sync as normal will cause all your files to be overwritten by an Add Folder Sync Connection - + اضافه کردن اتصال همگام سازی پوشه Add Sync Connection - + افزودن اتصال همگام سازی @@ -1102,12 +1111,12 @@ Continuing the sync as normal will cause all your files to be overwritten by an Click to select a local folder to sync. - + کلیک کنید تا یک پوشه را برای همگام سازی انتخاب نمایید. Enter the path to the local folder. - + مسیر را به پوشه محلی وارد کنید. @@ -1120,12 +1129,12 @@ Continuing the sync as normal will cause all your files to be overwritten by an Create Remote Folder - + ایجاد پوشه از راه دور Enter the name of the new folder to be created below '%1': - + نام پوشه جدید را برای ایجاد شدن در زیر '1%' وارد نمایید: @@ -1135,22 +1144,22 @@ Continuing the sync as normal will cause all your files to be overwritten by an Authentication failed accessing %1 - + تأیید اعتبار دسترسی به 1% شکست خورد Failed to create the folder on %1. Please check manually. - + شکست در ساخت پوشه در 1%. لطفا به صورت دستی بررسی کنید. Failed to list a folder. Error: %1 - + شکست در فهرست کردن یک پوشه. خطا: 1% Choose this to sync the entire account - + این را برای همگام سازی کل حساب انتخاب کنید @@ -1160,7 +1169,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an You are already syncing <i>%1</i>, which is a parent folder of <i>%2</i>. - + شما از قبل <i>1%</i> را همگام سازی کرده اید، که یک پوشه والد از <i>2%</i> است. @@ -1181,17 +1190,17 @@ Continuing the sync as normal will cause all your files to be overwritten by an No E-Tag received from server, check Proxy/Gateway - + E-Tag از سرور دریافت نشده است، لطفا پروکسی/دروازه را بررسی نمایید We received a different E-Tag for resuming. Retrying next time. - + ما برای بازخوانی E-Tag متفاوتی دریافت کردیم. بار بعدی دوباره امتحان کنید. Server returned wrong content-range - + سرور محدوده محتوای اشتباهی برگرداند. @@ -1224,7 +1233,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Ask for confirmation before synchronizing folders larger than - + درخواست تایید قبل از همگام سازی پوشه های بزرگتر @@ -1235,32 +1244,32 @@ Continuing the sync as normal will cause all your files to be overwritten by an Ask for confirmation before synchronizing external storages - + درخواست تایید قبل از همگام سازی مخازن خارجی &Launch on System Startup - + &Launch در سیستم راه اندازی Show &Desktop Notifications - + نمایش هشدار &Desktop Use &Monochrome Icons - + استفاده از آیکون های &Monochrome Edit &Ignored Files - + ویرایش پرونده های &Ignored S&how crash reporter - + گزارشگر تصادف S&how @@ -1284,7 +1293,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Please enter %1 password:<br><br>User: %2<br>Account: %3<br> - + لطفا رمز عبور 1% را وارد کنید: <br><br> کاربر: 2% <br> حساب: 3% <br> @@ -1299,7 +1308,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an <a href="%1">Click here</a> to request an app password from the web interface. - + <a href="%1">اینجا کلیک کنید</a> تا رمز عبور یک برنامه را از رابط وب درخواست کنید. @@ -1307,22 +1316,22 @@ Continuing the sync as normal will cause all your files to be overwritten by an Ignored Files Editor - + ویرایشگر پرونده های رد شده Global Ignore Settings - + تنظیمات رد کردن سراسری Sync hidden files - + همگام سازی پرونده های مخفی Files Ignored by Patterns - + پرونده ها توسط الگوها رد شده اند @@ -1337,7 +1346,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Allow Deletion - + اجازه حذف @@ -1349,7 +1358,8 @@ Continuing the sync as normal will cause all your files to be overwritten by an Files or folders matching a pattern will not be synchronized. Items where deletion is allowed will be deleted if they prevent a directory from being removed. This is useful for meta data. - + پرونده ها یا پوشه‌های مطابق با یک الگو همگام نخواهند شد. +مواردی که در آن حذف کردن مجاز است، اگر از حذف یک پوشه جلوگیری کنند حذف خواهند شد. این برای فرا داده ها مفید است. @@ -1364,17 +1374,17 @@ Items where deletion is allowed will be deleted if they prevent a directory from Add Ignore Pattern - + افزودن الگوی رد کردن Add a new ignore pattern: - + افزودن یک الگوی رد کردن جدید: This entry is provided by the system at '%1' and cannot be modified in this view. - + این ورودی توسط سیستم در '1%' ارائه شده است و در این دیدگاه قابل تغییر نیست. @@ -1387,7 +1397,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from List of issues - + فهرست موضوعات @@ -1398,7 +1408,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from <no filter> - + <no filter> @@ -1409,17 +1419,17 @@ Items where deletion is allowed will be deleted if they prevent a directory from Show warnings - + نمایش هشدارها Show ignored files - + نمایش پرونده های رد شده Copy the issues list to the clipboard. - + کپی کردن فهرست موضوعات در کلیپ بورد. @@ -1439,7 +1449,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from Issue - + موضوع @@ -1462,7 +1472,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from &Capture debug messages - + ضبط پیام های رفع خطا @@ -1472,7 +1482,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from Clear the log display. - + صفحه نمایش log را پاک کنید. @@ -1482,7 +1492,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from Save the log file to a file on disk for debugging. - + پرونده log را برای رفع اشکال در یک پرونده از دیسک ذخیره کنید. @@ -1497,7 +1507,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from Could not write to log file %1 - + نمی توان در فایل لاگ 1% نوشت @@ -1510,7 +1520,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from <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/>خروجی log <b>نمی تواند</b> ذخیره شود!</nobr> @@ -1523,7 +1533,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from <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> @@ -1581,7 +1591,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from Proxy server requires authentication - + سرور پروکسی نیازمند تایید است @@ -1610,7 +1620,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from Limit to 3/4 of estimated bandwidth - + محدود به 3/4 پهنای باند تخمین زده شده @@ -1659,19 +1669,19 @@ Items where deletion is allowed will be deleted if they prevent a directory from Closing in a few seconds... - + بستن در چند ثانیه... %1 request failed at %2 The second parameter is a time, such as 'failed at 09:58pm' - + درخواست 1% در 2% شکست خورد '%1' selected at %2 The second parameter is a time, such as 'selected at 09:58pm' - + '1%' در 2% انتخاب شد @@ -1679,32 +1689,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from Error returned from the server: <em>%1</em> - + خطای بازگشت از سرور: <em>1%</em> There was an error accessing the 'token' endpoint: <br><em>%1</em> - + خطایی در دسترسی به نقطه پایانی 'token' وجود داشت: <br><em>1%</em> Could not parse the JSON returned from the server: <br><em>%1</em> - + JSON بازگشتی از سرور قابل تجزیه نیست: <br><em>1%</em> The reply from the server did not contain all expected fields - + پاسخ سرور شامل تمامی زمینه های مورد انتظار نبود <h1>Login Error</h1><p>%1</p> - + <h1>خطای ورود</h1><p>1%</p> <h1>Wrong user</h1><p>You logged-in with user <em>%1</em>, but must login with user <em>%2</em>.<br>Please log out of %3 in another tab, then <a href='%4'>click here</a> and log in as user %2</p> - + <h1>کاربر نادرست</h1><p> شما با کاربر<em>1%</em> وارد شدید، اما باید با کاربر <em>2%</em> وارد می شدید. <br> لطفا در برگه دیگری از 3% خارج شده، سپس <a href='%4'>اینجا را کلیک کنید</a> و به عنوان کاربر 2% وارد شوید</p> @@ -1712,53 +1722,53 @@ Items where deletion is allowed will be deleted if they prevent a directory from New %1 Update Ready - + به روز رسانی جدید 1% آماده است A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. - + یک به روز رسانی جدید برای 1% در حال نصب است. به روز رسان ممکن است امتیازات اضافی در طول پردازش درخواست کند. Downloading version %1. Please wait... - + دانلود نسخه 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. - + نمی توان به روز رسانی های جدید را بررسی کرد. %1 version %2 available. Restart application to start the update. - + 1% نسخه 2% موجود است. برنامه را مجددا راه اندازی کنید تا به روز رسانی شروع شود. New %1 version %2 available. Please use the system's update tool to install it. - + 1% جدید نسخه 2% موجود است. لطفا از ابزار به روز رسانی سیستم استفاده کنید تا آن را نصب نمایید. Checking update server... - + بررسی سرور به روز رسانی... Update status is unknown: Did not check for new updates. - + وضعیت به روز رسانی نامشخص است: به روز رسانی های جدید را بررسی نکردید. No updates available. Your installation is at the latest version. - + به روز رسانی موجود نیست. نصب شما آخرین نسخه است. @@ -1776,7 +1786,7 @@ for additional privileges during the process. Setup local folder options - + راه اندازی گزینه های پوشه محلی @@ -1796,7 +1806,7 @@ for additional privileges during the process. <p><small><strong>Warning:</strong> The local folder is not empty. Pick a resolution!</small></p> - + <p><small><strong>هشدار:</strong> پوشه محلی خالی نیست. یک دقت انتخاب کنید!</small></p> @@ -1820,7 +1830,7 @@ for additional privileges during the process. <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> @@ -1835,12 +1845,12 @@ for additional privileges during the process. Configure client-side TLS certificate - + پیکربندی سمت مشتری گواهی‌نامه TLS <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> @@ -1848,7 +1858,7 @@ for additional privileges during the process. &Email - + &Email @@ -1858,7 +1868,7 @@ for additional privileges during the process. Enter user credentials - + وارد کردن گواهی نامه کاربر @@ -1871,7 +1881,7 @@ for additional privileges during the process. Login in your browser - + در مرورگر خود وارد شوید @@ -1890,7 +1900,8 @@ for additional privileges during the process. This url is NOT secure as it is not encrypted. It is not advisable to use it. - + این آدرس امن نیست زیرا رمزگذاری شده نیست. +استفاده از آن توصیه نمی شود. @@ -1918,7 +1929,7 @@ It is not advisable to use it. Timeout while trying to connect to %1 at %2. - + هنگام تلاش برای اتصال به 1% در 2% زمان به پایان رسید. @@ -1928,7 +1939,7 @@ 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. - + درخواست تایید شده به سرور '1%' هدایت شد. آدرس بد است، سرور اشتباه پیکربندی شده است. @@ -1938,7 +1949,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> تا با مرورگر خود به سرویس دسترسی پیدا کنید. @@ -1948,7 +1959,7 @@ It is not advisable to use it. The server reported the following error: - + سرور خطای زیر را گزارش کرد: @@ -1958,7 +1969,7 @@ It is not advisable to use it. Creating local sync folder %1... - + ساخت پوشه همگام سازی محلی 1%... @@ -1978,7 +1989,7 @@ It is not advisable to use it. No remote folder specified! - + هیچ پوشه از راه دوری مشخص نشده است! @@ -2004,7 +2015,7 @@ It is not advisable to use it. The folder creation resulted in HTTP error code %1 - + ایجاد پوشه به خطای HTTP کد 1% منجر شد @@ -2045,7 +2056,7 @@ It is not advisable to use it. 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. - + نمی توانید پوشه را حذف کنید یا پشتیبان بگیرید زیرا پوشه یا یک پرونده در آن در برنامه دیگری باز است. لطفا پوشه یا پرونده را ببندید و مجددا تلاش کنید یا تنظیم را لغو کنید. @@ -2071,7 +2082,7 @@ It is not advisable to use it. Everything set up! - + همه چیز تنظیم شده است! @@ -2089,7 +2100,7 @@ It is not advisable to use it. Invalid JSON reply from the poll URL - + پاسخ JSON نامعتبر از آدرس نظرسنجی @@ -2105,12 +2116,12 @@ It is not advisable to use it. File %1 can not be downloaded because of a local file name clash! - + پرونده 1% بخاطر یک پرونده محلی به نام برخورد دانلود نمی شود! The download would reduce free local disk space below the limit - + دانلود فضای دیسک محلی آزاد تحت محدودیت را کاهش می دهد @@ -2130,17 +2141,17 @@ It is not advisable to use it. The downloaded file is empty despite the server announced it should have been %1. - + پرونده دانلود شده خالی است با وجود اینکه سرور اعلام کرده است این باید 1% باشد. File %1 cannot be saved because of a local file name clash! - + پرونده 1% بخاطر یک پرونده محلی به نام برخورد ذخیره نمی شود! File has changed since discovery - + پرونده از زمان کشف تغییر کرده است. @@ -2153,12 +2164,12 @@ It is not advisable to use it. ; Restoration Failed: %1 - + ؛ بازگردانی شکست خورد: 1% A file or folder was removed from a read only share, but restoring failed: %1 - + یک پرونده یا پوشه از یک اشتراک فقط خواندنی حذف شد، اما بازگردانی شکست خورد: 1% @@ -2166,7 +2177,7 @@ It is not advisable to use it. could not delete file %1, error: %2 - + نمی توان پرونده 1% را حذف کرد: خطای 2% @@ -2194,12 +2205,12 @@ It is not advisable to use it. Could not remove folder '%1' - + پوشه '1%' حذف نمی شود Could not remove %1 because of a local file name clash - + 1% بخاطر یک پرونده محلی به نام برخورد حذف نمی شود @@ -2207,7 +2218,7 @@ It is not advisable to use it. File %1 can not be renamed to %2 because of a local file name clash - + پرونده 1% بخاطر یک پرونده محلی به نام برخورد نتغییر نام داده نمی شود @@ -2221,12 +2232,12 @@ It is not advisable to use it. The file has been removed from a read only share. It was restored. - + پرونده از یک استراک فقط خواندنی حذف شد. این بازگردانی شد. Wrong HTTP code returned by server. Expected 204, but received "%1 %2". - + کد HTTP اشتباه توسط سرور برگردانده شد. 204 انتظار می رفت، اما "1% 2%" دریافت شد. @@ -2234,7 +2245,7 @@ It is not advisable to use it. Wrong HTTP code returned by server. Expected 201, but received "%1 %2". - + کد HTTP اشتباه توسط سرور برگردانده شد. 201 انتظار می رفت، اما "1% 2%" دریافت شد. @@ -2247,22 +2258,22 @@ It is not advisable to use it. 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 received "%1 %2". - + کد HTTP اشتباه توسط سرور برگردانده شد. 201 انتظار می رفت، اما "1% 2%" دریافت شد. @@ -2276,7 +2287,7 @@ It is not advisable to use it. File %1 cannot be uploaded because another file with the same name, differing only in case, exists - + پرونده 1% بارگذاری نمی شود زیرا پرونده دیگری با نام مشابه، که تنها در وضعیت متفاوت است، وجود دارد @@ -2286,7 +2297,7 @@ It is not advisable to use it. Local file changed during syncing. It will be resumed. - + پرونده محلی در طول همگام سازی تغییر کرد. این ادامه خواهد یافت. @@ -2297,7 +2308,7 @@ It is not advisable to use it. Upload of %1 exceeds the quota for the folder - + بارگذاری از 1% بیش از سهمیه برای پوشه است @@ -2320,17 +2331,17 @@ It is not advisable to use it. Unexpected return code from server (%1) - + کد بازگشت غیر منتظره از سرور (1%) Missing File ID from server - + فاقد شناسه پرونده از سرور Missing ETag from server - + فاقد ETag از سرور @@ -2411,7 +2422,7 @@ It is not advisable to use it. Copy the activity list to the clipboard. - + لیست فعالیت را در کلیپ بورد کپی کنید. @@ -2845,7 +2856,7 @@ It is not advisable to use it. ... - + ... @@ -3523,7 +3534,7 @@ It is not advisable to use it. Checking for changes in '%1' - + بررسی تغییرات در '1%' @@ -3583,7 +3594,7 @@ It is not advisable to use it. Disconnected - + قطع شده From b9c167fc13de7d3ef1596454847992f764b03087 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Mon, 1 Jan 2018 02:18:34 +0100 Subject: [PATCH 039/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 + translations/client_fa.ts | 307 +++++++++++++++++++------------------- 2 files changed, 157 insertions(+), 153 deletions(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index 8f77b12d5..7d917da4f 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -131,6 +131,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_fa.ts b/translations/client_fa.ts index 433442066..9c54cee6b 100644 --- a/translations/client_fa.ts +++ b/translations/client_fa.ts @@ -716,12 +716,12 @@ %1 has and %n other file(s) have sync conflicts. - + 1% و n% سایر پرونده ها ناسازگاری همگام سازی دارند. %1 has a sync conflict. Please check the conflict file! - 1% داراری ناسازگاری همگام است. لطفا پرونده ناسازگار را بررسی نمایید. + 1% داراری ناسازگاری همگام سازی است. لطفا پرونده ناسازگار را بررسی نمایید. @@ -1249,27 +1249,27 @@ Continuing the sync as normal will cause all your files to be overwritten by an &Launch on System Startup - &Launch در سیستم راه اندازی + راه انداختن در سیستم راه اندازی Show &Desktop Notifications - نمایش هشدار &Desktop + نمایش هشدارهای دسکتاپ Use &Monochrome Icons - استفاده از آیکون های &Monochrome + استفاده از آیکون های تک رنگ Edit &Ignored Files - ویرایش پرونده های &Ignored + ویرایش پرونده های رد شده S&how crash reporter - گزارشگر تصادف S&how + نمایش گزارشگر برخورد @@ -1285,7 +1285,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an &Restart && Update - + راه اندازی مجدد و به روز رسانی @@ -1457,7 +1457,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from Log Output - + خروجی Log @@ -1858,7 +1858,7 @@ for additional privileges during the process. &Email - &Email + پست الکترونیکی @@ -1944,7 +1944,7 @@ It is not advisable to use it. There was an invalid response to an authenticated webdav request - + یک پاسخ نادرست به درخواست webdov تایید شده وجود داشت @@ -2074,7 +2074,7 @@ It is not advisable to use it. Skip folders configuration - + از پیکربندی پوشه‌ها بگذرید @@ -2349,12 +2349,12 @@ It is not advisable to use it. 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 - + فاقد آدرس نظرسنجی @@ -2369,7 +2369,7 @@ It is not advisable to use it. The server did not acknowledge the last chunk. (No e-tag was present) - + سرور آخرین تکه را تایید نکرد. (برچسب الکترونیکی وجود نداشت) @@ -2412,7 +2412,7 @@ It is not advisable to use it. Local sync protocol - + پروتکل همگام سازی محلی @@ -2422,7 +2422,7 @@ It is not advisable to use it. Copy the activity list to the clipboard. - لیست فعالیت را در کلیپ بورد کپی کنید. + فهرست فعالیت را در کلیپ بورد کپی کنید. @@ -2476,7 +2476,7 @@ It is not advisable to use it. Deselect remote folders you do not wish to synchronize. - + پوشه‌های از راه دور را که نمی خواهید همگام سازی کنید، انتخاب نکنید. @@ -2492,12 +2492,12 @@ It is not advisable to use it. No subfolders currently on the server. - + هیچ زیر پوشه ای در حال حاضر در سرور وجود ندارد. An error occurred while loading the list of sub folders. - + هنگام بارگذاری فهرست زیر پوشه ها خطایی روی داد. @@ -2580,7 +2580,7 @@ It is not advisable to use it. Dialog - + گفتگو @@ -2605,27 +2605,27 @@ It is not advisable to use it. The server does not allow sharing - + سرور اجازه به اشتراک گذاشتن نمی دهد Retrieving maximum possible sharing permissions from server... - + گرفتن مجوز بیشترین اشتراک ممکن از سرور... The file can not be shared because it was shared without sharing permission. - + پرونده نمی تواند به اشتراک گذاشته شود زیرا بدون مجوز به اشتراک گذاشته شده است. Users and Groups - + کاربران و گروه ها Public Links - + پیوندهای عمومی @@ -2633,7 +2633,7 @@ It is not advisable to use it. Share NewDocument.odt - + اشتراک NewDocument.odt @@ -2648,7 +2648,7 @@ It is not advisable to use it. Enter a name to create a new public link... - + یک نام وارد کنید تا پیوند عمومی جدیدی بسازید... @@ -2668,12 +2668,12 @@ It is not advisable to use it. Link properties: - + خواص پیوند: Show file listing - + نمایش فهرست نویسی پرونده @@ -2683,7 +2683,7 @@ It is not advisable to use it. Anyone with the link has access to the file/folder - + هر کسی با پیوند به پرونده/پوشه دسترسی دارد @@ -2699,22 +2699,22 @@ It is not advisable to use it. The file can not be shared because it was shared without sharing permission. - + پرونده نمی تواند به اشتراک گذاشته شود زیرا بدون مجوز به اشتراک گذاشته شده است. %1 link - + پیوند 1% Link shares have been disabled - + اشتراک های پیوند غیر فعال شده اند Create public link share - + اشتراک لینک عمومی بسازید @@ -2725,17 +2725,17 @@ It is not advisable to use it. Open link in browser - + لینک را در مرورگر باز کنید Copy link to clipboard - + لینک را در کلیپ بورد کپی کنید Copy link to clipboard (direct download) - + لینک را در کلیپ بورد کپی کنید (دانلود مستقیم) @@ -2745,17 +2745,17 @@ It is not advisable to use it. Send link by email (direct download) - + لینک را با پست الکترونیکی ارسال کنید (دانلود مستقیم) Confirm Link Share Deletion - + حذف اشتراک گذاری لینک را تایید کنید <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + <p>آیا شما واقعا می خواهید اشتراک لینک عمومی را حذف کنید<i>1%</i>؟</p><p> توجه: این عمل نمی تواند انجام نشود.</p> @@ -2765,12 +2765,12 @@ It is not advisable to use it. Public link - + پیوند عمومی Delete link share - + حذف پیوند اشتراک @@ -2788,7 +2788,7 @@ It is not advisable to use it. Share NewDocument.odt - + اشتراک NewDocument.odt @@ -2798,22 +2798,22 @@ It is not advisable to use it. <html><head/><body><p>You can direct people to this shared file or folder <a href="private link menu"><span style=" text-decoration: underline; color:#0000ff;">by giving them a private link</span></a>.</p></body></html> - + <html><head/><body><p>شما می تونید مردم را <a href="private link menu"><span style=" text-decoration: underline; color:#0000ff;"> با دادن لینک خصوصی به آن ها</span></a> به این پرونده یا پوشه مشترک هدایت کنید. </p></body></html> The item is not shared with any users or groups - + این مورد با هیچ کاربر یا گروهی به اشتراک گذاشته نشده است Open link in browser - + لینک را در مرورگر باز کنید Copy link to clipboard - + لینک را در کلیپ بورد کپی کنید @@ -2823,12 +2823,12 @@ It is not advisable to use it. No results for '%1' - + هیچ نتیجه ای برای '1%' وجود ندارد I shared something with you - + من چیزی را با شما به اشتراک گذاشتم @@ -2884,7 +2884,7 @@ It is not advisable to use it. You must sign in as user %1 - + شما باید به عنوان کاربر 1% وارد شوید @@ -2892,7 +2892,7 @@ It is not advisable to use it. %1 - Authenticate - + 1% - تایید اعتبار @@ -2902,12 +2902,12 @@ It is not advisable to use it. Reauthentication required - + تایید اعتبار مجدد مورد نیاز است Your session has expired. You need to re-login to continue to use the client. - + جلسه شما منقضی شده است. برای ادامه استفاده از سرویس گیرنده، مجددا باید وارد شوید. @@ -2921,22 +2921,22 @@ It is not advisable to use it. I shared something with you - + من چیزی را با شما به اشتراک گذاشتم Share... - + اشتراک گذاری... Copy private link to clipboard - + لینک خصوصی را در کلیپ بورد کپی کنید Send private link by email... - + لینک خصوصی را پست الکترونیکی ارسال کنید... @@ -2954,7 +2954,7 @@ It is not advisable to use it. Subject Alternative Names: - + نام های جایگزین موضوع: @@ -3004,7 +3004,7 @@ It is not advisable to use it. <h3>Fingerprints</h3> - + <h3>اثر انگشت</h3> @@ -3019,7 +3019,7 @@ It is not advisable to use it. <p><b>Note:</b> This certificate was manually approved</p> - + <p><b>توجه: </b>این گواهی‌نامه به طور دستی تایید شده است</p> @@ -3035,12 +3035,12 @@ It is not advisable to use it. This connection is encrypted using %1 bit %2. - + این اتصال با استفاده از 1% بیت 2% رمزگذاری شده است. No support for SSL session tickets/identifiers - + پشتیبانی برای جلسه SSL برچسب ها/شناسه ها وجود ندارد @@ -3051,7 +3051,8 @@ It is not advisable to use it. This connection is NOT secure as it is not encrypted. - + این اتصال امن نیست زیرا رمزگذاری نشده است. + @@ -3142,7 +3143,7 @@ It is not advisable to use it. CSync failed to load the journal file. The journal file is corrupted. - + CSync در بارگذاری پرونده مجله شکست خورد. پرونده مجله از بین رفته است. @@ -3152,7 +3153,7 @@ It is not advisable to use it. CSync fatal parameter error. - + خطای پارامتری وخیم CSync. @@ -3167,7 +3168,7 @@ It is not advisable to use it. CSync could not authenticate at the proxy. - + CSync نمی تواند پروکسی را تصدیق کند. @@ -3187,7 +3188,7 @@ It is not advisable to use it. A network connection timeout happened. - + وقفه اتصال شبکه روی داده است. @@ -3197,7 +3198,7 @@ It is not advisable to use it. The mounted folder is temporarily not available on the server - + پوشه نصب شده به طور موقت در سرور موجود نیست @@ -3212,53 +3213,53 @@ It is not advisable to use it. %1 (skipped due to earlier error, trying again in %2) - + 1% (به علت خطای قبلی از بین رفته است، دوباره در 2% امتحان کنید) File/Folder is ignored because it's hidden. - + پرونده/پوشه رد شد زیرا مخفی است. Folder hierarchy is too deep - + سلسله مراتب پوشه خیلی عمیق است Conflict: Server version downloaded, local copy renamed and not uploaded. - + ناسازگاری: نسخه سرور دانلود شد، کپی محلی تغییر نام داده شده و بارگذاری نشده است. Only %1 are available, need at least %2 to start Placeholders are postfixed with file sizes using Utility::octetsToString() - + تنها 1% موجود است، حداقل 2% برای شروع مورد نیاز است Unable to open or create the local sync database. Make sure you have write access in the sync folder. - + پایگاه داده محلی باز یا ساخته نمی شود. اطمینان حاصل کنید که دسترسی به نوشتن در پوشه همگام سازی دارید. Not allowed because you don't have permission to add parent folder - + مجاز نیستید زیرا شما اجازه افزودن به پوشه والد را ندارید Not allowed because you don't have permission to add files in that folder - + مجاز نیستید زیرا شما اجازه افزودن پرونده به آن پوشه را ندارید Disk space is low: Downloads that would reduce free space below %1 were skipped. - + فضای دیسک کم است: دانلودهایی که فضای آزاد را به کمتر از 1% کاهش می دهند رد می شوند. There is insufficient space available on the server for some uploads. - + برای بعضی از بارگذاری ها در سرور فضای کافی موجود نیست. @@ -3278,22 +3279,22 @@ It is not advisable to use it. CSync failed to access - + CSync برای دسترسی شکست خورد CSync failed to load or create the journal file. Make sure you have read and write permissions in the local sync folder. - + CSync در بارگذاری یا ساخت پرونده مجله شکست خورد. اطمینان حااصل کنید که شما اجازه خواندن و نوشتن در پوشه همگام سازی محلی را دارید. CSync failed due to unhandled permission denied. - + CSync به علت رد شدن مجوز نادرست شکست خورد. CSync tried to create a folder that already exists. - + CSync سعی کرد پوشه ای بسازد که از قبل موجود بود. @@ -3303,7 +3304,7 @@ It is not advisable to use it. Access is forbidden - + دسترسی ممنوع است @@ -3313,32 +3314,32 @@ It is not advisable to use it. Symbolic links are not supported in syncing. - + پیوندهای نمادین در همگام سازی پشتیبانی نمی شوند. File is listed on the ignore list. - + پرونده در فهرست رد شده ها موجود است. File names ending with a period are not supported on this file system. - + نام پرونده هایی که با دوره ای پایان می یابند در این سیستم پرونده پشتیبانی نشده اند. File names containing the character '%1' are not supported on this file system. - + نام پرونده هایی که شامل کاراکتر '1%' هستند در این سیستم پرونده پشتیبانی نشده اند. The file name is a reserved name on this file system. - + نام پرونده یک نام رزرو شده در این سیستم پرونده است. Filename contains trailing spaces. - + نام پرونده شامل دنباله فضای خالی است. @@ -3348,12 +3349,12 @@ It is not advisable to use it. The filename cannot be encoded on your file system. - + نام پرونده در سیستم پرونده شما رمزگذاری نمی شود. Unresolved conflict. - + ناسازگاری حل نشده. @@ -3373,17 +3374,17 @@ It is not advisable to use it. Unable to read the blacklist from the local database - + نمی توان لیست سیاه را از پایگاه داده محلی خواند Unable to read from the sync journal. - + نمی توان از مجله همگام ساز خواند. Cannot open the sync journal - + نمی توان مجله همگام ساز را باز کرد @@ -3394,7 +3395,7 @@ It is not advisable to use it. Ignored because of the "choose what to sync" blacklist - + به علت لیست سیاه "انتخاب کنید چه چیزی همگام سازی شود" رد شد @@ -3425,7 +3426,7 @@ It is not advisable to use it. Move not allowed because %1 is read-only - + انتقال مجاز نیست زیرا 1% فقط خواندنی است @@ -3443,7 +3444,7 @@ It is not advisable to use it. Synchronisation Log - + Log همگام سازی @@ -3469,7 +3470,7 @@ It is not advisable to use it. <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> @@ -3477,17 +3478,17 @@ It is not advisable to use it. The checksum header is malformed. - + سرتیتر checksum نادرست است. The checksum header contained an unknown checksum type '%1' - + سرتیتر checksum شامل یک checksum نوع '1%' ناشناخته است The downloaded file does not match the checksum, it will be resumed. - + پرونده دانلود شده با checksum مطابق نیست، این ادامه خواهد یافت. @@ -3549,7 +3550,7 @@ It is not advisable to use it. Open %1 in browser - + 1% را در مرورگر باز کنید @@ -3584,12 +3585,12 @@ It is not advisable to use it. Unsupported Server Version - + نسخه سرور پشتیبانی نشده The server on account %1 runs an old and unsupported version %2. Using this client with unsupported server versions is untested and potentially dangerous. Proceed at your own risk. - + سرور روی حساب 1% یک نسخه قدیمی و پشتیبانی نشده 2% را اجرا کرده است. استفاده از این مشتری با نسخه های سرور پشتیبانی نشده بررسی نشده و خطرناک است. مسئولیت با خود شماست. @@ -3599,12 +3600,12 @@ It is not advisable to use it. Disconnected from some accounts - + قطع شده از برخی حساب ها Disconnected from accounts: - + قطع شده از حساب ها: @@ -3619,68 +3620,68 @@ It is not advisable to use it. Account synchronization is disabled - + همگام سازی حساب غیر فعال است Synchronization is paused - + همگام سازی متوقف شده است Error during synchronization - + خطا حین همگام سازی No sync folders configured - + هیچ پوشه‌ همگام سازی پیکربندی شده Unpause all folders - + شروع مجدد تمام پوشه‌ها Pause all folders - + توقف تمام پوشه‌ها Unpause all synchronization - + شروع مجدد تمام همگام سازی ها Unpause synchronization - + شروع مجدد همگام سازی Pause all synchronization - + توقف تمام همگام سازی ها Pause synchronization - + توقف همگام سازی Log out of all accounts - + خروج از تمام حساب ها Log in to all accounts... - + ورود به تمام حساب ها... New account... - + حساب جدید... @@ -3701,7 +3702,7 @@ It is not advisable to use it. Syncing %1 of %2 - + همگام سازی 1% از 2% @@ -3729,7 +3730,7 @@ It is not advisable to use it. <p>Version %2. For more information visit <a href="%3">https://%4</a></p><p>For known issues and help, please visit: <a href="https://central.owncloud.org/c/desktop-client">https://central.owncloud.org</a></p><p><small>By Klaas Freitag, Daniel Molkentin, Olivier Goffart, Markus Götz, Jan-Christoph Borchardt, and others.</small></p><p>Copyright ownCloud GmbH</p><p>Licensed under the GNU General Public License (GPL) Version 2.0<br/>ownCloud and the ownCloud Logo are registered trademarks of ownCloud GmbH in the United States, other countries, or both.</p> - + <p>نسخه 2%. برای اطلاعات بیشتر https://%4 را مشاهده کنید.</p> <p>برای موضوعات آشنا و کمک، لطفا <a href="https://central.owncloud.org/c/desktop-client">https://central.owncloud.org</a> را مشاهده کنید.</p><p><small>توسط Klaas Freitag و Daniel Molkentin و Olivier Goffart و Markus Götz و Jan-Christoph Borchardt و دیگران. </small></p><p> Copyright ownCloud GmbH</p><p>تحت مجوز GNU مجوز عمومی سراسری (GPL) نسخه 2.0 <br/> ownCloud و لوگوی ownCloud علائم تجاری ownCloud GmbH در ایالت متحده، سایر کشورها، یا هر دو را ثبت کرده اند. </p> @@ -3758,17 +3759,17 @@ It is not advisable to use it. <html><head/><body><p>If this box is checked, existing content in the local folder 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 folder.</p></body></html> - + <html><head/><body><p>اگر جعبه بررسی شده است، وجود محتوا در پوشه محلی پاک خواهد شد تا یک همگام سازی جدید از سرور آغاز شود. </p><p> اگر محتوای محلی باید در پوشه های سرور بارگذاری شود، این را بررسی نکنید. </p></body></html> Start a &clean sync (Erases the local folder!) - + شروع یک همگام سازی &clean (پوشه محلی را پاک می کند!) Ask for confirmation before synchroni&zing folders larger than - + درخواست تایید پیش از همگام سازی پوشه‌های بزرگتر از @@ -3779,7 +3780,7 @@ It is not advisable to use it. Ask for confirmation before synchronizing e&xternal storages - + درخواست تایید پیش از همگام سازی مخازن خارجی @@ -3804,7 +3805,7 @@ It is not advisable to use it. S&ync everything from server - + همگام سازی همه چیز از سرور @@ -3840,17 +3841,17 @@ It is not advisable to use it. Please switch to your browser to proceed. - + لطفا برای ادامه به مرورگر خود سوئیچ کنید. An error occured while connecting. Please try again. - + هنگام اتصال خطایی روی داد. لطفا دوباره امتحان کنید. Re-open Browser - + مرورگر را دوباره باز کنید @@ -3869,7 +3870,7 @@ It is not advisable to use it. Ser&ver Address - + آدرس سرور @@ -3911,37 +3912,37 @@ It is not advisable to use it. in the future - + در آینده %n day(s) ago - + n% روز پیش %n hour(s) ago - + n% ساعت پیش now - + اکنون Less than a minute ago - + کمتر از یک دقیقه پیش %n minute(s) ago - + n% دقیقه پیش Some time ago - + چند وقت پیش @@ -3975,32 +3976,32 @@ It is not advisable to use it. %n year(s) - + n% سال %n month(s) - + n% ماه %n day(s) - + n% روز %n hour(s) - + n% ساعت %n minute(s) - + n% دقیقه %n second(s) - + n% ثانیه @@ -4026,7 +4027,7 @@ It is not advisable to use it. <p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p> - + <p><small>ساخته شده از اصلاح <a href="%1">2%</a> Git روی 3%، 4% با استفاده از Qt 5%، 6% </small></p> @@ -4044,7 +4045,7 @@ It is not advisable to use it. Server version downloaded, copied changed local file into conflict file - + نسخه سرور دانلود شد، پرونده محلی تغییر یافته به پرونده ناسازگار کپی شد @@ -4074,7 +4075,7 @@ It is not advisable to use it. Updated local metadata - + فرا داده محلی به روز رسانی شده @@ -4116,7 +4117,7 @@ It is not advisable to use it. updating local metadata - + فرا داده محلی به روز رسانی شده @@ -4124,7 +4125,7 @@ It is not advisable to use it. Status undefined - + وضعیت نامشخص است @@ -4177,22 +4178,22 @@ It is not advisable to use it. Could not open browser - + مرورگر باز نمی شود There was an error when launching the browser to go to URL %1. Maybe no default browser is configured? - + در راه اندازی مرورگر برای رفتن به آدرس 1% خطایی وجود دارد. شاید مرورگر پیش فرض پیکربندی نشده است؟ Could not open email client - + پست الکترونیکی مشتری باز نمی شود There was an error when launching the email client to create a new message. Maybe no default email client is configured? - + در راه اندازی پست الکترونیکی مشتری برای ساخت یک پیام جدید خطایی وجود دارد. شاید پست الکترونیکی مشتری پیش فرض پیکربندی نشده است؟ \ No newline at end of file From f89676d4bb2df9e2973e670eb96db955319fffcd Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Tue, 2 Jan 2018 02:18:36 +0100 Subject: [PATCH 040/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_es.ts | 14 +++++++------- translations/client_fa.ts | 6 +++--- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index 7d917da4f..e1db9b1a2 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -134,6 +134,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_es.ts b/translations/client_es.ts index 0d468b8bc..75645e499 100644 --- a/translations/client_es.ts +++ b/translations/client_es.ts @@ -283,7 +283,7 @@ There are folders that were not synchronized because they are too big or external storages: - Hay carpetas que no fueron sincronizadas porque son demasiado grandes o residen en almacenes externos: + Hay carpetas que no fueron sincronizadas porque son demasiado grandes o residen en almacenamiento externo: @@ -1244,7 +1244,7 @@ Si continua con la sincronización todos los archivos serán remplazados por su Ask for confirmation before synchronizing external storages - Preguntar si se desea sincronizar carpetas de almacenes externos + Preguntar si se desea sincronizar carpetas de almacenamiento externo @@ -3462,7 +3462,7 @@ No se recomienda usarla. <p>Version %1. For more information please visit <a href='%2'>%3</a>.</p> - <p>Versión %1. Para obtener más información, visita<a href='%2'>%3</a>.</p> + <p>Versión %1. Para obtener más información, visita <a href='%2'>%3</a>.</p> @@ -3643,7 +3643,7 @@ No se recomienda usarla. Unpause all folders - Despausar todas las carpetas + Reanudar todas las carpetas @@ -3653,12 +3653,12 @@ No se recomienda usarla. Unpause all synchronization - Despausar todas las sincronizaciones + Reanudar toda la sincronización Unpause synchronization - Despausar la sincronización + Reanudar la sincronización @@ -3782,7 +3782,7 @@ No se recomienda usarla. Ask for confirmation before synchronizing e&xternal storages - Preguntar si se desea sincronizar carpetas de almacenes e&xternos + Preguntar si se desea sincronizar carpetas de almacenamiento e&xterno diff --git a/translations/client_fa.ts b/translations/client_fa.ts index 9c54cee6b..63260f018 100644 --- a/translations/client_fa.ts +++ b/translations/client_fa.ts @@ -2653,7 +2653,7 @@ It is not advisable to use it. &Create new - + ایجاد جدید @@ -2689,7 +2689,7 @@ It is not advisable to use it. P&assword protect - + رمز عبور محافظت می شود @@ -2775,7 +2775,7 @@ It is not advisable to use it. Public sh&aring requires a password - + اشتراک عمومی نیازمند رمز عبور است From e2d4a386397d721cc19b582c3961d0cb9ee50cb7 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Wed, 3 Jan 2018 02:18:34 +0100 Subject: [PATCH 041/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index e1db9b1a2..b5a63a95f 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -137,6 +137,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From c0c10fd5f13eb774303943166be3ecd4803c42f1 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Thu, 4 Jan 2018 02:18:34 +0100 Subject: [PATCH 042/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index b5a63a95f..524d6b6ca 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -140,6 +140,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From ab9d6285c6b2aa118c39006d8d1b5c091b848a1a Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Sun, 5 Nov 2017 19:50:09 +0100 Subject: [PATCH 043/138] Proxy: Hostname validation and reconnection on setting change Where 'validation' currently just means "check whether it's empty". Code adapted from wiggiBe's original PR #6140 --- src/gui/accountstate.cpp | 7 +++++++ src/gui/accountstate.h | 10 ++++++++++ src/gui/networksettings.cpp | 21 +++++++++++++++++++++ src/gui/networksettings.h | 3 +++ 4 files changed, 41 insertions(+) diff --git a/src/gui/accountstate.cpp b/src/gui/accountstate.cpp index 0b19f3f88..a4b44b6a7 100644 --- a/src/gui/accountstate.cpp +++ b/src/gui/accountstate.cpp @@ -151,6 +151,13 @@ void AccountState::signOutByUi() setState(SignedOut); } +void AccountState::freshConnectionAttempt() +{ + if (isConnected()) + setState(Disconnected); + checkConnectivity(); +} + void AccountState::signIn() { if (_state == SignedOut) { diff --git a/src/gui/accountstate.h b/src/gui/accountstate.h index 3256424af..0ee6ec96a 100644 --- a/src/gui/accountstate.h +++ b/src/gui/accountstate.h @@ -105,6 +105,16 @@ public: * for the account and forgets the password. */ void signOutByUi(); + /** Tries to connect from scratch. + * + * Does nothing for signed out accounts. + * Connected accounts will be disconnected and try anew. + * Disconnected accounts will go to checkConnectivity(). + * + * Useful for when network settings (proxy) change. + */ + void freshConnectionAttempt(); + /// Move from SignedOut state to Disconnected (attempting to connect) void signIn(); diff --git a/src/gui/networksettings.cpp b/src/gui/networksettings.cpp index a981d80c5..018384f1a 100644 --- a/src/gui/networksettings.cpp +++ b/src/gui/networksettings.cpp @@ -20,8 +20,11 @@ #include "application.h" #include "configfile.h" #include "folderman.h" +#include "accountmanager.h" #include +#include +#include namespace OCC { @@ -73,6 +76,10 @@ NetworkSettings::NetworkSettings(QWidget *parent) connect(_ui->autoDownloadLimitRadioButton, &QAbstractButton::clicked, this, &NetworkSettings::saveBWLimitSettings); connect(_ui->downloadSpinBox, static_cast(&QSpinBox::valueChanged), this, &NetworkSettings::saveBWLimitSettings); connect(_ui->uploadSpinBox, static_cast(&QSpinBox::valueChanged), this, &NetworkSettings::saveBWLimitSettings); + + // Warn about empty proxy host + connect(_ui->hostLineEdit, &QLineEdit::textChanged, this, &NetworkSettings::checkEmptyProxyHost); + checkEmptyProxyHost(); } NetworkSettings::~NetworkSettings() @@ -150,6 +157,7 @@ void NetworkSettings::saveProxySettings() { ConfigFile cfgFile; + checkEmptyProxyHost(); if (_ui->noProxyRadioButton->isChecked()) { cfgFile.setProxyType(QNetworkProxy::NoProxy); } else if (_ui->systemProxyRadioButton->isChecked()) { @@ -170,6 +178,10 @@ void NetworkSettings::saveProxySettings() // ...and set the folders dirty, they refresh their proxy next time they // start the sync. FolderMan::instance()->setDirtyProxy(true); + + for (auto account : AccountManager::instance()->accounts()) { + account->freshConnectionAttempt(); + } } void NetworkSettings::saveBWLimitSettings() @@ -196,4 +208,13 @@ void NetworkSettings::saveBWLimitSettings() FolderMan::instance()->setDirtyNetworkLimits(); } +void NetworkSettings::checkEmptyProxyHost() +{ + if (_ui->hostLineEdit->isEnabled() && _ui->hostLineEdit->text().isEmpty()) { + _ui->hostLineEdit->setStyleSheet("border: 1px solid red"); + } else { + _ui->hostLineEdit->setStyleSheet(QString()); + } +} + } // namespace OCC diff --git a/src/gui/networksettings.h b/src/gui/networksettings.h index 34419a261..7201d1109 100644 --- a/src/gui/networksettings.h +++ b/src/gui/networksettings.h @@ -41,6 +41,9 @@ private slots: void saveProxySettings(); void saveBWLimitSettings(); + /// Red marking of host field if empty and enabled + void checkEmptyProxyHost(); + private: void loadProxySettings(); void loadBWLimitSettings(); From 15803d18379296abc83e17d448d50a9165eba835 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Fri, 5 Jan 2018 02:18:35 +0100 Subject: [PATCH 044/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 524d6b6ca..816062d4c 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -143,6 +143,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From 7aa9af08c35e5e777858f2a2c5e8b247e2601f40 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Thu, 4 Jan 2018 13:53:27 +0100 Subject: [PATCH 045/138] Issues: Speed up insertion and add hard upper limit #6272 Since sorting was enabled permanenty the list would be resorted with each inserted issue. When inserting thousands of ignored files that would make the whole ui freeze up. Instead, sorting is disabled for inserts now and is reenabled after some time has passed. That way users usually see the sorted view without the lockups. Also, there's now a maximum of 50k issue entries. --- src/gui/issueswidget.cpp | 24 ++++++++++++++++++++++-- src/gui/issueswidget.h | 4 ++++ src/gui/issueswidget.ui | 7 +++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/gui/issueswidget.cpp b/src/gui/issueswidget.cpp index c132ff925..0ebb5da33 100644 --- a/src/gui/issueswidget.cpp +++ b/src/gui/issueswidget.cpp @@ -38,6 +38,12 @@ namespace OCC { +/** + * If more issues are reported than this they will not show up + * to avoid performance issues around sorting this many issues. + */ +static const int maxIssueCount = 50000; + IssuesWidget::IssuesWidget(QWidget *parent) : QWidget(parent) , _ui(new Ui::IssuesWidget) @@ -96,6 +102,14 @@ IssuesWidget::IssuesWidget(QWidget *parent) #if defined(Q_OS_MAC) _ui->_treeWidget->setMinimumWidth(400); #endif + + _reenableSorting.setInterval(5000); + connect(&_reenableSorting, &QTimer::timeout, this, + [this]() { _ui->_treeWidget->setSortingEnabled(true); }); + + _ui->_tooManyIssuesWarning->hide(); + connect(this, &IssuesWidget::issueCountUpdated, this, + [this](int count) { _ui->_tooManyIssuesWarning->setVisible(count >= maxIssueCount); }); } IssuesWidget::~IssuesWidget() @@ -153,11 +167,17 @@ void IssuesWidget::addItem(QTreeWidgetItem *item) if (!item) return; - int insertLoc = 0; + int count = _ui->_treeWidget->topLevelItemCount(); + if (count >= maxIssueCount) + return; + + _ui->_treeWidget->setSortingEnabled(false); + _reenableSorting.start(); // Insert item specific errors behind the others + int insertLoc = 0; if (!item->text(1).isEmpty()) { - for (int i = 0; i < _ui->_treeWidget->topLevelItemCount(); ++i) { + for (int i = 0; i < count; ++i) { if (_ui->_treeWidget->topLevelItem(i)->text(1).isEmpty()) { insertLoc = i + 1; } else { diff --git a/src/gui/issueswidget.h b/src/gui/issueswidget.h index 4accd89b2..56f4900d9 100644 --- a/src/gui/issueswidget.h +++ b/src/gui/issueswidget.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "progressdispatcher.h" #include "owncloudgui.h" @@ -84,6 +85,9 @@ private: /// Wipes all insufficient remote storgage blacklist entries void retryInsufficentRemoteStorageErrors(const QString &folderAlias); + /// Each insert disables sorting, this timer reenables it + QTimer _reenableSorting; + Ui::IssuesWidget *_ui; }; } diff --git a/src/gui/issueswidget.ui b/src/gui/issueswidget.ui index 2d1161e78..73acf809a 100644 --- a/src/gui/issueswidget.ui +++ b/src/gui/issueswidget.ui @@ -127,6 +127,13 @@ + + + + There were too many issues. Not all will be visible here. + + + From 3988f3ad77b59d88b3b1e853bbb590c4eb514c54 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 5 Jan 2018 09:43:53 +0100 Subject: [PATCH 046/138] GCC: Fix implicit-fallthrough warnings --- src/common/c_jhash.h | 1 + src/csync/csync_reconcile.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/c_jhash.h b/src/common/c_jhash.h index 699244a0d..cd1549d7e 100644 --- a/src/common/c_jhash.h +++ b/src/common/c_jhash.h @@ -207,6 +207,7 @@ static inline uint64_t c_jhash64(const uint8_t *k, uint64_t length, uint64_t int /* handle the last 23 bytes */ c += length; switch(len) { +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" case 23: c+=((uint64_t)k[22]<<56); case 22: c+=((uint64_t)k[21]<<48); case 21: c+=((uint64_t)k[20]<<40); diff --git a/src/csync/csync_reconcile.cpp b/src/csync/csync_reconcile.cpp index f7e30785e..3324b8f76 100644 --- a/src/csync/csync_reconcile.cpp +++ b/src/csync/csync_reconcile.cpp @@ -279,7 +279,7 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) { /* If the file already exist on the other side, we have a conflict. Abort the rename and consider it is a new file. */ cur->instruction = CSYNC_INSTRUCTION_NEW; - /* fall trough */ + /* fall through */ /* file on current replica is changed or new */ case CSYNC_INSTRUCTION_EVAL: case CSYNC_INSTRUCTION_NEW: From 86377aa37a80e11ae6654b54aaa9e9a720c38d3e Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 5 Jan 2018 09:44:20 +0100 Subject: [PATCH 047/138] Folder: Remove unused 'dirty proxy' setting --- src/gui/folder.cpp | 14 -------------- src/gui/folder.h | 4 ---- src/gui/folderman.cpp | 4 +--- src/gui/folderman.h | 2 +- src/gui/networksettings.cpp | 2 +- 5 files changed, 3 insertions(+), 23 deletions(-) diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index d854f92ca..986af370d 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -52,7 +52,6 @@ Folder::Folder(const FolderDefinition &definition, , _accountState(accountState) , _definition(definition) , _csyncUnavail(false) - , _proxyDirty(true) , _lastSyncDuration(0) , _consecutiveFailingSyncs(0) , _consecutiveFollowUpSyncs(0) @@ -600,22 +599,9 @@ bool Folder::reloadExcludes() return _engine->excludedFiles().reloadExcludeFiles(); } -void Folder::setProxyDirty(bool value) -{ - _proxyDirty = value; -} - -bool Folder::proxyDirty() -{ - return _proxyDirty; -} - void Folder::startSync(const QStringList &pathList) { Q_UNUSED(pathList) - if (proxyDirty()) { - setProxyDirty(false); - } if (isBusy()) { qCCritical(lcFolder) << "ERROR csync is still running and new sync requested."; diff --git a/src/gui/folder.h b/src/gui/folder.h index 8ffa1e6d5..f2c2b1272 100644 --- a/src/gui/folder.h +++ b/src/gui/folder.h @@ -276,9 +276,6 @@ public slots: */ void startSync(const QStringList &pathList = QStringList()); - void setProxyDirty(bool value); - bool proxyDirty(); - int slotDiscardDownloadProgress(); int downloadInfoCount(); int slotWipeErrorBlacklist(); @@ -351,7 +348,6 @@ private: SyncResult _syncResult; QScopedPointer _engine; bool _csyncUnavail; - bool _proxyDirty; QPointer _requestEtagJob; QString _lastEtag; QElapsedTimer _timeSinceLastSyncDone; diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp index 7e5174700..adfe08110 100644 --- a/src/gui/folderman.cpp +++ b/src/gui/folderman.cpp @@ -1084,12 +1084,10 @@ bool FolderMan::startFromScratch(const QString &localFolder) return true; } -void FolderMan::setDirtyProxy(bool value) +void FolderMan::setDirtyProxy() { foreach (Folder *f, _folderMap.values()) { if (f) { - f->setProxyDirty(value); - if (f->accountState() && f->accountState()->account() && f->accountState()->account()->networkAccessManager()) { // Need to do this so we do not use the old determined system proxy diff --git a/src/gui/folderman.h b/src/gui/folderman.h index 415118689..44291dd74 100644 --- a/src/gui/folderman.h +++ b/src/gui/folderman.h @@ -178,7 +178,7 @@ public: /** Queues all folders for syncing. */ void scheduleAllFolders(); - void setDirtyProxy(bool value = true); + void setDirtyProxy(); void setDirtyNetworkLimits(); /** diff --git a/src/gui/networksettings.cpp b/src/gui/networksettings.cpp index 018384f1a..6305dc3a3 100644 --- a/src/gui/networksettings.cpp +++ b/src/gui/networksettings.cpp @@ -177,7 +177,7 @@ void NetworkSettings::saveProxySettings() // ...and set the folders dirty, they refresh their proxy next time they // start the sync. - FolderMan::instance()->setDirtyProxy(true); + FolderMan::instance()->setDirtyProxy(); for (auto account : AccountManager::instance()->accounts()) { account->freshConnectionAttempt(); From 0f8790d9936039efb0c6484cad41093b195f5414 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 5 Jan 2018 10:12:25 +0100 Subject: [PATCH 048/138] owncloudcmd: Remove some dead code --- src/cmd/cmd.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/cmd/cmd.cpp b/src/cmd/cmd.cpp index a1375a352..12bc4e972 100644 --- a/src/cmd/cmd.cpp +++ b/src/cmd/cmd.cpp @@ -480,11 +480,6 @@ restart_sync: } } else { clientProxy.setupQtProxyFromConfig(); - QString url(options.target_url); - if (url.startsWith("owncloud")) { - url.remove(0, 8); - url = QString("http%1").arg(url); - } } QStringList selectiveSyncList; From d0e7f61db62b52af9c94e9a97e1d201a09c2bd1a Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 5 Jan 2018 10:23:29 +0100 Subject: [PATCH 049/138] owncloudcmd: Set proxy earlier #6281 In particular before the capability call. Also warn if no proxy is set because the command line doesn't follow the strict format requirements. --- src/cmd/cmd.cpp | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/cmd/cmd.cpp b/src/cmd/cmd.cpp index 12bc4e972..e962dd4e0 100644 --- a/src/cmd/cmd.cpp +++ b/src/cmd/cmd.cpp @@ -420,6 +420,30 @@ int main(int argc, char **argv) folder.chop(1); } + if (!options.proxy.isNull()) { + QString host; + int port = 0; + bool ok; + + QStringList pList = options.proxy.split(':'); + if (pList.count() == 3) { + // http: //192.168.178.23 : 8080 + // 0 1 2 + host = pList.at(1); + if (host.startsWith("//")) + host.remove(0, 2); + + port = pList.at(2).toInt(&ok); + + QNetworkProxyFactory::setUseSystemConfiguration(false); + QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, host, port)); + } else { + qFatal("Could not read httpproxy. The proxy should have the format \"http://hostname:port\"."); + } + } else { + clientProxy.setupQtProxyFromConfig(); + } + SimpleSslErrorHandler *sslErrorHandler = new SimpleSslErrorHandler; HttpCredentialsText *cred = new HttpCredentialsText(user, password); @@ -457,31 +481,8 @@ int main(int argc, char **argv) int restartCount = 0; restart_sync: - opts = &options; - if (!options.proxy.isNull()) { - QString host; - int port = 0; - bool ok; - - QStringList pList = options.proxy.split(':'); - if (pList.count() == 3) { - // http: //192.168.178.23 : 8080 - // 0 1 2 - host = pList.at(1); - if (host.startsWith("//")) - host.remove(0, 2); - - port = pList.at(2).toInt(&ok); - - QNetworkProxyFactory::setUseSystemConfiguration(false); - QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, host, port)); - } - } else { - clientProxy.setupQtProxyFromConfig(); - } - QStringList selectiveSyncList; if (!options.unsyncedfolders.isEmpty()) { QFile f(options.unsyncedfolders); From f7c884d4d1442c4fe1fa1f6a357bd9f406633c0e Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 5 Jan 2018 10:12:25 +0100 Subject: [PATCH 050/138] owncloudcmd: Remove some dead code (cherry picked from commit 0f8790d9936039efb0c6484cad41093b195f5414) --- src/cmd/cmd.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/cmd/cmd.cpp b/src/cmd/cmd.cpp index a84aa82af..0a519e96d 100644 --- a/src/cmd/cmd.cpp +++ b/src/cmd/cmd.cpp @@ -480,11 +480,6 @@ restart_sync: } } else { clientProxy.setupQtProxyFromConfig(); - QString url(options.target_url); - if (url.startsWith("owncloud")) { - url.remove(0, 8); - url = QString("http%1").arg(url); - } } QStringList selectiveSyncList; From 81baebf113b725b91234e400bf4a2fce3f0281ed Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 5 Jan 2018 10:23:29 +0100 Subject: [PATCH 051/138] owncloudcmd: Set proxy earlier #6281 In particular before the capability call. Also warn if no proxy is set because the command line doesn't follow the strict format requirements. (cherry picked from commit d0e7f61db62b52af9c94e9a97e1d201a09c2bd1a) --- src/cmd/cmd.cpp | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/cmd/cmd.cpp b/src/cmd/cmd.cpp index 0a519e96d..9385fc791 100644 --- a/src/cmd/cmd.cpp +++ b/src/cmd/cmd.cpp @@ -420,6 +420,30 @@ int main(int argc, char **argv) folder.chop(1); } + if (!options.proxy.isNull()) { + QString host; + int port = 0; + bool ok; + + QStringList pList = options.proxy.split(':'); + if (pList.count() == 3) { + // http: //192.168.178.23 : 8080 + // 0 1 2 + host = pList.at(1); + if (host.startsWith("//")) + host.remove(0, 2); + + port = pList.at(2).toInt(&ok); + + QNetworkProxyFactory::setUseSystemConfiguration(false); + QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, host, port)); + } else { + qFatal("Could not read httpproxy. The proxy should have the format \"http://hostname:port\"."); + } + } else { + clientProxy.setupQtProxyFromConfig(); + } + SimpleSslErrorHandler *sslErrorHandler = new SimpleSslErrorHandler; HttpCredentialsText *cred = new HttpCredentialsText(user, password); @@ -457,31 +481,8 @@ int main(int argc, char **argv) int restartCount = 0; restart_sync: - opts = &options; - if (!options.proxy.isNull()) { - QString host; - int port = 0; - bool ok; - - QStringList pList = options.proxy.split(':'); - if (pList.count() == 3) { - // http: //192.168.178.23 : 8080 - // 0 1 2 - host = pList.at(1); - if (host.startsWith("//")) - host.remove(0, 2); - - port = pList.at(2).toInt(&ok); - - QNetworkProxyFactory::setUseSystemConfiguration(false); - QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, host, port)); - } - } else { - clientProxy.setupQtProxyFromConfig(); - } - QStringList selectiveSyncList; if (!options.unsyncedfolders.isEmpty()) { QFile f(options.unsyncedfolders); From 5656323434b97c47606e0764da8b7eec4604db85 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Sat, 6 Jan 2018 02:18:39 +0100 Subject: [PATCH 052/138] [tx-robot] updated from transifex --- mirall.desktop.in | 4 ++++ translations/client_ca.ts | 17 +++++++++++------ translations/client_cs.ts | 17 +++++++++++------ translations/client_de.ts | 17 +++++++++++------ translations/client_el.ts | 17 +++++++++++------ translations/client_en.ts | 17 +++++++++++------ translations/client_es.ts | 17 +++++++++++------ translations/client_es_AR.ts | 17 +++++++++++------ translations/client_et.ts | 17 +++++++++++------ translations/client_eu.ts | 17 +++++++++++------ translations/client_fa.ts | 17 +++++++++++------ translations/client_fi.ts | 17 +++++++++++------ translations/client_fr.ts | 17 +++++++++++------ translations/client_gl.ts | 17 +++++++++++------ translations/client_hu.ts | 17 +++++++++++------ translations/client_it.ts | 17 +++++++++++------ translations/client_ja.ts | 17 +++++++++++------ translations/client_nb_NO.ts | 17 +++++++++++------ translations/client_nl.ts | 17 +++++++++++------ translations/client_pl.ts | 17 +++++++++++------ translations/client_pt.ts | 17 +++++++++++------ translations/client_pt_BR.ts | 17 +++++++++++------ translations/client_ru.ts | 17 +++++++++++------ translations/client_sk.ts | 17 +++++++++++------ translations/client_sl.ts | 17 +++++++++++------ translations/client_sr.ts | 17 +++++++++++------ translations/client_sv.ts | 17 +++++++++++------ translations/client_th.ts | 17 +++++++++++------ translations/client_tr.ts | 17 +++++++++++------ translations/client_uk.ts | 17 +++++++++++------ translations/client_zh_CN.ts | 17 +++++++++++------ translations/client_zh_TW.ts | 17 +++++++++++------ 32 files changed, 345 insertions(+), 186 deletions(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index 816062d4c..a464cf354 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -146,6 +146,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion @@ -229,6 +232,7 @@ Icon[it]=@APPLICATION_EXECUTABLE@ Comment[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트 GenericName[ko]=폴더 동기화 Name[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트 +Icon[ko]=@APPLICATION_EXECUTABLE@ Comment[hu_HU]=@APPLICATION_NAME@ asztali szinkronizációs kliens GenericName[hu_HU]=Könyvtár szinkronizálás Name[hu_HU]=@APPLICATION_NAME@ asztali szinkr. kliens diff --git a/translations/client_ca.ts b/translations/client_ca.ts index 3dd48576a..bd2d99a06 100644 --- a/translations/client_ca.ts +++ b/translations/client_ca.ts @@ -1408,7 +1408,7 @@ Els elements que poden ser eliminats s'eliminaran si impedeixen que una car - + Folder Carpeta @@ -1423,27 +1423,32 @@ Els elements que poden ser eliminats s'eliminaran si impedeixen que una car - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Copiar - + Time Hora - + File Fitxer - + Issue diff --git a/translations/client_cs.ts b/translations/client_cs.ts index 909f61a03..03b86c918 100644 --- a/translations/client_cs.ts +++ b/translations/client_cs.ts @@ -1411,7 +1411,7 @@ Položky u kterých je povoleno smazání budou vymazány, pokud by bránily ods - + Folder Adresář @@ -1426,27 +1426,32 @@ Položky u kterých je povoleno smazání budou vymazány, pokud by bránily ods Ukázat ignorované soubory - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Kopie - + Time Čas - + File Soubor - + Issue Problém diff --git a/translations/client_de.ts b/translations/client_de.ts index 3f75f5db7..7207375ff 100644 --- a/translations/client_de.ts +++ b/translations/client_de.ts @@ -1413,7 +1413,7 @@ Objekte, bei denen Löschen erlaubt ist, werden gelöscht, wenn sie die Löschun - + Folder Ordner @@ -1428,27 +1428,32 @@ Objekte, bei denen Löschen erlaubt ist, werden gelöscht, wenn sie die Löschun Ignorierte Dateien anzeigen - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. Liste der Fehler in die Zwischenablage kopieren. - + Copy Kopieren - + Time Zeit - + File Datei - + Issue Fehler diff --git a/translations/client_el.ts b/translations/client_el.ts index 54d65ec3c..42a4bb04d 100644 --- a/translations/client_el.ts +++ b/translations/client_el.ts @@ -1413,7 +1413,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder Φάκελος @@ -1428,27 +1428,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Αντιγραφή - + Time Ώρα - + File Αρχείο - + Issue diff --git a/translations/client_en.ts b/translations/client_en.ts index 9c59d700e..0518e60d0 100644 --- a/translations/client_en.ts +++ b/translations/client_en.ts @@ -1434,7 +1434,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder @@ -1449,27 +1449,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy - + Time - + File - + Issue diff --git a/translations/client_es.ts b/translations/client_es.ts index 75645e499..2387361b6 100644 --- a/translations/client_es.ts +++ b/translations/client_es.ts @@ -1413,7 +1413,7 @@ Los elementos cuya eliminación está permitida serán eliminados si impiden que - + Folder Carpeta @@ -1428,27 +1428,32 @@ Los elementos cuya eliminación está permitida serán eliminados si impiden que Mostrar archivos ignorados - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. Copiar la lista de problemas al portapapeles. - + Copy Copiar - + Time Hora - + File Archivo - + Issue Problema diff --git a/translations/client_es_AR.ts b/translations/client_es_AR.ts index 193786e30..4efdac293 100644 --- a/translations/client_es_AR.ts +++ b/translations/client_es_AR.ts @@ -1402,7 +1402,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder Carpeta @@ -1417,27 +1417,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Copiar - + Time Hora - + File Archivo - + Issue diff --git a/translations/client_et.ts b/translations/client_et.ts index 8a687f3a9..b662dd20e 100644 --- a/translations/client_et.ts +++ b/translations/client_et.ts @@ -1402,7 +1402,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder Kaust @@ -1417,27 +1417,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Kopeeri - + Time Aeg - + File Fail - + Issue diff --git a/translations/client_eu.ts b/translations/client_eu.ts index 8361c94c4..91f125d1a 100644 --- a/translations/client_eu.ts +++ b/translations/client_eu.ts @@ -1404,7 +1404,7 @@ Ezabatzeko baimena duten itemak ezabatuko dira hauek karpeta bat ezabatzea uzten - + Folder Karpeta @@ -1419,27 +1419,32 @@ Ezabatzeko baimena duten itemak ezabatuko dira hauek karpeta bat ezabatzea uzten - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Kopiatu - + Time Noiz - + File Fitxategia - + Issue diff --git a/translations/client_fa.ts b/translations/client_fa.ts index 63260f018..f2cf68acf 100644 --- a/translations/client_fa.ts +++ b/translations/client_fa.ts @@ -1412,7 +1412,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder پوشه @@ -1427,27 +1427,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from نمایش پرونده های رد شده - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. کپی کردن فهرست موضوعات در کلیپ بورد. - + Copy کپی کردن - + Time زمان - + File فایل - + Issue موضوع diff --git a/translations/client_fi.ts b/translations/client_fi.ts index a8ac165ac..d69899e26 100644 --- a/translations/client_fi.ts +++ b/translations/client_fi.ts @@ -1404,7 +1404,7 @@ Kohteet, joiden poisto on sallittu, poistetaan, jos ne estävät kansion poistam - + Folder Kansio @@ -1419,27 +1419,32 @@ Kohteet, joiden poisto on sallittu, poistetaan, jos ne estävät kansion poistam - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Kopioi - + Time Aika - + File Tiedosto - + Issue diff --git a/translations/client_fr.ts b/translations/client_fr.ts index f475f7c23..9d0f40545 100644 --- a/translations/client_fr.ts +++ b/translations/client_fr.ts @@ -1414,7 +1414,7 @@ L'option "Autoriser suppression" permet de ne pas bloquer la supp - + Folder Dossier @@ -1429,27 +1429,32 @@ L'option "Autoriser suppression" permet de ne pas bloquer la supp Voir les fichiers ignorés - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. Copier la liste des anomalies dans le presse-papier. - + Copy Copier - + Time Heure - + File Fichier - + Issue Incident diff --git a/translations/client_gl.ts b/translations/client_gl.ts index 7ec393444..79611491c 100644 --- a/translations/client_gl.ts +++ b/translations/client_gl.ts @@ -1402,7 +1402,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder Cartafol @@ -1417,27 +1417,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Copiar - + Time Hora - + File Ficheiro - + Issue diff --git a/translations/client_hu.ts b/translations/client_hu.ts index f1cde2944..8d4fb385f 100644 --- a/translations/client_hu.ts +++ b/translations/client_hu.ts @@ -1402,7 +1402,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder Mappa @@ -1417,27 +1417,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Másolás - + Time Idő - + File Fájl - + Issue diff --git a/translations/client_it.ts b/translations/client_it.ts index 7ee834788..440555260 100644 --- a/translations/client_it.ts +++ b/translations/client_it.ts @@ -1409,7 +1409,7 @@ Gli elementi per i quali è consentita l'eliminazione, saranno eliminati se - + Folder Cartella @@ -1424,27 +1424,32 @@ Gli elementi per i quali è consentita l'eliminazione, saranno eliminati se Mostra i file ignorati - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. Copia la lista dei problemi negli appunti. - + Copy Copia - + Time Ora - + File File - + Issue Problema diff --git a/translations/client_ja.ts b/translations/client_ja.ts index b96ed51eb..28abe135f 100644 --- a/translations/client_ja.ts +++ b/translations/client_ja.ts @@ -1411,7 +1411,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder フォルダー @@ -1426,27 +1426,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy コピー - + Time 時刻 - + File ファイル - + Issue 課題 diff --git a/translations/client_nb_NO.ts b/translations/client_nb_NO.ts index 0487ff954..9573829d7 100644 --- a/translations/client_nb_NO.ts +++ b/translations/client_nb_NO.ts @@ -1412,7 +1412,7 @@ Elementer hvor sletting er tillatt, vil bli slettet hvis de forhindrer fjerning - + Folder Mappe @@ -1427,27 +1427,32 @@ Elementer hvor sletting er tillatt, vil bli slettet hvis de forhindrer fjerning - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Kopier - + Time Tid - + File Fil - + Issue diff --git a/translations/client_nl.ts b/translations/client_nl.ts index f34aa1dc0..53ee7ae1a 100644 --- a/translations/client_nl.ts +++ b/translations/client_nl.ts @@ -1417,7 +1417,7 @@ Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een ma - + Folder Map @@ -1432,27 +1432,32 @@ Onderdelen die gewist mogen worden worden verwijderd als ze voorkomen dat een ma Tonen genegeerde bestanden - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Kopiëren - + Time Tijd - + File Bestand - + Issue Probleem diff --git a/translations/client_pl.ts b/translations/client_pl.ts index cd205f306..b6772974f 100644 --- a/translations/client_pl.ts +++ b/translations/client_pl.ts @@ -1409,7 +1409,7 @@ Pozycje, dla których usuwanie jest dozwolone zostaną usunięte, jeżeli uprawn - + Folder Folder @@ -1424,27 +1424,32 @@ Pozycje, dla których usuwanie jest dozwolone zostaną usunięte, jeżeli uprawn - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Kopiuj - + Time Czas - + File Plik - + Issue diff --git a/translations/client_pt.ts b/translations/client_pt.ts index 35705b34f..062c246b7 100644 --- a/translations/client_pt.ts +++ b/translations/client_pt.ts @@ -1413,7 +1413,7 @@ Os itens onde é permitido a eliminação serão eliminados se estes impedirem a - + Folder Pasta @@ -1428,27 +1428,32 @@ Os itens onde é permitido a eliminação serão eliminados se estes impedirem a Mostrar ficheiros ignorados - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. Copiar a lista de situações para a área de transferência - + Copy Copiar - + Time Tempo - + File Ficheiro - + Issue Situação diff --git a/translations/client_pt_BR.ts b/translations/client_pt_BR.ts index e6c5c7608..98d8c0b9e 100644 --- a/translations/client_pt_BR.ts +++ b/translations/client_pt_BR.ts @@ -1412,7 +1412,7 @@ Itens onde a eliminação é permitida serão excluídos se eles evitarem que um - + Folder Pasta @@ -1427,27 +1427,32 @@ Itens onde a eliminação é permitida serão excluídos se eles evitarem que um Mostrar arquivos ignorados - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. Copie a lista de problemas para a área de transferência. - + Copy Copiar - + Time Horário - + File Arquivo - + Issue Problemas diff --git a/translations/client_ru.ts b/translations/client_ru.ts index 944313b65..9d5089fc3 100644 --- a/translations/client_ru.ts +++ b/translations/client_ru.ts @@ -1410,7 +1410,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder Папка @@ -1425,27 +1425,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from Показать игнорируемые файлы - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. Скопировать список проблем в буфер обмена. - + Copy Копировать - + Time Время - + File Файл - + Issue Проблема diff --git a/translations/client_sk.ts b/translations/client_sk.ts index 4d32078af..27a69743d 100644 --- a/translations/client_sk.ts +++ b/translations/client_sk.ts @@ -1402,7 +1402,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder Priečinok @@ -1417,27 +1417,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Kopírovať - + Time Čas - + File Súbor - + Issue diff --git a/translations/client_sl.ts b/translations/client_sl.ts index d0819235d..a047cf396 100644 --- a/translations/client_sl.ts +++ b/translations/client_sl.ts @@ -1413,7 +1413,7 @@ Predmeti na mestu, kjer je brisanje dovoljeno, bodo izbisani, v kolikor zaradi n - + Folder Mapa @@ -1428,27 +1428,32 @@ Predmeti na mestu, kjer je brisanje dovoljeno, bodo izbisani, v kolikor zaradi n Pokaži prezrte datoteke - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. Kopiraj seznam napak v odložišče. - + Copy Kopiraj - + Time Čas - + File Datoteka - + Issue Napaka diff --git a/translations/client_sr.ts b/translations/client_sr.ts index a039d862e..758f8dd4f 100644 --- a/translations/client_sr.ts +++ b/translations/client_sr.ts @@ -1402,7 +1402,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder фасцикла @@ -1417,27 +1417,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Копирај - + Time време - + File фајл - + Issue diff --git a/translations/client_sv.ts b/translations/client_sv.ts index 14c99f75c..a043fa655 100644 --- a/translations/client_sv.ts +++ b/translations/client_sv.ts @@ -1408,7 +1408,7 @@ Objekt som tillåter radering kommer tas bort om de förhindrar en mapp att tas - + Folder Mapp @@ -1423,27 +1423,32 @@ Objekt som tillåter radering kommer tas bort om de förhindrar en mapp att tas Visa ignorerade filer - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. Kopiera fellistan till klippbordet. - + Copy Kopiera - + Time Tid - + File Fil - + Issue Fel diff --git a/translations/client_th.ts b/translations/client_th.ts index 713eafbd2..2e8bafc75 100644 --- a/translations/client_th.ts +++ b/translations/client_th.ts @@ -1415,7 +1415,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder แฟ้มเอกสาร @@ -1430,27 +1430,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from แสดงไฟล์ที่ถูกเพิกเฉย - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. คัดลอกรายการปัญหาไปยังคลิปบอร์ด - + Copy คัดลอก - + Time เวลา - + File ไฟล์ - + Issue ปัญหา diff --git a/translations/client_tr.ts b/translations/client_tr.ts index 266abee13..b45e230c9 100644 --- a/translations/client_tr.ts +++ b/translations/client_tr.ts @@ -1404,7 +1404,7 @@ Bir dizinin silinmesine engel oluyorsa silmeye izin verilen yerlerdeki ögeler s - + Folder Klasör @@ -1419,27 +1419,32 @@ Bir dizinin silinmesine engel oluyorsa silmeye izin verilen yerlerdeki ögeler s - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Kopyala - + Time Zaman - + File Dosya - + Issue diff --git a/translations/client_uk.ts b/translations/client_uk.ts index 7e365b745..5908611ef 100644 --- a/translations/client_uk.ts +++ b/translations/client_uk.ts @@ -1402,7 +1402,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder Тека @@ -1417,27 +1417,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy Копіювати - + Time Час - + File Файл - + Issue diff --git a/translations/client_zh_CN.ts b/translations/client_zh_CN.ts index 764c31d8e..da672a37b 100644 --- a/translations/client_zh_CN.ts +++ b/translations/client_zh_CN.ts @@ -1413,7 +1413,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder 文件夹 @@ -1428,27 +1428,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy 复制 - + Time 时间 - + File 文件 - + Issue diff --git a/translations/client_zh_TW.ts b/translations/client_zh_TW.ts index 42ed3d14b..2bd356948 100644 --- a/translations/client_zh_TW.ts +++ b/translations/client_zh_TW.ts @@ -1404,7 +1404,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + Folder 資料夾 @@ -1419,27 +1419,32 @@ Items where deletion is allowed will be deleted if they prevent a directory from - + + There were too many issues. Not all will be visible here. + + + + Copy the issues list to the clipboard. - + Copy 複製 - + Time 時間 - + File 檔案 - + Issue From b6d74ad7535afaadb77fb02f17c8ffaeff9f0850 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Mon, 8 Jan 2018 02:18:35 +0100 Subject: [PATCH 053/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_pt_BR.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index a464cf354..010fff3b0 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -149,6 +149,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_pt_BR.ts b/translations/client_pt_BR.ts index 98d8c0b9e..50e982b06 100644 --- a/translations/client_pt_BR.ts +++ b/translations/client_pt_BR.ts @@ -1429,7 +1429,7 @@ Itens onde a eliminação é permitida serão excluídos se eles evitarem que um There were too many issues. Not all will be visible here. - + Havia muitos problemas. Nem todos serão visíveis aqui. From 51b662fdfeafea1035f2c33ab086619f8ec8e945 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Mon, 8 Jan 2018 09:32:38 +0100 Subject: [PATCH 054/138] Minor logging additions - Clearly mark local and remote discovery start, to make this searchable even without --logdebug. - Promote two messages from debug to info: The 'N entries read from db' message is useful and the 'read from db but ignored' message is rare and surprising - if there's a bug there we want to see what happened in the logs. --- src/csync/csync.cpp | 4 ++++ src/csync/csync_update.cpp | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/csync/csync.cpp b/src/csync/csync.cpp index 93438007a..60e600c2b 100644 --- a/src/csync/csync.cpp +++ b/src/csync/csync.cpp @@ -85,6 +85,8 @@ int csync_update(CSYNC *ctx) { csync_gettime(&start); ctx->current = LOCAL_REPLICA; + CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "## Starting local discovery ##"); + rc = csync_ftw(ctx, ctx->local.uri, csync_walker, MAX_DEPTH); if (rc < 0) { if(ctx->status_code == CSYNC_STATUS_OK) { @@ -104,6 +106,8 @@ int csync_update(CSYNC *ctx) { csync_gettime(&start); ctx->current = REMOTE_REPLICA; + CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "## Starting remote discovery ##"); + rc = csync_ftw(ctx, "", csync_walker, MAX_DEPTH); if (rc < 0) { if(ctx->status_code == CSYNC_STATUS_OK) { diff --git a/src/csync/csync_update.cpp b/src/csync/csync_update.cpp index b4787b2c1..74a53c84b 100644 --- a/src/csync/csync_update.cpp +++ b/src/csync/csync_update.cpp @@ -497,7 +497,7 @@ static bool fill_tree_from_db(CSYNC *ctx, const char *uri) * without a full remote discovery being triggered. */ CSYNC_EXCLUDE_TYPE excluded = csync_excluded_traversal(ctx, st->path, st->type); if (excluded != CSYNC_NOT_EXCLUDED) { - qDebug(lcUpdate, "%s excluded (%d)", st->path.constData(), excluded); + qInfo(lcUpdate, "%s excluded from db read (%d)", st->path.constData(), excluded); if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE || excluded == CSYNC_FILE_SILENTLY_EXCLUDED) { @@ -516,7 +516,7 @@ static bool fill_tree_from_db(CSYNC *ctx, const char *uri) ctx->status_code = CSYNC_STATUS_STATEDB_LOAD_ERROR; return false; } - qDebug(lcUpdate, "%" PRId64 " entries read below path %s from db.", count, uri); + qInfo(lcUpdate, "%" PRId64 " entries read below path %s from db.", count, uri); return true; } From 9078d9cfab357cc683c00d743b3f6f832d1ceaca Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Tue, 9 Jan 2018 02:18:35 +0100 Subject: [PATCH 055/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_ja.ts | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index 010fff3b0..f92e09413 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -152,6 +152,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_ja.ts b/translations/client_ja.ts index 28abe135f..d561319c2 100644 --- a/translations/client_ja.ts +++ b/translations/client_ja.ts @@ -1396,7 +1396,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from List of issues - 課題一覧 + 問題一覧 @@ -1418,12 +1418,12 @@ Items where deletion is allowed will be deleted if they prevent a directory from Show warnings - + 警告を表示 Show ignored files - + 除外ファイルを表示 @@ -1453,7 +1453,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from Issue - 課題 + 問題 @@ -2686,7 +2686,7 @@ It is not advisable to use it. Anyone with the link has access to the file/folder - リンクを知っている人はファイル/フォルダにアクセスできます + リンクを知っている人はファイル/フォルダーにアクセスできます From 585d2b20bdc5dcdb76c696b4e0306ddd3ce19329 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Tue, 19 Dec 2017 13:34:38 +0100 Subject: [PATCH 056/138] Exclude regex: Restore old matching on Windows #6245 Unfortunately matching behaved differently on Windows. This patch restores the previous matching behavior but still uses the new regular expression based matching. Further work will hopefully unify the behavior between platforms without breaking backwards compatibility. --- src/csync/csync_exclude.cpp | 71 ++++++++++-- src/csync/csync_exclude.h | 13 +++ .../csync/csync_tests/check_csync_exclude.cpp | 101 +++++++++++++++++- 3 files changed, 177 insertions(+), 8 deletions(-) diff --git a/src/csync/csync_exclude.cpp b/src/csync/csync_exclude.cpp index be3d80ae8..524daed27 100644 --- a/src/csync/csync_exclude.cpp +++ b/src/csync/csync_exclude.cpp @@ -241,6 +241,8 @@ using namespace OCC; ExcludedFiles::ExcludedFiles() { + // Windows used to use PathMatchSpec which allows *foo to match abc/deffoo. + _wildcardsMatchSlash = Utility::isWindows(); } ExcludedFiles::~ExcludedFiles() @@ -270,6 +272,12 @@ void ExcludedFiles::clearManualExcludes() reloadExcludeFiles(); } +void ExcludedFiles::setWildcardsMatchSlash(bool onoff) +{ + _wildcardsMatchSlash = onoff; + prepare(); +} + bool ExcludedFiles::reloadExcludeFiles() { _allExcludes.clear(); @@ -409,7 +417,12 @@ auto ExcludedFiles::csyncTraversalMatchFun() const return [this](const char *path, ItemType filetype) { return this->traversalPatternMatch(path, filetype); }; } -static QString convertToRegexpSyntax(QString exclude) +/** + * On linux we used to use fnmatch with FNM_PATHNAME, but the windows function we used + * didn't have that behavior. wildcardsMatchSlash can be used to control which behavior + * the resulting regex shall use. + */ +static QString convertToRegexpSyntax(QString exclude, bool wildcardsMatchSlash) { // Translate *, ?, [...] to their regex variants. // The escape sequences \*, \?, \[. \\ have a special meaning, @@ -433,11 +446,19 @@ static QString convertToRegexpSyntax(QString exclude) switch (exclude[i].unicode()) { case '*': flush(); - regex.append("[^/]*"); + if (wildcardsMatchSlash) { + regex.append(".*"); + } else { + regex.append("[^/]*"); + } break; case '?': flush(); - regex.append("[^/]"); + if (wildcardsMatchSlash) { + regex.append("."); + } else { + regex.append("[^/]"); + } break; case '[': { flush(); @@ -491,6 +512,42 @@ static QString convertToRegexpSyntax(QString exclude) return regex; } +static QString extractBnameTrigger(const QString &exclude, bool wildcardsMatchSlash) +{ + // We can definitely drop everything to the left of a / - that will never match + // any bname. + QString pattern = exclude.mid(exclude.lastIndexOf('/') + 1); + + // Easy case, nothing else can match a slash, so that's it. + if (!wildcardsMatchSlash) + return pattern; + + // Otherwise it's more complicated. Examples: + // - "foo*bar" can match "fooX/Xbar", pattern is "*bar" + // - "foo*bar*" can match "fooX/XbarX", pattern is "*bar*" + // - "foo?bar" can match "foo/bar" but also "fooXbar", pattern is "*bar" + + auto isWildcard = [](QChar c) { return c == QLatin1Char('*') || c == QLatin1Char('?'); }; + + // First, skip wildcards on the very right of the pattern + int i = pattern.size() - 1; + while (i >= 0 && isWildcard(pattern[i])) + --i; + + // Then scan further until the next wildcard that could match a / + while (i >= 0 && !isWildcard(pattern[i])) + --i; + + // Everything to the right is part of the pattern + pattern = pattern.mid(i + 1); + + // And if there was a wildcard, it starts with a * + if (i >= 0) + pattern.prepend('*'); + + return pattern; +} + void ExcludedFiles::prepare() { // Build regular expressions for the different cases. @@ -556,15 +613,15 @@ void ExcludedFiles::prepare() auto &fullFileDir = removeExcluded ? fullFileDirRemove : fullFileDirKeep; auto &fullDir = removeExcluded ? fullDirRemove : fullDirKeep; - auto regexExclude = convertToRegexpSyntax(QString::fromUtf8(exclude)); + auto regexExclude = convertToRegexpSyntax(QString::fromUtf8(exclude), _wildcardsMatchSlash); if (!fullPath) { regexAppend(bnameFileDir, bnameDir, regexExclude, matchDirOnly); } else { regexAppend(fullFileDir, fullDir, regexExclude, matchDirOnly); - // for activation, trigger on the 'bname' part of the full pattern - auto bnameExclude = exclude.mid(exclude.lastIndexOf('/') + 1); - auto regexBname = convertToRegexpSyntax(bnameExclude); + // For activation, trigger on the 'bname' part of the full pattern. + QString bnameExclude = extractBnameTrigger(exclude, _wildcardsMatchSlash); + auto regexBname = convertToRegexpSyntax(bnameExclude, true); regexAppend(bnameTriggerFileDir, bnameTriggerDir, regexBname, matchDirOnly); } } diff --git a/src/csync/csync_exclude.h b/src/csync/csync_exclude.h index 6f53e64a0..950a0f46f 100644 --- a/src/csync/csync_exclude.h +++ b/src/csync/csync_exclude.h @@ -109,6 +109,11 @@ public: */ void clearManualExcludes(); + /** + * Adjusts behavior of wildcards. Only used for testing. + */ + void setWildcardsMatchSlash(bool onoff); + /** * Generate a hook for traversal exclude pattern matching * that csync can use. @@ -200,6 +205,14 @@ private: bool _excludeConflictFiles = true; + /** + * Whether * and ? in patterns can match a / + * + * Unfortunately this was how matching was done on Windows so + * it continues to be enabled there. + */ + bool _wildcardsMatchSlash = false; + friend class ExcludedFilesTest; }; diff --git a/test/csync/csync_tests/check_csync_exclude.cpp b/test/csync/csync_tests/check_csync_exclude.cpp index 0062c2a39..41f3261d5 100644 --- a/test/csync/csync_tests/check_csync_exclude.cpp +++ b/test/csync/csync_tests/check_csync_exclude.cpp @@ -40,6 +40,7 @@ static int setup(void **state) { csync = new CSYNC("/tmp/check_csync1", new OCC::SyncJournalDb("")); excludedFiles = new ExcludedFiles; + excludedFiles->setWildcardsMatchSlash(false); csync->exclude_traversal_fn = excludedFiles->csyncTraversalMatchFun(); *state = csync; @@ -51,6 +52,7 @@ static int setup_init(void **state) { csync = new CSYNC("/tmp/check_csync1", new OCC::SyncJournalDb("")); excludedFiles = new ExcludedFiles; + excludedFiles->setWildcardsMatchSlash(false); csync->exclude_traversal_fn = excludedFiles->csyncTraversalMatchFun(); excludedFiles->addExcludeFilePath(EXCLUDE_LIST_FILE); @@ -429,7 +431,101 @@ static void check_csync_pathes(void **) assert_int_equal(check_dir_full("/excludepath/withsubdir/foo"), CSYNC_FILE_EXCLUDE_LIST); } -static void check_csync_is_windows_reserved_word(void **) { +static void check_csync_wildcards(void **) +{ + excludedFiles->addManualExclude("a/foo*bar"); + excludedFiles->addManualExclude("b/foo*bar*"); + excludedFiles->addManualExclude("c/foo?bar"); + excludedFiles->addManualExclude("d/foo?bar*"); + excludedFiles->addManualExclude("e/foo?bar?"); + excludedFiles->addManualExclude("g/bar*"); + excludedFiles->addManualExclude("h/bar?"); + + excludedFiles->setWildcardsMatchSlash(false); + + assert_int_equal(check_file_traversal("a/fooXYZbar"), CSYNC_FILE_EXCLUDE_LIST); + assert_int_equal(check_file_traversal("a/fooX/Zbar"), CSYNC_NOT_EXCLUDED); + + assert_int_equal(check_file_traversal("b/fooXYZbarABC"), CSYNC_FILE_EXCLUDE_LIST); + assert_int_equal(check_file_traversal("b/fooX/ZbarABC"), CSYNC_NOT_EXCLUDED); + + assert_int_equal(check_file_traversal("c/fooXbar"), CSYNC_FILE_EXCLUDE_LIST); + assert_int_equal(check_file_traversal("c/foo/bar"), CSYNC_NOT_EXCLUDED); + + assert_int_equal(check_file_traversal("d/fooXbarABC"), CSYNC_FILE_EXCLUDE_LIST); + assert_int_equal(check_file_traversal("d/foo/barABC"), CSYNC_NOT_EXCLUDED); + + assert_int_equal(check_file_traversal("e/fooXbarA"), CSYNC_FILE_EXCLUDE_LIST); + assert_int_equal(check_file_traversal("e/foo/barA"), CSYNC_NOT_EXCLUDED); + + assert_int_equal(check_file_traversal("g/barABC"), CSYNC_FILE_EXCLUDE_LIST); + assert_int_equal(check_file_traversal("g/XbarABC"), CSYNC_NOT_EXCLUDED); + + assert_int_equal(check_file_traversal("h/barZ"), CSYNC_FILE_EXCLUDE_LIST); + assert_int_equal(check_file_traversal("h/XbarZ"), CSYNC_NOT_EXCLUDED); + + excludedFiles->setWildcardsMatchSlash(true); + + assert_int_equal(check_file_traversal("a/fooX/Zbar"), CSYNC_FILE_EXCLUDE_LIST); + assert_int_equal(check_file_traversal("b/fooX/ZbarABC"), CSYNC_FILE_EXCLUDE_LIST); + assert_int_equal(check_file_traversal("c/foo/bar"), CSYNC_FILE_EXCLUDE_LIST); + assert_int_equal(check_file_traversal("d/foo/barABC"), CSYNC_FILE_EXCLUDE_LIST); + assert_int_equal(check_file_traversal("e/foo/barA"), CSYNC_FILE_EXCLUDE_LIST); +} + +static void check_csync_regex_translation(void **) +{ + QByteArray storage; + auto translate = [&storage](const char *pattern) { + storage = convertToRegexpSyntax(pattern, false).toUtf8(); + return storage.constData(); + }; + + assert_string_equal(translate(""), ""); + assert_string_equal(translate("abc"), "abc"); + assert_string_equal(translate("a*c"), "a[^/]*c"); + assert_string_equal(translate("a?c"), "a[^/]c"); + assert_string_equal(translate("a[xyz]c"), "a[xyz]c"); + assert_string_equal(translate("a[xyzc"), "a\\[xyzc"); + assert_string_equal(translate("a[!xyz]c"), "a[^xyz]c"); + assert_string_equal(translate("a\\*b\\?c\\[d\\\\e"), "a\\*b\\?c\\[d\\\\e"); + assert_string_equal(translate("a.c"), "a\\.c"); + assert_string_equal(translate("?𠜎?"), "[^/]\\𠜎[^/]"); // 𠜎 is 4-byte utf8 +} + +static void check_csync_bname_trigger(void **) +{ + bool wildcardsMatchSlash = false; + QByteArray storage; + auto translate = [&storage, &wildcardsMatchSlash](const char *pattern) { + storage = extractBnameTrigger(pattern, wildcardsMatchSlash).toUtf8(); + return storage.constData(); + }; + + assert_string_equal(translate(""), ""); + assert_string_equal(translate("a/b/"), ""); + assert_string_equal(translate("a/b/c"), "c"); + assert_string_equal(translate("c"), "c"); + assert_string_equal(translate("a/foo*"), "foo*"); + assert_string_equal(translate("a/abc*foo*"), "abc*foo*"); + + wildcardsMatchSlash = true; + + assert_string_equal(translate(""), ""); + assert_string_equal(translate("a/b/"), ""); + assert_string_equal(translate("a/b/c"), "c"); + assert_string_equal(translate("c"), "c"); + assert_string_equal(translate("*"), "*"); + assert_string_equal(translate("a/foo*"), "foo*"); + assert_string_equal(translate("a/abc?foo*"), "*foo*"); + assert_string_equal(translate("a/abc*foo*"), "*foo*"); + assert_string_equal(translate("a/abc?foo?"), "*foo?"); + assert_string_equal(translate("a/abc*foo?*"), "*foo?*"); + assert_string_equal(translate("a/abc*/foo*"), "foo*"); +} + +static void check_csync_is_windows_reserved_word(void **) +{ assert_true(csync_is_windows_reserved_word("CON")); assert_true(csync_is_windows_reserved_word("con")); assert_true(csync_is_windows_reserved_word("CON.")); @@ -537,6 +633,9 @@ int torture_run_tests(void) cmocka_unit_test_setup_teardown(T::check_csync_excluded_traversal, T::setup_init, T::teardown), cmocka_unit_test_setup_teardown(T::check_csync_dir_only, T::setup, T::teardown), cmocka_unit_test_setup_teardown(T::check_csync_pathes, T::setup_init, T::teardown), + cmocka_unit_test_setup_teardown(T::check_csync_wildcards, T::setup, T::teardown), + cmocka_unit_test_setup_teardown(T::check_csync_regex_translation, T::setup, T::teardown), + cmocka_unit_test_setup_teardown(T::check_csync_bname_trigger, T::setup, T::teardown), cmocka_unit_test_setup_teardown(T::check_csync_is_windows_reserved_word, T::setup_init, T::teardown), cmocka_unit_test_setup_teardown(T::check_csync_excluded_performance, T::setup_init, T::teardown), cmocka_unit_test(T::check_csync_exclude_expand_escapes), From e389fcaecbd2cf7e4267f9e29252f5a674698d46 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Tue, 9 Jan 2018 11:33:43 +0100 Subject: [PATCH 057/138] Avatars: Use old location for servers <10 #6279 --- src/libsync/networkjobs.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libsync/networkjobs.cpp b/src/libsync/networkjobs.cpp index 6e2b81eb0..93766de1e 100644 --- a/src/libsync/networkjobs.cpp +++ b/src/libsync/networkjobs.cpp @@ -629,7 +629,11 @@ bool PropfindJob::finished() AvatarJob::AvatarJob(AccountPtr account, QObject *parent) : AbstractNetworkJob(account, QString(), parent) { - _avatarUrl = Utility::concatUrlPath(account->url(), QString("remote.php/dav/avatars/%1/128.png").arg(account->davUser())); + if (account->serverVersionInt() >= Account::makeServerVersion(10, 0, 0)) { + _avatarUrl = Utility::concatUrlPath(account->url(), QString("remote.php/dav/avatars/%1/128.png").arg(account->davUser())); + } else { + _avatarUrl = Utility::concatUrlPath(account->url(), QString("index.php/avatar/%1/128").arg(account->davUser())); + } } void AvatarJob::start() From 883deb1c5d404c37bb70ecd562e847fc32cdcf53 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Tue, 9 Jan 2018 12:28:06 +0100 Subject: [PATCH 058/138] Fix potential crash in Composite job destruction Sentry: https://sentry.io/owncloud/desktop-win-and-mac/issues/427476987/ --- src/libsync/owncloudpropagator.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libsync/owncloudpropagator.h b/src/libsync/owncloudpropagator.h index 9655e1ac4..1ab653d73 100644 --- a/src/libsync/owncloudpropagator.h +++ b/src/libsync/owncloudpropagator.h @@ -210,8 +210,9 @@ public: virtual ~PropagatorCompositeJob() { - qDeleteAll(_jobsToDo); - qDeleteAll(_runningJobs); + // Don't delete jobs in _jobsToDo and _runningJobs: they have parents + // that will be responsible for cleanup. Deleting them here would risk + // deleting something that has already been deleted by a shared parent. } void appendJob(PropagatorJob *job) From cdd8d109409934673a1daa9b9ace06b46635d48a Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Tue, 9 Jan 2018 11:41:39 +0100 Subject: [PATCH 059/138] Fix resizing crash when currentPage() is null Sentry: https://sentry.io/owncloud/desktop-win-and-mac/issues/425331770/ --- src/gui/folderwizard.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/folderwizard.cpp b/src/gui/folderwizard.cpp index 8e460653b..187e07bb1 100644 --- a/src/gui/folderwizard.cpp +++ b/src/gui/folderwizard.cpp @@ -568,10 +568,12 @@ void FolderWizard::resizeEvent(QResizeEvent *event) QWizard::resizeEvent(event); // workaround for QTBUG-22819: when the error label word wrap, the minimum height is not adjusted - int hfw = currentPage()->heightForWidth(currentPage()->width()); - if (currentPage()->height() < hfw) { - currentPage()->setMinimumSize(currentPage()->minimumSizeHint().width(), hfw); - setTitleFormat(titleFormat()); // And another workaround for QTBUG-3396 + if (auto page = currentPage()) { + int hfw = page->heightForWidth(page->width()); + if (page->height() < hfw) { + page->setMinimumSize(page->minimumSizeHint().width(), hfw); + setTitleFormat(titleFormat()); // And another workaround for QTBUG-3396 + } } } From a476c5420a0e7f2e6a9b1a76db3b9c1f0af40f08 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Wed, 10 Jan 2018 02:18:51 +0100 Subject: [PATCH 060/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_de.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index f92e09413..54d8f2b63 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -155,6 +155,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_de.ts b/translations/client_de.ts index 7207375ff..928134fcc 100644 --- a/translations/client_de.ts +++ b/translations/client_de.ts @@ -1430,7 +1430,7 @@ Objekte, bei denen Löschen erlaubt ist, werden gelöscht, wenn sie die Löschun There were too many issues. Not all will be visible here. - + Es gab zu viele Probleme. Nicht alle können hier dargestellt werden. From 7d70f1becb646040e2428c12bca9ec28596a50f8 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Wed, 10 Jan 2018 11:40:02 +0100 Subject: [PATCH 061/138] Ignore files that can't be encoded for the filesystem There's an upstream bug where QTextCodec::canEncode returns true even though it should be false. This works around that issue and adds a test. The original work was done in 72809ef5b1aeb578976e4360ed267ac1c4d71ea6 See #6287, #5676, #5719 See https://bugreports.qt.io/browse/QTBUG-6925 --- src/csync/csync_update.cpp | 14 ++++++++--- test/testsyncengine.cpp | 50 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/csync/csync_update.cpp b/src/csync/csync_update.cpp index 74a53c84b..458c8d918 100644 --- a/src/csync/csync_update.cpp +++ b/src/csync/csync_update.cpp @@ -150,10 +150,18 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr f } } - if (ctx->current == REMOTE_REPLICA && QTextCodec::codecForLocale()->mibEnum() != 106) { + auto localCodec = QTextCodec::codecForLocale(); + if (ctx->current == REMOTE_REPLICA && localCodec->mibEnum() != 106) { /* If the locale codec is not UTF-8, we must check that the filename from the server can - * be encoded in the local file system. */ - if (!QTextCodec::codecForLocale()->canEncode(QString::fromUtf8(fs->path))) { + * be encoded in the local file system. + * + * We cannot use QTextCodec::canEncode() since that can incorrectly return true, see + * https://bugreports.qt.io/browse/QTBUG-6925. + */ + QTextEncoder encoder(localCodec, QTextCodec::ConvertInvalidToNull); + if (encoder.fromUnicode(QString::fromUtf8(fs->path)).contains('\0')) { + qCDebug(lcUpdate, "cannot encode %s to local encoding %d", + fs->path.constData(), localCodec->mibEnum()); excluded = CSYNC_FILE_EXCLUDE_CANNOT_ENCODE; } } diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp index 10e5e9acd..22509388f 100644 --- a/test/testsyncengine.cpp +++ b/test/testsyncengine.cpp @@ -586,6 +586,56 @@ private slots: QVERIFY(localFileExists("A/.hidden")); QVERIFY(fakeFolder.currentRemoteState().find("B/.hidden")); } + + void testNoLocalEncoding() + { + auto utf8Locale = QTextCodec::codecForLocale(); + if (utf8Locale->mibEnum() != 106) { + QSKIP("Test only works for UTF8 locale"); + } + + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + // Utf8 locale can sync both + fakeFolder.remoteModifier().insert("A/tößt"); + fakeFolder.remoteModifier().insert("A/t𠜎t"); + QVERIFY(fakeFolder.syncOnce()); + QVERIFY(fakeFolder.currentLocalState().find("A/tößt")); + QVERIFY(fakeFolder.currentLocalState().find("A/t𠜎t")); + + // Try again with a locale that can represent ö but not 𠜎 (4-byte utf8). + QTextCodec::setCodecForLocale(QTextCodec::codecForName("ISO-8859-15")); + QVERIFY(QTextCodec::codecForLocale()->mibEnum() == 111); + + fakeFolder.remoteModifier().insert("B/tößt"); + fakeFolder.remoteModifier().insert("B/t𠜎t"); + QVERIFY(fakeFolder.syncOnce()); + QVERIFY(fakeFolder.currentLocalState().find("B/tößt")); + QVERIFY(!fakeFolder.currentLocalState().find("B/t𠜎t")); + QVERIFY(!fakeFolder.currentLocalState().find("B/t?t")); + QVERIFY(!fakeFolder.currentLocalState().find("B/t??t")); + QVERIFY(!fakeFolder.currentLocalState().find("B/t???t")); + QVERIFY(!fakeFolder.currentLocalState().find("B/t????t")); + QVERIFY(fakeFolder.syncOnce()); + QVERIFY(fakeFolder.currentRemoteState().find("B/tößt")); + QVERIFY(fakeFolder.currentRemoteState().find("B/t𠜎t")); + + // Try again with plain ascii + QTextCodec::setCodecForLocale(QTextCodec::codecForName("ASCII")); + QVERIFY(QTextCodec::codecForLocale()->mibEnum() == 3); + + fakeFolder.remoteModifier().insert("C/tößt"); + QVERIFY(fakeFolder.syncOnce()); + QVERIFY(!fakeFolder.currentLocalState().find("C/tößt")); + QVERIFY(!fakeFolder.currentLocalState().find("C/t??t")); + QVERIFY(!fakeFolder.currentLocalState().find("C/t????t")); + QVERIFY(fakeFolder.syncOnce()); + QVERIFY(fakeFolder.currentRemoteState().find("C/tößt")); + + QTextCodec::setCodecForLocale(utf8Locale); + } }; QTEST_GUILESS_MAIN(TestSyncEngine) From 9dc765142cd1181aa95d730b8d8872910275d23e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Weigert?= Date: Wed, 10 Jan 2018 16:19:08 +0100 Subject: [PATCH 062/138] Update updater.cpp depricate suffix nightly, promote suffix daily --- src/gui/updater/updater.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/updater/updater.cpp b/src/gui/updater/updater.cpp index 6249ebc3e..8aff77f6f 100644 --- a/src/gui/updater/updater.cpp +++ b/src/gui/updater/updater.cpp @@ -64,7 +64,8 @@ QUrl Updater::addQueryParams(const QUrl &url) QString suffix = QString::fromLatin1(MIRALL_STRINGIFY(MIRALL_VERSION_SUFFIX)); query.addQueryItem(QLatin1String("versionsuffix"), suffix); - if (suffix.startsWith("nightly") + if (suffix.startsWith("daily") + || suffix.startsWith("nightly") || suffix.startsWith("alpha") || suffix.startsWith("rc") || suffix.startsWith("beta")) { From a8ba3ee9e19b80c1dcca8fd763dfae32c3d34749 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 11 Jan 2018 14:32:49 +0100 Subject: [PATCH 063/138] Use docker for Linux CI --- Jenkinsfile | 79 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 8696042d4..9645c1ef4 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -6,46 +6,63 @@ // all possible error combinations. // See also the top comment in syncenginetestutils.h // +// We are building "Linux - GCC" with "make" and "Linux - Clang" with ninja, +// the combinations are more or less arbitrarily chosen. We just want to +// check that both compilers and both CMake generators work. It's +// unlikely that a specific generator only breaks with a specific +// compiler. + + +def linux = docker.image('dominikschmidt/owncloud-client-ci-image:latest') +def win32 = docker.image('guruz/docker-owncloud-client-win32:latest') node('CLIENT') { stage 'Checkout' checkout scm sh '''git submodule update --init''' - stage 'Qt5' - sh '''rm -rf build - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE="Debug" -DUNIT_TESTING=1 -DWITH_TESTING=1 -DCMAKE_PREFIX_PATH=/var/lib/jenkins/qt/5.6.2 .. - make -j4 - ctest -V --output-on-failure''' - - stage 'Qt5 - clang' - sh '''rm -rf build - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DUNIT_TESTING=1 -DWITH_TESTING=1 -DCMAKE_PREFIX_PATH=/var/lib/jenkins/qt/5.6.2 .. - make -j4 - ctest -V --output-on-failure''' + stage 'Linux - GCC' + linux.pull() + linux.inside { + sh ''' + export HOME="$(pwd)/home" + rm -rf build home + mkdir build + cd build + cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE="Debug" -DUNIT_TESTING=1 .. + make -j4 + ctest -V --output-on-failure + ''' + } + stage 'Linux - Clang' + linux.pull() + linux.inside { + sh ''' + export HOME="$(pwd)/home" + rm -rf build home + mkdir build + cd build + cmake -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE="Debug" -DUNIT_TESTING=1 .. + ninja -j4 + ctest -V --output-on-failure + ''' + } stage 'Win32' - def win32 = docker.image('guruz/docker-owncloud-client-win32:latest') - win32.pull() // make sure we have the latest available from Docker Hub - win32.inside { - sh ''' - rm -rf build-win32 - mkdir build-win32 - cd build-win32 - ../admin/win/download_runtimes.sh - cmake .. -DCMAKE_TOOLCHAIN_FILE=../admin/win/Toolchain-mingw32-openSUSE.cmake -DWITH_CRASHREPORTER=ON - make -j4 - make package - ctest . - ''' - } + win32.pull() // make sure we have the latest available from Docker Hub + win32.inside { + sh ''' + rm -rf build-win32 + mkdir build-win32 + cd build-win32 + ../admin/win/download_runtimes.sh + cmake .. -DCMAKE_TOOLCHAIN_FILE=../admin/win/Toolchain-mingw32-openSUSE.cmake -DWITH_CRASHREPORTER=ON + make -j4 + make package + ctest . + ''' + } // Stage 'macOS' TODO } - - From a253129fd6f50b1e4fe5caec255977c47682afe4 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 11 Jan 2018 16:11:06 +0100 Subject: [PATCH 064/138] Fix running tests until #6210 is fixed --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 9645c1ef4..eae819e9d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -31,7 +31,7 @@ node('CLIENT') { cd build cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE="Debug" -DUNIT_TESTING=1 .. make -j4 - ctest -V --output-on-failure + LC_ALL=C.UTF-8 ctest -V --output-on-failure ''' } @@ -45,7 +45,7 @@ node('CLIENT') { cd build cmake -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE="Debug" -DUNIT_TESTING=1 .. ninja -j4 - ctest -V --output-on-failure + LC_ALL=C.UTF-8 ctest -V --output-on-failure ''' } From dbf15fb8dcf5008b9c7c74df314146a05a95036a Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 11 Jan 2018 16:11:23 +0100 Subject: [PATCH 065/138] Make setLaunchOnStartup debug output more meaningful --- src/common/utility_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/utility_unix.cpp b/src/common/utility_unix.cpp index 2ccc88b9c..fa11aa67f 100644 --- a/src/common/utility_unix.cpp +++ b/src/common/utility_unix.cpp @@ -57,7 +57,7 @@ void setLaunchOnStartup_private(const QString &appName, const QString &guiName, QString desktopFileLocation = userAutoStartPath + appName + QLatin1String(".desktop"); if (enable) { if (!QDir().exists(userAutoStartPath) && !QDir().mkpath(userAutoStartPath)) { - qCWarning(lcUtility) << "Could not create autostart folder"; + qCWarning(lcUtility) << "Could not create autostart folder" << userAutoStartPath; return; } QFile iniFile(desktopFileLocation); From c22e3aaa4b2575ae40cd74b53a87830ab179d42f Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Fri, 12 Jan 2018 02:19:52 +0100 Subject: [PATCH 066/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_ru.ts | 2 +- translations/client_th.ts | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index 54d8f2b63..da7cd9995 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -158,6 +158,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_ru.ts b/translations/client_ru.ts index 9d5089fc3..e96cabbdb 100644 --- a/translations/client_ru.ts +++ b/translations/client_ru.ts @@ -1427,7 +1427,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from There were too many issues. Not all will be visible here. - + Было слишком много проблем. Не все будут видны здесь. diff --git a/translations/client_th.ts b/translations/client_th.ts index 2e8bafc75..afd5ef265 100644 --- a/translations/client_th.ts +++ b/translations/client_th.ts @@ -1432,7 +1432,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from There were too many issues. Not all will be visible here. - + มีปัญหามากเกินไป ทั้งหมดจะไม่ปรากฏที่นี่ From 01f3b82ea5f8f48346e3dc6d5cfcabbee5be4afa Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Fri, 12 Jan 2018 10:27:23 +0100 Subject: [PATCH 067/138] Move pulling docker images to their own stages --- Jenkinsfile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index eae819e9d..52c45ba96 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -21,8 +21,10 @@ node('CLIENT') { checkout scm sh '''git submodule update --init''' - stage 'Linux - GCC' + stage 'Linux - Pull Docker Image' linux.pull() + + stage 'Linux - GCC' linux.inside { sh ''' export HOME="$(pwd)/home" @@ -36,7 +38,6 @@ node('CLIENT') { } stage 'Linux - Clang' - linux.pull() linux.inside { sh ''' export HOME="$(pwd)/home" @@ -49,8 +50,10 @@ node('CLIENT') { ''' } + stage 'Win32 - Pull Docker Image' + win32.pull() + stage 'Win32' - win32.pull() // make sure we have the latest available from Docker Hub win32.inside { sh ''' rm -rf build-win32 From 4cf7ca41624a877154ed680db8259140839c112d Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Sat, 13 Jan 2018 02:18:33 +0100 Subject: [PATCH 068/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_et.ts | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index da7cd9995..5c365db3a 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -161,6 +161,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_et.ts b/translations/client_et.ts index b662dd20e..748eba1fe 100644 --- a/translations/client_et.ts +++ b/translations/client_et.ts @@ -2648,7 +2648,7 @@ Selle kasutamine pole soovitatav. &Create new - + &Loo uus @@ -2699,7 +2699,7 @@ Selle kasutamine pole soovitatav. %1 link - + %1 link @@ -2760,7 +2760,7 @@ Selle kasutamine pole soovitatav. Public link - + Avalik link From 776bbbf7b16ba2e30ad4de265d856445caf01e16 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 15 Dec 2017 11:07:53 +0100 Subject: [PATCH 069/138] Don't include sqlite3.h from headers So that sqlite is not part of the public interface of csync (and that the sqlite include path don't need to be passed when compiling libsync or gui) --- src/common/ownsql.cpp | 1 + src/common/ownsql.h | 5 +++-- src/common/syncjournaldb.cpp | 1 + src/csync/csync_private.h | 1 - src/gui/socketapi.cpp | 2 -- test/csync/csync_tests/check_csync_update.cpp | 1 + 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/common/ownsql.cpp b/src/common/ownsql.cpp index c4277a130..bcd9dd6b0 100644 --- a/src/common/ownsql.cpp +++ b/src/common/ownsql.cpp @@ -26,6 +26,7 @@ #include "ownsql.h" #include "common/utility.h" #include "common/asserts.h" +#include #define SQLITE_SLEEP_TIME_USEC 100000 #define SQLITE_REPEAT_COUNT 20 diff --git a/src/common/ownsql.h b/src/common/ownsql.h index bfff4b65d..1ad7e93b7 100644 --- a/src/common/ownsql.h +++ b/src/common/ownsql.h @@ -19,13 +19,14 @@ #ifndef OWNSQL_H #define OWNSQL_H -#include - #include #include #include "ocsynclib.h" +struct sqlite3; +struct sqlite3_stmt; + namespace OCC { /** diff --git a/src/common/syncjournaldb.cpp b/src/common/syncjournaldb.cpp index a40149d3a..63d2f7ef4 100644 --- a/src/common/syncjournaldb.cpp +++ b/src/common/syncjournaldb.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "common/syncjournaldb.h" #include "version.h" diff --git a/src/csync/csync_private.h b/src/csync/csync_private.h index 5463b7e40..f73a1b2d5 100644 --- a/src/csync/csync_private.h +++ b/src/csync/csync_private.h @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi.cpp index 0cdc9f0de..cc889b8f3 100644 --- a/src/gui/socketapi.cpp +++ b/src/gui/socketapi.cpp @@ -48,8 +48,6 @@ #include -#include - #include diff --git a/test/csync/csync_tests/check_csync_update.cpp b/test/csync/csync_tests/check_csync_update.cpp index 01681b7de..504ea2096 100644 --- a/test/csync/csync_tests/check_csync_update.cpp +++ b/test/csync/csync_tests/check_csync_update.cpp @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "csync_update.cpp" +#include #include "torture.h" From 48c55b7d29e3910510364f1e621144565a739621 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 14 Dec 2017 12:50:11 +0100 Subject: [PATCH 070/138] csync/std: don't build in a separate library There is no need to create a static library for the csync/std file, just put everything together in csync --- src/csync/CMakeLists.txt | 38 +++++++++++++++++------------------ src/csync/std/CMakeLists.txt | 39 ------------------------------------ src/csync/std/c_time.h | 4 +++- 3 files changed, 22 insertions(+), 59 deletions(-) delete mode 100644 src/csync/std/CMakeLists.txt diff --git a/src/csync/CMakeLists.txt b/src/csync/CMakeLists.txt index 701405431..a574f3311 100644 --- a/src/csync/CMakeLists.txt +++ b/src/csync/CMakeLists.txt @@ -23,26 +23,22 @@ find_package(SQLite3 3.8.0 REQUIRED) include(ConfigureChecks.cmake) include(../common/common.cmake) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - if (MEM_NULL_TESTS) add_definitions(-DCSYNC_MEM_NULL_TESTS) endif (MEM_NULL_TESTS) -add_subdirectory(std) - # Statically include sqlite set(CSYNC_PUBLIC_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/std ${CMAKE_SOURCE_DIR} CACHE INTERNAL "csync public include directories" ) set(CSYNC_PRIVATE_INCLUDE_DIRS ${SQLITE3_INCLUDE_DIRS} - ${CSTDLIB_PUBLIC_INCLUDE_DIRS} ${CMAKE_BINARY_DIR} ) @@ -52,7 +48,6 @@ set(CSYNC_LIBRARY ) set(CSYNC_LINK_LIBRARIES - ${CSTDLIB_LIBRARY} ${CSYNC_REQUIRED_LIBRARIES} ${SQLITE3_LIBRARIES} ) @@ -77,6 +72,13 @@ set(csync_SRCS csync_rename.cpp vio/csync_vio.cpp + + std/c_alloc.c + std/c_path.c + std/c_string.c + std/c_time.c + std/c_utf8.cpp + ) if (WIN32) @@ -89,16 +91,13 @@ else() ) endif() +if(NOT HAVE_ASPRINTF AND NOT HAVE___MINGW_ASPRINTF) + list(APPEND csync_SRCS std/asprintf.c) +endif() + configure_file(csync_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h) -set(csync_HDRS - ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h - csync.h - vio/csync_vio.h - vio/csync_vio_method.h - vio/csync_vio_module.h -) # Statically include sqlite if (USE_OUR_OWN_SQLITE3) @@ -112,14 +111,16 @@ if (USE_OUR_OWN_SQLITE3) endif() endif() -include_directories( - ${CSYNC_PUBLIC_INCLUDE_DIRS} - ${CSYNC_PRIVATE_INCLUDE_DIRS} -) add_library(${CSYNC_LIBRARY} SHARED ${common_SOURCES} ${csync_SRCS}) #add_library(${CSYNC_LIBRARY}_static STATIC ${csync_SRCS}) +target_include_directories( + ${CSYNC_LIBRARY} + PUBLIC ${CSYNC_PUBLIC_INCLUDE_DIRS} + PRIVATE ${CSYNC_PRIVATE_INCLUDE_DIRS} +) + generate_export_header( ${CSYNC_LIBRARY} EXPORT_MACRO_NAME OCSYNC_EXPORT EXPORT_FILE_NAME ocsynclib.h @@ -129,8 +130,7 @@ target_link_libraries(${CSYNC_LIBRARY} ${CSYNC_LINK_LIBRARIES}) #target_link_libraries(${CSYNC_LIBRARY}_static ${CSYNC_LINK_LIBRARIES}) if(ZLIB_FOUND) - target_link_libraries(${CSYNC_LIBRARY} ${ZLIB_LIBRARIES}) - include_directories(${ZLIB_INCLUDE_DIRS}) + target_link_libraries(${CSYNC_LIBRARY} ZLIB::ZLIB) endif(ZLIB_FOUND) find_package(Qt5Core REQUIRED) diff --git a/src/csync/std/CMakeLists.txt b/src/csync/std/CMakeLists.txt deleted file mode 100644 index fddd02e99..000000000 --- a/src/csync/std/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -project(cstdlib) - -set(CSTDLIB_PUBLIC_INCLUDE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR} - CACHE INTERNAL "cstdlib public include directories" -) - -set(CSTDLIB_LIBRARY - cstdlib - CACHE INTERNAL "cstdlib library" -) - -set(CSTDLIB_LINK_LIBRARIES - ${CSTDLIB_LIBRARY} -) - -set(cstdlib_SRCS - c_alloc.c - c_path.c - c_string.c - c_time.c - c_utf8.cpp -) - -if(NOT HAVE_ASPRINTF AND NOT HAVE___MINGW_ASPRINTF) - list(APPEND cstdlib_SRCS - asprintf.c - ) -endif() - -include_directories( - ${CSTDLIB_PUBLIC_INCLUDE_DIRS} -) - -add_library(${CSTDLIB_LIBRARY} STATIC ${cstdlib_SRCS}) -if(NOT WIN32) - add_definitions( -fPIC ) -endif() -qt5_use_modules(${CSTDLIB_LIBRARY} Core) diff --git a/src/csync/std/c_time.h b/src/csync/std/c_time.h index 67e7fcbad..dee1b0e2b 100644 --- a/src/csync/std/c_time.h +++ b/src/csync/std/c_time.h @@ -21,6 +21,8 @@ #ifndef _C_TIME_H #define _C_TIME_H +#include "ocsynclib.h" + #ifdef __cplusplus extern "C" { #endif @@ -58,7 +60,7 @@ struct timespec c_tspecdiff(struct timespec time1, struct timespec time0); */ double c_secdiff(struct timespec clock1, struct timespec clock0); -int c_utimes(const char *uri, const struct timeval *times); +OCSYNC_EXPORT int c_utimes(const char *uri, const struct timeval *times); #ifdef __cplusplus } From 257d8142b1af06e1a3892be5110b7b69e38a0659 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 14 Dec 2017 15:10:33 +0100 Subject: [PATCH 071/138] Build system: Get rid of QtVersionAbstraction.cmake Use modern cmake with target_link_libraries and Qt5:: that automatically add the include path and compile flags --- CMakeLists.txt | 35 ++------ cmake/modules/QtVersionAbstraction.cmake | 104 ----------------------- cmake/modules/Warnings.cmake | 1 - src/CMakeLists.txt | 5 ++ src/cmd/CMakeLists.txt | 3 +- src/crashreporter/CMakeLists.txt | 4 +- src/csync/CMakeLists.txt | 3 +- src/gui/CMakeLists.txt | 50 ++++++----- src/gui/application.cpp | 8 ++ src/libsync/CMakeLists.txt | 12 +-- src/libsync/discoveryphase.cpp | 1 - test/CMakeLists.txt | 8 +- test/owncloud_add_test.cmake | 10 +-- 13 files changed, 64 insertions(+), 180 deletions(-) delete mode 100644 cmake/modules/QtVersionAbstraction.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 9975452f9..132d93b1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,4 @@ - -cmake_minimum_required(VERSION 2.6) -cmake_policy(VERSION 2.8.0) -if(POLICY CMP0020) - cmake_policy(SET CMP0020 NEW) -endif() +cmake_minimum_required(VERSION 3.0) project(client) @@ -61,14 +56,6 @@ if(NOT WITH_CRASHREPORTER) message(STATUS "Build of crashreporter disabled.") endif() -##### -## handle DBUS for Fdo notifications -if( UNIX AND NOT APPLE ) - add_definitions( -DUSE_FDO_NOTIFICATIONS) - set(WITH_DBUS ON) -endif() -#### - include(GNUInstallDirs) include(DefineInstallationPaths) include(GenerateExportHeader) @@ -77,6 +64,12 @@ include(GetGitRevisionDescription) get_git_head_revision(GIT_REFSPEC GIT_SHA1) +add_definitions( + -DQT_USE_QSTRINGBUILDER + -DQT_MESSAGELOGCONTEXT #enable function name and line number in debug output + -DQT_DEPRECATED_WARNINGS +) + # if we cannot get it from git, directly try .tag (packages) # this will work if the tar balls have been properly created # via git-archive. @@ -218,20 +211,6 @@ add_definitions( -D_WIN32_WINNT=0x0600) add_definitions( -DWINVER=0x0600) endif( WIN32 ) -include(QtVersionAbstraction) -setup_qt() -if (${Qt5Core_VERSION_MAJOR} EQUAL "5") - if (${Qt5Core_VERSION_MINOR} EQUAL "6" OR ${Qt5Core_VERSION_MINOR} GREATER 6) - else() - message(FATAL_ERROR "Qt 5.6 or higher is required.") - endif() - if (${Qt5Core_VERSION_MINOR} EQUAL "9" OR ${Qt5Core_VERSION_MINOR} GREATER 9) - else() - message(STATUS "For HTTP2 use Qt 5.9.2 or higher.") - endif() -endif() -message("Qt ${Qt5Core_VERSION} at ${Qt5Core_INCLUDE_DIRS}") - if (APPLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") endif() diff --git a/cmake/modules/QtVersionAbstraction.cmake b/cmake/modules/QtVersionAbstraction.cmake deleted file mode 100644 index ce48b4487..000000000 --- a/cmake/modules/QtVersionAbstraction.cmake +++ /dev/null @@ -1,104 +0,0 @@ -# (c) 2014 Copyright ownCloud GmbH -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING* file. - -include (MacroOptionalFindPackage) -include (MacroLogFeature) - -find_package(Qt5Core REQUIRED) -find_package(Qt5Network REQUIRED) -find_package(Qt5Xml REQUIRED) -find_package(Qt5Concurrent REQUIRED) -if(UNIT_TESTING) - find_package(Qt5Test REQUIRED) -endif() - -if(NOT TOKEN_AUTH_ONLY) - find_package(Qt5Widgets REQUIRED) - if(APPLE) - find_package(Qt5MacExtras REQUIRED) - endif(APPLE) - - if(NOT NO_SHIBBOLETH) - find_package(Qt5WebKitWidgets) - find_package(Qt5WebKit) - if(NOT Qt5WebKitWidgets_FOUND) - message(FATAL_ERROR "Qt5WebKit required for Shibboleth. Use -DNO_SHIBBOLETH=1 to disable it.") - endif() - endif() -endif() - -# We need this to find the paths to qdbusxml2cpp and co -if (WITH_DBUS) - find_package(Qt5DBus REQUIRED) - include_directories(${Qt5DBus_INCLUDES}) - add_definitions(${Qt5DBus_DEFINITIONS}) -endif (WITH_DBUS) -include_directories(${Qt5Core_INCLUDES}) -add_definitions(${Qt5Core_DEFINITIONS}) -if (NOT WIN32) #implied on Win32 - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") -endif(NOT WIN32) -# set(CMAKE_CXX_FLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}") - -if(APPLE AND NOT TOKEN_AUTH_ONLY) - include_directories(${Qt5MacExtras_INCLUDE_DIRS}) - add_definitions(${Qt5MacExtras_DEFINITIONS}) - set (QT_LIBRARIES ${QT_LIBRARIES} ${Qt5MacExtras_LIBRARIES}) -endif() - -if(NOT BUILD_LIBRARIES_ONLY) - macro(qt_wrap_ui) - qt5_wrap_ui(${ARGN}) - endmacro() -else() - # hack - SET(QT_UIC_EXECUTABLE "") -endif() - -macro(qt_add_resources) - qt5_add_resources(${ARGN}) -endmacro() - -if(NOT TOKEN_AUTH_ONLY) - find_package(Qt5LinguistTools) - if(Qt5LinguistTools_FOUND) - macro(qt_add_translation) - qt5_add_translation(${ARGN}) - endmacro() - else() - macro(qt_add_translation) - endmacro() - endif() -else() - macro(qt_add_translation) - endmacro() -endif() - -macro(qt_add_dbus_interface) - qt5_add_dbus_interface(${ARGN}) -endmacro() - -macro(qt_add_dbus_adaptor) - qt5_add_dbus_adaptor(${ARGN}) -endmacro() - -macro(qt_wrap_cpp) - qt5_wrap_cpp(${ARGN}) -endmacro() - -macro(install_qt_executable) - install_qt5_executable(${ARGN}) -endmacro() - -macro(setup_qt) -endmacro() - -set(QT_RCC_EXECUTABLE "${Qt5Core_RCC_EXECUTABLE}") - -#Enable deprecated symbols -add_definitions("-DQT_DISABLE_DEPRECATED_BEFORE=0") -add_definitions("-DQT_DEPRECATED_WARNINGS") -add_definitions("-DQT_USE_QSTRINGBUILDER") #optimize string concatenation -add_definitions("-DQT_MESSAGELOGCONTEXT") #enable function name and line number in debug output - diff --git a/cmake/modules/Warnings.cmake b/cmake/modules/Warnings.cmake index 0edabd2a9..8faff001f 100644 --- a/cmake/modules/Warnings.cmake +++ b/cmake/modules/Warnings.cmake @@ -4,7 +4,6 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-long-long -Wno-gnu-zero-variadic-macro-arguments") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 894f93e4c..e20358c18 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,6 +4,11 @@ endif() set(synclib_NAME ${APPLICATION_EXECUTABLE}sync) +find_package(Qt5 5.6 COMPONENTS Core Network Xml Concurrent REQUIRED) +if (Qt5Core_VERSION VERSION_LESS 5.9.0) +message(STATUS "For HTTP/2 support, compile with Qt 5.9 or higher.") +endif() + if(NOT TOKEN_AUTH_ONLY) find_package(Qt5Keychain REQUIRED) endif() diff --git a/src/cmd/CMakeLists.txt b/src/cmd/CMakeLists.txt index 12fff82ce..4244fba8c 100644 --- a/src/cmd/CMakeLists.txt +++ b/src/cmd/CMakeLists.txt @@ -27,13 +27,12 @@ endif() if(NOT BUILD_LIBRARIES_ONLY) add_executable(${cmd_NAME} ${cmd_SRC}) - qt5_use_modules(${cmd_NAME} Network ) set_target_properties(${cmd_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} ) set_target_properties(${cmd_NAME} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE};${CMAKE_INSTALL_RPATH}" ) - target_link_libraries(${cmd_NAME} ${synclib_NAME}) + target_link_libraries(${cmd_NAME} ${synclib_NAME} Qt5::Core Qt5::Network) endif() if(BUILD_OWNCLOUD_OSX_BUNDLE) diff --git a/src/crashreporter/CMakeLists.txt b/src/crashreporter/CMakeLists.txt index b73e38fab..0d7938a34 100644 --- a/src/crashreporter/CMakeLists.txt +++ b/src/crashreporter/CMakeLists.txt @@ -32,14 +32,12 @@ if(NOT BUILD_LIBRARIES_ONLY) ${crashreporter_RC_RCC} ) - qt5_use_modules(${CRASHREPORTER_EXECUTABLE} Widgets Network) - set_target_properties(${CRASHREPORTER_EXECUTABLE} PROPERTIES AUTOMOC ON) set_target_properties(${CRASHREPORTER_EXECUTABLE} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} ) set_target_properties(${CRASHREPORTER_EXECUTABLE} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}" ) target_link_libraries(${CRASHREPORTER_EXECUTABLE} crashreporter-gui - ${QT_LIBRARIES} + Qt5::Core Qt5::Widgets ) if(BUILD_OWNCLOUD_OSX_BUNDLE) diff --git a/src/csync/CMakeLists.txt b/src/csync/CMakeLists.txt index a574f3311..2cf4e9600 100644 --- a/src/csync/CMakeLists.txt +++ b/src/csync/CMakeLists.txt @@ -50,6 +50,7 @@ set(CSYNC_LIBRARY set(CSYNC_LINK_LIBRARIES ${CSYNC_REQUIRED_LIBRARIES} ${SQLITE3_LIBRARIES} + Qt5::Core Qt5::Concurrent ) # Specific option for builds tied to servers that do not support renaming extensions @@ -133,8 +134,6 @@ if(ZLIB_FOUND) target_link_libraries(${CSYNC_LIBRARY} ZLIB::ZLIB) endif(ZLIB_FOUND) -find_package(Qt5Core REQUIRED) -qt5_use_modules(${CSYNC_LIBRARY} Core Concurrent) # For src/common/utility_mac.cpp if (APPLE) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index cee4cb457..b04159ad8 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -1,19 +1,21 @@ project(gui) +find_package(Qt5 REQUIRED COMPONENTS Widgets) set(CMAKE_AUTOMOC TRUE) - +set(CMAKE_AUTOUIC TRUE) +set(CMAKE_AUTORCC TRUE) add_subdirectory(updater) #TODO Move resources files -qt_add_resources(MIRALL_RC_SRC ../../client.qrc) +set(MIRALL_RC_SRC ../../client.qrc) if (EXISTS "${OEM_THEME_DIR}/theme.qrc") - qt_add_resources(MIRALL_RC_SRC ${OEM_THEME_DIR}/theme.qrc) + list(APPEND MIRALL_RC_SRC ${OEM_THEME_DIR}/theme.qrc) set(theme_dir ${OEM_THEME_DIR}/theme) else() - qt_add_resources(MIRALL_RC_SRC ../../theme.qrc) + list(APPEND MIRALL_RC_SRC ../../theme.qrc) set(theme_dir ${CMAKE_SOURCE_DIR}/theme) endif() -set(client_UI +set(client_UI_SRCS accountsettings.ui folderwizardsourcepage.ui folderwizardtargetpage.ui @@ -41,8 +43,6 @@ set(client_UI wizard/owncloudwizardresultpage.ui ) -qt_wrap_ui(client_UI_SRCS ${client_UI}) - set(client_SRCS accountmanager.cpp accountsettings.cpp @@ -191,8 +191,10 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) - -qt_add_translation(client_I18N ${TRANSLATIONS}) +find_package(Qt5LinguistTools) +if(Qt5LinguistTools_FOUND) + qt5_add_translation(client_I18N ${TRANSLATIONS}) +endif() IF( WIN32 ) configure_file( @@ -236,12 +238,7 @@ kde4_add_app_icon( ownCloud "${theme_dir}/colored/${APPLICATION_ICON_NAME}-*.png list(APPEND final_src ${ownCloud}) set(ownCloud ${ownCloud_old}) -if (WITH_DBUS) - set(ADDITIONAL_APP_MODULES DBus) -endif(WITH_DBUS) -if (NOT NO_SHIBBOLETH) - list(APPEND ADDITIONAL_APP_MODULES WebKitWidgets) -endif() + if(UNIX AND NOT APPLE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE") @@ -266,14 +263,12 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE) # add_executable( ${APPLICATION_EXECUTABLE} main.cpp ${final_src}) add_executable( ${APPLICATION_EXECUTABLE} WIN32 main.cpp ${final_src}) - qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml Sql ${ADDITIONAL_APP_MODULES}) else() # set(CMAKE_INSTALL_PREFIX ".") # Examples use /Applications. hurmpf. set(MACOSX_BUNDLE_ICON_FILE "ownCloud.icns") # we must add MACOSX_BUNDLE only if building a bundle add_executable( ${APPLICATION_EXECUTABLE} WIN32 MACOSX_BUNDLE main.cpp ${final_src}) - qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml Sql ${ADDITIONAL_APP_MODULES}) set (QM_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/Translations) install(FILES ${client_I18N} DESTINATION ${QM_DIR}) @@ -291,8 +286,7 @@ else() endif() add_library(updater STATIC ${updater_SRCS} ${updaterMoc}) -target_link_libraries(updater ${synclib_NAME}) -qt5_use_modules(updater Widgets Network Xml) +target_link_libraries(updater ${synclib_NAME} Qt5::Widgets Qt5::Network Qt5::Xml) set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} @@ -301,11 +295,23 @@ set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE};${CMAKE_INSTALL_RPATH}" ) -target_link_libraries( ${APPLICATION_EXECUTABLE} ${QT_LIBRARIES} ) +target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::Widgets Qt5::Network Qt5::Xml) target_link_libraries( ${APPLICATION_EXECUTABLE} ${synclib_NAME} ) target_link_libraries( ${APPLICATION_EXECUTABLE} updater ) target_link_libraries( ${APPLICATION_EXECUTABLE} ${OS_SPECIFIC_LINK_LIBRARIES} ) +## handle DBUS for Fdo notifications +if( UNIX AND NOT APPLE ) + find_package(Qt5 COMPONENTS DBus) + target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::DBus) + target_compile_definitions(${APPLICATION_EXECUTABLE} PRIVATE "USE_FDO_NOTIFICATIONS") +endif() + +if (NOT NO_SHIBBOLETH) + find_package(Qt5 COMPONENTS WebKitWidgets) + target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::WebKitWidgets) +endif() + if(WITH_CRASHREPORTER) target_link_libraries( ${APPLICATION_EXECUTABLE} crashreporter-handler) include_directories( "../3rdparty/libcrashreporter-qt/src/" ) @@ -316,6 +322,10 @@ if(WITH_CRASHREPORTER) endif() endif() +# application.cpp still uses QDesktopServices::storageLocation +target_compile_definitions(${APPLICATION_EXECUTABLE} PRIVATE "QT_DISABLE_DEPRECATED_BEFORE=0") + + install(TARGETS ${APPLICATION_EXECUTABLE} RUNTIME DESTINATION bin LIBRARY DESTINATION lib diff --git a/src/gui/application.cpp b/src/gui/application.cpp index 8f4b3f1ba..6280c04aa 100644 --- a/src/gui/application.cpp +++ b/src/gui/application.cpp @@ -128,7 +128,15 @@ Application::Application(int &argc, char **argv) if (!QFileInfo(confDir).exists()) { // Migrate from version <= 2.4 setApplicationName(_theme->appNameGUI()); +#ifndef QT_WARNING_DISABLE_DEPRECATED // Was added in Qt 5.9 +#define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_GCC("-Wdeprecated-declarations") +#endif + QT_WARNING_PUSH + QT_WARNING_DISABLE_DEPRECATED + // We need to use the deprecated QDesktopServices::storageLocation because of its Qt4 + // behavior of adding "data" to the path QString oldDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); + QT_WARNING_POP setApplicationName(_theme->appName()); if (QFileInfo(oldDir).isDir()) { qCInfo(lcApplication) << "Migrating old config from" << oldDir << "to" << confDir; diff --git a/src/libsync/CMakeLists.txt b/src/libsync/CMakeLists.txt index 93f3e4169..6b0633da5 100644 --- a/src/libsync/CMakeLists.txt +++ b/src/libsync/CMakeLists.txt @@ -95,11 +95,16 @@ IF (NOT APPLE) ENDIF(NOT APPLE) list(APPEND libsync_LINK_TARGETS - ${QT_LIBRARIES} ocsync ${OS_SPECIFIC_LINK_LIBRARIES} + Qt5::Core Qt5::Network ) +if (NOT TOKEN_AUTH_ONLY) + find_package(Qt5 REQUIRED COMPONENTS Widgets) + list(APPEND libsync_LINK_TARGETS Qt5::Widgets) +endif() + if(QTKEYCHAIN_FOUND OR QT5KEYCHAIN_FOUND) list(APPEND libsync_LINK_TARGETS ${QTKEYCHAIN_LIBRARY}) include_directories(${QTKEYCHAIN_INCLUDE_DIR}) @@ -118,11 +123,6 @@ GENERATE_EXPORT_HEADER( ${synclib_NAME} STATIC_DEFINE OWNCLOUD_BUILT_AS_STATIC ) -if(TOKEN_AUTH_ONLY) - qt5_use_modules(${synclib_NAME} Network) -else() - qt5_use_modules(${synclib_NAME} Widgets Network) -endif() set_target_properties( ${synclib_NAME} PROPERTIES VERSION ${MIRALL_VERSION} diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp index eb0ce8d3e..2cf096d4f 100644 --- a/src/libsync/discoveryphase.cpp +++ b/src/libsync/discoveryphase.cpp @@ -15,7 +15,6 @@ #include "discoveryphase.h" #include "account.h" -#include "theme.h" #include "common/asserts.h" #include "common/checksums.h" diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b23678543..4617dfd2e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,4 @@ -include_directories(${QT_INCLUDES} - ${CMAKE_SOURCE_DIR}/src +include_directories(${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/3rdparty/qtokenizer ${CMAKE_SOURCE_DIR}/src/csync ${CMAKE_SOURCE_DIR}/src/csync/std @@ -11,11 +10,6 @@ include_directories(${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR} ) -include_directories() - -include(QtVersionAbstraction) -setup_qt() - include(owncloud_add_test.cmake) owncloud_add_test(OwncloudPropagator "") diff --git a/test/owncloud_add_test.cmake b/test/owncloud_add_test.cmake index 7e7cc5057..ee2cfd200 100644 --- a/test/owncloud_add_test.cmake +++ b/test/owncloud_add_test.cmake @@ -1,17 +1,17 @@ +find_package(Qt5 COMPONENTS Core Test Xml Network REQUIRED) + macro(owncloud_add_test test_class additional_cpp) set(CMAKE_AUTOMOC TRUE) set(OWNCLOUD_TEST_CLASS ${test_class}) string(TOLOWER "${OWNCLOUD_TEST_CLASS}" OWNCLOUD_TEST_CLASS_LOWERCASE) add_executable(${OWNCLOUD_TEST_CLASS}Test test${OWNCLOUD_TEST_CLASS_LOWERCASE}.cpp ${additional_cpp}) - qt5_use_modules(${OWNCLOUD_TEST_CLASS}Test Test Sql Xml Network) set_target_properties(${OWNCLOUD_TEST_CLASS}Test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}) target_link_libraries(${OWNCLOUD_TEST_CLASS}Test updater ${APPLICATION_EXECUTABLE}sync - ${QT_QTTEST_LIBRARY} - ${QT_QTCORE_LIBRARY} + Qt5::Core Qt5::Test Qt5::Xml Qt5::Network ) add_definitions(-DOWNCLOUD_TEST) @@ -25,14 +25,12 @@ macro(owncloud_add_benchmark test_class additional_cpp) string(TOLOWER "${OWNCLOUD_TEST_CLASS}" OWNCLOUD_TEST_CLASS_LOWERCASE) add_executable(${OWNCLOUD_TEST_CLASS}Bench benchmarks/bench${OWNCLOUD_TEST_CLASS_LOWERCASE}.cpp ${additional_cpp}) - qt5_use_modules(${OWNCLOUD_TEST_CLASS}Bench Test Sql Xml Network) set_target_properties(${OWNCLOUD_TEST_CLASS}Bench PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}) target_link_libraries(${OWNCLOUD_TEST_CLASS}Bench updater ${APPLICATION_EXECUTABLE}sync - ${QT_QTTEST_LIBRARY} - ${QT_QTCORE_LIBRARY} + Qt5::Core Qt5::Test Qt5::Xml Qt5::Network ) add_definitions(-DOWNCLOUD_TEST) From d948ed11a185be55ff414a7eb3ab9968801d01dc Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 14 Dec 2017 15:36:19 +0100 Subject: [PATCH 072/138] Csync: use QElapsedTimer and qCInfo instead of CSYNC_LOG and its own csync time function This allow to remove all the csync time manipulation routne which are now unused --- src/csync/CMakeLists.txt | 1 - src/csync/csync.cpp | 46 ++++------- src/csync/csync_time.c | 84 -------------------- src/csync/csync_time.h | 37 --------- src/csync/std/c_time.c | 42 ---------- src/csync/std/c_time.h | 27 ------- test/csync/CMakeLists.txt | 2 +- test/csync/std_tests/check_std_c_time.c | 101 ------------------------ 8 files changed, 18 insertions(+), 322 deletions(-) delete mode 100644 src/csync/csync_time.c delete mode 100644 src/csync/csync_time.h delete mode 100644 test/csync/std_tests/check_std_c_time.c diff --git a/src/csync/CMakeLists.txt b/src/csync/CMakeLists.txt index 2cf4e9600..bf1fc34c4 100644 --- a/src/csync/CMakeLists.txt +++ b/src/csync/CMakeLists.txt @@ -63,7 +63,6 @@ set(csync_SRCS csync.cpp csync_exclude.cpp csync_log.cpp - csync_time.c csync_util.cpp csync_misc.cpp diff --git a/src/csync/csync.cpp b/src/csync/csync.cpp index 667ab25b9..3fadf65d9 100644 --- a/src/csync/csync.cpp +++ b/src/csync/csync.cpp @@ -36,7 +36,6 @@ #include "c_lib.h" #include "csync_private.h" #include "csync_exclude.h" -#include "csync_time.h" #include "csync_util.h" #include "csync_misc.h" #include "std/c_private.h" @@ -46,11 +45,12 @@ #include "vio/csync_vio.h" -#include "csync_log.h" #include "csync_rename.h" #include "common/c_jhash.h" #include "common/syncjournalfilerecord.h" +Q_LOGGING_CATEGORY(lcCSync, "sync.csync.csync", QtInfoMsg) + csync_s::csync_s(const char *localUri, OCC::SyncJournalDb *statedb) : statedb(statedb) @@ -66,7 +66,6 @@ csync_s::csync_s(const char *localUri, OCC::SyncJournalDb *statedb) int csync_update(CSYNC *ctx) { int rc = -1; - struct timespec start, finish; if (ctx == NULL) { errno = EBADF; @@ -79,11 +78,12 @@ int csync_update(CSYNC *ctx) { csync_memstat_check(); if (!ctx->exclude_traversal_fn) { - CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "No exclude file loaded or defined!"); + qCInfo(lcCSync, "No exclude file loaded or defined!"); } /* update detection for local replica */ - csync_gettime(&start); + QElapsedTimer timer; + timer.start(); ctx->current = LOCAL_REPLICA; CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "## Starting local discovery ##"); @@ -96,15 +96,12 @@ int csync_update(CSYNC *ctx) { return rc; } - csync_gettime(&finish); - - CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, - "Update detection for local replica took %.2f seconds walking %zu files.", - c_secdiff(finish, start), ctx->local.files.size()); + qCInfo(lcCSync) << "Update detection for local replica took" << timer.elapsed() / 1000. + << "seconds walking" << ctx->local.files.size() << "files"; csync_memstat_check(); /* update detection for remote replica */ - csync_gettime(&start); + timer.restart(); ctx->current = REMOTE_REPLICA; CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "## Starting remote discovery ##"); @@ -117,12 +114,9 @@ int csync_update(CSYNC *ctx) { return rc; } - csync_gettime(&finish); - CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, - "Update detection for remote replica took %.2f seconds " - "walking %zu files.", - c_secdiff(finish, start), ctx->remote.files.size()); + qCInfo(lcCSync) << "Update detection for remote replica took" << timer.elapsed() / 1000. + << "seconds walking" << ctx->remote.files.size() << "files"; csync_memstat_check(); ctx->status |= CSYNC_STATUS_UPDATE; @@ -133,7 +127,6 @@ int csync_update(CSYNC *ctx) { int csync_reconcile(CSYNC *ctx) { int rc = -1; - struct timespec start, finish; if (ctx == NULL) { errno = EBADF; @@ -142,17 +135,15 @@ int csync_reconcile(CSYNC *ctx) { ctx->status_code = CSYNC_STATUS_OK; /* Reconciliation for local replica */ - csync_gettime(&start); + QElapsedTimer timer; + timer.start(); ctx->current = LOCAL_REPLICA; rc = csync_reconcile_updates(ctx); - csync_gettime(&finish); - - CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, - "Reconciliation for local replica took %.2f seconds visiting %zu files.", - c_secdiff(finish, start), ctx->local.files.size()); + qCInfo(lcCSync) << "Reconciliation for local replica took " << timer.elapsed() / 1000. + << "seconds visiting " << ctx->local.files.size() << " files."; if (rc < 0) { if (!CSYNC_STATUS_IS_OK(ctx->status_code)) { @@ -162,17 +153,14 @@ int csync_reconcile(CSYNC *ctx) { } /* Reconciliation for remote replica */ - csync_gettime(&start); + timer.restart(); ctx->current = REMOTE_REPLICA; rc = csync_reconcile_updates(ctx); - csync_gettime(&finish); - - CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, - "Reconciliation for remote replica took %.2f seconds visiting %zu files.", - c_secdiff(finish, start), ctx->remote.files.size()); + qCInfo(lcCSync) << "Reconciliation for remote replica took " << timer.elapsed() / 1000. + << "seconds visiting " << ctx->remote.files.size() << " files."; if (rc < 0) { if (!CSYNC_STATUS_IS_OK(ctx->status_code)) { diff --git a/src/csync/csync_time.c b/src/csync/csync_time.c deleted file mode 100644 index 442263cee..000000000 --- a/src/csync/csync_time.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2008-2013 by Andreas Schneider - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config_csync.h" - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include -#include -#include - -#include "csync_time.h" - -#ifndef _WIN32 -#include -#include -#else -#include -#endif - -#define CSYNC_LOG_CATEGORY_NAME "csync.time" -#include "csync_log.h" - -#ifdef HAVE_CLOCK_GETTIME -# ifdef _POSIX_MONOTONIC_CLOCK -# define CSYNC_CLOCK CLOCK_MONOTONIC -# else -# define CSYNC_CLOCK CLOCK_REALTIME -# endif -#endif - - -int csync_gettime(struct timespec *tp) -{ -#if defined(_WIN32) - __int64 wintime; - GetSystemTimeAsFileTime((FILETIME*)&wintime); - wintime -= 116444736000000000ll; //1jan1601 to 1jan1970 - tp->tv_sec = wintime / 10000000ll; //seconds - tp->tv_nsec = wintime % 10000000ll * 100; //nano-seconds -#elif defined(HAVE_CLOCK_GETTIME) - return clock_gettime(CSYNC_CLOCK, tp); -#else - struct timeval tv; - - if (gettimeofday(&tv, NULL) < 0) { - return -1; - } - - tp->tv_sec = tv.tv_sec; - tp->tv_nsec = tv.tv_usec * 1000; -#endif - return 0; -} - -#undef CSYNC_CLOCK - -void csync_sleep(unsigned int msecs) -{ -#if defined(_WIN32) - Sleep(msecs); -#else - usleep(msecs * 1000); -#endif -} diff --git a/src/csync/csync_time.h b/src/csync/csync_time.h deleted file mode 100644 index 14d355b32..000000000 --- a/src/csync/csync_time.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2008-2013 by Andreas Schneider - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _CSYNC_TIME_H -#define _CSYNC_TIME_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -int csync_gettime(struct timespec *tp); -void csync_sleep(unsigned int msecs); - -#ifdef __cplusplus -} -#endif - -#endif /* _CSYNC_TIME_H */ diff --git a/src/csync/std/c_time.c b/src/csync/std/c_time.c index 4bcdcbf56..c28459e1b 100644 --- a/src/csync/std/c_time.c +++ b/src/csync/std/c_time.c @@ -26,48 +26,6 @@ #include "c_time.h" #include "c_utf8.h" -struct timespec c_tspecdiff(struct timespec time1, struct timespec time0) { - struct timespec ret; - int xsec = 0; - int sign = 1; - - if (time0.tv_nsec > time1.tv_nsec) { - xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1)); - time0.tv_nsec -= (long int) (1E9 * xsec); - time0.tv_sec += xsec; - } - - if ((time1.tv_nsec - time0.tv_nsec) > 1E9) { - xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9); - time0.tv_nsec += (long int) (1E9 * xsec); - time0.tv_sec -= xsec; - } - - ret.tv_sec = time1.tv_sec - time0.tv_sec; - ret.tv_nsec = time1.tv_nsec - time0.tv_nsec; - - if (time1.tv_sec < time0.tv_sec) { - sign = -1; - } - - ret.tv_sec = ret.tv_sec * sign; - - return ret; -} - -double c_secdiff(struct timespec clock1, struct timespec clock0) { - double ret; - struct timespec diff; - - diff = c_tspecdiff(clock1, clock0); - - ret = diff.tv_sec; - ret += (double) diff.tv_nsec / (double) 1E9; - - return ret; -} - - #ifdef HAVE_UTIMES int c_utimes(const char *uri, const struct timeval *times) { mbchar_t *wuri = c_utf8_path_to_locale(uri); diff --git a/src/csync/std/c_time.h b/src/csync/std/c_time.h index dee1b0e2b..3792198f8 100644 --- a/src/csync/std/c_time.h +++ b/src/csync/std/c_time.h @@ -33,33 +33,6 @@ extern "C" { #include #endif -/** - * @brief Calculate time difference - * - * The c_tspecdiff function returns the time elapsed between time time1 and time - * time0 represented as timespec. - * - * @param time1 The time. - * @param time0 The time. - * - * @return time elapsed between time1 and time0. - */ -struct timespec c_tspecdiff(struct timespec time1, struct timespec time0); - -/** - * @brief Calculate time difference. - * - * The function returns the time elapsed between time clock1 and time - * clock0 represented as double (in seconds and milliseconds). - * - * @param clock1 The time. - * @param clock0 The time. - * - * @return time elapsed between clock1 and clock0 in seconds and - * milliseconds. - */ -double c_secdiff(struct timespec clock1, struct timespec clock0); - OCSYNC_EXPORT int c_utimes(const char *uri, const struct timeval *times); #ifdef __cplusplus diff --git a/test/csync/CMakeLists.txt b/test/csync/CMakeLists.txt index 5cb0590e4..75cee7b7d 100644 --- a/test/csync/CMakeLists.txt +++ b/test/csync/CMakeLists.txt @@ -24,7 +24,7 @@ add_cmocka_test(check_std_c_alloc std_tests/check_std_c_alloc.c ${TEST_TARGET_LI add_cmocka_test(check_std_c_jhash std_tests/check_std_c_jhash.c ${TEST_TARGET_LIBRARIES}) add_cmocka_test(check_std_c_path std_tests/check_std_c_path.c ${TEST_TARGET_LIBRARIES}) add_cmocka_test(check_std_c_str std_tests/check_std_c_str.c ${TEST_TARGET_LIBRARIES}) -add_cmocka_test(check_std_c_time std_tests/check_std_c_time.c ${TEST_TARGET_LIBRARIES}) + # csync tests # This will be rewritten soon anyway. diff --git a/test/csync/std_tests/check_std_c_time.c b/test/csync/std_tests/check_std_c_time.c deleted file mode 100644 index db8e72ff6..000000000 --- a/test/csync/std_tests/check_std_c_time.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2008-2013 by Andreas Schneider - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include - -#include "csync_time.h" -#include "std/c_time.h" -#include - -#include "torture.h" - -static void check_c_tspecdiff(void **state) -{ - struct timespec start, finish, diff; - - (void) state; /* unused */ - - csync_gettime(&start); - csync_gettime(&finish); - - diff = c_tspecdiff(finish, start); - - assert_int_equal(diff.tv_sec, 0); - assert_true(diff.tv_nsec >= 0); -} - -static void check_c_tspecdiff_five(void **state) -{ - struct timespec start, finish, diff; - - (void) state; /* unused */ - - csync_gettime(&start); - sleep(5); - csync_gettime(&finish); - - diff = c_tspecdiff(finish, start); - - assert_int_equal(diff.tv_sec, 5); - assert_true(diff.tv_nsec > 0); -} - -static void check_c_secdiff(void **state) -{ - struct timespec start, finish; - double diff; - - (void) state; /* unused */ - - csync_gettime(&start); - csync_gettime(&finish); - - diff = c_secdiff(finish, start); - - assert_true(diff >= 0.00 && diff < 1.00); -} - -static void check_c_secdiff_three(void **state) -{ - struct timespec start, finish; - double diff; - - (void) state; /* unused */ - - csync_gettime(&start); - sleep(3); - csync_gettime(&finish); - - diff = c_secdiff(finish, start); - - assert_true(diff > 3.00 && diff < 4.00); -} - -int torture_run_tests(void) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(check_c_tspecdiff), - cmocka_unit_test(check_c_tspecdiff_five), - cmocka_unit_test(check_c_secdiff), - cmocka_unit_test(check_c_secdiff_three), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} - From 3ddd4b6f16cddaeff989bb2beefb4802e2d903df Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 14 Dec 2017 16:14:08 +0100 Subject: [PATCH 073/138] Get rid of csync_log We use Qt's debugging code everywhere --- src/cmd/cmd.cpp | 1 - src/csync/CMakeLists.txt | 1 - src/csync/csync.cpp | 4 +- src/csync/csync.h | 37 ------ src/csync/csync_log.cpp | 77 ------------ src/csync/csync_log.h | 75 ----------- src/csync/csync_misc.cpp | 1 - src/csync/csync_util.cpp | 9 +- src/csync/vio/csync_vio_local_unix.cpp | 6 +- src/csync/vio/csync_vio_local_win.cpp | 6 +- src/libsync/discoveryphase.cpp | 2 - src/libsync/discoveryphase.h | 7 -- src/libsync/logger.cpp | 42 ------- src/libsync/logger.h | 6 - test/csync/CMakeLists.txt | 4 - test/csync/csync_tests/check_csync_log.cpp | 140 --------------------- test/csync/log_tests/check_log.cpp | 98 --------------- 17 files changed, 12 insertions(+), 504 deletions(-) delete mode 100644 src/csync/csync_log.cpp delete mode 100644 src/csync/csync_log.h delete mode 100644 test/csync/csync_tests/check_csync_log.cpp delete mode 100644 test/csync/log_tests/check_log.cpp diff --git a/src/cmd/cmd.cpp b/src/cmd/cmd.cpp index e962dd4e0..c521d14f2 100644 --- a/src/cmd/cmd.cpp +++ b/src/cmd/cmd.cpp @@ -331,7 +331,6 @@ int main(int argc, char **argv) parseOptions(app.arguments(), &options); - csync_set_log_level(options.silent ? 1 : 11); if (options.silent) { qInstallMessageHandler(nullMessageHandler); } else { diff --git a/src/csync/CMakeLists.txt b/src/csync/CMakeLists.txt index bf1fc34c4..59f574712 100644 --- a/src/csync/CMakeLists.txt +++ b/src/csync/CMakeLists.txt @@ -62,7 +62,6 @@ endif() set(csync_SRCS csync.cpp csync_exclude.cpp - csync_log.cpp csync_util.cpp csync_misc.cpp diff --git a/src/csync/csync.cpp b/src/csync/csync.cpp index 3fadf65d9..992e60f21 100644 --- a/src/csync/csync.cpp +++ b/src/csync/csync.cpp @@ -86,7 +86,7 @@ int csync_update(CSYNC *ctx) { timer.start(); ctx->current = LOCAL_REPLICA; - CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "## Starting local discovery ##"); + qCInfo(lcCSync, "## Starting local discovery ##"); rc = csync_ftw(ctx, ctx->local.uri, csync_walker, MAX_DEPTH); if (rc < 0) { @@ -104,7 +104,7 @@ int csync_update(CSYNC *ctx) { timer.restart(); ctx->current = REMOTE_REPLICA; - CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "## Starting remote discovery ##"); + qCInfo(lcCSync, "## Starting remote discovery ##"); rc = csync_ftw(ctx, "", csync_walker, MAX_DEPTH); if (rc < 0) { diff --git a/src/csync/csync.h b/src/csync/csync.h index 3a1d8d584..88fc0570c 100644 --- a/src/csync/csync.h +++ b/src/csync/csync.h @@ -223,10 +223,6 @@ typedef struct csync_s CSYNC; typedef int (*csync_auth_callback) (const char *prompt, char *buf, size_t len, int echo, int verify, void *userdata); -typedef void (*csync_log_callback) (int verbosity, - const char *function, - const char *buffer); - typedef void (*csync_update_callback) (bool local, const char *dirUrl, void *userdata); @@ -304,39 +300,6 @@ csync_auth_callback OCSYNC_EXPORT csync_get_auth_callback(CSYNC *ctx); */ int OCSYNC_EXPORT csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb); -/** - * @brief Set the log level. - * - * @param[in] level The log verbosity. - * - * @return 0 on success, < 0 if an error occurred. - */ -int OCSYNC_EXPORT csync_set_log_level(int level); - -/** - * @brief Get the log verbosity - * - * @return The log verbosity, -1 on error. - */ -int OCSYNC_EXPORT csync_get_log_level(void); - -/** - * @brief Get the logging callback set. - * - * @return The logging callback set or NULL if an error - * occurred. - */ -csync_log_callback OCSYNC_EXPORT csync_get_log_callback(void); - -/** - * @brief Set the logging callback. - * - * @param cb The logging callback. - * - * @return 0 on success, less than 0 if an error occurred. - */ -int OCSYNC_EXPORT csync_set_log_callback(csync_log_callback cb); - /* Used for special modes or debugging */ CSYNC_STATUS OCSYNC_EXPORT csync_get_status(CSYNC *ctx); diff --git a/src/csync/csync_log.cpp b/src/csync/csync_log.cpp deleted file mode 100644 index 4a2e24a32..000000000 --- a/src/csync/csync_log.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2008-2013 by Andreas Schneider - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config_csync.h" - -#include -#include -#include - -#include "csync_private.h" -#include "csync_log.h" - -CSYNC_THREAD int csync_log_level; -CSYNC_THREAD csync_log_callback csync_log_cb; - -void csync_log(int verbosity, - const char *function, - const char *format, ...) -{ - csync_log_callback log_fn = csync_get_log_callback(); - if (log_fn && verbosity <= csync_get_log_level()) { - char buffer[1024]; - va_list va; - - va_start(va, format); - vsnprintf(buffer, sizeof(buffer), format, va); - va_end(va); - - log_fn(verbosity, function, buffer); - return; - } -} - -int csync_set_log_level(int level) { - if (level < 0) { - return -1; - } - - csync_log_level = level; - - return 0; -} - -int csync_get_log_level(void) { - return csync_log_level; -} - -int csync_set_log_callback(csync_log_callback cb) { - if (cb == NULL) { - return -1; - } - - csync_log_cb = cb; - - return 0; -} - -csync_log_callback csync_get_log_callback(void) { - return csync_log_cb; -} diff --git a/src/csync/csync_log.h b/src/csync/csync_log.h deleted file mode 100644 index 0cd0d01fc..000000000 --- a/src/csync/csync_log.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2008-2013 by Andreas Schneider - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file csync_log.h - * - * @brief Logging interface of csync - * - * @defgroup csyncLogInternals csync logging internals - * @ingroup csyncInternalAPI - * - * @{ - */ - -#ifndef _CSYNC_LOG_H -#define _CSYNC_LOG_H - -/* GCC have printf type attribute check. */ -#ifndef PRINTF_ATTRIBUTE -#ifdef __GNUC__ -#ifdef _WIN32 -#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__gnu_printf__, a, b))) -#else -#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b))) -#endif -#else -#define PRINTF_ATTRIBUTE(a,b) -#endif /* __GNUC__ */ -#endif /* ndef PRINTF_ATTRIBUTE */ - -enum csync_log_priority_e { - CSYNC_LOG_PRIORITY_NOLOG = 0, - CSYNC_LOG_PRIORITY_FATAL, - CSYNC_LOG_PRIORITY_ALERT, - CSYNC_LOG_PRIORITY_CRIT, - CSYNC_LOG_PRIORITY_ERROR, - CSYNC_LOG_PRIORITY_WARN, - CSYNC_LOG_PRIORITY_NOTICE, - CSYNC_LOG_PRIORITY_INFO, - CSYNC_LOG_PRIORITY_DEBUG, - CSYNC_LOG_PRIORITY_TRACE, - CSYNC_LOG_PRIORITY_NOTSET, - CSYNC_LOG_PRIORITY_UNKNOWN, -}; - -#define CSYNC_LOG(priority, ...) \ - csync_log(priority, __func__, __VA_ARGS__) - -void csync_log(int verbosity, - const char *function, - const char *format, ...) PRINTF_ATTRIBUTE(3, 4); - -/** - * }@ - */ -#endif /* _CSYNC_LOG_H */ - -/* vim: set ft=c.doxygen ts=4 sw=4 et cindent: */ diff --git a/src/csync/csync_misc.cpp b/src/csync/csync_misc.cpp index bb8e98c8a..7945c428f 100644 --- a/src/csync/csync_misc.cpp +++ b/src/csync/csync_misc.cpp @@ -44,7 +44,6 @@ #include "c_lib.h" #include "csync_misc.h" #include "csync_macros.h" -#include "csync_log.h" #ifdef HAVE_FNMATCH #include diff --git a/src/csync/csync_util.cpp b/src/csync/csync_util.cpp index b05228efe..cd7c589ce 100644 --- a/src/csync/csync_util.cpp +++ b/src/csync/csync_util.cpp @@ -34,8 +34,8 @@ #include "csync_util.h" #include "vio/csync_vio.h" -#define CSYNC_LOG_CATEGORY_NAME "csync.util" -#include "csync_log.h" +Q_LOGGING_CATEGORY(lcCSyncUtils, "sync.csync.utils", QtInfoMsg) + typedef struct { const char *instr_str; @@ -102,8 +102,8 @@ void csync_memstat_check(void) { return; } - CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Memory: %dK total size, %dK resident, %dK shared", - m.size * 4, m.resident * 4, m.shared * 4); + qCInfo(lcCSyncUtils, "Memory: %dK total size, %dK resident, %dK shared", + m.size * 4, m.resident * 4, m.shared * 4); } bool (*csync_file_locked_or_open_ext) (const char*) = 0; // filled in by library user @@ -121,7 +121,6 @@ bool csync_file_locked_or_open( const char *dir, const char *fname) { if (asprintf(&tmp_uri, "%s/%s", dir, fname) < 0) { return -1; } - CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "csync_file_locked_or_open %s", tmp_uri); ret = csync_file_locked_or_open_ext(tmp_uri); SAFE_FREE(tmp_uri); return ret; diff --git a/src/csync/vio/csync_vio_local_unix.cpp b/src/csync/vio/csync_vio_local_unix.cpp index c65e21d9f..f2620bbb6 100644 --- a/src/csync/vio/csync_vio_local_unix.cpp +++ b/src/csync/vio/csync_vio_local_unix.cpp @@ -31,11 +31,12 @@ #include "c_string.h" #include "c_utf8.h" #include "csync_util.h" -#include "csync_log.h" #include "csync_vio.h" #include "vio/csync_vio_local.h" +Q_LOGGING_CATEGORY(lcCSyncVIOLocal, "sync.csync.vio_local", QtInfoMsg) + /* * directory functions */ @@ -105,8 +106,7 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *d QByteArray fullPath = QByteArray() % const_cast(handle->path) % '/' % QByteArray() % const_cast(dirent->d_name); if (file_stat->path.isNull()) { file_stat->original_path = fullPath; - CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Invalid characters in file/directory name, please rename: \"%s\" (%s)", - dirent->d_name, handle->path); + qCWarning(lcCSyncVIOLocal) << "Invalid characters in file/directory name, please rename:" << dirent->d_name << handle->path; } /* Check for availability of d_type, see manpage. */ diff --git a/src/csync/vio/csync_vio_local_win.cpp b/src/csync/vio/csync_vio_local_win.cpp index 3b94550bb..1c9a5907f 100644 --- a/src/csync/vio/csync_vio_local_win.cpp +++ b/src/csync/vio/csync_vio_local_win.cpp @@ -31,11 +31,11 @@ #include "c_lib.h" #include "c_utf8.h" #include "csync_util.h" -#include "csync_log.h" #include "csync_vio.h" #include "vio/csync_vio_local.h" +Q_LOGGING_CATEGORY(lcCSyncVIOLocal, "sync.csync.vio_local", QtInfoMsg) /* * directory functions @@ -235,13 +235,13 @@ static int _csync_vio_local_stat_mb(const mbchar_t *wuri, csync_file_stat_t *buf FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL ); if( h == INVALID_HANDLE_VALUE ) { - CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "CreateFileW failed on %ls", wuri); + qCCritical(lcCSyncVIOLocal, "CreateFileW failed on %ls", wuri); errno = GetLastError(); return -1; } if(!GetFileInformationByHandle( h, &fileInfo ) ) { - CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "GetFileInformationByHandle failed on %ls", wuri); + qCCritical(lcCSyncVIOLocal, "GetFileInformationByHandle failed on %ls", wuri); errno = GetLastError(); CloseHandle(h); return -1; diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp index 2cf096d4f..bd74d439c 100644 --- a/src/libsync/discoveryphase.cpp +++ b/src/libsync/discoveryphase.cpp @@ -697,8 +697,6 @@ void DiscoveryJob::start() _csync_ctx->callbacks.remote_closedir_hook = remote_vio_closedir_hook; _csync_ctx->callbacks.vio_userdata = this; - csync_set_log_callback(_log_callback); - csync_set_log_level(_log_level); _lastUpdateProgressCallbackCall.invalidate(); int ret = csync_update(_csync_ctx); diff --git a/src/libsync/discoveryphase.h b/src/libsync/discoveryphase.h index 222f4a999..b5e743d33 100644 --- a/src/libsync/discoveryphase.h +++ b/src/libsync/discoveryphase.h @@ -157,8 +157,6 @@ class DiscoveryJob : public QObject Q_OBJECT friend class DiscoveryMainThread; CSYNC *_csync_ctx; - csync_log_callback _log_callback; - int _log_level; QElapsedTimer _lastUpdateProgressCallbackCall; /** @@ -191,12 +189,7 @@ public: : QObject(parent) , _csync_ctx(ctx) { - // We need to forward the log property as csync uses thread local - // and updates run in another thread - _log_callback = csync_get_log_callback(); - _log_level = csync_get_log_level(); } - QStringList _selectiveSyncBlackList; QStringList _selectiveSyncWhiteList; SyncOptions _syncOptions; diff --git a/src/libsync/logger.cpp b/src/libsync/logger.cpp index 31afbbe8c..58afde287 100644 --- a/src/libsync/logger.cpp +++ b/src/libsync/logger.cpp @@ -19,13 +19,8 @@ #include #include -#include "csync.h" -#include "csync_log.h" - namespace OCC { -Q_LOGGING_CATEGORY(lcCsync, "sync.csync", QtInfoMsg) - static void mirallLogCatcher(QtMsgType type, const QMessageLogContext &ctx, const QString &message) { auto logger = Logger::instance(); @@ -34,26 +29,6 @@ static void mirallLogCatcher(QtMsgType type, const QMessageLogContext &ctx, cons } } -static void csyncLogCatcher(int verbosity, - const char *function, - const char *buffer) -{ - if (verbosity <= CSYNC_LOG_PRIORITY_FATAL) { - QMessageLogger(0, 0, function, lcCsync().categoryName()).fatal("%s", buffer); - } else if (verbosity <= CSYNC_LOG_PRIORITY_CRIT) { - if (lcCsync().isCriticalEnabled()) - QMessageLogger(0, 0, function, lcCsync().categoryName()).critical("%s", buffer); - } else if (verbosity <= CSYNC_LOG_PRIORITY_WARN) { - if (lcCsync().isWarningEnabled()) - QMessageLogger(0, 0, function, lcCsync().categoryName()).warning("%s", buffer); - } else if (verbosity <= CSYNC_LOG_PRIORITY_INFO) { - if (lcCsync().isInfoEnabled()) - QMessageLogger(0, 0, function, lcCsync().categoryName()).info("%s", buffer); - } else if (verbosity <= CSYNC_LOG_PRIORITY_NOTSET) { - if (lcCsync().isDebugEnabled()) - QMessageLogger(0, 0, function, lcCsync().categoryName()).debug("%s", buffer); - } -} Logger *Logger::instance() { @@ -74,12 +49,7 @@ Logger::Logger(QObject *parent) qInstallMessageHandler(mirallLogCatcher); #else Q_UNUSED(mirallLogCatcher) - // Always get logging from csync in that case. - csync_set_log_level(11); #endif - - // Setup CSYNC logging to forward to our own logger - csync_set_log_callback(csyncLogCatcher); } Logger::~Logger() @@ -112,11 +82,6 @@ void Logger::log(Log log) msg = log.timeStamp.toString(QLatin1String("MM-dd hh:mm:ss:zzz")) + QLatin1Char(' '); } - if (log.source == Log::CSync) { - // msg += "csync - "; - } else { - // msg += "ownCloud - "; - } msg += QString().sprintf("%p ", (void *)QThread::currentThread()); msg += log.message; // _logs.append(log); @@ -151,7 +116,6 @@ void Logger::doLog(const QString &msg) void Logger::mirallLog(const QString &message) { Log log_; - log_.source = Log::Occ; log_.timeStamp = QDateTime::currentDateTimeUtc(); log_.message = message; @@ -161,18 +125,12 @@ void Logger::mirallLog(const QString &message) void Logger::setLogWindowActivated(bool activated) { QMutexLocker locker(&_mutex); - - csync_set_log_level(11); - _logWindowActivated = activated; } void Logger::setLogFile(const QString &name) { QMutexLocker locker(&_mutex); - - csync_set_log_level(11); - if (_logstream) { _logstream.reset(0); _logFile.close(); diff --git a/src/libsync/logger.h b/src/libsync/logger.h index bf73009a9..9d6ef6b26 100644 --- a/src/libsync/logger.h +++ b/src/libsync/logger.h @@ -30,13 +30,7 @@ namespace OCC { struct Log { - typedef enum { - Occ, - CSync - } Source; - QDateTime timeStamp; - Source source; QString message; }; diff --git a/test/csync/CMakeLists.txt b/test/csync/CMakeLists.txt index 75cee7b7d..8e722e0dc 100644 --- a/test/csync/CMakeLists.txt +++ b/test/csync/CMakeLists.txt @@ -27,10 +27,6 @@ add_cmocka_test(check_std_c_str std_tests/check_std_c_str.c ${TEST_TARGET_LIBRAR # csync tests -# This will be rewritten soon anyway. -#add_cmocka_test(check_logger log_tests/check_log.cpp ${TEST_TARGET_LIBRARIES}) - -add_cmocka_test(check_csync_log csync_tests/check_csync_log.cpp ${TEST_TARGET_LIBRARIES}) add_cmocka_test(check_csync_exclude csync_tests/check_csync_exclude.cpp ${TEST_TARGET_LIBRARIES}) add_cmocka_test(check_csync_util csync_tests/check_csync_util.cpp ${TEST_TARGET_LIBRARIES}) add_cmocka_test(check_csync_misc csync_tests/check_csync_misc.cpp ${TEST_TARGET_LIBRARIES}) diff --git a/test/csync/csync_tests/check_csync_log.cpp b/test/csync/csync_tests/check_csync_log.cpp deleted file mode 100644 index 9c767b7c2..000000000 --- a/test/csync/csync_tests/check_csync_log.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2008-2013 by Andreas Schneider - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include -#include - -#include "csync.h" -#include "csync_log.cpp" -#include "c_private.h" -#include "std/c_utf8.h" - -#include "torture.h" - -static int setup(void **state) { - int rc; - - rc = system("mkdir -p /tmp/check_csync1"); - assert_int_equal(rc, 0); - - *state = NULL; - - return 0; -} - -static int teardown(void **state) { - int rc; - - rc = system("rm -rf /tmp/check_csync"); - assert_int_equal(rc, 0); - - rc = system("rm -rf /tmp/check_csync1"); - assert_int_equal(rc, 0); - - *state = NULL; - - return 0; -} - -static void check_log_callback(int verbosity, - const char *function, - const char *buffer) -{ - int rc; - - assert_true(verbosity >= 0); - assert_non_null(function); - assert_false(function[0] == '\0'); - assert_non_null(buffer); - assert_false(buffer[0] == '\0'); - - rc = system("touch /tmp/check_csync1/cb_called"); - assert_int_equal(rc, 0); -} - -static void check_set_log_level(void **state) -{ - int rc; - - (void) state; - - rc = csync_set_log_level(-5); - assert_int_equal(rc, -1); - - rc = csync_set_log_level(5); - assert_int_equal(rc, 0); - - rc = csync_get_log_level(); - assert_int_equal(rc, 5); -} - -static void check_set_auth_callback(void **state) -{ - csync_log_callback log_fn; - int rc; - - (void) state; - - rc = csync_set_log_callback(NULL); - assert_int_equal(rc, -1); - - rc = csync_set_log_callback(check_log_callback); - assert_int_equal(rc, 0); - - log_fn = csync_get_log_callback(); - assert_non_null(log_fn); - assert_true(log_fn == &check_log_callback); -} - -static void check_logging(void **state) -{ - int rc; - csync_stat_t sb; - mbchar_t *path; - path = c_utf8_path_to_locale("/tmp/check_csync1/cb_called"); - - (void) state; /* unused */ - - assert_non_null(path); - - rc = csync_set_log_level(1); - assert_int_equal(rc, 0); - - rc = csync_set_log_callback(check_log_callback); - assert_int_equal(rc, 0); - - csync_log(1, __func__, "rc = %d", rc); - - rc = _tstat(path, &sb); - - c_free_locale_string(path); - - assert_int_equal(rc, 0); -} - -int torture_run_tests(void) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(check_set_log_level), - cmocka_unit_test(check_set_auth_callback), - cmocka_unit_test_setup_teardown(check_logging, setup, teardown), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/test/csync/log_tests/check_log.cpp b/test/csync/log_tests/check_log.cpp deleted file mode 100644 index f5f961f72..000000000 --- a/test/csync/log_tests/check_log.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2008-2013 by Andreas Schneider - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include - -#include "support.h" - -#include "config_csync.h" -#include "csync_log.h" - -static void setup(void) { - csync_log_init(); -} - -static void teardown(void) { - csync_log_fini(); -} - -START_TEST (log_create) -{ - fail_unless((csync_log_init() == 0), NULL); - fail_unless((csync_log_fini() == 0), NULL); -} -END_TEST - -START_TEST (log_load) -{ - char buf[256]; - snprintf(buf, (size_t) 256 - 1, "%s/%s", SOURCEDIR, "config/ocsync_log.conf"); - fail_unless(csync_log_load(buf) == 0); -} -END_TEST - -START_TEST (log_prio) -{ - CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "log %s", "test"); - CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "log %s", "test"); - CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "log %s", "test"); - CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "log %s", "test"); - CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "log %s", "test"); - CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "log %s", "test"); - CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "log %s", "test"); - CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "log %s", "test"); - CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "log %s", "test"); - CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "log %s", "test"); - CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTSET, "log %s", "test"); - CSYNC_LOG(CSYNC_LOG_PRIORITY_UNKNOWN, "log %s", "test"); -} -END_TEST - -START_TEST (log_null) -{ - char *z = NULL; - CSYNC_LOG(CSYNC_LOG_PRIORITY_UNKNOWN, "log %s", z); -} -END_TEST - -static Suite *log_suite(void) { - Suite *s = suite_create("Logger"); - - create_case(s, "log_create", log_create); - create_case_fixture(s, "log_load", log_load, setup, teardown); - create_case_fixture(s, "log_prio", log_prio, setup, teardown); - create_case_fixture(s, "log_null", log_null, setup, teardown); - - return s; -} - -int main(void) { - int nf; - - Suite *s = log_suite(); - - SRunner *sr; - sr = srunner_create(s); - srunner_run_all(sr, CK_VERBOSE); - nf = srunner_ntests_failed(sr); - srunner_free(sr); - - return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE; -} - From 1c117786936fc811c5593c0c15d08bb48bfb4665 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 14 Dec 2017 16:16:42 +0100 Subject: [PATCH 074/138] Remove the unusued csync_file_locked_or_open test in csync_reconcile It is unused. Also remove the corresponding error code --- src/csync/csync.h | 1 - src/csync/csync_reconcile.cpp | 10 ---------- src/csync/csync_util.cpp | 20 -------------------- src/csync/csync_util.h | 2 -- src/libsync/syncengine.cpp | 3 --- 5 files changed, 36 deletions(-) diff --git a/src/csync/csync.h b/src/csync/csync.h index 88fc0570c..e913a726a 100644 --- a/src/csync/csync.h +++ b/src/csync/csync.h @@ -108,7 +108,6 @@ enum csync_status_codes_e { CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS, CSYNC_STATUS_INDIVIDUAL_TRAILING_SPACE, CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME, - CYSNC_STATUS_FILE_LOCKED_OR_OPEN, CSYNC_STATUS_INDIVIDUAL_EXCLUDE_HIDDEN, CSYNC_STATUS_INVALID_CHARACTERS, CSYNC_STATUS_INDIVIDUAL_STAT_FAILED, diff --git a/src/csync/csync_reconcile.cpp b/src/csync/csync_reconcile.cpp index 3324b8f76..ce1beb142 100644 --- a/src/csync/csync_reconcile.cpp +++ b/src/csync/csync_reconcile.cpp @@ -283,16 +283,6 @@ static int _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) { /* file on current replica is changed or new */ case CSYNC_INSTRUCTION_EVAL: case CSYNC_INSTRUCTION_NEW: - // This operation is usually a no-op and will by default return false - if (csync_file_locked_or_open(ctx->local.uri, cur->path)) { - qCDebug(lcReconcile, "[Reconciler] IGNORING file %s/%s since it is locked / open", ctx->local.uri, cur->path.constData()); - cur->instruction = CSYNC_INSTRUCTION_ERROR; - if (cur->error_status == CSYNC_STATUS_OK) // don't overwrite error - cur->error_status = CYSNC_STATUS_FILE_LOCKED_OR_OPEN; - break; - } else { - //qCDebug(lcReconcile, "[Reconciler] not ignoring file %s/%s", ctx->local.uri, cur->path); - } switch (other->instruction) { /* file on other replica is changed or new */ case CSYNC_INSTRUCTION_NEW: diff --git a/src/csync/csync_util.cpp b/src/csync/csync_util.cpp index cd7c589ce..761537bb8 100644 --- a/src/csync/csync_util.cpp +++ b/src/csync/csync_util.cpp @@ -106,26 +106,6 @@ void csync_memstat_check(void) { m.size * 4, m.resident * 4, m.shared * 4); } -bool (*csync_file_locked_or_open_ext) (const char*) = 0; // filled in by library user -void set_csync_file_locked_or_open_ext(bool (*f) (const char*)); -void set_csync_file_locked_or_open_ext(bool (*f) (const char*)) { - csync_file_locked_or_open_ext = f; -} - -bool csync_file_locked_or_open( const char *dir, const char *fname) { - char *tmp_uri = NULL; - bool ret; - if (!csync_file_locked_or_open_ext) { - return false; - } - if (asprintf(&tmp_uri, "%s/%s", dir, fname) < 0) { - return -1; - } - ret = csync_file_locked_or_open_ext(tmp_uri); - SAFE_FREE(tmp_uri); - return ret; -} - #ifndef HAVE_TIMEGM #ifdef _WIN32 static int is_leap(unsigned y) { diff --git a/src/csync/csync_util.h b/src/csync/csync_util.h index 57a5f12a0..f9c0d8876 100644 --- a/src/csync/csync_util.h +++ b/src/csync/csync_util.h @@ -30,8 +30,6 @@ const char OCSYNC_EXPORT *csync_instruction_str(enum csync_instructions_e instr) void OCSYNC_EXPORT csync_memstat_check(void); -bool OCSYNC_EXPORT csync_file_locked_or_open( const char *dir, const char *fname); - /* Returns true if we're reasonably certain that hash equality * for the header means content equality. * diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 31338f4f6..b3bbc5383 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -534,9 +534,6 @@ int SyncEngine::treewalkFile(csync_file_stat_t *file, csync_file_stat_t *other, item->_errorString = tr("Conflict: Server version downloaded, local copy renamed and not uploaded."); } break; - case CYSNC_STATUS_FILE_LOCKED_OR_OPEN: - item->_errorString = QLatin1String("File locked"); // don't translate, internal use! - break; case CSYNC_STATUS_INDIVIDUAL_STAT_FAILED: item->_errorString = tr("Stat failed."); break; From 41798cef1839ab2593ddf09332ad44a4b9d3eabe Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 14 Dec 2017 17:02:20 +0100 Subject: [PATCH 075/138] Csync: remove some unused build system stuff --- cmake/modules/MacroAddPlugin.cmake | 30 ---------------- cmake/modules/MacroCopyFile.cmake | 37 ------------------- cmake/modules/UseAsciidoc.cmake | 58 ------------------------------ src/csync/CMakeLists.txt | 4 --- src/csync/ConfigureChecks.cmake | 10 ------ src/csync/config_csync.h.cmake | 4 --- src/csync/std/c_private.h | 4 --- 7 files changed, 147 deletions(-) delete mode 100644 cmake/modules/MacroAddPlugin.cmake delete mode 100644 cmake/modules/MacroCopyFile.cmake delete mode 100644 cmake/modules/UseAsciidoc.cmake diff --git a/cmake/modules/MacroAddPlugin.cmake b/cmake/modules/MacroAddPlugin.cmake deleted file mode 100644 index 8ddf8d689..000000000 --- a/cmake/modules/MacroAddPlugin.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# - MACRO_ADD_PLUGIN(name [WITH_PREFIX] file1 .. fileN) -# -# Create a plugin from the given source files. -# If WITH_PREFIX is given, the resulting plugin will have the -# prefix "lib", otherwise it won't. -# -# Copyright (c) 2006, Alexander Neundorf, -# Copyright (c) 2006, Laurent Montel, -# Copyright (c) 2006, Andreas Schneider, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - - -macro (MACRO_ADD_PLUGIN _target_NAME _with_PREFIX) - - if (${_with_PREFIX} STREQUAL "WITH_PREFIX") - set(_first_SRC) - else (${_with_PREFIX} STREQUAL "WITH_PREFIX") - set(_first_SRC ${_with_PREFIX}) - endif (${_with_PREFIX} STREQUAL "WITH_PREFIX") - - add_library(${_target_NAME} MODULE ${_first_SRC} ${ARGN}) - - if (_first_SRC) - set_target_properties(${_target_NAME} PROPERTIES PREFIX "") - endif (_first_SRC) - -endmacro (MACRO_ADD_PLUGIN _name _sources) - diff --git a/cmake/modules/MacroCopyFile.cmake b/cmake/modules/MacroCopyFile.cmake deleted file mode 100644 index 210c7a427..000000000 --- a/cmake/modules/MacroCopyFile.cmake +++ /dev/null @@ -1,37 +0,0 @@ -# (c) 2014 Copyright ownCloud GmbH -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING* file. - -# - macro_copy_file(_src _dst) -# Copies a file to ${_dst} only if ${_src} is different (newer) than ${_dst} -# -# Example: -# macro_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/icon.png ${CMAKE_CURRENT_BINARY_DIR}/.) -# Copies file icon.png to ${CMAKE_CURRENT_BINARY_DIR} directory -# -# Copyright (c) 2006-2007 Wengo -# Copyright (c) 2006-2008 Andreas Schneider -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING file. - - -macro (macro_copy_file _src _dst) - # Removes all path containing .svn or CVS or CMakeLists.txt during the copy - if (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*") - - if (CMAKE_VERBOSE_MAKEFILE) - message(STATUS "Copy file from ${_src} to ${_dst}") - endif (CMAKE_VERBOSE_MAKEFILE) - - # Creates directory if necessary - get_filename_component(_path ${_dst} PATH) - file(MAKE_DIRECTORY ${_path}) - - execute_process( - COMMAND - ${CMAKE_COMMAND} -E copy_if_different ${_src} ${_dst} - OUTPUT_QUIET - ) - endif (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*") -endmacro (macro_copy_file) diff --git a/cmake/modules/UseAsciidoc.cmake b/cmake/modules/UseAsciidoc.cmake deleted file mode 100644 index 42024b29e..000000000 --- a/cmake/modules/UseAsciidoc.cmake +++ /dev/null @@ -1,58 +0,0 @@ -# - macro_asciidoc2man(inputfile outputfile) -# -# Create a manpage with asciidoc. -# Example: macro_asciidoc2man(foo.txt foo.1) -# -# Copyright (c) 2006, Andreas Schneider, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -include(MacroCopyFile) - -macro(MACRO_ASCIIDOC2MAN _a2m_input _a2m_output) - find_program(A2X - NAMES - a2x - ) - #message("+++ A2X: ${A2X}") - - if (A2X) - - #message("+++ ${A2X} --doctype=manpage --format=manpage --destination-dir=${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${_a2m_input}") - macro_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/${_a2m_input} ${CMAKE_CURRENT_BINARY_DIR}/${_a2m_input}) - - execute_process( - COMMAND - ${A2X} --doctype=manpage --format=manpage ${_a2m_input} - WORKING_DIRECTORY - ${CMAKE_CURRENT_BINARY_DIR} - RESULT_VARIABLE - A2M_MAN_GENERATED - ERROR_QUIET - ) - - #message("+++ A2M_MAN_GENERATED: ${A2M_MAN_GENERATED}") - if (A2M_MAN_GENERATED EQUAL 0) - find_file(A2M_MAN_FILE - NAME - ${_a2m_output} - PATHS - ${CMAKE_CURRENT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - if (A2M_MAN_FILE) - get_filename_component(A2M_MAN_CATEGORY ${A2M_MAN_FILE} EXT) - string(SUBSTRING ${A2M_MAN_CATEGORY} 1 1 A2M_MAN_CATEGORY) - install( - FILES - ${A2M_MAN_FILE} - DESTINATION - ${MAN_INSTALL_DIR}/man${A2M_MAN_CATEGORY} - ) - endif (A2M_MAN_FILE) - endif (A2M_MAN_GENERATED EQUAL 0) - - endif (A2X) -endmacro(MACRO_ASCIIDOC2MAN _a2m_input _a2m_file) diff --git a/src/csync/CMakeLists.txt b/src/csync/CMakeLists.txt index 59f574712..09dc930b1 100644 --- a/src/csync/CMakeLists.txt +++ b/src/csync/CMakeLists.txt @@ -14,10 +14,6 @@ include(DefineOptions.cmake) include(DefineInstallationPaths) -# add macros -include(MacroAddPlugin) -include(MacroCopyFile) - find_package(SQLite3 3.8.0 REQUIRED) include(ConfigureChecks.cmake) diff --git a/src/csync/ConfigureChecks.cmake b/src/csync/ConfigureChecks.cmake index 6d64d5a63..e035e2ebb 100644 --- a/src/csync/ConfigureChecks.cmake +++ b/src/csync/ConfigureChecks.cmake @@ -25,16 +25,6 @@ if (NOT LINUX) set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ) endif (NOT LINUX) -check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME) -if (HAVE_LIBRT OR HAVE_CLOCK_GETTIME) - set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} rt) -endif (HAVE_LIBRT OR HAVE_CLOCK_GETTIME) - -check_library_exists(dl dlopen "" HAVE_LIBDL) -if (HAVE_LIBDL) - set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} dl) -endif (HAVE_LIBDL) - check_function_exists(asprintf HAVE_ASPRINTF) check_function_exists(fnmatch HAVE_FNMATCH) diff --git a/src/csync/config_csync.h.cmake b/src/csync/config_csync.h.cmake index f5c9f09b2..d1a64cb95 100644 --- a/src/csync/config_csync.h.cmake +++ b/src/csync/config_csync.h.cmake @@ -6,10 +6,6 @@ #cmakedefine BINARYDIR "${BINARYDIR}" #cmakedefine SOURCEDIR "${SOURCEDIR}" -#cmakedefine HAVE_CLOCK_GETTIME - -#cmakedefine WITH_LOG4C 1 - #cmakedefine HAVE_ARGP_H 1 #cmakedefine HAVE_TIMEGM 1 diff --git a/src/csync/std/c_private.h b/src/csync/std/c_private.h index 26bba70db..76f25e453 100644 --- a/src/csync/std/c_private.h +++ b/src/csync/std/c_private.h @@ -102,10 +102,6 @@ typedef struct stat csync_stat_t; #endif #endif -#ifndef HAVE_STRERROR_R -#define strerror_r(errnum, buf, buflen) snprintf(buf, buflen, "%s", strerror(errnum)) -#endif - #ifndef HAVE_LSTAT #define lstat _stat #endif From 5d0aa5f0396bdccbf5f67c7e326f7ac42c622a12 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 14 Dec 2017 18:30:57 +0100 Subject: [PATCH 076/138] Remove unused c_path --- src/csync/CMakeLists.txt | 1 - src/csync/std/c_lib.h | 1 - src/csync/std/c_path.c | 392 ------------------- src/csync/std/c_path.h | 123 ------ src/csync/std/c_string.c | 1 - src/csync/std/c_time.c | 1 - src/libsync/filesystem.cpp | 1 - test/csync/CMakeLists.txt | 1 - test/csync/encoding_tests/check_encoding.cpp | 1 - test/csync/std_tests/check_std_c_path.c | 185 --------- 10 files changed, 707 deletions(-) delete mode 100644 src/csync/std/c_path.c delete mode 100644 src/csync/std/c_path.h delete mode 100644 test/csync/std_tests/check_std_c_path.c diff --git a/src/csync/CMakeLists.txt b/src/csync/CMakeLists.txt index 09dc930b1..1d3207056 100644 --- a/src/csync/CMakeLists.txt +++ b/src/csync/CMakeLists.txt @@ -69,7 +69,6 @@ set(csync_SRCS vio/csync_vio.cpp std/c_alloc.c - std/c_path.c std/c_string.c std/c_time.c std/c_utf8.cpp diff --git a/src/csync/std/c_lib.h b/src/csync/std/c_lib.h index 43f352ff4..2f0135ede 100644 --- a/src/csync/std/c_lib.h +++ b/src/csync/std/c_lib.h @@ -23,7 +23,6 @@ #include "c_macro.h" #include "c_alloc.h" -#include "c_path.h" #include "c_string.h" #include "c_time.h" #include "c_private.h" diff --git a/src/csync/std/c_path.c b/src/csync/std/c_path.c deleted file mode 100644 index f81799c05..000000000 --- a/src/csync/std/c_path.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * cynapses libc functions - * - * Copyright (c) 2008-2013 by Andreas Schneider - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include -#include -#include -#include -#include -#include - -#include "c_private.h" -#include "c_alloc.h" -#include "c_path.h" -#include "c_string.h" -#include "c_utf8.h" - -/* - * dirname - parse directory component. - */ -char *c_dirname (const char *path) { - char *newbuf = NULL; - unsigned int len; - - if (path == NULL || *path == '\0') { - return c_strdup("."); - } - - len = strlen(path); - - /* Remove trailing slashes */ - while(len > 0 && path[len - 1] == '/') --len; - - /* We have only slashes */ - if (len == 0) { - return c_strdup("/"); - } - - /* goto next slash */ - while(len > 0 && path[len - 1] != '/') --len; - - if (len == 0) { - return c_strdup("."); - } else if (len == 1) { - return c_strdup("/"); - } - - /* Remove slashes again */ - while(len > 0 && path[len - 1] == '/') --len; - - newbuf = c_malloc(len + 1); - - strncpy(newbuf, path, len); - newbuf[len] = '\0'; - - return newbuf; -} - -char *c_basename (const char *path) { - char *newbuf = NULL; - const char *s; - unsigned int len; - - if (path == NULL || *path == '\0') { - return c_strdup("."); - } - - len = strlen(path); - /* Remove trailing slashes */ - while(len > 0 && path[len - 1] == '/') --len; - - /* We have only slashes */ - if (len == 0) { - return c_strdup("/"); - } - - while(len > 0 && path[len - 1] != '/') --len; - - if (len > 0) { - s = path + len; - len = strlen(s); - - while(len > 0 && s[len - 1] == '/') --len; - } else { - return c_strdup(path); - } - - newbuf = c_malloc(len + 1); - - strncpy(newbuf, s, len); - newbuf[len] = '\0'; - - return newbuf; -} - -int c_parse_uri(const char *uri, - char **scheme, - char **user, char **passwd, - char **host, unsigned int *port, - char **path) { - const char *p, *z; - - if (uri == NULL || *uri == '\0') { - return -1; - } - - /* - * uri = scheme://user:password@host:port/path - * p = ^ - * z = ^ - */ - p = z = uri; - - /* check for valid scheme; git+ssh, pop3 */ - while (isalpha((int) *p) || isdigit((int) *p) || - *p == '+' || *p == '-') { - /* - * uri = scheme://user:password@host:port/path - * p = ^ - * z = ^ - */ - p++; - } - - /* get scheme */ - if (*p == ':') { - if (scheme != NULL) { - *scheme = c_strndup(z, p - z); - - if (*scheme == NULL) { - errno = ENOMEM; - return -1; - } - } - p++; - z = p; - } - - /* - * uri = scheme://user:password@host:port/path - * p = ^ - * z = ^ - */ - p = z; - - /* do we have a hostname */ - if (p[0] == '/' && p[1] == '/') { - /* - * uri = scheme://user:password@host:port/path - * p = ^ - * z = ^ - */ - z += 2; - p = z; - - /* check for user and passwd */ - while (*p && *p != '@' && *p != '/') { - /* - * uri = scheme://user:password@host:port/path - * p = ^ or ^ - * z = ^ - */ - p++; - } - - /* check for user and password */ - if (*p == '@') { - const char *q; - - q = p; - - /* check if we have a password */ - while (q > z && *q != ':') { - /* - * uri = scheme://user:password@host:port/path - * p = ^ - * z = ^ - * q = ^ - */ - q--; - } - - /* password found */ - if (*q == ':') { - if (user != NULL) { - *user = c_strndup(z, q - z); - if (*user == NULL) { - errno = ENOMEM; - if (scheme != NULL) SAFE_FREE(*scheme); - return -1; - } - } - - if (passwd != NULL) { - *passwd = c_strndup(q + 1, p - (q + 1)); - if (*passwd == NULL) { - if (scheme != NULL) SAFE_FREE(*scheme); - if (user != NULL) SAFE_FREE(*user); - errno = ENOMEM; - return -1; - } - } - } else { - /* user only */ - if (user != NULL) { - *user = c_strndup(z, p - z); - if( *user == NULL) { - if (scheme != NULL) SAFE_FREE(*scheme); - errno = ENOMEM; - return -1; - } - } - } - - p++; - z = p; - } - - /* - * uri = scheme://user:password@host:port/path - * p = ^ - * z = ^ - */ - p = z; - - /* check for IPv6 address */ - if (*p == '[') { - /* - * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path - * p = ^ - * z = ^ - */ - p++; - - /* check if we have a valid IPv6 address */ - while (*p && (isxdigit((int) *p) || *p == '.' || *p == ':')) { - /* - * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path - * p = ^ - * z = ^ - */ - p++; - } - - /* valid IPv6 address found */ - if (*p == ']') { - /* - * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path - * p = ^ - * z = ^ - */ - z++; - - if (host != NULL) { - *host = c_strndup(z, p - z); - if (*host == NULL) { - if (scheme != NULL) SAFE_FREE(*scheme); - if (user != NULL) SAFE_FREE(*user); - if (passwd != NULL) SAFE_FREE(*passwd); - errno = ENOMEM; - return -1; - } - } - - /* - * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path - * p = ^ - * z = ^ - */ - p++; - } else { - /* invalid IPv6 address, assume a hostname */ - p = z; - - while (*p && *p != ':' && *p != '/') { - p++; - /* - * uri = scheme://user:password@host:port/path - * p = ^ or ^ - * z = ^ - */ - } - - if (host != NULL) { - *host = c_strndup(z, p - z); - if (*host == NULL) { - if (scheme != NULL) SAFE_FREE(*scheme); - if (user != NULL) SAFE_FREE(*user); - if (passwd != NULL) SAFE_FREE(*passwd); - errno = ENOMEM; - return -1; - } - } - } - } else { - /* check for hostname */ - while (*p && *p != ':' && *p != '/') { - /* - * uri = scheme://user:password@host:port/path - * p = ^ ^ - * z = ^ - */ - p++; - } - - if (host != NULL) { - *host = c_strndup(z, p - z); - if (*host == NULL) { - if (scheme != NULL) SAFE_FREE(*scheme); - if (user != NULL) SAFE_FREE(*user); - if (passwd != NULL) SAFE_FREE(*passwd); - errno = ENOMEM; - return -1; - } - } - } - - /* check for port */ - if (*p == ':') { - char **e = NULL; - /* - * uri = scheme://user:password@host:port/path - * p = ^ - * z = ^ - */ - z = ++p; - - /* get only the digits */ - while (isdigit((int) *p)) { - /* - * uri = scheme://user:password@host:port/path - * p = ^ - * z = ^ - */ - e = (char **) &p; - p++; - } - - if (port != NULL) { - *port = strtoul(z, e, 0); - } - - /* - * uri = scheme://user:password@host:port/path - * p = ^ - */ - } - } - - if (*p == '\0') { - return 0; - } - - /* get the path with the leading slash */ - if (*p == '/') { - if (path != NULL) { - *path = c_strdup(p); - if (*path == NULL) { - if (scheme != NULL) SAFE_FREE(*scheme); - if (user != NULL) SAFE_FREE(*user); - if (passwd != NULL) SAFE_FREE(*passwd); - if (host != NULL) SAFE_FREE(*host); - errno = ENOMEM; - return -1; - } - } - - return 0; - } - - return -1; -} diff --git a/src/csync/std/c_path.h b/src/csync/std/c_path.h deleted file mode 100644 index d0dd43d9e..000000000 --- a/src/csync/std/c_path.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * cynapses libc functions - * - * Copyright (c) 2008-2013 by Andreas Schneider - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file c_path.h - * - * @brief Interface of the cynapses libc path functions - * - * @defgroup cynPathInternals cynapses libc path functions - * @ingroup cynLibraryAPI - * - * @{ - */ - -#ifndef _C_PATH_H -#define _C_PATH_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "c_macro.h" -#include "c_private.h" - -/** - * @brief Parse directory component. - * - * dirname breaks a null-terminated pathname string into a directory component. - * In the usual case, c_dirname() returns the string up to, but not including, - * the final '/'. Trailing '/' characters are not counted as part of the - * pathname. The caller must free the memory. - * - * @param path The path to parse. - * - * @return The dirname of path or NULL if we can't allocate memory. If path - * does not contain a slash, c_dirname() returns the string ".". If - * path is the string "/", it returns the string "/". If path is - * NULL or an empty string, "." is returned. - */ -char *c_dirname(const char *path); - -/** - * @brief basename - parse filename component. - * - * basename breaks a null-terminated pathname string into a filename component. - * c_basename() returns the component following the final '/'. Trailing '/' - * characters are not counted as part of the pathname. - * - * @param path The path to parse. - * - * @return The filename of path or NULL if we can't allocate memory. If path - * is a the string "/", basename returns the string "/". If path is - * NULL or an empty string, "." is returned. - */ -char *c_basename (const char *path); - -/** - * @brief parse a uri and split it into components. - * - * parse_uri parses an uri in the format - * - * [:][//[[:]@][:]]/[] - * - * into its compoments. If you only want a special component, - * pass NULL for all other components. All components will be allocated if they have - * been found. - * - * @param uri The uri to parse. - * @param scheme String for the scheme component - * @param user String for the username component - * @param passwd String for the password component - * @param host String for the password component - * @param port Integer for the port - * @param path String for the path component with a leading slash. - * - * @return 0 on success, < 0 on error. - */ -int c_parse_uri(const char *uri, char **scheme, char **user, char **passwd, - char **host, unsigned int *port, char **path); - -/** - * @brief Parts of a path. - * - * @param directory '\0' terminated path including the final '/' - * - * @param filename '\0' terminated string - * - * @param extension '\0' terminated string - * - */ -typedef struct -{ - char * directory; - char * filename; - char * extension; -} C_PATHINFO; - -/** - * }@ - */ - -#ifdef __cplusplus -} -#endif - -#endif /* _C_PATH_H */ diff --git a/src/csync/std/c_string.c b/src/csync/std/c_string.c index 8929f2458..14f9d5e88 100644 --- a/src/csync/std/c_string.c +++ b/src/csync/std/c_string.c @@ -32,7 +32,6 @@ #include #include "c_string.h" -#include "c_path.h" #include "c_alloc.h" #include "c_macro.h" diff --git a/src/csync/std/c_time.c b/src/csync/std/c_time.c index c28459e1b..28528fdc6 100644 --- a/src/csync/std/c_time.c +++ b/src/csync/std/c_time.c @@ -22,7 +22,6 @@ #include "c_private.h" #include "c_string.h" -#include "c_path.h" #include "c_time.h" #include "c_utf8.h" diff --git a/src/libsync/filesystem.cpp b/src/libsync/filesystem.cpp index 69bbbe3f1..648b6ebf3 100644 --- a/src/libsync/filesystem.cpp +++ b/src/libsync/filesystem.cpp @@ -23,7 +23,6 @@ extern "C" int c_utimes(const char *, const struct timeval *); #include "csync.h" #include "vio/csync_vio_local.h" -#include "std/c_path.h" #include "std/c_string.h" #include "std/c_utf8.h" diff --git a/test/csync/CMakeLists.txt b/test/csync/CMakeLists.txt index 8e722e0dc..f5f7b68fb 100644 --- a/test/csync/CMakeLists.txt +++ b/test/csync/CMakeLists.txt @@ -22,7 +22,6 @@ set(TEST_TARGET_LIBRARIES ${TORTURE_LIBRARY}) # std add_cmocka_test(check_std_c_alloc std_tests/check_std_c_alloc.c ${TEST_TARGET_LIBRARIES}) add_cmocka_test(check_std_c_jhash std_tests/check_std_c_jhash.c ${TEST_TARGET_LIBRARIES}) -add_cmocka_test(check_std_c_path std_tests/check_std_c_path.c ${TEST_TARGET_LIBRARIES}) add_cmocka_test(check_std_c_str std_tests/check_std_c_str.c ${TEST_TARGET_LIBRARIES}) diff --git a/test/csync/encoding_tests/check_encoding.cpp b/test/csync/encoding_tests/check_encoding.cpp index d2459b8d2..372005e93 100644 --- a/test/csync/encoding_tests/check_encoding.cpp +++ b/test/csync/encoding_tests/check_encoding.cpp @@ -19,7 +19,6 @@ */ #include #include "c_string.h" -#include "c_path.h" #include "c_utf8.h" #include "common/filesystembase.h" #include "torture.h" diff --git a/test/csync/std_tests/check_std_c_path.c b/test/csync/std_tests/check_std_c_path.c deleted file mode 100644 index 2513d3fa2..000000000 --- a/test/csync/std_tests/check_std_c_path.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2008-2013 by Andreas Schneider - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include -#include -#include -#include - -#include "std/c_path.h" - -#include "torture.h" - -static void check_c_basename(void **state) -{ - char *bname; - - (void) state; /* unused */ - - bname = c_basename("/usr/lib"); - assert_string_equal(bname, "lib"); - free(bname); - - bname = c_basename("/usr//"); - assert_string_equal(bname, "usr"); - free(bname); - - bname = c_basename("usr"); - assert_string_equal(bname, "usr"); - free(bname); - - bname = c_basename("///"); - assert_string_equal(bname, "/"); - free(bname); - - bname = c_basename("/"); - assert_string_equal(bname, "/"); - free(bname); - - bname = c_basename("."); - assert_string_equal(bname, "."); - free(bname); - - bname = c_basename(".."); - assert_string_equal(bname, ".."); - free(bname); - - bname = c_basename(""); - assert_string_equal(bname, "."); - free(bname); - - bname = c_basename(NULL); - assert_string_equal(bname, "."); - free(bname); -} - -static void check_c_basename_uri(void **state) -{ - char *bname = NULL; - - (void) state; /* unused */ - - bname = c_basename("smb://server/share/dir/"); - assert_string_equal(bname, "dir"); - free(bname); -} - -static void check_c_dirname(void **state) -{ - char *dname; - - (void) state; /* unused */ - - dname = c_dirname("/usr/lib"); - assert_string_equal(dname, "/usr"); - free(dname); - - dname = c_dirname("/usr//"); - assert_string_equal(dname, "/"); - free(dname); - - dname = c_dirname("usr"); - assert_string_equal(dname, "."); - free(dname); - - dname = c_dirname("/"); - assert_string_equal(dname, "/"); - free(dname); - - dname = c_dirname("///"); - assert_string_equal(dname, "/"); - free(dname); - - dname = c_dirname("."); - assert_string_equal(dname, "."); - free(dname); - - dname = c_dirname(".."); - assert_string_equal(dname, "."); - free(dname); - - dname = c_dirname(NULL); - assert_string_equal(dname, "."); - free(dname); -} - -static void check_c_dirname_uri(void **state) -{ - char *dname; - - (void) state; /* unused */ - - dname = c_dirname("smb://server/share/dir"); - assert_string_equal(dname, "smb://server/share"); - free(dname); -} - -static void check_c_parse_uri(void **state) -{ - const char *test_scheme = "git+ssh"; - const char *test_user = "gladiac"; - const char *test_passwd = "secret"; - const char *test_host = "git.csync.org"; - const char *test_path = "/srv/git/csync.git"; - - char *scheme = NULL; - char *user = NULL; - char *passwd = NULL; - char *host = NULL; - unsigned int port; - char *path = NULL; - char uri[1024] = {0}; - int rc; - - (void) state; /* unused */ - - rc = snprintf(uri, sizeof(uri), "%s://%s:%s@%s:22%s", - test_scheme, test_user, test_passwd, test_host, test_path); - assert_true(rc); - - rc = c_parse_uri(uri, &scheme, &user, &passwd, &host, &port, &path); - assert_int_equal(rc, 0); - - assert_string_equal(test_scheme, scheme); - assert_string_equal(test_user, user); - assert_string_equal(test_passwd, passwd); - assert_string_equal(test_host, host); - assert_int_equal(port, 22); - assert_string_equal(test_path, path); - - free(scheme); - free(user); - free(passwd); - free(host); - free(path); -} - -int torture_run_tests(void) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(check_c_basename), - cmocka_unit_test(check_c_basename_uri), - cmocka_unit_test(check_c_dirname), - cmocka_unit_test(check_c_dirname_uri), - cmocka_unit_test(check_c_parse_uri), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} - From 1c721e9422069744dcc3447219487bf2695a81b6 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 14 Dec 2017 18:07:21 +0100 Subject: [PATCH 077/138] shell_integration/dolphin: Silence some warnings --- shell_integration/dolphin/CMakeLists.txt | 1 + shell_integration/dolphin/ownclouddolphinactionplugin.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/shell_integration/dolphin/CMakeLists.txt b/shell_integration/dolphin/CMakeLists.txt index 394bc7eee..14a72041f 100644 --- a/shell_integration/dolphin/CMakeLists.txt +++ b/shell_integration/dolphin/CMakeLists.txt @@ -19,6 +19,7 @@ set_package_properties(DolphinVcs PROPERTIES PURPOSE "Provides plugin interfaces for Dolphin." ) +set(KDE_INSTALL_DIRS_NO_DEPRECATED TRUE) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings) diff --git a/shell_integration/dolphin/ownclouddolphinactionplugin.cpp b/shell_integration/dolphin/ownclouddolphinactionplugin.cpp index c47cb783d..71c1f1171 100644 --- a/shell_integration/dolphin/ownclouddolphinactionplugin.cpp +++ b/shell_integration/dolphin/ownclouddolphinactionplugin.cpp @@ -31,6 +31,7 @@ class OwncloudDolphinPluginAction : public KAbstractFileItemActionPlugin { + Q_OBJECT public: explicit OwncloudDolphinPluginAction(QObject* parent, const QList&) : KAbstractFileItemActionPlugin(parent) { } From 3ae327ea8ea31da46995da01c6b623c14248dc65 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 14 Dec 2017 17:54:31 +0100 Subject: [PATCH 078/138] Modernize out CMakeLists.txt Mainly uses target_include_directories instead of include_directories so libraries public include directory get automatically added when adding the target in target_link_library --- CMakeLists.txt | 11 +----- src/cmd/CMakeLists.txt | 16 ++------ src/crashreporter/CMakeLists.txt | 9 +---- src/csync/CMakeLists.txt | 66 ++++++++++---------------------- src/gui/CMakeLists.txt | 30 ++++++--------- src/libsync/CMakeLists.txt | 40 ++++--------------- test/CMakeLists.txt | 2 + test/csync/CMakeLists.txt | 8 ++-- 8 files changed, 50 insertions(+), 132 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 132d93b1c..0f4abfd3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.1) project(client) @@ -183,15 +183,6 @@ if(BUILD_CLIENT) find_package(Sphinx) find_package(PdfLatex) - find_package(SQLite3 3.8.0 REQUIRED) - # On some OS, we want to use our own, not the system sqlite - if (USE_OUR_OWN_SQLITE3) - include_directories(BEFORE ${SQLITE3_INCLUDE_DIR}) - if (WIN32) - add_definitions(-DSQLITE_API=__declspec\(dllimport\)) - endif() - endif() - find_package(ZLIB REQUIRED) endif() diff --git a/src/cmd/CMakeLists.txt b/src/cmd/CMakeLists.txt index 4244fba8c..449313668 100644 --- a/src/cmd/CMakeLists.txt +++ b/src/cmd/CMakeLists.txt @@ -7,17 +7,7 @@ set(cmd_SRC simplesslerrorhandler.cpp netrcparser.cpp ) -include_directories(${CMAKE_SOURCE_DIR}/src/libsync - ${CMAKE_BINARY_DIR}/src/libsync - ) -# csync is required. -include_directories(${CMAKE_SOURCE_DIR}/src/csync - ${CMAKE_BINARY_DIR}/src/csync - ) - -# Need tokenizer for netrc parser -include_directories(${CMAKE_SOURCE_DIR}/src/3rdparty/qtokenizer) if(UNIX AND NOT APPLE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE") @@ -32,7 +22,10 @@ if(NOT BUILD_LIBRARIES_ONLY) set_target_properties(${cmd_NAME} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE};${CMAKE_INSTALL_RPATH}" ) - target_link_libraries(${cmd_NAME} ${synclib_NAME} Qt5::Core Qt5::Network) + target_link_libraries(${cmd_NAME} ocsync ${synclib_NAME} Qt5::Core Qt5::Network) + + # Need tokenizer for netrc parser + target_include_directories(${cmd_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src/3rdparty/qtokenizer) endif() if(BUILD_OWNCLOUD_OSX_BUNDLE) @@ -44,7 +37,6 @@ elseif(NOT BUILD_LIBRARIES_ONLY) ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() - # FIXME: The following lines are dup in src/gui and src/cmd because it needs to be done after both are installed #FIXME: find a nice solution to make the second if(BUILD_OWNCLOUD_OSX_BUNDLE) unnecessary # currently it needs to be done because the code right above needs to be executed no matter diff --git a/src/crashreporter/CMakeLists.txt b/src/crashreporter/CMakeLists.txt index 0d7938a34..3354e9a5e 100644 --- a/src/crashreporter/CMakeLists.txt +++ b/src/crashreporter/CMakeLists.txt @@ -4,10 +4,6 @@ cmake_policy(SET CMP0017 NEW) list(APPEND crashreporter_SOURCES main.cpp) list(APPEND crashreporter_RC resources.qrc) -qt_wrap_ui( crashreporter_UI_HEADERS ${crashreporter_UI} ) -qt_add_resources( crashreporter_RC_RCC ${crashreporter_RC} ) - - # TODO: differentiate release channel # if(BUILD_RELEASE) # set(CRASHREPORTER_RELEASE_CHANNEL "release") @@ -19,10 +15,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CrashReporterConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/CrashReporterConfig.h) -include_directories(${CMAKE_CURRENT_BINARY_DIR} - "../3rdparty/libcrashreporter-qt/src/" -) - if(NOT BUILD_LIBRARIES_ONLY) add_executable( ${CRASHREPORTER_EXECUTABLE} WIN32 @@ -32,6 +24,7 @@ if(NOT BUILD_LIBRARIES_ONLY) ${crashreporter_RC_RCC} ) + target_include_directories(${CRASHREPORTER_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/libcrashreporter-qt/src/" ) set_target_properties(${CRASHREPORTER_EXECUTABLE} PROPERTIES AUTOMOC ON) set_target_properties(${CRASHREPORTER_EXECUTABLE} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} ) set_target_properties(${CRASHREPORTER_EXECUTABLE} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}" ) diff --git a/src/csync/CMakeLists.txt b/src/csync/CMakeLists.txt index 1d3207056..a10ac3b05 100644 --- a/src/csync/CMakeLists.txt +++ b/src/csync/CMakeLists.txt @@ -23,32 +23,6 @@ if (MEM_NULL_TESTS) add_definitions(-DCSYNC_MEM_NULL_TESTS) endif (MEM_NULL_TESTS) -# Statically include sqlite - -set(CSYNC_PUBLIC_INCLUDE_DIRS - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/std - ${CMAKE_SOURCE_DIR} - CACHE INTERNAL "csync public include directories" -) - -set(CSYNC_PRIVATE_INCLUDE_DIRS - ${SQLITE3_INCLUDE_DIRS} - ${CMAKE_BINARY_DIR} -) - -set(CSYNC_LIBRARY - ocsync - CACHE INTERNAL "ocsync library" -) - -set(CSYNC_LINK_LIBRARIES - ${CSYNC_REQUIRED_LIBRARIES} - ${SQLITE3_LIBRARIES} - Qt5::Core Qt5::Concurrent -) - # Specific option for builds tied to servers that do not support renaming extensions set(NO_RENAME_EXTENSION 0 CACHE BOOL "Do not issue rename if the extension changes") if(NO_RENAME_EXTENSION) @@ -89,39 +63,39 @@ if(NOT HAVE_ASPRINTF AND NOT HAVE___MINGW_ASPRINTF) list(APPEND csync_SRCS std/asprintf.c) endif() +if (USE_OUR_OWN_SQLITE3) + list(APPEND csync_SRCS ${SQLITE3_SOURCE}) +endif() configure_file(csync_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h) - -# Statically include sqlite -if (USE_OUR_OWN_SQLITE3) - list(APPEND csync_SRCS ${SQLITE3_SOURCE}) - if (WIN32) - # We want to export sqlite symbols from the ocsync DLL without - # having to patch both sqlite3.h and the amalgation sqlite3.c, - # so do the import/export magic manually through the build system. - remove_definitions(-DSQLITE_API=__declspec\(dllimport\)) - add_definitions(-DSQLITE_API=__declspec\(dllexport\)) - endif() -endif() - - +set(CSYNC_LIBRARY ocsync) add_library(${CSYNC_LIBRARY} SHARED ${common_SOURCES} ${csync_SRCS}) -#add_library(${CSYNC_LIBRARY}_static STATIC ${csync_SRCS}) target_include_directories( ${CSYNC_LIBRARY} - PUBLIC ${CSYNC_PUBLIC_INCLUDE_DIRS} - PRIVATE ${CSYNC_PRIVATE_INCLUDE_DIRS} + PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/std ) -generate_export_header( ${CSYNC_LIBRARY} +find_package(SQLite3 3.8.0 REQUIRED) +if (USE_OUR_OWN_SQLITE3) + # make sure that the path for the local sqlite3 is before the system one + target_include_directories(${CSYNC_LIBRARY} BEFORE PRIVATE ${SQLITE3_INCLUDE_DIR}) +else() + target_include_directories(${CSYNC_LIBRARY} PRIVATE ${SQLITE3_INCLUDE_DIR}) +endif() + + +generate_export_header(${CSYNC_LIBRARY} EXPORT_MACRO_NAME OCSYNC_EXPORT EXPORT_FILE_NAME ocsynclib.h ) -target_link_libraries(${CSYNC_LIBRARY} ${CSYNC_LINK_LIBRARIES}) -#target_link_libraries(${CSYNC_LIBRARY}_static ${CSYNC_LINK_LIBRARIES}) +target_link_libraries(${CSYNC_LIBRARY} + ${CSYNC_REQUIRED_LIBRARIES} + ${SQLITE3_LIBRARIES} + Qt5::Core Qt5::Concurrent +) if(ZLIB_FOUND) target_link_libraries(${CSYNC_LIBRARY} ZLIB::ZLIB) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index b04159ad8..e347c3831 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -173,23 +173,6 @@ else() list(APPEND 3rdparty_SRC ../3rdparty/qtlockedfile/qtlockedfile_win.cpp ) endif() -set(3rdparty_INC - ${CMAKE_SOURCE_DIR}/src/3rdparty/QProgressIndicator - ${CMAKE_SOURCE_DIR}/src/3rdparty/qtlockedfile - ${CMAKE_SOURCE_DIR}/src/3rdparty/qtmacgoodies/src - ${CMAKE_SOURCE_DIR}/src/3rdparty/qtsingleapplication - ) - -include_directories(${3rdparty_INC}) - -# csync is required. -include_directories(${CMAKE_SOURCE_DIR}/src/csync - ${CMAKE_BINARY_DIR}/src/csync - ) -include_directories(../libsync ${CMAKE_CURRENT_BINARY_DIR}/../libsync) -include_directories(${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - ) find_package(Qt5LinguistTools) if(Qt5LinguistTools_FOUND) @@ -285,8 +268,9 @@ else() install(FILES ${qtkeychain_I18N} DESTINATION ${QM_DIR}) endif() -add_library(updater STATIC ${updater_SRCS} ${updaterMoc}) +add_library(updater STATIC ${updater_SRCS}) target_link_libraries(updater ${synclib_NAME} Qt5::Widgets Qt5::Network Qt5::Xml) +target_include_directories(updater PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} @@ -300,6 +284,14 @@ target_link_libraries( ${APPLICATION_EXECUTABLE} ${synclib_NAME} ) target_link_libraries( ${APPLICATION_EXECUTABLE} updater ) target_link_libraries( ${APPLICATION_EXECUTABLE} ${OS_SPECIFIC_LINK_LIBRARIES} ) +target_include_directories(${APPLICATION_EXECUTABLE} PRIVATE + ${CMAKE_SOURCE_DIR}/src/3rdparty/QProgressIndicator + ${CMAKE_SOURCE_DIR}/src/3rdparty/qtlockedfile + ${CMAKE_SOURCE_DIR}/src/3rdparty/qtmacgoodies/src + ${CMAKE_SOURCE_DIR}/src/3rdparty/qtsingleapplication + ${CMAKE_CURRENT_BINARY_DIR} +) + ## handle DBUS for Fdo notifications if( UNIX AND NOT APPLE ) find_package(Qt5 COMPONENTS DBus) @@ -314,7 +306,7 @@ endif() if(WITH_CRASHREPORTER) target_link_libraries( ${APPLICATION_EXECUTABLE} crashreporter-handler) - include_directories( "../3rdparty/libcrashreporter-qt/src/" ) + target_include_directories(${APPLICATION_EXECUTABLE} "../3rdparty/libcrashreporter-qt/src/" ) if(UNIX AND NOT MAC) find_package(Threads REQUIRED) diff --git a/src/libsync/CMakeLists.txt b/src/libsync/CMakeLists.txt index 6b0633da5..69092f2f3 100644 --- a/src/libsync/CMakeLists.txt +++ b/src/libsync/CMakeLists.txt @@ -1,11 +1,6 @@ project(libsync) set(CMAKE_AUTOMOC TRUE) -include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) -# csync is required. -include_directories(${CMAKE_SOURCE_DIR}/src/csync - ${CMAKE_BINARY_DIR}/src/csync - ) if ( APPLE ) list(APPEND OS_SPECIFIC_LINK_LIBRARIES @@ -94,7 +89,8 @@ IF (NOT APPLE) ) ENDIF(NOT APPLE) -list(APPEND libsync_LINK_TARGETS +add_library(${synclib_NAME} SHARED ${libsync_SRCS}) +target_link_libraries(${synclib_NAME} ocsync ${OS_SPECIFIC_LINK_LIBRARIES} Qt5::Core Qt5::Network @@ -102,20 +98,16 @@ list(APPEND libsync_LINK_TARGETS if (NOT TOKEN_AUTH_ONLY) find_package(Qt5 REQUIRED COMPONENTS Widgets) - list(APPEND libsync_LINK_TARGETS Qt5::Widgets) -endif() - -if(QTKEYCHAIN_FOUND OR QT5KEYCHAIN_FOUND) - list(APPEND libsync_LINK_TARGETS ${QTKEYCHAIN_LIBRARY}) - include_directories(${QTKEYCHAIN_INCLUDE_DIR}) + target_link_libraries(${synclib_NAME} Qt5::Widgets ${QTKEYCHAIN_LIBRARY}) + target_include_directories(${synclib_NAME} PRIVATE ${QTKEYCHAIN_INCLUDE_DIR}) endif() if(INOTIFY_FOUND) - include_directories(${INOTIFY_INCLUDE_DIR}) + target_include_directories(${synclib_NAME} PRIVATE ${INOTIFY_INCLUDE_DIR}) link_directories(${INOTIFY_LIBRARY_DIR}) + target_link_libraries(${synclib_NAME} ${INOTIFY_LIBRARY} ) endif() -add_library(${synclib_NAME} SHARED ${libsync_SRCS} ${syncMoc}) GENERATE_EXPORT_HEADER( ${synclib_NAME} BASE_NAME ${synclib_NAME} EXPORT_MACRO_NAME OWNCLOUDSYNC_EXPORT @@ -123,6 +115,8 @@ GENERATE_EXPORT_HEADER( ${synclib_NAME} STATIC_DEFINE OWNCLOUD_BUILT_AS_STATIC ) +target_include_directories(${synclib_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + set_target_properties( ${synclib_NAME} PROPERTIES VERSION ${MIRALL_VERSION} @@ -132,24 +126,6 @@ set_target_properties( ${synclib_NAME} PROPERTIES set_target_properties( ${synclib_NAME} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE};${CMAKE_INSTALL_RPATH}" ) -target_link_libraries(${synclib_NAME} ${libsync_LINK_TARGETS} ) - -if(INOTIFY_FOUND) - target_link_libraries(${synclib_NAME} ${INOTIFY_LIBRARY} ) -endif() - -if(BUILD_LIBRARIES_ONLY) - #add_library(${synclib_NAME}_static STATIC ${libsync_SRCS} ${syncMoc}) - #qt5_use_modules(${synclib_NAME}_static Widgets Network Xml Sql) - - #set_target_properties( ${synclib_NAME}_static PROPERTIES - # VERSION ${MIRALL_VERSION} - # SOVERSION ${MIRALL_SOVERSION} - #) - - #target_link_libraries(${synclib_NAME}_static ${libsync_LINK_TARGETS} ) -endif() - if(NOT BUILD_OWNCLOUD_OSX_BUNDLE) install(TARGETS ${synclib_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4617dfd2e..a2879a42b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,3 +1,4 @@ +find_package(SQLite3 3.8.0 REQUIRED) include_directories(${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/3rdparty/qtokenizer ${CMAKE_SOURCE_DIR}/src/csync @@ -8,6 +9,7 @@ include_directories(${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR}/src/libsync ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} + ${SQLITE3_INCLUDE_DIR} ) include(owncloud_add_test.cmake) diff --git a/test/csync/CMakeLists.txt b/test/csync/CMakeLists.txt index f5f7b68fb..a7ec9f133 100644 --- a/test/csync/CMakeLists.txt +++ b/test/csync/CMakeLists.txt @@ -1,11 +1,9 @@ -project(tests C) +project(tests) set(TORTURE_LIBRARY torture) include_directories( ${CMAKE_CURRENT_SOURCE_DIR} - ${CSYNC_PUBLIC_INCLUDE_DIRS} - ${CSTDLIB_PUBLIC_INCLUDE_DIRS} ${CMAKE_BINARY_DIR} ${CMOCKA_INCLUDE_DIR} ) @@ -13,9 +11,9 @@ include_directories( include_directories(${CHECK_INCLUDE_DIRS}) # create test library add_library(${TORTURE_LIBRARY} STATIC torture.c cmdline.c) -target_link_libraries(${TORTURE_LIBRARY} ${CMOCKA_LIBRARIES} ${CSYNC_LIBRARY} ${CSTDLIB_LIBRARY}) +target_link_libraries(${TORTURE_LIBRARY} ${CMOCKA_LIBRARIES} ${CSYNC_LIBRARY}) -set(TEST_TARGET_LIBRARIES ${TORTURE_LIBRARY}) +set(TEST_TARGET_LIBRARIES ${TORTURE_LIBRARY} Qt5::Core ocsync) # create tests From 437d45981ebe2efc01ef9e236ed422106726e987 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 14 Dec 2017 18:57:12 +0100 Subject: [PATCH 079/138] Remove unused c_strlist --- src/csync/std/c_string.c | 103 ------------------------- src/csync/std/c_string.h | 84 -------------------- test/csync/std_tests/check_std_c_str.c | 67 ---------------- 3 files changed, 254 deletions(-) diff --git a/src/csync/std/c_string.c b/src/csync/std/c_string.c index 14f9d5e88..553b97cb9 100644 --- a/src/csync/std/c_string.c +++ b/src/csync/std/c_string.c @@ -63,106 +63,3 @@ int c_streq(const char *a, const char *b) { return 0; } - -c_strlist_t *c_strlist_new(size_t size) { - c_strlist_t *strlist = NULL; - - if (size == 0) { - errno = EINVAL; - return NULL; - } - - strlist = c_malloc(sizeof(c_strlist_t)); - if (strlist == NULL) { - return NULL; - } - - strlist->vector = (char **) c_malloc(size * sizeof(char *)); - strlist->count = 0; - strlist->size = size; - - return strlist; -} - -c_strlist_t *c_strlist_expand(c_strlist_t *strlist, size_t size) { - if (strlist == NULL || size == 0) { - errno = EINVAL; - return NULL; - } - - if (strlist->size >= size) { - return strlist; - } - - strlist->vector = (char **) c_realloc(strlist->vector, size * sizeof(char *)); - if (strlist->vector == NULL) { - return NULL; - } - - strlist->size = size; - - return strlist; -} - -int c_strlist_add(c_strlist_t *strlist, const char *string) { - if (strlist == NULL || string == NULL) { - return -1; - } - - if (strlist->count < strlist->size) { - strlist->vector[strlist->count] = c_strdup(string); - if (strlist->vector[strlist->count] == NULL) { - return -1; - } - strlist->count++; - } else { - errno = ENOBUFS; - return -1; - } - - return 0; -} - -int c_strlist_add_grow(c_strlist_t **strlist, const char *string) { - if (*strlist == NULL) { - *strlist = c_strlist_new(32); - if (*strlist == NULL) { - return -1; - } - } - - if ((*strlist)->count == (*strlist)->size) { - c_strlist_t *list = c_strlist_expand(*strlist, 2 * (*strlist)->size); - if (list == NULL) { - return -1; - } - *strlist = list; - } - - return c_strlist_add(*strlist, string); -} - -void c_strlist_clear(c_strlist_t *strlist) { - size_t i = 0; - - if (strlist == NULL) { - return; - } - - for (i = 0; i < strlist->count; i++) { - SAFE_FREE(strlist->vector[i]); - } - - strlist->count = 0; -} - -void c_strlist_destroy(c_strlist_t *strlist) { - - if (strlist == NULL) { - return; - } - - c_strlist_clear(strlist); - SAFE_FREE(strlist->vector); - SAFE_FREE(strlist); -} diff --git a/src/csync/std/c_string.h b/src/csync/std/c_string.h index 8b0421b2c..3066ee2b3 100644 --- a/src/csync/std/c_string.h +++ b/src/csync/std/c_string.h @@ -41,28 +41,6 @@ extern "C" { #include -struct c_strlist_s; typedef struct c_strlist_s c_strlist_t; - -/** - * @brief Structure for a stringlist - * - * Using a for loop you can access the strings saved in the vector. - * - * c_strlist_t strlist; - * int i; - * for (i = 0; i < strlist->count; i++) { - * printf("value: %s", strlist->vector[i]; - * } - */ -struct c_strlist_s { - /** The string vector */ - char **vector; - /** The count of the strings saved in the vector */ - size_t count; - /** Size of strings allocated */ - size_t size; -}; - /** * @brief Compare to strings case insensitively. * @@ -84,68 +62,6 @@ int c_strncasecmp(const char *a, const char *b, size_t n); */ int c_streq(const char *a, const char *b); -/** - * @brief Create a new stringlist. - * - * @param size Size to allocate. - * - * @return Pointer to the newly allocated stringlist. NULL if an error occurred. - */ -c_strlist_t *c_strlist_new(size_t size); - -/** - * @brief Expand the stringlist - * - * @param strlist Stringlist to expand - * @param size New size of the strlinglist to expand - * - * @return Pointer to the expanded stringlist. NULL if an error occurred. - */ -c_strlist_t *c_strlist_expand(c_strlist_t *strlist, size_t size); - -/** - * @brief Add a string to the stringlist. - * - * Duplicates the string and stores it in the stringlist. - * - * @param strlist Stringlist to add the string. - * @param string String to add. - * - * @return 0 on success, less than 0 and errno set if an error occurred. - * ENOBUFS if the list is full. - */ -int c_strlist_add(c_strlist_t *strlist, const char *string); - -/** - * @brief Add a string to the stringlist, growing it if necessary - * - * Duplicates the string and stores it in the stringlist. - * It also initializes the stringlist if it starts out as null. - * - * @param strlist Stringlist to add the string. - * @param string String to add. - * - * @return 0 on success, less than 0 and errno set if an error occurred. - */ -int c_strlist_add_grow(c_strlist_t **strlist, const char *string); - -/** - * @brief Removes all strings from the list. - * - * Frees the strings. - * - * @param strlist Stringlist to clear - */ -void c_strlist_clear(c_strlist_t *strlist); - -/** - * @brief Destroy the memory of the stringlist. - * - * Frees the strings and the stringlist. - * - * @param strlist Stringlist to destroy - */ -void c_strlist_destroy(c_strlist_t *strlist); /** * }@ diff --git a/test/csync/std_tests/check_std_c_str.c b/test/csync/std_tests/check_std_c_str.c index 20921b100..e815958c2 100644 --- a/test/csync/std_tests/check_std_c_str.c +++ b/test/csync/std_tests/check_std_c_str.c @@ -49,70 +49,6 @@ static void check_c_streq_null(void **state) assert_false(c_streq(NULL, NULL)); } -static void check_c_strlist_new(void **state) -{ - c_strlist_t *strlist = NULL; - - (void) state; /* unused */ - - strlist = c_strlist_new(42); - assert_non_null(strlist); - assert_int_equal(strlist->size, 42); - assert_int_equal(strlist->count, 0); - - c_strlist_destroy(strlist); -} - -static void check_c_strlist_add(void **state) -{ - int rc; - size_t i = 0; - c_strlist_t *strlist = NULL; - - (void) state; /* unused */ - - strlist = c_strlist_new(42); - assert_non_null(strlist); - assert_int_equal(strlist->size, 42); - assert_int_equal(strlist->count, 0); - - for (i = 0; i < strlist->size; i++) { - rc = c_strlist_add(strlist, (char *) "foobar"); - assert_int_equal(rc, 0); - } - - assert_int_equal(strlist->count, 42); - assert_string_equal(strlist->vector[0], "foobar"); - assert_string_equal(strlist->vector[41], "foobar"); - - c_strlist_destroy(strlist); -} - -static void check_c_strlist_expand(void **state) -{ - c_strlist_t *strlist; - size_t i = 0; - int rc; - - (void) state; /* unused */ - - strlist = c_strlist_new(42); - assert_non_null(strlist); - assert_int_equal(strlist->size, 42); - assert_int_equal(strlist->count, 0); - - strlist = c_strlist_expand(strlist, 84); - assert_non_null(strlist); - assert_int_equal(strlist->size, 84); - - for (i = 0; i < strlist->size; i++) { - rc = c_strlist_add(strlist, (char *) "foobar"); - assert_int_equal(rc, 0); - } - - c_strlist_destroy(strlist); -} - int torture_run_tests(void) @@ -121,9 +57,6 @@ int torture_run_tests(void) cmocka_unit_test(check_c_streq_equal), cmocka_unit_test(check_c_streq_not_equal), cmocka_unit_test(check_c_streq_null), - cmocka_unit_test(check_c_strlist_new), - cmocka_unit_test(check_c_strlist_add), - cmocka_unit_test(check_c_strlist_expand), }; return cmocka_run_group_tests(tests, NULL, NULL); From 1f12d6344b60adc830b13f3ddd0330b66178ccae Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 4 Jan 2018 19:54:56 +0100 Subject: [PATCH 080/138] Fix sqlite compilation (on OSX) --- cmake/modules/Warnings.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/modules/Warnings.cmake b/cmake/modules/Warnings.cmake index 8faff001f..54fe9374b 100644 --- a/cmake/modules/Warnings.cmake +++ b/cmake/modules/Warnings.cmake @@ -5,6 +5,9 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-long-long -Wno-gnu-zero-variadic-macro-arguments") + # Fix sqlite compilation + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-incompatible-pointer-types-discards-qualifiers") + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) From cbf470f17b67e2b599ea61d07538a185a78a6159 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 4 Jan 2018 20:42:23 +0100 Subject: [PATCH 081/138] Fix csync installation on windows --- src/csync/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/csync/CMakeLists.txt b/src/csync/CMakeLists.txt index a10ac3b05..26d66e655 100644 --- a/src/csync/CMakeLists.txt +++ b/src/csync/CMakeLists.txt @@ -135,11 +135,11 @@ else() TARGETS ${CSYNC_LIBRARY} LIBRARY DESTINATION - ${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE} + ${CMAKE_INSTALL_LIBDIR}/${APPLICATION_EXECUTABLE} ARCHIVE DESTINATION - ${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE} + ${CMAKE_INSTALL_LIBDIR}/${APPLICATION_EXECUTABLE} RUNTIME DESTINATION - ${BIN_INSTALL_DIR}/${APPLICATION_EXECUTABLE} + ${CMAKE_INSTALL_BINDIR}/${APPLICATION_EXECUTABLE} ) endif() From 1f9763eda9db9e9aead8060f7f222e0d3f2bf1ce Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 4 Jan 2018 20:43:50 +0100 Subject: [PATCH 082/138] Package libssp-0.dll in NSIS installer. It's needed since 586fd346ead9aaa21aace8b2ffd616f0cc249a9e activated stack-protector-strong --- admin/win/docker/Dockerfile | 2 +- cmake/modules/NSIS.template.in | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/admin/win/docker/Dockerfile b/admin/win/docker/Dockerfile index 1629b9760..7be50c383 100644 --- a/admin/win/docker/Dockerfile +++ b/admin/win/docker/Dockerfile @@ -12,7 +12,7 @@ RUN zypper --non-interactive --gpg-auto-import-keys ar http://download.opensuse. RUN zypper --non-interactive --gpg-auto-import-keys ar http://download.opensuse.org/repositories/isv:ownCloud:toolchains:mingw:win32:2.3/openSUSE_Leap_42.1/isv:ownCloud:toolchains:mingw:win32:2.3.repo RUN zypper --non-interactive --gpg-auto-import-keys install cmake make mingw32-cross-binutils mingw32-cross-cpp mingw32-cross-gcc \ mingw32-cross-gcc-c++ mingw32-cross-pkg-config mingw32-filesystem \ - mingw32-headers mingw32-runtime site-config mingw32-libwebp \ + mingw32-headers mingw32-runtime site-config mingw32-libwebp mingw32-libssp0 \ mingw32-cross-libqt5-qmake mingw32-cross-libqt5-qttools mingw32-libqt5* \ mingw32-qt5keychain* mingw32-angleproject* \ mingw32-cross-nsis mingw32-libopenssl* \ diff --git a/cmake/modules/NSIS.template.in b/cmake/modules/NSIS.template.in index 9b52bf338..967eebdf5 100644 --- a/cmake/modules/NSIS.template.in +++ b/cmake/modules/NSIS.template.in @@ -461,6 +461,7 @@ Section "${APPLICATION_NAME}" SEC_APPLICATION File "${MING_BIN}\libgcc_s_sjlj-1.dll" File "${MING_BIN}\libstdc++-6.dll" File "${MING_BIN}\libwinpthread-1.dll" + File "${MING_BIN}\libssp-0.dll" ;CSync configs File "${SOURCE_PATH}/sync-exclude.lst" From da98e2aa28b98b0b467c8fc2c536137a6a8d0243 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 4 Jan 2018 20:46:14 +0100 Subject: [PATCH 083/138] Fix building sqlite on macOS and Windows --- cmake/modules/Warnings.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/modules/Warnings.cmake b/cmake/modules/Warnings.cmake index 54fe9374b..f2c271e88 100644 --- a/cmake/modules/Warnings.cmake +++ b/cmake/modules/Warnings.cmake @@ -5,8 +5,10 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-long-long -Wno-gnu-zero-variadic-macro-arguments") - # Fix sqlite compilation + # Fix sqlite compilation on macOS set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-incompatible-pointer-types-discards-qualifiers") + # Fix sqlite compilation on MinGW + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-discarded-qualifiers") if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion From 539d6fd92e550344ff2969d0edcf9323337ea2e7 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 4 Jan 2018 20:47:54 +0100 Subject: [PATCH 084/138] Link client against QtMacExtras as it bundles qtmacgoodies --- src/gui/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index e347c3831..fe42148bc 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -299,6 +299,11 @@ if( UNIX AND NOT APPLE ) target_compile_definitions(${APPLICATION_EXECUTABLE} PRIVATE "USE_FDO_NOTIFICATIONS") endif() +if (APPLE) + find_package(Qt5 COMPONENTS MacExtras) + target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::MacExtras) +endif() + if (NOT NO_SHIBBOLETH) find_package(Qt5 COMPONENTS WebKitWidgets) target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::WebKitWidgets) From 6ee87a77cc8557729ed33dd438578468071c8000 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 4 Jan 2018 20:48:34 +0100 Subject: [PATCH 085/138] Fix macOS updater build without deprecated Qt apis --- src/gui/updater/updater.cpp | 18 ++++++++++++------ src/gui/updater/updater.h | 3 ++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/gui/updater/updater.cpp b/src/gui/updater/updater.cpp index 8aff77f6f..868595a42 100644 --- a/src/gui/updater/updater.cpp +++ b/src/gui/updater/updater.cpp @@ -13,6 +13,7 @@ */ #include +#include #include #include "updater/updater.h" @@ -39,7 +40,7 @@ Updater *Updater::instance() return _instance; } -QUrl Updater::addQueryParams(const QUrl &url) +QUrlQuery Updater::getQueryParams() { QUrlQuery query; Theme *theme = Theme::instance(); @@ -74,9 +75,7 @@ QUrl Updater::addQueryParams(const QUrl &url) // to beta channel } - QUrl paramUrl = url; - paramUrl.setQuery(query); - return paramUrl; + return query; } @@ -108,9 +107,16 @@ Updater *Updater::create() qCWarning(lcUpdater) << "Not a valid updater URL, will not do update check"; return 0; } - updateBaseUrl = addQueryParams(updateBaseUrl); + + auto urlQuery = getQueryParams(); + +#if defined(Q_OS_MAC) && defined(HAVE_SPARKLE) + urlQuery.addQueryItem(QLatin1String("sparkle"), QLatin1String("true")); +#endif + + updateBaseUrl.setQuery(urlQuery); + #if defined(Q_OS_MAC) && defined(HAVE_SPARKLE) - updateBaseUrl.addQueryItem(QLatin1String("sparkle"), QLatin1String("true")); return new SparkleUpdater(updateBaseUrl.toString()); #elif defined(Q_OS_WIN32) // the best we can do is notify about updates diff --git a/src/gui/updater/updater.h b/src/gui/updater/updater.h index 77f322638..04d18ac85 100644 --- a/src/gui/updater/updater.h +++ b/src/gui/updater/updater.h @@ -19,6 +19,7 @@ #include class QUrl; +class QUrlQuery; namespace OCC { @@ -50,7 +51,7 @@ protected: private: static QString getSystemInfo(); - static QUrl addQueryParams(const QUrl &url); + static QUrlQuery getQueryParams(); static Updater *create(); static Updater *_instance; }; From 4e52ee9ebd6672bb3f1099e27f3cd2cf9a0635d4 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 4 Jan 2018 20:51:12 +0100 Subject: [PATCH 086/138] Build Explorer extension if building with MSVC --- shell_integration/CMakeLists.txt | 4 + shell_integration/windows/CMakeLists.txt | 4 + .../windows/OCContextMenu/CMakeLists.txt | 16 + .../windows/OCOverlays/CMakeLists.txt | 15 + .../windows/OCUtil/CMakeLists.txt | 17 + .../windows/OCUtil/OCMessage.cpp | 74 ---- shell_integration/windows/OCUtil/OCMessage.h | 42 -- .../windows/OCUtil/ParserUtil.cpp | 389 ------------------ 8 files changed, 56 insertions(+), 505 deletions(-) create mode 100644 shell_integration/windows/CMakeLists.txt create mode 100644 shell_integration/windows/OCContextMenu/CMakeLists.txt create mode 100644 shell_integration/windows/OCOverlays/CMakeLists.txt create mode 100644 shell_integration/windows/OCUtil/CMakeLists.txt delete mode 100644 shell_integration/windows/OCUtil/OCMessage.cpp delete mode 100644 shell_integration/windows/OCUtil/OCMessage.h delete mode 100644 shell_integration/windows/OCUtil/ParserUtil.cpp diff --git a/shell_integration/CMakeLists.txt b/shell_integration/CMakeLists.txt index 87c453bf2..959d94b7e 100644 --- a/shell_integration/CMakeLists.txt +++ b/shell_integration/CMakeLists.txt @@ -21,3 +21,7 @@ if( UNIX AND NOT APPLE ) endif() endif() endif() + +if(MSVC) + add_subdirectory(windows) +endif() diff --git a/shell_integration/windows/CMakeLists.txt b/shell_integration/windows/CMakeLists.txt new file mode 100644 index 000000000..b9c080b6e --- /dev/null +++ b/shell_integration/windows/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(OCContextMenu) +add_subdirectory(OCOverlays) +add_subdirectory(OCUtil) + diff --git a/shell_integration/windows/OCContextMenu/CMakeLists.txt b/shell_integration/windows/OCContextMenu/CMakeLists.txt new file mode 100644 index 000000000..27f45f582 --- /dev/null +++ b/shell_integration/windows/OCContextMenu/CMakeLists.txt @@ -0,0 +1,16 @@ +add_library(OCContextMenu MODULE + dllmain.cpp + OCClientInterface.cpp + OCContextMenu.cpp + OCContextMenuFactory.cpp + OCContextMenuRegHandler.cpp + stdafx.cpp +) + +target_link_libraries(OCContextMenu + OCUtil) + +install(TARGETS OCContextMenu + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +) diff --git a/shell_integration/windows/OCOverlays/CMakeLists.txt b/shell_integration/windows/OCOverlays/CMakeLists.txt new file mode 100644 index 000000000..5e3cb7dff --- /dev/null +++ b/shell_integration/windows/OCOverlays/CMakeLists.txt @@ -0,0 +1,15 @@ +add_library(OCOverlays MODULE + DllMain.cpp + OCOverlay.cpp + OCOverlayFactory.cpp + OCOverlayRegistrationHandler.cpp + stdafx.cpp +) + +target_link_libraries(OCOverlays + OCUtil) + +install(TARGETS OCOverlays + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +) diff --git a/shell_integration/windows/OCUtil/CMakeLists.txt b/shell_integration/windows/OCUtil/CMakeLists.txt new file mode 100644 index 000000000..718a6c327 --- /dev/null +++ b/shell_integration/windows/OCUtil/CMakeLists.txt @@ -0,0 +1,17 @@ +add_library(OCUtil SHARED + CommunicationSocket.cpp + FileUtil.cpp + RegistryUtil.cpp + RemotePathChecker.cpp + stdafx.cpp + StringUtil.cpp +) + +target_include_directories(OCUtil + PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}" +) + +install(TARGETS OCUtil + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/shell_integration/windows/OCUtil/OCMessage.cpp b/shell_integration/windows/OCUtil/OCMessage.cpp deleted file mode 100644 index 31da93180..000000000 --- a/shell_integration/windows/OCUtil/OCMessage.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) - * any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - */ - -#include "OCMessage.h" -#include "ParserUtil.h" -#include "UtilConstants.h" - -#include - -#include -#include - -using namespace std; - -OCMessage::OCMessage(void) -{ - _command = new wstring(); - _value = new wstring(); -} - -OCMessage::~OCMessage(void) -{ -} - -bool OCMessage::InitFromMessage(const wstring* message) -{ - if(message->length() == 0) - { - return false; - } - - if(!ParserUtil::GetItem(COMMAND, message, _command)) - { - return false; - } - - if(!ParserUtil::GetItem(VALUE, message, _value)) - { - return false; - } - - return true; -} - -std::wstring* OCMessage::GetCommand() -{ - return _command; -} - -std::wstring* OCMessage::GetValue() -{ - return _value; -} - -void OCMessage::SetCommand(std::wstring* command) -{ - _command = command; -} - -void OCMessage::SetValue(std::wstring* value) -{ - _value = value; -} diff --git a/shell_integration/windows/OCUtil/OCMessage.h b/shell_integration/windows/OCUtil/OCMessage.h deleted file mode 100644 index 7b0eefca3..000000000 --- a/shell_integration/windows/OCUtil/OCMessage.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) - * any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - */ - -#ifndef OCMESSAGE_H -#define OCMESSAGE_H - -#include - -#pragma once - -class __declspec(dllexport) OCMessage -{ -public: - OCMessage(void); - ~OCMessage(void); - - bool InitFromMessage(const std::wstring*); - - std::wstring* GetCommand(); - std::wstring* GetValue(); - - void SetCommand(std::wstring*); - void SetValue(std::wstring*); - -private: - - std::wstring* _command; - std::wstring* _value; -}; - -#endif \ No newline at end of file diff --git a/shell_integration/windows/OCUtil/ParserUtil.cpp b/shell_integration/windows/OCUtil/ParserUtil.cpp deleted file mode 100644 index 5ca05f670..000000000 --- a/shell_integration/windows/OCUtil/ParserUtil.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/** - * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) - * any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - */ - -#include "ParserUtil.h" -#include "UtilConstants.h" - -#include - -using namespace std; - -bool ParserUtil::GetItem(const wchar_t* item, const wstring* message, wstring* result) -{ - size_t start = message->find(item, 0); - - if(start == string::npos) - { - return false; - } - - size_t end = message->find(COLON, start); - - if(end == string::npos) - { - return false; - } - - //Move to next character after : - end += 1; - - wchar_t c = message->at(end); - - //Move to the next character, which is the start of the value - end += 1; - - if(c == '[') - { - return GetList(end - 1, message, result); - } - else - { - return GetValue(end, message, result); - } -} - -bool ParserUtil::GetList(size_t start, const wstring* message, wstring* result) -{ - size_t end = start + 1; - - int openBraceCount = 1; - - while(openBraceCount > 0) - { - size_t closeBraceLocation = message->find(CLOSE_BRACE, end); - size_t openBraceLocation = message->find(OPEN_BRACE, end); - - if(closeBraceLocation < openBraceLocation) - { - openBraceCount--; - end = closeBraceLocation + 1; - } - else if(openBraceLocation < closeBraceLocation) - { - openBraceCount++; - end = openBraceLocation + 1; - } - - } - - size_t length = end - start; - - return GetString(start, end, message, result); -} - -size_t ParserUtil::GetNextStringItemInList(const wstring* message, size_t start, wstring* result) -{ - size_t end = string::npos; - size_t commaLocation = message->find(COMMA, start); - - if(commaLocation == string::npos) - { - end = message->find(CLOSE_BRACE, start); - if(end == string::npos) - { - end = message->length(); - } - else - { - end = end - 1; - } - } - else - { - end = commaLocation - 1; - } - - if(!GetString(start + 2, end, message, result)) - { - return string::npos; - } - - return end + 2; -} - -size_t ParserUtil::GetNextOCItemInList(const wstring* message, size_t start, wstring* result) -{ - size_t end = message->find(OPEN_CURLY_BRACE, start) + 1; - - int openBraceCount = 1; - - while(openBraceCount > 0) - { - size_t closeBraceLocation = message->find(CLOSE_CURLY_BRACE, end); - size_t openBraceLocation = message->find(OPEN_CURLY_BRACE, end); - - if(closeBraceLocation < openBraceLocation) - { - openBraceCount--; - end = closeBraceLocation + 1; - } - else if(openBraceLocation < closeBraceLocation) - { - openBraceCount++; - end = openBraceLocation + 1; - } - } - - size_t length = end - start; - - if(!GetString(start, end, message, result)) - { - return string::npos; - } - - return end; -} - -bool ParserUtil::GetValue(size_t start, const wstring* message, wstring* result) -{ - if(message->at(start - 1) == '\"') - { - size_t end = message->find(QUOTE, start); - return GetString(start, end, message, result); - } - else - { - start = start - 1; - - size_t end = message->find(COMMA, start); - - result->append(message->substr(start, end-start)); - } - - return true; -} - -bool ParserUtil::GetString(size_t start, size_t end, const wstring* message, wstring* result) -{ - if(end == string::npos) - { - return false; - } - - size_t length = end - start; - - if(length > 0) - { - result->append(message->substr(start, length)); - } - else - { - result->append(L""); - } - - - return true; -} - -bool ParserUtil::IsList(wstring* message) -{ - wchar_t c = message->at(0); - - if(c == '[') - { - return true; - } - - return false; -} - -bool ParserUtil::ParseJsonList(wstring* message, vector* items) -{ - - size_t currentLocation = message->find(OPEN_BRACE, 0); - - while(currentLocation < message->size()) - { - wstring* item = new wstring(); - - currentLocation = ParserUtil::GetNextStringItemInList(message, currentLocation, item); - - if(currentLocation == string::npos) - { - return false; - } - - items->push_back(item); - } - - return true; -} - -bool ParserUtil::ParseOCList(wstring* message, vector* items) -{ - - size_t currentLocation = message->find(OPEN_CURLY_BRACE, 0); - - while(currentLocation < message->size()) - { - wstring* item = new wstring(); - - currentLocation = ParserUtil::GetNextOCItemInList(message, currentLocation, item); - - if(currentLocation == string::npos) - { - return false; - } - - items->push_back(item); - } - - return true; -} - -bool ParserUtil::ParseOCMessageList(wstring* message, vector* messages) -{ - vector* items = new vector(); - - if(!ParseOCList(message, items)) - { - return false; - } - - for(vector::iterator it = items->begin(); it != items->end(); it++) - { - wstring* temp = *it; - - OCMessage* message = new OCMessage(); - message->InitFromMessage(temp); - - messages->push_back(message); - } - - return true; -} - -bool ParserUtil::SerializeList(std::vector* list, std::wstring* result, bool escapeQuotes) -{ - if(result == 0) - { - return false; - } - - result->append(OPEN_BRACE); - - for(vector::iterator it = list->begin(); it != list->end(); it++) - { - wstring value = *it; - - if(escapeQuotes) - { - result->append(BACK_SLASH); - } - - result->append(QUOTE); - result->append(value.c_str()); - - if(escapeQuotes) - { - result->append(BACK_SLASH); - } - - result->append(QUOTE); - result->append(COMMA); - } - - //Erase last comma - result->erase(result->size() - 1, 1); - - result->append(CLOSE_BRACE); - - return true; -} - -bool ParserUtil::SerializeMessage(std::map* arguments, std::wstring* result, bool escapeQuotes) -{ - if(result == 0) - { - return false; - } - - result->append(OPEN_CURLY_BRACE); - - for(map::iterator it = arguments->begin(); it != arguments->end(); it++) - { - wstring key = *it->first; - wstring value = *it->second; - - if(escapeQuotes) - { - result->append(BACK_SLASH); - } - - result->append(QUOTE); - result->append(key.c_str()); - - if(escapeQuotes) - { - result->append(BACK_SLASH); - } - - result->append(QUOTE); - result->append(COLON); - result->append(value.c_str()); - result->append(COMMA); - } - - //Erase last comma - result->erase(result->size() - 1, 1); - - result->append(CLOSE_CURLY_BRACE); - - return true; -} - -bool ParserUtil::SerializeMessage(OCMessage* OCMessage, std::wstring* result) -{ - if(result == 0) - { - return false; - } - - result->append(OPEN_CURLY_BRACE); - - result->append(QUOTE); - result->append(COMMAND); - result->append(QUOTE); - - result->append(COLON); - - result->append(QUOTE); - result->append(OCMessage->GetCommand()->c_str()); - result->append(QUOTE); - - result->append(COMMA); - - result->append(QUOTE); - result->append(VALUE); - result->append(QUOTE); - - result->append(COLON); - - if(!IsList(OCMessage->GetValue())) - { - result->append(QUOTE); - } - - result->append(OCMessage->GetValue()->c_str()); - - if(!IsList(OCMessage->GetValue())) - { - result->append(QUOTE); - } - - result->append(CLOSE_CURLY_BRACE); - - return true; -} - From 81c20352e1dfd7800f7c43ce8dc9bb08b68b33ce Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 4 Jan 2018 21:06:23 +0100 Subject: [PATCH 087/138] Use new ECMAddAppIcon macro for application icons. cmake/modules/ECMAddAppIcon.cmake is heavily patched to support sidebar icons, OUTFILE_BASE parameter and to not include 64 and 64@2x icons on macOS which are not supported. All changes are made in a way that we can upstream this. --- cmake/modules/ECMAddAppIcon.cmake | 332 ++++++++++++++++++ cmake/modules/ECMFindModuleHelpers.cmake | 297 ++++++++++++++++ cmake/modules/ECMFindModuleHelpersStub.cmake | 1 + cmake/modules/FindPng2Ico.cmake | 117 ++++++ shell_integration/MacOSX/CMakeLists.txt | 3 +- src/gui/CMakeLists.txt | 18 +- theme.qrc | 14 +- ...d-icon-1024.png => 1024-owncloud-icon.png} | Bin ...oud-icon-128.png => 128-owncloud-icon.png} | Bin ...cloud-icon-16.png => 16-owncloud-icon.png} | Bin ...sidebar-16.png => 16-owncloud-sidebar.png} | Bin ...sidebar-18.png => 18-owncloud-sidebar.png} | Bin ...cloud-icon-22.png => 22-owncloud-icon.png} | Bin ...oud-icon-256.png => 256-owncloud-icon.png} | Bin ...cloud-icon-32.png => 32-owncloud-icon.png} | Bin ...sidebar-32.png => 32-owncloud-sidebar.png} | Bin ...sidebar-36.png => 36-owncloud-sidebar.png} | Bin ...cloud-icon-48.png => 48-owncloud-icon.png} | Bin ...oud-icon-512.png => 512-owncloud-icon.png} | Bin ...cloud-icon-64.png => 64-owncloud-icon.png} | Bin ...sidebar-64.png => 64-owncloud-sidebar.png} | Bin 21 files changed, 766 insertions(+), 16 deletions(-) create mode 100644 cmake/modules/ECMAddAppIcon.cmake create mode 100644 cmake/modules/ECMFindModuleHelpers.cmake create mode 100644 cmake/modules/ECMFindModuleHelpersStub.cmake create mode 100644 cmake/modules/FindPng2Ico.cmake rename theme/colored/{owncloud-icon-1024.png => 1024-owncloud-icon.png} (100%) rename theme/colored/{owncloud-icon-128.png => 128-owncloud-icon.png} (100%) rename theme/colored/{owncloud-icon-16.png => 16-owncloud-icon.png} (100%) rename theme/colored/{owncloud-sidebar-16.png => 16-owncloud-sidebar.png} (100%) rename theme/colored/{owncloud-sidebar-18.png => 18-owncloud-sidebar.png} (100%) rename theme/colored/{owncloud-icon-22.png => 22-owncloud-icon.png} (100%) rename theme/colored/{owncloud-icon-256.png => 256-owncloud-icon.png} (100%) rename theme/colored/{owncloud-icon-32.png => 32-owncloud-icon.png} (100%) rename theme/colored/{owncloud-sidebar-32.png => 32-owncloud-sidebar.png} (100%) rename theme/colored/{owncloud-sidebar-36.png => 36-owncloud-sidebar.png} (100%) rename theme/colored/{owncloud-icon-48.png => 48-owncloud-icon.png} (100%) rename theme/colored/{owncloud-icon-512.png => 512-owncloud-icon.png} (100%) rename theme/colored/{owncloud-icon-64.png => 64-owncloud-icon.png} (100%) rename theme/colored/{owncloud-sidebar-64.png => 64-owncloud-sidebar.png} (100%) diff --git a/cmake/modules/ECMAddAppIcon.cmake b/cmake/modules/ECMAddAppIcon.cmake new file mode 100644 index 000000000..ee2296ead --- /dev/null +++ b/cmake/modules/ECMAddAppIcon.cmake @@ -0,0 +1,332 @@ +#.rst: +# ECMAddAppIcon +# ------------- +# +# Add icons to executable files and packages. +# +# :: +# +# ecm_add_app_icon( +# ICONS [ [...]] +# [SIDEBAR_ICONS [ [...]] # Since 5.4x +# [OUTFILE_BASE ]) # Since 5.4x +# ) +# +# The given icons, whose names must match the pattern:: +# +# -.png +# +# will be added to the executable target whose sources are specified by +# ```` on platforms that support it (Windows and Mac OS X). +# Other icon files are ignored but on Mac SVG files can be supported and +# it is thus possible to mix those with png files in a single macro call. +# +# ```` is a numeric pixel size (typically 16, 32, 48, 64, 128 or 256). +# ```` can be any other text. See the platform notes below for any +# recommendations about icon sizes. +# +# ``SIDEBAR_ICONS`` can be used to add Mac OS X sidebar +# icons to the generated iconset. They are used when a folder monitored by the +# application is dragged into Finder's sidebar. Since 5.4x. +# +# ``OUTFILE_BASE`` will be used as the basename for the icon file. If +# you specify it, the icon file will be called ``.icns`` on Mac OS X +# and ``.ico`` on Windows. If you don't specify it, it defaults +# to ``.``. Since 5.4x. +# +# +# Windows notes +# * Icons are compiled into the executable using a resource file. +# * Icons may not show up in Windows Explorer if the executable +# target does not have the ``WIN32_EXECUTABLE`` property set. +# * The tool png2ico is required. See :find-module:`FindPng2Ico`. +# * Supported sizes: 16, 32, 48, 64, 128. +# +# Mac OS X notes +# * The executable target must have the ``MACOSX_BUNDLE`` property set. +# * Icons are added to the bundle. +# * If the ksvg2icns tool from KIconThemes is available, .svg and .svgz +# files are accepted; the first that is converted successfully to .icns +# will provide the application icon. SVG files are ignored otherwise. +# * The tool iconutil (provided by Apple) is required for bitmap icons. +# * Supported sizes: 16, 32, 64, 128, 256 (and 512, 1024 after OS X 10.9). +# * At least a 128x128px (or an SVG) icon is required. +# * Larger sizes are automatically used to substitute for smaller sizes on +# "Retina" (high-resolution) displays. For example, a 32px icon, if +# provided, will be used as a 32px icon on standard-resolution displays, +# and as a 16px-equivalent icon (with an "@2x" tag) on high-resolution +# displays. That is why you should provide 64px and 1024px icons although +# they are not supported anymore directly. Instead they will be used as +# 32px@2x and 512px@2x. ksvg2icns handles this internally. +# * This function sets the ``MACOSX_BUNDLE_ICON_FILE`` variable to the name +# of the generated icns file, so that it will be used as the +# ``MACOSX_BUNDLE_ICON_FILE`` target property when you call +# ``add_executable``. +# * Sidebar icons should typically provided in 16, 32, 64, 128 and 256px. +# +# Since 1.7.0. + + +#============================================================================= +# Copyright 2014 Alex Merry +# Copyright 2014 Ralf Habacker +# Copyright 2006-2009 Alexander Neundorf, +# Copyright 2006, 2007, Laurent Montel, +# Copyright 2007 Matthias Kretz +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(CMakeParseArguments) + +function(ecm_add_app_icon appsources) + set(options) + set(oneValueArgs OUTFILE_BASE) + set(multiValueArgs ICONS SIDEBAR_ICONS) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT ARG_ICONS) + message(FATAL_ERROR "No ICONS argument given to ecm_add_app_icon") + endif() + if(ARG_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unexpected arguments to ecm_add_app_icon: ${ARG_UNPARSED_ARGUMENTS}") + endif() + + if(APPLE) + find_program(KSVG2ICNS NAMES ksvg2icns) + foreach(icon ${ARG_ICONS}) + get_filename_component(icon_full ${icon} ABSOLUTE) + get_filename_component(icon_type ${icon_full} EXT) + # do we have ksvg2icns in the path and did we receive an svg (or compressed svg) icon? + if(KSVG2ICNS AND (${icon_type} STREQUAL ".svg" OR ${icon_type} STREQUAL ".svgz")) + # convert the svg icon to an icon resource + execute_process(COMMAND ${KSVG2ICNS} "${icon_full}" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} RESULT_VARIABLE KSVG2ICNS_ERROR) + if(${KSVG2ICNS_ERROR}) + message(AUTHOR_WARNING "ksvg2icns could not generate an OS X application icon from ${icon}") + else() + # install the icns file we just created + get_filename_component(icon_name ${icon_full} NAME_WE) + set(MACOSX_BUNDLE_ICON_FILE ${icon_name}.icns PARENT_SCOPE) + set(${appsources} "${${appsources}};${CMAKE_CURRENT_BINARY_DIR}/${icon_name}.icns" PARENT_SCOPE) + set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${icon_name}.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + # we're done now + return() + endif() + endif() + endforeach() + endif() + + + _ecm_add_app_icon_categorize_icons("${ARG_ICONS}" "icons" "16;32;48;64;128;256;512;1024") + if(ARG_SIDEBAR_ICONS) + _ecm_add_app_icon_categorize_icons("${ARG_SIDEBAR_ICONS}" "sidebar_icons" "16;18;32;36;64") + endif() + + set(mac_icons + # Icons: https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Optimizing/Optimizing.html#//apple_ref/doc/uid/TP40012302-CH7-SW4 + ${icons_at_16px} + ${icons_at_32px} + ${icons_at_64px} + ${icons_at_128px} + ${icons_at_256px} + ${icons_at_512px} + ${icons_at_1024px} + + # Sidebar Icons: https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/Finder.html#//apple_ref/doc/uid/TP40014214-CH15-SW15 + ${sidebar_icons_at_16px} + ${sidebar_icons_at_18px} + ${sidebar_icons_at_32px} + ${sidebar_icons_at_36px} + ${sidebar_icons_at_64px}) + if (NOT icons_at_128px) + message(AUTHOR_WARNING "No 128px icon provided; this will not work on Mac OS X") + endif() + + + set(windows_icons ${icons_at_16px} + ${icons_at_32px} + ${icons_at_48px} + ${icons_at_64px} + ${icons_at_128px}) + if (NOT windows_icons) + message(AUTHOR_WARNING "No icons suitable for use on Windows provided") + endif() + + if (ARG_OUTFILE_BASE) + set (_outfilebasename "${ARG_OUTFILE_BASE}") + else() + set (_outfilebasename "${appsources}") + endif() + set (_outfilename "${CMAKE_CURRENT_BINARY_DIR}/${_outfilebasename}") + + if (WIN32 AND windows_icons) + set(saved_CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}") + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_FIND_MODULE_DIR}) + find_package(Png2Ico) + set(CMAKE_MODULE_PATH "${saved_CMAKE_MODULE_PATH}") + + if (Png2Ico_FOUND) + if (Png2Ico_HAS_RCFILE_ARGUMENT) + add_custom_command( + OUTPUT "${_outfilename}.rc" "${_outfilename}.ico" + COMMAND Png2Ico::Png2Ico + ARGS + --rcfile "${_outfilename}.rc" + "${_outfilename}.ico" + ${windows_icons} + DEPENDS ${windows_icons} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + ) + else() + add_custom_command( + OUTPUT "${_outfilename}.ico" + COMMAND Png2Ico::Png2Ico + ARGS "${_outfilename}.ico" ${windows_icons} + DEPENDS ${windows_icons} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + ) + # this bit's a little hacky to make the dependency stuff work + file(WRITE "${_outfilename}.rc.in" "IDI_ICON1 ICON DISCARDABLE \"${_outfilename}.ico\"\n") + add_custom_command( + OUTPUT "${_outfilename}.rc" + COMMAND ${CMAKE_COMMAND} + ARGS -E copy "${_outfilename}.rc.in" "${_outfilename}.rc" + DEPENDS "${_outfilename}.ico" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + ) + endif() + set(${appsources} "${${appsources}};${_outfilename}.rc" PARENT_SCOPE) + else() + message(WARNING "Unable to find the png2ico utility - application will not have an application icon!") + endif() + elseif (APPLE AND mac_icons) + # first generate .iconset directory structure, then convert to .icns format using the Mac OS X "iconutil" utility, + # to create retina compatible icon, you need png source files in pixel resolution 16x16, 32x32, 64x64, 128x128, + # 256x256, 512x512, 1024x1024 + find_program(ICONUTIL_EXECUTABLE NAMES iconutil) + if (ICONUTIL_EXECUTABLE) + add_custom_command( + OUTPUT "${_outfilename}.iconset" + COMMAND ${CMAKE_COMMAND} + ARGS -E make_directory "${_outfilename}.iconset" + ) + set(iconset_icons) + macro(copy_icon filename sizename type) + add_custom_command( + OUTPUT "${_outfilename}.iconset/${type}_${sizename}.png" + COMMAND ${CMAKE_COMMAND} + ARGS -E copy + "${filename}" + "${_outfilename}.iconset/${type}_${sizename}.png" + DEPENDS + "${_outfilename}.iconset" + "${filename}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + ) + list(APPEND iconset_icons + "${_outfilename}.iconset/${type}_${sizename}.png") + endmacro() + foreach(size 16 32 128 256 512) + math(EXPR double_size "2 * ${size}") + foreach(file ${icons_at_${size}px}) + copy_icon("${file}" "${size}x${size}" "icon") + endforeach() + foreach(file ${icons_at_${double_size}px}) + copy_icon("${file}" "${size}x${size}@2x" "icon") + endforeach() + endforeach() + + foreach(size 16 18 32) + math(EXPR double_size "2 * ${size}") + foreach(file ${sidebar_icons_at_${size}px}) + copy_icon("${file}" "${size}x${size}" "sidebar") + endforeach() + foreach(file ${sidebar_icons_at_${double_size}px}) + copy_icon("${file}" "${size}x${size}@2x" "sidebar") + endforeach() + endforeach() + + # generate .icns icon file + add_custom_command( + OUTPUT "${_outfilename}.icns" + COMMAND ${ICONUTIL_EXECUTABLE} + ARGS + --convert icns + --output "${_outfilename}.icns" + "${_outfilename}.iconset" + DEPENDS "${iconset_icons}" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + ) + # This will register the icon into the bundle + set(MACOSX_BUNDLE_ICON_FILE "${_outfilebasename}.icns" PARENT_SCOPE) + + # Append the icns file to the sources list so it will be a dependency to the + # main target + set(${appsources} "${${appsources}};${_outfilename}.icns" PARENT_SCOPE) + + # Install the icon into the Resources dir in the bundle + set_source_files_properties("${_outfilename}.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + else() + message(STATUS "Unable to find the iconutil utility - application will not have an application icon!") + endif() + endif() +endfunction() + +macro(_ecm_add_app_icon_categorize_icons icons type known_sizes) + set(_${type}_known_sizes) + foreach(size ${known_sizes}) + set(${type}_at_${size}px) + list(APPEND _${type}_known_sizes ${size}) + endforeach() + + + foreach(icon ${icons}) + get_filename_component(icon_full ${icon} ABSOLUTE) + if (NOT EXISTS "${icon_full}") + message(AUTHOR_WARNING "${icon_full} does not exist, ignoring") + else() + get_filename_component(icon_name ${icon} NAME) + string(REGEX MATCH "([0-9]+)\\-[^/]+\\.([a-z]+)$" + _dummy "${icon_name}") + set(size "${CMAKE_MATCH_1}") + set(ext "${CMAKE_MATCH_2}") + + if (NOT (ext STREQUAL "svg" OR ext STREQUAL "svgz")) + if (NOT size) + message(AUTHOR_WARNING "${icon_full} is not named correctly for ecm_add_app_icon - ignoring") + elseif (NOT ext STREQUAL "png") + message(AUTHOR_WARNING "${icon_full} is not a png file - ignoring") + else() + list(FIND _${type}_known_sizes ${size} offset) + + if (offset GREATER -1) + list(APPEND ${type}_at_${size}px "${icon_full}") + elseif() + message(STATUS "not found ${type}_at_${size}px ${icon_full}") + endif() + endif() + endif() + endif() + endforeach() +endmacro() diff --git a/cmake/modules/ECMFindModuleHelpers.cmake b/cmake/modules/ECMFindModuleHelpers.cmake new file mode 100644 index 000000000..f2e32f959 --- /dev/null +++ b/cmake/modules/ECMFindModuleHelpers.cmake @@ -0,0 +1,297 @@ +#.rst: +# ECMFindModuleHelpers +# -------------------- +# +# Helper macros for find modules: ecm_find_package_version_check(), +# ecm_find_package_parse_components() and +# ecm_find_package_handle_library_components(). +# +# :: +# +# ecm_find_package_version_check() +# +# Prints warnings if the CMake version or the project's required CMake version +# is older than that required by extra-cmake-modules. +# +# :: +# +# ecm_find_package_parse_components( +# RESULT_VAR +# KNOWN_COMPONENTS [ [...]] +# [SKIP_DEPENDENCY_HANDLING]) +# +# This macro will populate with a list of components found in +# _FIND_COMPONENTS, after checking that all those components are in the +# list of KNOWN_COMPONENTS; if there are any unknown components, it will print +# an error or warning (depending on the value of _FIND_REQUIRED) and call +# return(). +# +# The order of components in is guaranteed to match the order they +# are listed in the KNOWN_COMPONENTS argument. +# +# If SKIP_DEPENDENCY_HANDLING is not set, for each component the variable +# __component_deps will be checked for dependent components. +# If is listed in _FIND_COMPONENTS, then all its (transitive) +# dependencies will also be added to . +# +# :: +# +# ecm_find_package_handle_library_components( +# COMPONENTS [ [...]] +# [SKIP_DEPENDENCY_HANDLING]) +# [SKIP_PKG_CONFIG]) +# +# Creates an imported library target for each component. The operation of this +# macro depends on the presence of a number of CMake variables. +# +# The __lib variable should contain the name of this library, +# and __header variable should contain the name of a header +# file associated with it (whatever relative path is normally passed to +# '#include'). __header_subdir variable can be used to specify +# which subdirectory of the include path the headers will be found in. +# ecm_find_package_components() will then search for the library +# and include directory (creating appropriate cache variables) and create an +# imported library target named ::. +# +# Additional variables can be used to provide additional information: +# +# If SKIP_PKG_CONFIG, the __pkg_config variable is set, and +# pkg-config is found, the pkg-config module given by +# __pkg_config will be searched for and used to help locate the +# library and header file. It will also be used to set +# __VERSION. +# +# Note that if version information is found via pkg-config, +# __FIND_VERSION can be set to require a particular version +# for each component. +# +# If SKIP_DEPENDENCY_HANDLING is not set, the INTERFACE_LINK_LIBRARIES property +# of the imported target for will be set to contain the imported +# targets for the components listed in __component_deps. +# _FOUND will also be set to false if any of the compoments in +# __component_deps are not found. This requires the components +# in __component_deps to be listed before in the +# COMPONENTS argument. +# +# The following variables will be set: +# +# ``_TARGETS`` +# the imported targets +# ``_LIBRARIES`` +# the found libraries +# ``_INCLUDE_DIRS`` +# the combined required include directories for the components +# ``_DEFINITIONS`` +# the "other" CFLAGS provided by pkg-config, if any +# ``_VERSION`` +# the value of ``__VERSION`` for the first component that +# has this variable set (note that components are searched for in the order +# they are passed to the macro), although if it is already set, it will not +# be altered +# +# Note that these variables are never cleared, so if +# ecm_find_package_handle_library_components() is called multiple times with +# different components (typically because of multiple find_package() calls) then +# ``_TARGETS``, for example, will contain all the targets found in any +# call (although no duplicates). +# +# Since pre-1.0.0. + +#============================================================================= +# Copyright 2014 Alex Merry +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(CMakeParseArguments) + +macro(ecm_find_package_version_check module_name) + if(CMAKE_VERSION VERSION_LESS 2.8.12) + message(FATAL_ERROR "CMake 2.8.12 is required by Find${module_name}.cmake") + endif() + if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12) + message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use Find${module_name}.cmake") + endif() +endmacro() + +macro(ecm_find_package_parse_components module_name) + set(ecm_fppc_options SKIP_DEPENDENCY_HANDLING) + set(ecm_fppc_oneValueArgs RESULT_VAR) + set(ecm_fppc_multiValueArgs KNOWN_COMPONENTS DEFAULT_COMPONENTS) + cmake_parse_arguments(ECM_FPPC "${ecm_fppc_options}" "${ecm_fppc_oneValueArgs}" "${ecm_fppc_multiValueArgs}" ${ARGN}) + + if(ECM_FPPC_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unexpected arguments to ecm_find_package_parse_components: ${ECM_FPPC_UNPARSED_ARGUMENTS}") + endif() + if(NOT ECM_FPPC_RESULT_VAR) + message(FATAL_ERROR "Missing RESULT_VAR argument to ecm_find_package_parse_components") + endif() + if(NOT ECM_FPPC_KNOWN_COMPONENTS) + message(FATAL_ERROR "Missing KNOWN_COMPONENTS argument to ecm_find_package_parse_components") + endif() + if(NOT ECM_FPPC_DEFAULT_COMPONENTS) + set(ECM_FPPC_DEFAULT_COMPONENTS ${ECM_FPPC_KNOWN_COMPONENTS}) + endif() + + if(${module_name}_FIND_COMPONENTS) + set(ecm_fppc_requestedComps ${${module_name}_FIND_COMPONENTS}) + + if(NOT ECM_FPPC_SKIP_DEPENDENCY_HANDLING) + # Make sure deps are included + foreach(ecm_fppc_comp ${ecm_fppc_requestedComps}) + foreach(ecm_fppc_dep_comp ${${module_name}_${ecm_fppc_comp}_component_deps}) + list(FIND ecm_fppc_requestedComps "${ecm_fppc_dep_comp}" ecm_fppc_index) + if("${ecm_fppc_index}" STREQUAL "-1") + if(NOT ${module_name}_FIND_QUIETLY) + message(STATUS "${module_name}: ${ecm_fppc_comp} requires ${${module_name}_${ecm_fppc_comp}_component_deps}") + endif() + list(APPEND ecm_fppc_requestedComps "${ecm_fppc_dep_comp}") + endif() + endforeach() + endforeach() + else() + message(STATUS "Skipping dependency handling for ${module_name}") + endif() + list(REMOVE_DUPLICATES ecm_fppc_requestedComps) + + # This makes sure components are listed in the same order as + # KNOWN_COMPONENTS (potentially important for inter-dependencies) + set(${ECM_FPPC_RESULT_VAR}) + foreach(ecm_fppc_comp ${ECM_FPPC_KNOWN_COMPONENTS}) + list(FIND ecm_fppc_requestedComps "${ecm_fppc_comp}" ecm_fppc_index) + if(NOT "${ecm_fppc_index}" STREQUAL "-1") + list(APPEND ${ECM_FPPC_RESULT_VAR} "${ecm_fppc_comp}") + list(REMOVE_AT ecm_fppc_requestedComps ${ecm_fppc_index}) + endif() + endforeach() + # if there are any left, they are unknown components + if(ecm_fppc_requestedComps) + set(ecm_fppc_msgType STATUS) + if(${module_name}_FIND_REQUIRED) + set(ecm_fppc_msgType FATAL_ERROR) + endif() + if(NOT ${module_name}_FIND_QUIETLY) + message(${ecm_fppc_msgType} "${module_name}: requested unknown components ${ecm_fppc_requestedComps}") + endif() + return() + endif() + else() + set(${ECM_FPPC_RESULT_VAR} ${ECM_FPPC_DEFAULT_COMPONENTS}) + endif() +endmacro() + +macro(ecm_find_package_handle_library_components module_name) + set(ecm_fpwc_options SKIP_PKG_CONFIG SKIP_DEPENDENCY_HANDLING) + set(ecm_fpwc_oneValueArgs) + set(ecm_fpwc_multiValueArgs COMPONENTS) + cmake_parse_arguments(ECM_FPWC "${ecm_fpwc_options}" "${ecm_fpwc_oneValueArgs}" "${ecm_fpwc_multiValueArgs}" ${ARGN}) + + if(ECM_FPWC_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unexpected arguments to ecm_find_package_handle_components: ${ECM_FPWC_UNPARSED_ARGUMENTS}") + endif() + if(NOT ECM_FPWC_COMPONENTS) + message(FATAL_ERROR "Missing COMPONENTS argument to ecm_find_package_handle_components") + endif() + + include(FindPackageHandleStandardArgs) + find_package(PkgConfig) + foreach(ecm_fpwc_comp ${ECM_FPWC_COMPONENTS}) + set(ecm_fpwc_dep_vars) + set(ecm_fpwc_dep_targets) + if(NOT SKIP_DEPENDENCY_HANDLING) + foreach(ecm_fpwc_dep ${${module_name}_${ecm_fpwc_comp}_component_deps}) + list(APPEND ecm_fpwc_dep_vars "${module_name}_${ecm_fpwc_dep}_FOUND") + list(APPEND ecm_fpwc_dep_targets "${module_name}::${ecm_fpwc_dep}") + endforeach() + endif() + + if(NOT ECM_FPWC_SKIP_PKG_CONFIG AND ${module_name}_${ecm_fpwc_comp}_pkg_config) + pkg_check_modules(PKG_${module_name}_${ecm_fpwc_comp} QUIET + ${${module_name}_${ecm_fpwc_comp}_pkg_config}) + endif() + + find_path(${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR + NAMES ${${module_name}_${ecm_fpwc_comp}_header} + HINTS ${PKG_${module_name}_${ecm_fpwc_comp}_INCLUDE_DIRS} + PATH_SUFFIXES ${${module_name}_${ecm_fpwc_comp}_header_subdir} + ) + find_library(${module_name}_${ecm_fpwc_comp}_LIBRARY + NAMES ${${module_name}_${ecm_fpwc_comp}_lib} + HINTS ${PKG_${module_name}_${ecm_fpwc_comp}_LIBRARY_DIRS} + ) + + set(${module_name}_${ecm_fpwc_comp}_VERSION "${PKG_${module_name}_${ecm_fpwc_comp}_VERSION}") + if(NOT ${module_name}_VERSION) + set(${module_name}_VERSION ${${module_name}_${ecm_fpwc_comp}_VERSION}) + endif() + + find_package_handle_standard_args(${module_name}_${ecm_fpwc_comp} + FOUND_VAR + ${module_name}_${ecm_fpwc_comp}_FOUND + REQUIRED_VARS + ${module_name}_${ecm_fpwc_comp}_LIBRARY + ${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR + ${ecm_fpwc_dep_vars} + VERSION_VAR + ${module_name}_${ecm_fpwc_comp}_VERSION + ) + + mark_as_advanced( + ${module_name}_${ecm_fpwc_comp}_LIBRARY + ${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR + ) + + if(${module_name}_${ecm_fpwc_comp}_FOUND) + list(APPEND ${module_name}_LIBRARIES + "${${module_name}_${ecm_fpwc_comp}_LIBRARY}") + list(APPEND ${module_name}_INCLUDE_DIRS + "${${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR}") + set(${module_name}_DEFINITIONS + ${${module_name}_DEFINITIONS} + ${PKG_${module_name}_${ecm_fpwc_comp}_DEFINITIONS}) + if(NOT TARGET ${module_name}::${ecm_fpwc_comp}) + add_library(${module_name}::${ecm_fpwc_comp} UNKNOWN IMPORTED) + set_target_properties(${module_name}::${ecm_fpwc_comp} PROPERTIES + IMPORTED_LOCATION "${${module_name}_${ecm_fpwc_comp}_LIBRARY}" + INTERFACE_COMPILE_OPTIONS "${PKG_${module_name}_${ecm_fpwc_comp}_DEFINITIONS}" + INTERFACE_INCLUDE_DIRECTORIES "${${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${ecm_fpwc_dep_targets}" + ) + endif() + list(APPEND ${module_name}_TARGETS + "${module_name}::${ecm_fpwc_comp}") + endif() + endforeach() + if(${module_name}_LIBRARIES) + list(REMOVE_DUPLICATES ${module_name}_LIBRARIES) + endif() + if(${module_name}_INCLUDE_DIRS) + list(REMOVE_DUPLICATES ${module_name}_INCLUDE_DIRS) + endif() + if(${module_name}_DEFINITIONS) + list(REMOVE_DUPLICATES ${module_name}_DEFINITIONS) + endif() + if(${module_name}_TARGETS) + list(REMOVE_DUPLICATES ${module_name}_TARGETS) + endif() +endmacro() diff --git a/cmake/modules/ECMFindModuleHelpersStub.cmake b/cmake/modules/ECMFindModuleHelpersStub.cmake new file mode 100644 index 000000000..bb8c9a62f --- /dev/null +++ b/cmake/modules/ECMFindModuleHelpersStub.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/../modules/ECMFindModuleHelpers.cmake) diff --git a/cmake/modules/FindPng2Ico.cmake b/cmake/modules/FindPng2Ico.cmake new file mode 100644 index 000000000..d84f66730 --- /dev/null +++ b/cmake/modules/FindPng2Ico.cmake @@ -0,0 +1,117 @@ +#.rst: +# FindPng2Ico +# ----------- +# +# Try to find png2ico. +# +# If the png2ico executable is not in your PATH, you can provide +# an alternative name or full path location with the ``Png2Ico_EXECUTABLE`` +# variable. +# +# This will define the following variables: +# +# ``Png2Ico_FOUND`` +# True if png2ico is available. +# +# ``Png2Ico_EXECUTABLE`` +# The png2ico executable. +# +# If ``Png2Ico_FOUND`` is TRUE, it will also define the following imported +# target: +# +# ``Png2Ico::Png2Ico`` +# The png2ico executable. +# +# and the following variables: +# +# ``Png2Ico_HAS_COLORS_ARGUMENT`` +# Whether png2ico accepts a ``--colors`` argument. `Matthias Benkmann's +# tool `_ does, while the +# version of png2ico from the `"KDE On Windows" (kdewin) +# `_ project does not. +# +# ``Png2Ico_HAS_RCFILE_ARGUMENT`` +# Whether png2ico accepts an ``--rcfile`` argument. The version of png2ico +# from the `"KDE On Windows" (kdewin) +# `_ project does, +# while `Matthias Benkmann's tool +# `_ does not. +# +# Since 1.7.0. + +#============================================================================= +# Copyright 2014 Alex Merry +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +include(${CMAKE_CURRENT_LIST_DIR}/ECMFindModuleHelpersStub.cmake) + +ecm_find_package_version_check(Png2Ico) + +# Find png2ico +find_program(Png2Ico_EXECUTABLE NAMES png2ico) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Png2Ico + FOUND_VAR + Png2Ico_FOUND + REQUIRED_VARS + Png2Ico_EXECUTABLE +) + +mark_as_advanced(Png2Ico_EXECUTABLE) + +if (Png2Ico_FOUND) + execute_process( + COMMAND "${Png2Ico_EXECUTABLE}" --help + OUTPUT_VARIABLE _png2ico_help_text + ERROR_VARIABLE _png2ico_help_text + ) + if (_png2ico_help_text MATCHES ".*--rcfile .*") + set(Png2Ico_HAS_RCFILE_ARGUMENT TRUE) + else() + set(Png2Ico_HAS_RCFILE_ARGUMENT FALSE) + endif() + if (_png2ico_help_text MATCHES ".*--colors .*") + set(Png2Ico_HAS_COLORS_ARGUMENT TRUE) + else() + set(Png2Ico_HAS_COLORS_ARGUMENT FALSE) + endif() + unset(_png2ico_help_text) + + if (NOT TARGET Png2Ico::Png2Ico) + add_executable(Png2Ico::Png2Ico IMPORTED) + set_target_properties(Png2Ico::Png2Ico PROPERTIES + IMPORTED_LOCATION "${Png2Ico_EXECUTABLE}" + ) + endif() +endif() + +include(FeatureSummary) +set_package_properties(Png2Ico PROPERTIES + URL "http://www.winterdrache.de/freeware/png2ico/ or https://projects.kde.org/projects/kdesupport/kdewin" + DESCRIPTION "Executable that converts a collection of PNG files into a Windows icon file" +) + diff --git a/shell_integration/MacOSX/CMakeLists.txt b/shell_integration/MacOSX/CMakeLists.txt index 06174af7c..4173f6e94 100644 --- a/shell_integration/MacOSX/CMakeLists.txt +++ b/shell_integration/MacOSX/CMakeLists.txt @@ -1,6 +1,5 @@ if(APPLE) -# Contrary to popular belief, this is called like this no matter what theme/OEM. -set(OC_OEM_SHARE_ICNS "${CMAKE_BINARY_DIR}/src/gui/ownCloud.icns") +set(OC_OEM_SHARE_ICNS "${CMAKE_BINARY_DIR}/src/gui/${APPLICATION_ICON_NAME}.icns") # The bundle identifier and application group need to have compatible values with the client # to be able to open a Mach port across the extension's sandbox boundary. diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index fe42148bc..bd6651879 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -208,8 +208,11 @@ if(QTKEYCHAIN_FOUND OR QT5KEYCHAIN_FOUND) endif() # add executable icon on windows and osx -include( AddAppIconMacro ) -set(ownCloud_old ${ownCloud}) + +# UPSTREAM our ECMAddAppIcon.cmake then require that version here +# find_package(ECM 1.7.0 REQUIRED NO_MODULE) +# list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) +include(ECMAddAppIcon) # For historical reasons we can not use the application_shortname # for ownCloud but must rather set it manually. @@ -217,11 +220,12 @@ if (NOT DEFINED APPLICATION_ICON_NAME) set(APPLICATION_ICON_NAME ${APPLICATION_SHORTNAME}) endif() -kde4_add_app_icon( ownCloud "${theme_dir}/colored/${APPLICATION_ICON_NAME}-*.png") -list(APPEND final_src ${ownCloud}) -set(ownCloud ${ownCloud_old}) - - +file(GLOB_RECURSE OWNCLOUD_ICONS "${theme_dir}/colored/*-${APPLICATION_ICON_NAME}-icon*") +if(APPLE) + file(GLOB_RECURSE OWNCLOUD_SIDEBAR_ICONS "${theme_dir}/colored/*-${APPLICATION_ICON_NAME}-sidebar*") + MESSAGE(STATUS "OWNCLOUD_SIDEBAR_ICONS: ${APPLICATION_ICON_NAME}: ${OWNCLOUD_SIDEBAR_ICONS}") +endif() +ecm_add_app_icon(final_src ICONS "${OWNCLOUD_ICONS}" SIDEBAR_ICONS "${OWNCLOUD_SIDEBAR_ICONS}" OUTFILE_BASE "${APPLICATION_ICON_NAME}") if(UNIX AND NOT APPLE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE") diff --git a/theme.qrc b/theme.qrc index 4f4357e61..e85cedd71 100644 --- a/theme.qrc +++ b/theme.qrc @@ -1,12 +1,12 @@ - theme/colored/owncloud-icon-512.png - theme/colored/owncloud-icon-256.png - theme/colored/owncloud-icon-128.png - theme/colored/owncloud-icon-22.png - theme/colored/owncloud-icon-32.png - theme/colored/owncloud-icon-48.png - theme/colored/owncloud-icon-64.png + theme/colored/512-owncloud-icon.png + theme/colored/256-owncloud-icon.png + theme/colored/128-owncloud-icon.png + theme/colored/22-owncloud-icon.png + theme/colored/32-owncloud-icon.png + theme/colored/48-owncloud-icon.png + theme/colored/64-owncloud-icon.png theme/colored/state-error-32.png theme/colored/state-error-64.png theme/colored/state-error-128.png diff --git a/theme/colored/owncloud-icon-1024.png b/theme/colored/1024-owncloud-icon.png similarity index 100% rename from theme/colored/owncloud-icon-1024.png rename to theme/colored/1024-owncloud-icon.png diff --git a/theme/colored/owncloud-icon-128.png b/theme/colored/128-owncloud-icon.png similarity index 100% rename from theme/colored/owncloud-icon-128.png rename to theme/colored/128-owncloud-icon.png diff --git a/theme/colored/owncloud-icon-16.png b/theme/colored/16-owncloud-icon.png similarity index 100% rename from theme/colored/owncloud-icon-16.png rename to theme/colored/16-owncloud-icon.png diff --git a/theme/colored/owncloud-sidebar-16.png b/theme/colored/16-owncloud-sidebar.png similarity index 100% rename from theme/colored/owncloud-sidebar-16.png rename to theme/colored/16-owncloud-sidebar.png diff --git a/theme/colored/owncloud-sidebar-18.png b/theme/colored/18-owncloud-sidebar.png similarity index 100% rename from theme/colored/owncloud-sidebar-18.png rename to theme/colored/18-owncloud-sidebar.png diff --git a/theme/colored/owncloud-icon-22.png b/theme/colored/22-owncloud-icon.png similarity index 100% rename from theme/colored/owncloud-icon-22.png rename to theme/colored/22-owncloud-icon.png diff --git a/theme/colored/owncloud-icon-256.png b/theme/colored/256-owncloud-icon.png similarity index 100% rename from theme/colored/owncloud-icon-256.png rename to theme/colored/256-owncloud-icon.png diff --git a/theme/colored/owncloud-icon-32.png b/theme/colored/32-owncloud-icon.png similarity index 100% rename from theme/colored/owncloud-icon-32.png rename to theme/colored/32-owncloud-icon.png diff --git a/theme/colored/owncloud-sidebar-32.png b/theme/colored/32-owncloud-sidebar.png similarity index 100% rename from theme/colored/owncloud-sidebar-32.png rename to theme/colored/32-owncloud-sidebar.png diff --git a/theme/colored/owncloud-sidebar-36.png b/theme/colored/36-owncloud-sidebar.png similarity index 100% rename from theme/colored/owncloud-sidebar-36.png rename to theme/colored/36-owncloud-sidebar.png diff --git a/theme/colored/owncloud-icon-48.png b/theme/colored/48-owncloud-icon.png similarity index 100% rename from theme/colored/owncloud-icon-48.png rename to theme/colored/48-owncloud-icon.png diff --git a/theme/colored/owncloud-icon-512.png b/theme/colored/512-owncloud-icon.png similarity index 100% rename from theme/colored/owncloud-icon-512.png rename to theme/colored/512-owncloud-icon.png diff --git a/theme/colored/owncloud-icon-64.png b/theme/colored/64-owncloud-icon.png similarity index 100% rename from theme/colored/owncloud-icon-64.png rename to theme/colored/64-owncloud-icon.png diff --git a/theme/colored/owncloud-sidebar-64.png b/theme/colored/64-owncloud-sidebar.png similarity index 100% rename from theme/colored/owncloud-sidebar-64.png rename to theme/colored/64-owncloud-sidebar.png From 0656c77da8ec4096aa897702ad86fa49184d2e02 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 4 Jan 2018 21:08:33 +0100 Subject: [PATCH 088/138] Set CMAKE_CXX_STANDARD to 14 --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f4abfd3c..67b6d0d9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 3.1) +set(CMAKE_CXX_STANDARD 14) project(client) From 15967b121964f14c809bfc5686e1bc802c711dd1 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 11 Jan 2018 23:05:23 +0100 Subject: [PATCH 089/138] Install all dlls to BINDIR so craft does not ignore them --- shell_integration/windows/OCContextMenu/CMakeLists.txt | 2 +- shell_integration/windows/OCOverlays/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shell_integration/windows/OCContextMenu/CMakeLists.txt b/shell_integration/windows/OCContextMenu/CMakeLists.txt index 27f45f582..fb4a42efd 100644 --- a/shell_integration/windows/OCContextMenu/CMakeLists.txt +++ b/shell_integration/windows/OCContextMenu/CMakeLists.txt @@ -12,5 +12,5 @@ target_link_libraries(OCContextMenu install(TARGETS OCContextMenu RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_BINDIR} ) diff --git a/shell_integration/windows/OCOverlays/CMakeLists.txt b/shell_integration/windows/OCOverlays/CMakeLists.txt index 5e3cb7dff..7837f8fb4 100644 --- a/shell_integration/windows/OCOverlays/CMakeLists.txt +++ b/shell_integration/windows/OCOverlays/CMakeLists.txt @@ -11,5 +11,5 @@ target_link_libraries(OCOverlays install(TARGETS OCOverlays RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_BINDIR} ) From fc62e9e9d9caf01dd5b25da2fb5c5c5c0c330b46 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sat, 13 Jan 2018 20:59:34 +0100 Subject: [PATCH 090/138] Fix .def and .rc files not being compiled into windows shell extensions --- .../windows/OCContextMenu/CMakeLists.txt | 2 ++ .../windows/OCContextMenu/OCContextMenu.rc | Bin 4772 -> 4586 bytes .../windows/OCOverlays/CMakeLists.txt | 2 ++ .../windows/OCOverlays/OCOverlay.rc | Bin 5744 -> 5534 bytes 4 files changed, 4 insertions(+) diff --git a/shell_integration/windows/OCContextMenu/CMakeLists.txt b/shell_integration/windows/OCContextMenu/CMakeLists.txt index fb4a42efd..badfbb638 100644 --- a/shell_integration/windows/OCContextMenu/CMakeLists.txt +++ b/shell_integration/windows/OCContextMenu/CMakeLists.txt @@ -5,6 +5,8 @@ add_library(OCContextMenu MODULE OCContextMenuFactory.cpp OCContextMenuRegHandler.cpp stdafx.cpp + OCContextMenu.rc + OCContextMenu.def ) target_link_libraries(OCContextMenu diff --git a/shell_integration/windows/OCContextMenu/OCContextMenu.rc b/shell_integration/windows/OCContextMenu/OCContextMenu.rc index 5025d081ffb2a242e2342c8e956bca568075b9ac..ab3041ee13ac38090460d256e1d1ae656a1c47f4 100644 GIT binary patch delta 707 zcmZ`%O-lk{5T4Y{-B(@nBSTQvvPgrp6oSGoTOwsthw4<+p`<|k%0Ezaj&wRjK}ENI zLg!8qh`*q7RM0)5*>yM9AYNW(=G~cx=XrMSMqVRld5%E>67|w}z3hv{Ar70c0&}nq zH8_9*RU5DeRXC)o1V#G34@1D}&lwDJm+fK9xv~wDPb(x-tcRh*UE!Na*0Pp)k+MNc z1 z`thzeEE%3iz=T5B0FhE4X8(bp{wm#~I`a$s7X??Wvu2{B$c$*z6&s02w_UodZGIXr z_$h4hY3vimFf9Zq`mii8k{cn53uN&gI)wqe78prZ-iokGw&(Fdh~SG5YOvuhZ|+4u zF0qiOBe&z*5li7Q^ICNuZ|pJrVl#MakK&H4phX_PZD}>%wJY%yla88NHy!QXrb9$o zOcR#7U;hibEozPT;^aRJJov#x^g5IN4nrM7i)3UFPn@#04T`0ezLa4%a;_~wH@Ll3 NtJVP4+)<0N4L>N7if;e_ delta 912 zcmah|Jxc>Y5FO2(-d(a6LxM4A$R$A}AovME(LynXV9-h{?KB`r#00JN7igGD5Ja%C z@+SxuHWoI5Scz8RAF#1-X0w-^i73l1Z)fJcnVZ@BNM8<~luQ8@jL;I8=!~M)74fC& zxON-S*(qvIIUfP+=sERMTqFLxCy!cZ?+=Acx1{`tPQyNw@kQ&eeK}sYF2(TGF4Xg2 zNZacWc%-eW`;#{IYvL z8DcHAm0^?AOJrR!)5O^`6LcP%gF%k)cKF83M%m_mpVxOJ!Z=_##ALK=SrTRN(3)20 z&Dv4uz`x+y{4)wI21*J&28t48aZLaz5|&y!#r1^|>%lZoCgpxW1NOWJA8d#)Rq&o~@5GNH=G=D&IWXjSc_+ diff --git a/shell_integration/windows/OCOverlays/CMakeLists.txt b/shell_integration/windows/OCOverlays/CMakeLists.txt index 7837f8fb4..13526b749 100644 --- a/shell_integration/windows/OCOverlays/CMakeLists.txt +++ b/shell_integration/windows/OCOverlays/CMakeLists.txt @@ -4,6 +4,8 @@ add_library(OCOverlays MODULE OCOverlayFactory.cpp OCOverlayRegistrationHandler.cpp stdafx.cpp + OCOverlay.rc + OCOverlays.def ) target_link_libraries(OCOverlays diff --git a/shell_integration/windows/OCOverlays/OCOverlay.rc b/shell_integration/windows/OCOverlays/OCOverlay.rc index 7e937bd90178a195f36e1f498cb242976d8b7f79..fb298e242937c9d02c140cc1d2f5ebd2788c2543 100644 GIT binary patch delta 778 zcmeyMGf#U$8Y>rrK7;FWh@|^Ct2{T@5e!^FXgK*St0a)`#Nf){&fv-5H(8NQotF#9^J8!Ut1!Y)(aPp1 z&&8ksg-Sq28-N^%q{kSf#}>&{pe(ZbBA}i;upVSl6jLS#vfDBPT?q1>EX=*YpaYuY z$&d^V9H{8zXpZj5FF1TAn{hTx-o;r1#8Q)kxC$m8;cA%d#@z-97iCm4P=gs}(rg~f z$=7(yCiC&yO!nc`nq0vvGkF@X0x*1(fzgr!jF!~NM|l;2;RE95F{A*aDQ)t1UggO$ zd~%a*_*76rGM~>}7~yY32!G@gom|7mGx;8$(Bw~iGC(Xexj;~CvIV~toGmB7F?k7p z021E?&h8N~gR|cV6hPT&P+Da&pO6ih9Vf)bkFXycqm%RbBqvW0lEC3E;mHC5e3Kst z8A+n)L&PpHUSuZ+2s=Sj6exylMU0Ws*G@+F$#J4$oUrhQq|YFBnaK`f8Z4kR2LNb^ Bq5c2> delta 986 zcmZuw&ubG=5S}!LkHp4jR@bJ{DY#ye(V zMD$JT5;Chx92C(_zH$``86MvJWQDAX~GV|6%kq_ z)PA2HfhX=!oJeh>y6x0;$dycl!_W{GNFgb@^DFPcr(nNUNy% zF+CiSuVSAQ9{Vih8~Xxe+pa?Xv5Q*I^Kq5YXDowd4J@m254PAXzNZXV@` Date: Sat, 13 Jan 2018 23:28:18 +0100 Subject: [PATCH 091/138] Add Linux CI Dockerfile --- admin/linux/Dockerfile | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 admin/linux/Dockerfile diff --git a/admin/linux/Dockerfile b/admin/linux/Dockerfile new file mode 100644 index 000000000..16cf56dec --- /dev/null +++ b/admin/linux/Dockerfile @@ -0,0 +1,19 @@ +# Distro with Qt 5.6 +FROM ubuntu:yakkety + +RUN apt-get update -q && DEBIAN_FRONTEND=noninteractive apt-get install -q -y --no-install-recommends \ + locales \ + build-essential \ + clang \ + ninja-build \ + cmake \ + extra-cmake-modules \ + libsqlite3-dev \ + libssl-dev \ + libcmocka-dev \ + qt5-default \ + qttools5-dev-tools \ + libqt5webkit5-dev \ + qt5keychain-dev \ + kio-dev \ + && apt-get clean From 86ea5876cdd236e6a928b56c90b98d4d59c29ecb Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sat, 13 Jan 2018 23:28:52 +0100 Subject: [PATCH 092/138] Use standard png2ico in our cross env too --- Jenkinsfile | 8 ++++---- admin/win/docker/Dockerfile | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 52c45ba96..80d4a1844 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -13,8 +13,8 @@ // compiler. -def linux = docker.image('dominikschmidt/owncloud-client-ci-image:latest') -def win32 = docker.image('guruz/docker-owncloud-client-win32:latest') +def linux = docker.image('dominikschmidt/docker-owncloud-client-linux:latest') +def win32 = docker.image('dominikschmidt/docker-owncloud-client-win32-cross:latest') node('CLIENT') { stage 'Checkout' @@ -50,10 +50,10 @@ node('CLIENT') { ''' } - stage 'Win32 - Pull Docker Image' + stage 'Win32 Cross - Pull Docker Image' win32.pull() - stage 'Win32' + stage 'Win32 Cross' win32.inside { sh ''' rm -rf build-win32 diff --git a/admin/win/docker/Dockerfile b/admin/win/docker/Dockerfile index 7be50c383..1ff621175 100644 --- a/admin/win/docker/Dockerfile +++ b/admin/win/docker/Dockerfile @@ -1,11 +1,9 @@ FROM opensuse:42.1 -MAINTAINER Daniel Molkentin - ENV TERM ansi ENV HOME /root -ENV REFRESHED_AT 20160421 +ENV REFRESHED_AT 20170113 RUN zypper --non-interactive --gpg-auto-import-keys refresh RUN zypper --non-interactive --gpg-auto-import-keys ar http://download.opensuse.org/repositories/windows:/mingw/openSUSE_Leap_42.1/windows:mingw.repo @@ -16,7 +14,7 @@ RUN zypper --non-interactive --gpg-auto-import-keys install cmake make mingw32-c mingw32-cross-libqt5-qmake mingw32-cross-libqt5-qttools mingw32-libqt5* \ mingw32-qt5keychain* mingw32-angleproject* \ mingw32-cross-nsis mingw32-libopenssl* \ - mingw32-sqlite* kdewin-png2ico \ + mingw32-sqlite* png2ico \ osslsigncode wget # RPM depends on curl for installs from HTTP From 6d56f30d9bd70e3e999790c90da9c41e1e823b59 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sat, 13 Jan 2018 23:49:58 +0100 Subject: [PATCH 093/138] Fix incorrect target_include_directories usage for crash reporter --- src/gui/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index bd6651879..31303cbf1 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -314,8 +314,8 @@ if (NOT NO_SHIBBOLETH) endif() if(WITH_CRASHREPORTER) - target_link_libraries( ${APPLICATION_EXECUTABLE} crashreporter-handler) - target_include_directories(${APPLICATION_EXECUTABLE} "../3rdparty/libcrashreporter-qt/src/" ) + target_link_libraries(${APPLICATION_EXECUTABLE} crashreporter-handler) + target_include_directories(${APPLICATION_EXECUTABLE} PRIVATE "../3rdparty/libcrashreporter-qt/src/") if(UNIX AND NOT MAC) find_package(Threads REQUIRED) From d8a279c67174ca102b4dae3a3a5f1795dc6fd9ce Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sun, 14 Jan 2018 00:45:02 +0100 Subject: [PATCH 094/138] Fix windows cross build of the updater and bump libcrashreporter-qt revision --- src/3rdparty/libcrashreporter-qt | 2 +- src/crashreporter/CMakeLists.txt | 4 +++- src/gui/CMakeLists.txt | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/libcrashreporter-qt b/src/3rdparty/libcrashreporter-qt index e8fffe61e..7df66f72a 160000 --- a/src/3rdparty/libcrashreporter-qt +++ b/src/3rdparty/libcrashreporter-qt @@ -1 +1 @@ -Subproject commit e8fffe61e7c94ce88e59b80579754c4a46da65ea +Subproject commit 7df66f72aac595295dffcf4dc8a536822008c51d diff --git a/src/crashreporter/CMakeLists.txt b/src/crashreporter/CMakeLists.txt index 3354e9a5e..693fd9efd 100644 --- a/src/crashreporter/CMakeLists.txt +++ b/src/crashreporter/CMakeLists.txt @@ -24,7 +24,9 @@ if(NOT BUILD_LIBRARIES_ONLY) ${crashreporter_RC_RCC} ) - target_include_directories(${CRASHREPORTER_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/libcrashreporter-qt/src/" ) + find_package(Qt5 REQUIRED COMPONENTS Widgets) + + target_include_directories(${CRASHREPORTER_EXECUTABLE} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) set_target_properties(${CRASHREPORTER_EXECUTABLE} PROPERTIES AUTOMOC ON) set_target_properties(${CRASHREPORTER_EXECUTABLE} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} ) set_target_properties(${CRASHREPORTER_EXECUTABLE} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}" ) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 31303cbf1..a9e8b055e 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -315,7 +315,6 @@ endif() if(WITH_CRASHREPORTER) target_link_libraries(${APPLICATION_EXECUTABLE} crashreporter-handler) - target_include_directories(${APPLICATION_EXECUTABLE} PRIVATE "../3rdparty/libcrashreporter-qt/src/") if(UNIX AND NOT MAC) find_package(Threads REQUIRED) From 969d90d15ba2c45b5b6d4832ac7ee25734501684 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sun, 14 Jan 2018 00:57:40 +0100 Subject: [PATCH 095/138] Fix UIC detection in windows cross env --- admin/win/Toolchain-mingw32-openSUSE.cmake | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/admin/win/Toolchain-mingw32-openSUSE.cmake b/admin/win/Toolchain-mingw32-openSUSE.cmake index 3877ca1d4..ae1c5745f 100644 --- a/admin/win/Toolchain-mingw32-openSUSE.cmake +++ b/admin/win/Toolchain-mingw32-openSUSE.cmake @@ -27,8 +27,8 @@ SET(QT_MKSPECS_DIR ${CMAKE_FIND_ROOT_PATH}/share/qt5/mkspecs) SET(QT_QT_INCLUDE_DIR ${CMAKE_FIND_ROOT_PATH}/include) # qt tools -SET(QT_QMAKE_EXECUTABLE ${MINGW_PREFIX}-qmake ) -SET(QT_MOC_EXECUTABLE ${MINGW_PREFIX}-moc) -SET(QT_RCC_EXECUTABLE ${MINGW_PREFIX}-rcc) -SET(QT_UIC_EXECUTABLE ${MINGW_PREFIX}-uic) -SET(QT_LRELEASE_EXECUTABLE ${MINGW_PREFIX}-lrelease) +SET(QT_QMAKE_EXECUTABLE ${MINGW_PREFIX}-qmake-qt5) +SET(QT_MOC_EXECUTABLE ${MINGW_PREFIX}-moc-qt5) +SET(QT_RCC_EXECUTABLE ${MINGW_PREFIX}-rcc-qt5) +SET(Qt5Widgets_UIC_EXECUTABLE ${MINGW_PREFIX}-uic-qt5) +SET(QT_LRELEASE_EXECUTABLE ${MINGW_PREFIX}-lrelease-qt5) From c454d626b666ac074447d7aa5d24b1f062f434c8 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Sun, 14 Jan 2018 02:18:36 +0100 Subject: [PATCH 096/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_fr.ts | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index 5c365db3a..f7193d057 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -164,6 +164,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_fr.ts b/translations/client_fr.ts index 9d0f40545..ce96f2b27 100644 --- a/translations/client_fr.ts +++ b/translations/client_fr.ts @@ -1735,8 +1735,8 @@ L'option "Autoriser suppression" permet de ne pas bloquer la supp A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. - Une nouvelle mise à jour de %1 est sur le point d'être installée. -L'assistant peut demander des privilèges additionnels durant le processus. + Une mise à jour de %1 est sur le point d'être installée. +L'assistant de mise à jour peut vous demandez des autorisations supplémentaires afin de procéder à l'installation. From 7839c4d4e1192a14165fef546b074e78acbc61d1 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sun, 14 Jan 2018 14:39:29 +0100 Subject: [PATCH 097/138] Revert "Disable stack protection for mingw win32 builds in 2.4" This reverts commit 298f1ab57000afd7acb8c0ddbddca8a1fc6cd92a. We're shipping libssp-0.dll now with mingw builds. We would have enough time to test this for 2.5.0 now anyway, but we also will most likely switch to MSVC for that release. --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e20358c18..ac60b1b66 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,7 +13,7 @@ if(NOT TOKEN_AUTH_ONLY) find_package(Qt5Keychain REQUIRED) endif() -if(NOT WIN32) +if(NOT MSVC) if(NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "^(alpha|parisc|hppa)")) if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector --param=ssp-buffer-size=4") From ca200e788e5ce3c559a72dbab9f7e7754125219a Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Mon, 15 Jan 2018 02:18:34 +0100 Subject: [PATCH 098/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index f7193d057..1722d1d19 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -167,6 +167,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From a33fc2a0dbd99c1ad3cf5fd56111ff46cdd0fbd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Weigert?= Date: Wed, 10 Jan 2018 16:22:28 +0100 Subject: [PATCH 099/138] Update updater.cpp deprecate suffix nightly, promote suffix daily --- src/gui/updater/updater.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/updater/updater.cpp b/src/gui/updater/updater.cpp index 940f2026b..ebf70b7aa 100644 --- a/src/gui/updater/updater.cpp +++ b/src/gui/updater/updater.cpp @@ -64,7 +64,8 @@ QUrl Updater::addQueryParams(const QUrl &url) QString suffix = QString::fromLatin1(MIRALL_STRINGIFY(MIRALL_VERSION_SUFFIX)); paramUrl.addQueryItem(QLatin1String("versionsuffix"), suffix); - if (suffix.startsWith("nightly") + if (suffix.startsWith("daily") + || suffix.startsWith("nightly") || suffix.startsWith("alpha") || suffix.startsWith("rc") || suffix.startsWith("beta")) { From d0713d018c021d7d9b1dde4ecc191ff3828a4732 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 15 Jan 2018 11:29:08 +0100 Subject: [PATCH 100/138] client_de.ts: Fix spacing in a translation Issue #6303 --- translations/client_de.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/client_de.ts b/translations/client_de.ts index 928134fcc..a453fc0c4 100644 --- a/translations/client_de.ts +++ b/translations/client_de.ts @@ -2804,7 +2804,7 @@ Es ist nicht ratsam, diese zu benutzen. <html><head/><body><p>You can direct people to this shared file or folder <a href="private link menu"><span style=" text-decoration: underline; color:#0000ff;">by giving them a private link</span></a>.</p></body></html> - <html><head/><body><p>Sie können Leute direkt zu dieser Freigabe leiten<a href="private link menu"><span style=" text-decoration: underline; color:#0000ff;">, wenn Sie Ihnen einen privaten Link</span></a>gibst.</p></body></html> + <html><head/><body><p>Sie können Leute direkt zu dieser Freigabe leiten, <a href="private link menu"><span style=" text-decoration: underline; color:#0000ff;">wenn Sie Ihnen einen privaten Link</span></a> gibst.</p></body></html> From cfe99095601c760b9bedc5564623ab042477056f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 15 Jan 2018 13:56:35 +0100 Subject: [PATCH 101/138] admin/linux/Dockerfile: Add comments --- Jenkinsfile | 3 ++- admin/linux/Dockerfile | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 80d4a1844..22dc1f99f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,8 +12,9 @@ // unlikely that a specific generator only breaks with a specific // compiler. - +// Constructed from the DockerFile in admin/linux/DockerFile def linux = docker.image('dominikschmidt/docker-owncloud-client-linux:latest') +// Constructed from the DockerFile in admin/win/docker/DockerFile def win32 = docker.image('dominikschmidt/docker-owncloud-client-win32-cross:latest') node('CLIENT') { diff --git a/admin/linux/Dockerfile b/admin/linux/Dockerfile index 16cf56dec..8f2326fb2 100644 --- a/admin/linux/Dockerfile +++ b/admin/linux/Dockerfile @@ -1,3 +1,6 @@ +# This DockerFile is used to create the image used for Jenkins, the CI system (see Jenkinsfile) +# It is not meant to be used to create the production packages. + # Distro with Qt 5.6 FROM ubuntu:yakkety From 2a842a5745b6182679aab11e246279a07e0584e5 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 15 Jan 2018 15:07:09 +0100 Subject: [PATCH 102/138] Application: remove declaration of non-existing functions --- src/gui/application.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/application.h b/src/gui/application.h index 47f7bee50..c61f7645e 100644 --- a/src/gui/application.h +++ b/src/gui/application.h @@ -77,8 +77,6 @@ protected: void parseOptions(const QStringList &); void setupTranslations(); void setupLogging(); - void enterNextLogFile(); - bool checkConfigExists(bool openSettings); signals: void folderRemoved(); From 2a14ba5582c2aea4195eec7c84460a8b324a15e0 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 15 Jan 2018 15:43:13 +0100 Subject: [PATCH 103/138] Folder: remove declaration of non-existing method --- src/gui/folder.cpp | 1 - src/gui/folder.h | 6 ------ 2 files changed, 7 deletions(-) diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index 986af370d..f0664d218 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -115,7 +115,6 @@ Folder::~Folder() _engine.reset(); } - void Folder::checkLocalPath() { const QFileInfo fi(_definition.localPath); diff --git a/src/gui/folder.h b/src/gui/folder.h index f2c2b1272..51ae7cd58 100644 --- a/src/gui/folder.h +++ b/src/gui/folder.h @@ -171,12 +171,6 @@ public: */ SyncResult syncResult() const; - /** - * set the config file name. - */ - void setConfigFile(const QString &); - QString configFile(); - /** * This is called if the sync folder definition is removed. Do cleanups here. */ From d4106b9a884f206777beb90eace6e072b5c9938b Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Tue, 16 Jan 2018 02:18:35 +0100 Subject: [PATCH 104/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_de.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index 1722d1d19..6f14c34df 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -170,6 +170,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_de.ts b/translations/client_de.ts index a453fc0c4..928134fcc 100644 --- a/translations/client_de.ts +++ b/translations/client_de.ts @@ -2804,7 +2804,7 @@ Es ist nicht ratsam, diese zu benutzen. <html><head/><body><p>You can direct people to this shared file or folder <a href="private link menu"><span style=" text-decoration: underline; color:#0000ff;">by giving them a private link</span></a>.</p></body></html> - <html><head/><body><p>Sie können Leute direkt zu dieser Freigabe leiten, <a href="private link menu"><span style=" text-decoration: underline; color:#0000ff;">wenn Sie Ihnen einen privaten Link</span></a> gibst.</p></body></html> + <html><head/><body><p>Sie können Leute direkt zu dieser Freigabe leiten<a href="private link menu"><span style=" text-decoration: underline; color:#0000ff;">, wenn Sie Ihnen einen privaten Link</span></a>gibst.</p></body></html> From 24d6fda3601eb40bd114251145b852edcfd7c247 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Wed, 17 Jan 2018 02:18:35 +0100 Subject: [PATCH 105/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_fr.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index 6f14c34df..bf3484c34 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -173,6 +173,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_fr.ts b/translations/client_fr.ts index ce96f2b27..0460fe105 100644 --- a/translations/client_fr.ts +++ b/translations/client_fr.ts @@ -1431,7 +1431,7 @@ L'option "Autoriser suppression" permet de ne pas bloquer la supp There were too many issues. Not all will be visible here. - + De trop nombreuses questions se posent. Toutes n'apparaissent pas ici. From fe3c68b9dd64cbb391421e2f444aca27e72a6937 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 17 Jan 2018 12:14:56 +0100 Subject: [PATCH 106/138] Fix Linux icons --- src/gui/CMakeLists.txt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index a9e8b055e..bc50ebbb7 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -234,14 +234,13 @@ if(UNIX AND NOT APPLE) endif() if(NOT BUILD_OWNCLOUD_OSX_BUNDLE) - if(NOT WIN32) - file( GLOB _icons "${theme_dir}/colored/${APPLICATION_ICON_NAME}-icon-*.png" ) - foreach( _file ${_icons} ) - string( REPLACE "${theme_dir}/colored/${APPLICATION_ICON_NAME}-icon-" "" _res ${_file} ) - string( REPLACE ".png" "" _res ${_res} ) - install( FILES ${_file} RENAME ${APPLICATION_ICON_NAME}.png DESTINATION ${DATADIR}/icons/hicolor/${_res}x${_res}/apps ) - endforeach( _file ) + file(GLOB _icons "${theme_dir}/colored/*-${APPLICATION_ICON_NAME}-icon.png") + foreach(_file ${_icons}) + string(REPLACE "${theme_dir}/colored/" "" _res ${_file}) + string(REPLACE "-${APPLICATION_ICON_NAME}-icon.png" "" _res ${_res}) + install(FILES ${_file} RENAME ${APPLICATION_ICON_NAME}.png DESTINATION ${DATADIR}/icons/hicolor/${_res}x${_res}/apps) + endforeach(_file) endif(NOT WIN32) install(FILES ${client_I18N} DESTINATION ${SHAREDIR}/${APPLICATION_EXECUTABLE}/i18n) From a8a6f8227026fa4e6b96f11affd6a9586ab85c34 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 12 Jan 2018 09:27:11 +0100 Subject: [PATCH 107/138] Link shares: Change default share name #6298 There's a 64 character limit and we don't want to accidentally exceed it. Eventually there might be server API for default share name generation. See owncloud/core#29913 --- src/gui/sharelinkwidget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/sharelinkwidget.cpp b/src/gui/sharelinkwidget.cpp index 3742db309..938f6b7ee 100644 --- a/src/gui/sharelinkwidget.cpp +++ b/src/gui/sharelinkwidget.cpp @@ -58,7 +58,9 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account, //Is this a file or folder? QFileInfo fi(localPath); _isFile = fi.isFile(); - _ui->nameLineEdit->setText(tr("%1 link").arg(fi.fileName())); + + // Note: the share name cannot be longer than 64 characters + _ui->nameLineEdit->setText(tr("Public link")); // the following progress indicator widgets are added to layouts which makes them // automatically deleted once the dialog dies. From 4337e8532e28c1156cff95b84d592041553072e2 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Thu, 11 Jan 2018 10:51:42 +0100 Subject: [PATCH 108/138] Exclude matching: Speedup the full-path traversal case Previously we'd use the full regex when the bname triggered a full-path matching to take place. Now we have a simplified full-traversal regex for this case that can be significantly faster to apply. Triggered by #5017 but doesn't actually solve it. --- src/csync/csync_exclude.cpp | 86 ++++++++++++------- src/csync/csync_exclude.h | 11 ++- .../csync/csync_tests/check_csync_exclude.cpp | 7 +- 3 files changed, 69 insertions(+), 35 deletions(-) diff --git a/src/csync/csync_exclude.cpp b/src/csync/csync_exclude.cpp index 524daed27..2e824f21c 100644 --- a/src/csync/csync_exclude.cpp +++ b/src/csync/csync_exclude.cpp @@ -361,29 +361,34 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, ItemTy QRegularExpressionMatch m; if (filetype == ItemTypeDirectory) { - m = _bnameActivationRegexDir.match(bnameStr); + m = _bnameTraversalRegexDir.match(bnameStr); } else { - m = _bnameActivationRegexFile.match(bnameStr); + m = _bnameTraversalRegexFile.match(bnameStr); } if (!m.hasMatch()) - return match; - - // Now run the full match + return CSYNC_NOT_EXCLUDED; + if (!m.captured(1).isEmpty()) { + return CSYNC_FILE_EXCLUDE_LIST; + } else if (!m.captured(2).isEmpty()) { + return CSYNC_FILE_EXCLUDE_AND_REMOVE; + } + // third capture: full path matching is triggered QString pathStr = QString::fromUtf8(path); + if (filetype == ItemTypeDirectory) { - m = _fullRegexDir.match(pathStr); + m = _fullTraversalRegexDir.match(pathStr); } else { - m = _fullRegexFile.match(pathStr); + m = _fullTraversalRegexFile.match(pathStr); } if (m.hasMatch()) { if (!m.captured(1).isEmpty()) { - match = CSYNC_FILE_EXCLUDE_LIST; + return CSYNC_FILE_EXCLUDE_LIST; } else if (!m.captured(2).isEmpty()) { - match = CSYNC_FILE_EXCLUDE_AND_REMOVE; + return CSYNC_FILE_EXCLUDE_AND_REMOVE; } } - return match; + return CSYNC_NOT_EXCLUDED; } CSYNC_EXCLUDE_TYPE ExcludedFiles::fullPatternMatch(const char *path, ItemType filetype) const @@ -552,16 +557,16 @@ void ExcludedFiles::prepare() { // Build regular expressions for the different cases. // - // To compose the _bnameActivationRegex and _fullRegex patterns we - // collect several subgroups of patterns here. + // To compose the _bnameTraversalRegex, _fullTraversalRegex and _fullRegex + // patterns we collect several subgroups of patterns here. // // * The "full" group will contain all patterns that contain a non-trailing - // slash. They only make sense in the fullRegex. + // slash. They only make sense in the fullRegex and fullTraversalRegex. // * The "bname" group contains all patterns without a non-trailing slash. // These need separate handling in the _fullRegex (slash-containing // patterns must be anchored to the front, these don't need it) // * The "bnameTrigger" group contains the bname part of all patterns in the - // "full" group. These and the "bname" group become _bnameActivationRegex. + // "full" group. These and the "bname" group become _bnameTraversalRegex. // // To complicate matters, the exclude patterns have two binary attributes // meaning we'll end up with 4 variants: @@ -644,18 +649,37 @@ void ExcludedFiles::prepare() emptyMatchNothing(bnameTriggerFileDir); emptyMatchNothing(bnameTriggerDir); - // The bname activation regexe is applied to the bname only, so must be - // anchored in the beginning and in the end. It has the explicit triggers - // plus the bname-only patterns. Here we don't care about the remove/keep - // distinction. - _bnameActivationRegexFile.setPattern( - "^(?:" + bnameFileDirKeep + "|" + bnameFileDirRemove + "|" + bnameTriggerFileDir + ")$"); - _bnameActivationRegexDir.setPattern( - "^(?:" + bnameFileDirKeep + "|" + bnameFileDirRemove - + "|" + bnameDirKeep + "|" + bnameFileDirRemove - + "|" + bnameTriggerFileDir + "|" + bnameTriggerDir + ")$"); + // The bname activation regex is applied to the bname only, so must be + // anchored in the beginning and in the end. It has the structure: + // (exclude-and-keep)|(exclude-and-remove)|(bname triggers). + // If the third group matches, the fullActivatedRegex needs to be applied + // to the full path. + _bnameTraversalRegexFile.setPattern( + "^(" + bnameFileDirKeep + ")$|" + + "^(" + bnameFileDirRemove + ")$|" + + "^(" + bnameTriggerFileDir + ")$"); + _bnameTraversalRegexDir.setPattern( + "^(" + bnameFileDirKeep + "|" + bnameDirKeep + ")$|" + + "^(" + bnameFileDirRemove + "|" + bnameDirRemove + ")$|" + + "^(" + bnameTriggerFileDir + "|" + bnameTriggerDir + ")$"); - // The full regex has two captures, it's basic form is "(...)|(...)". The first + // The full traveral regex is applied to the full path if the bname activation + // capture matches. Its basic form is (exclude-and-keep)|(exclude-and-remove)". + // This pattern can be much simpler than fullRegex since we can assume a traversal + // situation and doesn't need to look for bname patterns in parent paths. + _fullTraversalRegexFile.setPattern( + QLatin1String("") + // Full patterns are anchored to the beginning + + "^(" + fullFileDirKeep + ")(?:$|/)" + + "|" + + "^(" + fullFileDirRemove + ")(?:$|/)"); + _fullTraversalRegexDir.setPattern( + QLatin1String("") + + "^(" + fullFileDirKeep + "|" + fullDirKeep + ")(?:$|/)" + + "|" + + "^(" + fullFileDirRemove + "|" + fullDirRemove + ")(?:$|/)"); + + // The full regex has two captures, its basic form is "(...)|(...)". The first // capture has the keep/exclude-only patterns, the second the remove/exclude-and-remove // patterns. _fullRegexFile.setPattern( @@ -684,10 +708,14 @@ void ExcludedFiles::prepare() QRegularExpression::PatternOptions patternOptions = QRegularExpression::NoPatternOption; if (OCC::Utility::fsCasePreserving()) patternOptions |= QRegularExpression::CaseInsensitiveOption; - _bnameActivationRegexFile.setPatternOptions(patternOptions); - _bnameActivationRegexFile.optimize(); - _bnameActivationRegexDir.setPatternOptions(patternOptions); - _bnameActivationRegexDir.optimize(); + _bnameTraversalRegexFile.setPatternOptions(patternOptions); + _bnameTraversalRegexFile.optimize(); + _bnameTraversalRegexDir.setPatternOptions(patternOptions); + _bnameTraversalRegexDir.optimize(); + _fullTraversalRegexFile.setPatternOptions(patternOptions); + _fullTraversalRegexFile.optimize(); + _fullTraversalRegexDir.setPatternOptions(patternOptions); + _fullTraversalRegexDir.optimize(); _fullRegexFile.setPatternOptions(patternOptions); _fullRegexFile.optimize(); _fullRegexDir.setPatternOptions(patternOptions); diff --git a/src/csync/csync_exclude.h b/src/csync/csync_exclude.h index 950a0f46f..249ec7bff 100644 --- a/src/csync/csync_exclude.h +++ b/src/csync/csync_exclude.h @@ -179,8 +179,9 @@ private: * full("a/b/c/d") == traversal("a") || traversal("a/b") || traversal("a/b/c") * * The traversal matcher can be extremely fast because it has a fast early-out - * case: It checks the bname part of the path against _bnameActivationRegex - * and only runs the full regex if the bname activation was triggered. + * case: It checks the bname part of the path against _bnameTraversalRegex + * and only runs a simplified _fullTraversalRegex on the whole path if bname + * activation for it was triggered. * * Note: The traversal matcher will return not-excluded on some paths that the * full matcher would exclude. Example: "b" is excluded. traversal("b/c") @@ -198,8 +199,10 @@ private: QList _allExcludes; /// see prepare() - QRegularExpression _bnameActivationRegexFile; - QRegularExpression _bnameActivationRegexDir; + QRegularExpression _bnameTraversalRegexFile; + QRegularExpression _bnameTraversalRegexDir; + QRegularExpression _fullTraversalRegexFile; + QRegularExpression _fullTraversalRegexDir; QRegularExpression _fullRegexFile; QRegularExpression _fullRegexDir; diff --git a/test/csync/csync_tests/check_csync_exclude.cpp b/test/csync/csync_tests/check_csync_exclude.cpp index 41f3261d5..f719aa4aa 100644 --- a/test/csync/csync_tests/check_csync_exclude.cpp +++ b/test/csync/csync_tests/check_csync_exclude.cpp @@ -118,10 +118,13 @@ static void check_csync_exclude_add(void **) assert_true(excludedFiles->_allExcludes.contains("/tmp/check_csync1/*")); assert_true(excludedFiles->_fullRegexFile.pattern().contains("csync1")); - assert_false(excludedFiles->_bnameActivationRegexFile.pattern().contains("csync1")); + assert_true(excludedFiles->_fullTraversalRegexFile.pattern().contains("csync1")); + assert_false(excludedFiles->_bnameTraversalRegexFile.pattern().contains("csync1")); excludedFiles->addManualExclude("foo"); - assert_true(excludedFiles->_bnameActivationRegexFile.pattern().contains("foo")); + assert_true(excludedFiles->_bnameTraversalRegexFile.pattern().contains("foo")); + assert_true(excludedFiles->_fullRegexFile.pattern().contains("foo")); + assert_false(excludedFiles->_fullTraversalRegexFile.pattern().contains("foo")); } static void check_csync_excluded(void **) From e0cc93c04741bc593cecf4f22965ef18a22a85c7 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 17 Jan 2018 15:57:57 +0100 Subject: [PATCH 109/138] Enable appveyor builds --- appveyor.ini | 45 +++++++++++++++++++++++++++++++++++++++++++++ appveyor.yml | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 appveyor.ini create mode 100644 appveyor.yml diff --git a/appveyor.ini b/appveyor.ini new file mode 100644 index 000000000..658eeac24 --- /dev/null +++ b/appveyor.ini @@ -0,0 +1,45 @@ +[General] +Branch = master +ShallowClone = True +Command=craft + +# Variables defined here override the default value +# The variable names are casesensitive +[Variables] +#Values need to be overwritten to create a chache +UseCache = True +CreateCache = False + +# Settings applicable for all Crafts matrices +# Settings are Category/key=value +# Category is case sensitive + +[GeneralSettings] +General/EMERGE_PKGDSTDIR=${Variables:APPVEYOR_BUILD_FOLDER}/binaries +Paths/python = C:\Python36 +Paths/python27 = C:\Python27 +Paths/downloaddir = ${Variables:Root}\downloads +ShortPath/Enabled = False +ShortPath/EnableJunctions = True +ShortPath/JunctionDir = C:\CM-SP\ +Packager/CacheDir = ${Variables:Root}\cache +Packager/UseCache = ${Variables:UseCache} +Packager/CreateCache = ${Variables:CreateCache} +; Packager/RepositoryUrl = https://files.kde.org/craft/ +Packager/PackageType = PortablePackager +Packager/RepositoryUrl = http://ftp.acc.umu.se/mirror/kde.org/files/craft/master/ +Compile/BuildType = RelWithDebInfo +ContinuousIntegration/Enabled = True + +[BlueprintSettings] +# don't try to pip install on the ci +python-modules.ignored = True + +libs/qt5.version = 5.9.3 +craft/craft-core.version = master + +[windows-msvc2017_64-cl] +General/ABI = windows-msvc2017_64-cl + +[windows-msvc2017_32-cl] +General/ABI = windows-msvc2017_32-cl diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000..11098ae10 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,51 @@ +version: '{build}-{branch}' + +branches: + only: + - master + +clone_depth: 50 + + +init: +- ps: | + function craft($target) { + & C:\Python36\python.exe "C:\CraftMaster\CraftMaster\CraftMaster.py" --config "$env:APPVEYOR_BUILD_FOLDER\appveyor.ini" --variables "APPVEYOR_BUILD_FOLDER=$env:APPVEYOR_BUILD_FOLDER" --target $target -c $args + if($LASTEXITCODE -ne 0) {exit $LASTEXITCODE} + } + +install: +- ps: | + #use cmd to silence powershell behaviour for stderr + & cmd /C "git clone -q --depth=1 git://anongit.kde.org/craftmaster.git C:\CraftMaster\CraftMaster 2>&1" + + craft $env:TARGET -i craft + craft $env:TARGET --install-deps owncloud-client + +build_script: +- ps: | + craft $env:TARGET --no-cache --src-dir $env:APPVEYOR_BUILD_FOLDER owncloud-client + +after_build: +- ps: | + craft $env:TARGET --src-dir $env:APPVEYOR_BUILD_FOLDER --package owncloud-client + + +on_finish: +- ps: | + Get-ChildItem $env:USERPROFILE\.craft\* | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name } + +#test_script: +#- ps: | + #craft $env:TARGET --src-dir $env:APPVEYOR_BUILD_FOLDER --test owncloud-client +test: off + +environment: + matrix: + - TARGET: windows-msvc2017_32-cl + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + - TARGET: windows-msvc2017_64-cl + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + +artifacts: + - path: binaries/* From 486ccaff56318a625d7e284acb53813867ff89be Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 17 Jan 2018 16:25:03 +0100 Subject: [PATCH 110/138] Enable tests in appveyor builds --- appveyor.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 11098ae10..289f58958 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -35,10 +35,9 @@ on_finish: - ps: | Get-ChildItem $env:USERPROFILE\.craft\* | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name } -#test_script: -#- ps: | - #craft $env:TARGET --src-dir $env:APPVEYOR_BUILD_FOLDER --test owncloud-client -test: off +test_script: +- ps: | + craft $env:TARGET --src-dir $env:APPVEYOR_BUILD_FOLDER --test owncloud-client environment: matrix: From 926609bd74b237049018d7dfa29b0a902a87d076 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 17 Jan 2018 17:31:32 +0100 Subject: [PATCH 111/138] Partially revert "shell_integration/dolphin: Silence some warnings" This partially reverts commit 1c721e9422069744dcc3447219487bf2695a81b6. This caused the overlay plugin to be installed at the wrong place because the kcoreaddons_add_plugin macto still use deprecated ${PLUGIN_INSTALL_DIR}. I guess we'll have to live with the warnings. --- shell_integration/dolphin/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/shell_integration/dolphin/CMakeLists.txt b/shell_integration/dolphin/CMakeLists.txt index 14a72041f..394bc7eee 100644 --- a/shell_integration/dolphin/CMakeLists.txt +++ b/shell_integration/dolphin/CMakeLists.txt @@ -19,7 +19,6 @@ set_package_properties(DolphinVcs PROPERTIES PURPOSE "Provides plugin interfaces for Dolphin." ) -set(KDE_INSTALL_DIRS_NO_DEPRECATED TRUE) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings) From a32b3e565b7d8348ac9f04c39b53ab32215f3eb6 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Thu, 18 Jan 2018 02:18:38 +0100 Subject: [PATCH 112/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ translations/client_ca.ts | 46 ++++++++++++++++-------------------- translations/client_cs.ts | 46 ++++++++++++++++-------------------- translations/client_de.ts | 46 ++++++++++++++++-------------------- translations/client_el.ts | 46 ++++++++++++++++-------------------- translations/client_en.ts | 46 ++++++++++++++++-------------------- translations/client_es.ts | 46 ++++++++++++++++-------------------- translations/client_es_AR.ts | 46 ++++++++++++++++-------------------- translations/client_et.ts | 46 ++++++++++++++++-------------------- translations/client_eu.ts | 46 ++++++++++++++++-------------------- translations/client_fa.ts | 46 ++++++++++++++++-------------------- translations/client_fi.ts | 46 ++++++++++++++++-------------------- translations/client_fr.ts | 46 ++++++++++++++++-------------------- translations/client_gl.ts | 46 ++++++++++++++++-------------------- translations/client_hu.ts | 46 ++++++++++++++++-------------------- translations/client_it.ts | 46 ++++++++++++++++-------------------- translations/client_ja.ts | 46 ++++++++++++++++-------------------- translations/client_nb_NO.ts | 46 ++++++++++++++++-------------------- translations/client_nl.ts | 46 ++++++++++++++++-------------------- translations/client_pl.ts | 46 ++++++++++++++++-------------------- translations/client_pt.ts | 46 ++++++++++++++++-------------------- translations/client_pt_BR.ts | 46 ++++++++++++++++-------------------- translations/client_ru.ts | 46 ++++++++++++++++-------------------- translations/client_sk.ts | 46 ++++++++++++++++-------------------- translations/client_sl.ts | 46 ++++++++++++++++-------------------- translations/client_sr.ts | 46 ++++++++++++++++-------------------- translations/client_sv.ts | 46 ++++++++++++++++-------------------- translations/client_th.ts | 46 ++++++++++++++++-------------------- translations/client_tr.ts | 46 ++++++++++++++++-------------------- translations/client_uk.ts | 46 ++++++++++++++++-------------------- translations/client_zh_CN.ts | 46 ++++++++++++++++-------------------- translations/client_zh_TW.ts | 46 ++++++++++++++++-------------------- 32 files changed, 654 insertions(+), 775 deletions(-) diff --git a/mirall.desktop.in b/mirall.desktop.in index bf3484c34..3142c5b6b 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -176,6 +176,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion diff --git a/translations/client_ca.ts b/translations/client_ca.ts index bd2d99a06..be35103fe 100644 --- a/translations/client_ca.ts +++ b/translations/client_ca.ts @@ -2688,99 +2688,95 @@ No és aconsellada usar-la. - - + + P&assword protect Protegit amb contr&asenya - + Password Protected Protegit amb contrasenya - + The file can not be shared because it was shared without sharing permission. El fitxer no es pot compartir perquè va ser compartit sense permisos de compartició. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Esborra - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Envia l'enllaç per correu electrònic - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Cancel·lar - + + Public link - + Delete link share - + Public sh&aring requires a password La comp&artició pública requereix una contrasenya - + Please Set Password Establiu la contrasenya diff --git a/translations/client_cs.ts b/translations/client_cs.ts index 03b86c918..50131a190 100644 --- a/translations/client_cs.ts +++ b/translations/client_cs.ts @@ -2691,99 +2691,95 @@ Nedoporučuje se jí používat. Kdokoliv, kdo má odkaz, může přistupovat k tomuto souboru/složce - - + + P&assword protect Ch&ránit heslem - + Password Protected Chráněno heslem - + The file can not be shared because it was shared without sharing permission. Tento soubor nelze sdílet, protože byl nasdílen bez možnosti dalšího sdílení. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Smazat - + Open link in browser Otevřít odkaz v prohlížeči - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Poslat odkaz emailem - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Zrušit - + + Public link Veřejný odkaz - + Delete link share - + Public sh&aring requires a password Veřejné s&dílení vyžaduje heslo - + Please Set Password Nastavte prosím heslo diff --git a/translations/client_de.ts b/translations/client_de.ts index 928134fcc..6064178cd 100644 --- a/translations/client_de.ts +++ b/translations/client_de.ts @@ -2692,99 +2692,95 @@ Es ist nicht ratsam, diese zu benutzen. Jeder mit dem Link hat Zugriff auf die Datei/Ordner - - + + P&assword protect Passwort geschützt - + Password Protected passwortgeschützt - + The file can not be shared because it was shared without sharing permission. Die Datei kann nicht geteilt werden, weil sie ohne erneute Teilungs-Berechtigung für Sie geteilt wurde. - - %1 link - %1 - Link - - - + Link shares have been disabled Das Teilen von Links wurde deaktiviert - + Create public link share Öffentlichen Link zum Teilen erstellen - - + + Delete Löschen - + Open link in browser Link im Browser öffnen - + Copy link to clipboard Link in Zwischenablage kopieren - + Copy link to clipboard (direct download) Link in die Zwischenablage kopieren (direkter download) - + Send link by email Link als E-Mail verschicken - + Send link by email (direct download) Link per Email senden (direkter download) - + Confirm Link Share Deletion Löschung des öffentlichen Links bestätigen - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> <p>Möchte Sie wirklich den öffentlichen Link <i>%1 </i>löschen?<p>Hinweis: Dies kann nicht rückgängig gemacht werden.</p> - + Cancel Abbrechen - + + Public link Öffentlicher Link - + Delete link share Öffentlichen Link löschen - + Public sh&aring requires a password Öffentliches Teilen erfordert ein P&asswort - + Please Set Password Bitte wählen Sie ein Passwort: diff --git a/translations/client_el.ts b/translations/client_el.ts index 42a4bb04d..f8d25d012 100644 --- a/translations/client_el.ts +++ b/translations/client_el.ts @@ -2693,99 +2693,95 @@ It is not advisable to use it. Οποιοσδήποτε με τη σύνδεση έχει πρόσβαση στο αρχείο / φάκελο - - + + P&assword protect Π&ροστασία με κωδικό - + Password Protected Προστατευμένο με κωδικό πρόσβασης - + The file can not be shared because it was shared without sharing permission. Το αρχείο δεν μπορεί να διαμοιραστεί γιατί διαμοιράστηκε χωρίς δικαιώματα διαμοιρασμού. - - %1 link - %1 σλυνδεσμος - - - + Link shares have been disabled - + Create public link share - - + + Delete Διαγραφή - + Open link in browser Άνοιγμα συνδέσμου στον περιηγητή - + Copy link to clipboard Αντιγραφή συνδέσμου στο πρόχειρο - + Copy link to clipboard (direct download) - + Send link by email Αποστολή συνδέσμου με αλληλογραφία - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Ακύρωση - + + Public link Δημόσιος σύνδεσμος - + Delete link share - + Public sh&aring requires a password Ο δημόσιος &διαμοιρασμός απαιτεί κωδικό πρόσβασης - + Please Set Password Παρακαλούμε ορίστε Κωδικό diff --git a/translations/client_en.ts b/translations/client_en.ts index 0518e60d0..cec124faa 100644 --- a/translations/client_en.ts +++ b/translations/client_en.ts @@ -2712,99 +2712,95 @@ It is not advisable to use it. - - + + P&assword protect - + Password Protected - + The file can not be shared because it was shared without sharing permission. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel - + + Public link - + Delete link share - + Public sh&aring requires a password - + Please Set Password diff --git a/translations/client_es.ts b/translations/client_es.ts index 2387361b6..1d26e031f 100644 --- a/translations/client_es.ts +++ b/translations/client_es.ts @@ -2692,99 +2692,95 @@ No se recomienda usarla. Quienquiera que posea el vínculo tendrá acceso al archivo/carpeta - - + + P&assword protect Protegido por contr&aseña - + Password Protected Protegido con contraseña - + The file can not be shared because it was shared without sharing permission. El archivo no puede compartirse; ya que fue compartido sin permisos correspondientes. - - %1 link - %1 Enlace - - - + Link shares have been disabled Se ha deshabilitado la compartición de enlaces - + Create public link share Crear un enlace público compartido - - + + Delete Eliminar - + Open link in browser Abrir enlace en el explorador - + Copy link to clipboard Copiar enlace al portapapeles - + Copy link to clipboard (direct download) Copiar enlace al portapapeles (descarga directa) - + Send link by email Enviar enlace por e-mail - + Send link by email (direct download) Enviar enlace por e-mail (descarga directa) - + Confirm Link Share Deletion Confirmar eliminación de enlace de recurso compartido - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> <p>¿Realmente desea borrar el enlace público compartido <i>%1</i>?</p><p>Nota: Esta acción no se puede deshacer</p> - + Cancel Cancelar - + + Public link Enlace Publico - + Delete link share Borrar el enlace compartido - + Public sh&aring requires a password Compartir public&amente requiere contraseña - + Please Set Password Por favor establece una contraseña diff --git a/translations/client_es_AR.ts b/translations/client_es_AR.ts index 4efdac293..d4aea5cb5 100644 --- a/translations/client_es_AR.ts +++ b/translations/client_es_AR.ts @@ -2680,99 +2680,95 @@ It is not advisable to use it. - - + + P&assword protect - + Password Protected - + The file can not be shared because it was shared without sharing permission. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Borrar - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Mandar enlace por e-mail - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Cancelar - + + Public link - + Delete link share - + Public sh&aring requires a password - + Please Set Password diff --git a/translations/client_et.ts b/translations/client_et.ts index 748eba1fe..e477a5ecb 100644 --- a/translations/client_et.ts +++ b/translations/client_et.ts @@ -2681,99 +2681,95 @@ Selle kasutamine pole soovitatav. - - + + P&assword protect P&arooliga kaitstud - + Password Protected Parooliga kaitstud - + The file can not be shared because it was shared without sharing permission. - - %1 link - %1 link - - - + Link shares have been disabled - + Create public link share - - + + Delete Kustuta - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Saada link e-postiga - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Loobu - + + Public link Avalik link - + Delete link share - + Public sh&aring requires a password Avalik j&agamine nõuab parooli - + Please Set Password Palun määra parool diff --git a/translations/client_eu.ts b/translations/client_eu.ts index 91f125d1a..10eea4ab2 100644 --- a/translations/client_eu.ts +++ b/translations/client_eu.ts @@ -2683,99 +2683,95 @@ Ez da gomendagarria erabltzea. Esteka duen edonork atzitu dezake fitxategi/karpeta - - + + P&assword protect - + Password Protected - + The file can not be shared because it was shared without sharing permission. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Ezabatu - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Bidali lotura posta bidez - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Ezeztatu - + + Public link - + Delete link share - + Public sh&aring requires a password - + Please Set Password Mesedez Ezarri Pasahitza diff --git a/translations/client_fa.ts b/translations/client_fa.ts index f2cf68acf..8c9d53594 100644 --- a/translations/client_fa.ts +++ b/translations/client_fa.ts @@ -2691,99 +2691,95 @@ It is not advisable to use it. هر کسی با پیوند به پرونده/پوشه دسترسی دارد - - + + P&assword protect رمز عبور محافظت می شود - + Password Protected محافظت شده توسط رمزعبور - + The file can not be shared because it was shared without sharing permission. پرونده نمی تواند به اشتراک گذاشته شود زیرا بدون مجوز به اشتراک گذاشته شده است. - - %1 link - پیوند 1% - - - + Link shares have been disabled اشتراک های پیوند غیر فعال شده اند - + Create public link share اشتراک لینک عمومی بسازید - - + + Delete حذف - + Open link in browser لینک را در مرورگر باز کنید - + Copy link to clipboard لینک را در کلیپ بورد کپی کنید - + Copy link to clipboard (direct download) لینک را در کلیپ بورد کپی کنید (دانلود مستقیم) - + Send link by email لینک را توسط ایمیل بفرست. - + Send link by email (direct download) لینک را با پست الکترونیکی ارسال کنید (دانلود مستقیم) - + Confirm Link Share Deletion حذف اشتراک گذاری لینک را تایید کنید - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> <p>آیا شما واقعا می خواهید اشتراک لینک عمومی را حذف کنید<i>1%</i>؟</p><p> توجه: این عمل نمی تواند انجام نشود.</p> - + Cancel لغو - + + Public link پیوند عمومی - + Delete link share حذف پیوند اشتراک - + Public sh&aring requires a password اشتراک عمومی نیازمند رمز عبور است - + Please Set Password لطفا رمزعبور را تعیین کنید diff --git a/translations/client_fi.ts b/translations/client_fi.ts index d69899e26..e05f18be5 100644 --- a/translations/client_fi.ts +++ b/translations/client_fi.ts @@ -2683,99 +2683,95 @@ Osoitteen käyttäminen ei ole suositeltavaa. - - + + P&assword protect &Suojaa salasanalla - + Password Protected Salasanasuojattu - + The file can not be shared because it was shared without sharing permission. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Poista - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Lähetä linkki sähköpostitse - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Peruuta - + + Public link - + Delete link share - + Public sh&aring requires a password &Julkinen jakaminen vaatii salasanan - + Please Set Password Aseta salasana diff --git a/translations/client_fr.ts b/translations/client_fr.ts index 0460fe105..09b80e47a 100644 --- a/translations/client_fr.ts +++ b/translations/client_fr.ts @@ -2694,100 +2694,96 @@ Il est déconseillé de l'utiliser. Quiconque dispose du lien a accès aux fichiers/dossiers - - + + P&assword protect Protéger par mot de p&asse - + Password Protected Protégé par mot de passe - + The file can not be shared because it was shared without sharing permission. Le fichier ne peut pas être partagé car il a été partagé sans permission de repartage. - - %1 link - lien %1 - - - + Link shares have been disabled Les partages par lien ont été désactivés - + Create public link share Créer une lien de partage public - - + + Delete Supprimer - + Open link in browser Ouvrir le lien dans le navigateur - + Copy link to clipboard Copier le lien vers le presse-papier - + Copy link to clipboard (direct download) Copier le lien vers le presse-papier (téléchargement direct) - + Send link by email Envoyer le lien par email - + Send link by email (direct download) Envoyer le lien par courriel (téléchargement direct) - + Confirm Link Share Deletion Confirmer la suppression du partage par lien - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> <p>Voulez-vous vraiment supprimer le partage par lien public<i>%1</i>? <p>Note: Cette action ne peut être annulée.</p> - + Cancel Anuler - + + Public link Lien public - + Delete link share Supprimer le partage par lien - + Public sh&aring requires a password Le p&artage public nécessite un mot de passe - + Please Set Password Veuillez choisir un mot de passe diff --git a/translations/client_gl.ts b/translations/client_gl.ts index 79611491c..0315e96a1 100644 --- a/translations/client_gl.ts +++ b/translations/client_gl.ts @@ -2682,99 +2682,95 @@ Recomendámoslle que non o use. - - + + P&assword protect Contr&asinal de protección - + Password Protected Protexido con contrasinal - + The file can not be shared because it was shared without sharing permission. Non é posíbel compartir o ficheiro, xa que foi compartido sen permisis para compartir. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Eliminar - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Enviar a ligazón por correo - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Cancelar - + + Public link - + Delete link share - + Public sh&aring requires a password A comp&artición pública precisa de contrasinal - + Please Set Password Estabeleza o contrasinal diff --git a/translations/client_hu.ts b/translations/client_hu.ts index 8d4fb385f..30e0428f8 100644 --- a/translations/client_hu.ts +++ b/translations/client_hu.ts @@ -2680,99 +2680,95 @@ It is not advisable to use it. Bárki a hivatkozással hozzáférhet a fájlhoz/mappához - - + + P&assword protect J&elszóval védve - + Password Protected Jelszóval védett - + The file can not be shared because it was shared without sharing permission. A fájlt nem lehetett megosztani, mert megosztási jogosultság nélkül lett megosztva. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Törlés - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Link küldése e-mail-ben - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Mégsem - + + Public link - + Delete link share - + Public sh&aring requires a password Nyilvános me&gosztáshoz szükség van jelszóra - + Please Set Password Kérjük, állíts be egy jelszót diff --git a/translations/client_it.ts b/translations/client_it.ts index 440555260..2da0e159c 100644 --- a/translations/client_it.ts +++ b/translations/client_it.ts @@ -2688,99 +2688,95 @@ Non è consigliabile utilizzarlo. Chiunque sia in possesso del collegamento ha accesso al file/cartella - - + + P&assword protect Proteggi con p&assword - + Password Protected Protetta da password - + The file can not be shared because it was shared without sharing permission. Il file non può essere condiviso poiché è stato condiviso senza il permesso di condivisione. - - %1 link - - - - + Link shares have been disabled La condivisione tramite link è stata disabilitata - + Create public link share Crea collegamento pubblico - - + + Delete Elimina - + Open link in browser Apri collegamento nel browser - + Copy link to clipboard Copia link negli appunti - + Copy link to clipboard (direct download) - + Send link by email Invia collegamento tramite email - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Annulla - + + Public link Collegamento pubblico - + Delete link share - + Public sh&aring requires a password La condivisione pubblic&a richiede una password - + Please Set Password imposta la password diff --git a/translations/client_ja.ts b/translations/client_ja.ts index d561319c2..8c3166546 100644 --- a/translations/client_ja.ts +++ b/translations/client_ja.ts @@ -2689,99 +2689,95 @@ It is not advisable to use it. リンクを知っている人はファイル/フォルダーにアクセスできます - - + + P&assword protect パスワード保護(&A) - + Password Protected パスワード保護 - + The file can not be shared because it was shared without sharing permission. 再共有権限がない共有ため、このファイルは共有できません。 - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete 削除 - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email メールでリンクを送信 - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel キャンセル - + + Public link - + Delete link share - + Public sh&aring requires a password 共有するにはパスワードが必要(&A) - + Please Set Password パスワードを入力してください diff --git a/translations/client_nb_NO.ts b/translations/client_nb_NO.ts index 9573829d7..46fa85f73 100644 --- a/translations/client_nb_NO.ts +++ b/translations/client_nb_NO.ts @@ -2692,99 +2692,95 @@ Det er ikke tilrådelig å bruke den. Alle med linken har tilgang til filen/mappen - - + + P&assword protect P&assordbeskyttelse - + Password Protected Passordbeskyttet - + The file can not be shared because it was shared without sharing permission. Filen kan ikke deles fordi den ble delt uten adgang til å dele. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Slett - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Send link i e-post - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Avbryt - + + Public link Offentlig lenke - + Delete link share - + Public sh&aring requires a password Offentlig d&eling krever et passord - + Please Set Password Sett passord diff --git a/translations/client_nl.ts b/translations/client_nl.ts index 53ee7ae1a..e543cecfe 100644 --- a/translations/client_nl.ts +++ b/translations/client_nl.ts @@ -2697,99 +2697,95 @@ We adviseren deze site niet te gebruiken. Iedereen met de link heeft toegang tot het bestand of de map - - + + P&assword protect &Wachtwoord beveiligd - + Password Protected Wachtwoord beveiligd - + The file can not be shared because it was shared without sharing permission. Het bestand kan niet worden gedeeld, omdat het werd gedeeld zonder verder delen toestemming. - - %1 link - %1 link - - - + Link shares have been disabled - + Create public link share - - + + Delete Verwijderen - + Open link in browser Openen link in browser - + Copy link to clipboard Kopiëren link naar klembord - + Copy link to clipboard (direct download) - + Send link by email Versturen links via e-mail - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Annuleren - + + Public link Openbare Link - + Delete link share - + Public sh&aring requires a password Openbaar de&len vereist een wachtwoord - + Please Set Password Stel uw wachtwoord in diff --git a/translations/client_pl.ts b/translations/client_pl.ts index b6772974f..5d1ce36e5 100644 --- a/translations/client_pl.ts +++ b/translations/client_pl.ts @@ -2689,99 +2689,95 @@ Niezalecane jest jego użycie. Każdy posiadający link ma dostęp do pliku/katalogu. - - + + P&assword protect - + Password Protected Zabezpieczone hasłem - + The file can not be shared because it was shared without sharing permission. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Usuń - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Wyślij link mailem - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Anuluj - + + Public link - + Delete link share - + Public sh&aring requires a password - + Please Set Password Proszę podać hasło diff --git a/translations/client_pt.ts b/translations/client_pt.ts index 062c246b7..9bceb1e06 100644 --- a/translations/client_pt.ts +++ b/translations/client_pt.ts @@ -2693,99 +2693,95 @@ Não é aconselhada a sua utilização. Qualquer pessoa com a hiperligação terá acesso ao ficheiro/pasta - - + + P&assword protect Protegida por senha - + Password Protected Protegido com Senha - + The file can not be shared because it was shared without sharing permission. O ficheiro não pode ser partilhado porque foi partilhado sem permissão de partilha. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Eliminar - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Enviar hiperligação por e-mail - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Cancelar - + + Public link Hiperligação Pública - + Delete link share - + Public sh&aring requires a password A pa&rtilha pública requer uma palavra-passe: - + Please Set Password Por favor, Definir Senha diff --git a/translations/client_pt_BR.ts b/translations/client_pt_BR.ts index 50e982b06..886cec6a2 100644 --- a/translations/client_pt_BR.ts +++ b/translations/client_pt_BR.ts @@ -2690,99 +2690,95 @@ It is not advisable to use it. Qualquer pessoa com o link tem acesso ao arquivo/pasta - - + + P&assword protect S&enha de proteção - + Password Protected Protegido por Senha - + The file can not be shared because it was shared without sharing permission. O arquivo não pode ser partilhado, pois foi compartilhado sem permissão de compartilhamento. - - %1 link - %1 linque - - - + Link shares have been disabled Os compartilhamentos de linque foram desativados - + Create public link share Criar linque de compartilhamento público - - + + Delete Excluir - + Open link in browser Abrir linque no navegador - + Copy link to clipboard Copiar o linque para a área de transferência - + Copy link to clipboard (direct download) Copiar o linque para a área de transferência (download direto) - + Send link by email Enviar linque por e-mail - + Send link by email (direct download) Enviar linque por e-mail (download direto) - + Confirm Link Share Deletion Confirmar o Link de Eliminação de Compartilhamento - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> <p>Você realmente deseja excluir o compartilhamento de links públicos <i>%1</i>?</p><p>Nota: Esta ação não pode ser desfeita.</p> - + Cancel Cancelar - + + Public link Linque público - + Delete link share Excluir linque de compartilhamento - + Public sh&aring requires a password Comp&artilhamento público requer uma senha - + Please Set Password Por favor, Definir senha diff --git a/translations/client_ru.ts b/translations/client_ru.ts index e96cabbdb..266b36c5d 100644 --- a/translations/client_ru.ts +++ b/translations/client_ru.ts @@ -2690,99 +2690,95 @@ It is not advisable to use it. Каждый, у кого есть эта ссылка, имеет доступ к файлу/каталогу - - + + P&assword protect Защитить паролем - + Password Protected Защищено Паролем - + The file can not be shared because it was shared without sharing permission. Невозможно предоставить общий доступ к файлу: нет разрешения на предоставление общего доступа. - - %1 link - Ссылка на %1 - - - + Link shares have been disabled Доступ по ссылкам был отключён - + Create public link share Создать ссылку общего доступа - - + + Delete Удалить - + Open link in browser Открыть ссылку в браузере - + Copy link to clipboard Копировать ссылку в буфер обмена - + Copy link to clipboard (direct download) Скопировать ссылку в буфер обмена (прямое скачивание) - + Send link by email Отправить ссылку по email - + Send link by email (direct download) Отправить ссылку по почте (прямое скачивание) - + Confirm Link Share Deletion Подтвердите удаление доступа по ссылке - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> <p>Вы действтиельно хотите удалить доступ по общей ссылке <i>%1</i>?</p><p>Внимание: это действие будет невозможно отменить.</p> - + Cancel Отмена - + + Public link Общедоступная ссылка - + Delete link share Удалить доступ по ссылке - + Public sh&aring requires a password Публичные ссылки требуют пароля - + Please Set Password Пожалуйста, установите пароль diff --git a/translations/client_sk.ts b/translations/client_sk.ts index 27a69743d..ac2ed2044 100644 --- a/translations/client_sk.ts +++ b/translations/client_sk.ts @@ -2682,99 +2682,95 @@ Nie je vhodné ju používať. - - + + P&assword protect Ch&rániť heslom - + Password Protected Chránené heslom - + The file can not be shared because it was shared without sharing permission. Tento súbor nemožno zdieľať, lebo bol vyzdieľaný bez možnosti ďalšieho zdieľania. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Zmazať - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Odoslať odkaz emailom - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Zrušiť - + + Public link - + Delete link share - + Public sh&aring requires a password Verejné z&dieľanie vyžaduje heslo - + Please Set Password Prosím nastavte si heslo diff --git a/translations/client_sl.ts b/translations/client_sl.ts index a047cf396..52657ec18 100644 --- a/translations/client_sl.ts +++ b/translations/client_sl.ts @@ -2693,99 +2693,95 @@ Uporaba ni priporočljiva. Vsak, ki ima povezavo ima dostop do datoteke ali mape - - + + P&assword protect &Zaščiti z geslom - + Password Protected Zaščiteno z geslom - + The file can not be shared because it was shared without sharing permission. Datoteke ni mogoče dodeliti v souporabo, ker je ni navedenih ustreznih dovoljenj. - - %1 link - Povezava %1 - - - + Link shares have been disabled - + Create public link share - - + + Delete Izbriši - + Open link in browser Odpri povezavo v brskalniku - + Copy link to clipboard Kopiraj povezavo v odložišče - + Copy link to clipboard (direct download) - + Send link by email Pošlji povezavo po elektronski pošti - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Prekliči - + + Public link Javna povezava - + Delete link share - + Public sh&aring requires a password Javna omogočanje &souporabe zahteva geslo - + Please Set Password Določite geslo diff --git a/translations/client_sr.ts b/translations/client_sr.ts index 758f8dd4f..81442142b 100644 --- a/translations/client_sr.ts +++ b/translations/client_sr.ts @@ -2682,99 +2682,95 @@ It is not advisable to use it. - - + + P&assword protect &Заштићено лозинком - + Password Protected Заштићено лозинком - + The file can not be shared because it was shared without sharing permission. Фајл се не може делити јер је подељен без дозволе за поновно дељење. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Обриши - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Пошаљи везу е-поштом - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Откажи - + + Public link - + Delete link share - + Public sh&aring requires a password Јавно дељење з&хтева лозинку - + Please Set Password Поставите лозинку diff --git a/translations/client_sv.ts b/translations/client_sv.ts index a043fa655..6381d2f22 100644 --- a/translations/client_sv.ts +++ b/translations/client_sv.ts @@ -2688,99 +2688,95 @@ Det är inte lämpligt använda den. Vem som helst med länken kan komma åt filen eller mappen - - + + P&assword protect L&ösenordsskydda - + Password Protected Lösenordsskyddad - + The file can not be shared because it was shared without sharing permission. Filen kan inte delas eftersom den delades utan delningsrättigheter. - - %1 link - %1 länk - - - + Link shares have been disabled Delningslänkar har inaktiverats - + Create public link share Skapa publik delningslänk - - + + Delete Ta bort - + Open link in browser Öppna länk i webbläsare - + Copy link to clipboard Kopiera länk till urklipp - + Copy link to clipboard (direct download) Kopiera länk till urklipp (direktnedladdning) - + Send link by email Skicka länk via e-post - + Send link by email (direct download) Skicka länk med e-post (direktnedladdning) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Avbryt - + + Public link Publik länk - + Delete link share - + Public sh&aring requires a password Publik d&elning kräver lösenord - + Please Set Password Var vänlig sätt lösenord diff --git a/translations/client_th.ts b/translations/client_th.ts index afd5ef265..30d42c15e 100644 --- a/translations/client_th.ts +++ b/translations/client_th.ts @@ -2694,99 +2694,95 @@ It is not advisable to use it. ทุกคนที่มีลิงค์สามารถเข้าถึงไฟล์หรือโฟลเดอร์ได้ - - + + P&assword protect ป้องกันด้วยรหัสผ่าน - + Password Protected รหัสผ่านถูกป้องกันแล้ว - + The file can not be shared because it was shared without sharing permission. ไม่สามารถแชร์ไฟล์เพราะไม่ได้รับอนุญาต - - %1 link - %1 ลิงค์ - - - + Link shares have been disabled แชร์ลิงค์แล้วถูกปิดใช้งาน - + Create public link share สร้างแชร์ลิงค์สาธารณะ - - + + Delete ลบ - + Open link in browser เปิดลิงค์ในเบราว์เซอร์ - + Copy link to clipboard คัดลอกลิงค์ไปยังคลิปบอร์ด - + Copy link to clipboard (direct download) คัดลอกลิงค์ทางอีเมล (ดาวน์โหลดโดยตรง) - + Send link by email ส่งลิงค์ทางอีเมล - + Send link by email (direct download) ส่งลิงค์ทางอีเมล (ดาวน์โหลดโดยตรง) - + Confirm Link Share Deletion ยืนยันการลบลิงค์ที่แชร์ - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> <p>คุณต้องการลบลิงค์ที่แชร์แบบสาธารณะ<i>%1</i>?</p><p>หมายเหตุ: ไม่สามารถยกเลิกการดำเนินการนี้ได้</p> - + Cancel ยกเลิก - + + Public link ลิงค์สาธารณะ - + Delete link share ลบลิงค์ที่แชร์ - + Public sh&aring requires a password การแชร์สาธารณะจำเป็นต้องมีรหัสผ่าน - + Please Set Password กรุณาตั้งรหัสผ่าน diff --git a/translations/client_tr.ts b/translations/client_tr.ts index b45e230c9..4e17dc223 100644 --- a/translations/client_tr.ts +++ b/translations/client_tr.ts @@ -2683,99 +2683,95 @@ Kullanmanız önerilmez. Dosya/klasör linkine sahip Herkes erişebilir - - + + P&assword protect &Parola koruması - + Password Protected Parola Korumalı - + The file can not be shared because it was shared without sharing permission. Dosya paylaşılamaz, çünkü sizinle paylaşım izni olmaksızın paylaşılmış. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Sil - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Bağlantıyı e-posta ile gönder - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel İptal - + + Public link - + Delete link share - + Public sh&aring requires a password Herkese &açık paylaşım için parola gerekir - + Please Set Password Lütfen Parola Atayın diff --git a/translations/client_uk.ts b/translations/client_uk.ts index 5908611ef..15068e19d 100644 --- a/translations/client_uk.ts +++ b/translations/client_uk.ts @@ -2681,99 +2681,95 @@ It is not advisable to use it. Будь хто з цім посиланням має доступ до файлу/теки - - + + P&assword protect &Захистити паролем - + Password Protected Захищено паролем - + The file can not be shared because it was shared without sharing permission. Цей файл неможливо поширити, бо ним поділилися без права на поширення. - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete Видалити - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email Надіслати посилання по електронній пошті - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel Скасувати - + + Public link - + Delete link share - + Public sh&aring requires a password Публічне по&ширення вимагає пароль - + Please Set Password diff --git a/translations/client_zh_CN.ts b/translations/client_zh_CN.ts index da672a37b..531d9c5f0 100644 --- a/translations/client_zh_CN.ts +++ b/translations/client_zh_CN.ts @@ -2692,99 +2692,95 @@ It is not advisable to use it. 任何查看此链接的人都可以访问文件、文件夹 - - + + P&assword protect 密码保护(&a) - + Password Protected 密码保护 - + The file can not be shared because it was shared without sharing permission. 未分配共享权限,无法共享文件。 - - %1 link - %1 的链接 - - - + Link shares have been disabled 分享链接已被关闭 - + Create public link share 创建公共分享链接 - - + + Delete 删除 - + Open link in browser 在浏览器中打来链接 - + Copy link to clipboard 复制链接到剪贴板 - + Copy link to clipboard (direct download) 复制链接到剪贴板 (直接下载) - + Send link by email 通过邮件发送链接 - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel 取消 - + + Public link 公开链接 - + Delete link share - + Public sh&aring requires a password 公开分享需要密码 - + Please Set Password 请设置密码 diff --git a/translations/client_zh_TW.ts b/translations/client_zh_TW.ts index 2bd356948..632ab7560 100644 --- a/translations/client_zh_TW.ts +++ b/translations/client_zh_TW.ts @@ -2684,99 +2684,95 @@ It is not advisable to use it. - - + + P&assword protect &密碼保護 - + Password Protected 密碼保護 - + The file can not be shared because it was shared without sharing permission. 這個檔案無法被分享,並沒有分享此檔案的權限。 - - %1 link - - - - + Link shares have been disabled - + Create public link share - - + + Delete 刪除 - + Open link in browser - + Copy link to clipboard - + Copy link to clipboard (direct download) - + Send link by email 使用電子郵件傳送連結 - + Send link by email (direct download) - + Confirm Link Share Deletion - + <p>Do you really want to delete the public link share <i>%1</i>?</p><p>Note: This action cannot be undone.</p> - + Cancel 取消 - + + Public link - + Delete link share - + Public sh&aring requires a password 公開&共享需要密碼 - + Please Set Password 請設定密碼 From 217c6bbcafdce79fe39c65da0173b8a08ffce309 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 18 Jan 2018 09:46:06 +0100 Subject: [PATCH 113/138] Add AppVeyor badge --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c1a9a8246..3f6bbe2da 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # ownCloud Desktop Client -[![Build Status](https://jenkins.owncloud.org/buildStatus/icon?job=owncloud-client/client/master)](https://jenkins.owncloud.org/job/owncloud-client/job/client/job/master/) +[![Build Status](https://jenkins.owncloud.org/buildStatus/icon?job=owncloud-client/client/master)](https://jenkins.owncloud.org/job/owncloud-client/job/client/job/master/) [![Build status](https://ci.appveyor.com/api/projects/status/a1x3dslys7de6e21/branch/master?svg=true)](https://ci.appveyor.com/project/ownclouders/client/branch/master) + ## Introduction From c1b5412c1649331edf33daaa30ac34158f68826f Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Wed, 17 Jan 2018 15:22:19 +0100 Subject: [PATCH 114/138] Exclude regex: Use named captures My benchmarks show no performance difference. --- src/csync/csync_exclude.cpp | 57 +++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/csync/csync_exclude.cpp b/src/csync/csync_exclude.cpp index 2e824f21c..c52b1ac91 100644 --- a/src/csync/csync_exclude.cpp +++ b/src/csync/csync_exclude.cpp @@ -367,9 +367,9 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, ItemTy } if (!m.hasMatch()) return CSYNC_NOT_EXCLUDED; - if (!m.captured(1).isEmpty()) { + if (m.capturedStart(QStringLiteral("exclude")) != -1) { return CSYNC_FILE_EXCLUDE_LIST; - } else if (!m.captured(2).isEmpty()) { + } else if (m.capturedStart(QStringLiteral("excluderemove")) != -1) { return CSYNC_FILE_EXCLUDE_AND_REMOVE; } @@ -382,9 +382,9 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, ItemTy m = _fullTraversalRegexFile.match(pathStr); } if (m.hasMatch()) { - if (!m.captured(1).isEmpty()) { + if (m.capturedStart(QStringLiteral("exclude")) != -1) { return CSYNC_FILE_EXCLUDE_LIST; - } else if (!m.captured(2).isEmpty()) { + } else if (m.capturedStart(QStringLiteral("excluderemove")) != -1) { return CSYNC_FILE_EXCLUDE_AND_REMOVE; } } @@ -407,9 +407,9 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::fullPatternMatch(const char *path, ItemType fi m = _fullRegexFile.match(p); } if (m.hasMatch()) { - if (!m.captured(1).isEmpty()) { + if (m.capturedStart(QStringLiteral("exclude")) != -1) { return CSYNC_FILE_EXCLUDE_LIST; - } else if (!m.captured(2).isEmpty()) { + } else if (m.capturedStart(QStringLiteral("excluderemove")) != -1) { return CSYNC_FILE_EXCLUDE_AND_REMOVE; } } @@ -649,41 +649,40 @@ void ExcludedFiles::prepare() emptyMatchNothing(bnameTriggerFileDir); emptyMatchNothing(bnameTriggerDir); - // The bname activation regex is applied to the bname only, so must be + // The bname regex is applied to the bname only, so it must be // anchored in the beginning and in the end. It has the structure: - // (exclude-and-keep)|(exclude-and-remove)|(bname triggers). + // (exclude)|(excluderemove)|(bname triggers). // If the third group matches, the fullActivatedRegex needs to be applied // to the full path. _bnameTraversalRegexFile.setPattern( - "^(" + bnameFileDirKeep + ")$|" - + "^(" + bnameFileDirRemove + ")$|" - + "^(" + bnameTriggerFileDir + ")$"); + "^(?P" + bnameFileDirKeep + ")$|" + + "^(?P" + bnameFileDirRemove + ")$|" + + "^(?P" + bnameTriggerFileDir + ")$"); _bnameTraversalRegexDir.setPattern( - "^(" + bnameFileDirKeep + "|" + bnameDirKeep + ")$|" - + "^(" + bnameFileDirRemove + "|" + bnameDirRemove + ")$|" - + "^(" + bnameTriggerFileDir + "|" + bnameTriggerDir + ")$"); + "^(?P" + bnameFileDirKeep + "|" + bnameDirKeep + ")$|" + + "^(?P" + bnameFileDirRemove + "|" + bnameDirRemove + ")$|" + + "^(?P" + bnameTriggerFileDir + "|" + bnameTriggerDir + ")$"); - // The full traveral regex is applied to the full path if the bname activation - // capture matches. Its basic form is (exclude-and-keep)|(exclude-and-remove)". + // The full traveral regex is applied to the full path if the trigger capture of + // the bname regex matches. Its basic form is (exclude)|(excluderemove)". // This pattern can be much simpler than fullRegex since we can assume a traversal // situation and doesn't need to look for bname patterns in parent paths. _fullTraversalRegexFile.setPattern( QLatin1String("") // Full patterns are anchored to the beginning - + "^(" + fullFileDirKeep + ")(?:$|/)" + + "^(?P" + fullFileDirKeep + ")(?:$|/)" + "|" - + "^(" + fullFileDirRemove + ")(?:$|/)"); + + "^(?P" + fullFileDirRemove + ")(?:$|/)"); _fullTraversalRegexDir.setPattern( QLatin1String("") - + "^(" + fullFileDirKeep + "|" + fullDirKeep + ")(?:$|/)" + + "^(?P" + fullFileDirKeep + "|" + fullDirKeep + ")(?:$|/)" + "|" - + "^(" + fullFileDirRemove + "|" + fullDirRemove + ")(?:$|/)"); + + "^(?P" + fullFileDirRemove + "|" + fullDirRemove + ")(?:$|/)"); - // The full regex has two captures, its basic form is "(...)|(...)". The first - // capture has the keep/exclude-only patterns, the second the remove/exclude-and-remove - // patterns. + // The full regex is applied to the full path and incorporates both bname and + // full-path patterns. It has the form "(exclude)|(excluderemove)". _fullRegexFile.setPattern( - QLatin1String("(") + QLatin1String("(?P") // Full patterns are anchored to the beginning + "^(?:" + fullFileDirKeep + ")(?:$|/)" + "|" // Simple bname patterns can be any path component @@ -691,16 +690,20 @@ void ExcludedFiles::prepare() // When checking a file for exclusion we must check all parent paths // against the dir-only patterns as well. + "(?:^|/)(?:" + bnameDirKeep + ")/" - + ")|(" + + ")" + + "|" + + "(?P" + "^(?:" + fullFileDirRemove + ")(?:$|/)" + "|" + "(?:^|/)(?:" + bnameFileDirRemove + ")(?:$|/)" + "|" + "(?:^|/)(?:" + bnameDirRemove + ")/" + ")"); _fullRegexDir.setPattern( - QLatin1String("(") + QLatin1String("(?P") + "^(?:" + fullFileDirKeep + "|" + fullDirKeep + ")(?:$|/)" + "|" + "(?:^|/)(?:" + bnameFileDirKeep + "|" + bnameDirKeep + ")(?:$|/)" - + ")|(" + + ")" + + "|" + + "(?P" + "^(?:" + fullFileDirRemove + "|" + fullDirRemove + ")(?:$|/)" + "|" + "(?:^|/)(?:" + bnameFileDirRemove + "|" + bnameDirRemove + ")(?:$|/)" + ")"); From 6f5b3eb4d7028c08718756a3dff89016c1511c28 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Fri, 19 Jan 2018 02:18:35 +0100 Subject: [PATCH 115/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 3142c5b6b..8e72dff8f 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -179,6 +179,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From b9c7aa8df36513c1fbb896bbcf6d1da67534f173 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Wed, 17 Jan 2018 10:59:47 +0100 Subject: [PATCH 116/138] Sync: Deal with file/folder conflicts #6312 Previously conflicts with a different type on both ends lead to sync errors. Now they are handled in the expected way: the local item gets renamed and the remote item gets propagated downwards. This also adds a unittest for the TYPE_CHANGE case. That one looks like parts of it might be unified with CONFLICT cases. --- src/libsync/owncloudpropagator.cpp | 100 +++++++++++++- src/libsync/owncloudpropagator.h | 25 +++- src/libsync/propagatedownload.cpp | 63 +-------- src/libsync/propagatorjobs.cpp | 27 ++-- src/libsync/syncengine.cpp | 3 +- test/testsyncconflict.cpp | 202 +++++++++++++++++++++++++++++ 6 files changed, 346 insertions(+), 74 deletions(-) diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp index d960b4a2d..e9e4df3ea 100644 --- a/src/libsync/owncloudpropagator.cpp +++ b/src/libsync/owncloudpropagator.cpp @@ -22,6 +22,7 @@ #include "propagateremotemove.h" #include "propagateremotemkdir.h" #include "propagatorjobs.h" +#include "filesystem.h" #include "common/utility.h" #include "account.h" #include "common/asserts.h" @@ -368,8 +369,10 @@ PropagateItemJob *OwncloudPropagator::createJob(const SyncFileItemPtr &item) return new PropagateRemoteDelete(this, item); case CSYNC_INSTRUCTION_NEW: case CSYNC_INSTRUCTION_TYPE_CHANGE: + case CSYNC_INSTRUCTION_CONFLICT: if (item->isDirectory()) { - if (item->_direction == SyncFileItem::Down) { + // CONFLICT has _direction == None + if (item->_direction != SyncFileItem::Up) { auto job = new PropagateLocalMkdir(this, item); job->setDeleteExistingFile(deleteExisting); return job; @@ -380,7 +383,6 @@ PropagateItemJob *OwncloudPropagator::createJob(const SyncFileItemPtr &item) } } //fall through case CSYNC_INSTRUCTION_SYNC: - case CSYNC_INSTRUCTION_CONFLICT: if (item->_direction != SyncFileItem::Up) { auto job = new PropagateDownloadFile(this, item); job->setDeleteExistingFolder(deleteExisting); @@ -431,6 +433,7 @@ void OwncloudPropagator::start(const SyncFileItemVector &items) directories.push(qMakePair(QString(), _rootJob.data())); QVector directoriesToRemove; QString removedDirectory; + QString maybeConflictDirectory; foreach (const SyncFileItemPtr &item, items) { if (!removedDirectory.isEmpty() && item->_file.startsWith(removedDirectory)) { // this is an item in a directory which is going to be removed. @@ -464,6 +467,20 @@ void OwncloudPropagator::start(const SyncFileItemVector &items) } } + // If a CONFLICT item contains files these can't be processed because + // the conflict handling is likely to rename the directory. This can happen + // when there's a new local directory at the same time as a remote file. + if (!maybeConflictDirectory.isEmpty()) { + if (item->destination().startsWith(maybeConflictDirectory)) { + qCInfo(lcPropagator) << "Skipping job inside CONFLICT directory" + << item->_file << item->_instruction; + item->_instruction = CSYNC_INSTRUCTION_NONE; + continue; + } else { + maybeConflictDirectory.clear(); + } + } + while (!item->destination().startsWith(directories.top().first)) { directories.pop(); } @@ -513,6 +530,12 @@ void OwncloudPropagator::start(const SyncFileItemVector &items) } else { directories.top().second->appendTask(item); } + + if (item->_instruction == CSYNC_INSTRUCTION_CONFLICT) { + // This might be a file or a directory on the local side. If it's a + // directory we want to skip processing items inside it. + maybeConflictDirectory = item->_file + "/"; + } } } @@ -702,6 +725,72 @@ OwncloudPropagator::DiskSpaceResult OwncloudPropagator::diskSpaceCheck() const return DiskSpaceOk; } +bool OwncloudPropagator::createConflict(const SyncFileItemPtr &item, + PropagatorCompositeJob *composite, QString *error) +{ + QString fn = getFilePath(item->_file); + + QString renameError; + auto conflictModTime = FileSystem::getModTime(fn); + QString conflictFileName = Utility::makeConflictFileName( + item->_file, Utility::qDateTimeFromTime_t(conflictModTime)); + QString conflictFilePath = getFilePath(conflictFileName); + + emit touchedFile(fn); + emit touchedFile(conflictFilePath); + + if (!FileSystem::rename(fn, conflictFilePath, &renameError)) { + // If the rename fails, don't replace it. + + // If the file is locked, we want to retry this sync when it + // becomes available again. + if (FileSystem::isFileLocked(fn)) { + emit seenLockedFile(fn); + } + + if (error) + *error = renameError; + return false; + } + qCInfo(lcPropagator) << "Created conflict file" << fn << "->" << conflictFileName; + + // Create a new conflict record. To get the base etag, we need to read it from the db. + ConflictRecord conflictRecord; + conflictRecord.path = conflictFileName.toUtf8(); + conflictRecord.baseModtime = item->_previousModtime; + + SyncJournalFileRecord baseRecord; + if (_journal->getFileRecord(item->_originalFile, &baseRecord) && baseRecord.isValid()) { + conflictRecord.baseEtag = baseRecord._etag; + conflictRecord.baseFileId = baseRecord._fileId; + } else { + // We might very well end up with no fileid/etag for new/new conflicts + } + + _journal->setConflictRecord(conflictRecord); + + // Create a new upload job if the new conflict file should be uploaded + if (account()->capabilities().uploadConflictFiles()) { + if (composite && !QFileInfo(conflictFilePath).isDir()) { + SyncFileItemPtr conflictItem = SyncFileItemPtr(new SyncFileItem); + conflictItem->_file = conflictFileName; + conflictItem->_type = ItemTypeFile; + conflictItem->_direction = SyncFileItem::Up; + conflictItem->_instruction = CSYNC_INSTRUCTION_NEW; + conflictItem->_modtime = conflictModTime; + conflictItem->_size = item->_previousSize; + emit newItem(conflictItem); + composite->appendTask(conflictItem); + } else { + // Directories we can't process in one go. The next sync run + // will take care of uploading the conflict dir contents. + _anotherSyncNeeded = true; + } + } + + return true; +} + // ================================================================================ PropagatorJob::PropagatorJob(OwncloudPropagator *propagator) @@ -741,7 +830,7 @@ void PropagatorCompositeJob::slotSubJobAbortFinished() void PropagatorCompositeJob::appendJob(PropagatorJob *job) { - job->setCompositeParent(this); + job->setAssociatedComposite(this); _jobsToDo.append(job); } @@ -858,6 +947,7 @@ PropagateDirectory::PropagateDirectory(OwncloudPropagator *propagator, const Syn { if (_firstJob) { connect(_firstJob.data(), &PropagatorJob::finished, this, &PropagateDirectory::slotFirstJobFinished); + _firstJob->setAssociatedComposite(&_subJobs); } connect(&_subJobs, &PropagatorJob::finished, this, &PropagateDirectory::slotSubJobsFinished); } @@ -901,7 +991,9 @@ void PropagateDirectory::slotFirstJobFinished(SyncFileItem::Status status) { _firstJob.take()->deleteLater(); - if (status != SyncFileItem::Success && status != SyncFileItem::Restoration) { + if (status != SyncFileItem::Success + && status != SyncFileItem::Restoration + && status != SyncFileItem::Conflict) { if (_state != Finished) { // Synchronously abort abort(AbortType::Synchronous); diff --git a/src/libsync/owncloudpropagator.h b/src/libsync/owncloudpropagator.h index 7cd00531d..88bb2f1f7 100644 --- a/src/libsync/owncloudpropagator.h +++ b/src/libsync/owncloudpropagator.h @@ -103,11 +103,13 @@ public: */ virtual qint64 committedDiskSpace() const { return 0; } - /** Set the composite parent job + /** Set the associated composite job * - * Used only from PropagatorCompositeJob itself, when a job is added. + * Used only from PropagatorCompositeJob itself, when a job is added + * and from PropagateDirectory to associate the subJobs with the first + * job. */ - void setCompositeParent(PropagatorCompositeJob *job) { _compositeParent = job; } + void setAssociatedComposite(PropagatorCompositeJob *job) { _associatedComposite = job; } public slots: /* @@ -137,11 +139,14 @@ protected: OwncloudPropagator *propagator() const; /** If this job gets added to a composite job, this will point to the parent. + * + * For the PropagateDirectory::_firstJob it will point to + * PropagateDirectory::_subJobs. * * That can be useful for jobs that want to spawn follow-up jobs without * becoming composite jobs themselves. */ - PropagatorCompositeJob *_compositeParent = nullptr; + PropagatorCompositeJob *_associatedComposite = nullptr; }; /* @@ -492,6 +497,18 @@ public: */ DiskSpaceResult diskSpaceCheck() const; + /** Handles a conflict by renaming the file 'item'. + * + * Sets up conflict records. + * + * It also creates a new upload job in composite if the item that's + * moved away is a file and conflict uploads are requested. + * + * Returns true on success, false and error on error. + */ + bool createConflict(const SyncFileItemPtr &item, + PropagatorCompositeJob *composite, QString *error); + private slots: void abortTimeout() diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index 2b7bd7640..0601e9fba 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -697,14 +697,9 @@ void PropagateDownloadFile::deleteExistingFolder() // on error, just try to move it away... } - QString conflictDir = Utility::makeConflictFileName( - existingDir, Utility::qDateTimeFromTime_t(FileSystem::getModTime(existingDir))); - - emit propagator()->touchedFile(existingDir); - emit propagator()->touchedFile(conflictDir); - QString renameError; - if (!FileSystem::rename(existingDir, conflictDir, &renameError)) { - done(SyncFileItem::NormalError, renameError); + QString error; + if (!propagator()->createConflict(_item, _associatedComposite, &error)) { + done(SyncFileItem::NormalError, error); } } @@ -819,58 +814,14 @@ void PropagateDownloadFile::downloadFinished() return; } - // In case of conflict, make a backup of the old file - // Ignore conflicts where both files are binary equal bool isConflict = _item->_instruction == CSYNC_INSTRUCTION_CONFLICT - && !FileSystem::fileEquals(fn, _tmpFile.fileName()); + && (QFileInfo(fn).isDir() || !FileSystem::fileEquals(fn, _tmpFile.fileName())); if (isConflict) { - QString renameError; - auto conflictModTime = FileSystem::getModTime(fn); - QString conflictFileName = Utility::makeConflictFileName( - _item->_file, Utility::qDateTimeFromTime_t(conflictModTime)); - QString conflictFilePath = propagator()->getFilePath(conflictFileName); - if (!FileSystem::rename(fn, conflictFilePath, &renameError)) { - // If the rename fails, don't replace it. - - // If the file is locked, we want to retry this sync when it - // becomes available again. - if (FileSystem::isFileLocked(fn)) { - emit propagator()->seenLockedFile(fn); - } - - done(SyncFileItem::SoftError, renameError); + QString error; + if (!propagator()->createConflict(_item, _associatedComposite, &error)) { + done(SyncFileItem::SoftError, error); return; } - qCInfo(lcPropagateDownload) << "Created conflict file" << fn << "->" << conflictFileName; - - // Create a new conflict record. To get the base etag, we need to read it from the db. - ConflictRecord conflictRecord; - conflictRecord.path = conflictFileName.toUtf8(); - conflictRecord.baseModtime = _item->_previousModtime; - - SyncJournalFileRecord baseRecord; - if (propagator()->_journal->getFileRecord(_item->_originalFile, &baseRecord) && baseRecord.isValid()) { - conflictRecord.baseEtag = baseRecord._etag; - conflictRecord.baseFileId = baseRecord._fileId; - } else { - // We might very well end up with no fileid/etag for new/new conflicts - } - - propagator()->_journal->setConflictRecord(conflictRecord); - - // Create a new upload job if the new conflict file should be uploaded - if (propagator()->account()->capabilities().uploadConflictFiles()) { - SyncFileItemPtr conflictItem = SyncFileItemPtr(new SyncFileItem); - conflictItem->_file = conflictFileName; - conflictItem->_type = ItemTypeFile; - conflictItem->_direction = SyncFileItem::Up; - conflictItem->_instruction = CSYNC_INSTRUCTION_NEW; - conflictItem->_modtime = conflictModTime; - conflictItem->_size = _item->_previousSize; - ASSERT(_compositeParent); - emit propagator()->newItem(conflictItem); - _compositeParent->appendTask(conflictItem); - } } FileSystem::setModTime(_tmpFile.fileName(), _item->_modtime); diff --git a/src/libsync/propagatorjobs.cpp b/src/libsync/propagatorjobs.cpp index 49ecfe156..66b934c06 100644 --- a/src/libsync/propagatorjobs.cpp +++ b/src/libsync/propagatorjobs.cpp @@ -151,13 +151,21 @@ void PropagateLocalMkdir::start() // When turning something that used to be a file into a directory // we need to delete the file first. QFileInfo fi(newDirStr); - if (_deleteExistingFile && fi.exists() && fi.isFile()) { - QString removeError; - if (!FileSystem::remove(newDirStr, &removeError)) { - done(SyncFileItem::NormalError, - tr("could not delete file %1, error: %2") - .arg(newDirStr, removeError)); - return; + if (fi.exists() && fi.isFile()) { + if (_deleteExistingFile) { + QString removeError; + if (!FileSystem::remove(newDirStr, &removeError)) { + done(SyncFileItem::NormalError, + tr("could not delete file %1, error: %2") + .arg(newDirStr, removeError)); + return; + } + } else if (_item->_instruction == CSYNC_INSTRUCTION_CONFLICT) { + QString error; + if (!propagator()->createConflict(_item, _associatedComposite, &error)) { + done(SyncFileItem::SoftError, error); + return; + } } } @@ -186,7 +194,10 @@ void PropagateLocalMkdir::start() } propagator()->_journal->commit("localMkdir"); - done(SyncFileItem::Success); + auto resultStatus = _item->_instruction == CSYNC_INSTRUCTION_CONFLICT + ? SyncFileItem::Conflict + : SyncFileItem::Success; + done(resultStatus); } void PropagateLocalMkdir::setDeleteExistingFile(bool enabled) diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index b3bbc5383..cd0cf6ccd 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -432,6 +432,7 @@ int SyncEngine::treewalkFile(csync_file_stat_t *file, csync_file_stat_t *other, item->_modtime = file->modtime; item->_size = file->size; item->_checksumHeader = file->checksumHeader; + item->_type = file->type; } else { if (instruction != CSYNC_INSTRUCTION_NONE) { qCWarning(lcEngine) << "ERROR: Instruction" << item->_instruction << "vs" << instruction << "for" << fileUtf8; @@ -576,8 +577,6 @@ int SyncEngine::treewalkFile(csync_file_stat_t *file, csync_file_stat_t *other, item->_inode = file->inode; } - item->_type = file->type; - SyncFileItem::Direction dir = SyncFileItem::None; int re = 0; diff --git a/test/testsyncconflict.cpp b/test/testsyncconflict.cpp index 0a15bb9e9..daf7eab0d 100644 --- a/test/testsyncconflict.cpp +++ b/test/testsyncconflict.cpp @@ -345,6 +345,208 @@ private slots: QFETCH(QString, output); QCOMPARE(Utility::conflictFileBaseName(input.toUtf8()), output.toUtf8()); } + + void testLocalDirRemoteFileConflict() + { + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + fakeFolder.syncEngine().account()->setCapabilities({ { "uploadConflictFiles", true } }); + QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItemPtr &))); + + auto cleanup = [&]() { + completeSpy.clear(); + }; + cleanup(); + + // 1) a NEW/NEW conflict + fakeFolder.localModifier().mkdir("Z"); + fakeFolder.localModifier().mkdir("Z/subdir"); + fakeFolder.localModifier().insert("Z/foo"); + fakeFolder.remoteModifier().insert("Z", 63); + + // 2) local file becomes a dir; remote file changes + fakeFolder.localModifier().remove("A/a1"); + fakeFolder.localModifier().mkdir("A/a1"); + fakeFolder.localModifier().insert("A/a1/bar"); + fakeFolder.remoteModifier().appendByte("A/a1"); + + // 3) local dir gets a new file; remote dir becomes a file + fakeFolder.localModifier().insert("B/zzz"); + fakeFolder.remoteModifier().remove("B"); + fakeFolder.remoteModifier().insert("B", 31); + + QVERIFY(fakeFolder.syncOnce()); + + auto conflicts = findConflicts(fakeFolder.currentLocalState()); + conflicts += findConflicts(fakeFolder.currentLocalState().children["A"]); + QCOMPARE(conflicts.size(), 3); + std::sort(conflicts.begin(), conflicts.end()); + + auto conflictRecords = fakeFolder.syncJournal().conflictRecordPaths(); + QCOMPARE(conflictRecords.size(), 3); + std::sort(conflictRecords.begin(), conflictRecords.end()); + + // 1) + QVERIFY(itemConflict(completeSpy, "Z")); + QCOMPARE(fakeFolder.currentLocalState().find("Z")->size, 63); + QVERIFY(conflicts[2].contains("Z")); + QCOMPARE(conflicts[2].toUtf8(), conflictRecords[2]); + QVERIFY(QFileInfo(fakeFolder.localPath() + conflicts[2]).isDir()); + QVERIFY(QFile::exists(fakeFolder.localPath() + conflicts[2] + "/foo")); + + // 2) + QVERIFY(itemConflict(completeSpy, "A/a1")); + QCOMPARE(fakeFolder.currentLocalState().find("A/a1")->size, 5); + QVERIFY(conflicts[0].contains("A/a1")); + QCOMPARE(conflicts[0].toUtf8(), conflictRecords[0]); + QVERIFY(QFileInfo(fakeFolder.localPath() + conflicts[0]).isDir()); + QVERIFY(QFile::exists(fakeFolder.localPath() + conflicts[0] + "/bar")); + + // 3) + QVERIFY(itemConflict(completeSpy, "B")); + QCOMPARE(fakeFolder.currentLocalState().find("B")->size, 31); + QVERIFY(conflicts[1].contains("B")); + QCOMPARE(conflicts[1].toUtf8(), conflictRecords[1]); + QVERIFY(QFileInfo(fakeFolder.localPath() + conflicts[1]).isDir()); + QVERIFY(QFile::exists(fakeFolder.localPath() + conflicts[1] + "/zzz")); + + // The contents of the conflict directories will only be uploaded after + // another sync. + QVERIFY(fakeFolder.syncEngine().isAnotherSyncNeeded() == ImmediateFollowUp); + cleanup(); + QVERIFY(fakeFolder.syncOnce()); + + QVERIFY(itemSuccessful(completeSpy, conflicts[0], CSYNC_INSTRUCTION_NEW)); + QVERIFY(itemSuccessful(completeSpy, conflicts[0] + "/bar", CSYNC_INSTRUCTION_NEW)); + QVERIFY(itemSuccessful(completeSpy, conflicts[1], CSYNC_INSTRUCTION_NEW)); + QVERIFY(itemSuccessful(completeSpy, conflicts[1] + "/zzz", CSYNC_INSTRUCTION_NEW)); + QVERIFY(itemSuccessful(completeSpy, conflicts[2], CSYNC_INSTRUCTION_NEW)); + QVERIFY(itemSuccessful(completeSpy, conflicts[2] + "/foo", CSYNC_INSTRUCTION_NEW)); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + } + + void testLocalFileRemoteDirConflict() + { + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + fakeFolder.syncEngine().account()->setCapabilities({ { "uploadConflictFiles", true } }); + QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItemPtr &))); + + // 1) a NEW/NEW conflict + fakeFolder.remoteModifier().mkdir("Z"); + fakeFolder.remoteModifier().mkdir("Z/subdir"); + fakeFolder.remoteModifier().insert("Z/foo"); + fakeFolder.localModifier().insert("Z"); + + // 2) local dir becomes file: remote dir adds file + fakeFolder.localModifier().remove("A"); + fakeFolder.localModifier().insert("A", 63); + fakeFolder.remoteModifier().insert("A/bar"); + + // 3) local file changes; remote file becomes dir + fakeFolder.localModifier().appendByte("B/b1"); + fakeFolder.remoteModifier().remove("B/b1"); + fakeFolder.remoteModifier().mkdir("B/b1"); + fakeFolder.remoteModifier().insert("B/b1/zzz"); + + QVERIFY(fakeFolder.syncOnce()); + auto conflicts = findConflicts(fakeFolder.currentLocalState()); + conflicts += findConflicts(fakeFolder.currentLocalState().children["B"]); + QCOMPARE(conflicts.size(), 3); + std::sort(conflicts.begin(), conflicts.end()); + + auto conflictRecords = fakeFolder.syncJournal().conflictRecordPaths(); + QCOMPARE(conflictRecords.size(), 3); + std::sort(conflictRecords.begin(), conflictRecords.end()); + + // 1) + QVERIFY(itemConflict(completeSpy, "Z")); + QVERIFY(conflicts[2].contains("Z")); + QCOMPARE(conflicts[2].toUtf8(), conflictRecords[2]); + + // 2) + QVERIFY(itemConflict(completeSpy, "A")); + QVERIFY(conflicts[0].contains("A")); + QCOMPARE(conflicts[0].toUtf8(), conflictRecords[0]); + + // 3) + QVERIFY(itemConflict(completeSpy, "B/b1")); + QVERIFY(conflicts[1].contains("B/b1")); + QCOMPARE(conflicts[1].toUtf8(), conflictRecords[1]); + + // Also verifies that conflicts were uploaded + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + } + + void testTypeConflictWithMove() + { + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItemPtr &))); + + // the remote becomes a file, but a file inside the dir has moved away! + fakeFolder.remoteModifier().remove("A"); + fakeFolder.remoteModifier().insert("A"); + fakeFolder.localModifier().rename("A/a1", "a1"); + + // same, but with a new file inside the dir locally + fakeFolder.remoteModifier().remove("B"); + fakeFolder.remoteModifier().insert("B"); + fakeFolder.localModifier().rename("B/b1", "b1"); + fakeFolder.localModifier().insert("B/new"); + + QVERIFY(fakeFolder.syncOnce()); + + QVERIFY(itemSuccessful(completeSpy, "A", CSYNC_INSTRUCTION_TYPE_CHANGE)); + QVERIFY(itemConflict(completeSpy, "B")); + + auto conflicts = findConflicts(fakeFolder.currentLocalState()); + std::sort(conflicts.begin(), conflicts.end()); + QVERIFY(conflicts.size() == 2); + QVERIFY(conflicts[0].contains("A_conflict")); + QVERIFY(conflicts[1].contains("B_conflict")); + for (auto conflict : conflicts) + QDir(fakeFolder.localPath() + conflict).removeRecursively(); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + // Currently a1 and b1 don't get moved, but redownloaded + } + + void testTypeChange() + { + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItemPtr &))); + + // dir becomes file + fakeFolder.remoteModifier().remove("A"); + fakeFolder.remoteModifier().insert("A"); + fakeFolder.localModifier().remove("B"); + fakeFolder.localModifier().insert("B"); + + // file becomes dir + fakeFolder.remoteModifier().remove("C/c1"); + fakeFolder.remoteModifier().mkdir("C/c1"); + fakeFolder.remoteModifier().insert("C/c1/foo"); + fakeFolder.localModifier().remove("C/c2"); + fakeFolder.localModifier().mkdir("C/c2"); + fakeFolder.localModifier().insert("C/c2/bar"); + + QVERIFY(fakeFolder.syncOnce()); + + QVERIFY(itemSuccessful(completeSpy, "A", CSYNC_INSTRUCTION_TYPE_CHANGE)); + QVERIFY(itemSuccessful(completeSpy, "B", CSYNC_INSTRUCTION_TYPE_CHANGE)); + QVERIFY(itemSuccessful(completeSpy, "C/c1", CSYNC_INSTRUCTION_TYPE_CHANGE)); + QVERIFY(itemSuccessful(completeSpy, "C/c2", CSYNC_INSTRUCTION_TYPE_CHANGE)); + + // A becomes a conflict because we don't delete folders with files + // inside of them! + auto conflicts = findConflicts(fakeFolder.currentLocalState()); + QVERIFY(conflicts.size() == 1); + QVERIFY(conflicts[0].contains("A_conflict")); + for (auto conflict : conflicts) + QDir(fakeFolder.localPath() + conflict).removeRecursively(); + + QVERIFY(fakeFolder.syncEngine().isAnotherSyncNeeded() == ImmediateFollowUp); + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + } }; QTEST_GUILESS_MAIN(TestSyncConflict) From b8539eb32918109388bf70389ffea51c4d8f8822 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 19 Jan 2018 11:11:53 +0100 Subject: [PATCH 117/138] Get rid of the StopWatch in the PropagateUpload job For issue #6318 The StopWatch is using memory, and we are not really using it. --- src/libsync/propagateupload.cpp | 13 ------------- src/libsync/propagateupload.h | 6 ------ src/libsync/propagateuploadng.cpp | 11 ----------- src/libsync/propagateuploadv1.cpp | 11 ----------- 4 files changed, 41 deletions(-) diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp index 1b5bcc0c8..4579139ce 100644 --- a/src/libsync/propagateupload.cpp +++ b/src/libsync/propagateupload.cpp @@ -214,10 +214,6 @@ void PropagateUploadFileCommon::slotComputeContentChecksum() // change during the checksum calculation _item->_modtime = FileSystem::getModTime(filePath); -#ifdef WITH_TESTING - _stopWatch.start(); -#endif - QByteArray checksumType = contentChecksumType(); // Maybe the discovery already computed the checksum? @@ -243,11 +239,6 @@ void PropagateUploadFileCommon::slotComputeTransmissionChecksum(const QByteArray { _item->_checksumHeader = makeChecksumHeader(contentChecksumType, contentChecksum); -#ifdef WITH_TESTING - _stopWatch.addLapTime(QLatin1String("ContentChecksum")); - _stopWatch.start(); -#endif - // Reuse the content checksum as the transmission checksum if possible const auto supportedTransmissionChecksums = propagator()->account()->capabilities().supportedChecksumTypes(); @@ -291,10 +282,6 @@ void PropagateUploadFileCommon::slotStartUpload(const QByteArray &transmissionCh done(SyncFileItem::SoftError, tr("File Removed")); return; } -#ifdef WITH_TESTING - _stopWatch.addLapTime(QLatin1String("TransmissionChecksum")); -#endif - time_t prevModtime = _item->_modtime; // the _item value was set in PropagateUploadFile::start() // but a potential checksum calculation could have taken some time during which the file could // have been changed again, so better check again here. diff --git a/src/libsync/propagateupload.h b/src/libsync/propagateupload.h index c156190b5..a3ebe25bb 100644 --- a/src/libsync/propagateupload.h +++ b/src/libsync/propagateupload.h @@ -211,12 +211,6 @@ protected: bool _finished BITFIELD(1); /// Tells that all the jobs have been finished bool _deleteExisting BITFIELD(1); quint64 _abortCount; /// Keep track of number of aborted items - -// measure the performance of checksum calc and upload -#ifdef WITH_TESTING - Utility::StopWatch _stopWatch; -#endif - QByteArray _transmissionChecksumHeader; public: diff --git a/src/libsync/propagateuploadng.cpp b/src/libsync/propagateuploadng.cpp index 0b2c14295..2586664ca 100644 --- a/src/libsync/propagateuploadng.cpp +++ b/src/libsync/propagateuploadng.cpp @@ -467,17 +467,6 @@ void PropagateUploadFileNG::slotMoveJobFinished() return; } _item->_responseTimeStamp = job->responseTimestamp(); - -#ifdef WITH_TESTING - // performance logging - quint64 duration = _stopWatch.stop(); - qCDebug(lcPropagateUpload) << "*==* duration UPLOAD" << _item->_size - << _stopWatch.durationOfLap(QLatin1String("ContentChecksum")) - << _stopWatch.durationOfLap(QLatin1String("TransmissionChecksum")) - << duration; - // The job might stay alive for the whole sync, release this tiny bit of memory. - _stopWatch.reset(); -#endif finalize(); } diff --git a/src/libsync/propagateuploadv1.cpp b/src/libsync/propagateuploadv1.cpp index 91aa16098..ca0a61ccb 100644 --- a/src/libsync/propagateuploadv1.cpp +++ b/src/libsync/propagateuploadv1.cpp @@ -318,17 +318,6 @@ void PropagateUploadFileV1::slotPutFinished() done(SyncFileItem::SoftError, "Server does not support X-OC-MTime"); } -#ifdef WITH_TESTING - // performance logging - quint64 duration = _stopWatch.stop(); - qCDebug(lcPropagateUpload) << "*==* duration UPLOAD" << _item->_size - << _stopWatch.durationOfLap(QLatin1String("ContentChecksum")) - << _stopWatch.durationOfLap(QLatin1String("TransmissionChecksum")) - << duration; - // The job might stay alive for the whole sync, release this tiny bit of memory. - _stopWatch.reset(); -#endif - finalize(); } From 484ec9559615c6168a405424671c390e9e952311 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Sat, 20 Jan 2018 02:18:50 +0100 Subject: [PATCH 118/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 8e72dff8f..f80b70f27 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -182,6 +182,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From a19eb594610362e2ee740099ec32d0ad8163514c Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Sun, 21 Jan 2018 02:18:35 +0100 Subject: [PATCH 119/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index f80b70f27..4bdc24d33 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -185,6 +185,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From ba4712c922c00681d19a48b42f3a0f248e053a07 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Mon, 22 Jan 2018 02:18:54 +0100 Subject: [PATCH 120/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 4bdc24d33..684633298 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -188,6 +188,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From e2b89c5afe57e5881c749e63469cfa8a4ac8ad91 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Mon, 22 Jan 2018 14:05:08 +0100 Subject: [PATCH 121/138] TextXmlParse: Add truncated-xml testcase #6317 --- test/testxmlparse.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/testxmlparse.cpp b/test/testxmlparse.cpp index 9ec675f47..6c0945554 100644 --- a/test/testxmlparse.cpp +++ b/test/testxmlparse.cpp @@ -238,6 +238,40 @@ private slots: QVERIFY(_subdirs.size() == 0); } + void testParserTruncatedXml() { + 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" + ""; // no proper end here + + + 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(!parser.parse( testXml, &sizes, "/oc/remote.php/webdav/sharefolder" )); + QVERIFY(!_success); + } + void testParserBogfusHref1() { const QByteArray testXml = "" "" From c3dbb20ce398b25ebdb517b11f69b9b62ae857a5 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Sun, 21 Jan 2018 10:43:27 +0100 Subject: [PATCH 122/138] Logger: --logdebug only show owncloud's debug message Recent Qt version show way too many debug messages, spamming the console. So filter only messages that comes from the client. --- src/libsync/logger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsync/logger.cpp b/src/libsync/logger.cpp index 31afbbe8c..366fbfc32 100644 --- a/src/libsync/logger.cpp +++ b/src/libsync/logger.cpp @@ -219,7 +219,7 @@ void Logger::setLogFlush(bool flush) void Logger::setLogDebug(bool debug) { - QLoggingCategory::setFilterRules(debug ? QStringLiteral("qt.*=true\n*.debug=true") : QString()); + QLoggingCategory::setFilterRules(debug ? QStringLiteral("sync.*.debug=true\ngui.*.debug=true") : QString()); _logDebug = debug; } From c1a1e552078cba1db7bc2b002c3d576989c8d661 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Tue, 23 Jan 2018 02:18:36 +0100 Subject: [PATCH 123/138] [tx-robot] updated from transifex --- mirall.desktop.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mirall.desktop.in b/mirall.desktop.in index 684633298..b7cf6bf30 100644 --- a/mirall.desktop.in +++ b/mirall.desktop.in @@ -191,6 +191,9 @@ X-GNOME-Autostart-Delay=3 # Translations +# Translations + + # Translations Comment[oc]=@APPLICATION_NAME@ sincronizacion del client GenericName[oc]=Dorsièr de Sincronizacion From d831369f86ffd1782113869eba3970e4cdfb4f8c Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Mon, 22 Jan 2018 10:51:53 +0100 Subject: [PATCH 124/138] Protocol: Remove entries for auto resolved conflicts #6316 --- src/gui/issueswidget.cpp | 2 +- src/gui/protocolwidget.cpp | 2 +- src/libsync/syncfileitem.h | 23 ++++++++++++++++++----- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/gui/issueswidget.cpp b/src/gui/issueswidget.cpp index 0ebb5da33..82db7c9fc 100644 --- a/src/gui/issueswidget.cpp +++ b/src/gui/issueswidget.cpp @@ -216,7 +216,7 @@ void IssuesWidget::slotProgressInfo(const QString &folder, const ProgressInfo &p void IssuesWidget::slotItemCompleted(const QString &folder, const SyncFileItemPtr &item) { - if (!item->hasErrorStatus()) + if (!item->showInIssuesTab()) return; QTreeWidgetItem *line = ProtocolWidget::createCompletedTreewidgetItem(folder, *item); if (!line) diff --git a/src/gui/protocolwidget.cpp b/src/gui/protocolwidget.cpp index e27152563..14b2fa245 100644 --- a/src/gui/protocolwidget.cpp +++ b/src/gui/protocolwidget.cpp @@ -195,7 +195,7 @@ QTreeWidgetItem *ProtocolWidget::createCompletedTreewidgetItem(const QString &fo void ProtocolWidget::slotItemCompleted(const QString &folder, const SyncFileItemPtr &item) { - if (item->hasErrorStatus()) + if (!item->showInProtocolTab()) return; QTreeWidgetItem *line = createCompletedTreewidgetItem(folder, *item); if (line) { diff --git a/src/libsync/syncfileitem.h b/src/libsync/syncfileitem.h index dd364ae43..c72363938 100644 --- a/src/libsync/syncfileitem.h +++ b/src/libsync/syncfileitem.h @@ -178,20 +178,33 @@ public: /** * True if the item had any kind of error. - * - * Used for deciding whether an item belongs to the protocol or the - * issues list on the activity page and for checking whether an - * item should be announced in the notification message. */ bool hasErrorStatus() const { return _status == SyncFileItem::SoftError || _status == SyncFileItem::NormalError || _status == SyncFileItem::FatalError - || _status == SyncFileItem::Conflict || !_errorString.isEmpty(); } + /** + * Whether this item should appear on the issues tab. + */ + bool showInIssuesTab() const + { + return hasErrorStatus() || _status == SyncFileItem::Conflict; + } + + /** + * Whether this item should appear on the protocol tab. + */ + bool showInProtocolTab() const + { + return !showInIssuesTab() + // Don't show conflicts that were resolved as "not a conflict after all" + && !(_instruction == CSYNC_INSTRUCTION_CONFLICT && _status == SyncFileItem::Success); + } + // Variables useful for everybody QString _file; QString _renameTarget; From 497b327d438b04da4c998e0663a98f4a7f5d2054 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Mon, 22 Jan 2018 10:52:25 +0100 Subject: [PATCH 125/138] ShareLinkWidget: Remove outdated signal connection Also convert the others to the new syntax to avoid similar errors in the future. --- src/gui/sharelinkwidget.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/gui/sharelinkwidget.cpp b/src/gui/sharelinkwidget.cpp index 938f6b7ee..c94f37601 100644 --- a/src/gui/sharelinkwidget.cpp +++ b/src/gui/sharelinkwidget.cpp @@ -223,11 +223,10 @@ void ShareLinkWidget::slotSharesFetched(const QList> &shar // Connect all shares signals to gui slots connect(share.data(), &Share::serverError, this, &ShareLinkWidget::slotServerError); connect(share.data(), &Share::shareDeleted, this, &ShareLinkWidget::slotDeleteShareFetched); - connect(share.data(), SIGNAL(expireDateSet()), SLOT(slotExpireSet())); - connect(share.data(), SIGNAL(publicUploadSet()), SLOT(slotPermissionsSet())); - connect(share.data(), SIGNAL(passwordSet()), SLOT(slotPasswordSet())); - connect(share.data(), SIGNAL(passwordSetError(int, QString)), SLOT(slotPasswordSetError(int, QString))); connect(share.data(), &Share::permissionsSet, this, &ShareLinkWidget::slotPermissionsSet); + connect(linkShare.data(), &LinkShare::expireDateSet, this, &ShareLinkWidget::slotExpireSet); + connect(linkShare.data(), &LinkShare::passwordSet, this, &ShareLinkWidget::slotPasswordSet); + connect(linkShare.data(), &LinkShare::passwordSetError, this, &ShareLinkWidget::slotPasswordSetError); // Build the table row auto row = table->rowCount(); From 32bb1e67637e48184d22379c420b767296bf3fea Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Tue, 23 Jan 2018 10:23:32 +0100 Subject: [PATCH 126/138] ProtocolItem: Use accessors over magic numbers --- src/gui/issueswidget.cpp | 13 +++----- src/gui/protocolwidget.cpp | 65 ++++++++++++++++++++++++++++++-------- src/gui/protocolwidget.h | 10 ++++++ 3 files changed, 66 insertions(+), 22 deletions(-) diff --git a/src/gui/issueswidget.cpp b/src/gui/issueswidget.cpp index 196846396..9a510568f 100644 --- a/src/gui/issueswidget.cpp +++ b/src/gui/issueswidget.cpp @@ -154,7 +154,7 @@ void IssuesWidget::cleanItems(const QString &folder) int itemCnt = _ui->_treeWidget->topLevelItemCount(); for (int cnt = itemCnt - 1; cnt >= 0; cnt--) { QTreeWidgetItem *item = _ui->_treeWidget->topLevelItem(cnt); - QString itemFolder = item->data(2, Qt::UserRole).toString(); + QString itemFolder = ProtocolItem::folderName(item); if (itemFolder == folder) { delete item; } @@ -197,11 +197,8 @@ void IssuesWidget::addItem(QTreeWidgetItem *item) void IssuesWidget::slotOpenFile(QTreeWidgetItem *item, int) { - QString folderName = item->data(2, Qt::UserRole).toString(); QString fileName = item->text(1); - - Folder *folder = FolderMan::instance()->folder(folderName); - if (folder) { + if (Folder *folder = ProtocolItem::folder(item)) { // folder->path() always comes back with trailing path QString fullPath = folder->path() + fileName; if (QFile(fullPath).exists()) { @@ -288,13 +285,13 @@ bool IssuesWidget::shouldBeVisible(QTreeWidgetItem *item, AccountState *filterAc const QString &filterFolderAlias) const { bool visible = true; - auto status = item->data(3, Qt::UserRole); + auto status = ProtocolItem::status(item); visible &= (_ui->showIgnores->isChecked() || status != SyncFileItem::FileIgnored); visible &= (_ui->showWarnings->isChecked() || (status != SyncFileItem::SoftError && status != SyncFileItem::Restoration)); - auto folderalias = item->data(2, Qt::UserRole).toString(); + auto folderalias = ProtocolItem::folderName(item); if (filterAccount) { auto folder = FolderMan::instance()->folder(folderalias); visible &= folder && folder->accountState() == filterAccount; @@ -443,7 +440,7 @@ void IssuesWidget::addErrorWidget(QTreeWidgetItem *item, const QString &message, auto button = new QPushButton("Retry all uploads", widget); button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); - auto folderAlias = item->data(2, Qt::UserRole).toString(); + auto folderAlias = ProtocolItem::folderName(item); connect(button, &QPushButton::clicked, this, [this, folderAlias]() { retryInsufficentRemoteStorageErrors(folderAlias); }); layout->addWidget(button); diff --git a/src/gui/protocolwidget.cpp b/src/gui/protocolwidget.cpp index 7324a1026..2dd9360cc 100644 --- a/src/gui/protocolwidget.cpp +++ b/src/gui/protocolwidget.cpp @@ -43,6 +43,46 @@ QString ProtocolItem::timeString(QDateTime dt, QLocale::FormatType format) return loc.toString(dt, dtFormat); } +QString ProtocolItem::folderName(const QTreeWidgetItem *item) +{ + return item->data(2, Qt::UserRole).toString(); +} + +void ProtocolItem::setFolderName(QTreeWidgetItem *item, const QString &folderName) +{ + item->setData(2, Qt::UserRole, folderName); +} + +QString ProtocolItem::filePath(const QTreeWidgetItem *item) +{ + return item->toolTip(1); +} + +void ProtocolItem::setFilePath(QTreeWidgetItem *item, const QString &filePath) +{ + item->setToolTip(1, filePath); +} + +QDateTime ProtocolItem::timestamp(const QTreeWidgetItem *item) +{ + return item->data(0, Qt::UserRole).toDateTime(); +} + +void ProtocolItem::setTimestamp(QTreeWidgetItem *item, const QDateTime ×tamp) +{ + item->setData(0, Qt::UserRole, timestamp); +} + +SyncFileItem::Status ProtocolItem::status(const QTreeWidgetItem *item) +{ + return static_cast(item->data(3, Qt::UserRole).toInt()); +} + +void ProtocolItem::setStatus(QTreeWidgetItem *item, SyncFileItem::Status status) +{ + item->setData(3, Qt::UserRole, status); +} + ProtocolItem *ProtocolItem::create(const QString &folder, const SyncFileItem &item) { auto f = FolderMan::instance()->folder(folder); @@ -84,13 +124,13 @@ ProtocolItem *ProtocolItem::create(const QString &folder, const SyncFileItem &it // Warning: The data and tooltips on the columns define an implicit // interface and can only be changed with care. twitem->setData(0, Qt::SizeHintRole, QSize(0, ActivityItemDelegate::rowHeight())); - twitem->setData(0, Qt::UserRole, timestamp); twitem->setIcon(0, icon); twitem->setToolTip(0, longTimeStr); - twitem->setToolTip(1, item._file); - twitem->setData(2, Qt::UserRole, folder); twitem->setToolTip(3, message); - twitem->setData(3, Qt::UserRole, item._status); + setTimestamp(twitem, timestamp); + setFilePath(twitem, item._file); // also sets toolTip(1) + setFolderName(twitem, folder); + setStatus(twitem, item._status); return twitem; } @@ -100,22 +140,22 @@ SyncJournalFileRecord ProtocolItem::syncJournalRecord(QTreeWidgetItem *item) auto f = folder(item); if (!f) return rec; - f->journalDb()->getFileRecord(item->toolTip(1), &rec); + f->journalDb()->getFileRecord(filePath(item), &rec); return rec; } Folder *ProtocolItem::folder(QTreeWidgetItem *item) { - return FolderMan::instance()->folder(item->data(2, Qt::UserRole).toString()); + return FolderMan::instance()->folder(folderName(item)); } void ProtocolItem::openContextMenu(QPoint globalPos, QTreeWidgetItem *item, QWidget *parent) { - auto f = ProtocolItem::folder(item); + auto f = folder(item); if (!f) return; AccountPtr account = f->accountState()->account(); - auto rec = ProtocolItem::syncJournalRecord(item); + auto rec = syncJournalRecord(item); // rec might not be valid auto menu = new QMenu(parent); @@ -151,8 +191,8 @@ bool ProtocolItem::operator<(const QTreeWidgetItem &other) const // Items with empty "File" column are larger than others, // otherwise sort by time (this uses lexicographic ordering) - return std::forward_as_tuple(text(1).isEmpty(), data(0, Qt::UserRole).toDateTime()) - < std::forward_as_tuple(other.text(1).isEmpty(), other.data(0, Qt::UserRole).toDateTime()); + return std::forward_as_tuple(text(1).isEmpty(), timestamp(this)) + < std::forward_as_tuple(other.text(1).isEmpty(), timestamp(&other)); } ProtocolWidget::ProtocolWidget(QWidget *parent) @@ -243,11 +283,8 @@ void ProtocolWidget::slotItemContextMenu(const QPoint &pos) void ProtocolWidget::slotOpenFile(QTreeWidgetItem *item, int) { - QString folderName = item->data(2, Qt::UserRole).toString(); QString fileName = item->text(1); - - Folder *folder = FolderMan::instance()->folder(folderName); - if (folder) { + if (Folder *folder = ProtocolItem::folder(item)) { // folder->path() always comes back with trailing path QString fullPath = folder->path() + fileName; if (QFile(fullPath).exists()) { diff --git a/src/gui/protocolwidget.h b/src/gui/protocolwidget.h index 147ba4d1f..d555965ff 100644 --- a/src/gui/protocolwidget.h +++ b/src/gui/protocolwidget.h @@ -49,6 +49,16 @@ public: static ProtocolItem *create(const QString &folder, const SyncFileItem &item); static QString timeString(QDateTime dt, QLocale::FormatType format = QLocale::NarrowFormat); + // accessors for extra data stored in the item + static QString folderName(const QTreeWidgetItem *item); + static void setFolderName(QTreeWidgetItem *item, const QString &folderName); + static QString filePath(const QTreeWidgetItem *item); + static void setFilePath(QTreeWidgetItem *item, const QString &filePath); + static QDateTime timestamp(const QTreeWidgetItem *item); + static void setTimestamp(QTreeWidgetItem *item, const QDateTime ×tamp); + static SyncFileItem::Status status(const QTreeWidgetItem *item); + static void setStatus(QTreeWidgetItem *item, SyncFileItem::Status status); + static SyncJournalFileRecord syncJournalRecord(QTreeWidgetItem *item); static Folder *folder(QTreeWidgetItem *item); From 59f2e0634e349fa911d05b28a3b8e5d066fdc8f9 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Tue, 23 Jan 2018 10:28:52 +0100 Subject: [PATCH 127/138] Protocol: Correct sorting by size #6326 Previously we were sorting by size string, where "6 MB" < "3 KB". --- src/gui/protocolwidget.cpp | 25 +++++++++++++++++++------ src/gui/protocolwidget.h | 2 ++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/gui/protocolwidget.cpp b/src/gui/protocolwidget.cpp index 2dd9360cc..76c155c3a 100644 --- a/src/gui/protocolwidget.cpp +++ b/src/gui/protocolwidget.cpp @@ -83,6 +83,16 @@ void ProtocolItem::setStatus(QTreeWidgetItem *item, SyncFileItem::Status status) item->setData(3, Qt::UserRole, status); } +quint64 ProtocolItem::size(const QTreeWidgetItem *item) +{ + return item->data(4, Qt::UserRole).toULongLong(); +} + +void ProtocolItem::setSize(QTreeWidgetItem *item, quint64 size) +{ + item->setData(4, Qt::UserRole, size); +} + ProtocolItem *ProtocolItem::create(const QString &folder, const SyncFileItem &item) { auto f = FolderMan::instance()->folder(folder); @@ -131,6 +141,7 @@ ProtocolItem *ProtocolItem::create(const QString &folder, const SyncFileItem &it setFilePath(twitem, item._file); // also sets toolTip(1) setFolderName(twitem, folder); setStatus(twitem, item._status); + setSize(twitem, item._size); return twitem; } @@ -185,14 +196,16 @@ void ProtocolItem::openContextMenu(QPoint globalPos, QTreeWidgetItem *item, QWid bool ProtocolItem::operator<(const QTreeWidgetItem &other) const { int column = treeWidget()->sortColumn(); - if (column != 0) { - return QTreeWidgetItem::operator<(other); + if (column == 0) { + // Items with empty "File" column are larger than others, + // otherwise sort by time (this uses lexicographic ordering) + return std::forward_as_tuple(text(1).isEmpty(), timestamp(this)) + < std::forward_as_tuple(other.text(1).isEmpty(), timestamp(&other)); + } else if (column == 4) { + return size(this) < size(&other); } - // Items with empty "File" column are larger than others, - // otherwise sort by time (this uses lexicographic ordering) - return std::forward_as_tuple(text(1).isEmpty(), timestamp(this)) - < std::forward_as_tuple(other.text(1).isEmpty(), timestamp(&other)); + return QTreeWidgetItem::operator<(other); } ProtocolWidget::ProtocolWidget(QWidget *parent) diff --git a/src/gui/protocolwidget.h b/src/gui/protocolwidget.h index d555965ff..d8612634d 100644 --- a/src/gui/protocolwidget.h +++ b/src/gui/protocolwidget.h @@ -58,6 +58,8 @@ public: static void setTimestamp(QTreeWidgetItem *item, const QDateTime ×tamp); static SyncFileItem::Status status(const QTreeWidgetItem *item); static void setStatus(QTreeWidgetItem *item, SyncFileItem::Status status); + static quint64 size(const QTreeWidgetItem *item); + static void setSize(QTreeWidgetItem *item, quint64 size); static SyncJournalFileRecord syncJournalRecord(QTreeWidgetItem *item); static Folder *folder(QTreeWidgetItem *item); From f254ee3211d18af79ed5c2fd1fa87c23658c7b6b Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 18 Jan 2018 14:13:40 +0100 Subject: [PATCH 128/138] Nautilus shell integration: Port to Python 3 --- shell_integration/nautilus/syncstate.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/shell_integration/nautilus/syncstate.py b/shell_integration/nautilus/syncstate.py index 082be4e22..6ea719100 100644 --- a/shell_integration/nautilus/syncstate.py +++ b/shell_integration/nautilus/syncstate.py @@ -17,6 +17,7 @@ import os import urllib +import urllib.parse import socket import tempfile @@ -34,7 +35,7 @@ print("Initializing "+appname+"-client-nautilus extension") def get_local_path(url): if url[0:7] == 'file://': url = url[7:] - return urllib.unquote(url) + return urllib.parse.unquote(url) def get_runtime_dir(): """Returns the value of $XDG_RUNTIME_DIR, a directory path. @@ -56,7 +57,7 @@ class SocketConnect(GObject.GObject): self._watch_id = 0 self._sock = None self._listeners = [self._update_registered_paths] - self._remainder = '' + self._remainder = ''.encode() self.nautilusVFSFile_table = {} # not needed in this object actually but shared # all over the other objects. @@ -74,7 +75,7 @@ class SocketConnect(GObject.GObject): # print("Server command: " + cmd) if self.connected: try: - self._sock.send(cmd) + self._sock.send(cmd.encode()) except: print("Sending failed.") self.reconnect() @@ -113,17 +114,17 @@ class SocketConnect(GObject.GObject): # Prepend the remaining data from last call if len(self._remainder) > 0: data = self._remainder + data - self._remainder = '' + self._remainder = ''.encode() if len(data) > 0: # Remember the remainder for next round - lastNL = data.rfind('\n'); + lastNL = data.rfind('\n'.encode()); if lastNL > -1 and lastNL < len(data): self._remainder = data[lastNL+1:] data = data[:lastNL] - for l in data.split('\n'): - self._handle_server_response(l) + for l in data.split('\n'.encode()): + self._handle_server_response(l.decode()) else: return False From 72363155d86b4b51b1bfbd75c7a4a19fed3f8ee9 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Tue, 23 Jan 2018 11:47:23 +0100 Subject: [PATCH 129/138] Nautilus integration: Work with python2 and python3 --- shell_integration/nautilus/syncstate.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/shell_integration/nautilus/syncstate.py b/shell_integration/nautilus/syncstate.py index 6ea719100..77a233d3d 100644 --- a/shell_integration/nautilus/syncstate.py +++ b/shell_integration/nautilus/syncstate.py @@ -15,9 +15,13 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. +import sys +python3 = sys.version_info[0] >= 3 + import os import urllib -import urllib.parse +if python3: + import urllib.parse import socket import tempfile @@ -31,11 +35,11 @@ appname = 'ownCloud' print("Initializing "+appname+"-client-nautilus extension") - def get_local_path(url): if url[0:7] == 'file://': url = url[7:] - return urllib.parse.unquote(url) + unquote = urllib.parse.unquote if python3 else urllib.unquote + return unquote(url) def get_runtime_dir(): """Returns the value of $XDG_RUNTIME_DIR, a directory path. From 1782ae3c0861635e105e79a413e395969227b00f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 18 Jan 2018 15:17:29 +0100 Subject: [PATCH 130/138] SocketAPI: Make it easier to add or remove item in the action menu By making it dynamic. So far only the dolphin shell extension have been ported --- .../dolphin/ownclouddolphinactionplugin.cpp | 82 +++++++++++++++---- .../dolphin/ownclouddolphinpluginhelper.cpp | 11 +++ .../dolphin/ownclouddolphinpluginhelper.h | 4 + src/gui/socketapi.cpp | 32 +++++++- src/gui/socketapi.h | 12 ++- 5 files changed, 120 insertions(+), 21 deletions(-) diff --git a/shell_integration/dolphin/ownclouddolphinactionplugin.cpp b/shell_integration/dolphin/ownclouddolphinactionplugin.cpp index 71c1f1171..a2010be90 100644 --- a/shell_integration/dolphin/ownclouddolphinactionplugin.cpp +++ b/shell_integration/dolphin/ownclouddolphinactionplugin.cpp @@ -17,8 +17,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ******************************************************************************/ -#include -#include +#include +#include #include #include #include @@ -27,6 +27,7 @@ #include #include #include +#include #include "ownclouddolphinpluginhelper.h" class OwncloudDolphinPluginAction : public KAbstractFileItemActionPlugin @@ -39,22 +40,70 @@ public: QList actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) Q_DECL_OVERRIDE { auto helper = OwncloudDolphinPluginHelper::instance(); - QList urls = fileItemInfos.urlList(); - if (urls.count() != 1 || !helper->isConnected()) + if (!helper->isConnected() || !fileItemInfos.isLocal()) return {}; - auto url = urls.first(); - if (!url.isLocalFile()) - return {}; - QDir localPath(url.toLocalFile()); - auto localFile = localPath.canonicalPath(); - + // If any of the url is outside of a sync folder, return an empty menu. + const QList urls = fileItemInfos.urlList(); const auto paths = helper->paths(); - if (!std::any_of(paths.begin(), paths.end(), [&](const QString &s) { - return localFile.startsWith(s); - } )) - return {}; + QByteArray files; + for (const auto &url : urls) { + QDir localPath(url.toLocalFile()); + auto localFile = localPath.canonicalPath(); + if (!std::any_of(paths.begin(), paths.end(), [&](const QString &s) { + return localFile.startsWith(s); + })) + return {}; + if (!files.isEmpty()) + files += '\x1e'; // Record separator + files += localFile.toUtf8(); + } + + if (helper->version() < "1.1") { // in this case, lexicographic order works + return legacyActions(fileItemInfos, parentWidget); + } + + auto menu = new QMenu(parentWidget); + QEventLoop loop; + auto con = connect(helper, &OwncloudDolphinPluginHelper::commandRecieved, this, [&](const QByteArray &cmd) { + if (cmd.startsWith("GET_MENU_ITEMS:END")) { + loop.quit(); + } else if (cmd.startsWith("MENU_ITEM:")) { + auto args = QString::fromUtf8(cmd).split(QLatin1Char(':')); + if (args.size() < 3) + return; + auto action = menu->addAction(args.mid(2).join(QLatin1Char(':'))); + auto call = args.value(1).toLatin1(); + connect(action, &QAction::triggered, [helper, call, files] { + helper->sendCommand(QByteArray(call + ":" + files + "\n")); + }); + } + }); + QTimer::singleShot(100, &loop, SLOT(quit())); // add a timeout to be sure we don't freeze dolphin + helper->sendCommand(QByteArray("GET_MENU_ITEMS:" + files + "\n")); + loop.exec(QEventLoop::ExcludeUserInputEvents); + disconnect(con); + if (menu->actions().isEmpty()) { + delete menu; + return {}; + } + + auto menuaction = new QAction(parentWidget); + menuaction->setText(helper->contextMenuTitle()); + menuaction->setMenu(menu); + return { menuaction }; + } + + + QList legacyActions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget) + { + QList urls = fileItemInfos.urlList(); + if (urls.count() != 1) + return {}; + QDir localPath(urls.first().toLocalFile()); + auto localFile = localPath.canonicalPath(); + auto helper = OwncloudDolphinPluginHelper::instance(); auto menuaction = new QAction(parentWidget); menuaction->setText(helper->contextMenuTitle()); auto menu = new QMenu(parentWidget); @@ -62,8 +111,8 @@ public: auto shareAction = menu->addAction(helper->shareActionTitle()); connect(shareAction, &QAction::triggered, this, [localFile, helper] { - helper->sendCommand(QByteArray("SHARE:"+localFile.toUtf8()+"\n")); - } ); + helper->sendCommand(QByteArray("SHARE:" + localFile.toUtf8() + "\n")); + }); if (!helper->copyPrivateLinkTitle().isEmpty()) { auto copyPrivateLinkAction = menu->addAction(helper->copyPrivateLinkTitle()); @@ -78,7 +127,6 @@ public: helper->sendCommand(QByteArray("EMAIL_PRIVATE_LINK:" + localFile.toUtf8() + "\n")); }); } - return { menuaction }; } diff --git a/shell_integration/dolphin/ownclouddolphinpluginhelper.cpp b/shell_integration/dolphin/ownclouddolphinpluginhelper.cpp index ae1705220..248aa06cf 100644 --- a/shell_integration/dolphin/ownclouddolphinpluginhelper.cpp +++ b/shell_integration/dolphin/ownclouddolphinpluginhelper.cpp @@ -59,6 +59,7 @@ void OwncloudDolphinPluginHelper::sendCommand(const char* data) void OwncloudDolphinPluginHelper::slotConnected() { + sendCommand("VERSION:\n"); sendCommand("GET_STRINGS:\n"); } @@ -98,6 +99,16 @@ void OwncloudDolphinPluginHelper::slotReadyRead() _strings[args[1]] = args.mid(2).join(QLatin1Char(':')); } continue; + } else if (line.startsWith("VERSION:")) { + auto args = line.split(':'); + auto version = args.value(2); + _version = version; + if (!version.startsWith("1.")) { + // Incompatible version, disconnect forever + _connectTimer.stop(); + _socket.disconnectFromServer(); + return; + } } emit commandRecieved(line); } diff --git a/shell_integration/dolphin/ownclouddolphinpluginhelper.h b/shell_integration/dolphin/ownclouddolphinpluginhelper.h index 294d1969d..3e7a97477 100644 --- a/shell_integration/dolphin/ownclouddolphinpluginhelper.h +++ b/shell_integration/dolphin/ownclouddolphinpluginhelper.h @@ -21,6 +21,7 @@ #include #include #include +#include #include "ownclouddolphinpluginhelper_export.h" class OWNCLOUDDOLPHINPLUGINHELPER_EXPORT OwncloudDolphinPluginHelper : public QObject { @@ -44,6 +45,8 @@ public: QString copyPrivateLinkTitle() const { return _strings["COPY_PRIVATE_LINK_MENU_TITLE"]; } QString emailPrivateLinkTitle() const { return _strings["EMAIL_PRIVATE_LINK_MENU_TITLE"]; } + QByteArray version() { return _version; } + signals: void commandRecieved(const QByteArray &cmd); @@ -61,4 +64,5 @@ private: QBasicTimer _connectTimer; QMap _strings; + QByteArray _version; }; diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi.cpp index cc889b8f3..b175fb036 100644 --- a/src/gui/socketapi.cpp +++ b/src/gui/socketapi.cpp @@ -54,7 +54,7 @@ // This is the version that is returned when the client asks for the VERSION. // The first number should be changed if there is an incompatible change that breaks old clients. // The second number should be changed when there are new features. -#define MIRALL_SOCKET_API_VERSION "1.0" +#define MIRALL_SOCKET_API_VERSION "1.1" static inline QString removeTrailingSlash(QString path) { @@ -535,7 +535,7 @@ void SocketApi::emailPrivateLink(const QString &link) const 0); } -void SocketApi::command_GET_STRINGS(const QString &, SocketListener *listener) +void SocketApi::command_GET_STRINGS(const QString &argument, SocketListener *listener) { static std::array, 5> strings { { { "SHARE_MENU_TITLE", tr("Share...") }, @@ -545,11 +545,37 @@ void SocketApi::command_GET_STRINGS(const QString &, SocketListener *listener) } }; listener->sendMessage(QString("GET_STRINGS:BEGIN")); for (auto key_value : strings) { - listener->sendMessage(QString("STRING:%1:%2").arg(key_value.first, key_value.second)); + if (argument.isEmpty() || argument == QLatin1String(key_value.first)) { + listener->sendMessage(QString("STRING:%1:%2").arg(key_value.first, key_value.second)); + } } listener->sendMessage(QString("GET_STRINGS:END")); } +void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListener *listener) +{ + listener->sendMessage(QString("GET_MENU_ITEMS:BEGIN")); + bool hasSeveralFiles = argument.contains(QLatin1Char('\x1e')); // Record Separator + Folder *syncFolder = hasSeveralFiles ? nullptr : FolderMan::instance()->folderForPath(argument); + if (syncFolder) { + QString systemPath = QDir::cleanPath(argument); + if (systemPath.endsWith(QLatin1Char('/'))) { + systemPath.truncate(systemPath.length() - 1); + } + QString relativePath = systemPath.mid(syncFolder->cleanPath().length() + 1); + + SyncJournalFileRecord rec; + if (syncFolder->accountState()->isConnected() && syncFolder->journalDb()->getFileRecord(relativePath, &rec) && rec.isValid()) { + // If the file is on the DB, it is on the server + // TODO: check if sharing is allowed + listener->sendMessage(QLatin1String("MENU_ITEM:SHARE:") + tr("Share...")); + listener->sendMessage(QLatin1String("MENU_ITEM:COPY_PRIVATE_LINK:") + tr("Copy private link to clipboard")); + listener->sendMessage(QLatin1String("MENU_ITEM:EMAIL_PRIVATE_LINK:") + tr("Send private link by email...")); + } + } + listener->sendMessage(QString("GET_MENU_ITEMS:END")); +} + QString SocketApi::buildRegisterPathMessage(const QString &path) { QFileInfo fi(path); diff --git a/src/gui/socketapi.h b/src/gui/socketapi.h index e50a68fb7..2f4d4b375 100644 --- a/src/gui/socketapi.h +++ b/src/gui/socketapi.h @@ -83,9 +83,19 @@ private: Q_INVOKABLE void command_COPY_PRIVATE_LINK(const QString &localFile, SocketListener *listener); Q_INVOKABLE void command_EMAIL_PRIVATE_LINK(const QString &localFile, SocketListener *listener); - /** Sends translated/branded strings that may be useful to the integration */ + /** Sends translated/branded strings that may be useful to the integration + * Note: Deprecated, only used for compatibility with older shell_integrations (version 1.0) + */ Q_INVOKABLE void command_GET_STRINGS(const QString &argument, SocketListener *listener); + /** Send the list of menu item. (added in version 1.1) + * argument is a list of files for which the menu should be shown, separated by '\x1e' + * Reply with GET_MENU_ITEMS:BEGIN + * followed by several MENU_ITEM:[Action]::[Text] + * and ends with GET_MENU_ITEMS:END + */ + Q_INVOKABLE void command_GET_MENU_ITEMS(const QString &argument, SocketListener *listener); + QString buildRegisterPathMessage(const QString &path); QSet _registeredAliases; From 982c591ec9c2c9e4535f519cd233ecd41b4e56e3 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 19 Jan 2018 14:02:46 +0100 Subject: [PATCH 131/138] SocketApi: add a way to disable menu entries --- shell_integration/dolphin/ownclouddolphinactionplugin.cpp | 6 ++++-- src/gui/socketapi.cpp | 6 +++--- src/gui/socketapi.h | 7 +++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/shell_integration/dolphin/ownclouddolphinactionplugin.cpp b/shell_integration/dolphin/ownclouddolphinactionplugin.cpp index a2010be90..8b306ba95 100644 --- a/shell_integration/dolphin/ownclouddolphinactionplugin.cpp +++ b/shell_integration/dolphin/ownclouddolphinactionplugin.cpp @@ -71,9 +71,11 @@ public: loop.quit(); } else if (cmd.startsWith("MENU_ITEM:")) { auto args = QString::fromUtf8(cmd).split(QLatin1Char(':')); - if (args.size() < 3) + if (args.size() < 4) return; - auto action = menu->addAction(args.mid(2).join(QLatin1Char(':'))); + auto action = menu->addAction(args.mid(3).join(QLatin1Char(':'))); + if (args.value(2).contains(QLatin1Char('d'))) + action->setDisabled(true); auto call = args.value(1).toLatin1(); connect(action, &QAction::triggered, [helper, call, files] { helper->sendCommand(QByteArray(call + ":" + files + "\n")); diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi.cpp index b175fb036..f4e7a85e9 100644 --- a/src/gui/socketapi.cpp +++ b/src/gui/socketapi.cpp @@ -568,9 +568,9 @@ void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListe if (syncFolder->accountState()->isConnected() && syncFolder->journalDb()->getFileRecord(relativePath, &rec) && rec.isValid()) { // If the file is on the DB, it is on the server // TODO: check if sharing is allowed - listener->sendMessage(QLatin1String("MENU_ITEM:SHARE:") + tr("Share...")); - listener->sendMessage(QLatin1String("MENU_ITEM:COPY_PRIVATE_LINK:") + tr("Copy private link to clipboard")); - listener->sendMessage(QLatin1String("MENU_ITEM:EMAIL_PRIVATE_LINK:") + tr("Send private link by email...")); + listener->sendMessage(QLatin1String("MENU_ITEM:SHARE::") + tr("Share...")); + listener->sendMessage(QLatin1String("MENU_ITEM:COPY_PRIVATE_LINK::") + tr("Copy private link to clipboard")); + listener->sendMessage(QLatin1String("MENU_ITEM:EMAIL_PRIVATE_LINK::") + tr("Send private link by email...")); } } listener->sendMessage(QString("GET_MENU_ITEMS:END")); diff --git a/src/gui/socketapi.h b/src/gui/socketapi.h index 2f4d4b375..04bb418e9 100644 --- a/src/gui/socketapi.h +++ b/src/gui/socketapi.h @@ -83,15 +83,14 @@ private: Q_INVOKABLE void command_COPY_PRIVATE_LINK(const QString &localFile, SocketListener *listener); Q_INVOKABLE void command_EMAIL_PRIVATE_LINK(const QString &localFile, SocketListener *listener); - /** Sends translated/branded strings that may be useful to the integration - * Note: Deprecated, only used for compatibility with older shell_integrations (version 1.0) - */ + /** Sends translated/branded strings that may be useful to the integration */ Q_INVOKABLE void command_GET_STRINGS(const QString &argument, SocketListener *listener); /** Send the list of menu item. (added in version 1.1) * argument is a list of files for which the menu should be shown, separated by '\x1e' * Reply with GET_MENU_ITEMS:BEGIN - * followed by several MENU_ITEM:[Action]::[Text] + * followed by several MENU_ITEM:[Action]:[flag]:[Text] + * If flag contains 'd', the menu should be disabled * and ends with GET_MENU_ITEMS:END */ Q_INVOKABLE void command_GET_MENU_ITEMS(const QString &argument, SocketListener *listener); From 3c2622d2de84697857bca6b20fc85e721a416a65 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 19 Jan 2018 11:32:08 +0100 Subject: [PATCH 132/138] Shell integration: Update nautilus for GET_MENU_ITEMS --- shell_integration/nautilus/syncstate.py | 114 +++++++++++++++++++----- 1 file changed, 92 insertions(+), 22 deletions(-) diff --git a/shell_integration/nautilus/syncstate.py b/shell_integration/nautilus/syncstate.py index 082be4e22..e81a83691 100644 --- a/shell_integration/nautilus/syncstate.py +++ b/shell_integration/nautilus/syncstate.py @@ -19,6 +19,7 @@ import os import urllib import socket import tempfile +import time from gi.repository import GObject, Nautilus @@ -55,8 +56,9 @@ class SocketConnect(GObject.GObject): self.registered_paths = {} self._watch_id = 0 self._sock = None - self._listeners = [self._update_registered_paths] + self._listeners = [self._update_registered_paths, self._get_version] self._remainder = '' + self.protocolVersion = '1.0' self.nautilusVFSFile_table = {} # not needed in this object actually but shared # all over the other objects. @@ -96,6 +98,7 @@ class SocketConnect(GObject.GObject): self._watch_id = GObject.io_add_watch(self._sock, GObject.IO_IN, self._handle_notify) print("Socket watch id: " + str(self._watch_id)) + self.sendCommand('VERSION:\n') self.sendCommand('GET_STRINGS:\n') return False # Don't run again @@ -107,29 +110,43 @@ class SocketConnect(GObject.GObject): return True # Run again, if enabled via timeout_add() + # Reads data that becomes available. + # New responses can be accessed with get_available_responses(). + # Returns false if no data was received within timeout + def read_socket_data_with_timeout(self, timeout): + self._sock.settimeout(timeout) + try: + self._remainder += self._sock.recv(1024) + except socket.timeout: + return False + else: + return True + finally: + self._sock.settimeout(None) + + # Parses response lines out of collected data, returns list of strings + def get_available_responses(self): + end = self._remainder.rfind('\n') + if end == -1: + return [] + data = self._remainder[:end] + self._remainder = self._remainder[end+1:] + return data.split('\n') + # Notify is the raw answer from the socket def _handle_notify(self, source, condition): - data = source.recv(1024) - # Prepend the remaining data from last call - if len(self._remainder) > 0: - data = self._remainder + data - self._remainder = '' + # Blocking is ok since we're notified of available data + self._remainder += self._sock.recv(1024) - if len(data) > 0: - # Remember the remainder for next round - lastNL = data.rfind('\n'); - if lastNL > -1 and lastNL < len(data): - self._remainder = data[lastNL+1:] - data = data[:lastNL] - - for l in data.split('\n'): - self._handle_server_response(l) - else: + if len(self._remainder) == 0: return False + for line in self.get_available_responses(): + self.handle_server_response(line) + return True # Run again - def _handle_server_response(self, line): + def handle_server_response(self, line): print("Server response: " + line) parts = line.split(':') action = parts[0] @@ -149,6 +166,10 @@ class SocketConnect(GObject.GObject): if not self.registered_paths: self.reconnect() + def _get_version(self, action, args): + if action == 'VERSION': + self.protocolVersion = args[1] + socketConnect = SocketConnect() @@ -201,6 +222,56 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider): if topLevelFolder or not internalFile: return [] + if socketConnect.protocolVersion >= '1.1': # lexicographic! + return self.ask_for_menu_items(filename) + else: + return self.legacy_menu_items(filename) + + def ask_for_menu_items(self, filename): + socketConnect.sendCommand('GET_MENU_ITEMS:{}\n'.format(filename)) + + done = False + start = time.time() + timeout = 0.1 # 100ms + menu_items = [] + while not done: + dt = time.time() - start + if dt >= timeout: + break + if not socketConnect.read_socket_data_with_timeout(timeout - dt): + break + for line in socketConnect.get_available_responses(): + # Process lines we don't care about + if done or not (line.startswith('GET_MENU_ITEMS:') or line.startswith('MENU_ITEM:')): + socketConnect.handle_server_response(line) + continue + if line == 'GET_MENU_ITEMS:END': + done = True + # don't break - we'd discard other responses + if line.startswith('MENU_ITEM:'): + args = line.split(':') + if len(args) < 4: + continue + menu_items.append([args[1], 'd' not in args[2], ':'.join(args[3:])]) + + if not done: + return self.legacy_menu_items(filename) + + # Set up the 'ownCloud...' submenu + item_owncloud = Nautilus.MenuItem( + name='IntegrationMenu', label=self.strings.get('CONTEXT_MENU_TITLE', appname)) + menu = Nautilus.Menu() + item_owncloud.set_submenu(menu) + + for action, enabled, label in menu_items: + item = Nautilus.MenuItem(name=action, label=label, sensitive=enabled) + item.connect("activate", self.context_menu_action, action, filename) + menu.append_item(item) + + return [item_owncloud] + + + def legacy_menu_items(self, filename): entry = socketConnect.nautilusVFSFile_table.get(filename) if not entry: return [] @@ -235,7 +306,7 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider): item = Nautilus.MenuItem( name='NautilusPython::ShareItem', label=self.strings.get('SHARE_MENU_TITLE', 'Share...')) - item.connect("activate", self.context_menu_action, 'SHARE', file) + item.connect("activate", self.context_menu_action, 'SHARE', filename) menu.append_item(item) # Add permalink menu options, but hide these options for older clients @@ -243,20 +314,19 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider): if 'COPY_PRIVATE_LINK_MENU_TITLE' in self.strings: item_copyprivatelink = Nautilus.MenuItem( name='CopyPrivateLink', label=self.strings.get('COPY_PRIVATE_LINK_MENU_TITLE', 'Copy private link to clipboard')) - item_copyprivatelink.connect("activate", self.context_menu_action, 'COPY_PRIVATE_LINK', file) + item_copyprivatelink.connect("activate", self.context_menu_action, 'COPY_PRIVATE_LINK', filename) menu.append_item(item_copyprivatelink) if 'EMAIL_PRIVATE_LINK_MENU_TITLE' in self.strings: item_emailprivatelink = Nautilus.MenuItem( name='EmailPrivateLink', label=self.strings.get('EMAIL_PRIVATE_LINK_MENU_TITLE', 'Send private link by email...')) - item_emailprivatelink.connect("activate", self.context_menu_action, 'EMAIL_PRIVATE_LINK', file) + item_emailprivatelink.connect("activate", self.context_menu_action, 'EMAIL_PRIVATE_LINK', filename) menu.append_item(item_emailprivatelink) return [item_owncloud] - def context_menu_action(self, menu, action, file): - filename = get_local_path(file.get_uri()) + def context_menu_action(self, menu, action, filename): print("Context menu: " + action + ' ' + filename) socketConnect.sendCommand(action + ":" + filename + "\n") From ebfac84c69cc69b3633b37f97fd501610cd159d1 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Mon, 22 Jan 2018 10:22:51 +0100 Subject: [PATCH 133/138] Shell integration: Make nautilus work with multiselections Previously no menu would ever be shown if more than one file is selected. Now the GET_MENU_ITEMS command is sent with all selected files as an argument - similar to what is done for the dolphin integration. --- shell_integration/nautilus/syncstate.py | 60 ++++++++++++++----------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/shell_integration/nautilus/syncstate.py b/shell_integration/nautilus/syncstate.py index e81a83691..067c6a40a 100644 --- a/shell_integration/nautilus/syncstate.py +++ b/shell_integration/nautilus/syncstate.py @@ -199,36 +199,38 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider): def get_file_items(self, window, files): # Show the menu extension to share a file or folder - # - # Show if file is OK. - # Ignore top level folders. - # Also show extension for folders - # if there is a OK or SYNC underneath. - # This is only - if len(files) != 1: - return - file = files[0] + # Get usable file paths from the uris + all_internal_files = True + for i, file_uri in enumerate(files): + filename = get_local_path(file_uri.get_uri()) - filename = get_local_path(file.get_uri()) - # Check if its a folder (ends with an /), if yes add a "/" - # otherwise it will not find the entry in the table - isDir = os.path.isdir(filename + os.sep) - if isDir: - filename += os.sep + # Check if its a folder (ends with an /), if yes add a "/" + # otherwise it will not find the entry in the table + isDir = os.path.isdir(filename + os.sep) + if isDir: + filename += os.sep - # Check if toplevel folder, we need to ignore those as they cannot be shared - topLevelFolder, internalFile = self.check_registered_paths(filename) - if topLevelFolder or not internalFile: + # Check if toplevel folder, we need to ignore those as they cannot be shared + topLevelFolder, internalFile = self.check_registered_paths(filename) + if not internalFile: + all_internal_files = False + + files[i] = filename + + # Don't show a context menu if some selected files aren't in a sync folder + if not all_internal_files: return [] if socketConnect.protocolVersion >= '1.1': # lexicographic! - return self.ask_for_menu_items(filename) + return self.ask_for_menu_items(files) else: - return self.legacy_menu_items(filename) + return self.legacy_menu_items(files) - def ask_for_menu_items(self, filename): - socketConnect.sendCommand('GET_MENU_ITEMS:{}\n'.format(filename)) + def ask_for_menu_items(self, files): + record_separator = '\x1e' + filesstring = record_separator.join(files) + socketConnect.sendCommand('GET_MENU_ITEMS:{}\n'.format(filesstring)) done = False start = time.time() @@ -255,7 +257,10 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider): menu_items.append([args[1], 'd' not in args[2], ':'.join(args[3:])]) if not done: - return self.legacy_menu_items(filename) + return self.legacy_menu_items(files) + + if len(menu_items) == 0: + return [] # Set up the 'ownCloud...' submenu item_owncloud = Nautilus.MenuItem( @@ -265,13 +270,18 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider): for action, enabled, label in menu_items: item = Nautilus.MenuItem(name=action, label=label, sensitive=enabled) - item.connect("activate", self.context_menu_action, action, filename) + item.connect("activate", self.context_menu_action, action, filesstring) menu.append_item(item) return [item_owncloud] - def legacy_menu_items(self, filename): + def legacy_menu_items(self, files): + # No legacy menu for a selection of several files + if len(files) != 1: + return [] + filename = files[0] + entry = socketConnect.nautilusVFSFile_table.get(filename) if not entry: return [] From 883080b55786ac21cbac973ee381ebc3d08f58aa Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 19 Jan 2018 19:44:10 +0100 Subject: [PATCH 134/138] Windows shell extension: port to the new protocol --- .../OCContextMenu/OCClientInterface.cpp | 38 ++-- .../windows/OCContextMenu/OCClientInterface.h | 18 +- .../windows/OCContextMenu/OCContextMenu.cpp | 184 ++++-------------- .../windows/OCContextMenu/OCContextMenu.h | 20 +- shell_integration/windows/OCUtil/StringUtil.h | 24 +++ 5 files changed, 89 insertions(+), 195 deletions(-) diff --git a/shell_integration/windows/OCContextMenu/OCClientInterface.cpp b/shell_integration/windows/OCContextMenu/OCClientInterface.cpp index 6c6396fa5..019ca5c27 100644 --- a/shell_integration/windows/OCContextMenu/OCClientInterface.cpp +++ b/shell_integration/windows/OCContextMenu/OCClientInterface.cpp @@ -34,7 +34,7 @@ using namespace std; #define PIPE_TIMEOUT 5*1000 //ms #define SOCK_BUFFER 4096 -OCClientInterface::ContextMenuInfo OCClientInterface::FetchInfo() +OCClientInterface::ContextMenuInfo OCClientInterface::FetchInfo(const std::wstring &files) { auto pipename = CommunicationSocket::DefaultPipePath(); @@ -45,7 +45,8 @@ OCClientInterface::ContextMenuInfo OCClientInterface::FetchInfo() if (!socket.Connect(pipename)) { return {}; } - socket.SendMsg(L"GET_STRINGS\n"); + socket.SendMsg(L"GET_STRINGS:CONTEXT_MENU_TITLE\n"); + socket.SendMsg((L"GET_MENU_ITEMS:" + files + L"\n").data()); ContextMenuInfo info; std::wstring response; @@ -60,16 +61,14 @@ OCClientInterface::ContextMenuInfo OCClientInterface::FetchInfo() wstring stringName, stringValue; if (!StringUtil::extractChunks(response, stringName, stringValue)) continue; - if (stringName == L"SHARE_MENU_TITLE") - info.shareMenuTitle = move(stringValue); - else if (stringName == L"CONTEXT_MENU_TITLE") + if (stringName == L"CONTEXT_MENU_TITLE") info.contextMenuTitle = move(stringValue); - else if (stringName == L"COPY_PRIVATE_LINK_MENU_TITLE") - info.copyLinkMenuTitle = move(stringValue); - else if (stringName == L"EMAIL_PRIVATE_LINK_MENU_TITLE") - info.emailLinkMenuTitle = move(stringValue); - } - else if (StringUtil::begins_with(response, wstring(L"GET_STRINGS:END"))) { + } else if (StringUtil::begins_with(response, wstring(L"MENU_ITEM:"))) { + wstring commandName, flags, title; + if (!StringUtil::extractChunks(response, commandName, flags, title)) + continue; + info.menuItems.push_back({ commandName, flags, title }); + } else if (StringUtil::begins_with(response, wstring(L"GET_MENU_ITEMS:END"))) { break; // Stop once we completely received the last sent request } } @@ -81,22 +80,7 @@ OCClientInterface::ContextMenuInfo OCClientInterface::FetchInfo() return info; } -void OCClientInterface::RequestShare(const std::wstring &path) -{ - SendRequest(L"SHARE", path); -} - -void OCClientInterface::RequestCopyLink(const std::wstring &path) -{ - SendRequest(L"COPY_PRIVATE_LINK", path); -} - -void OCClientInterface::RequestEmailLink(const std::wstring &path) -{ - SendRequest(L"EMAIL_PRIVATE_LINK", path); -} - -void OCClientInterface::SendRequest(wchar_t *verb, const std::wstring &path) +void OCClientInterface::SendRequest(const wchar_t *verb, const std::wstring &path) { auto pipename = CommunicationSocket::DefaultPipePath(); diff --git a/shell_integration/windows/OCContextMenu/OCClientInterface.h b/shell_integration/windows/OCContextMenu/OCClientInterface.h index 74e6364fe..586a03f2f 100644 --- a/shell_integration/windows/OCContextMenu/OCClientInterface.h +++ b/shell_integration/windows/OCContextMenu/OCClientInterface.h @@ -46,18 +46,14 @@ public: struct ContextMenuInfo { std::vector watchedDirectories; std::wstring contextMenuTitle; - std::wstring shareMenuTitle; - std::wstring copyLinkMenuTitle; - std::wstring emailLinkMenuTitle; + struct MenuItem + { + std::wstring command, flags, title; + }; + std::vector menuItems; }; - static ContextMenuInfo FetchInfo(); - - static void RequestShare(const std::wstring &path); - static void RequestCopyLink(const std::wstring &path); - static void RequestEmailLink(const std::wstring &path); - -private: - static void SendRequest(wchar_t *verb, const std::wstring &path); + static ContextMenuInfo FetchInfo(const std::wstring &files); + static void SendRequest(const wchar_t *verb, const std::wstring &path); }; #endif //ABSTRACTSOCKETHANDLER_H diff --git a/shell_integration/windows/OCContextMenu/OCContextMenu.cpp b/shell_integration/windows/OCContextMenu/OCContextMenu.cpp index bda86b86d..bd305da65 100644 --- a/shell_integration/windows/OCContextMenu/OCContextMenu.cpp +++ b/shell_integration/windows/OCContextMenu/OCContextMenu.cpp @@ -22,13 +22,8 @@ #include #include -extern HINSTANCE g_hInst; extern long g_cDllRef; -#define IDM_SHARE 0 -#define IDM_COPYLINK 1 -#define IDM_EMAILLINK 2 - OCContextMenu::OCContextMenu(void) : m_cRef(1) { @@ -40,23 +35,6 @@ OCContextMenu::~OCContextMenu(void) InterlockedDecrement(&g_cDllRef); } - -void OCContextMenu::OnVerbShare(HWND hWnd) -{ - OCClientInterface::RequestShare(std::wstring(m_szSelectedFile)); -} - -void OCContextMenu::OnVerbCopyLink(HWND hWnd) -{ - OCClientInterface::RequestCopyLink(std::wstring(m_szSelectedFile)); -} - -void OCContextMenu::OnVerbEmailLink(HWND hWnd) -{ - OCClientInterface::RequestEmailLink(std::wstring(m_szSelectedFile)); -} - - #pragma region IUnknown // Query to the interface the component supported. @@ -97,12 +75,12 @@ IFACEMETHODIMP_(ULONG) OCContextMenu::Release() IFACEMETHODIMP OCContextMenu::Initialize( LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hKeyProgID) { + m_selectedFiles.clear(); + if (!pDataObj) { return E_INVALIDARG; } - HRESULT hr = E_FAIL; - FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM stm; @@ -110,14 +88,19 @@ IFACEMETHODIMP OCContextMenu::Initialize( // Get an HDROP handle. HDROP hDrop = static_cast(GlobalLock(stm.hGlobal)); if (hDrop) { - // Ignore multi-selections UINT nFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); - if (nFiles == 1) { + for (int i = 0; i < nFiles; ++i) { // Get the path of the file. - if (0 != DragQueryFile(hDrop, 0, m_szSelectedFile, ARRAYSIZE(m_szSelectedFile))) - { - hr = S_OK; + wchar_t buffer[MAX_PATH]; + + if (!DragQueryFile(hDrop, i, buffer, ARRAYSIZE(buffer))) { + m_selectedFiles.clear(); + break; } + + if (i) + m_selectedFiles += L'\x1e'; + m_selectedFiles += buffer; } GlobalUnlock(stm.hGlobal); @@ -128,7 +111,7 @@ IFACEMETHODIMP OCContextMenu::Initialize( // If any value other than S_OK is returned from the method, the context // menu item is not displayed. - return hr; + return m_selectedFiles.empty() ? E_FAIL : S_OK; } #pragma endregion @@ -153,17 +136,8 @@ IFACEMETHODIMP OCContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0)); } - OCClientInterface::ContextMenuInfo info = OCClientInterface::FetchInfo(); - bool skip = true; - size_t selectedFileLength = wcslen(m_szSelectedFile); - for (const std::wstring path : info.watchedDirectories) { - if (StringUtil::isDescendantOf(m_szSelectedFile, selectedFileLength, path)) { - skip = false; - break; - } - } - - if (skip) { + m_info = OCClientInterface::FetchInfo(m_selectedFiles); + if (m_info.menuItems.empty()) { return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0)); } @@ -175,7 +149,7 @@ IFACEMETHODIMP OCContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT mii.fMask = MIIM_SUBMENU | MIIM_FTYPE | MIIM_STRING; mii.hSubMenu = hSubmenu; mii.fType = MFT_STRING; - mii.dwTypeData = &info.contextMenuTitle[0]; + mii.dwTypeData = &m_info.contextMenuTitle[0]; if (!InsertMenuItem(hMenu, indexMenu++, TRUE, &mii)) return HRESULT_FROM_WIN32(GetLastError()); @@ -183,133 +157,59 @@ IFACEMETHODIMP OCContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT InsertSeperator(hMenu, indexMenu++); UINT indexSubMenu = 0; - { - assert(!info.shareMenuTitle.empty()); + for (auto &item : m_info.menuItems) { + bool disabled = item.flags.find(L'd') != std::string::npos; + MENUITEMINFO mii = { sizeof(mii) }; - mii.fMask = MIIM_ID | MIIM_FTYPE | MIIM_STRING; - mii.wID = idCmdFirst + IDM_SHARE; + mii.fMask = MIIM_ID | MIIM_FTYPE | MIIM_STRING | MIIM_STATE; + mii.wID = indexSubMenu; mii.fType = MFT_STRING; - mii.dwTypeData = &info.shareMenuTitle[0]; + mii.dwTypeData = &item.title[0]; + mii.fState = disabled ? MFS_DISABLED : MFS_ENABLED; - if (!InsertMenuItem(hSubmenu, indexSubMenu++, TRUE, &mii)) + if (!InsertMenuItem(hSubmenu, indexSubMenu, true, &mii)) return HRESULT_FROM_WIN32(GetLastError()); + indexSubMenu++; } - { - assert(!info.copyLinkMenuTitle.empty()); - MENUITEMINFO mii = { sizeof(mii) }; - mii.fMask = MIIM_ID | MIIM_FTYPE | MIIM_STRING; - mii.wID = idCmdFirst + IDM_COPYLINK; - mii.fType = MFT_STRING; - mii.dwTypeData = &info.copyLinkMenuTitle[0]; - - if (!InsertMenuItem(hSubmenu, indexSubMenu++, TRUE, &mii)) - return HRESULT_FROM_WIN32(GetLastError()); - } - { - assert(!info.emailLinkMenuTitle.empty()); - MENUITEMINFO mii = { sizeof(mii) }; - mii.fMask = MIIM_ID | MIIM_FTYPE | MIIM_STRING; - mii.wID = idCmdFirst + IDM_EMAILLINK; - mii.fType = MFT_STRING; - mii.dwTypeData = &info.emailLinkMenuTitle[0]; - - if (!InsertMenuItem(hSubmenu, indexSubMenu++, TRUE, &mii)) - return HRESULT_FROM_WIN32(GetLastError()); - } - // Return an HRESULT value with the severity set to SEVERITY_SUCCESS. // Set the code value to the offset of the largest command identifier // that was assigned, plus one (1). - return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(IDM_EMAILLINK + 1)); + return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(indexSubMenu)); } IFACEMETHODIMP OCContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO pici) { + std::wstring command; // For the Unicode case, if the high-order word is not zero, the // command's verb string is in lpcmi->lpVerbW. if (HIWORD(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW)) { - // Is the verb supported by this context menu extension? - if (StrCmpIW(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW, L"ocshare") == 0) { - OnVerbShare(pici->hwnd); - } - else if (StrCmpIW(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW, L"occopylink") == 0) { - OnVerbCopyLink(pici->hwnd); - } - else if (StrCmpIW(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW, L"ocemaillink") == 0) { - OnVerbEmailLink(pici->hwnd); - } - else { - // If the verb is not recognized by the context menu handler, it - // must return E_FAIL to allow it to be passed on to the other - // context menu handlers that might implement that verb. + command = ((CMINVOKECOMMANDINFOEX *)pici)->lpVerbW; + } else { + // If the command cannot be identified through the verb string, then + // check the identifier offset. + + auto offset = LOWORD(pici->lpVerb); + if (offset < m_info.menuItems.size()) return E_FAIL; - } - } - - // If the command cannot be identified through the verb string, then - // check the identifier offset. - else - { - // Is the command identifier offset supported by this context menu - // extension? - if (LOWORD(pici->lpVerb) == IDM_SHARE) { - OnVerbShare(pici->hwnd); - } - else if (LOWORD(pici->lpVerb) == IDM_COPYLINK) { - OnVerbCopyLink(pici->hwnd); - } - else if (LOWORD(pici->lpVerb) == IDM_EMAILLINK) { - OnVerbEmailLink(pici->hwnd); - } - else { - // If the verb is not recognized by the context menu handler, it - // must return E_FAIL to allow it to be passed on to the other - // context menu handlers that might implement that verb. - return E_FAIL; - } + + command = m_info.menuItems[offset].command; } + OCClientInterface::SendRequest(command.data(), m_selectedFiles); return S_OK; } IFACEMETHODIMP OCContextMenu::GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *pwReserved, LPSTR pszName, UINT cchMax) { - HRESULT hr = E_INVALIDARG; - - switch (idCommand) { - case IDM_SHARE: - if (uFlags == GCS_VERBW) { - // GCS_VERBW is an optional feature that enables a caller to - // discover the canonical name for the verb passed in through - // idCommand. - hr = StringCchCopy(reinterpret_cast(pszName), cchMax, - L"OCShareViaOC"); - } - break; - case IDM_COPYLINK: - if (uFlags == GCS_VERBW) { - hr = StringCchCopy(reinterpret_cast(pszName), cchMax, - L"OCCopyLink"); - } - break; - case IDM_EMAILLINK: - if (uFlags == GCS_VERBW) { - hr = StringCchCopy(reinterpret_cast(pszName), cchMax, - L"OCEmailLink"); - } - break; - default: - break; + if (idCommand < m_info.menuItems.size() && uFlags == GCS_VERBW) { + return StringCchCopyW(reinterpret_cast(pszName), cchMax, + m_info.menuItems[idCommand].command.data()); } - - // If the idCommand or uFlags is not supported by this context menu - // extension handler, return E_INVALIDARG. - - return hr; + return E_INVALIDARG; } -#pragma endregion \ No newline at end of file +#pragma endregion diff --git a/shell_integration/windows/OCContextMenu/OCContextMenu.h b/shell_integration/windows/OCContextMenu/OCContextMenu.h index 7fe3e2ade..e8836d6fe 100644 --- a/shell_integration/windows/OCContextMenu/OCContextMenu.h +++ b/shell_integration/windows/OCContextMenu/OCContextMenu.h @@ -17,6 +17,8 @@ #pragma once #include // For IShellExtInit and IContextMenu +#include +#include "OCClientInterface.h" class OCContextMenu : public IShellExtInit, public IContextMenu { @@ -43,21 +45,9 @@ private: // Reference count of component. long m_cRef; - // The name of the selected file. - wchar_t m_szSelectedFile[MAX_PATH]; - - // The method that handles the "ocshare" verb. - void OnVerbShare(HWND hWnd); - void OnVerbCopyLink(HWND hWnd); - void OnVerbEmailLink(HWND hWnd); - - PWSTR m_pszMenuText; - PCSTR m_pszVerb; - PCWSTR m_pwszVerb; - PCSTR m_pszVerbCanonicalName; - PCWSTR m_pwszVerbCanonicalName; - PCSTR m_pszVerbHelpText; - PCWSTR m_pwszVerbHelpText; + // The name of the selected files (separated by '\x1e') + std::wstring m_selectedFiles; + OCClientInterface::ContextMenuInfo m_info; }; #endif //OCCONTEXTMENU_H diff --git a/shell_integration/windows/OCUtil/StringUtil.h b/shell_integration/windows/OCUtil/StringUtil.h index 8ec325aa9..c0cef5851 100644 --- a/shell_integration/windows/OCUtil/StringUtil.h +++ b/shell_integration/windows/OCUtil/StringUtil.h @@ -61,6 +61,30 @@ public: thirdChunk = source.substr(statusEnd + 1); return true; } + + static bool extractChunks(const std::wstring &source, std::wstring &secondChunk, std::wstring &thirdChunk, std::wstring &forthChunk) + { + auto statusBegin = source.find(L':', 0); + assert(statusBegin != std::wstring::npos); + + auto statusEnd = source.find(L':', statusBegin + 1); + if (statusEnd == std::wstring::npos) { + // the command do not contains two colon? + return false; + } + + auto thirdColon = source.find(L':', statusEnd + 1); + if (statusEnd == std::wstring::npos) { + // the command do not contains three colon? + return false; + } + + // Assume the caller extracted the chunk before the first colon. + secondChunk = source.substr(statusBegin + 1, statusEnd - statusBegin - 1); + thirdChunk = source.substr(statusEnd + 1, thirdColon - statusEnd - 1); + forthChunk = source.substr(thirdColon + 1); + return true; + } }; #endif // STRINGUTIL_H From 02988229b13f472fc52ec671e061a46d644e6b84 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 24 Jan 2018 10:19:54 +0100 Subject: [PATCH 135/138] FolderStatusModel: don't use deprecated QModelIndex::child Was deprecated in Qt 5.8. (IMHO this show that child can be usefull and I am not sure the deprecation was justified) --- src/gui/folderstatusmodel.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/folderstatusmodel.cpp b/src/gui/folderstatusmodel.cpp index d51b987dc..6c2925614 100644 --- a/src/gui/folderstatusmodel.cpp +++ b/src/gui/folderstatusmodel.cpp @@ -298,7 +298,7 @@ bool FolderStatusModel::setData(const QModelIndex &index, const QVariant &value, // also check all the children for (int i = 0; i < info->_subs.count(); ++i) { if (info->_subs[i]._checked != Qt::Checked) { - setData(index.child(i, 0), Qt::Checked, Qt::CheckStateRole); + setData(this->index(i, 0, index), Qt::Checked, Qt::CheckStateRole); } } } @@ -313,7 +313,7 @@ bool FolderStatusModel::setData(const QModelIndex &index, const QVariant &value, // Uncheck all the children for (int i = 0; i < info->_subs.count(); ++i) { if (info->_subs[i]._checked != Qt::Unchecked) { - setData(index.child(i, 0), Qt::Unchecked, Qt::CheckStateRole); + setData(this->index(i, 0, index), Qt::Unchecked, Qt::CheckStateRole); } } } @@ -703,7 +703,7 @@ void FolderStatusModel::slotUpdateDirectories(const QStringList &list) } for (auto it = undecidedIndexes.begin(); it != undecidedIndexes.end(); ++it) { - suggestExpand(idx.child(*it, 0)); + suggestExpand(index(*it, 0, idx)); } /* We need lambda function for the following code. From aa7e47f52544730d7d977f23707da6bf60632f75 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Thu, 25 Jan 2018 12:04:50 +0100 Subject: [PATCH 136/138] Fix new icon naming Signed-off-by: Roeland Jago Douma --- theme.qrc | 14 +- theme/colored/1024-Nextcloud-icon.png | Bin 0 -> 345325 bytes theme/colored/1024-owncloud-icon.png | Bin 52860 -> 0 bytes ...ud-icon-128.png => 128-Nextcloud-icon.png} | Bin theme/colored/128-owncloud-icon.png | Bin 4296 -> 0 bytes ...loud-icon-16.png => 16-Nextcloud-icon.png} | Bin ...d-icon-16.png => 16-Nextcloud-sidebar.png} | Bin theme/colored/16-owncloud-icon.png | Bin 495 -> 0 bytes theme/colored/16-owncloud-sidebar.png | Bin 495 -> 0 bytes theme/colored/18-Nextcloud-sidebar.png | Bin 0 -> 1002 bytes theme/colored/18-owncloud-sidebar.png | Bin 625 -> 0 bytes ...loud-icon-22.png => 22-Nextcloud-icon.png} | Bin theme/colored/22-owncloud-icon.png | Bin 713 -> 0 bytes ...ud-icon-256.png => 256-Nextcloud-icon.png} | Bin theme/colored/256-owncloud-icon.png | Bin 9012 -> 0 bytes ...loud-icon-32.png => 32-Nextcloud-icon.png} | Bin ...d-icon-32.png => 32-Nextcloud-sidebar.png} | Bin theme/colored/32-owncloud-icon.png | Bin 1061 -> 0 bytes theme/colored/32-owncloud-sidebar.png | Bin 1061 -> 0 bytes theme/colored/36-Nextcloud-sidebar.png | Bin 0 -> 2731 bytes theme/colored/36-owncloud-sidebar.png | Bin 1159 -> 0 bytes ...loud-icon-48.png => 48-Nextcloud-icon.png} | Bin theme/colored/48-owncloud-icon.png | Bin 1581 -> 0 bytes ...ud-icon-512.png => 512-Nextcloud-icon.png} | Bin theme/colored/512-owncloud-icon.png | Bin 18391 -> 0 bytes ...loud-icon-64.png => 64-Nextcloud-icon.png} | Bin ...d-icon-64.png => 64-Nextcloud-sidebar.png} | Bin theme/colored/64-owncloud-icon.png | Bin 2153 -> 0 bytes theme/colored/64-owncloud-sidebar.png | Bin 2153 -> 0 bytes theme/colored/nextcloud-icon-128.png | Bin 17488 -> 0 bytes theme/colored/nextcloud-icon-22.png | Bin 1190 -> 0 bytes theme/colored/nextcloud-icon-256.png | Bin 52351 -> 0 bytes theme/colored/nextcloud-icon-48.png | Bin 3725 -> 0 bytes theme/colored/nextcloud-icon-512.png | Bin 137075 -> 0 bytes theme/colored/owncloud-icon.svg | 1400 ----------------- 35 files changed, 7 insertions(+), 1407 deletions(-) create mode 100644 theme/colored/1024-Nextcloud-icon.png delete mode 100644 theme/colored/1024-owncloud-icon.png rename theme/colored/{Nextcloud-icon-128.png => 128-Nextcloud-icon.png} (100%) delete mode 100644 theme/colored/128-owncloud-icon.png rename theme/colored/{Nextcloud-icon-16.png => 16-Nextcloud-icon.png} (100%) rename theme/colored/{nextcloud-icon-16.png => 16-Nextcloud-sidebar.png} (100%) delete mode 100644 theme/colored/16-owncloud-icon.png delete mode 100644 theme/colored/16-owncloud-sidebar.png create mode 100644 theme/colored/18-Nextcloud-sidebar.png delete mode 100644 theme/colored/18-owncloud-sidebar.png rename theme/colored/{Nextcloud-icon-22.png => 22-Nextcloud-icon.png} (100%) delete mode 100644 theme/colored/22-owncloud-icon.png rename theme/colored/{Nextcloud-icon-256.png => 256-Nextcloud-icon.png} (100%) delete mode 100644 theme/colored/256-owncloud-icon.png rename theme/colored/{Nextcloud-icon-32.png => 32-Nextcloud-icon.png} (100%) rename theme/colored/{nextcloud-icon-32.png => 32-Nextcloud-sidebar.png} (100%) delete mode 100644 theme/colored/32-owncloud-icon.png delete mode 100644 theme/colored/32-owncloud-sidebar.png create mode 100644 theme/colored/36-Nextcloud-sidebar.png delete mode 100644 theme/colored/36-owncloud-sidebar.png rename theme/colored/{Nextcloud-icon-48.png => 48-Nextcloud-icon.png} (100%) delete mode 100644 theme/colored/48-owncloud-icon.png rename theme/colored/{Nextcloud-icon-512.png => 512-Nextcloud-icon.png} (100%) delete mode 100644 theme/colored/512-owncloud-icon.png rename theme/colored/{Nextcloud-icon-64.png => 64-Nextcloud-icon.png} (100%) rename theme/colored/{nextcloud-icon-64.png => 64-Nextcloud-sidebar.png} (100%) delete mode 100644 theme/colored/64-owncloud-icon.png delete mode 100644 theme/colored/64-owncloud-sidebar.png delete mode 100644 theme/colored/nextcloud-icon-128.png delete mode 100644 theme/colored/nextcloud-icon-22.png delete mode 100644 theme/colored/nextcloud-icon-256.png delete mode 100644 theme/colored/nextcloud-icon-48.png delete mode 100644 theme/colored/nextcloud-icon-512.png delete mode 100644 theme/colored/owncloud-icon.svg diff --git a/theme.qrc b/theme.qrc index e85cedd71..1be58f01e 100644 --- a/theme.qrc +++ b/theme.qrc @@ -1,12 +1,12 @@ - theme/colored/512-owncloud-icon.png - theme/colored/256-owncloud-icon.png - theme/colored/128-owncloud-icon.png - theme/colored/22-owncloud-icon.png - theme/colored/32-owncloud-icon.png - theme/colored/48-owncloud-icon.png - theme/colored/64-owncloud-icon.png + theme/colored/512-Nextcloud-icon.png + theme/colored/256-Nextcloud-icon.png + theme/colored/128-Nextcloud-icon.png + theme/colored/22-Nextcloud-icon.png + theme/colored/32-Nextcloud-icon.png + theme/colored/48-Nextcloud-icon.png + theme/colored/64-Nextcloud-icon.png theme/colored/state-error-32.png theme/colored/state-error-64.png theme/colored/state-error-128.png diff --git a/theme/colored/1024-Nextcloud-icon.png b/theme/colored/1024-Nextcloud-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b8c89ee03189351ef87757282810de51de20cfcb GIT binary patch literal 345325 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�vLEa>Z! zto=pTotka!H!Vi4Huk=qa#2RwC?E^apZ_@^HV(X1$^Z5lALMxh)P2=W=58gUN!XUB zb#1@=M#SlpV1^@8>-a%dO*R87a+7ckkA}kHt@vnyXccl(N-h3pIj)M?rd+`11wMwcFeMxS&07I`D^@dpa2E1l0_|dE04CL_Ae!K$G7#`8kIJ?($dd%%$ zmB}(8R7IXrHL69wST%g=QzEn{r^uEjW>7rlY+wXvkD|RN{1^Z_SQPk2^5ASQG=W-L zGIIkS;oQ;l;~Flc@yR_7iedRM%}mZSZSgMoYf`tg&l3UJZ7IG|6N|ax1DjU^iMkQO%{3U z?1i*pzBroLexJFnAoy~k5#SpO=??{qsId}U#4>y<-5fCURcQ7DX%>y(EPM8qNF`K7 zUJU?SD#vqVO{ebWnl^zqaW7W};7azY&!emH)Nz6#)xnc;I5E*y-n%wT>G% z`#H-{7ebZMpWpl4pmF=dkqO`j9s*csC%bE z83B?gKIM-{P6+7c@O=g7A6SFP`;Nem*_j)3V^H@-fbw$m#Ta)#0Ztdcnzq~^Ys|`X zYrUU314jD6!+8F#)?-yb1vnS?e_WqI`xV5wIAJnj2T)EpNu4r2-V(65P~jJ#0(5Z& zoGvzxy+&htAIB}99Q7*s(V!k@^45rk%)Xh@i-UJDWs~y({b}Ofl}e54_`r7IOJkuR zTCa#I#2lZYW!zkYTloNKw%^ZSV9~Y5++RnCwg}YY)Y{6$GMv?`nk7+%5cw|k`>%(f zdPR8F*LTgb+pNGGCoC34YMyj;!vH5aUaeX~r&Sqzd)RlOVx#iA&$VABvx~^GTC*3q zI2cw}sy`k#l*qbg9nlbXRgE9vE!MUwuUeuR1Z2Oyt^CXCzwVRO^2ybUMA1*F?lbp7 z^iZ)3?X$-td*x>dOo5oX`zH8k{ANH>%C(#4QTcDWW76IcPLePcqOxDwjgjJ0D|l79 zSj|86_fbTlx4}R-@b5_wl-VgNIyBbgwzfIX!j4l84Bun*hF~j0e zsq!>!rC5~}sGTr2^dq@MXdCZ#Pj(P`iCtjETASY^+2R~}syI%e zbiXAp1o}D(MNV@7 zNMi?O6s5VVt0z|_bCpYboDvusI|H4DR+pNgE!FPjnt4|oDHtc<$F^Hw)yX}{G#dIw z2EWlb`<40rW&eTzA82oQ1KWX$4_E8GN5h zh_>5U>K!8nmkH1m+z(s5KBoy~1OrmZNUhh=JOPpo*%7_qTB zqK=ZP>$Eo8g^}aV$wnm9}d==~4^;dQ=>fM48`!r+ILk+7layw&r0+R%G?;VT|u1AVy;#J6qxL zxSNCU94)cILSF4DRQf!GL}O-*O(TUO?C3tJO|UWuz}E54J%04%A*}pHa6I>s(eLvh zW4JACXaTsN(#e@iv|>MxR30Fzanf{4(ps(yNkVy62c?UsQgL>|mHUSCE~VuXb^BjzE@=Te`iW**)R-sI*svD-`o*TV(b_vP} zv=F#&nV#|$w6gGo3uvKZ%I@!#{3Z~ame%Ao>^qpxxhK)0XWgRVVH3G*zwW>;c(rLi z?ZEW~xcdDItXw`(e;)3Ud2E z;nq`Eh{U)HC9!PNq|`wuP-ZvxYbDvu(-N<`Zuw%gZGm3X;6ybFA2ri~MgAHC$=27i zBfyKZSfGFQ+UXcOS0hRD*5w5TuEn4O+1^Ve(f(P}61J4;IGsT0tA!a%{$fM3g~Vz0 zb{zPGv?yFm$)Xx@ca4w?D&-Y68HkKrEc4TB^j$I)k=;L+@!;bL69Z~MVBa=ZZ{3qs zT*z95U{=$0E*v|D-E}R0b$`gZn5PV`d_}Cr4RX&v3;s57zZIC`wYe^;Ax)#h%aMJ0 zTpSSrN%!&pzz_Vu4}1a`{kb{m=@ z%fKmvGYNlp3|}YP2*D2w06u%G658}d3E$i2sxXt?xED8AXnLK$sTAjY1H#{kybKIZ zj2kkcvz7aCb(~c(TDXSZ7^AGY`F#lJRvcJRnp+uk0G+Z=avYpmmPvQ23I)`C|Fnr$ znVbo4ihnf>xbQxI9UL7W`l^!~&b|qp?4j`U2Y%oq!P9xV{VeLW;BWFDXIbIb6~!t; zRL_2uDI|U4EdY4pd?+yg%<22XY^=Mj0te|n15BAahm~W3)dk%0hUD*8b9M1&Rc^Xx z*DRwxua$e}sl?0U@#^ShZv)OCmLp5$;pX;Fn*(^Dpc#zkru#@d(Ibuq0b; zC$0`nORYUxNglY?pXC)xJ&Q|W>P%d1w=}efFDJ{M=6QC*=*|oxgFFsTIJk)~wEEyo zPJMLw@uG<7wB*H(P)1E{Uo;B4XY2x}QzzF5JBi?KyrM7EzFV<~_0tQN-TfKu;(|tBH$pt)U+hor?lUsnHVAf6G zrL5i;9G-bw4l4!sIHwL4x=(-r-Is4JPu3hiocXLL^>L2>_`xQC?mja<91|_F1e`@D`riNh}kZj9LuuzgR-EPdl{(}7S8~F1d;Q1H$`MK`>7foMR|I2|TtOu8@7TiA@Zd(}ZJ6(3OJWtBz z(es-WcCmaMZR5NJ-lF`EjFUI1T7yN@FXm}*(GIX`-|PV}AXuI`D`U5Jst7BLI-T2J zm%duxd^&XZ)#y;%r#qEgjSG3Ninu9oMe#C=uMGB5&qQMZ*Js=q2b>4R5%5~DlY+ah zzV?l2r(T1tts&VeP>ZYe&NWTccKx=UsV7EUQ6E{%9!;t87EhfU;tAlpbZGG;n5(`S z3PhRrLtnZx6*?tH_}NwsA>cI{wkzvv(Uvy?&v8TuJm1844oY(Q7oIT2$ya$C{J;-< z1z=C>TkzgZje-6E*5`_>j>T1d7XHWpNERAg5Vv4s*HZ2J<5&F|OM5s0d=ElC;(yfs z#_I{(;?ea;M%b~TX(SU@d8_P|hQo0ukJijWId`q~aynjGpn8Y#c%U)vA2x?)6@8!v0c^_Mtgma;YQ%g3 zU`Lv%g4Hl+2?!#u@@yq)p!|0$s}sfUQ=sePR{7MvDfE0mG#tKYG=3m~nNUB`wy`bp z*GJB9pl4y10WGEa2-$xDRB|ye0(dL$GR{z+ZfYg=27$3c^c9Hv4}5cY4;&oPwO3`c z$}64XulHHK3+sMcf(Dpkx#v~~r6Sbkj6smri6QZ>z*vhz@Q#54KNAMZ|CvJH2l@LX znz~eOP_$Go=;Rs21J@6t2vU$iH5gyv@Pqs$%g{f z39rjtpG(kNxt_M6)2W6fJUC=&m_!@;d;RiT{YjWdvyP)y|H^QR)@dH2b zR{%3|&Q++nx8%(%o@QK)0oa`~rTi~fW2m`Um-o85O78k`;hPYcW>Mz{S~=4H!WKWw zp@o69?VmsJXuyDZ6zlpYGlTaG?7IZ~%b*L8Qi9SoW zt9z%n6Ep=2vYR_-Q^!HycF%+8c;pH2nGow0t48snuRG7~O!gz^^6xANW{J_GYg{}4 z^%^*>|3aFt0%v$}i*d@P!dd#BZg>~yANYZ92~nX7bkO*-8kEmqRp>HT|F{jHRq`9J zG*$Rn#cACZI0(A*A*=s?DNH=7Mk|R5XTio^RqiK2vqjAodC-Y@W;$co{_n<+r3szf ziT2GMVRRsK54?P;##(;M5arI}gdY!b)SWKeWMuL1$Z|G(mD6lEN!1-^)Fc4gjf(Tc zW3h2LKbjjuZDfJ%6S^2A7Nmg2iUqtQvOM^+j%7>Q}+a3TWQ?j}b9nftf2()`9%;>1ci5bwO@3nruS|rN3;dV^y z>(2FgW8Ct16wB1(|9pA#>b*bQxzL&N?r^UychpA|`emZT$Is3L&!IJ0vnmK+wwtd( z-_a^e+MGZWPMP{yV}sEDHwlDyhY`&_f|0QE8syY1Zn1pLQV5{Y{2PJ8MWd*@KMRfR z_y+^T8BI_!5y16*NuALK!RiRW&DHKbB3=H?V#7iaCWCxD6n3@R{xLmO7Rc_ZHD(9O zVyv(}eOJNwXyveBCvmQ<)u|0V9q`r+9A&S!&Xel#TK>$BbU4SXA+MWbi?D29SVUEy zUrYNbq**C0XVt2T#Nvvz%gl&57KDouVx8I8g?(ruZ8e^wWR<6AOJ~3K~xQinEq*^B8T5_O8_p&T!P*K(wHp_7?89{ z8Bn(+W&(3+Fov`P2nG4~E10hURb`iq&$HtlgiLv9LKCwH1CFWWfk9y8UNW#w7w5qR zDv@)4e1&VXCF2b6J}$Gd5*0V^YJKXNBzvSigJyy$Lib8m`A-Pgj?#Y5#O0CzBnuEA zXVgnjJIjVk{iEHcGRiOwhP)wsoVnfN(IBxC^O!(LwTTQ2gHn0}lZQ^}83;Wo1g2z0 zq8baL9wq7jq)fa3^bDi~+Ac_R0aEF^Y}8TWUXa`OPx_3cJ$u0sP5>@_``#V$xL+gi z5|&n+FtS1QxhK}7c&B{@{hm zqE$Jb6Y#t!E&#_Mdq6ue0I;5<12l84EPhs6$rShe`#e?FC`whsX9y;ES3bE3?;Q}M zc)#f3Oh^ahufE6-+3CarKv*WHcZP!;8yXk~y`AHhi=19_RwC!QbVU={=q8x0Am%)7 za`$Y_vyNj~IvJn}m*8{;khzuN0`25Pz)rG-rD;s}|Gi-yuZnzio}UKn1S;Jsyqi?6 zVFKd?z}|h|l}f3|SSOG8LdE@xwH_)9eYuZQmW;j2vC0|c%|Lr=K$()pz(zpUtJgS62DiKLasEo zCZ5#qhPM2``@kL3A-JU#-Ng)m>f zQ^?urOHuE6wH_DC?D*E8PP6hxi^j8JzX|=5B}J!k#fI6Ki7=@v`Hfk~w9ksHJ_~p6 z?Z}pw2?=ZGjxHffr<74Qfo?iSeBfcga$O8v+A`OU&ds?+M0IIwP8)#hFYVV=!-(mn zC+%t!D<1ca%ai>5Nq-HG$7wS?2Hyq@uH{}a&Q8kn;O|GPl##${v5jf7R)~F_c*oR| z-SmwT6RMsws#GNcZJT(YaInl)tL>vhKd)a`=g!J&N9C7qtgleL~M@8&wxL$ez2l0!c8z`&FC4B>If%U=nHi!}q~e~H=gkD_XUK4$U)PR>cA2u`(szBYKi)dwCU4WfV}+VJ zrIBiWs{f7JVOu;Ru_!FglF-Z=zBi7t>{COVHeQl7+ zGqp7Yxr956aW2QR++K>-}J5OTjI?Wko)E zkDex#0k1o7{R3Q|f&HaCQ(cG$^XS%cPH=48{$BAOrW>q^ze%1M$y0+xO$yc#Z^&(E zJ0Ob~H`dLU?H8z&SB-c^pl^TE?7ZMqa91@juF~n=7u_2VAd8{{7OTG~!(ugStp0FF zQEtNVeiM+nb+|%2dhV6~5%QmbSwN2K)|A&Q$6%~S`262A0pSEKd7#2rQ+6j&)w;SB z96uGSApr1~_P!a4Hz@!5UCynMXV&l1z9N5yzMClj(`cp?+BdT(Dgq9SIgJC$2GoFl z@|O~bHXv=Fl)!P1`y(rq9tIv60G8?>SMH|4US_|B(^6L2S69?JpLu*(4PN#T^KDA!lt!$;gOAZI zI5aa{2cB{m!0gd^$GgDyXmg=(JM#VlTwj2f-@x@Zus=&Yq7n~eeTdye4r`P-^b;WZ&S=$ zs#cF~^YzhpwF%aafwk<_5M{mCJm2Agn2_tUs+4j24H%7o6O|rmm355!-YRqqqyep< zMyF9e(io4jinm@l)Y`fBj@*u#^FPV{Ys)p6gN7bP0#cUvNE1(JR7UNk0PPZfKm5y zt1?%ERk5Wh9b>^vRrwchfV$g-kVAjb;OYlH2o9&3S3(B7aQI1>e+;L@N2bD+)|w*d z=&$i}7l@5ZzN{=ocwomSz40NtkF6;yeC9jAC$)vp(Z$ixeub~DtmvKxe*092=zW_0 zfOo**?`a<230Kdd$Y;ER!~HL7ht;-<$v3dXftAE(W^TP%@>45X7PtafXdD@0PR@+WlZx?p!LYp|GdVHI!DeRbH!;FrQa*+L?v=LYrbk#)3UuV>jMc! zeaC2~MNT`LET1kduJwSW!gRq!5F}m=iir*D3 zHOl14kp)2kQx&G$8lW$`yx4vINklOU{x?h%YcGj7WX%Zz7gDP(#L4MWH*V{1T?Mw8 zI-hX1OI-yp^6#CdZ~ddfd*KF)9@zfvKus*$!wg;uK9-AZv^Y7l58 zUs)L~!Y`1Cmavy(<-aIR3945C#Q?xs>tHQ@ynX+rPo^vN`rF{r0{A&N9AigYoWk1H z3t|AM1{uSL&dZ~Ib7~Q{RZqoxr$h~=%Oe6gLzvPloA=JWjvB*Ad19-rM6QiV3~W@# z+Id!J|2D@6{=mlokLHKITQzSp`WOH;5BF1mnq% zH4r$Np(X!wKJ(CUi&FSt^o4>fvvhp&!^33W%wV+QIx;99;pfBg_>Y1$O7zIUoI!an z3jg(w{K@`*K=@;-^zk%9%)4cTCsFoti&K6N`)lRMUV+vePd}{n8sK~MEGS92O@CrU zIFB1Os+M>ID1V9djrF-zj{V|rAz6`Z_Kys~3kIz+<&knpF7C9i8z=oJ{cN(_i`bId zHMru4x#+M@HguVb_tmquRs8!&a$^O3zLPv_=H)*U0jy2tm7iB=J4379%6E(TDK54e zNCRc@lk5A5(pm972m_&CNS{RmPoor--z3VB($B2cMP%4E5iu)0p3?7NN)B!iWLF>< z7D_j&){4RS>+@7x?}9O{a}|!RZL_)$jhR)+X}3!~E);JSNL&`Ju_}2M zkP=LmT*_~t01sBPW01TlkR8U}e0vKtMu25wWzYu)%61LJhc>Oh)-qSiH63j9%E^vF zZ=IgH*2p&BA1)U8+%Ij}s++rSdbkeKXb(q=a3f`1vuzdUm3iX@h&I20g17?1x<)H+ z`L75e&I(1Y!i~HmDy6r`Emp@Tw%k`O$enc>81G+h(`b<#Uzl-1iJGfd^TA9xbK^Vc z=eoM%l{a*9XDdwVqmro9h1#Lx((Y{8a`!$G+rACxpp1p|g(^oRtNf~9DuIF0GIsRL z^-F4rV$;qCgfS!WNHD;&X>;5+4XuGA)H1#daEB0R(?j;&vBTNMP$P^7Iv+I-gw|!0 zKexDHNz`DryP%J~0m!`xx%RjWXi?OsL!83{eDz9O!*|QM?ZgyT^9lZl#s1`C?k_pX z&KDAVPvE3V}+U4N!QcgGN0ByoyyWDg-G77dH zcPBm6cKI|(o!ZLVffg<5Shgb9Y;I2IDF=S&Bd2oMqJq%Ivko^wdYdhO>eZ)$rfj@fy+G{Bc(-4@c^265i@bv2J?NZ|85 zm&FIpRVH?GuhO^?uSQjNn?l+dO%&+vnei#Si?OceM+d^{4e==8=AqV2?wwYzZ6bxSi* zLFjn=0t3~z^8$d8^Gk7sVHX5$WVuNMY-upLdV*MDqO*J4<~2Nm1+eplyK>V)kQ!xT zqlswcPzm1VgP1f{Bllgd=eo!GTfLd9@NCaqUVg&GlM#Ydus)wOZzk{toub*cL;&;{ zJFh5{y7H)=<5mkBp~MN0K-o8%a#ai@JpmxDL?KBToHkLMvkN92+L3oK=hBZkfs-C+ zQ4|tDaE@f}GXZAEAZ?G}2PHY$rS`QRdBp(srtE}j<`_BVn~W|IzR%jgNebo_SW*YqXF6rK2s`lEL{L>U^&vVFn2jw zK+Cha2sHc9Gk}z_w7FY(&lyC|oGD1Togfr(6>c9oI~3{rX2pXiLC2%O?hRkwg9vRq zrd}(oc-7-cmBLWQ##U9}_*P&6S!0t(J-jmQgeyXZr&go+;j7c}a3>%a@|>O8P>XM` zQ#lgKC!5WcJHzsJ-kgJxJ7$F1|10{O;@p|RgL)HxC)5sLc52F5PuB6=*UfD-coyq3 zG6efydp;PDZsCJal(KWYV5Nx*DZRJ`!((pistvaJtn^0P;!k8*fp+ob7I@9-ufcGT zynyJQrM`ac=PQPyd9g!yi}%H}WG;MB#4_c{i2=fn#5=$lnHf9h;$61`8xvA0t=w6U z-W5f8Vg7Q%yy5*SprQxBWOeZO(lt9;vHd#Cd%wepo;yJ=*HoJ+W)B=QUxIkOmg*xD1= z^g2l2b=&4O|B$w8uhsVq)@ITLipT&CjT%mQt%_hptf4i_f7d9sFk6rX@A@LHwWqM! zjI-5@kAzO(8bGkHRquwrvFwCr`$&(9)C5^qI5_7YV?&p%@WL5u72%T1p)?RsgopGF2+|{T;`5r2}ut&MDWu z5Y6stO%hN8NzLyY@VX!Pe7G~-|G*FYl|Y1YN|P9_MJX)*%fA1-BfmUjfBpl!JOkHj zHRhOMN{vCw1;0mY7R$Yn2OY_|rqIUst}ne2VWq5DId=KOL*EJ)Q_Kt>27^4X#tad6 z^qsdFHgX_K5+?)?26yEQ$u~iCshQ?ILCDVVLATB6pxpWh_3ww^P7v37Q=$>{=$IB} znIz3BD9#q-sWAj_Q5rNoI~PZ;7IW5>eLwy~!;<{!B7S3#V8b!>Mj+xg=%Qv~x|CA{ zqrt#`m(th(&~zCiyX)5jI=vvKgd;mbaaM%n9z5;M#$!@^5 zy7H6!(94|CKuA=*1B}ra;TS`^(tVt^spwL&K^sS_jm&kGr0J_rAEE(W>47OrwmynJ z9Ia74^7<9OkA$Q7QFz#>n+N^;14}SEzIK+*|E}cs?lEYFRcZOHPKVQD9=*JAQt#D0 z)3-ps6~fo;8{_q?pB|r7EkkuQt9+^)`}YFAzJRaK$bWtVe|`baf6Cr}&Zhg5((<9~ zgH~1?c~cz0z2|6@agP#qYTdzi&D^B$d-6>!p!|r(L&rD#?{`^zi}sigYSX0=Yy>Hs zXzp}&UF+>D))2!{#l0JYwUjEscdJ3KReEoAWjn~IzbEPh`9{JyH6G~eW`w8nZ?@Ip zUeLO+dBwTW{9XHC9a=+03Vx_-jzV_$#QxeHLuP-l+?dMw2|4e@-P0?PwdVE8dEsll zs{WPRw31DvNlfhA*J2P%Zvb$eX0F~Pqj_MtZz2pxr~2bm##qVl`^wwr4t!stTo)rv z>j6;E?|eQjpYz-Bj)H%~Pr3DJnF^#4Ejgxf^NH$Q?hJgBIo=roO|S>l^_%nv)~v>W zT@wg>BGjONe%`4uK$0r$9rlO*=L`U4vfAU)RCNcCW+yJnHZjy4&;+DGNyD*@bv=X? zH{KBhI^)OD3?+kfdg*A;VJWo3woGaM02+Ejiq; ze{pa!#*qPKI1WdB;*|gQls7u1-h-D9oP^oDJH7V8iNl3eeCYVq1PBdMA8wiYP7rXS z3kLbo^?5I_aa6`uo^if{ug}2qZ{Xz_tjfPd{x3X^$!(z;;cHO*eSENoq4}M00(E)~ z)S(F#Qef_InE9Xe^WToEiwCZWqoP+m;}*y(ki1`f&{GAdthUGVnXblpMyad$S%MMCHFOVN=7Q9m zq%Im8Kc ze?$F7WAU9}V2qr_jrbOze1LOpcFsllfB6Ia`EPOifB91)|EuyZ3sJ4-=|C?Cbj#~i z4}m!Y1-CKqxH_MDBKegzH3B$LS;svX)@7LHgK)2_W9Mn`Cc$$ICvCgMb95Chq7nLH zDzho2_6RDS!y2G&Mzj?HoMotI?qU=uN)M>!rFu>sCs98LK+>Zxr4AcO&^T!$BE$2|i7?-OVK}b4!H*o&>pRVPr^Z z@XMFa&WNUU=dwQ$8q_e$YCM2ybQ1%BDYjBSq+0(Vk2iy9o&-+d){Y>VShS&d9gryh z7cm&50u*#n@+19GAN`#G)eMtDEO z8E$1IFN67K-FFjMmEU65G&K2bxcwDir2MN)_I+B-4G$r{7We=C8Mr@IG<}D7#gW?BY4+^h+cg5}ae6Ywqvr~plB}|^^ODuG6V^%Jgr`b=jl2|tq`w&i zqeHvieX;KV54tUpcSM*H1TZoMMdro`&2@m$s|bXN@=+^m=v*~=E& zW_qKCGkK_1>|OLnt3y}}d@rN(XJN^u2$l{}y<%U_K@xoCs<8W&sF}5lk(Dd7&nTw-&8lUq3AAsT}&hFESBMp6t<&Ns|nz_-`Dd65wS%Y_q z&OUP$4TuHbGgmq~@-`Z*WFBt=h<&VW7+h;mK=r!uh5~83%@$^teeD-gqZ-Rt>0Bpv z>C~X0N^BN=Typ0oN}we5#~J$ep%)OA&KqA0p69g@46fZX=H1=;^!DE}a3&=!QV&O; z)ClthgvIKqCHF@>IzGRH@N~EZ;JpOFdxG(_m4t}GL`cFuWuIn+b~<`g`jYO7hAKDe zwbiJb>lnASYlG4;y%kwS=oCpod~a78o%3H{j@}DKUN@uX-vYd0){N%GvySrBt`p}H zdk4kijya)D9<{0L03_0P~E z#T^@b+a56c==L&36JZ5}(JsyV8!XgIgqbxeIGO->^*zKrej5vV(|jeTMtFD6<%WAC z=<28V5Di4;U4T-@_6%PUT*$i@lbCj0)P9ZPZ)e352=dGs4r+V-_&Qvr>Z=eL9$4D^+wVF03ZNKL_t)^$?C_3Yc;riivCaNaCm0$8C{PSEu;rv+XjeaTBt5? z!pr^K(!Yt(^ZUVMi}^c4IR-G1DOV%{k{_rhB4V>DGZ63*9x=oA{YHIZh!|ZWn1pKJ zCQW0YQl@rs@2i06pSPJ$9Bolc&^SJ zqs-)t1B2>&knV2OIVa=>K3x|M4UcL)%BKad%njV9^OeXbLPKH+7R7~l)S7*?(6OdwU{pwN-C?`Cvhl(mX^ zT8`8w8jdBeCKf?scx)Qf(xO;}Ff|S5RNp1R9Ael$_~G~5KkMX4d6Bu@Rzr1_3k-0Q zzc40ZxR|COI7 z-h?rz?+O{xal9uO`#h!*rTfpzrjelR4R<#i4%b>-=*EFe(V)aij&JDaI}cIKH_X2~ zms2S^SGmRLY%R+5BCs;H;R2|1-cZV7`KPS^2;2;JqCEM=#I7zMFTn zi}K?NaRn_@t9j$6-+)Ijvv|7>#+01tD~_9$Q1O<1yG>4z*aV@zoJD@O#ZIk{Z;_i5 z;)SOgMiqDTYGFH{H#C_M!OgK#oF?D!dU3>uqHzNdofy>+fk>@h4@&`a<1=q8za!bW zB&T2!5mF+N)5^na=S*|E;;(x@O`r?RSSy>a`a> z>o@X!%V1+&1ug)mg>j=W*#j*!Vw4%!a~;#1ji5Sxp#)wL^}V!zg6;bi0E4zC(4`b? z=%RrwDHZE22$Z(6GLW7?+XhY-WL&`FuBBq0HKIjmX2xg70@R15$`)+l&)-LJ^|Gg8{* z`^{Vi+kim?U~30pv?>qr7zFJFjp;wpXVR#V`IMYfmNmZcKAgmN)%_&J!ESvSSK8IL5;`2$nCgIAt5mZ^b0~6Q01YTXmY(!WXW*Srvo{qc|BoV ztIFUVg-Za)UUn-C9@PMtK~(4haRTkFlGBWFc>t58nl5!b%&rLJ5N5W5oq1mi813fu zQD2gtNaX6l_A4}n3jW=-vx5RRPIAMseMG<}=djD8x73z63qMx&Q)p5R*`c-9c~tN} zDbI5?U}a~%LS9a=3Nv`C?NFalk`?}(ckuNJFk|C?gYti|KffS9zZAZZ*-o=9Tlt=l z(=NPy1Mt++9u!=><`)qu77$DMkeqoBC*yd!sC=LpD1>LpX;eyI&G4mkRr3&?$!M|2 z;$Q|+LfSSYS8mQ3tbZwiw%YFzY)a4tyN|8o_%WGG6k^9|1`|4Vc>JG!qx~U42aDXN zyw25oq=TBQSpRBlx^@du_Oxe9!}?f#k7(`e9rp(5VO}bR+zBo@?@i;g?DuRcq0p>U zyL8ew9o(6jd>?oZ6>-+tGC0c?G)b1T2##mzXsJ2OSxyJ=iWlC-UHk;ex|Hy^iD1kT6oz;M5(@*OdTz1JS@B!PFW7c;7qa zU-zFCUg)%C)3CY4op%J*Kzr`V`Sk%fLt%ZU%t;AxFC>2yFy|tq5S2qYa0T%u3N1iX zgbJ46g&DGE5M|Zdj2Zg7UU0oWvi9pPgtM$WZajIu3L}~aN2Um7_tHS6_kfY!{Wall zrPF^0ME=njYRkoERO@#5BGo*EnNs!^NX3xbh?HuWOmO3?C&`p&*`__299Qg~d%p{nd#e}Mc8xbDEq)x5v58qB#U&2+hU-z>_{+Q!kl z(IVzTvEIlSjc%6TYny7aoyz3O+!iN@$b&=Ua3k+wvE7pPp#0C=y1UHX?mR6o$Sf2{0BdsF_~vCxIK`XSJ){!bMD9wM%L1|em$ORGG*S)$hY z>wkp~P{rXA(;^9DQT+2&QMxd$Yg{?_oJ?XQ0x1tCxCoAHxt@8Ulk%Zzb? z_Bx&j5@W+0tsGVte{ZxT`)+jhaqE z{C(V}*XFSTjgC8O(`UhfLgi^qzB36$;7L)-;Er{O>Sp&O-gmunu^=fxe$Ms>xky62RklZ&RJ)siBAv(>b@Jl!XalgWb@pp0mQ zcY}^%v--8yU4APF`C7&?`^GCE@w9~|UB41K2B+M{GX08Y=Q}llJgUq9;&@C!6*^xR z4B9q1CMe<<0~Xv*nTD;7rlRaoDsH#($F!l_vhdAUm4@@lDY`A8wg0+wmO#c#Us0FV z;dQ(Q;M7($VVV>dG@m%$y05;;E8aTh(isJ~;7en8LYo$~Ju7p)>)F_UPWf+#fos}f zU!9bibU&Wo{rb63@yu^Es5L87)Ynyy50ob=*r@BB3Q-XUk8riYH46M9;-9AD_7;kn z3{RJbxa{axRQ5f;Xt&bD(JJ*}U1>_G$;V$ec{g3aLt9BP3M^{ai^)C(WE_Wv%1$_Z z)JFWk5pXkq0~~quoaJd*^g)~7GoanbBkm!M025Si&C>0&X=7O1jgr;=kk!L* zrmx&Q#=W6ns*Dee*}Yz}h|?jDn3us6@`fmfA{bs51-(x3hu{q}fB`KpNM{1qO-h0pI51?tnr8I8 zkLtW$?7bm+Psl}^$j#Y@QKY^pJW~HskkNQ`0VBZ31Hkr7uP9A7^hrxLW;pvveH@j4 zw_5(bk^WVUcKk`@Q3kx>*gQc~pbHWghyf&Ak@$+7GxENdZD(xZY71XV3E&qXzW{j$ z=c}yvKLgi4!1Wm^@4&tn#lDH;PZrV+_RF?_bk}Z~;9o0mG%uQQZ1_wRtB%U`GQQ#| z72}EKx4yiwf06-zYs@o2rh~bR~&f4R@ znOc2bQ&kia)*{d#p-u{)WLE4-b(BC_MWSg;|KoK7z@n0K6EpM1A`!ezi7^AnAip@4 zVu>wEJ(Xht$+<`+Dgnl}Ct$mXM}QiK3TZdX?rkmjnlLb^L}8mpX*G}@!Xs}rW&m4@ za%CR6ef>(mHGKfmyo8pN(@40c?u*eB>84dDjFC<%e?` zJE~!W`3mG`@O}lZFXeB4F2SKW%aRd`9JwKpZWAoK0hFE^H=>IvvB&$$ln!unW$W4?L#ZNezPyDaXY zrk_V?us&hN|3qUu;rMG5e;{Gh)+3Cx?@#1+>)D@DXSce}#aO4tWR_C`2uZ>Lh#=w0D8Ke!&BtiI3IvX6QG>*q&^{+K zO3wEE$NO99hA-DE2jzS6Zm&8=QkobOX8HQZn%8Rm9vvnO{0F`TkkYghSYMp^!IvQf zWoo+b`QF8%oJdkUTKA&3=PM{*MRCudyrTs2D_)!_m0vJp-!rgZv0tyizJvK0d%hO_ zuKF*BfNBwewqDw|v zsbAd_zwk+v7lzs1&=xb`0ClTxHkp9I#R2oyDH-s!EAthK`C+?0$pHFJCbv_#v_}|e z1ohAXLm5L)T4(n@2v!3@eg@0PrpkY};uDMjb{tT!0CWS~yI$VxirH2KYB6NC|AIgU zfT{tdRPRg?J1dq7u`8rjYT~Sgqt&b!CCJbbw?Hd zjU+IP9G94qJimZ1Vhl)^)=1@a)$a!~E1P}}iYFJwM#$|DH^u>dnC(%`&;44mc3-m6 z6?WHMK0w1XP5D1qJ>iI#6!2vPtgI>0CH+rn3Q+c-du6q)cBwMe&tpAfef3C7=?9yO zv4UotI05N*7CP8`(#-DoVw*ffvAxrq?unUI~_jV=&97XX6^@ zgSO>%p8O%OD)-#NyMEwpaPQTwC0q-qyEvZkrY#8p-}@~(i-uR9*9}Rg@hUzEY&A4K zb8vINtdzT7k+|#w=X@H$gws0XP8J60((vmAd;T>g?Ar3cg?+JlA1*3i7vGpG6n>4M%UNu=k? z^mLM6n1if&o@WS^JBw^t#-ar1&T`CP7gG8d2F5DuCp#r-5lKCNKPt=8fAGAW7(mCX z|M#1imzY)8)Y+<4P^Mb`d_N(h4}uU0SXlYN1i@6%h*mnov7=R%8|o{6Ed7$bQse(p zJu6%a)dtoUSUpzyF#~!eU&^q(uc+Z%_!c2*^~eqtT36~9+-wa^?Efgd3Q)gCEvHn@ zcumEMYXJdMi4@D14YZ}Q4@}Qk^~RX*DooB$B`VHQusWLOBL&RfxmOK3bMxC(FDfKa z@kj6mnAT;LrAVBJW`6lOLQZK7`_xns?b_iLJguM0zj?`nbnbm#X+x}g5Yj$dN%Hi~ zETI0qXXqjGU}&pw)JH9Ev=83DQa|wF(C`iBe!e?9?u{A0 z4QJk}1U!K955Q!p5p=8B_k`;U@>TZY@2dPigUuyhyaG5wUENvbHlq!>%A42UWknyT za%4jrg_d8lDe!=t1VtM}PzEyvW~J%J`5pA#7x zS~=2bRv^mlGeh&L!bt!TgEN;gG}*1J{3oaazqswjDgPb5Hgd*Xac3!$h-BAlq$T0o zRh)k-Eg1q0niAz-+`ZgOLG+qwC-ls&^#K=QyW5UV_{@V0Ms)eQ4{d5EEKmvO&S{a@Nffx52)0> z3kt+^p3jQs`mHOcD04@OQq5+`!^RtF{M?9)3&BPF0LmV0|Ddc?m&J4?R(oZ76#nE{ z#hU>=;N}4^z_;+YZ!Zqg0aa0qjA$ryjObr@+|f0c&XV{O8zy7d&{0M`QdR?x%1S@i zS>BMj446kpB9L4!t)h(t0%!DX@y+o&u1u=>2vh?_Uncim>In$N&ei@nFckRzjYo(9 z#Fyc5jOC%B*$98cz||=FY?)cDhCI?`7x-mdNg=Jjk&lV@!>HdP9`YnXgWCrJ@5u1< z7T_8?q@UaFI?la&RpCtnVEFb`dClhA!MnB)RGjtO0Nbp}u<1AA~vY z@~@EA$7&I;#w(4Bw0#7tddWgUidPhd(uPaviONqwaWg}zmro0=A$M)O;Lm@7=igv4 z0C2w6{rLM{JOc7=6=4XQ5Z~SE&csY`fIGP3AfPuJ%T7MC&a$!J$ahSi#$oVu z2?IEjRcG|-MtEKD)G*hs<+Y{o*)2cyg~Ex~wRN5ejYGa8Bg8eKxzK@h&!j0c#BQ5L z5+js@l64GR`<9vd$rT6N)(fSxHJLTqXkf$~5rn*^%pt&h0rN%kQCFvG$CQ}s5K!<7 zw6+io4D#daySirKWTZXLi)(sWz znF_e*TrhY+rO9Ad8*5#ZS%lo&H74#e=s?$H#6S5PW<4rUm>RaNK~6vcKWeE~P~8xA zLmzPzguE(cn12$j*(}%$taUn1xh!ChwP1m0TYLjQJfOs&uRAc&?&oresG)U*>dkD? zj|+ghUP8jiSFg?RcvRkkTPQgHv&scSQnI0WMg`8a`=V4CnVkx>&m; zP%lvp!aw}CTk}M+ohnu;2x~4}RHez`bP!jWnDU!hXfGxDtKhxh!9;s}(#!BF0B}8o zv63QC`T`!=ztk_gnpY zk20ZF@t&CRu>s1mcx<5dY3ABw+wXad{Y6dN}CDuHr8SG^#L%&!W+|tA9yXiasmIq_kcwWKv~ep z;D)#8g&R*pMmoq@Z}G1mc9Bb7-p9+!OWG#p&p&C=LbF< zqGDq=-4)BcUmuV??t#qDb#rV6TYSz(!A$Wmf!NR9zRcI%0G$G09-aHXjNc55IiJAj z=9%jpgi8CHTD~TqV$^TP4qE->9YMPGW-g{PrBQAN&(fBJTek4r(G_eio3@pMv}7i+BzPN>px%vt z)=1>4%<2+^|6xu9!QbBHHV%xqDKYi)VEyo44i}x0CyaZQUl|U{t=6ohKJq(j+vJ(I zF)AR6TAqNW?7j`++?dX(SHh#|gz4~X=vVfM;b%6{Mp75>Uvj~451)a<@ zt_>oRxD4@=@UG(D~1_%{RgbrU)<#U@-+`pe&0;>0oK^P~5IQQ3BPGV72D4=Bn;lk#?X0irRmW24&w zeHB6G4Q6iwlsZt)>Aq*-Y`T~S%N9ijIE@o2k4h1#m;%7!0CXM#a^K>*em@wkszx{) zQMY5%6l}FG34jzV`v8uOTlk)Hx?W)0vJywPyH<3M6TA9kygXCVxH2QwAq$WM3|qb? zz$y$Yqv}Gm;#DT!DVpjM_q1P80L;KO_m(?3`QQ$pAH})3O^P28`qdfsNc>&v465ps?E*gHOW$ z-32q@|4rIMhd7SIdNSH}5AX6jkX8QyCtPCX$$wM`AlX9MNJikTJfG?j{c(8_f&cs) zwEh9rXMkV8ID`2Kyrygwn&xh7N!3!6#oUk#?uG5f%Ro3_)pg zIzV}-J>^bI`Je{G?8f=>uz-K>1w`{XnDH;qY1zGS>X4#de`etyIM@L*rqga`9smgM zW|M}4yG1T1{8~^cA{8b8*uF3ejZzC0LDH0O)y~Cu{%LaZ?Px_K``8RdB(s^Q5a3a zM}Fft@jEG7Rau=WBC4bThj$?eLMsvcy<%_ zroNwji?nsa|LdgFKCe9>bd2rIL@2p>rhp8s8nKTZj`VY!r-rLSUdGJ0w-7Mk`m8XS z(vY3|s8lA+#Pi?yK72bp$C=Y^^-keqeP{|j+tMM55K_fS#t^NDI2W#@@$zE{P8^>A z03ZNKL_t)0**y(l+A=EG-jXoF-u9z=fI5XvUq){rIK}|-E9&yOAdTZDY~Y;l&<8Vo z|B-^gN0jY!UvX1yio@o_L?}4PS|UbeMiqv(eFw$i>$6z;pZ|!}|K&GmeMYG-C|E&- zQHimd;Bw6>+)HtG z0VVzlxPix-DK`(o-~kXypI>+PAGmO4#5`Gc#tu1%@YPz>AuJDAl**qh4hrtAR0&`c zD8xd-W9S~QUM5O3WzZ7bM4XQ+0DOP2(FeDpabU1-6#fTmLr`!41M@#yj?CPm{u2R6 zf!Ywf0ghM?zbH(tT5buI-)8w&1pwmvA;bA~uq48NWcM|Cqx^Y`3J}H%<1zZ7XZp2{L>LUHnn^Nms(XaG=zm#Q z>8@>LDPa8px)l2Z5a+hx)Dz9@ZLYelUL zi=OYalp((_{{qkd3%oo7e?$?$>ob_o;u(Myg{s63Eo0C=sr&?YOXF{8)G_FI>)Z36 zdBV-$OKmyYYtIJ15$T)<;9Hii-CPsRGkNMQ6)syiUd!Ga^N$^~9w%|&O|pF6wILdZ zBh-3`bbY-bfCmO?YDqD^{f4|c%llED#-mm%16I^6vJ#kAa9!0iz!=|vkkGVfqESP~ zL%#0>Rb&sVqcN1NuIQdTuv}-JW%4^S9p|}Q{xuq`S^m2SsB|+k`e}iVwS&X4lbz+? zqaaU&Bl)oZZ7)LN{2S6RkL&9_Aj}N_;rO21p7=|XYrWzcJkxdS4sjD2?VBtJJp_7z zyZh~4OoYN*pE@VB!;_#j&mKpX9JaN0}^#XCcgYX~LxzH4g7EKK|cFM4XTROpCb1}xm|F<=l zG)-V2Y(e@Iu%$Hn+bw@HIJ(@vl7REBFk>_)si+)Q0z4LM{TC213R{gufhf3R1)a~} zRjvPOaG_!b7Jydgqzm>$-9q$h&+NeDY~MV0-zl+GwHY; z20-{B)r@vZfJyqy@S0n?F+;lNnn~m^6cNk_VXv6gnV@^Gv)~%9gdy_xMk;a> zXPg7_=W;dkW2@)mYh$d8rX2}_5G$Y)_D$Lio?x<0V8O+e`s7D3QAQDiFYV}2j&Y8u!4oUN@Sedb3`a{EpNoJX(9!P{qA zf2m`CKT9u?Y1h69{^}yhPReZB$qM$+hdySBUNc*X1JjVwOvn9 zz#-FevXUYO){5^;7}j=l8qB`ZeE`pPJ$Ph{+5w=dw-%e%mbQ{PoTY8Q)Y=#Npc~)t z-j0FtI?@ILO| zhcqbfRF?!v0Z60){%Qr+6o?T`Op$=i=Xl(oUk5<~Xaa4d#}mu4 z&6Upbm<3fr6G9#Y7H1;6`wzzw# zg7~K3KL37t%FCV-#j7^Kl|k#@<(Ki$Ov&t7brZ04f#P{Gh06gr6nrZylx8@S8M8B{ zhw><#Mq&bWTm>#*?=!vmv<0g|t0&S8wKd$$3HhTqmRax*^u_B4TW2l*s5Br`01!mM zXc}M&${9;<-W0bkkN4m&zL_xlaB$uR-?ESTbtdp|=Ks@o8+YSuNAdA`0bgE#^D}B) zL4Tfs^I7m)A>h|902NqHf{rg0d_Du0->L*yMFGGJLUG*4RNGXl8y*i?IPYGKV+Pzf zZX3e?U%&T%rUba6lmReJvwONjm&aol2pP@2aUGAx>V7ozhScpjdLYih4RGqUGm*=` z29bey&xJG-{sVJkmVam9jmet`0hWgem(=cAl>o-8mQobCSv9!lSA!;ui^utgTSaV?GAsWEt)~Esx1;()qL2zt-AL_;04iR;L+Q znOoDu3MBH&F6wn*6~v;DzX0W=zvlX%kGR>X($!Ln|btYAC)JQtn=28Cee8siuYA)@W-_!h%soM^+@&>ZxGR5sK?NM_f-twjh~S#w$Ye#l zt>2N-2ctcfmvx`dRWHNVKcgM&X`%4aRyY&>^8~WBz#&ag5;W_-{})Na4!;l=j(!_( z40(RMkxzerI7;^(6B`uv@5cOXDJJjEE}hi0NmnC7e?ytBD7lvIP-bJDayi|7oLDrz zr<4p6wBhd~UXuG(JcTJSHss!^!Lxc#!D=0Oy)Gl;xG-!L80Jr$+cC358;Q`44TbDX zWjQs3*9yLzf#+x7@&f+z8@ODAA3ZG~T0vMr%SlcdxvZe`1$_P^fdE$qR>`}n0zhiN zXj9j|Q}@;Yjn{^nx-L30MgwgM-yirq!+0d}YvJ`~6K_?Z7xRQPzdlsRr1N7rwaQkr zu0rv1<8i`wT{T-j7zVEx7j0Ru^9@ikhjZLv@DFr{(7H z>0fb9st-=I^p=i%?qjS}zNg^!@owNemtK^U1nwe2$B;$F!anT2g&;Rx04!anTCfwJ zf6S;9qD%vu$V~QKH>Q|$kEHW}Mb1v;wTd;R6!98ZM35b|(=R|hw}G#d#lwVBsB5b6 zb8W%NFP{J|VMYWV!VPVtVWcdov-Wi%5@O+J%2$+9QHW8wf_e461Gw|br}6}%r^$f! zP#_kp3c_mESC%(eo&fqKzrX$;=%4@0Gx?Ccb$5dGua5_#xjnZi-=y=DP+R0}ma(8< zeP7ozxW2$OR}o=&w-C58Xm*@jwj>jD9~k!!jf3zU)wg62&ihY6VP4pGhS$0>VkI`# z9e`p=f-EdtyN~O=Tg#;%6D|_J!<2IHyEtYvr1;B!~ zaJ8P4$76*k54%S9znblg;YtHAX_(~0>3xcc2l46&IKj&gR_GmpgNY^B=M@Ng$$cQ! zzvA^^50VGHC-g@Y+E__ir!z(%s4*k*MkYre^;-AN?lKLHrW!9#Ak^CCgem>(gcS7QTL#`a6{PVjWO@ap@8@{~dd@1S5DGO~RBHvZTJo~8h|`~gG5!qk6wr0RRRx-= zOg;HL>6q8d&(v8&h6zNaljc8LsJvDeSgyiBX8BDl%Nu3)!v79qZ})k7)?k@asO!c; zqI5?dFm4YL*R&0~fLnDWmJ%b+H>-1MbJyPzw5}ZBPo=yWZOFAgC@>X``*f{bW)!qN z^D z@&f$#f5okzDhLJTQn2td=q2ETshO{yyJ zmlbsdsLDVyNNJoZ0HQ+0tP_q@TTsEND{gFV;7y%n@+Kxuzf*eHQ)_EMJYLTkTxHnm zTAk2TR8=Z0Xe6J9oR2`&v~2ro%OV2*qJsbF3ACKLJxAXLO!!CqHOqWMxXi2cCL3dJ zZofe}V@NnlMl3?rU3zEUxSrj=5;B6`JT43e1%ulwpzB_}c1+lT3E>Ye&i;$zmHRs{ zrJeD}TP1$r0L*B{(NFm?dwO#|dq=0H2mP-<$9|ifStFn@sA&1>;nMzv0FXd$zZfDh z20#R-nfm>Mal#LLV<0gwjE{9|;G+~Op9GkJRTW{*lbT`@@HI=z30MkjYfZn!%7l2p z71yPxC065cD8Ee0f>K2BUpbz@!s7B@FB-t_43H`l))maGCjrzZI0pXoEl$FDB)kHp z{{S#30Q}Otmd#*1qkYq7<=BZk4~C=k`IArQhr_4<*wX-QOoopF*DRXQ8X4oRejJ|r z$NHPncL=sCt$jR8qxXdf#WQ6v1-E~zFB7nww9cZj^%ww9ZJBKsAU*ERG;IK87H$T~ zS*=!AtFG%Uf>aTM`*BNSN`nIGg#YgBY!)Kb2y^ULf&`3!` z@ys;6DtA?LOdfDm>rx}GX|ye9t@`p_3%UJo!D}4T=l{SvfybEuwrN8UK;w7zdk?`PAbh(fp5dw~%`T0MNB+$^`W;paqpywI^vm))iP^z!#0= zUta*epgXpdC2)0DqF%YN`XL1c z^vCGe@2hyV8{u#nA2p;qa%D*L&?4s^0M{7KPXS>ON4)2XfXHN1`p%H822&}^YsR<_4kghFCtHaXHq$X;y1iWdM zzBZwz>hmb)k=8#Sspm-ATw9GWK>N@<1sKuI(}i2I;}Nfc`qr3d#OVa`zbCmTbHn`x z;7oMzobbNWK8E!(;1_o6m+keB7V4%gun7eW>!7!)Yzo<%!hd?Vha)D+xGXGf5rXY{ z&Fi=4DR3MDk+MY@PXVyLe8m(Tqq~PPv*14n(UU&O1%LQ0T38%6dls21PE#FfSGdVDB}_LDBjH&&6Go2!Cbv9D#kA>Rd9*D|IP-Wma^!r_>aGVdH*6H^RJD^Op%raxtumUxVik9OYrR3)qIZP zj-@nLUS}5D{(Q%gtk!?8g#OnVcFbTCkZ(0F001c9N?6S`)RlItSp3&N!1=cZ^m_(y znJ5z`cqNUOJm%rq6r#)a5#Hh6wK`EI=6Q9K@+k1h(|Y3AJoz#Z`+vhjNBR^&78%#F z{TdCL$KBZAPaXib3I88Bey_x1x5A(Rm}fV3ZC~6{w;qF*AK|>(6HT9 zlx>u>V;)(yY3WNGQ&dhW5a`9$yxn^iY43FfLYN@(anF?dH;Nyafm&3q2y2>Kpi8Ll znvJ0g{}InbR6^v6VE0t&6i>$(n88bA!nFUu4txfl?A6esU}v}grij`XF7FNKwUz$O z1v%sM80e4cjcefv;3WwDjpwu4Nua3yS64C1cL%#SXf#3{|u9y+4&DJBv90B zokN+O*_&#JR3`5Xq4e%$Xp=M4BP&H3^Ggk(J5KKxil=s7Nhco#Y{_alcZRCMtt_$1 zWocSqb1(DzFlH+Oq!C%&s*@V-%w2C0^V1a~e_Ulhne1>NWd@mNinwBIGZzf~ap{N&CEp0!n5EE4f zM2>X_tk1Qcf;ta)0Ca15F8FV^VPwcUMmnUi6G4azU?&SW?l3y2-dh752+V(LY*g}%kI)vT zEmB6eSohjB6E5OpWmbeu!c7ahLj~wi(Vb83~E;LZ2d12 zM#t;QO$pFCwXc(3>vyK0uzFg20{vLL9@>#vqDQFVl!hx{3I-yfrWF!tHlM<9HvJykj)ee+?zh`jUVy1!fajc zi%mght80JK+>F-zzz#fCxil&OlD0Meei|1Sj*N#1+Gx+Z_vqWhF>O==Op57lDyED| z?i071Gho}WsHJPdl$mMwkv5=P8a-xTYjgw(R3hUgbPk%ZLa?HP{@o+Xo{;n(wL}57v)GkG=UKjQVv@1Zvt*^!xu? z%!bm^yVAyfGl35CD$Q-_Il>X^f2basq9I>T@&K+Y(t;2+Xp<9x-gRZ?oiukt$eU}^ z=y&bAvz*O-w(-P#=oqQZSH@$S|HivV0{edt%5NJ#_i)s0KX$OJh^+Uf*Nfu>P3?-~#K5rzZq4}x3e_vo!#(skFw3W!qV`4w*_Kj$+TtH* zuz`!G@R|FsHDYsHT3BOy@d92W%x!K5eK<6uPbsqbrqBwiO7qu?uBBBJ1H6jxw4TB1 z8Ms_f*RveA$3dtn3;6T|KK}>&>mShRA5d9j=Rjr9%fH~4e?{nj`3=17W^B6XW&7 z>t-6qW{XzMZE7Tq8{T@;&3oDh63CeYv=oZn>YYI zpKUyBEJ83pv*OuSkZyZGR2JA=9JzHO`1ZkWN?cjTmfn}b>=PF(_Oa(}2(0Z1of3_# z21Vc}9 z33$a742FZMr+qa%sy~0=>q2CRr>`4-`beJi&4sx@FXc>e25J?d{_+BxU%=}Hw)$8V z09ao{0kB@cmorc={hFf!loQsM-{4>W0X_W!l_%jQDuDF`<@^WrU!a~rL@4DX z-U3*_-S*YA20LR?Fx2>?>pZ~LGv5lZ@&2wcx%SN~Y1MZY{s9P`**b+MDP?Bz;ovQB zgtom^Uw-N_N;LeP>Ux^cd$`~VAnpTaV+BYM#B|^MtdtvgsrF44stwFSIup9X(Ot@z ziQ(L(=2n@W3krlL*Ed%_wRw20!dp}rSa2m61200oXhvD~{VHEI?j4QoLa3`L6-rxt z#hy_U+yS(h0YPdA%&!G<>I84HK#Sxuey;?emXY^s@jQ4{=8#svEzb5g>o^1ip=oMq zN7g_z^MwiuEgskAvjTT*#b#v*wU5q?Hq8ATRif9`++Iic7{7>L+rS-hWJ#Dn4S7JU&EH)B*LU$}lO;(c2` zuKL748vxe@kM&JOaT=>g0B-L8jk(n+#5SIj9j_*T&X6&btWZyPta?VL5U!1u#_U;`p%wgvjwAF`XYxRD(SCIS=qsZZPxit{4D0(_x{@>O|JNM)9nVgL{ zkxk1+0967UJ8rn;6TkO-^w&|vHGI`&80g>xNYmI+zRVTtdIn#ff%6~m%OB9o3$UJ> zQHNK_cfE+vUoRTpL#_0-?Gpsx48EMPUe3Vj37|#mMp#hA{oexq)m68SPWE+MpG3pb zpom24E0XatC1S)MmamPQ-0pYi)l&oxueU36-{`TPR%ni8mAy`Si)W+;KcJgMQp-c+wKF*T3U)d*ro04>st;X;>U|0!~Y~H-;$X z!?;SY1^T_)CaewtkC@Pu4cZJF?6?ngs()n^Nc7Tw=f8gt1&trsw@p&Rdgt!7|d&wnj zr+2HQ+yeE6I@0eddH;z*Mwnj;h*yr3l(AFa3{WBPn(6_Dm?B07Z5Z+i@@6|LJT$ef zVK|Z|Z`=%`FtBRvC-n?aFf#lzubSqXybs=YylQ=hb`)eV}iizU&Jk-d$8&nGkQ=04^V-^>B4|1001BWNklm5p25$5z|X&dKmP?@{zbVwqtr8~uBa%|-YF1_h4)gN-d51%Spxm}D?+t7 z#4O4Ih<89`))N5EEuRB;s6yIWA}_bDa)J?STosF>6Y26~ep?;s$Z1iLF7Br582dR) z^D+97*I?M<Fk>#gwP;r{!Ilm9D%;ah^lNl|8wY7qQwEI!eA9JP!E2CG?8se3;E4hNCZ$KZn> z_~!6dOReMe63+zO!2d1A%D@$gT$^F2u41$YuyPeQ{`0d&;eV0$EXqZqg4djWF{4-S z>ZKC<^Mm+5%OW}>?z>)df+Okg@yL3S* zAdlo3cV3@gA5PP2%@gH=br?G$*? zyFd%*nr2AMzEAC&Sp6DPXcNdH{tM$MTL2amwc2`?lYSwruw&kazIEX_C^#V2o=ri8 zPQa2*APDYbWY6+?-O{87U56+>+2b*gdMKcZHWX|NsGWqs)<+gspf)85Q1p01JqjmS zr9L}QH$NK;tHT6-RNaYTf(N?iGY#k#MC3k0kT)>_uSDE$Dl~7D7k?j*cX7U9-p-D?PRYh(AZC1e$jIM z5p%*V2pm8Rw`dnLLv}wSOaaMS z=JsE|2t}UP0j<;m|5bC}C@}-g-joTH-faj%5#hzUWG2j*EMvT=gd~7WTjh5_*^J*sk1euRFYL?)GHf30y(7fa-!3 zx^K-Ipf$6y+HbtwA{ zVWRMROGUuUh5TN|I0i~HQ7*b+nMl>9Q&Oe?gd8GcwVe z(VCm)U!*CzFVMGvxhEBZ@NCx%-_~R0V#7)M0qdb_(*)nxEM>BIDy?4Dj)yZfw_1-n zg>v9M-gvG)Y?|2f=6d1pqKyS{zv`LL0{DK7@TILv+L^(KOU z%;&>L`Ib4IzRT@8HD<;VN5*C+v!ewYBeW;{^DS5|3;#hVW6v?+Zk1cUM{6EZ9ZXJ*>&((XlZ>!!{TIG zT7S4Q0?x=<^F?q^0iB#F4h>}sMkjqH-v?%s2tw!zaIpa>ZQ+#yR(Bf!8ra4Z84}SJ z<;fKQMCFFL@`1oXT+DN3hJ<_$hjEVmeM`Zf^~SfiFf@nZx`N_X2K%`DFt&N_iS!z1 zM6CUv7oOscZru6+LA#2Xqt%$@x6$5dd0F84f^bcEn|T1R(X1D@WE&oC*xhW?B zv{*C+M)jYqvsbkT&k_d!^y;hNO#kqW@8x|kbc(jaqHgVR}%l2(}s zKIPOl1VJ1vy_YXSY!xj;>sb9*=A>B~HG}M4$pnV(IVBVHw+41YVKX47(g%0p@E6N2 zsyLY`b7FDprG4x8ATY?TWLUtc>e9cqMQKU^R{#_ZIA}2dijG|Ynf8@GzY@Tsy6-Wv zS@@si;y)B8+-|`QQFUbmxCH?p7MN^$Y%n7CmVXd-@l~F)H)oFaedgGl+0lf#Xlw{| zcQQma3w9L=uBg}`a$g*F65)ke%gyoe?CmwojOS`5+`d+=!M>sMGNN@W>s-lNJ@_Pa^z31DD^T03bQh zh;=>5rbt3}iUuPgNRpf+c(QIvuj+b%D(BQr7^)DEv-k8musg<*XorYv9${= zzpB5pw)(m;hVek#T|tmD33>VBp7ESQ43^jm2)8y~%P}U7DG*0xjJ@yLbH<`NfeP6I z02lr{rl6ccUX(2VdXmGp1M9bUEb_Bqwoeb-a9C6VSUeJQ^NE5Zfa5V$eqaWNh2jSb zL9tXp)yB~U+F^?5Oxvcy#)KxkB|{YI-o+x=5T0VHUAljZ9P}FaDpte49Ue7KA7nL+ z`+OfW?-`(qf(y!e2Guiom3{xrRoKJD=tXf>kd%LuBBHD6L50?=f;$S4H-R989X;yr zJ3!tmPDD-`z9aaYMVoQ6?RV1;KMDe^{Tt@wQ8=|dEy}!Batl+ZF#)EU{^>%`mU8qA z(crdv)cSArv>y{ZRS+lD;t^Msn=OCalSQy|y~PVa1h4LBg{^kXn78`cjZ6{OSw z9~|)rcm*_v#fp^Xy?8U$ZukeyDkvYeeK(@{^xbz_d5!UhXjS>3#eXz%NcZj2E9B3 z=QDU+h0i2FT>Og~GpO4l8bqqwms+;GPx{}kJFloIFMA^-Md)78?@tLE{T40XFgfVT zG;NmS4_L36Ukl@#W9R6@?YuhUV*e~}0TB7hvP|QAODr=kc%oxvW4PF8kp5D9%%=MqzQ*9j)1gXE)5f1ndg?b zyeY8#`+9aL)O}wWUWSCgB0JBv_z?l1Qc#>R2xpE`IE{cTe>>THOJ(u7zz7C#g@(JZ zZ%9m)EEK=IrKQRJf12c$HOq(6Q<#f#|61JeT1M>Acq#RR1?aT@r%KG8DSA{j=FjhB z+JH|cSnR{@7L%D3{!TF6oaqeucr~&{sYKyEmZi8-e;o@%0pt;V9u;3`Yi^8Mt^Wl} zRiCEK@ zJiq4pyh%Hc;@5fxU!Fnd3;5+3czH%Wzkn}i@M?x80;8a+m!)9|b|y~$j0ZSUbTlr7 z_V!7}cT=U|J>w7*@y=OZRr-7)nBboou58x*jd|k_K5C67J|)lh&CfQ*Kgt+cd7QtG z+aqSiuD5`RB77?yhwEvbNQ04={gYKhv43B69|1>s>uHewK>>i-9;l|>8H(`-6%AL$ z4&&KZp6_nQMR}(~#IfQkOf!P8AO527Y=W}qPwmh0AVxb1Fy!H7>#y&d&j{Is@zUx| zk}nZF5_r3sB5qG4Hy&d|~15d@jSiUB!+%bZ)Zp|QBkrQf9m=IVVwxB);?T~rX zoEpd#3G4{A=n#_b>DRf&(kC$OgE0;S_z_ksPt9HYQEvbg5WB zSwm?y96Jy!GmnBpdC{>UIb5%Rf$}HW!Z{{LzZ>~Xw8FaqIekpbd#J5jinxtp@)7Ay zGw;6L>Bxv1@^0d!uXpYl8|9HyGvmK|}<&_zORDIsK22@Ca zmZxp#{(y0eCeQsc;f*YSZ8B@Kdg}b?milBqQhYvZtUc)icwUD%_OHdills{}?Gf~M zf~meU1NEMxn=~mJHLjODsmsJ*6$O!4wj&c;$F}af3|m=op6<;Bmhb3t0nX3h^BL>; z59s^{_3|RIlKc#D!3A-xOOatMI9r#>&7{w-sb3>E3S5sA)~!3cJ=9TX^0F*-`mkHQ z8|}C<94*FE)vf{D4&$kRYnJ7 zSen5L(fN+Xw~u+HX9wBIL+zzD!WKtt=*ReMixmp};A>%{T4wN!=wYj-RwKUFp1c=FBjmoB$9r z+Tm|S%a?nuRtFY=(vSBm7%cI$KwQ-qbq28V13|C_#4N^Y*xWb^^Am|$g_Knaa5_Pb zuv;~cMQTeY5EU>js5oi)0G1U^@qjithDkCB9yI~BZ4chHW1lkslqXO*4bM3}7_CUu zBXos|3kY>XbFS0h`aj0E0fWP_g`yNFS_UiQEd5QCBC4>?gM)qZSg7dyWjn=J1OkOE z3j{(n4P5t^zip%8=2ew|+F>fFD0K8ssC_>J`C^{mp zox+&t5tGhuSR{8OgulhC$79hDx;?BC21J-M0g`;Kw(TmGX0OjXuCsfVqw0Dp>N)S; zG97ZR#yUo3D%T~wF!QszzOmZ$Y8r?u4}Aif!`o%E4;Q?@KJ-VgnGNZ?Fs6aZ=!UZ>-| z%lx~ch_QWka#mcxggWwt)B45l_8>C|eO-97zEe`v5@u46-uo6>>b~mf2tjacXzrGW zHW7~TYeNI(wN$JP!{%Kj1KuSK)E!}v2@J;`sM4U6+kmAM4W_9_0oP`X?l~A!?6-`& zQ@WHV5c}}vpy`t3emd>|5uuus|mjW z=~Gcg$?{%6%KS?@wfGZ3kp8VfU2cRO0z9O9XtBrVLI<7Tvc=ebFDNAUQC7;FIJklVI=nzOz@5{fM^u9|-ZE-UK!44hYB{SB;t zfXi9_Rz23ZLkJ%?qYmTU!)x|ub$o9)M!0sjg5~Q65<-*9oUeXIT5|-LS(IVv*_+qX zjN0xEAD_d=V^jbD`xwHGhMNg~Gu$?@8gE%=7!kqBA2X|kSN& zX+7q8XG?1QcB_r4zGLvbw}q$`e^h?cJ@H*T0}^&ueznv?$1-}R5zyjuL_sn@#)GW? z(ZT$X@pvPuJuNw^fj^d%Nl(uKb{IDVgwNYF6A9lB8BAcd24~NrHEEW{>;PNEnGo0U zqZ_mKfp9JP6&OVRi_vN%VqZp{NC&RdXZqt zmoxD43_L#rFE4^ecomob^%4{iHctptSxy6Z4ctAJJZs`>DuSu|%TfBbrFD4}{6$m# zO(4oC)V2z{H?S+vcW`xgO%ELtQ}pgB0A_pUAHruG%A&2e&0x^L>it zYv;=KYY5$Y2smBaURmc^z^@#DtVzTs=*RJCLAu(=2Emf^a|-Fb5*q@gjoU0g`DK3* zg@2=;V)xpRpmgyaRB?EA7Qw zmmJo*@e^pzwEVdTK!9$riFywJ%oc9P7EkJx38$9fd2kc{4T-t}AViS&BHCVmh8!!` zv`iy&*#+ea)&NVMSQO>GOaZU}bOMzp&~k!B{I8~jaD=IWm(&ZP+fzKL+f_J#h~I)q z-&!zTS#chW2}9klAc{Q;%ohaK(-t^rP5bvr!1&_OA>Ypm$!a(p4Ryo(qlh=a8f+~f zkQsxs2T6FJ5v}L}F!c4za&<&ekYOfN-8intBGh8qwzu>EXfC`!BZ5JB%)oRHz9c}u zR!s~~&*NN*Ru5+M0(LL_Hz?y{Vo>%R$cms%IOt&%kC7Q5w?iLoFgMKx&~X0YVcl9c z8v_6MeY!S<1wy_3Vxnk3KX(SmN{GF>ydzB4`Zb~Q+XHpWtVQKf9ug$mMPR&T7*8K# z<2}{tzn+21GjI{%AD2I%^E3G64{$yM9zi`{rw88|qQJPt57@gceErr21gAyYBmHpU|7dnw>4rXebo~_B7!4!}tWT4B z2L*sJ^7)t$yY89jG{Cb?-WdETV{3UBv&3uI#}yDX1I;2Y44W(U0T7A`V1ePXV1&$w zLEK2mLZ`*|CQ8Ri$-1Y%oIvFST23O|`v)Q3fZccRTW}$vNmmplH^MCw{K#^gTC8(E z)S~-0gx)1+3Y5Ri(jAy%W=={V^o;bkfG^UJApG0!lo`1Oj$kz(A8zXNqUG+cnF}Hl zLU)VR?^>Ey5^NKRuUCUNl>l8`fZG%($r?HwK^AHXb6+(gY57<%qi&0U5>va+X5($& zUlV}Z3AFG)gWXZUR(Bc+;Y9H^c-+jG+Q>V609+OR|3)x@MD=-Ml4${Qxf<`HL49i# zmwr$m%#3ue|M@H~{+AcvlvlK0DK11ifW!TrQw`HQSeRUb;JYU8cu!- zA!}l^m==9a$a6Z25f|S>cW(p+4l=xNR)wz($!Ie3{Lah3Q+Bu1BD^&>G!N>i>{Q}|G^hwC?z(f%^h z_S`kxS10Q!~vUXen5VZc*iMOr{A>1XSpe&_{9mQ9S;} zmey?uxGK}Ij<-8lx4(!L{1VV1fAmWAsC54@9{ywS^W$4PP|eqY(`IfoF+ay_3xE!+ zX>WG-PE57n*EKDJ5aiD)+zr#+6vEy_=BB{~P*GLbw|tFx+Nvv!h{@sxxP?cXLH5qR zUBm-mIf08t{CDI>EghX81f*viL*pmU_Ti8w_Kg|-=n2vt5k_bV7Yc$85c-om9!1D7 zjl(V4qb~rP3Ltz>;mkC#hZ24e%rw4xmX}=+tt!X4&X9E<0|VXzftj0H_wqW5zd4`T z{oXib1zmi8sP0E`Q4+Ie?Ysw)CqVXK6Mjad(?s!=6Ufl^DtF^LxdZ&Ul72w!=JiMn?zB zj_K4b0L0Xe6eEHkO_t|g_SCqli~;VU>koxTt)FiKF}NQpqY}5%EqO&L6%A*9{vcHu{``~78ZDj%OQKBWhLoGa8d(N+2avNp7 zb4R|Hh3Qf4+N`hSPsYp;C*|Zs(A?9`8x89i^Io6XoKF({i%Nj*d5%LMi8#=`;|uAa zD{qZ77ifwR0+H2TaeP;_pJW}Lr1sniU2wZuo>|Fi&x_VbMDF-Y?3f7>+{z2bud`;4f&1ULyeznL6CEjF-Ys1 zz@VAjfWMR-y9$asU4S+(nP5nr@=v?QhBv@NvpF5*iu~>o{LGO#GvyEDK2e#+cZ(VE z6QAllD%%zS=J3{3{4<9zSv=!m=@K4t^iO8J_z>Y=rsu3okbtI4PU== zpfp|Ps1o9tOo?8L?4eHSqI(Eg)X{T6sIDQ)Pg001BWNkld~-)m}d%@sM+1kZ}Rqy32Vb#5r@qLwuUph>DCdi9YJpjcKU@0aw19k3@5FT z6V37a@p%~UnFXJM@Y)ev|1W%-g|#@xqEIlY$H1|n|29&rAncA^m>!w{X+m13FiCaJ z{WZY@r1cmm*amTDNHp$DfX6~qIFt_8X3UsX>x;f@*5@tKeX7qU^I^jOg`A~25 zQ(w?QI-_(s4`w*k#~FF=7rD*`b7L-sF;9u6Br+85&2t)`x7J1aV0ALV9?txbD+IKS z=JXfm@RVWY?#IiG?eFMdO`lG_pFemXI3j3GjX4dg+MQe%f70h1CuixO=gHCy_`0($ zVpW`*NO{C$GUgVH*S7$0ZO8XrR^az<@Spz^LBIAM0H!#=Wd)u9EYMg+94yU<6IAYLdJuDBcsUX^A7kCM-J%W2Q0xjdD}E%`^{(iZKY*9HxXKHHb9N zF1mSEdU?X|%qXcNn9>Bwd`#DC!12Irfa3gH6TY1wdI+KwB%8@n?yGbk6ohwK3#sf@+;A0H%T| z#`j|oA5n_x%k~{JNc%zfMX7J~psWCuBG2=}UJ7cJ<68;pNCg13Vy!FqazXj$KcLf- z=C|tpY@r*5rU8J9#dOh%RO2)YijHZ)g4F|XU4zo{Gv-w)-qxbybn6#yTd;*%qx@`gyPg;>I7>z5dsIs@q4| zXIHQdF-%cI<;mSSqY%VVkI|01N zJzoH>AQ$wD@L(tap8;I7Ju#p%&?}Id0Y+$}7-d@MQ57<opQAO3AC7G6&b{)ID`hVJt>~%V>U29FpW5#Fp%iP+k zd~8wN%*=vgVQE$o;@r!@lq8uiN%h-OP*76>b-E9|HzoM&B&6Ba0BJ`5+(*{uK~;Lb zB)Y~yK`Fm-5Z877xrVti1sk7|2ljPPjS$U*<~YX0VMtQip*q*=N4kyK=(z_(IyURy3Odi)BT7w-iYW}L>Z4*+{S-m<% zfKBQ|l%nwec$MG}d{Q{N0FOpP|AFrfk7oC?qGbE{JU)h&))md_9EdaYkuw{~4UkCO z#!aEB!q`&u9Bj3;F)?ZtC4ng}PztImf{g)StwITPPgbY`_#SzAi&`(JSo<@z-xC7) zxcR$8e!Bb~1!j5tOkhGZTC-zUjEZ$*x~cDHQ$8_=xfqH;pS;uK9PJWU@+7(sbWHH$ z2kv8_6jjL5qJks56FK~oJ@z74RulL#{s171U#amN>>#R4#a?dU!$w_bqrGx+=)Sf9o9{{T&QKJ-x#*1*+t z1~hS-kM!VLendEGxjYJ+iu<6@c#9*dMQFVOHG zHr#1^L>0wWDXPSWDLwSNXwVHfai-jvjZcRyEsr#R$?^RGIGF4ZcBUH$!(p2Gx#_|r z2%!Hb5D4CMPo5LqK%`Op7!*m&B6PE=1RW6xlJ5fZfYDn@4}34UC!k3rPj4Nd@w31*;E7zkU7?YH zd@#)SG;ZJp9*-P5RtOrg-tquY%SX<3?lw9(C!TtIX5zM|H|@Py@r)^`RndEac#f!b z!SSTxXj7`LswH-dd1HrMfu_fYIs>K_7_t1;z>E~^dLrElY;DCpGiJ1_au{l*W2V%$ z{>s*!$V55a-C(F^^-Fb|9edcN-2owy6GkuGx3n7;o_xJq|2{vdri$zX?bf*w=VV^@ z#=u(}a?=NeOHe2<_wT~@h!($GK3czYmd7s)Vm_g6%`%Co@3x*=Eft*7MZBN_zkG7> zNcyB+5=PN+Rr9@oFK6KS88|;naK9rSH%B7(-$IKv1ov(V=JFI@OzG;RYExnM2%8#t`n~p8 zdxtU_Pi&qD^++Gz0G(U)tX{M0gYd4rJS8Q7(S!-E$qk;?^YHYmx?}@w((yDMT%@=1 zje3*R=H1=4XQlWQK{=YMzt)TA%ghW}v;&hU6FtbKazBo)g01{%- z&Wai^B0`NCID)uq#9o*6KyVX9t zR|Np62LNf4y?Sv05&>mFDW$oh#jBbuBcVF4}jZiD&#Ju=Gra6xg^0Y?r~RP5Nd;j*f9)~ z0J5Fb86U5@@|nA9z-Oho4Fe3+Rgc>fA)i=d zKCNPD=emm35dg{pKK)WV&H|iP@hD)?TH08&xGX?be8KAq@C&eBz?TbfIfK^=WJ{@T zNU9oZn)m5LJB@O^;H!XJi<__i7O)#Zf_vPJtr*wrRStzaBsI1L( zdj&i?*xy!O_X_W^AGSOII9xvp+V(#!K9$+ZJ|O%9H_Q)=%A2SJs8!@7q?6#%H?wVL zd*d7x&0Qc?d+C`RTW^x$z zD3K^dwMQ!a`;l1%OhvOHxSNs+|6CT(B0>0wPD=Qp$8hybX&cA|=FTs=1|?#~w0fH& zqpA#@c`4|Am|^dT7dKA+ANWR)5zx&-?Z)@t5=Oyvv%lVBz1(7rc_WAnEP#%GrbtAA zL;J}h>@rk}*NzZSF~Bte*KlJOgvl-1dQI>>q|J4*G%JtMgwo?uIYxESx@$hv>Px6V zRpz5!go!PX{qrgS_KIH)-#;2Ag0HnppGPZnH<}*gC@>WabQ_C3KVWdny=U46CZ_iQ z;A86`Y^`Wna%1=`k5c;T&DQ&oy6Ug&MHL3O51QKOEv2zHw|`5{p_?0{*XFCPhL$fv z`e1)^CZEC|WIyV3t4()(L;F85zff6uG9M!m_QN1(KQlzJBwKxGT|sNr7$p^?7W{ht zFV@R{!RiG76ks_4r+f?; zdMw`}3WM_*%o5v$swgX%SBdRVLJX8W*b>b1vwLXHhSH3;6vb08Ji8%?b@fbbnF_r6 zxKnmc@|wMmCC%2&BY*+sKK4p>)4xUOz!}fY-c#7;{wNsqEZevt;`PDH%btgzt;fnw z0x+d{q=LA4adZk{{q^kvdwuOfetT4kdJl&Bdpi%3Em)hcK`W%MQ*0{{rXG=-8Ge0! ze*YLizwIYp8>se)rzRugst&NTckPVjg0ROcAUJ}0{u?7g!Z4Oa_KcPjh!!m7mhXk9 zK`;-1Y5`&bBN5^S*zh^;&}F0Li{=1K=6x{l#K9W(tp&Zm4DMlYJ?)-=c4K~@9XK-C z*cSfZ06Ib+`}VyV?U};J1S^+GxJfJ&zA35yHlV0NGveVHqrCK?R=L^Qi}l(rP{%dUPvr?BZSK>zG($gA{zwL;>EWpF3erIfYpRD{ zp|a@}@$G1S6!19UDf_FS^#!PBS?}uwe5v5|B8q^zf>zm7S=ax9*MDUjz*=R^E+^o0 z7Quh5z|%jdr~d&?Poh{P0xhK}b_|y>1D8L*^M55W|H~iX`Hv_7ssL<2lfNF-SE|Mq zcmjBFWujQ31UE^@Kn94h(y?G(Q$c*|yCeDSt&#lhT7I5pL-_B?vH8AD7tC9xTN9Hy zcpj82#QMvj9uMC`|K98Eop_1SgV0{U@%y$sc4MDJ!8bjN?)wz;He8qK46`couJluK z*^hPam8%%Z*1)@LoUk*4v_5h^e(hV+uViO+{Nga*0?^&EKaG0~m1k@da|@KIkxi+! zF>Te(N+tODyv7lh1t1mvmy_SiUbNDNF$!7sP&rDXA}(c7qeW5`Z&9S%L~U{ssb;w7 zqjwf0e&F-Lw_@;q;N8F}sNPe0XO{;R7LN`t>A{Z;FS2c&(m%Hhv*2l<;pjz_05I!7 zQ6}5Gy<$Fw%anTCr9Q&UInk=eq)|?zKbrU>*lC@3ZgNhb-%JNH}N+G#e+ZM=JQZnZSXT?pni+;K9sT2IimLOQi7?&PK%Y zVSJ`ByrY6+yL|gkzq2hTQ4x@p0mJuJO&-_jR3Y+B=z|+rWSnI6uONtLPOT#7^ZB<} z<7;h4>a7>>x~jDw5S($A_39@-!D9l*vkS2P0)Cx=`VVMXP?kj$h{}>x#SN$xSbqcO z-%{S?MfdRQ7JxX1v5HDlpHUI!o(L!qZ&NA&qhNicaCg*Ve~Tq~&tPzK-Dw|f#I<_E zl=gKR+y9nI_@n)N5I!mhpeaiBlQ1}2rjzi0Gju#jFZ8z}+9?tx&ew@jYIDnHPKPU0 zD=2!8(YMEpiH)xv8~V4vu~Ps7(dz>@=q!qYxN7u$Sk#K-!as}VwFL!aSmb9(uP*n? z6R4adN^DVgezGH>SeaH1OrRk)YQnrBJG1&zV=^qb6o3|(%F`@UXO`a!rfZ%N5PKALpNJGAuv3;siaMqb zfyOjN?LFeDDM9gCPI_;_P!q0Q#G=pUO=S$aDRavLT25e6++9xcx14~}6Zmujm4XWM z8j$a~$UT`r|I5zfUWL)WoQ3IMFHI?MgQfe1UPgbeyD>>}-DFHXwIK8-IR)IQ4>Mdj zj&@DBVcB%bB%Y4%VV6ciaHYSJJ|5i^e<#-z{+NaCyAnXla>2jzXh1-Xk&fFhwS-X^ zpmd+w=!%35APS>N&@CxfaGEO#ZcvVVRxtht(7AKbfO{A4dKRJkau)0RMFZ%q7vOTy zH5ulcvQ+>#1pqTZs~iQ$D^Sm(6g;1SrLwJMqeDn=^+47ST zXX&z_crD(~n{AODycT-6mlt@?ExoQjob+Ln&nd`CJ)UFz))f@DG)o-R(uFa&Uzdl|h8$aGLfhoUcKdFCrr?>MUNEFT%x@S@`kb(>0N7eQ_S`i>93CsV z_VJ7YlL^sPnWkW|F+s>c_m|Qlj3~P$$-ED!6%zeOqqU#eLRmV}bMKD0m_zVX|u$=ZC} zVjA`0s_-umPdYIR{Ry-@0p&@(uL`KJ@3o_dD**}aRabQZTwOsxCsE>7lB2#Xe=ZB^ zqDQ&b3Z_+%GwC_vi!lKVT24})1@F4N0OynJ{XIVi4}pXId>Ewvas+1EQEu0H)HcO_ zqdVQa?D(QKM8|5k^D@v?KE~2S4}dIWbak$yC8|@5CZ;m}b#>S8I-$niW&z#=_eA6S zz*Ak~u@gDHV|acPaYxE#SVx=d^qbIr=bs>JvtCfwvmBXs{sVsb1Dsz#>h8~Vm3{VW zw8HDoOAu;R1!J|~fa1ABe33XG>kF6`5MDrd5}s?3KVFJ%jRIgwvh%;-mp`(Xe{B|i z8PA{;;?N$8Er5nIN#{d5zVHAXrC$fq*jeklN?hm^En#a;S4_XQHse!tYw~*aWB&UA z-N?_8@5(e`Qe}iU5vXbIm%C-XzXl%_1aQECld}E29d$ZZu2<09P_}*FKOX0idmAJi zKctWO%@hDZ;XBl&%|6i?8rb+3J6QOiXfmvYq{xyPo4s>+{(g_1G=%2(8FjnuHK_|BRIBaOM zz6me!rN9`%3;}VqXE-oMlSDjRY^0yPKRPLlQ5YG9p-#5$oDj^*9}xT=LwwU3P>pNH zb@SwU8=~TIHz?i_1s+;nuY%YIzND|^%jkl{Z6;H9K>ucgafkxl)an`VEs9w5mlJUM z1v>o#Ex$w&ps`m#RfKaT#H9F=f#%M;)Q01i6XY#Vjao zEuK!|e#k6&pPs*gt=MB#r+jL?25!$lj)Pq0kz}0sp+N}d^e*H7{)Y4v08_T{ zC}_N^Q`2jt%JzJZ2i@+8w{Mxi=LQQhi%fjuM8qP?SwjJe*%)!U?w5GHaNE zX`)9qinJ`?)9f9yb|Sa^{9HkWL6?eJt;-956L30(`Ak4Lq0$K+IokH66#_0$ZE|LQ zAOvZJG8rp;&#LZ2wc~_ZU@py*icf?V)QZ7ay*)(K?}ORu@I67JdoKIje&BO}9ce^q z{?DSG+U#f_kBqZS<(`@MW0Nv-O6Cz05tXH@dUp&t#Hgx$-OOGoh^po~m`BbKQFUxv zpKr(_GZLJ>ap7*Zjv^C>R-bEN0>rgs2VJ3WaU0AG-Hch2u{$EzOC;^9$u!D!FZ8DT zi^jrY(&MvOajw={aco&mU^+>_tkVg2`UU*@1wQ=(FTW&M9}0j4wZ4FHY2W+S0CQ0# z?*k){TdLYV8b07rxF_hatQEKbwJfq7?4N&tU;hDq{iAe)fIt6gB=FVeSRh||LYR(! z(LddeR+LULi>tSU*sxXG?naWl-93AEL*4~HXKRPDc_ zTNX*ztn;ocnJtYE(}pFw!Se+P4X{WD94B)8fkJS{fBIC?Ccr;Qe zC?v9F)qusJ;I0lUL;8*u2}Wv_viK#{l$(&_h`A(vd&3R=7R}7>&*3K7pGUl5b%<@M zwT5R#b8CkWPqD%S@(V)H5OMNwWr0qppwL++;FqGFs07d=5nz>|Sp@#fWNvEA2FN{I z(z7{&KGd{{u<&7fkbmGC!Z(>qH+#nXz;RH)4S_gzbW)T)O*sSidLkm==?OUf2RNO; z%OXPc>7>WA>DDVIVHj$_y$JZYyMAMcoR7sSSf0dsSc4#Egg4TkiNKIgQ_u^HbYrhV z@6hhg0@+e%_frev!Tj=l%1gHNG^T30-}g{ajWIQMRu|%CILaluPdvV+R5hW0Wq`~; z5|kRS;F(ab1`DiNLnKhfx?bc2j`bpz_VcsE+^|UdD|@`n*Yrx>vh~9^eQyw+|A+$M zXCD0Zpz>j@YWx}$fM|+BBMlt3egK)W&3Tix0tj^^Rv*o5ep^{-fn$ zql2yq`1^Zs5!I*u+oDE)Vy5B;b|5YOTi3&;FlMAEe5WsyIA`UU>=3%r~ps{cs?^-*c~)69_(kLhnaLMxQ>KoIeZ zrBR0XO;KF5zEu?f?I;7VxhSjMj#O!3K?^GI;E?>a!sL(O;I|QO-&fB++6hi9b$}+F~=>MJw&($+Wd|EVHPyE-q1#+ zKM6z+93b#S+=i1OLOiRtr=6;yzZSrgnI)KCHLI6huPxxFm3b$f+O_~5$j=Q`Hx)QO zi}U_l!6%-mbkz3+cmt{F2QqwM7jMzSJ`J2^bZN{0Veuu*n~X?EM=%t#dVL$EI9NF= z%pNp+ibhKs$(YlhF3{~mA+;vSp4`#j{wjMn1J_Og$b#)_H2kWyp-z~O3IN@APqGJt zG{Q6yp$=9i@+>*lEf5n93?Cuv>xgAX*S@{BO*|yr1?Cz73*U4MrvLW?UlQ(M9;N~6 zqLn7|+WJ2^pZhTcz6%Bv*ICC%C5dS!{L9VHynh7{7^M?vM9~>GEH%QZgp%T(de|u| zw&(u@*7LVT_;1nuZLFBM8U7UqljBx6PJNqUmEeOxOb1ZJLqSgz02sWUK($EJc4j?V zkX?~a5Tad87t+y+-i_`ytK_zT7_FR>ms2IcO^U?VLbr~i(AcR+@<)?kRI_XD6q>%n z)Vn>G5d>JnC6)DPNzEb3`#d{o;X02J@tBYGpv;W4{SymSfX491c({gR_Ou=6|H=`1 zQ30^7O}MYCbftL(cpv1Tk7!KzfvM_>mMtSmoP#sZj(ZGFTj}#S&uCdre^1#T0L|ES z9X|Pt{()}{W2`y&I_v3RO_qQAFW_W~`}Ilf8~IeDpya(3M6=N0y2y8JWjW%k$E`TA zvC!CuLz(-1Y;RA~0m(2!!Z&qlD8mMls0H9#H0X;R^%va!rLoiv0F{{rn!7efgxHSt zF>QI#=>LQcZ)O2MwYlHhfy5}FDIzlA2+W4HfqyKaUlTHeyv5kSA`JI1XbdC6jC5(! z>Jzx3cGk=(BenVAj>krUJ)@rMyxB3y zWG3loXJxyyJ>8iRgzJZ2-~d4q5y{Ams!H$93I>D3)!}zI3aV6LQKGvi(!G9j;GMed zYM#I}Bc~ZTP4b)_dD^96C{YK1(li8%vp#h8#JLiwIL81{LZV3%4gQceyuSkJ4X`uA zfyxL__Sf1GXMuJ{A;GhA-_XVbrNWaHq4Qi&j&4l?bXVAPwRVO7QBWLBU2no9nrr*L z2t)p1_Z{B~eG{~8j(uA9DwNAGV@;e09RL6z07*naR2G>Ls4|$yvs?RdS0{tSVL)R5 zXla@k|Mj$YA0|IinTSDpTps5u_=1eE;(CcK*RZ-`N!Y25Y3sF!G4 z*}DyjK==(mA8gD!w>W9RM*`czy$Y}%YN`vw1npSm7odzOPTgbnw!AFy`hhg%cLY*l zojFNDKq6!$C6y|mCjb-4aat*X$r5krGn9~LIhv2tiy8H;|C`oy?|$l_TrZxvQL?=0LO@j?8}K>Qo)oBXZpN;Qzu5CW-I8;1H3<~qF3thgVP z`4vxg`JfigVh*Fy{$`A;xd;Z0XXn#OW0OY)iE_`&JC@5|;I}v6dI8@4Q!@AiqU<9o z{@K^EB+g2n2XO)GdNRY=gJ^oA{2v`bcL+U&Au9Lnb1mPB&p%Y4KNCjgfze_9ENp4F%#j+i!NHo$2vmr zAxB+yo7SnPM=Slz`{s7T7x%XSJO~&-m6%CdBVSCijC=1w1OSJB$*eFs89p?@LL%RT z!k-9|MYa|aj~l%u*r8?^Et9E)yD)*@Mu2Z{P`vLFsGmgm*z%-&q`aR-@cKLu+6gc+ zvgbBYnwI85gJ#X_?+h^*Sas_a(*(>vK$C6(m_i0!HT;NDA!;<6=a@gEd z?7odawlPTHX_B_gKY&+FUPf0)M)C{fZ1OB-07i*eXodUG4>{Xf$LhFwCzJ69@r6bY zKXPmnb6;p5UXuqE7(WCQpQxUTQRBv~L$%j_HDc68&Kt}BY~T#ak_j7m(Ifl*0>AwU zy!{Eh{|Q{)H3xvnIgQgtt$a!QYzKyzt<1Lp#N>h$i~{#STz^}h|Eiyj(e4`>2!^Xe z_<}JUm3P0z;$ItXloyI2P!-ztb>kJJ+ZquZ7#_8BFTQgmf|Vh;I#sIis#k40onGxM zkXU~ThWTD8+OBye#BEteKh%*Ty!m*R^o{TYPZXGozi0QfLn_e4=DB4k*5?9GQ2s5e zHK=R>7!*|c-P#zpok1@anCY9&{j9Jh6j%3YXPr|0T(rt<)%V57QdwuCfLxx~R;t?Z z8W9}7<-9&5+w+e?x`=e|zU|?kfS11k^NSqQL~@!+*-ApeN%tOB zpJV7YLg2L%VLTK`%|MnJOxceyVw&Vwzxjt`Gf!9fqjwpP)wWA;1j)@w#{s zONeL?47=488r3__wbwOq{)kfiQ)H%B+|GFcmN(G*U*LCD{NMisUEhG^0%99qpvY8F z27~6>&{IEP(pvdF2wWIl>s=#K-3e=W*lx}6h$!f_osxo#ob_1Q%yllD z$UiHZGg$9%^ZL1owzn47?P<5)ts?+N1eKeBYKOc@t~NRL7j=GbM-fc@hivZ;S6`P` z{n`2J>jA7_k3rnx`E0`#zlq&%2kS6L3^KnSl8flxE=dZ=m@HC{0Ld0;^{)+dCQ>CyKsK4U^MX<}8`?mki1bMn*h0 zo1!QV5bGYT$kT{0(KLCgEm)DevURY{KYD+7#|nh2b4 zkTt#nmIYXJzyIY=@Y^5i_5TyNz9Hoc5@klpD(zJA$-T?1P;)^A<+oU7@$+x)bF zJG<}^MZAYA2Qpiaw>>ou0C;w$YDr^{;pqqZ*MM8~rxRgy@{L^dE7wRwOYlc3>ySn* zagrnBDd>vE0ss|wxDvHVr3MJR*YUbkAeZ~Nj1*p-wy$A zjLC6BwxME-{pSfX|9-NGdhttE|5wm70WYs^0B|oVhxs?d>XK#OyW$)ni&CHo!uYCt zh20KI0BcwsY2=nE3U*we5oXsIjFz`F@0bQw)PKcO>@xxB1vF1!5C0E!P|`hvi|RL2 zvlqAWYZAP?HBa2Ru9aRF9=h^O2uqASu2Ncia~^B7XIfgc1r5L2Xx|wtb?iig*hgOD zhY?Eu3-7sL)~h3ab_5CO|;hvojwZqi1i*q%ZqF*%tNJr zbo~qT{sz9htLOip!24es@_zwgku9^RJx41#7!_p-{X>$v6lckefP~ETSarYt!n6d`LDlwq5m|{m_6iTR$H}>hqO85P4 zaUJXwa|hf~+z=I_v10&brHx9@gRLCNj>x>4Hlrn7oQ$$p)vz|H>qqd!3Plc#0l9OD5hFu1QZQl0E4RQfcy!$Jj#2T>_>Q%=FB?3*dt$l);9=DRn{FMOz5J;*qZx>FM-tI?C^!+*EFG| z(v^fuafuxdi66Db0cDkWecI(&hj<7}@2niS63JVDNCZUsF! z9V)!A6>3A>vHMuocw2eOl<4GKwwP{}cMJZH?lEN*(0l8*+$dpUN9&wji#>qR=Q?fb z)tlP>a`(Bs$b8WJf;1)M`3I0*fb zG6*xEZRD^3R*^n5Y0iZgV16z68kps*_3OLjFTet!D^kUT!YUcSVn?=FZimAGq=HvQ zGgd-II67&oj2&nb3t5@ednWK{5HycP!21+r5QHXCoO3aNQAe=PtlorJKWqMqtn-$` z(UOT|F4VKaEHglWtSkNt$d`IJV)-_fxyARZ7iQdIVxhcxBcZ%+PtYYIx=&4B=T1U9R2 zK?|8OfjHrs${2B)Jh8DI@dtW=$h}g_=AX$~9B&?xf9a`J1vw0*Qag1p~Ndj0ERx2yJ&>_N=kWCw-v?|B` z0@G9r@rp?tT1`WtHfarm7|t+T^<|*SZ}^Si2IX(Goa+4LTHw8fkbJ{04o06fl$}lK zohHyUsfB!duU%c1{RwO2d_`Wa;N@B=$D;91Zm6J&wuj8@sCfwiBJiq0?&SMqbatUQ zDUX;EJbU?~#~iW=5F`qWWkXkE8|MX-vpNkl3W5lfxG0en)+CJKt6*3u!rC5VAuluN zRU$RgERhrw3)HlAJL z`i9SeDqM;6|DHf;7Dm^w^a=9!5MA;{uqx%BOB8^YS=Yg>z|p8+-+-S=*y@L$8ji5g zG~4r^X3#W?hkJSfrWrKLy}kXGRUH}`m6<)0xbLH1?1(UyIwz&6YE*U9MaNL9ze}F6 zcy2B|$N-?cD^oe<6|?4-)i7o-#B-2~Fd1^5rV1Ep*aqM$z(D zt;6NJLHbD(GFOZ~bmQ`4zZQj+WkRgT%sA7AM;@@}`(C|M1jpzD281sf`rz*w2 z;kgG*tLv#f|1ve5dYNTTz$HwyEyv`S%9|zs#DtiS05|q90EjV&c>yi&pv$`)?{|4a ze!qat^KVftLDs2`tU6mM-oTlUBu`u?vkLWmh7r7HbZGCj>m|yT(G5y<6bSd;{f2M& z3h45*4?v^bukaoyvhx6l0aW>dMH5bzpClD3Z^!#(JK8ij(acEi|7NG(uK1IDAK9K# zb=UiR)Q{4Ffd}hby?Tl2@vNNf@<}Oyn{eE2-Yzr-05ANgU#-=1Zy*|ZuL@;J>$1p+ zX52R&ds51E!ON{UvEH-mcD+eS6h};;G^r8bMUL~EX4&`OAljx9l;F6^ z7GAzAqWr7ZD?yG7q0+}_Oww#Y%7P)OXvGNjVj{qo{+HVG3A7lIVKL9r%hJQLzlq%)wX^ zjkHZ$8bz>>;j_n2+rk7f04$(<0bSlf?{CO&e~AI$a*GEdMkC$*gs`{QmZ3&*q~d(glZyz2 z-6IFXCju>RTUV^Y^)<^e$MShgUZ=5BOK!>(wMD-I4J49N2sr0rPz=u%qp!?Je2*(S zB``-uQNr(In|74rMyal>&E^HFtT3T$DrInJcvY1}0jwCnmXaRJPn(K=?fpO>TH^gp zxxc}{y+2z@Ip6}j-!p-@5F?>G6ok*PpIw#z5=qdhbE_S{6A&~Mtf3JUZ_jY;uYGN zK$9jbgjnt6sgXUNHv%*KSTi#?B#RWYTnGT@6~gw)o2xn_uUPoUmo z*5pEq3Jnv8ItBn!CK4HUsV2s!XK1>w&Q~L`tuMvQ!xn;XV9{MuJ6F* z4b%G@aD7A03v!NLFZdky1io{dxHbZGvw9EW*YLK?M?%9(K&uP=iJs=H* zD6jHr5XwGQUiI&rP=7-oIs(9!qSYD%sDo>*)zTCU)?{EYDgaG+t2(|AM%T-O+Dn1Z zRYrhP@k8o;7{vDXXs<^}5z2Na@%&rNNOwkBrr}9*4DT$A7@%pwG$l+aA?wzHb#aQ9 zuCJ)l41hFI4{7_DO++Zikevn$)O-Jowx{wH(Bylsm3{?UKr~5`p)^bQ|CA*Gp$iF% zZjTUetQbqOZaoNjX2Q6*V#=%`|FZYrwre1%(I#0^CNRMB)-woGHS=DEVLkOsQR@+zCwAfZfe5S8hYGj2Q0^mZYSEELvFQFXf z0AWpdNUZpGm2Cj|0?HQ=fH&kZZjv@fdFZ214nJ5sRVrR~3t#BX(`XdK$$Vuif#XPB z-7PlF@4Y&{;Tt{+2soGAGd!}*Z}sqg6z3y-QCgT9KE_%3vZp335$x2+PH7^|1ElS6 z2b-M$6!Q3-X|Vh%u%<<$Fq(V7+5qq{pyt{boLY8PB8>_F>qy4~hR_q5t74nbM{3Ia zCd%J%E12-uQ_!pDf-%gDPf`jcz*|>$iL+6WGrC5g7^yHiYaA5*{q2`V*)?}Gwe+RCq~@W!rugJ9D!QKtPHa8 z@#1XS3cvk^Z}?T9JpyoR&-pN)iB4iIKbyDSctp;ioI$(<3LQ?EBhm;xxi(#rG-Aq6 zwzEIxu*LD9zr*}(@VOg!NM(%dIJ+c&!dO|eDB38*Di!Z{_b3E=*6#0Ed8wIdamvzpMV&HGRYH4jTev9fq{_P8A#t1j_L~C=8HK ziirU&a-j9#e#;XT#C82N(GerCWvQ*gy6h;N7x*!7(+o=T$7z;*4f^q5o#z=SGmd|rUb5(MUA06~)tvy@j|*g{A%;DWMYd>hjP@U`NXuFOXvf#oNVLkZBPd$<6r2Pixbo=6A2$Fcw35 zW%s=Q&HH;^#xtO8?4ojqUn?$DI- zb%W+La>q*EJJ8SPmRQ{cp}@7G9zI(mfH%H+sUFjcvxah4iaz!41q5$1;6^0v?`iD` z7(9l!-|%ZgrQh#R0LRs+c%hF&QIS9)Mr-52QQN|L`;DNx*Q^!NeimauM?kD2mO?h% zNs|DkB#Hkl`QIM8G_;WN0=iydrwbJNE6AET7pAD^_cnIgijLZmJ1%0h%OEIwXQF9> zY&Eds(>RJaK7O``Pz3_wdX>2&2{RXQM^pZpaYyHsco8oz6G~o?QJSFte1*bssQee409x|c5X+Tbx+Q#lIP&{)Q)lQEIg%w6>4c3h^f1 zkD`1N0bq36!}l}P2q3i4w?b-;t(dz-@~9SmAnUX?0+@+!Al@rmG$KDCcWMK6@!_iBgts2JSVWRc;~U|CK8;Cuo2 z0`Yhuh*q`I?20o(=mO{6V?p;}|Gg33FieJ93k`zaZeA-K7&C~}z}oO- zqpMy|T9w-^tBo31J!1Who7_^UGte}{&x8IMd?eZ8Dk^rA%?4g^^w^jwZCsGJMGWZ4 zPMe9)Z>pKr9BsC~B1QBQu)g}*xh|*LhSc?<`jw$9UB&a}Fg@Z)vzIUt$9##!A zBinP`zVo`T-S&6Bf5R^aL~`DFwf$pd0OR0EDLBetP~x(u7YyXc*jvLCd*~*UCi^qx zq+Lh4?rQNT6x#~mnd-H;Wz1>?mCfgXUg-A<@&XzlO}&Vl?lzr`=B?Tn6J4zy4&V1I zrguO*^`x$B+bJ(Ih*gP9B-3d7=j}+-X_BHY3-J01Oh16>6-%0x#ws(^gki{* zNKzq@lw~NrFfdQx^nz@m#0-=@`&u^=kZC=9POIh9lo5h$Lx>OZo%}El;Z+8CDxl&y zSXY+)*h9bs>L_RVilvN1?OD3&ZS@vSu;Un4>r#HM?JZ4P7+LcB`AZWRSBXHF5-|Tj zhVsg*%z>P2a7D^lJRnv3dI|4z&0_sUj_0#@Q7Ajv&}m8psTH5nOmh zBfuokl0nNA>G~(={lCEPe;~jAiF{oYkzeKcsh&5EW30&!vRq^Ds6lT&>ek-%3=xJ!)a^dB%h`R*LEew0#|gq*MMa#{A7@ z1zBNDZfZJE|29@9VZWU=#?|RRop+d73}8dk5w~O3;9G-J8a{nhQt|qNhU9*!N`)&v zygrG|_Hm1C-g3yCZ2&ly>oNyt6#BSIL~_~>s6LUTrxS9P6j$!y*T}=*?HAhhB65V@ zOJLut&w0_vM9Gzv;?^*gza`5*RMrmpPs{+3ZCjN@1Z2WEhOCx(*A z{_w%obG^5|theUvFk^S*ohGnl5e#D+KP$Od+DHc36L5wUp`hq(^+5!m2lnri#!l)& zJ#kxObX~xgE0#r${iF9c@cX;u>{yo2=Cc)puL8oTGCl-7JT+r_O2L4eKW**Y2ZL?f zFnE5XUgp6y{LFBRo-$fqghp{M&z(_KFk1a2Qd4*PW%+S^ZAyCkyMftA_{0%->h=D) zFt-b&ceG9fpIoBb29mNbM>M2`*tnC=$@ScoiXHo>#WJGFzc>t!?q5MwqWIHT)|BWhT>_@vu<@{O)`0X2QKo* zZx`Tl)udOpU95LX(g&gS+MU+#12{QC3&9iLMq||YdR~=}fneC(gB=6FU9`*AfXe$- z)K2^0iDPK%HGVf3Ia;y5&POU9Zs7V}V+0`5(?jkV_5*q7vtg5V23RTlMmIVN|B63F z{ISztYDR38z(Viq_LT1&=oM4I8{@PPyGFcF99~u(DsI!0U#?Xg*~G~ zjK?L;@}0x=9k9avjdd{g+{vC9SkcEyd*$`pG6bB>F!#C}+uV?)O~b_&A z9zB)xJo#zTq;lq+7aSDjK=!ITLu~mevuCsCDz2JJc_BRSnIZr-Lo_`(-cbP?_lfG? zsE=1`f#~FMF;721@-AeSJP$b>Z^Rm{(dln56n|uG+~eun+y1hrc-IjE8wx}aAenW~ zCmnC4>D95X9N4-IxAgNN7;hw18n;$bb!}44puB*WEBI1-{t1Mn>vA}0)lF?2Q8>@W zd;jNLXy|ekR_jX1`PH5Wxt0$$AZ`={cK8u6*kLY)Dz2k{t5Xpkpr~%G*GN-*L-JQD z$}3|l-$h65-Dib+wzRDD>VP{HU-Eu4dRt8kj_KdVF!^&avOpajT%N$HfXIVBnGk#^ z!RbjbSA|Bw|HuG9`;GC5uDtmsSZ=)J3P-4;efLIo*EIyx4;TQK$^?TcwLFg(jt8zuL?$&+R zn33srMbWE_r+VLy{woFmXMUW0-#Uf828D`gKTdm0Z0sRFYl-Iv2Z10KB4=@nE%{yM|6)eVR1VrC0I&w%q*&y0F>q7mosQ0wW<~VKD+A z%dwLQlGk8L6POZ)L)b@gqaCNu5{g&6a|Z_7)NWy2{bu9;%oYGWCiDKteBj zZM*mWmhCW%eji)#Bu@s7XJ>DFK(C#o!dDwc8q1RB03I>$L}431mM-rDb@cED$8yztdb5NQCiZaAMW@&HZhj z@sJ0ACe((3CxlxKFPvS$2UOX1VX|0SxcdHiK-M^d7|y2&;8{)um~=kO5U`;TKXi|C z<6-|aFENh>yWbeC;sX>vA4yYWEq4tiao&)T`GU;vK)&eT0#1YlNsq!_JP*YA&3w}J zJ_tU(9pjSy?psiv8TiEQS0~RYA1G8ORIvVjV;|1O;;sifLR3_L@-=i5n39iuL-N`v ztn$ZhBo3Ext%jWXVxo_Kubh4jw7PgwIN3qB-U471#LucyyKIiv1s; zmm}azXv26m7(~4ODm~*Ho)FYC>LEh}lx$2YR1l5x#>y*uqe8RQ#Ksca6M}}GI~ng~ znMcpt#&uiq-nfiJ3f#bqH$#Twck29h0+C=~pY{ap#|`&N4YlCa1{>Oe~3V zDCx-q1VSp&TJCMW!(e+VNaL%p^LBn+5FOkj&hYgrV;IB;8`CDqL-bx$0?x@g1SkHYrGwtKfWQ){)Sg**Tb{17C8!c@o}IjZ&cX`vP@`Ow=Het z<4VA^^7hAXBvDp;HnuJIjxi-mjJP246`J`GAO@3c@F_WGPKH)C>RmqqM$5mk9lbDQ zKthy>^w_eeHUbbvGCj5ir1JW`^G20XdTXo7>GDCBwp){;tiDdJwiWR-G6dt@;6Ofh zwieww>^r)Ye7~{0Pk_4b^<|GHMjlbNWkdS9cg&&jcMgB{ZtvL<BPOR%4HO?@-;lIRHBMyMo>~d;<^^`@)Edve25k zZor?jq`8KQRoh^8>KJ|Qq|7mLB+K{)&D%u}T<`JyS zdkS+Oj%2iRg$o|&Ydzuji0|D42Ljb0udQA&fv#h?QTZcaG)9u4t%Qc295V>gzH>Le zxKpI3=rjrhQ&3KWpzLx~zHxrzVFR#L9LbSmjJbAK#cCFL`=&X-Bak(>xWCp=6f+3mE@PY_PslU#8Ji`C5Ph*U4 zciOR=m&IP*YCaK&A9u#l$P&3#=00T$l)}7LT4E`yQiB52ycVrqO0!IsVvx>@{ea@> za_>zjuo8mpl8b!iLYmcC#99|@W1D-|)gV%RrIK|$hQFIJU<`q7v7DX@gmXnRg{@}x z?ynZv9s%1an9Ai|vjo-0gxS^7MW4_deZR#lIz)6<3fRW=o{%vt#57~Yf#kHz#FP*d znw+M@`DyAs@PbHqc|+e?FQd~s^|rg$))XFlI4RvDKo#|d+zN%XSD1BAycz*ivCKd@ z1&{zr6H=Pos9?%JdC6(rhf`pbzOb4)xXfFNGsa9tinPvC_>&*BF2my{l-z|G8!D=b zTeZ7`qeF~a+u~jcVi%4$={5k{3XqqkuJGyi+65fj(4!LJxm6da>N~jc!nJFgV%@#= zP%X*ZrT$a)$5spX02rWfWT4Z4Fj1{hz;kDCdDg%8=eNi+@g_P$9b^<;v!q8jO4kVM zO7u8c8*4SnA%3s=c`_edc^_|3B)d2;ROw*T2Fr8$*ZBz&c~SV`7G6;y&wFgQ<)OWj zT19%R-5c#VgpRSJ{B%!tdd)Ktt2lh+Bs|>WtIitbVw)UQ|cLbz3Oz1gh|ADK^hoY+eiP@<>QtmIxW5bUOoFu9AV@-c1vxX+kC)nMK-_ zz>?*EdJ)D!6L?8rOiFiI`oIg4PHF~$IRV!!v~*U_u_=v7=xb({>v=-PB>4pDZiFw( zgG`@e^hL6qFLk?C3a?y}=PTGNk3+q(j$}0l#>1s&ZPzji8+2c^$BpvC3Fp%d-d!ok_Nl7=0pu zQe4mBs#1!Z_3IB-6A3%M%o8zs14WRvjM{)?y*~tM>fM-%l%Waq^f8Y01v(ySZESg4 zt|{s9d;HYv>9Qa#84C!RCM*`+kr>1az*lg-BIiZtlvJQfI!=tlj0IPKuK-?v0lZ(e zZxb5cwlNN?ZIN+J#{1Qr9@K33*i&XlJ%v@p+wwuR7rCuZ>!eh0lhsJH-WnQkCTDQc zh^kI~ZS#iu!3@GW;pghH7SWsWD+e6(ZYRG^33hwU4Eu;r^w9eclZ6nf6fHa*rv ztG76kR{G@zWMF8$5iuqheyBd>3ZcjenPtw>zyeMzXDfFehNs^+sOA>>ZD0zqyTL)+KLxdMuYfF@}Gz1H}q*M3WQr+ zRyx{M{_|D@k27;GqN=lF^y@{iZy5u&lK_@F>k;ueGh|hT!vuhqSZgw>BjE5)H857a zdtkWR9`XmhZ{P44FiJajP3VuTco0_jb5C1!(Zsd$4ZkM1B}Kj#)?~r+6uyP5`V+ye z*bI^lB94k99*sePLtThh)U?VD*lgAQpZUZnWEF4>BTPn_uL^8gqW(ii~I1-R15M}Vhz{}sH9XX3p z3D-hjNl_pXaz>RXZnbCC1u`!6`j(F%==WrS6JU$Zwpq5hiiX*N4TZf^!#`# zrr;BaVYc^vIx%72t#G=0^^3sPxO~+-{VLFopCuHwgvAQ1w=4c((M(&=I^MqFF+hZQ zWqq+QieQ|HU`8ABg1A7HOyCSiK#=o`hqx41#^ZRtsGI?8j6elt?*st0G)~`(`qP0i zEO4F5z#l*#hLrx5a!-zf?pd@@s9tfSjJkcUvRvX*3FNL7xZJ$EyshLtUkQ~068^Q{ z$bV}TDtnSl$0va1V3nT0$ht>A5LpJy0FX5LNizMlL6kX$xNfUd-f#M5fDklxGH@9wr~-OyNgr`VKE+sEf_(+r5+m zd*O|B#%LZZ5E$b#>cNTOm!GjGJSUNFWvG>BnDWnDo<&F|Dtuc|?kB*ROu2$&Wzgwmj?@2u^^_a+&L`0`9HLpm5H)C+7NU{?(a-^7ZGS z{o^po&y2r5k8JT%!^S#i6?)p!H&)xzf`gdcpl*+xH%F0{|CG4@!8UL5vZmbG!c;tL z042mxZ)`yDYPAM{DgvNWKsQ7IFu}vU{1JED=$e}{Tk{gaOW$xWm|%7YgNXXzQQeW$y z{rmc3b?x8uxIRirGfy)zW#lE75I+D63o%W){i!JbnEwX6{44O|UqEwG(rcdQaLNiz zNW@@D;`MEq?c) z*ffsW7YLMQ!6jtmG=Y~_AYA~DBGG2^BKTyMs1+|)dXpT{`yjNTk@fg> zj2PWQ0A5C(3kqEi&!i#8<=hAih=I=dNFtSOWS=YRHUQ*{eDVShVP%U52qy^uT`ZSGS0B8(P zEFQ1i_(l5vh0t5)oF(L`wcO)y|3~}5a<}S;BB6wmY6nz$;0NNtBl=K*N)Kr6nNCOj{#aA zIpomNoz?FNpcgd)OhPJC22n2i6Bz)mf)94o8_nSK0?aSK`~!IT7x2r!%DY$!<8*RJ z#Wn>7CDtH-HNAaW=qU>J$*8X@gMeKegD=N!9Xo5E^ex+y?f17m$M=l6*%sX?&nm+D zc8?iEESuQVA_k@^VIhN;jAao;G1C+jH>w0@4tx0}FGcLX{zKW{6>>AWMt5X@tv86) zazXUu4CE{sZXTEL`p-0q6&cB7C%_F*c>xy9?XX-x%LUAqn}N$G2jkA^K>cEaAra`= z1`3^Nh41chY0Y}$%qrV$11qmPo0e54;KVi>WLpFNLTOK1R`|Vorb|!GpTE8lrd&U( z0r*xBnm90i#yWbk(l^`;TkD(>5Tn8inl}+TvJtrC!5ld+nkAy--OWF24gF^LJvXe7sR}`@W0W(_BJ>w~bKm85CJKIJ8G)4e9AtN=)KX*E3XF&&pLM-=@ zaI&)gyvo18dW%APfimSrm$odolmMELNtAj@Qa)1#@)QJN5@j+aAkC8Kbb67!-miZH z=2!6i3c?kZ&0iZ8E7htcSy)uqdLePoGvWbyib8weT5ev4)_6PsmH>|1ddd@>m)1PR z-}gt>@7*GJn?6_^Arg_7NNEZQo`}boG>vZ%9yDVzFAJ_$NHPFFQc(Upk3r>aE$M>mG{|nCjoWDMb$M=i}`>^G;2I9DsZXNWZU%II29V6u1NVBqM(-0=VAnScHx<}l&}Vvzlfg3982c;${Dm= zfy+Da_6A(u!SCP2zS)k$!aN%UqIZ(FR^rFO{9kIkQh#r9g&(|!08p367oDNZ8ZZA7sD8nuO$W}O|vBZ zd-)r9e!)TjvV{W|!QV1cvy~Uy&HeE7iUxn#&@1nV-m%tG#$lXX`Da)Dt7F^-Yjt7R z#->&3UC_@GmTXO}E@B>hy#k9x z4QcOiNMYv5$1bI*v=;=w?*LtD8ZIM7r6 zJ_iB~&pPhQ0=_Ju>qWf(%S8=-7W1J5$BY0Pa(jL#dB}GXjAMt!lAb}ASsh8GjqSQv zmD-6mVCHg`_#=3JR0^qVfrwG0E5$z=4x2XLG*)N#qX$(q2k`WY&?t;Lp8Rrfe!gKF zHr9F34?93qqR-?7bc842x@t6B?v1eR%`Nxpdv5rs^1q_9E!|R>5r~}Za{}bdVG7~N zCbX)8K}}&%Scsk!1iBPtCHrnB0=8eG1*s)ecFFdF31gvIg@&uAq}fwe)fev`W7;h= z<7))#rh(CNJqYWOLM4p$tMv)lDGj#`U=KQDIm{nO+IgaDfRQl?}rsNjoBbZcfoKG+$W~c)X#v5tScY8IOOfD1cCAb8TI%A1m`+*RKz@Ysz_2Q+j)2wa!9Y)i@)M z8dp1{1`R}ErAv`RIeJQfG1QbmNJx_^B@AS~su94NTed&28*dp{GI+WISipIKSfhgR zz{ZTYs=wbpYg-P#MggGdZ=@@g2O#`5h^C?_4vaH5ZQpu@+GnwCEaroH%r#*XC-Ou_}?;iaomBQ;@q=)&j05*xRyG z*?+$?SM?hhd~gM;{;fkI%Kf1H$88h!@n;R;pr)Khz^3=l+H`lpO%-)ndvQ9ONfTG! zjuw6U+#ZxNxQ!YJC^8~TiczS!x79`lDnn%TSWU~F9+!%$Yk8%or92RSJ_JD#Go~8X z$0~r1l^=z-jX(G3Z(9#K&qUchM)X98_2~`vJ9}e$3++`N)Jg!X%G`WmbzPIief5s*O0 zT*BVgM>DOVF!uX;v9%|UntKcK82_y1yQw1<(0YX0-@QEBLz@5>$Ox?8orusPN>0}z z89J1&_Xz?@8>vx{vJsk|r8c}=#7eu<3NBXQ0>Z)iFnzW%*acxIcG#7UwhU^n2iByP zIu`JoQG4>+{#q%u$F!;_+)Rl;N%v+W0nokvX-1x3W&eJffgk@0y#A>BXvQZ0gM@2y zR`2Z(@HF9)5-tom>m86R*_2@W<NK#G|N~Y6=!R#p-;W+>Q%zm_*oaIzhxvW zVE!la^$+0kU%=%LfZsuB0cQeO*0A>`3eC$>?xig}jlgU4>oREyAM4+@W$}KWg&mCu z1I-rDp0enC_qaU4-MXA!LR6$02lh_%IO+#8BliqYjqvZ~9rWQQ=+vJHM$vW)(kb_zZ=yh~l2{(PF<_mwl6N6L^Br!Zs467(S2a z%PnJ$D-i$yAOJ~3K~&XlJlw43nK{=Jt(F(&tOKZ{Q|<5Hfe(7WW8#@!M$@`u(pC@2 zWIJ*u3V7de4={6I`R^*lr?RqBVbdV8>c^nx$cYVy?_9o{m+X<&{f|P?P);rKd9mPp z$RH3B*u4JJ45U}thdsXn^9zVH?7tPx%s>JSsCdI7uwc4wWB>jVi;P(C{Zml zGlE64*UrGZx2nEtjRm@4(FVbJCS-Y^zug5-tQ!Hq90$RyG9IJBB%YbdQr-;GNQ^>z zzlX$8XfuH~TEJGw7zH^sT4Y&t1WmMMm_j5L9|}nD3qo%p>&3{+#d2p}4^{fJdF2L_ z{|^z5-R5#%0^!(YCIhk^G`)i6S753Q0G!flEtoN_tkFOdRr&Alm;L$Zmj^Bz zPCyL+gc9nUH3GssHRcT%P4?;J-i#`GlenxCH@w(8ws<1bSHUel6CnyXFd@olK;vcb zhQaA+DduDINTA}q4CC6;hhjhpZR_x3Io9_DdD5hn!~ieaZordNw%+i-v*qhP-EY_5 z@QS->X^xC74VKx^@vVNEXXnsZr-p~TNVxyyDu36j+{-0WX#_{cQX_WYqxd)A5f>Pp zI36RvgP!wYMd)-mS%LT}7+k}{-KA!|eU)Mql;j$JPj1hiA+pt(jtme)g)ds0gL9xx z>N`eL^}L}?rygs0x61K_jcUILe&pX;PBxrqwmigswqmsQ@#fiT`)P6j3qIFTRu2(8 zt1b z6^A0&S2);HzR!e?vRZVWPQ9(+qg&jDGJJyKUtRAgQ6H`E7T8q&@2Q^>K(iVEUP1E@ zr1^(<|ECw-4lubs+1t)k838nmw1jR5BKWxiU5v9lH_6tO1=ly@x)=kiklLYWXk`#G`MIw-UR2 zPiX>8uiz5vd%-C3_QM3n(sEejk4*1@g$5Xup^NN%o=XKV;J$e zc#&-i%T@OMzrV?Ge`WyS>;|(j1Hg^2<&42?!s#tEX#~BwQVfm?9C>KFtW{R{6G8Oc zCzllmp*v0=G1PZ>;GfyY!QSFB#?$%jS8@3yHacLd@V zDDOVS#O}gtDG}Hr8m!UAw>#}vT^kR(Nw@KTtg$X4)JBt&x8}6Xcp~K=0A}#AFw<1+ zLD0P%Ndx6TEE5L_eO(Df9c8_0NX*c$#noN}FQ}B)0Wwd%c~yD>nhJ7uG+~juim#?= zV7IQH6}pPe9x`nHcA)%k5eCJBp2zjadjxUBbxHOJ-sbn;~wdv4Z<_Y0``zz6B_hCz-aAHTl=?|+FAV7cnH7u$+< z_9CavxxZHt8<{`qDMJ0yMr$2@>_f+h-3h~y5p6D}CxbSr;ilnkcz(xnC=3^OE9@!% zM;`dQs*{{#mE6&*$L_n9+_bBFS&vI&1X$%D!NwZ3b{zG2OQ-8TDsqk=2?#hDtMqo| zndPJ%eQ>4xhYM5ooAHaMbPTkxk&DsSj~+=fxTZ+8fo;6<6Afp}49@Q$`WI;c`5;Rr z83{8?lV%cMf`~;sf=nf>a*argCJ~=@$j-Fgu@VXqk}y#hT0&6?g0~^;me;dS$Og(|s?`auud6l>C7$aL z>Rx%naKlTTIa>>yjRIg*RD!pN^5gjtM%retc5txzPV0!D_Su^RiyN9a+TS60hMLU& zn)pbCAY;za{=HT zY7RiAzLM+Z4G4|*c|iis>=!;rHU^{HfWtXs=5^AvMs9J)>iNIE1D7}XyS|G7z$Q$s zM?=lK7lk^?|4rekqjV_^ZsGYP*gPKV8&+_?v2G1QHv5RM&g*p^nBu*PW@r`dR%SXG zs<&(MY& zV0hIH%KPWTs8XQMvLx?fUVvo*Gl|lV31&FOM3o1$OYlvfdU}s~=mxLK9(cL|8$Lqe zr6yR#F{pShR`;2Kg$ev3S^s5wiymirVLge$j3c)+^ql^V6N5oX-iqh5*$QwhBdQElfp z(g{~q<wi#k;?(rOLhG$vrs^-qK$cuN3<5E& z+Uz0muB3CtFJ1n*WuDn`51_ULm=IRcfX>+HJNBwX{1Z5-@;^-)*}?#>V7@>S1LVFD zphy4XckJN*P`?N1sXco5%xHOo27tEg;ECg9DY$=$`~KfS%LU1z8WYPrxNtn85Z~CY z>MK>BH^G>Id0TNO3g4qiH_vur+@eT6J5}EdACF&0`$|r2w#$AntmgVOyv z+*pevxncIo83%F}+#LrR+{$8)C);)%XkSZWm8Oa4)T42va zT>88d>fT-tHM>K!J`;|Jgra$O1+QGXw+cQsChN6F7&FE)%daab==>|kYQ zT)JiYb$C>^(q#XEd&xDQ6d z-22xNY(Bc~hlQV!ho-)~(Lfb#xL=@DoP-9Xl!})tXHD{##Q?Bq$p7^MS{5Y5kGy3p z+i&4Wa)5Eze{DlOfB03v<{|dOki5%-`D#;N1qLEDUAziNw2+SogHDdOlJ$v9-mf zGqJS3CEpumvGvMzyva54#KL#vAD7xfn^6KY55Z-c&mma#qUm(1i%`5Czt+{u&D{8J z{l(b#l7>aoryQM|H_}@ZO5+%;%zd}n|D+N6Pup)7?Ax}l%P&zS(uVC;1pKhY*?ZN`!r_7Nv`ofCpgiZ2KH3}4XkkOw+0AwGc zY+);uOK!5R`wn)q{9Y0`X*DL4aJiP>Ed0BXS}OjP)_kq%!Zv z(I~vep0_>Q3E&x6d$yiCSEUly;rzx>G*M zoUVo2M$w&S(3HY&k!G@gW-MX^D2?xSiLCMV$xx&QkTYmmfaL@D-LrqNb4> zeftPR9H8|{J#zaNfq(GXM+npaTuN$jd!tHAFc+{(VA~m zYasG2Yk#E6fXR>baD`6t`mX&{)#rm4aJ=nrB`>;wa+~2Q;59le-=z;5CZP|c z0ci$JbL{CRbXU=S_n!}#inOPE#s305Cne3E?2j4D;x%1uJ&J1=q@n3S45V@-pL-sx zEc;K(VO&8eoXUU|`!7|uT{B@fMV_}7D5XjD`OGB%rk)h228Ku>lL{CAquRWW4{O;PGC$n&r8NK zy&|XAx~eV`PXJ~lT0qE{!I+Y4H_S-50$5n`K_oBAjwBX5V5+|xez-ts&->aX@SK1- z)%=xNy!6XbKBonkqRf#cWFH9Q&zQgE49bkOWYBT}u5aMK{tI~fhw~$z z8JCFXtYbnH3=}rUJ)W>*XsKRC5qga$SP=&bKo4Zt?pJzN%^R#c5hEo_da2PjtujGW zx*5i{tS3vVCXpJxRiouK_w>(>H>0u!OCQ5U<&-*t;|D2?d2I92**?2j-f@IX&MZou z3tHA^rC>IsNLZ@!n*Q6;v>acsG5}L7lfF-6+mL5O=;08l(~_Ab2S-#Y6-lzn^&?RU zj7but-T_@%j0ltpt=ckfkjmN7C|y=DYf%Kwi+^t#ZjBIrs9W7g@!#8}V{h5~N7tp* zn^fl_nn0A0K*)v%3;^!{UjvPv02W?mY$`JYS@^+beO>UUImp-%0_?vGKC z>R1Y(eWK{KwhpAmc*inkcKQJWH)sYQ?MVTzQrej?N#q|hc+!3UF9f200i_9fxyTWi z%R4CR9`?L|@)bFe8p1{@&H!I^d=|04v89u;oSiB1V9apw&UzBqjQt{rJUUeZmIHX#=9X*n{6|@Zm6|cmMm$oc~@wN5Z&>AxB$5 z38#8gEJ>0lATldWf~VQ1DCjKP0$Q-9xISW$0Kr>Snr0Rhvrxc087)GLF=BJX>>?3} z%%;l1*?;k{?p_;q_p0MIQ_5yU!7cD5G)x7n(MLxfYrWC~V>7D!pEAx;K>ymlcPBq2 zR8jC%afDZW8`_6pYn-3YXte`2&Ra$R1bR?;I2vo~?`#C9ygxC-Ioyw4xdXaa6-&|R zV*h@`P#3Fh-|Z;(W^rIML@(H0Om>Qa@+?TM9gFy3XhazYuS?_E-z55eRNVT%5$E>Jw?O+>Twgv$EG?LB@qdUoO{JVmP5-Ml(bPJ(}f1i=@Z&-y0n!sY;6*(+~ zQN0zgN+`VN2tehNLs7Lj5;c}OqM-7&#o`E*CV4g@7eRyua=hxoUg&mPZ%c5tq7LfC zG={nD!rEJnQPZWwwghQ?INHjD%R-A^=pc^#$i~<&`QWmK$draFW}`b@bwSb zIo~JA(5|fy%(+GFkq&8PEs-`!VcMsL!_blFMYeph9XKKrKU<1heJo(TB;63vfZ3 zOwqEs9bYuD6LUD$FSN}*Hx~H{+6B-G{_(k1nd&W=L18p{X?EM$GU~XH+6B||gmuUK zOgNh$Cin>ihxLv>c4!!BmHMsmqZSQ1@91+kDZfW}(7oSlV_;?n<*(M{hX`(`-kmW# z6}ECM+yjvoR&~&NoU?>RXY&Z=N!k*~(C-I~qWH(X)ApS}6t)HgS|)on!#yC-UGo-1 z{?sUZXBh#U2Uxpf-|W*2Lwm|XIL^@Xx}DP({XgLu-TcM*&LbQ>-;20n)#En4xe z$lsJUcqE_hN9PFuBc}|B3=riS=?bJ-i~;Eiq(#oV=j%YD6-R=B-;HN!2Id#wd zpUiuoRH+ZgPFWWyX#|cu!)}bzip*$7<@jKkHw`yd*@Dswk}465VgO)`01$hXMmgpM zm@dEtKz;)+e~IG%{!bwPC1aBb%q8!|E}S8p+v}i8-q@8rHk9i}Z+9Gm%AknuxO_;d zi3Z=F3dT+!ctEv2R<2w}{BgYk_z*+1I;4?m!yh6D3!_>*(V`BiV_8X4#( z$Df`tuycQNOGj6);Gz~e9p0$h=K+XgDh9?4{_rS`KRqL^TpF#Nh>RjKT z#M-IM0t`Rmipw)#E{-q2cLKyk+f@c)XqGClZs~W!LWLdxk}hfX&${gg64Q$5DYmxC z|CWM(1g!wO1$zv*Qljeb{T7uKw;xFm1=zD-lpv16;Fz}tnS)2m^#%c}3`zTC^$pGU zmACnBd%xjhZdF~qyQ9#w3hdGN?S;~GU`Y8t9T>w~M(!$}`}DwxX?8;Za+dv&k0=^x-Ys~XW6y^=sabX{pD@C*DkI|5Pjh_R!^J@Xzsxx6t0+_+}y_Jo^jVn8;AF_ zEul=`6&ef&BIA&@U-?vqFvkpl<|4ypEg=ysbG)+=3uQNc>qhp2D5+k5%HVXK2W&rk z+%`Z+fu%0U9HK6i=QC*{LrP*0AkA*SjPXH$ygLk1uYJ-)Q4=uDMesLck7tog#rQ)c zW9kBC3dt5t`H#wj7^Iwxn&1&WEy17}03@J5L;r2-25if~0$SdYXhD9@;P=0PKmQAO z`vX`mNF;e7xRtls`HJ5=5lCg|=%%E@!#QmZl>g!h{bGn-#FjS4-%+=}Hx8@qo~;u5 z491Tg7@mzsOYiJ%zGc$%G$!uI2RqGW>k12DPCUR>&!=R4Srs1&BQ-nMhBR=n~nQ9H9l9`YS=()f8&kSdcv`o?Tqk+<2uO1W5kMLS%EpfuiL9Yzf#)OA z=s;8WDYT=6AZuG%p~FQQ{hoG=C^}Y|OD<|ck_^>)-nC@rW)LRK6F__g@deBa`28>N z`#*uVKY{l@fqd1IAS2EAI8c$;c0n8_2lehLUe5$uivMZF_twKhUZ38$cZSD%VV9P{!Y9ApKvh2aUW4D=Y&Rwnnm7u`&cukmZc|+R-40M4+=S zBD2=Uf(QxW7$pSbLoA@9{Cmg>cY;V-%T;f2Z+ZXs?)R>bpyyHSwP{#i=lb2P>lG^*K&_981IUI zR<$YS-i38YH%H!8DgQxv&ZGwOT$kap6KSe|wXkau28UaH+@K%mnf2YvqIf%WlFFs^ zle4yoM0uZ*?s{Q>NiyJ@_dX5Gsv9^=m0i>bk^x+S^e*!_y~vv41oCY*lHFepno9Lp zlNn8H%LP?(OIgc(nqJI$T+KD3J*h!VPYD1m8TsuU*FXM1{_~%}+nXdvWa!Ds5uXO( zz?(f@j>%9B?0IgV5jqYcgPzjThH!VEKZ2gJ`D}2D;B+cb!!oxFlEsm@U);e{?vX~l zHa_COi;5>Yw4f@tJ%)Uv$iO3>9>O@*N6F>!F%1r2&KVSQJ{T>wF^S5(&10qfKQaAr z=*iyC1Kk9(ah=HD|2-q6|J}C$u=-KhvIhsxgeEBxZch;A+pSrxKyA{F^=P%>S9N1c zn}c-#n*$$|fAa)%5ou4s>M+~3j>GF);SkyT{p}sOabNlSRUZPKy$S{eB*r*_J$kGo zFjUE6Dn>I_<;~RLo_Siy`Zp@yTL!R4fh$%|%ou}LX-jw{B4kS7Bu9x+N_y;>g)Qs8 zX*;pxw}QaLowvuaCAa`PVhUs?_Hs;s2yZ z1DoH6<>)@wvxhuKmRrC&D@g_!3&0l_9wo`?x=9GgX;h?w#%ZH29(hnxa9L>!evz_LpoM&OXR8PNkgH@1cx_ z-jBf6{7PPr93L#7m3%l<%})t?UE7NoaJ?*RDMov(RObgMGJ(Gv?o|c=9zmCH*n*a) zHO?%#&i`Y^ANU{mmuLw`vDC;NRMH5uPOupQ%s0<~TH?#zIK6Mow}U(`BC+hTV-kUa z*}NiD^WI*^+>+l2TOF^*s*Fw)LGd0m0~gz|iJX0fy?#fDN%ROusf8Avl|nn2SGN;5c3BIrzZG}$c%qvrLPt}+n4<6O|o+aK{XBBmuftWZ}JX4bljW~xO@?0m9H4Cn%q2~OnY z5rUGt2djRqE=pZN&$m70%z^!*;JwTpd9DHifpP*71H__?r&-I@gqXdmZ5;hMJD$&? z3mKMSpRNpG0n$bG{e%3dKg;lM`2d&*m}b4ty06!UFM*QECtxuOgl24xVKZdOXbCiI z)!x3mf&cj*$p83v;2-}Ey!{s@e#b;WN`!@`ahA2xGJ;G(YHqnn`QNUC9LYP4>los0 zH3D$ObG9D3p}-GlU@I?g*WuIQnNc1*ZeUf0Nyomv+yi$*w|jE)QRK#oPad_oEvuE6 zO1-NPc^lKJ9UN$xeGU$y89_r^y3LHNn>r5%h0^HoCJvkOU&;GYM%>Fz{?9&a%a0wn zfzMTP>`HWFrO|P$d$?VATzP-J*6nTUOSNX~oz|&iO5=~oH2}d@d`&`cT`OzCt=vu$- zTR{lK&XI=xJ!2?adwKzA9;ZFGkp+n zoN+S?u9zHuG;cf>@|K+U9N<-6HVt2OKh}84E%R`^Y8ak{6+6>mU|xVJWS`GUw>SZq zgx&za%cP6-orU{AUH$oCmCyaJXz!d-HLQ^>5=KYUP2n+;)i)BoaA&QzQuNl@` z3qjis>$8&+uCmt~*%h2(Y-M8#&VPDdKTFV7z2ENdX89*Et?)GW@G3V-eN1AgiXQ=B zny_{H0EIUA7B-Twbx~M@fg6+aD=-%Ycb;6)EqqXvZUWadU~8;fBe#CGiQN*Fq;eeo z%0oa}WKX`;oAqeCGG;n{fBgZx|5a~=F@e$E$;uPR@aZah<@pNY1u0*(KMNQM*^C8g zmNhoL6or3!0g!M6B`u%DAuO6;){9!> z0HFP|H6=Hy`d5yvs(GFE-4 zfDP(H&<^!VAqRkzCGwCbDDeYag*QHXm91KtHfTy&ABki;HnXJcWmkF;KB?$lhn=vb za55Lu|Igl=#oYER_d&nvwa>kF9KsWdA`v8BlZVK`kVx=i@d8Njh~OCsNFo7Z2ttm- z|2oEil7K`IK`|cUNRh$f#fq>cNaP`&t`j0`B9H-3lCOR3`ybBuO?!3mP(xSu>a}+7 z{q1i&UmbmC@4Z&9o>p~rOBSclo_GJ#jWN0yzT zk%ilVGMAu&RfR!Fk9mMeIaC627FWV%&~b{I&pQSq&^l+CYfr#Y;s5Ev;JEmRbujYk z2Iun>>&Bx5R;Kly@hI*K_X>+fP0$L2TlXfXF)kol8nd0|8V7iqfE|@OQV_sWa<_hS zd?#v5r;qgUlXe%lBOgWblpsENxqYvrZt1s!g)8jDK_b8|^1H2bS zP%6qE&Lqh-RQN{@Dg2yaQ~^1u!fle{0hlIXd`y{P3J4-p!4!`L#p8LQ7LkeCUtfbR zFOhGqrO*BdBil1Jh6kYs54X2ItbquN^jMyGWg&kbfO=$ZPphrgL-4m0I7=ro23b*3^_4~%y!KnkOmTBu3FM+ zNNIvF@m0Et4#8ZFRj{_1+4uMv?lY;C3`+!Wzi(N+PK7lq?Ku|O?dv*1cpWLnT)q8c zy)2&e#t?C-bMKUSS*ySEvs>q>?8Jh>i8Z!77lkio`Qij9D=ze6SA>W3%7u5DQlT$F zQ9zzkT!a}RPo@Ac8Z>#n@y!%C&lxIm7ifM1q;#9fBwVGjR*9G!{A#4ZQRw$J;&jK2 zrNI|*+g@RGV?Rj+H9N9Uvn+L6RogY=e7a&$=Y++3jfhJ8UF*&o#68HqZ&>eSA7pqyG`F zw>P{N9!TRJ@Ql2_0rq>$7w_cQ!+h;?#IR!mD*P|J2W}6hgggw(ywLY1M64+Qs|)wj z?s6@hyVa#@`l<)&P}|M3LHKVCQ&o(CP`-REN`Qkr=LT-vDc)@0a_ee6S|1_2gE&5; zOUKmrz;Ku+I(LJ%r+41he+eHNL^Ad2jRcmT8?weAbM60KTan?tu&Z3*ur79RRXiqJSI~Pj@3jO7& z&?eOg$sN|lKSJ3-B(7kKS*$KCIL598w)c{Ug#ROv<6H^_w2WhKGm&D0^)rTYfVQuE ztAA_Ee`jM|+vX+lZ_&IySVm=buJ zKtcO&ieocj)TcD~^VYCIZzA>{p4-XKll#mb_b$k!i$s|(=bEpYQe6c+Ar zAc`BCScyY)W@YUIMww7nHds^6DU4wLTxZp#<#yVQe%b8ndUY}`~nZ{x~#5!I05Bw5^ zJ$OqAaA(lqH)Dy9y)}If+InnOlfg>M_oy5s`ac0v0A&89VWQ=QFsQZA{|*c&R_7Wg zI~xk?GX=Mh62-R^@c)zbeIQ)|5i7Ny+|gjWDbu&F$iv;UY%us@#4aUzfLO$i?GPaDWl$cF~4Vd$oj z>&`rKoVjxVazKs0=vbs!!_6~{#%C3pph}Zjge4QEM(IADt5g>Y?S zs|;w{T~@lW&^8BA{xX#N|G1=3=rljsGz^fn=8<~m-S0jGH#@#*$1?(q(^&tf>Ya%f!D&8!jfeDr<5>( zMfkt^0DSlyc>fN#dZ)raBO!U9$sD*E30{1DA!B517;Rd>T{6?qzO_N!diXiYPoAq! zRaef}u+Xm&{`m+7x?R&zv4}#u+9Ls_csC-_E+d z*BDl?g(76A!sYx_ zG$H>oUJQuic(o>|GjLK6z^d_0p_q$jUhO(Y1_0flZp+e-dA=Sb0K9p4OxG5qRvFlL5G5lLo0DO!P6=CO^5;g&ROrdo| z#YdHP(ahGedhKU0GO`)vM4+4`m>;F)tbS%>V$fu@MfE}};3QbGQ`Qu88+!7O4_f-y zY>Z4QP&0%+(*!0J8H0BUY2Za>&1`WDoFsh5{=)^|jYe=z`jTLd;#nkcic!xkjp7lC zg~9PVgK2vwkqB-s{G&U}wV7E};5B{AffUIzcHD-6T~V?TB_yLY1bFaYt;dsoG~gG(|(eD2_+D`92jfr@=M;u{Xa0m;&Ih{5x0pH-GT|0q{ov zY%d10pxj3IkGn8{g&mJHaE}JpVzR(oO`UBDzz_^jSn^pkQ<>DlpcQbaE1dUj&r)q6 z*m}fNULtOHku;2o5w?!PVAcA6iv@7d<$Jj9j^J|}>+fi@%tKiP#SL?`f1NUi$~`t{ zHO1)s_R9nFLY;eUxq$yi9VIvw;@ZnWVN@yeY%Pi#bw&n}W#P!`yll!rbK$oXI$4E_ zkXyb4CXseYj|un~870D(U4KG&b1opbBFIPISdxec*(1$`=>Im&Q`W#~gh=*RweSNL zZeuRC-pGQc2kQoz3-~ClY`qDN5Y&9hnG(QM!)ppXK>^e+{~R z4}ACn{O0$7w_gW7d;z+?L~>dqbV=IKRD_81;Cu|C$0j&fkeBbhi%4f?UfV@?qJ`|F zrh7bEyADP@35Q|DRl6N)?|p1m+tQOp5OPI)S?_JOl!JRx=iS_UW~6pr;yAr)NA!t# zxeqnZ^RbHM#{gkos`i9 zj};)1^kWtP3HHUt{BtgvLTcMwG8xocOv6Kr^X2~)hOtv8p|+P+1p63`(_O$(b&qnk zXYTKCABQ>bTekDa;1H1<_5xTDn~r5*?3r_e5xQi8I+ipiGeEPr3Nu6);Ut0lNRYDWtmrXcL%ed!(I)* zYA~YM8y!bf=0+j@SU8eVp@?1#Q~^>BcLt`AAn<~V2wpot*yvUtftQuZ#jn6u_-ht}O6J3{D$GtNu zWP0x-^rb2{DloObw*(^;B|y2%VZZL+!HQtK$qU~RU(`)u9Dc9ql2+@Bc;CE-MPR`D zR(6~Lmhb2o+BQ-@D(Y!+n9rqs@?eaS_I*Uk%qsjd3m?!b+M5&IEXJ z4}fTy5REQ#=n#drd_yXAkqHGAzV(Er?wp1?4a`-OA;%In7&S-u6(McWaPytZ_lCvl z_Sv_Hmf5SUHOnWenyJ0LGBI%hAH{SX2GJ6Z)Tcs4{j}d&B`|H-`1`DT-&lPSEqU`* z9S{oa+UN!z6$L#lXS+FXy=K4HpJ%D=*vZxTb3QJtZw~iUhMO`;a;kgM5bt>DnQeA; zw{yV#kcmW1lSU%}6>^z_rSg8k4pgSo%QCtZ1&DdVDfqTYaNWy_-p~dn375T)3P-62tIq-gc z&)O_h`r*rs!*Fcug_f1QSD&vm2TSI@GveyA+KvNbRzB+Bf3>#@%5T5i?CmWMRKj@q zUFe*5rZe79Cm5&{c1=H;QBrsk$P&wgQ3UnK$P$4_;t9}x58PY=@85vmeG0t&hPwWL zkgNrmz(_>^R02a`jCQYV>!FjaU}C*q5zb1vHQZ`8iN!X)e9kR-gU}Ur>l(Xl_0FoF zbxR!q7yiy$?Ur}RDLVnTd-bMvwJlO8RJAuRc;QgIW=#(^x$N+=Kc&877@ZE^=?V@G z^k~71u6JMyV$sb34+gb_1wE~wJsTWQ0>Sy?pmc0`7nh}KzNhBHWN)c^Zu^6|?VoV` z(Q!?_a9E2ya@8H9eIG^81uxR{XRXx{C0uLlJxMXag`MS%SvWN2mafI}G6x+6z_{j!iMnCp$bS&Cs$hOu0~RW z5P3W1`d+bP$STxS{joX8VIw%&YTNd^3``h?1MX9CK~P}S&Srxe(#Gu|86efr_!2>Y06{y0a zXYoU4?Nv-+@0kSRsg!Z1Vp=kK8@-C#+S)#Bx?4)Xj4RB11>_q!L!I{k&sthFI1FIY zcjx3r6flmvn#bMJH?jqdBW1D|Y)6;}g5n7I{P8puoFJe}$0{5uBldJgKov`ev+N0# z)!*gg?C6{^0~CYZMO;_L%$PLNt#!e~_anl@^w(-eSe*%t(#%GC)j$a ziZ7<~AX^wZzTTu^&Z}Jp@g7%K%Ii$uEVO|cxYh}w86870LBnB(K5+x0O72ofG0N>te>1WSs)CwL1xT39TyB5gDc-O`D z-JvDxG72xhcdX>M0k!~=VT@#gOluK8BiOoLcBsRH>{j;ZSgaQe4P`v`eNA96{3yLz z;z}<_wkuQ@U8m|^-9DN=wEY`^)prv4WaWrS;`n%phL@t$_O%yT9*%n>_&0i5U}?PW z?76mg4B>q}*40uoR2-kdnBf};Mfqx{%Jw+ddSt8Vl7vsIX@*m|3|J7CHi(^#d6Bly zQlo-_xltP=$*n{w0X@TU=z}(}Bv_qixWa4sFQ$|9wG(lFqrTFO!^Cp&ct`mO#J#`Q zP?$8-I*an){s9|!apx8C=f@N$CyAKR?Gz()e6Sh9_Vg5ZNd zWH}4-J}Xb4!ro7Hv~czgctJw=cV5^8|@2x)nX zFV*iA0pni510^DmO_OHI$)=Q}8Rqz<_^XbEWzx#cE&wdmIz$f4S4&V6` zzns$UTPf|qoWXf7S~bo9i#LEwe+JErl!45Q>S$Ydj~T4S3@Vy=QcH?6>%zRV<@2@k z{FdSe;avZ7;$~V29as_sSDu(+RDPQalok@HP238k6o0l2DE$c>A&Y= z7{bRrTE&>kh3FQ*JhnNGLc4Le#=m1B$$P-OX=nzKxa|THkR}lAMbNBVic1~9v*1mh z7^vd7Q3RW^r{rgEEdg-a#3YL9uIoQK>Hm`2&ztJJ&fqFUAXvPaV{oHTcCQ_)l%RJz zbN@!Dc$C@ddV&P&|8s+dA#Rc-a*T`?a0lfJXxOfZPTzNSl zNy@6cq5L@o9N`pt`)pJ^SsDFo-R#BEwbInWBkTFS^C*ZU^^P0zV0@&oOocXxd(2CE z7r#IFdZ%ZDeq#Y^A2~;1%EJy`v^?C}`SnFW^+B1T?C~3ANAa~I_}ofq+m30g;Rjz+ z1&Htu@Du;tJNvz>?(V+yv!Ll)k#-=?;A}a0vwqGdi6S9GH!0`GP(F930koI+5)QupJT&fCLkU@PC;`=j;g&>t?^yW4A9SU0@b&V7Nq zb*%{hFIv3^fo|0Eg;j)WT&i&M^!L`ycWT#r49dV5v;qJo>=i`=DFeYSA zIkpq`--$r^m3RuQFhoU}_ME8D;{}N{Tzi8NX;3etk8GY}s_+Cv*~$8vm?6g@8vKIc zJ>bNY06%LV-Z52-X}F#;h{Xb&&Fy$iP>a7|%PO?9vL=dRx0xLCzKg*ry&bBQ3>v{{(*6qh`U3keeh>WmQ}D$b;Nmr~zY_d2FQW|b++;jB z1S|8s3{bZ6?81$hmfx2THYga31x>kU!C-aPTfA3XlaFvue<0`vFgzp}tw2lvtS)P( zD)$gTV;ue?e`Wm+KBjp-1{!5zzeufg^pw4alpw1fOo9i|STr0UeZ4|&vud^44}nLo zl(_{k_-EqpS^+>``dLi-KZ7)>#Y~R?m?FS}F=Yl#83}T~oVP-yefGKZo2lke+>V{# zu>n-8Ud~49pD}6A_uU9A5Zp9y&E>!!Sd?Kek9xB>cZT)_^cM8GxncYFUBFWyvX2FN zf_;0fCpa82#S5a2j+S`1uDWp--cu8Cd!8jtS0aEU(my-h$to`C*|WBRW^*g;zQA3B zWP(ZJnUM$*A11r?RRnzT7$XlNXnG*lqa9h4J zx)Q($c3?vMLLk{>&Dy0{P392RA}CZj^uO*TR>M$kF;dTGN1N zt(V4%6%MG+=yuO#x5}_53=3;yRJ!FX-lZJY&{Km-i6}6MEN`y;}-POWNCOr|ZFTENmzqhGy}J zGJpiyPynR#Gn`Y2Jenraj1vK*;d3~7us;F=vu-HN%7~E%bCA`n%$qh3K#*SlB;B)a z!tOoL{8iSrN4)573++bEfn%&R{gCN$!;qCTV$u=f?ySqrMjM62YNNrjPhDlfnJo~b zTEn}Tu18EHJP29iO1RLndcO96hw{Kl<1>L|lMy|##;RY_BIh>4I)ftiz%9!>qH z%O*2{@M=SEwPdJY;66ZKP$D2tvgbIXs;OTAAWdLOzJC({$_&Z)kdYDtnUUui)naE> z2Q{ky0F8#f2kC{2w{;qmTG=YqxFqI1GTt|+E--r$4x0?i(5XgIbfJ@WTHtdu!3pLkEuGky#{ ziID-1l^O>@tL++Nn$1IFvid4Mv-=Et-ECXp$MO5s*7Hw|4x9k*t}@&BqS13E74s%scF_q<&>h%O`)jSCDvkP}(8U z4wQDFG?jgHuLIZb#N&i#An!5XTw}huLB81w4p2h+@+;78 zI@spXFhYkq-bp-xqr zE_77_=Ul5@m7~|`nCW`WpwO2X{fceKk{HM%-?=B!*HY8?c zz&HW(RL$*^LNS4-;r1{sN^taKN^6t8R7_6yC({D-prx| zutnkJ3i~TwfF!{;a^`Z3!|LJwd75+gxl7!9qry6Ic!B$cMzFVye<>iSVA38DXbJEG zz1My~ov1j|4NR4coOYm{{Bdd(0HPr9RHMDRZS#1ZeDmW5E*~y4n|FYxsg?IFI}H^N zd3}ab0wa1!odUGRW7V)2UvD2=p?O_}0=O@zw@QFfydPC8jaE0a*i(G6BmNMqV zBJ5jM0L#tYzLAHU&-IqMy5A3)v4kz5DH6dT%pj~KpeER4N)=c zc&6x7=&g~h$<=$^XO87kcoijGaIbn4H}>$GH4BX^ehalFw&*8P#s%}>ImL<#qENQ> zG#5BSw9`(b2u}A*`>op;vt}k{6z?l2ZkUFlqLa2h*5*ye!a2~gP*>@FGmWMY*Yt*f zuBVI=7{=;mY}3gVX8XzFyF%QH!hY$u{XPKBnDRAfzQ%m<2K@eW;Qedh<`Pq4%nb1o zaLa!JO{xIk4Bls8f1|Wy$xgLk?{iHN0KaDekq?cv#l2ctP%+sn40EmcZPGedz4juG z<7>L#x|ywYP|8$nLGyI~$5wS=K2YYNHm+FFG0A|=eYR$(I>VE)wOM}_rH1&X=GiUb zZq-WK78`ykhl?n!K3J2ZeXF>L4Cfuuu>mFTP^AB(6gONCZDSuV32$5C7ZE6jYi z`yRwMs@w~0yEk~X-}Sl_*ItkjIDD_hXME=Yd^`r)y4U8tAyr$rJ@$^P2kJ4jgsq`j zbv^6-=qgZ_uj6um@uih(05w|ti+7O^}JMCcJE)VX++?aV_<6r7kA4wpvND$hx4GPO122}2kILpez{mF z>k6u$q)G5r-ADCz%1Y$zoyHeupYCFbf`6`TG64>HJ$E)R{hqnH(zBAa*K%gb>Al8< z+B3T^gQhQoDHTOP5dJak06iW+l)5-vwavvl=>-C)&Nk_pbj-PUjU3u&Gz@dOvyq*AGe_|I}6%)z; zKzapAua10)PZvlt4Q0g}%k-Jle!+8=(;w+e041dP8sB{N7I^)2>_7V&ZeD*K`NL}< zUjh?=eFDwr+iN6UauL#794K_wJR{@aX!(0f`mX5JUmt%eU zX=ASTo;i5%V1>EfVvtXUv56Tuw+tM!Pml62k&jRc>HB9m9-H@AWU$$2`*5?JV=Zg% zW0wEANDP9LAS8e_;)^ZB>GQ=+}~$io&PlW^mOl}N)j-OSXI@Zm0n=d#D2C+Pqq3AF!8WxXP)uu;Cdq@ICdG@gQ7n=~HM}sJ){b-mI%9x!2INR6 zWN4gEd4c`1y4nP{sN~1vk1%Kg39d_T<)tUz-q-ORs}$o7sD3NF-HY}W^MO<#0~xuB+#1AL_NW_+mU= zE5LkQX!Y^IDBTzqUYKUJ%t6Y!o$I!6c0KSQOXb) zM0RAOK_Ip0x)s*tFVohkMvhQL%8o*M+h(@9Vei_M1~E8WQ6wPzWQ4P|RkeZ9ZLb{x z$0%tYyH~*|tZGwR!6?l5swTDv6utzlWhKnJb)xz1Vfc%HLI5lsS2<3tF-H_fB5u~> z23bCFL7bW)22U;e};P2auK9@4TR^qWwd-E)M? zXFNg{&g?TYW+L&>QuoISS0L@?oFOqU<{ z{Q2(!Z$1Ss-vaZsl%q+XJ9h{DKY<>7G2A@m)vfJequTYJ0wChI-yiJU%9_~nJbTj6 zQ9$;9($XX7QNac;blUqG6#kwG4|Ws`&1ZiNjq)eGeTGo>Wj{`~G;@YO3qI zi!zUU;kzKag{-&PxNiv_7n;0%{?1?j|9Ur8qt-Cd|3u8I3V;RuT0x#(hr0~* zBY5{m!(%{Lhv>LMF8qU)5u^-eaebtw-<)+(Qen0;C6&(uvuwgVN5avh&8Rf~krIve#79sozR<;LkSS&wy-Tt=CKg9>8mCmOd_sR(lqP zz=aQS6#^20kd+oy52G*$%22ovZe?mkj(;)5B2d4x$fOhr9z_X&pn)>Q1SEz)TnEb7 zaHvyi2?An=ULBsUm9=KU0c+w~@Ohd5Oho~ZG&+4y2Dq~2BLY)PyE4V*A_2I$2KHB& z=Na=iz6N~bH-Vcg;QA8aSuz->1Y!d333HD4a?TD0f!OGfg70~wc+@Lr3f4Q_E03&u zt51)LkGduFnD>6cJMYSEppDbe6+X_X!1`EW&1-B~5W=jiDAD{~_<#L!Rh2A;5u-U# zsPlTl{!7ctmGIwq{k3d82gA*a)xW78cSsSKeq`;|df3{G9|qw+TdmWqHJkSf@n~Tg zjA6B^7Z?C?W-k%~{gSvWKAx6NKDk}EvY_3a)|q$I!lW`P%&De1-L+yuV5nzd;st=L zG;!(P6eIZ_r3o7;`(T^cna9!Axgq>_N4y}+oib{TEP}uOw)CD}kF}7(bNX(*YQsz2 z6ii@=%!Sn%7-pv*ZYVCBV-)`Vy(W^(B#FSOq|Nj)ah`lbtT)_c;G5nAe%#<^|LxB# z0**5fS~97wM^nWD?8-*96Tlos3U8xsa-QwM8rA;{=i2vVObP=MfT$7bA}-J70b-sE zsO$1)>MF{`qb6&4&FgLJDvDMKY_-!k8O8F?LGZWZGbi-w$peEiTd=O(PL3mT0(eIL z@D}*+9{5b%{z<&$CX1iQlHo|ub*F27-fr+Hpt2T#nwFvLaVPs7bOh~V6amLYbRVd9 z)G+k1@qbTXyyrZoQSHUs1#i{PQ-jfY5pSgCTFcwn{?#GrFF7Rnt`WyX{}c>V5yv_W6GLafjr9G365!0H6HRzlyJX^?wKO$M2$73m|$D zM6rUN_U?h`S5daajwE%B&0tPoWQmyFScOtbu=ob-3;0HuWgBCn&Vt4YAJCbEG!+Ga zG3+T22^ZoT!gO1BE}EssGLA~oLoP(K3F>C~b!)w4f0$5Go&~#U)B(kf!-4>s%GtAu zh_FLy<^&SyLp#%gho&%BjXqk&vabWkjC;|v5sRujbi$9!c>M&ka zxs7{^vO%%dYo8fJYW)Y`F8^eC6zutr5KnE`_P%ol5o4OKfU9@N?>+@ye+FE?2Thtm zf-*Q~?B`iM{wIKTNYf6SXJNk2*+2W*2>*`;Dn-{)5qgTJ%TQY%6FkD#9%1O{+hfGt zj|~=vi{S@#-!i4SUR%6Vsn>;nZNQcGfzB4^&z|s)%KrBPOIQT_+cH3n!!O_`e(=}V zZf+*7Wx|gTpI-scOYhZFygVi-xuFkPpC5)O_HakmwVr<_07!b>+3D~hFTf(DS7}H5 zTu-T3j&hSEoug2fe{C3IOCi__dX>fyD8$Id^2|4x$gG~N!lurZ`iC{Ki^oYf1Gtb4 zN?@9#aMpAGtOB14Wh63HE1NI{4Kh?nL=ecrUqC7bRIpFAuotXsY{Gp~r9u+(Kd0pG z(;WK|$KRn-&njTmU4RPlj4ZT-0{V0zy`gB#k4GMG+8c06`CZ1QH_{ zC#5{n|Eh)E?lqf^(nhv2y&b8i>@24F(8&%x?9NxqCDDp9oGX5y%qtb+jem)=^05IG zWi%JK)1>;N54yyH7#$6=)KACI2k-q}Fj)+z7*QP+nJ!7h7j}SE0vGb?P4L zp9vBjyspZO_0MK<)Aj#3(bQ2(_hZ)pU`62Q;lfB=gJq4Uc!48eZLe#~)E7`Q+D4dG z>h2jkRWZLfvKQ+%Rw~leR+-rC-{XTjl|>@YxkYz-*SCOp)%p({PyisOzX{6U4aw`Z z-OiDkiYF)7Q4s*D>;{iz96IN#K@27(R7zy)SUtJ?<(1 z+G*u^K(KbF_` z`bNq=hq*ff#^S`YaE3BLu;9x-x3KU(9PmTSJMZV7wQ3UbwuPG9t%DFdQF zmjY5(RRqS(c_quu8S#UUpdkYVZ$Xdxj}C5lCpWzETqOu|r$R-Zwih&Y9~x?`^L5z>IQbbxrk|@RoV?=W_i! zMo)(-5HAGO$_uovK^$c@RyXe zWcG6HZ0ufxKX%Q!XF`3;D+QV_U8Lq-_#Vf*=AqN$#R4kIIQFTn3U1KxiDx_S@nuk^_TP}aIqnKB{? zUg=o?PFed~W2dkehD=J;p4vV_>%Rkz7GqsOq@#IR->)t1gazb<^A0`WdLZ3?cimjO zb#2V~Ax8KVOWC51_6HreNJg3%wTJ^Hyi>&naZSTU=H-|^b2Tc!WIt*-%pHx>(ZCSUZ;Cc z6&T!Pin8B!y9u1OAB45Mnu((Qy@BJ)cht^bGlttL0vcMpRqhVpf5Fdu|JSw(Y%2f& zaK`r%EfoN=FKqXEO$*%%E;7F8RWQA8U`r*oga;J)9fTjQ8Nm`^TNkrgI98^wW?pvy zBsPEy&{BJ`TJG4N5#53bZo%qi=e8*cvxQVK7XXUTNAk&8b2lU8>vo+0qgW0bAz*WI z2Fma{@mf^ZS~0o=i6d*b-mFwO(m^ab*dd5^3bw=25U26#sqyIN8o%aFO{I= zvdHKFEJY1r0;LIr9gtoDv;)(m4k#qghg5|vh+^#p)*z9@R>(OcCkj?}1@-Qr^h(}i zR@dt}yuT=P@eJ@@zY7jznv`*|Vl23v_Z8zKWJWv#CJ4sdP{K_9psrC}GbU6sgJu?z zWVI!7I^;m6lqht_Qyo_5qr$M$u!c@rT|KCjB6f*@SF$cadLY6A0IEXEl`xBH1D%V! zPg>He-kv<3BI(TgbY$XbhOF2bK-Nip#TZsJ0R2VOzaBl`dI|y}V4qY8Zw3@9dx-CKdOu|E@-)3Z zFZRCb_gmzK(tb4~n+na&`#))I2b{J4drE{P@pDp2;7o#pojQivY89T*%Te$5kA3y7 zRSo#FBYk3KF!A>tDtAx;0KETE;9Gthz#lqX_643TM5HsTlWKd#s;lQMUC4wJ6jFhW zdju<9^Y8Yjf>_8E_H=}=hwAA-y9C|DcHshiUvf?D1QGJdf=Q}aW#{Mp96bTkE(qHj zFsY?2LGfn-uvc7}#r-z33gOnZ&`wNq#w6Ya9L|lq=K%R;EsT&TltlPX&d`SNa$z1u zIOb7i@Z$ng5LRjQ;u^R2X!DmyID?eb+OK6G$Sd&eda*n4jnQ_<-eE+oxF z8Q*tc#Ep?|`2OmLZPe6U@BMZLugpuuFh^l#LH`CIpn2U}Q~jAVxWZdCWP)wYoel12 zeW)O23OiQs9aHB}B2d1;{NXj;zWzPn^H0I=-hi$yk@8+%-2Ra$)?z!N$7Scxon;8#!wEC$-N=1`o#+!)eQQ`X7k^fW(LN$O| zS@!hdckpKSV}}YIRsekR?R)ylFa8jN|Krh?woc$E?q+f4grm{6Z@58qt#m;HSp;@-edqAL zNxzzaHi0!zo-1%Dxn}@0DnC!JTQwGt85K(QJ4tbJ^SQEokWrETMP;+PoQ~0ig%UlrIU)>a=fyr@rc9 zaZ@j*Bxn0!RzeFHNh)a@F13GJsi1@gEDChU+GLLYG6eHF)9z0Q`2VFhBmn4vxV%V-&OTnMVv%@*q1+=M*v_`6tziVc%=@nt4ziGu%T;w`1mR z6vx|go&C0CK`Zp2m&*Pj80RUu9{{zwdXR+~`yPfJVIxj)p zo)(lC4Su0wa0x0{AxWh5AV><`wDeTvPskhq03ZNKL_t)gzNm5YdroA-nbzu@r$lNF z(!|{jdI0X707Rl&IIP)`6LF8=b}Qt|0|fAs($ zO2G6AJgNY2%PouWpK>_=zYjqG$@^|O&RJc}BvxAjvZyK&F>=m&KCMw`Xg#b70H!1g z4%_EEI34%rxa+occ&HyGIHRYGaN=^qEKs)2iS+nSf}g_{O%u#vkT`)jBl9e;%hC;* zkXs4h#Z|E=DGU9I-T?Iq3H`O-w%#JWi^6^LcZfOV71GZ)Ku=>K<=*mi-#rH1$1gx(yt_d0ZQy}Bb50Jgrn z{2bTi*7|r#+vkL_HW@R%f281$0sx=lc0uO#jk$vnv8h$71~0HDoVP!)kCV zBLo!BkQ$?nu;AdD##m?J=TZ;|q3Pmcec{|cMe1_^j#;B4hOH4H+?&290?{(^YoLUW z-4dJBReN@~dq#<@FJ&ii5ZcIcj;91nlPh@UX@|wx)_x~Ya6{i~W)bMpTv7mX6I|2J z{U=ohK>M1-A($D2genDGCF4ypKC?c%0wCZRAAwgd&*Jwb2|7>x=?!wU%##WVi&ux#&?86_2Erk4O`OLcxDi=PbV~ z0XlRtmJ5Hb6eSFzpv^6Z9Lz-tz^>3}h}!BN-EU>dggwl@ZJ9*a+(gW?41foT%o+Ud zbMWV11KxZFT)qXR8I#hJ{k#X}z0f~Q!Aqr~>*rwXo;`naOc35j4jtZRG?u|_U`T*i zQAjVcQFS`lKSz9OZ~GuDUagGi@<^^2exzUuUxO7P^vNr^0x(eNWfGB^*@{BEWr-GB zYvBLK8}7)3D@v@pgvI)4h5w)sY}eaSiidN#(IGBoPW|#-rRw7UO!DjbdTM zXf2E|IcY)_^d(vgQ$jXZ?X&~Ov;BSsUj;pVPZR@>ZFaEg9AJ^SK>$?w18yS5Gyx<{ z0001Fa8kTVC|Lxy-bWQd-u~Oht0mq(LL7VqK#7pj4e2wMlWZVb~VyFyfA%H_-kl4a<+6sw0ur(WcAC}8Xqr@&(A%(XLB~7u*ZzJk;sdt=lfe_? z?P$dnIPM{ALqiOaMSZ9YJ~31z{IqqP3MHo^Yc#z4)^;xrLc@~Vi=4m>{+{j zFEeLJhuRuSx;)lM!(8yWRRr|B0UioA)?0P`zF|mdNPl^>x?u$XKKT=W2VeQ>KLGHp zL*-XAmoM&Donpwc*7A8q6x{h)vVs#B^_Lq zHqDe&t8_^FpMv1GVF7sdcy$s4MGcG4Rxt}E;9DFCSN7PtHaubw?T{6(GUpOwLd!5_ z57JJCBQP%)z(jD4mVCByjn7NBis?w%fx7dd!pWNX7);b9IwBm|54sxEIyx&%@ zc{Nx(fWWxBrCQLP3;5wM&R zZtfjp4X^5X0C_OrVYko5`}XcVmUVcD*C+ma_^BWK$C8j{Oz=9U^OT7S& z;6FyN>!{_urU^XNdNhLnG&+)AyN#8REc(3?#F*mDqruv{*ugEKW~D`VUcd9GLdN$U zmh<}*qLv3YvIL_GwGDGI!_`<+f1pn>LtTdfq}FAX7qyYr=hGbC%Yx3CqUr@2poXrS zunx$4n_#NmBVfHm@Dz;EIzc3K024$>U}ZH;C>Y4ID1QR|AqomDif`KDKd6#{HCuok zJt@ZX!VIa!pR)!fWD7_dg=dtq)Zie0MH~# z(2Twt=NcWq^rucA0<>oYpMNi+>;L}GVX-W<`ti% zr^eH-(B1A)ixC(Vj2~*A8ZWf6oJ}FF<-&Joi`a^B^?L|f&w-xx|1O}dKj3YfT8~2+ zwBO@8e8_jVe)BIKQ`J!l0Q|x9KjL@t_W=0AtMqWqHDr~rzQ9v}_24eTs2h1uk^lr& z)QE~Nxh=-Qh^@JX`z__--THq_=LgE19VPF8&0AYHk$`sAUXf?Xe@n!Ma0I~r8U=v4 z{JUIc(v(EfH+cudNWGwAov!LP5Elgid-oZI!8c;dC@$3Dk3=Z5WM0%TY#!WC=Pnv* zU17mohAKLVVodF98il^`9pKEr18i3_ta|pL_|5 zIQu*;{g5@TS_?l05bsm@8oxNB7p@yl`z3b9ux@r`fA970%9Xgx!*DIMQ1A}67otxZ^|tmxVQpLbAG%b)Y0Ciy@tMOhXVWd( zzUYx^0Z7VNFvbSR-0yrtKvdxPpT`T(+omMQnkghFQ7kDV6TLbLNn$@bQra>hdIBX2 zYASzB8KRIR-GkV}RTLcbfyyv+{9P0>=A*mz871hc{f>X|d1BRGkfpd|J-TD*Q(4xU zy+2ye@5tN)VW_f*6gsxtqu20)LvTXCSjf0N0FX2M40VzaTD{oc0l2q_&i}-Fq?-%y z;Z#8@CzueQFgfl$DjKcq72)bPxa z`R!T6S~!*=4!C7$?8bTJk+z!3R)wcd*@5atVJmgpsztnK+4JY*zcQR->AbGFjXCsV zL#GId8$v3TADzdjDPR5SR2T~O<}vag9Rp4;ZQ5~x(_)=tkKGPhx_AOqkKeYw<@`w- zfo`Cl=Yj)=)_T}WwcivJ-TtmJ2Y%6bP4+6_m&w}?ompv`>M^vI^d7&k0SkI+-y58@ z)Xi-7In-e7#9^+1^?#He2PL%8me}+`STmOP`G)@*Kl#aitYZSlDF6WAo4@>5@!{$} zWbhw!ZrLWqkq9ssNCFp2o^e6;5piiP7z=8|;z=V%TmDHq1X^#ekR5&`D)}g6)RD6AUqrHFNC?vACwnndw-@m?>1qmnb126$`HYwbm5|z;kJ@ zHv|p@$K2BAy{3qBE)k#|{1`yA$eLAGs~6AWNzV}bo*hEN3Ac&8p~PoPO7_Co?HvaSb86Q-S{?6Y^o_Pi70LbQle zVWa^k{EM!tN5Da_W8C$_ZDr-OL4fXS99e2c{5iTs*TTje%lG*2^2o;tqr6NCilMc~ zjD}R}BozijuglL|mt$z4$1HLBw7#669v>nU^9+s6N7Wx&z&_^sox{r3TcTJ+X2~Is zSsqOpz$EK`&cL1vZW!HLZ1$`IvCuYl8rL#oGhFz$y|tP}y_fX}gr&!%8AzHT!#f}} z-93Hua?&!M77-;|BisM_xC`dQg$($_DU;}QC@zkFPcB{Wq}x{Og#%_&w0&TfE|o%s`$Kct3-*qmt?raL(w< zQ`j#%P_6MJnD|Jrs6J-pG`3RUpx$%r{AuKcI?S=pHkqK>5fB!V?BsgN3_kpo=^UC+eF<9SGFt)jO(;mvNSZEAaeZ1T6O^!6y z^vZBNDhPPK5uOqNSZPotgxX2}2?X_~W#}=w>`H`03?$aDJY~ON3QA6rEKxr8+|bi@ z{5H0jE_!9Wqd=1wsMvx(TOV59I5Q}&B|^0~Gi!z!qgOrNTG#7Q!5}H5Tf`c^*!Zzh zuIhG>F{(NLZCrlS_l|X{zyQbIz<>0|-ZSXGJo-5UE|wXXkjVhgx%$idSw5TVm`zZN z8~C{i!E=C)R0Y5-J@$w2+l0|JaMx-Rp-cdwKwiI~$Ni@U-_fvEya>3(vMp9_6VvHf zyL8KpcL)-r8mbg)+K}k^V^M=gL1@y77Cp9;k_7a#&uNl#{8Iu?1Wuw5c}||FFYt&U z$ika{?INnsI+RQam`MLr`Kv;9=8Tzvc}vEK$}(nE^z93+bH!+Bl1%xi8!WqZJjA)^ zDdF1duDA?LUPW8B7Gb2T%@`^x3@xj%y5sdNAqX4u*A|M()~?dIRXm6Ga|Y)udwnrPIC%yUgHpzn_t;%sf-gTHUw%Nox&U8aB41x&zPT#Q?_-9Rxom}n zwLNfnZ+rn}Mz*z!jlJ{yEf*d)8m{8+b1OxFae;HVuCb!ysgB15rm=B6leKW_cms|Z zUPXKdC@62qv!=*VIVlr@?;^a2Vjp$`Qn2Xx?j@b~}PhhytI-U9#t_}yOxebc`W;2%F&G%ze{!b{Y|G!J*as}|i| zQ%JQea*uC=oSP7GH87K z5fjtX?%Jm0ytG=U31W+9fFQ2FfCdB`ZxNQyUYZXhX)0m2;#Ayqr!}(x^@dlg59+jZ zq3w8C=bY_b7;*PLs)sAJ%+t&f<7ue?q@{fzKkns&xm_2Md_EWB_aCi&&2)5K6|6dNPXJ z6cI4(0?F5G5Jvto19^|#oRM-yzPbP|KOkSe!TkOU@P~K6^#w3rVMY$#hRxVc<_SjW zVZ_S~I@->iS%JH}4r*L#tI~FFMY6YefhP>B@BOaF8rMhUZGrmTudV%4;ecRu^z#cE zx>oryN`L{_n3w00g0F&8#vAB)<>8XE(_y##yPPD3F%QnFe5@E_qfpP4kZH8P?sG>- z9>tgTIU7$q?v6)M4;J3GCc9Mij^oWD7+_S|Eej9Vd&lrKuaRT zOU#!akgwhY*YA<9--9pT0sAW;->A|-7~S&;3(elQRj#F{TXeK76ZxO$N*k~Dc%(r= za-rOA>y?`a>v=M8iZ$_$`f*=Mmac315yJnvYx@?oG-j)vu|mV+I5(TJp=|Re&(0ei zG2VDx_Xy6pQ1Wa?V2!_1qn3HcYRspiJSc&Xovxb_AS%jxeK>U<)`b7gc!$u+_8+5z zK6b9}4&-^!h&l@K0`*;|xjJ z!@NT$~%)FcN*D0O~AC1Gr{3Zc2NS@wE;%;1zrFU zzG6_YKZWsj62vVdnnke7xzH_F0wfo#)65`E70M8o@~RhIgUwebOAaBJc3Qs8Ah%b7_V5KC}<+d*uKDU zv;@dBWNok~x9kMwlj=YiWBsp%>555KOTFZPXIJ=1Redvrl%P~(Q- z;~FE{*3||~te6LjAf5EMZL=Bpd(-(<0iQ{Z0HhcMkpOoIdlCL$;0TZ?!2{>3k7Nei ziJc1*Tj|!=&g(NgHG~P1NdvAji`5u%W-;dV?FRj--e%(Rbh<{>b&IkDsmp0D$lKlRt#- z{`o%*;GbD96dA(s>C6QOkL#8p>TKG~BL8P$78r~I=AN2`t46Wq<80kyi> zI|x}FtZt~_bSeRVfsYc{qTnAaSN|7-(D+)GG^f5U#f%SeYx~ z-zPT+o@>xFQ|V`7_ZPggOi1;3kHN;Qd$uTXh-XamHR$>S=8HGT7heFE??5;2fNYlk zEZIyn0`?qb*p`gn7YuJR1B%!7{j}FlYIqQy3y=IjitVLSMcKpeQkabb{ATBdD;zC& z-gzFLsQdX11Bt;Cz>^AqDV?20RA*b`LTnmxi}V8lMZ7hOv6;v9JB4>r;WwiQ zpi&aV<##EjxtpWX0Q%{c?`9HmIWDjX#s73UHfsYAi_a9TOj(|_pi?&XW7aQ+aVS9{ zC8kaUDVG=kHm8=+!mW|kbf@tJa(X6`l zd^Xh=I6rV@9^WcBSYcGG0Yy{qzm)=c)|aM<#q%WbEu2q^!gLY($vp|exUAN=-(*t) z!~jXf1AvUN2o`%%`dN-ag?_STz9A@$ii2$w0MRSLvK|;C=1M#g%eVRJ`Zx*V_G!UC z18r$DlN_}EvXdL{ZnD6L+GgYNK}G|qP@h)K;Ywpbl+w`S6?q2D*WjB=@a0?Z#T(G& zJK*{Q5?=vn2B(aiGLl;SGus{};}&IeGp03WZiwW?mwBMvh}FL>(-ZRJds%z-M0&ko z=I_ws;31(+v3K7L{hC02*Ghl|9Pw^fQ`#MZp*BYATghR+XyXwJW=Fx`csDHcQj1?f z;rSBmP*$~1us@8R&>!g!Yun2#7AMYs@7b2-om8*<$6+t@86-WJHc~xv*e(JMj^7`W zUY33^IQ_f0o-a8m^J}Wo+XQ8hcU;Q`CaaDT^Y5A!C$t z2ZEQ%;0w-XbO{}5VcR40+x=+u3++PlvX-c)k+p6HqJgyKUE78r^_5e)OC`Vyyud1$ zqU(%M?fEV9Y3o1Fpd5qA*=N~TOxCwOzN}@GC1UF+?}54Cz0=Hv&=`b&TU2%&z&5XD zpDGnn=xPz>mu)m(dbHSAunP8xWUvWf;-c3zw|^4l0BPCW^DycHS09xJneiOn#mL0@ zZ2O*L`!hBBBG(0_^n4>}|5(y9=Icw~>OFAr27K`bxOxlRTmgIoN*OfSkqrj(49==p z0qK4)$BDf)2(=u@{|+2x43$?P%}>8((W|U%ZJpuwZIrfa0gayvv}fW06lKR<3*m7o zX`4$01Xb(c3=J=@b@+|tV?Ek)1VkQX1BP*|$M^O4rgOhTTZ^5s+^KP7c)W{FEz1$9 z3>Aqi)!R%^Sj$?leKPK;MSPZ6IH413%E{sP+o5?@@5%EV`V{x!$h-4mmRGyim5st2 zKN6bxH}KQn_to20a(e{;0L=KaAp9#}d`n>(VtS@jUcBL-@lgxL13`;p%vG6eN*1|N z>otLulSD~QNd=z?l{FLmVYCHsl=$@TFOLYZQ zQ{EcXTAe{*N_xn@uwWq&6st7VL8%wR()poSS6xVG6$Oh=^M0B1Y^?>tn&o{od8g}U zDSQ?pD1^hJsG?Z3k_yg-#K<5deeXKYaScS23C$UaWh~n#LOnLL&)5Wp%9Cn(T@fbF zS4=krVFD$P;(b{~Uf{7qiwA)YS2U$l^r&W71X)l~@OnG-Cvi-%DKS5+4vu9Lhvnj8 zeIjY9Xg5pM@lddWaGFOEtBvPRF^-E17#JUnU4IfCt9*Nn1O%F0GFEEc1~;_D&?WLHV$%5LtT;7@FpB4tj9Fi?%7; z+Bm|x(QIGIthdY767aCSFc#o&+_`Mb@%|_ z&y9Ct9d3!$0sj2Y{ii_wM64z=+|AO?Qkpd-tA^g9(K8p<(ukW@2cS$KJK-!ZP~E^a z?HNrwfCwo~$Y}>oyCO(UnjT2qV!XjEULk-ku_9c1fT)cfi3ixymq;94SbLEj=lv zV!?p~9V@t90))A7-SI=*Tpf=g^Tufho~C+^dqki2@=kji)RZty6H-c;r!OI=SEZit zS8twr6yOCuY9Mn9_o(-*a;L7+%$VmrJjI+Z;06z+Hrs9;*79+yJiEBpmSdVk=#`rQ zEHZyCG&nO7(V{+cTde3oRAN}!_~-3t%mbr6e$2;4YRp&7uv+a4CPOn6V4B>s$om$L zR!pxXgNF&tw3C<}X{XmGjUkXron&j-gqiT&=o7G{F_G3J-F)MCtGTgp+`tu^uC$F_ zQc91rX8uVDbK1!`Y|qbo{mV%7W#A?wzxxz;{Waj-H$eM$nDRA<#lvA{*%s2krkV3K znD>VZj)Lz|3LT+bFTlOms>}7W&X`;EabJr2>Lfv2&joqp_zuwLe>zs)QF$oGDBb?- zO5o&?N-d)Kp<8w6AO<(3x#{OC_g3Cww2@Q<({ z?e+WfVl6+i*~x)2=Qc*P%CzwPG>?Lnw0*HHEKzFBeV&w`Y|C}~!z{<)?A|mv{|X3> z61_s2ULmCDw$Wljiro@Fh?iRvlI z?0Vp-7n5uAb_fT1JoO=H>+2~kZmSeJ1!Sz>fuH`t?>R?x=kWjlfb<9cbL7weRS^G? zn)@MCKG^L-Txeuhz!0x{y)aUg5^|Q*QA}c;buE{jqpnoa?fLfA4g}#kS7+)An7fQJ z15q=Tj0sC9X`luWhkMH^NhE#DcTEIP8_h-M*-7I!LE zECB52X4dLbAGszk7Xq=iu#Z`Ht>!!8Tp&!85;z@ZxFVAaRrs*=J(0gJ_IXhJ*JBkP zOF}PIRz5V}Z4M~nlj2`2Yw2A^aq0zLK*9V#qM$4>J_=psNFUC`pGhju@;!dWGDrdM z<)RDnjCi?U-{~%{W95B$+Io(US4+{>u>4i@uEU%<-8IEzOx+o~<}RF(PPF@PpyU1r zFIQa7!(N?~_PVB4e{&OnP!+{Sd%XM84um8TdrWCTNn*+XBAjssZZ5$W7h?6lzL2zj z^DKf27_*J{s1&Ua0b~7(vT!9lEi7J-eY_6@F$nJ_oLP{3Y7qIHyM$2%K%h7G3LApj z-Ns{R)_L2fQ`?TuIuBmbh%(QZnUE(*|HrX?qx(}@D)1}5*12;Gzq6FOLb~n2mBM=z zMr6W=5W*i8ei@&=|4Zkp?0gDggY+6kTV~y>4hQ~)yz-FeFMq} z*p6VB$mH$>wSb2@JKXJp88yL+?K7MSbz8cJu7anXutn!Gf4Dxd zxZLt)v$BHlGDd<~oIT)_48}^C?AbgV=D-C}%cii>PZJPK@OMj5_Otf@`}pNOWNkZX z)yZ>r63Oi4${G?nODJQe<|LJ-jP9e8@Iq#h)LXFZ*{*LKZ%76~&M4(MMF zedeUDxX?W2lg~AEHp<#csqZE#F_L;P#K2$vZkHRNr-C{-+822Cz=6gX69FJA?s8sQ z1uEuYK}@&=$%NJ2DX7caWY&df0_afF2YkTeOARIhc>zcjsXWFt?~QEF=s__ z(jDo7`K@UDv;%f1W{2Kh}W38a|R^P zrCqTte@8}d0nh|alj?$1IpE*K3xMYv@Wngu`?tWwTj2UVFki_%^(S-TKPY&%;eiCd zVF8D03m8z(x$k9X?%yq;b-%t1?|m!5%lF(z9Cx1#<`5B|pk5&MNm!=zEp-!$kFuZWJ=8y-w#dg%bmsj9 zPJs;I-@Z-SzZTA?004kb{<)t|-}#gOeFpz&0tzF@5ph*C4@g|jWdVLrTxBYG9?k&B zUPANG6cyx+HL#RnW9{Gu-Vv3a~+llxoVnn4sR@NVH#e9yOE9&1~-_ z%nt+DF)(GF$#O;&JOPO{+kgtTZF;Q8s73;)2vG-{3g_gtf6PYof*>7;DXRwn4R`<` zn?kDKuQwlr7xt+AQMign8&q*ZI{;JF9~*Mv@iowuqgk`D7*S7QZki2ksW^He#LpRq znQTL};PNeNCj(?mOv_-{wQvcxObxf~I+xEy|8h-YdkTP@i-K)S3F}G$U`s&Y5XoOV zQa)RHKL9a1O!Y(*2yNrCAhphwp{6BaK4qU$PXRqX#z@FaMbNGk$&o=UF+hawrP3$T z7zJcqECOeFO4^(@AR^Fg@Iv-&_i3&dN)^c67-@E;56%{>2MoQ(3og2AS4zaz#j|(Hz zS9s6D(r(0!Sew7N-cOz5R>QbPBR(daCjKk<$shRHb5?m?1pt6Nefd90`-^`W;6L2T z@NqL095EMaTOhz%bQBZlNCkFhxiZ7u-C@rY06hm7qtPc}ti%#*0y98Js8ZW;ImcQM zJ~Eq)Am_oIY*8tLM%uTm{UFjng*K{@GuSpS&78Cg!WKER9}VR^7lObLx6W*gA*63k zD4Iz0Y$*T>v8vyUzJW={oMsstu^ifDmT2@j%O^#RW75}@Bq5`0_LxIL1&{`GbDe1H-JywMT`^Lr|@RZ!e zUg%SC&a}0inl(Qax~{=@sX2ldX;x9hhppH4KZeBLG3J?p3=M2%^wU3TL6%89o1pt8 z0hDLZ%{BPyJ@UKP;`aakGqL{9HzNG=UK?(hzsJJpjndPeU|$%Q!_Phx*^cjW1!7RW zA=nZII>OOm7>sA|u|khGyvw$R>VKH^yLqPmF6SjSw<7#^vued>*1!#5oift|>@@b- zlxhWl(UpZl5-`IVP;Xmhs~qUxh;rZ+k5w5*_x|9?6-Q)xt|`vc8Vgd*pXtY zQe~%1#bqFn0^;D{i7Y-Hzw3u7=s200Ftq2y~Bh@avilVA~~k4J=!tSXFLjzZ+< zL+F!05>#Rn1C@%AFcNxv-+i6eoSD6Q<&W;wy}Ebzo}M`~XXczc>(;rmXHV~b?e5iU z{nqN$#vlZ^5I1b`P650iC4yeuI-p&n08^yDr zM|Ad-fQz2V1=m~atvl8U#9>c+2bdEtIEI%sW?*s@mhTr4mP2<5V+cw`Ca@N}nB0ET zRYWG)jvBFq^jVg1M*x^27{H>i%eWLFUMc4>(EV{EqbWQOhD6 zr{{D&A!sY&0|6X}vyTHH>c8i8QI;4jXe9c7ZiyefvL9~c-dFPQkQSPcd)9R>v{BP0 zQzo0PNga#>0LTb`WmO+t2RCm8AW+Ws?yyk}mXlWgRiIfzk%txnriqn4^n2hT(g?NW zDC>VnB%V@P|7t$yfLHMVAavZL8QOXW}2C=+ugj9uq% zit=_Az8B-Klt6$M+N)qYam-ao2ydm_(?+jxYvsiuj>M57vF6J_u}_O&<@O3+P5XFl z)}}4?yprn_yZC!(pIDOo5FfKt9|AK;^MGz0=N3bH1v%+t+`iXKq*~6|ZqNeq!nf0)`U_iSrbFg3na&%V^ z{QaK{+psto-;Wv(sDTni)2eO0WRf_Ig5xNH1094t_lg+SZ41GuLO_yj2^=} zMuMW10@tPcQj zZGq<>Ch`*Tq{?HH6j~crzNxnAItqU;rqeIf)q}w3m|>O!%<{?|^LO#c{moB-;R?h9 zqJM`!%2dNcU}R&QMxmM6Bdg*80Mc_C)mkc+a!{ zWEVN_1ONa4dxdW@GyD4h`ki49qGuLb4ID+nP2Bxz!lYMj7^y%7L}f}TV8j;0-gz<% zY$GM8ENRTB!goDkZ2A@X6j2~R2-v1U07UxZ604Pgp$f1?PjM|wI)=~)RgBnKx(w{#!^0P>Z`<31l}697Ql-a@4ehV5LL z@-Kk0q$}m6*OXmY!2l%ImOLIu=H&yxvnEm}fd~*7m3j67KFOa1K&JEWBzi>Tt9INbU(fR}R&7pLI!N8t0vm|dO0^p_ZzVM+L% z=HdFC@9>>ngOaTj3I_8(rl0ygHH_0vgCI9gBc*7=wWECGAJTqV*8`vpwZu_zIntE% zU61jt%SJh`PYaLbjl9$<^KFIq4f$jL$gkIy#j{!X5a53pp8%kX@O2~W4OJ3fYE}Je z7WxuE)H2^|d}0+ZxqI|WIP3oVU1h#A004jcKRdU7=^d{^XWkF+J?&Z&Et~1!$lq^O zsS10mft1mE0n7^z>}}!{%CXLh;uUh%@diZE6l=3sXjq-~?DLEjarvrUnMsP!zMw37 z8KM5Usuna$ZAp^L#jX1J@ekhTENN9 zpOx$dILqvh&hvbsbNR6GX*&myk{u$yXXE*<JSx^K3fT(&%+%u4OfTqA&vjPAC<=Mv5e}W#gqJC4xHO6Bxa zfcH zk${Pa;!jG1=Ra=&%BCx5o|yfB8?6b)7C|5MTmraYViY9p{N@I%g;?(z|UH8e+> z#=?JH?IQb=BmOvCn*abv?%th0{80?*Wc=wYHm*@|tCQl3Ig6X3Dj$pYLMvrW1wjI* z2CqKf0freg46w^N?EDFE`T#h409-r# z_f$w*s$K~YUj=ZKR^3**d9S-T>0{Zf=2S*C%dPuy{2S?kKuRv#B5h(Zt`Mo`tKKZy zXtXlJiMpsfD4*vg5MXU8@O4FQ>5O~(jRJ&01mkre2QY_4N-fD5KTUWsvN2Gqo?4G& z%YrEXI**#yLy1JR<=FJ3j-w99>(o$2wd@t`-84T<)8pwcQyi2M9X(vOaW zYyYjI>>T^J#UVNIbG9MBF3umX*ala2aXr$K99&eXSOR-W1MA)_?GV zwH#?!t=p=0)Hvw6q=oR(&;EW_e%ISzEvZnW%E{N!EtGX6N931Mq2y!;-_v68Ygv1o zCr8Tw%mU&8=>jX?q2@=Z7^UNsfoMrb6b4wuW&yj?JKS`$$eL@uzIW`iQ{cJ`D_r2UshD8o`)YHZx$^g8R7V zGI-ONxRr)|Vq+}Gu-jTC%@y8m3FtZ)>Kp*-tv3t@GkyV`k^~%f|P0iIkgkD^HtBm+0q9xKnUu=x~A)cH^SQfS#6s>46#WjP20PmzY2N6#9q1 z4xGIJvv}eI{tf71ur&8TY|(L_jQxBb@W2sNPku-iMt`|Zpgwgr+7$`H#ygR zqx(LRwbt9t{OM=iiTk4tPQPM*B3BPH^d3l7&0$tXP6B8KHaY-$LmTq?%V*x_rl1F8 z-w71tC=Ei8`X7P_aJh=|>^iU41`vBYG`W>3<44((@8U21x88u~wpW)DZRn4&2Hn4J z`Go%@fRAo9--2RT{9VX1mgH!w!0^}~U5E6$+zV%91JTH#N1ZH?ZnBN*QmF5?P^Ep- zlvP3gwA)gJVaB5d??}HK=|~tWGh4_pFW{Ql+3asX1Q`?vkn=5~?1&*9ksc}?2jNuU zSp%=obz`MYvh55oBY=oiomkaPdz8uV1DFR`9^5@UxNS$G46p+#a%D3Y*7g3(lF~q` z4>&0Fq9k~Qkqp>KRDQM9$M;bTzUq(5^Dh2@SB{kb!{Cc#W-#3|=w>Hi)8PshSKMQO z1(88VGjwcVFV3-e@&fwv2f+CgU~vh%T!8xl*1Dj7A$~&x?Js^wW4})*69*A{WlB!E zZhqtgkonKFFSa{wn|m^sJLGu*@R(seXtQdY+|Hus-%>h=@%+@2tP4oxY-9XM0MUEQ ztyxHA?QJh7xe=mT?Za5ds&p9D`&T>+ufqNNJ3sbj_Z|QM@ST6?6L{@UemRJL8o)h> zOH%kmG#E`-0^9%_E7HNzMuY^ROY%ZGNQ01P5TfzxJ@7I~yqhKYBk{lp!T)1+n73OHOGflIQm7zh?~%nKsfCCG5`d3%Buyn@NCFH+ zVY4ZtMrFRThkfJ$z(`LS@w_qFQY7ykgYS2(!zGDs89HMlkb0WWwHN95HBPJVko6vVw6bz6qC9YuC_wlW^pFr6QjpdPb;FhZ+hif=Z)Re zJa+d%6@Y4GoifYrMv?4W=|FhhL6aWe3hW{cARF)g&jmRf9CaedXA;JBeHzUdS*LH$ z`;6PW71h?7hIUowN&VR+6TT8Z^OjGo%zO)UGXMYpyy44!7O(w@*8=#v07jk3*}YYJ zWq3NTg>Kj^ylZ`M=yY%d;*xC1B-J2OArQx z7(5~Psr5srP3&A5P-`8^`%_!UqzHGXm_82#*i=W3*-eoIFs=cNd6_GzkajAtVSBda zXSNbNutp8}3UHS`R(@{uzDvBg0w|2D#?`iO^xk$%#Xd>ah#LkglyNAhQC$zHA8(XI z*9ic8)Gti%95d>8a~iW9hTF0XH7p&oVkU{KL8J+sQFv_T%%pp6CcXJ zp~=<<)0i9x@| z!)w!#j#MQLV9JHHRh}|>wnf+q=6Id9gfKHkYqtmuNx8}@pCqM_jeAV^ol;~3c!em< z@Y|+Dfku+AJ88rR!%RdH4FC}0@u}jv=xanJmf$&tBxDzq&+U~bF#Fwv@(u(5V8wq) z_U6O!X{(M;3Y9OE8`c~zkdaZ!|IF>>Hzr2#_eY(=bP)s~Z>8~Z2sjbk4v+@N#Oa;~ zPpAj51lb<6=wVM!(La0)K79eWd;~1#fL(wLyCxE0U?04P+=VCz<~He zvTjdjL1hInsbhQnrussDZ&fD4I@?fQOP*pqEJBYXVY#V_+ofhtffU5q258ap-uBZe z7>$AAcrC6mqYvKqC6?-E1jJ4-LSAD zW>^A582|=l>CwsD4GR|$SqBJmvV&6oNsfm?OtUSzVW4(YeD;n;3o8L^N=ixU8F5tp zk8~$U^Df&00EGXh$!1I}2SRmz`AH+iYA_OHPCX`kmE~a`5SgE7<{WrkY{#I!`~0ni z14&)*3(dG0001BWNkle{Byi67Id&TbK4M+W!XYa7PEeIt z{65`;MKpLWH32eupMMwJ{@rH>bTilPj==s%Kk{h>00_}+Rkt4OK3ij8z%aIlUChDD z3t)K#yST#gVh(8=j4n}zmI;3&G zg0|ipEp2ycJ_y5Kv+d$n(ai$@Z~D>;eB;}{gkXM_!LM9DgG^`;G>g(SD=ADSN+&h> z?;LD9v0QionA|?TpzM41PAh_)2%eIkR{DXRS$Ga&dWk28{~FQd3YzS(NU{ANsMvd? zBNb_-)u>r1*l^@m1d?FHSy@IwkN`l;sXi5Ab1>2)=loVCac1gHBJU&uF+&3ISv!CS z*#KwimUeTJ; zzdD1RUt&3*1DA8~{0cN&0Ni`f2vPB8`0+phdQ?!U!=Vip)uO9%xOWh%^!7*;|I+<^ zQ!ae_x~7V2mMu?Y)#;%bWzgGN4>cQ5R zW8w(_a#Sh99hGV*JRb5@5yOL}GzeIgqe%e}%|H^kuk#lFnF9b=?!gDkBLtWg09>7e7U#g#1$Z$BZ12ZL?}xn`D=y{(ML|@J z&t}iRQkqriHlW0N4XL+C?LBb5_T}3Kw6|dk<-lGkZ(nZf*eGtb$osJnIloA$v>vj?3jVr!7>lVud&q&y7}ErTpjoZk;?c@X_;| zCjfsLo_qG=8`k(*v>yNf0N(hA{{_G1?SGU&?*#Z>ltEhurDoQwT+sY)#Q}*Zy!qoX z9AX9~P$C46CLj$cMF4fqh0}B$tQKsPJEwD!^v_8(^7?Gu(zCC{B>S!f3t?C_VM8;B zeYlk!=}4PWY1|iiSK}OCXV`1OTW675wzTpe>Q+#kNZ(h|g0jd*h8X!LOb1d{ZXy%5 z8Af4+-Tr$ToKlF+pEK>i0XaQIs=(GM?K})%%ivk(gUzK!8A<(O9F{Kb-yduQ8+?8e z1Ar*T2nYhd0)usIl8`1BWK>$h4B}NlrURK1u$h6o8OV4LK&&x-F<}yye{#zIh&_&l zrbFS4!_@`)CojN0_$2W71$4s|Iy(pVmsl?6PVjumGY;Tj0Xg!M4gi4B8LCg4R=TEw zFck<-N6v1lhgOag5f!!7iezTHs9N}XSYI9h`E%kk6C{`2)S-VW^#004mR{bTRuZ}^8_ z2j(A41WYZg=HP312MYa4gx50a8-+X{cnK61c*n?8UPR(!;I6|0!65Rkp23wg<{9^M z8U^?l+}iVMZ-e#)l#Y}UIT8#hb16kbFTEqZXdfKpJ&w;sM7|0W^%?bsr~EzXgk^VL}a4ZA*uR+z;Ymn zabSQuPu_vBouBsv2LQ0Ou-3v37U%?Al@x{kV0fMkCj@m2@Bj>hSN;JK3kfg5c8Q>X z3l%J%fC=)O` z%`C)S;Fvh9VZnpLVmN&Pct zkstMQVIhZ;zhNEd4jwN#0T_du*Nl2x@m!%7;9)9F2@FUooARLvj+9)+Q-R7^2bE&o zIa-<*E$Ks{>NUXe0a1>0q?;$^#(l|l!07lqt5A6{g&T5wL8I-SLZp2UCo~=8VV59Sr;va^=+wSH z6XT4A9LY5P8NhmG&Us336Ga(XyNVLb}MtyXf3 z!ARL$x80j4l|^rYLLDjrN6Gk8C<@Q$`a2*mRbDvf8_e!hi>_PUjG+Mh7p(Y+H%`{Z z@u>nCP*=&X<-Jt{?0n7z_ zka0v^2X1{bUSHzD0k~`j0E~`+o((KlfFPsvn$kEe@`EmILrozr0ZOIcWDMlL=jBR$ zR}k68X(_6tj5T0v9FX@_t9uRr6f4Bvig&;HI~%IBQ`)ZwfYA57>h<`BfABJ9{$`+} z{A*$W!E)lS!w+hZ!u=)zq$r8DEG~(SNRKG{Gq&rn$I?|DD70F7W zz8Vu1f7x4qO>1F^9B(AI#V_!@v@XH&u3ZoW8C46Z3lPlC-QJ`BFkY|^0v?(c+1o%g zyVoQMkhLH?z!-*Q3znD!aEc@uuiP62z*LA?0*&1~0MMBkhiGGKcJGzGVOfcpq= zo33*!WxoJlU0`wX2z>ewxI6=2oWpv-h?yfmvPVj`N8}28CcFn>eUmEhU@mWiid*b9 z&kZt8Cxc-f%^cgI3II`6ss*$OkKeKP;AQoZhrvj}TC?4yermPuZi6-{YlC;|g2}qr zWXu4Vf=J?BnPEv{;1rbcl2V)3L()y@Xp@y(As6j=J=r-CzUvT_f8bC6008!lf8txr zYyQDK%lu8nft5@k8Gw!vklb^lT3P=Q7>XR{2P8?V0nrD;t7T) z55P}e0L~r)i%an0yl(l=1iL27pgbqv3s!0M<8(f;;B=iyvJeG|%IQl~`EB38M^cBH zheYUy@^fQv3qbc~@qG9~e(TbcEi^x0_n z9|h9OsPz6zR{yDc%`~N8m+qHnBu^WFW?--6Gpve-;kIUl(`Gc~YgldGx3p*KzJ8x2 zP(*&u>rs2(tvbZiRv(>=RI;7SC;mRX`^~T2LB<==!2kdNV88b({vy8q$36|fSJx-B zDE(g8^&mhJ?>ZR8{J{5vBT&;#(Nvv}Yiws*jG$q+X&jwX*iZsC)wyasB3PyTKTpw2Y4 zj#3(rt-LOq64MXk_rKybczus%{o1%c~GN4m8n3#VKoXj|l! zY_b5;;O*?$!m=@+@VqVrSOX&R?~l0iQT4}Sj$B7jf)mhF7a@5m0pSktHil_xhgkWG z))D~LuOIPv#8M`?Qn7x0uS-2!5W8@UY*Zz}*kJ$`9b3$74=k^+oS$O(_yyR9oM-Q6t@W&B z%0|~^JNTx(A78DL^35w}{;0daw(^e1yv%Qp5Kwiq^fRvHy>^G9qZ2r^Keg81d2&65 zczmk)!=F>BgniEGp&Hb&z1*Aem+6mS?1umx)1CE zcOt!v`nTPKOfo+!dmrv-&={GilM*J=>W6g<+zFP$QkPopi5aWJL@Knf+_DuzggFy> zz{!?E+?%0nMEIKnvR23$n(lj)?oG;&S~=wt$pAFYjLj!Hyf^>7i^dnknG_KbA+SA1 z)j`+((`^bCJ{XD|qBroY)<031EX0;kFT`u7YmlyQPM=}bc0)1Mn}{-8_-s>+>~(8& zEt8#7L$Cq~p0+~A4K`7v3DJ`iiOY~>2kEx*WP)j_u=~cOHvP$&vYWqCE^8TU(_3$g zK7$-TkmO}~`E3ZfRp#9fFQx5#v--pPGqk5NGbb{xWD<(2xIOev&Sf=Sqn&}{2K zb!ie#2rL8FugTA0yx&8UfY37zUBat?t5c!ufKyD@TS!|I8uu8imvVeeO4t0Icv*eZ zo-kdbZg%FEP5uAoS$7v-wQ0NIhs(<^R(#-3NzW5ChrYjd`M@W_%i!do>9w{W6{J5B zmI-Rmn0=smKirN}G*jNLT2_zn-xZq=1vMc29hZO}R2ZYD`l5)&c?ny+ii82_U726J zU+w7i8b~q}IjQ~XF6)H8eSM}W;3=E)N%}k1b5RdHdANS}e1oM&^~}VjvI@8-D+UxZ zwGZ0sNKk0Jo&yQ5;?1ex5BTsUdEbR0bBexX$+M-_uj-5+)csWH2Z_EtEzen)(Cz|* zTs>TE`WSz5Oqs8Q{-Pkm#-;uWCX+Y0eYH6;jpI@cy8X@s7_H>)-=c-%!E}#hXF8j= zdzaXkG#qWisEjBx2oo|$3Ik|2sVeH2nX3^8rDyl>I&y(?-UpPrwr8+xruoj0JFr#` z5uuT70z8oMaze%6_Rgl(m^BiUQN{FkjaVjGk*qOR#vP*_jnlTL8zF9-;y&8b@^`7- zS2DYUt2&2iHDU_KLBcd%Z7o3+=1dBQ4R`jm`|BmX@~d=91#!7rwM(z9J!?1z6~(gbz#{Qzz>HjpH*i8dew5fDB6VW3b^dJIE%%44!2miX-mf6<>V z+b)s4jMAlmLGVzjD*~g1{RbXzpJ$J!8F+OYzHo)k|L`8$ z>m{@7T&^Krk*qX%avOxvMDd+xZ_=b>bs7H*;>m*XD0k^>!%wlFNgbcfptlRm1NeU} zBS7c~{OnYNfL<;E+iR9T2K%X4`I0)M@?R!zYL|1D8`*+2j!Hxe46BRm{fh8!4ltxk zT(z!*8u>YQdg71f(#I3rPN|M9w$Z~4tH%9q*Uw%_$ z=i=y_5PV=nTdHnt0G!o3>!8vrT)EOKu9QA>gx^EPReA*T&x(d{yd1^Ec9?>nYL7J9 zGJ}=>IC0LBu4-Yoo}ZD%#9hg;t32Fmnl!*Pew{AGqYn)kxcDqJt~YnT*>ebQ@zco; zlR#cxA;d-Sf)@feEpW<>-WtL}6g% zBsL&4U?y?*H`(QkJgY%6yX2HbI>K6XHzzOyY|Io1#?|NtZ!7$9)*f03-%8^YB?by_ zrm2hR6@3$|W!a>VD7CAsDu^XCD)L*6)`M1=FEXgqYl&g>gkNZQX~Z;RYZ)d+m#n=r zm&xH7jK0ZBnYd0q{;?UZuA~07j(C0#JQdDMzBRhIJNL&Tvu0T~#bdY0tg(KS^+Q%{ zCCQMP@o`$dSIHNR@RJ=c@uZp*O7%S8dWghq`U~jwe`)Up9b8-A6vR1EKfb>v^^Jip z^o^(mnt)LhA6dlec_q$0=L(Stw{6pv^%7q+57NKye^Lewwn%6d{Hqp+2GAXQ4SNVB zHR-e%5wF<#9}t*kHwNztbwf-AQU6#evkURl|D^{olO7P4i5@L zKL^S=iAgF=RKOWLgiFEDiq>KcuT3`HQEu~~k+UU0Z}au~c65)mMIag2Tj-DXtd5;F z`5gnM{0;BRME__INOb%zZN`3P!gkK>frS|@>Qw%#8eUKir%X#oq<P%-dt8xQ&V~rZfr8gEDDN=YQ)* zm_hnpg`Lac84hpI3ul%$w`=^f`oY(tEtx*!CAiIMn+>Csfz=n9`hr*Q4n%df9U;>+ z#JdbTKAopoD78E?bAB=+KNm6`?7Cs3FK~Akl zwY#>hA#n{j#9-H#@7@tpSQ)r79CmWYj#z+EzDkmGowzNDdcAyaBRJ=sDD1PE@LTq(}X%Hwyoj!d{u40$)r7)8RgemcV_xm{;jS;F5T$*ImMg5=Tjf6TE_3aE;5?Rs2vEa zW__?K^~V|yK`{nbBo3%EM^^dfv|VlLSFwdM#xgm$3(5=XpU+Aayv)NY<4&+wvBQ;0 zqVxT{f$6s2;YoYTP^}@0C0O0`enIiphh#sY)qnOgd_U`T=?98BrL)NG?auT`MavIa#?r)bn`7!nNGCrfQ*7^M~aAk*oB zCia><%WSH0K8e8w_G-~f;F!T}}u+?>`_T=usuF@sPWPup5h*%x+UC2D%MPK^<0tq=yeH{xXou|#+8S7j_rF@mWnqN1XaZIzDl+**%wgzYN7fW9o4+FL9Yqf4V ziAr?!8(05uxqOl%Kg_L{xU*$`M>A}f`8|#{1ff-J)$3bu(aiP}Jm}q;TfX#S(u;h{ z?4Vmsc0DV~Z#I^IqQ|jXcbQzKh8TCe`HsKzk@I4o>o3@c^>_68{YHetujfxNL<9Kj z`gAo0@_qfdF8K(Uu40ah1CA3?{Ef-$c^@sUJ)WrtIgz+u?6Ouy|G}BI4xU4ziC(O% z@dN7<{!!nnbvdHnJrxG&qm7);^PqI)*6QpeZD&8X;I$Y#^pb#y7-(x78n8Jzj<7J~ z{T&A-eyzFNO4O0O|;rfzwC!sF90ho+-pY`wCHe08U zzxwaP+YN772@UOF-qL3fmq~o4Zfkufd0{{jQfw-Hf)R2?j5($@eiC&~s&-gZH?1`9 zphZc(bBmL5L-L%4&X*w$cYLl!p16j8GFv6lA)RF4+21v8boo6nH;bqhy}(iqp}1c- z{SJxLWc@x#4dC+>kt1%kir?g&ZL2~rnzo^`vqx>Ty%v`Mb8jUh5mGoQdD~#;Z1=uF zfg>^U^(tNjMS`NUh-G8oHSi^gFh~|C}9`NJxbuiP9KncHsA6O2)xdEh# zCQ;h~JJt>@2>YqSWt5nywR;swvY61N`S zwV9d|{SqMak$FVEt)aD9vpk@w-L!B`<}vp?cjA<|sI0p0sWiKu?uW7RJmY7sFDf2! zha*>CdE?;D8r*%SgODROmor1A>cFPodi6;SWb(xc$!3@PgcDmy=Agmtqv>gFRaORb zjB26j#8wHN(SAdse|qWOSaa$Yg7UBrC4#@uwHP$I+p;=?p6=DwRN*5~%>SSCz^V<$snMixtQ@qjKsdSi=k#opp4Q1$%Sxp z{3fvoU1uY-?$Zq803QgV6&2^aS5>RGzr95l z_}|;fxfafVzx?*>9v=Mw%f+A=Xqm5)ujpJm3S@Ty%(D!*&=SDdE0+$8*%`8i8+>2A zzs@LGn>HNXueHjm$B5@(yZVfaHQ)8vL;h?-rys_Q)%aZ*WNY|>1!9k;t}O_)9WQjS*M|{h{2O62zKS`3I&g`| z@%Ra(fQ*LI=9;**NlVpz^ye1iUU6lqRTn@^x|wGw>t_5&hT2HZ-8zzW1IW3eN8l}d z*er$#@y`avvM<@aBV0*B+SbVdluNU<&!Euz3v>h{;=KU09&wap zIRaR#qBBhvMgc1RMt}ZcR|AH`rNZ+-ADONp${7y)lGoIABPym&5rPh@CkfMu3^hbR zaTQE;f8)1%RNKGVN^)UnPY78FBWI~drD4` z{S*g#Sf=P##><|cM4ugj3T3C^KxFVsmy@hKiT7bbu~(j>{1g90m2rO=+GpIR7Adxh z=$%s?Un@u}&f2KsM0p7HTR7cEYDhYF-0m*Pd6>ktJ-L`j%RG_5bPifyrcbC+Z(`Lm z#nTqqaJ)5WPM^dKB+I1?r9zu1jQW4u^b!SNR#1k{<8(4}huYT62Yurv+KD!ZJrbyH zM>CaLQ2-=BWm0nRNOXvyxz`2ou<#aH`Gk#J?^o}w<|Q`(^V2OFhPF%DI4?&q(`7?k zIVm<&SNDrC|;WEj3BwUJwtIiBbG`uJG>hE#yK8cOqbk+dpplC*M zu5&=sQ+z0)1E-{bsqLm=``i&s(g zlRT?u!WIl;xFC0nBvz6rFNbTtj)|vI)dVzAvUDuqfc(dC0jT$LCk-WECiWG7QQ6g_ zg*pvQy+y^oHO3Q5S=Tyk@4#K|Ee><1@SofkG zoi}=MUz$?zeA{$sk-9+xSs8efBI+?MP&8mwc9@&t26bzV~B8Z8qEO zRk18J=X#HYudCb~k`Ck1WY7&o%jyRUm)E3_?{E-GJG-?p6^9dKtMctiKVZu{EmxoicRrdrsZ63n@U3 z8fg?nuE2l+u%L;I8nHV>zDycUPZ2G*l`s9MU#ao!b*be|33dVLqrwoR(4qD|?ml9LwMMrI$KoH>Gjxww1{Byls5LYT-$NP3=`^`I5jFnB~FiL>>95bv!lif=P_x zi#8|aBZbiMRgu55^T9#1x3mFs@DSzJ87m~u@Aa{D>s4n~#{0(cl`CNUyk#sv@@!Z# zJ#Y@xH1FZ29~x_bJ``{`Eoh-XZ2#~a`rVk{)2;_uCL&~;?C9&7de5}ccJ9&bh7}+; z_M=rP2^P3a$OO;=7F}&%p?stH*SOC;wpvvE>rUQ9eq3d zS^?7EyiCFwOzKos)COM_=C37c{#ClUn6(++Y$(urP+0wF$e2H+=HEm@x}_pP@L+u^ zI^-Pt=*Ltt@Js2`R;jDfZtzp7a?8wrs-E`eq^~=z*gzf|b)^TE1$1i^}!Jfda@If!-NH1keslt4YhcSvd*U22#jnm>w zj(VSJiZ;_%T@VIj$%!w?kbZ&K*ZrVVL13bF4cZkRUxknGJv!@orjB*_=axyeD_-{lim^d_5n>VNPX6!HOp7f^Ww4R@ zs?IH)B}VEgv1)X|{z$zdqas|gZux<^?HEI{#!Ij<`KJT`-C62D{35@0K;9Cx#X{Eb z5IC1c`HW824sot%>*<^x_AAu8Q$jaUa;iCb;NWYPNsYx|i^aaZxoPfhwACXnI`YJZ9%y!!-ranA^^P@R!$zLL z1S`^xrZAo>6-CdXGZlyd6)(iBn&A+V6TALer{0SX{rgL;kqumps2mCs?EO z_67ktbAGEBsW%bGISHf*$-n1Hx^!2eE^i;)+T!uKf3v~55o3QWGuQ7&aACqrZRHE_ zot|uT(4i5Fs7t??dk=3nV4Pv`#t-uj84vG%&UO+DG2(`{VXFN|rOZoU{B(02vj41i z_b2elja;$GFC$9ja0^7HDJ3KmQ!h>rc^b7SH&44a*;IJy+5URvSlB-o%Tk=Tv8p@K zO79WB%$(}+o%^nQPKSB?Jni)GJLSE-=i~R)7Wa=w47ATmXa;jYawOpRtz?J_Qitel zAGp8t)3N0mx}wt#yZq(D`bGX@AS=U-Ptj^-&RcqnMwq&**ZHrzHY~H+t(U%eq6*8x zKfdg2BZd{m@A<9=3t`WAK_Nk4FXi$;WWN@e)=@yh9aX)Yc<8tBfuF9W3v->Nn*oRD zOjMkXvhI{(i(~Nx7m@Cnj`N>eFhMl6&TXT?m!neyro&5`+(6V~4>^1>+Fke9I1)KI zo*@$(`nCe4@~7AP%}+*qs^aL*Jrp(G%A1|JUqo&nLZyu}PLuV;ued%|BI^j>&T6KA z#DQ7_c8;VlWD6H1<`oes;{JJ z9>lzu9N}sE0QcEeYD|0n7imOdJzSE&MJZO_zqsamBs+lKOs+7aRviYG;^10GL$?XK zp5M8)|5=x4S_x&%oO&X#Fdj9fmwxCwO@ zo|n$>$Z0t`6&WD|PbWGR4eu^2YHF#RrS^t2Ooc==&1zX=v}=m1NxC@Y$k*Gs^5ml(DwZc#ZVkbExoMYuFs4h*mR{NiTus zyRKXWD?TblK!*&Es*=Q`@_nqf)|TE#s?W*odZgzih{bN-2kbWE<{=dxI$PBnynDW$ zi1G&?JW~dND)gXedK3y3*f1-6hW(Ql);Mvk9tIu6oe-ypCOz+)w3c_egPT|Tc=;E+TMT8b;m=>&XU8N#zI;WbtZS2fKFrCQ z9W%A{gOO4*d3IUT;b4+UH~&@{{r+=-KqpbT{WNWS>??UUDm7Jv&RGF6DlUs9;Ro6N zh|J#n)xs4~%Eog5pYAA5WxM{G@|Uu)BJE#-6@!lDRFY;Zs$S8v31k8vy|j%v&Fm*_ zUiStrq7Nv}yuML7np^vjL0UZ;PY0O!ZSLu^UCLGC>2)v@pjrv_pFO72T$LQeHAc@o zDE{;Qtf$x6O$BrvtQnpDx{bN9)!brtP^`75pRAjNY(-L<&^-02nQOvxD%GCl);@X4=nGCwe5YiLq=J3}DWr87JM$BS; zU{rizurXs9DHI|@#0YF8Uc-kL!a5c46oXv4q#@G!d zc}d$^?~gxFU)QLr9L7nV2g8timq|L+#ITfa0BCDhD3A?KuFG(5B%jPCWS4CGVFc`; z_vfBu$SNSj|NbpEG~p}B1N)p{iz~%hye(JCpdU}dfYWo5MW_mm4HKgUGz1u~nhnee zu}5S?ebhg|7#RmI@6W1NJE2I^?=Il%ufNE? zRg^O0My^k&WqJ9qy?kM_VRO-Tt9Wq|t`03wa*_gB5~}yF)?@E@Ws5b_$&!tcHAt@s z9~YHnp7bBI{64N}sY-uyBE-ToSBp{K&S|dB%)apCaM1wyjFMOWAAOZGxcp;afiv|? z>kHe77lQR2CT8;a=l*_}$LU_v-#LQko4@|L>-n^|UB5VSDq-Gtv8E4;e?67FWrT3S zVo3SnBWeAbkAK`J81F~)&D8zJ7ZP&=D!<&=C0AAFoYGe*WM*sOx*_#~6%>xPJl&>f z*UD;T|DM2zR^Gb-gOg`7 zNf=k2B>gfByqLpf9j8UDnPEe9XaCm>cTY@fJO91NdNns(sG68IId5)cH=|!*NxG8U z|JNgrb{xW+4(xqp**-|Z*dwo*GX2|d(^PApU*n1Y%C4$`4;Fwuezo2{)?wjO-+t$s zKq!>&@C4`JMV4ZoZ&!C8g1S%{mW%kPsGf{#SduE@k2kttuJP<%`!HYZ1@gvob@A?x z4gJJ)07GIZVUJC5!AGu86;(#N;!_ed8hj_aQ>D7O#IBm#e3+c&*VOF!mfd8oG%>(* z2uH&?dc*!ry8YVVphQ|MX?R< zr3@K%LC%oD_~FJat_qSJ1A1?9DGMzLMs0yQSqg%7;}`$9>T&tpOiiL$j+5A*@fiJn zRMVdRAzOn#RH8HPUI83j+j_-r9@qMr@!vPieO21y>&1ZQ$KcW6yrdjs*XLIIWb!wy zg}Zv=$E~ac-uguBsbr~lHS7k`ew9a`XSl?&yy`^&Y-&l%IMI}y0&F@~=RT!{vM!?f zYu~4TfjMpcJj#PIx8#^NO*Q~NLQ7wP-H3fpAYrk$Sw?&&(r*9*6`Fyp>@nbsoJ(-f z+!2Cao1NdIdae;X1PH0!wZ4I&L>Wk+JyB_Uu{{L3^Q_mwnE7IRn{;+?EEpEM2Um*yv0J2d~-k%~8V;s1I zC-q6Msf49^-aHa|8=WTwN+o3?%11+dD*N;{;<>Y1c zit+q=IfUn}o$puM!9B76IAv3FxokEa;0ZhZ<>rparD{ z%HNy;n8hN43!3rpho{8bKu#g9DGz*rO}h};p#uVh;R&6!fcFohrOGLMh%=oA*Ucdg z@SZ~*9eAM)HKSwp6UnpZO+<`nAGgnZ+?@LX!~J;X?N;}27y}V_4Zw#U=wZjLF9B1~ zqh!}Pi{a`W*8P2Yl0oUR#(O!yH2wVW`0lW(w(>=v4sdjl74d?az9eLFjF+%Gk*Oamu5V)AP0jBsf^#dwJiQ?JSi zM`xMe(E^S__uphS2;qiBWojLgjY*l8kqqHMeV>-ai~v|P6(2e%LWAg?)L)d!oy zy%r)sRq;7+ymYNyjL8|J%bw?1cB8s%fCoSpNe@K9K+2F9rB<|dlr`3#9vUDp9<)PQ z|HJ(N4VY(6+-gP#G{xnAzJ!#~k6IWPRQlzmIyK*1yar&zm@$Q|+TEFXYWLD;7v`p%`P=4s8RDl(%yxnw|gB=eBRAi+zvN)+rDlhyd@ zkTQe;(S)kEtaqfGe6GFwxDK{J$;y42?i1N(Fg#hn&X+VVh@A z?+neujPQ6Csyk>LfZ*`g@}gJy63mVg%c@1Va_eU6z}@S;t?vbiaKRu=?0NZbzr{2B zE7&A&IK`6_3;o}dC9Bh(Uy)@uS{4s;c@tV*G&NvAv4A4>CoaE|sh!7_*8tRNI>h`Z zI&Af_;Ma!FW&j#s=_P(a2h_XoIH^NCJg9(Anx=9f1)YslEh`c6n5c<76^&};{+;nG z@{FUM;j=KXASxi7i1KJp4OBg9@*nQT0KjBt0cz151<;OH^~AAycJS0%FHgfhP6RYz zwLG0Y;Scz;6Fs`{K1l#PHvUQK!^amO*s?QeVw1qj$|t2{EmVLCQaC?e!d4KIC=%wZ z{F60L(P@Bk-STf(yQH8n2=GJ$ntI=&0vjOMp%V2FSmKiuXz-!I90x};?6X|&#^#Xm zsmuZe3vFO*ArbK294NC0Ya$0!2}i;=X~lsG**+Zgk-+}JF82`Nl`^lsc~~F?yar>- z1#yb9wT`lNk7DJIHL{Hl=w_gHGo#b-IuZzqmsOkczafNCLKa-Kej#vfQEs*D7w$cW!J0XM+L9YUb&{G+b*+ zyqlgsiX#$6IsVV3#0P*n{dvij`Mm=Sd&zzA>;4iAP%XmVHP@N(E_ksmhFN9M3 zM3it7Sfv-qukOVXQCpdCe?(@S3-JKPK^@wv|ALYM;P2}Kh6sb0W~T=2pt~O&DQ%4} zt1N5FiJlFF+B>* zm(-3sYVL&o#*x3b6aru$o)g{QP=Nl^lJ8_krpKZDcXeT%f4|`(+rcC|X;dutIsAaMu`QK%jak8TaX+Vaqw_XspORTg{NnkpxA&r5U_ zLq`_u)|)tDA&kg9DFB41#JNLmW0oz{WB|bv6hX`T3bZ>YY(6hTB5nTeW}Qo~X+}sP z8OOaBH$9vSnz^Uvw+4qzm){HXY*5zmt&8oITgq;v7ab*cFWnJ1Llv7kndMu(qp`Q-JNY(PO03ws7=pG4`7nZF5c5pQ?`}gbcyI zB33cg=hUk4)GqSr(nqa9B%jGg;=U2FjqSVb$6UnOwJqEh&$SRkPBPw;H9g-en_g{6Z3H(~A3LJ1*fJ;q~-BxhozmD|kZ zsfFL!D-S5@z&*B^Cl8-wz@*!8s^rzdcMq-kSna7;1v;vS@~6AaH(3D^xPCv)9~! z-}f9=o?cHzTm||7GCKW^tdD|=QPO4{s&R6!RQmkl+h}j>Nx4PAYe9IzXm=3ka&VFh zavjCpANx|fz5y$;L>MHi?$5AVD{Y~v!7PppIj0B1>qeY_4E(fDx{ ze?`i-h^`i0fP-Cyzn6c|!5&EmNU3~u_^%dI3Xo-(8KNfy&Ba;6l!auKP>M!sQ&y!C z{#i#|XhN7*j==l|XI*<)Gc6|}Vq zfB+~+4D0IOo0J425&1wOF58%79JVuH;B1oIJ%Jc6$R5(>kk25VjxK2p>9!}62td(v-)W}h^Z6iK7r8YyaX zgL=>{H~p$=Hf%r~H;!J+0L-e*o}BoKJ7K1|CY$Qjpyvnj_`E0G89A!$L<)+cUM}pR z&%&}A71m+0L&W%cf%eQv3_qo$)~DOakbV`3AX$CPxuM_|9rp?G0|pqe*tFJ4W7hpV z-dO+;f^X`9yBZmpHB^yhh-C1H;!UL-c=KIwfx~9Ig!Wk!i{ku2MoJTl&t#X;XH0Ji z%W+^927$~3nVMlX^+T;Oa3d7Xw+kVo^j$wCQMl<)&ooT=FmAyE9Ml|3`_Yo}ci9Y| zT&4s*7Zl$VbhhG2E$Bulin7p!XgXbn`#&22lxh}5R9e^QG*lnli=CI03d+iQoOhgC z<9kjgu>P?aJXGUGHy}Ni&5AC+O-o&AO+jH3%pw0+BF(&?gBtw`Y+f>^qoo3iEj|}m zy)(j_)dvd;=DGDhhPx|v5L~niZv}Gxm+zGTGUGblSlqO7W9y)QNHuAk#1?LH8-C9r ze3H+5tl&0rwV`ol^7>uk{=MfCN-RoJ!`p+agYC`I<~t{V9zC6aWJf1;gvTB7c(Z=L z%0nN$BkC*i1=NK1e^6`IO=rR?vLku@!&55khF0;q9FU+L$pYo7U`!RF-tPjBZUE1j z$~_A}n<3ZLsm-IwUecJ!I8W87(Wc^W_8IF)jxlmq?5x5Zu=DdbuSRf!RF6zXCB8l9 z#Jt=XrBfjbZz|eZ;!`5}u-c-v@m?-m##@>2-tffK2tc)hr3NCRi1zCzQBfvv1uR@; zAZ1!WL%N9PpFu(&YhM?AcbM1cMvn$hW+*vPP^Z zw5?R4BFAb*w&533in*#4cm7vW`X4$X64)QTIc7d}>^w(mW}Z+&6<`>!pVvMVfH)eG z5yFFVjxx{z&!)ipOM-f>Q=Jh2ISyF*_;absj4R6Z?EDFpC1!HWBhXglS*H(tkX4qc IkTwnaAKgk5UjP6A literal 0 HcmV?d00001 diff --git a/theme/colored/1024-owncloud-icon.png b/theme/colored/1024-owncloud-icon.png deleted file mode 100644 index e32847c1c91208540f2f876b4bd6dbf8266d5931..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52860 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

MkHU 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

#SeiI)8=}0Yb$+We$eE~k@S-YM`>rR#q{# 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 diff --git a/theme/colored/16-owncloud-sidebar.png b/theme/colored/16-owncloud-sidebar.png deleted file mode 100644 index 5c01c4fe9e855c3d6f40a7254ee8d4809973adea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 495 zcmVFoG^EQ5ES7CTbJfFhm1>fNOqYKnpWOXVMbHF!Dw zWdy}(lFxx!CBCJUkYWv7O2zESy=xb$`!(6#@ocKnoaaB!By%;;2kf&cxCkJ#0JJLC zBVhDUf~T*iIz`iU7wPKX+JRZ8ameumcpa6?TIIS90CAHg!`q~DUc0->ew(gESe>I!sTbsWy zr-ZLqd?e9_cn@mZuQpzi=|KY9lDZJLvRb`9j^bgMmK0i5avi*2vA8#-V3NcJq4Opc l0=@WcE~~)YQPci!_yZuuiOrMj=PdvL002ovPDHLkV1mpK*FgXP diff --git a/theme/colored/18-Nextcloud-sidebar.png b/theme/colored/18-Nextcloud-sidebar.png new file mode 100644 index 0000000000000000000000000000000000000000..017f0204abeef9ff84116d7ae6cf3fee3e353605 GIT binary patch literal 1002 zcmV8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H117}G@K~y-6Rg_<7mSq^mfA{mg-+wnZH=SdaS}jYRVkt@l;Swi- z$?ANU5~N<%ww2+;9SrHGBCUa;0!Z|Bn$^8B<8{}6W|0~lKiWo1;L;! zSm({a3SlnZ4AwJo@kRv#sCZ}ML1J9<|3!Xepm^I6m@Z833 zHa*nE_1hKXJRRkptKIr(gc!GTv;+EQX^Q|+)N6)XLt*HRO?K?I4-~ED< z7e{c*R@0UbnHakY-J2m>#O&aC5!F(qW(v@#K~#hBQJS;ji3dAy_x148?|(7XFjSku z!aVXZHd}?^uduFFn7#3hy{cgn9){--MNqV}JZGM>6+~ z$fG1daRa=+9I$5l1uL~~Ap`s%H%L}DTh3UupkskatU1j Ye|L=guCDFwG`2MYy3ge;P(bP=tDc5pEMpo1XRD46dj-*?~lIH+jT zK;89>_gtQPI2ZUgRjO8(mtVYDTO`dwyV5+kIW@Hi0M~$-nRnHiTpAA(&0x@#gD=nKa8Xv1k-gtd{_^H z3BM6_)uQ0;$b+Zn7ECmJfAR$B1`W(}3SR@*4Pe<%dzO%jfP2I-fBe9%$~@53vGRJ) zvpv@GiU@>|M?!9bU}@9cSqRIdTWKIK*^tq~k-a_uq%PjRcPNbfGbATPL;ygD8s|ZP zAL+OPkQ{&<=&}Hg0YK_o5amG{2n@(NfDaH;1KFwyP>_<}R<|gh<-UnYPaOZOb11YmUAHWn=bNIyGsX00000 LNkvXXu0mjfi{%XA diff --git a/theme/colored/Nextcloud-icon-22.png b/theme/colored/22-Nextcloud-icon.png similarity index 100% rename from theme/colored/Nextcloud-icon-22.png rename to theme/colored/22-Nextcloud-icon.png diff --git a/theme/colored/22-owncloud-icon.png b/theme/colored/22-owncloud-icon.png deleted file mode 100644 index be8a913e30d2b11fc9505c834b3bd280ae0eb0cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 713 zcmV;)0yh1LP)n+a8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10!B$hK~y-6-IQBs4R9RCKi~g3Thlgqa9v8|lA}n?ZH2vgQ_|eh zC=Xtyq)|$vytpjok{3yN(Aop>;9**wi8s;Ih(g53!(4W3=bSnJuZJCT>9{N@`M>>t z-+rGy|4TpF=5MU3tQ_Kz4|TVcbUSAWcg56F!>nW?Lf7px3VS=tHh@^Z>pUmBmjnx0(v zNLw&f!iKubXW8NccGpbIEB_Q^SfUKLV?@tz)r+S7O!`qpXPCMoUT=*}5s5 zL7o)|>BNvP?cBWTTsG4h&>F31LGqt23MxYy*gJCBW*EV7n`b_2vs&&~I1> zu_>9!x-F5&*2>H*wp4>65G+~d2=)%dn4;Do(n;IXq%R}E=57#!2Bgq2^4&J>J+?5E zCBy8*n>#&>o#CA3=L`93mk;mhZ)|O?%)U*`1E?5R=sDlq`~je0-?6%2W*|RHm1S-m vII!Pqnp-DaJlg#Fr?cWu)_*#W|0(b%W>o|BzSOBG00000NkvXXu0mjf`$$Qb diff --git a/theme/colored/Nextcloud-icon-256.png b/theme/colored/256-Nextcloud-icon.png similarity index 100% rename from theme/colored/Nextcloud-icon-256.png rename to theme/colored/256-Nextcloud-icon.png diff --git a/theme/colored/256-owncloud-icon.png b/theme/colored/256-owncloud-icon.png deleted file mode 100644 index ec0ecdb1a48a23f8c8034b609713ecacc511681e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9012 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 diff --git a/theme/colored/Nextcloud-icon-32.png b/theme/colored/32-Nextcloud-icon.png similarity index 100% rename from theme/colored/Nextcloud-icon-32.png rename to theme/colored/32-Nextcloud-icon.png diff --git a/theme/colored/nextcloud-icon-32.png b/theme/colored/32-Nextcloud-sidebar.png similarity index 100% rename from theme/colored/nextcloud-icon-32.png rename to theme/colored/32-Nextcloud-sidebar.png diff --git a/theme/colored/32-owncloud-icon.png b/theme/colored/32-owncloud-icon.png deleted file mode 100644 index 721c04e4858f09706c0d9cc2a8a5839548e43f3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1061 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 Z{R1F<8diQsqkI4W002ovPDHLkV1icD4=Dfu diff --git a/theme/colored/Nextcloud-icon-48.png b/theme/colored/48-Nextcloud-icon.png similarity index 100% rename from theme/colored/Nextcloud-icon-48.png rename to theme/colored/48-Nextcloud-icon.png diff --git a/theme/colored/48-owncloud-icon.png b/theme/colored/48-owncloud-icon.png deleted file mode 100644 index e696d98abfbe65abe612a7f4675ea1f574919f8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1581 zcmV+|2GaS7P)+H-n?mIH;;p3*{F+ESp<_J9(sZf-`GCH@=i zJ&mxo^puk5bjkVQllSF$p6~bYkn})cEH5uJ{?9Pz0(1eo09}ACKo_730Q|AoW?$@X znfLnLF7NffaL>|RgEw}k(HHwW_pvYFS-i7@4`o301L+sU~@6p7P*0Ak(+!+^wv%+d~*;B-ypKV7QXS-BP%dCy?DSH zS|XB|jpeP;GB6ZcGCZ;Zmf$rQK&&t@wP?2l7t0g1^)Lq)L&hNSI=Hu(C$AP-CYN&l zvjRqc)Nb<66RS)vbeQ}LoFpxkzk9E6S^<@F=1Zkx%BONn5s4@qGkbt;RXC=UN<4T_gucfe2MD6*4Qw{NKxL zfx1M!8}t3}Knrkf(_6&D6Hc*pf=GvC#Mdes@xLXqdP7thD##hhkb9SSXu>ES_W31N zU%MFd#0nhK=rN8FA4${_X))mk!C6J+Z-A<{J{-=NF*%Ad z7HC1R3lM@4N$5w4z-d~e--lyBcYrxHm7gu-jusfJ$(Yk&p(X@R`-Wn$d(jV?G}b79 zNJ48BT+&$U*XRJY#yUrSM%Y?wAf3Mv;yYmL7whGkHN$EDnq@So1}`_LP$HE^<)HVX zV&G6Z4-kPM=qWIZQurHS5N+&1^VZ8zSm0k} z=CWF;<;Z!y;ra7YGek9;HDE`be4sv?Y^}6^cWqC9NuAX6G57&K5id|JF$QZSMuGxY zm015?wZz~CIjBl%%&U=@e56+`>AMWh;~8eN1?=d9v&wcGzFxV5@5ykk+qsodDMWOY zA{{}A5b3Mt8geQ{@aKv8S&?q4q66MpDbxis&S%^WX8DF4XNAbj`dR(xSrJ^Gtm|7D z6@28v86Hez;wL`*%^9v%y+-H31!wr$@79~ABtENc$S$wpR&X_4$(nY8aZ;dpv%Et+ z10bjJ>tgqboZKTjZaefaIQZJ4i^6%&g=K zIP#nmkZhPL5Ac!u3p;vV1kcu`c3*C3*CJhjEs3$hB&vCPr00000NkvXXu0mjfn|t+X diff --git a/theme/colored/Nextcloud-icon-512.png b/theme/colored/512-Nextcloud-icon.png similarity index 100% rename from theme/colored/Nextcloud-icon-512.png rename to theme/colored/512-Nextcloud-icon.png diff --git a/theme/colored/512-owncloud-icon.png b/theme/colored/512-owncloud-icon.png deleted file mode 100644 index 723d583826f7e6f404a7c681cd12cf656c216999..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18391 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 z 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 BM5+J) diff --git a/theme/colored/Nextcloud-icon-64.png b/theme/colored/64-Nextcloud-icon.png similarity index 100% rename from theme/colored/Nextcloud-icon-64.png rename to theme/colored/64-Nextcloud-icon.png diff --git a/theme/colored/nextcloud-icon-64.png b/theme/colored/64-Nextcloud-sidebar.png similarity index 100% rename from theme/colored/nextcloud-icon-64.png rename to theme/colored/64-Nextcloud-sidebar.png diff --git a/theme/colored/64-owncloud-icon.png b/theme/colored/64-owncloud-icon.png deleted file mode 100644 index 5c6f17f0cd078587d6c496e0c604127a00f4d736..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2153 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 Eg798TbN~PV diff --git a/theme/colored/nextcloud-icon-256.png b/theme/colored/nextcloud-icon-256.png deleted file mode 100644 index 11b0833cac13e067f7425d988d55da98538fab04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52351 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 M07*qoM6N<$f>dmt2LJ#7 diff --git a/theme/colored/nextcloud-icon-48.png b/theme/colored/nextcloud-icon-48.png deleted file mode 100644 index a1a9625f999cb3cf9dfa09ae9c679726c6e98ec6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3725 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 diff --git a/theme/colored/nextcloud-icon-512.png b/theme/colored/nextcloud-icon-512.png deleted file mode 100644 index 9f40c76cfa593b71380490b9327e77f355620a5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137075 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 z 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 z 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

Y8hwK`2{S3b7?UFj28 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%0Am1D&a8Rt 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 diff --git a/theme/colored/owncloud-icon.svg b/theme/colored/owncloud-icon.svg deleted file mode 100644 index cb01fd8c4..000000000 --- a/theme/colored/owncloud-icon.svg +++ /dev/null @@ -1,1400 +0,0 @@ - - - - - - - - - - - -]> - - - - - - - - - - - - - - - - - - - - - - eJzUvfuSHcmRp/cEeIfSH2PGNhNrMyLvXJnMcJ2lRA5pbHJEabTWBnYXm9hBA21oNCny6eU/jzzn -ZPrnBwXuGY1mCesmWeXIa1y+DI+I7x/+p19/+dOn37z/w8NP+/vu7sk//MPzDw+vP77/8LM7/+nd -z9++/fGHjx/0o5/85ou7Mt93FvT058tXW+A/P3z44c37dz+7K8t95798pb/9k6df/+nNd1/c/eQL -+8lv33x8+2A/e/+Xd2+/fv/jNz998/X7d/c//PnbL04ntCO8eP3RYoodY70v413pf9ZN+vXrd39+ -/cMPb/6mX0790tvPnr3/8d03b959++z9/2M/LPN4t/T9XandfLeM1QL+y5vfPPyQRt3PS9fVta7T -Yj+wvzLdr/afaR7n0f96ue+Wrk5r309zV+xYL95//eN3D+8+/vrD+68ffvjh+fu37z/88LO75399 -/e7ul6+/td+8vvs/H96+ff+Xu2dvX3/9r0/s6YxfvXrz9sEexHevP9qd6LE8/XmpXz378c3bb/7p -x+/+8PBBD0w/7b/yI/7uBzuUHVX/Wz+ev/r5d/aTLx8+frRbsPPpyf7mH5/tr8J+6H9+8i+/tif0 -YCf78K8P7/7rF9thP7z/Xj/54XTzdbyf5/X8n9Pzmu2RtL/x24fvvn9rb2F7YGu5t7816N/7/7PF -2v153Fr0m2Eq4eDD3Okv1mE4H//yJB/+/ObhLz+7+6f37x7a43r64eOX7RUPQ9e1f7ff/ObHtw8f -fvfuzUfdh360tgf2y/ffPLzdfuR//9Xb1/6c/E+5/LsF/Pb1h28fPlqpeP/2x49eXpfTGex9/OL1 -Xx8+XE7wq+8f3v32/T/7NZZSp/tq9z5P9yox010dJj28oburk59mWOwdD+czl8u/2wl0OB3sdJbZ -XuWv7eX+6sObb9+8+9l2jfNX//jhzTeXFz7Xu6X9y2/j3q5X/7FXUTsrv5/7k/Y+5qmMSxnq5/yk -PQN7nB8/PrzbnomV3ee/3BXG7v6XX9pdvHz3zfP33+md/qBq+WC3YwX07ftv2+/O/9t/Y3/9x+/b -E/H//5W9/l9/ePNOx3zyT/6b5atfv/3RfvWPH97/+P3P3/3x/ZOftGbonx++trbGSsg3d7/6w3+z -/2Mtyz+9/vpP3z787eHN13969/Dx4Ye7Z1a57Ofn2PvXb77/4pOHtZv88HDXfml/0//v6b8f/9sv -Hv5oNfzy19tP/8v/Xfv57duHdz/9v3784fXHv333/psf39pvW/TjR/3129fvXn+485+fDro/1N3P -3318+PD6Xz+++fPdd6/tPBakv/Pw8fefcXArgN/b83nz59NtH0/0qYDdrx4/0Zdfq/h8uHv24ccf -/nT32/fv355P8eX3D3978/rt92/e/fDwNjyk7a/539Jf+g90ol+//vgna+Ef3n3zw/kMT999+1bl -78d33+J9/8KeUwv/rGPbxbz71bt2Et7KL60TfviQ3ok1fe3v/X338u96vvPfyc6lavs/4Jmev377 -9s23H15//6c3X2cn+9+33//xzUN6zv3f/3vK+1+/+8P7t29++O5SzHc/+fXrDx/ffP324cu/2vv7 -nMamFYS7l9+8sTbzSpPwyZgv//L649d/+sWbP3yymOvZ/vHNu2+son7545uPD+eD65moA/n24YeH -j3/7aE2yNZJ+I6e/8OX5uONX1qfse42f/vRJuXv2bten/OOH19+8se7IYPN37969/s76i2+3H33x -hD+yjrXePfvmyb88+V+eDC+Gl8OrsRvLWMd+HMZxnAwKl3Edn47Pxufji/Hl+GrqpjLVqZ+GaZym -aZ6WaZ2eTs/sz/PpxfRyejV3c5nr3D+ZB4PKeV7mdX5qf57Nz+cX88v51VKWuvTLsIyL/e1lXpZl -XZ4uz5bny4vl5fJq7Vbrv9d+HezPuE6rHWC1PvrJ+nR9tj5fX9ifl+urp93T8rQ+7Z8O9md8Otk5 -lqfr06dPn9mf509fPH355H+12yqLsdvT8sz/eW5/XpZXtavF/6m1r0Md61SXOts/a7Uj1mf1eX3h -/7ysL/vO/pS++j99Pzzpx14Yvvo/T/tn/fP+hf156f+8GrrBEGLoh8H/GQd7UMM8LHaRq/3zbHh+ -es6nZ/3EHnd72Pr3/oHrHz329tCL/dsffLst3c4zv6UXuqXttjq7Jd1WuzH9M/mNtZtb/QZPt+c3 -2Hf1VX3Vd0/O9zj4DY7+79n+LOcbfer/frH9eanb7V9uN1y32+7tlnXb4xO779Hv3960P4HVn8Bq -z0BP4fn2LF4Mr+x52BPx2+oe/085/6mHP/35z3D+Mz7p7CF3k/+Ztz/L9sfKWffU/zzzP8/tzwv7 -89L+vOpe2Rnaf+yBlr4M/md8UvxVlNnL1bqVrefnF/HSX8ar84vo/baevXz24tnzZ8+saK7Plmez -VZfRHkP/rNor7J6+evrSyutzK7dPrQQvVpInK9GDPe9qZbxbX1l5f2El/5nVgNWqwvzEasVoz7O3 -N1rWbnll9eaF1Z9nVpMWq1GT1a3BXly1utbNr6zWvbDa98xq4Wr1cZ71uTfYy61WVbvp1fTyidXd -51aHn1ptXqxWT1a7BytsVcVufGU1/4UXyKdWOO2TaZz8tl6M9v76F1aOXpQX3fNXz18+f/H8+XO7 -0+dPn6/Pl+fz88mKsN52b+WtPO+evfJHER/G9jienJ9HfCLxmcSnsj2X82PZHsyT85PRs3m6ezrx -+WxPyG/L3mH34pX9efnixYvnutoXT63RWV5YzItpu+n+fNOn235+vu1w40905+d7f76790tROBeG -XXHIbt8fwJPDE7iUjMszuBQOLx52W8PdP3z17IO19N39tNRqr7ibxnGdx96+gPq1WFO0zl3trV75 -T7pVBXwqix2hn+0npbfCYo3Tuqhh03dTbwVoHNaurFa5FvsAvB+W2o91HeyD21o9+267H/1X1rB4 -qPU25W66G+3T0L5y7YLsI+qr/zgX9OyHJzpRWZZhmO0rpiv2aasBGWtFa7XObFpLp59Y2zCXydrH -qZR+Wf37dB5Gu8TOnnoZrQ7pu3J36m70r9FwOeez7x7G/0/nt3t/9uJMGSeO+PTnat9+swGSMcev -37/919d3L95/PEGTQQd/dlfvu34o8zYGdT+uds9l0ZtZy91c9r/VKMr+13pEd0/937//S/s/D/Zf -P/r/LNsYxO//6v/3f7P/+d/sh3+xl3v3y7t/+a/d3Tftb/7G/uuTF/GdBRwvJEb8AhHxUj2k/n0R -2VneHW8zP6mhg732uV15etJzxGed9L/35g9n0ZX/J/u2ePHma405vf7w17uf6Ue//+UvfvfzF3dW -YL5///av375/N31Vvvri7j8bFP+8dBrMsl9/cfc/W+x095/se98w+5//8asv//T6+4ff/vX7h/ar -/2z/+KP5ldcbayqWdbQey5r4aV69ybDGfZ3sqoya9AP7Va+hocnq1rz2Xm1WrxzniqGK1B/+owPN -h6C7378+F7d6Km7/A72WP37ua1luei3nElvuXvgPLgOEpT3CqdgrsbZo7QZrzDpvofrJrtZaPv8A -GP25KWxdraeeDO7qrHbdOjVrHOtqXGmkWu/8SIuOVNQk9v5i7b6HqatT+4lC7CnMVia6brLewR5U -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 -NzbTZy/+TD63x34PS/EO3A/WD/aPnhxsF5qGTv7De/tu4JlVnV7+A7/nJAf7ViGnt5uH/MeXY9ey -ZY1v8cY2vn7BPd37seWGzr5umPebZ1z4gfu+tnenxQYu/cndl3eNoXC7s+iq4f3J5s6uFPHm/k4y -Nq4aDce/9EQGne7N+V/yn7P+pTCn9uK9jRdzZxX/1uy8VozdK7cevtj8e/z0eO9o1/Uo6Uc2fe6+ -IP0OANn7m/rbKrma+W5eHG85jj3KPppWaT7fDv7xYHfH+CRu7RxsjWUCw7V/1nyBfwfPkrH/i7KJ -giDVy2yGoF3sG/cP8g56cXffd8Cy32bMrtdfLv4m117Hfe7tYp+rZm8+dLqddP4mmLiRd1o1WxO0 -mZJ45oOGyfInrdkKreXzsmt/Hmyt+sLY3NvbDF9z/hj4BdckTYIPq/K6SXHxm9W/kN5AjWtPv+8e -brmX8T2s+zqZ68f2MDzQiSZj90VMx1JQk0KH7Xsw+UweHWw93P9ysCilW6ugyzLa2j36sSmgGNTm -rAUoJj/8+uP76paMnw++fFnd8hyd9NmlyWUv41QntwowvPjxdOy6HT9Wn5YX1OF01X23AqP7buCf -Xdu4lelqmMq62j8PVw8Otw/C7qeYYPvHqiv6MaBfpUmp++Do23hSmZ0bbLm3fJRPHJbe1s5x+W25 -BNNk7uMfMvVxcDjjYtN0Wq1VkmRifA5I56rEdHW8L5P3OzNSfTne3654O3GapDVK39CMqul/Z3N/ -/+Co/JNy7+LHwY7dMpbOa6uiyCfZs2ZYpQjGPCW3kX4S2z/+le79vHPg2oCdxfVn95/f6o4WP6w8 -fPFssS3W0auda51Wq/fhYvXN+csefNndq2hJ3O3J9KSfncz6Quse5WN0Y7+qRtaXeLxMV6AL60pf -9edTlmP8+ceT7GAPXdG/bbqmMO15unZrsOdazb2K9kLaGD+M2NqcTGs3XUdpjZrxTfrfcm1qsv2m -tImY7KweuTFHgU14B5LoYPJ19VvFdfYmhe+7rH3fGU93v+5vzmjat137sfqPfMDSHprF4hL5LX2u -oL8c1SqT6dFe8tEcHu6kNbEYW1D1hbuOcuz7tJxMSrqBrV3p92q/0UlhlWK1E5X+ws74i+BMoWBq -dIx52ZS/Wffd720erlZdNP0C/q7+AtJKdHiQTu5YfUSGPlsHx/uFLrXkS/hWGObO+hSOqvobSRa0 -GUYa+UR24o3j/harOk33qvfHXze5Udx+HbXfWfEhql9Z8jradkMlKaeyujOr4mbA74BxewYw+nRh -S19Wgw8K8/fRYFD95gq1wCQylzB5L7WrevIC9yvr65f9I0csW9MK6JG2vC3joM2j2pU6qHf2RyFT -mq67KbSGdZr0+APOy9/s5P2L395PH8qCBUlzmARS1B5/VBelf+t+ki654N3jyfa3xZeT8e6WG9i5 -17e7v+uahxlP6S6S5zPsdcq+m6BdmFGVDyuo0L1eebmCrJWQIF/Kzl51Jxe/okllBQ4r+4Rr1Egc -gO3Myp40CoNOWX9/MJE5l81qos7Hp9N4VDazmS5Wd4mCr6zuxRFYNLI7vZAC6lT4wx15PXvVn6l/ -364N25/RKuzsHU6+HGTLFKVvRwb7u274OyPZVOYHq0Fsun24t/2v6jSOAQ6/HUz+bY3Db6VJCyNx -zBLdkWWVO8myyvPiskq4qUAm5GU3wS2T17PZJLWYU2/Ox/9qxZRPeCcyl2PfiprwKX+0wm0nc0Pq -vovzWnGKiomt4u1F+ZT0xu4/x3sb48mX8fYREprThbf29l6MBSvzba6YK8kjRsNoQrnROMpQ5rfS -ny2syb8X/0XmX269uPPw4TC6O5baI1e9fCP6Y3D55uuttdba5adXL9/8dtSVv3V6P/92rZv94Lfs -b/4HP3Vvvjy6fffL6P73B2efX9+8+6X17kb2087l68/735Yudh9cX7q6duH5wvLS5Rvff166+Ovv -o6Ur33bdj/74srp0+fjai6UrT9/eXbraetpprV1/t+Kzj5buXPytN+1Mn7qbu/u9d/PZHze6t4fd -Yf/3/o/ff776x/rB4E23tZP/tPXg8/jOwvJkcuP61q0rh78++uXxaHpj+ODnN6vrB7/3Xt+bfPi9 -dff39Xcv16/fur7dvnRrsN9aezZ+dfnGu4+d1qON53daD/6I1jp/LD141r5y4dvr0htZWK5xK5PJ -zaXj2388PX5660F/+9m18/u7l+5HR09/cffw+sUva0et9Wsfn909GP3x4uot97uPfrR2zr+7m2V6 -6N/L/b0bowfn/vTXdre8dS97B+d9yhuHF38+9L+d5Lz5/Hbytz8e3fS/tro2jf5yf3txiCS+xKbD -9f2XnZXRu3PuBtr7kvez/A1OPky/Dle7T4bHl2/cXzqfl4S77PB+981PZ7/420xuPr65J9PJ5Kfp -75OPP208a631Xqy4Z5G7zbN1v9v+0Hv77ckVM9OPX28/KM203/lzbcnKVN7+T9Otyae1y298tsj0 -19sXz7463HtiZTo9+6l/uyzTBzd+G+y/9pkuLONZexffXv5p+9lTM9Mz6596pZm21m8//sXKdGHZ -Zds/e25/cvG6XcC9d59a619+fWFnen/p5/PtR59fmpnef9B56TOVb4wF3Pn9xss/fKbBJxe/1TeT -D8c3nkimF/lOV9513++1L7pMewd5pi6X+K0+aaUFvHHhgso0in58PizL9PPk47f9lyWZ/rLZH6yf -a/v3Usw2zvTTzT+el2X64Fx35acPdqY/L32cnv02fq4ydbnE2f525+KNv879eGJlevmnvWs3SjLt -nz371/HvAzvT3rv3rfXHP2+4XKxnPbP+Y7Tc+/Xub1amrfWD3UelmZ5/+mx8X2UquSTZjlv3fzv7 -u13Av75pLX9fe/3CZTo41JXmwn05y8dn+u7qiso0+uv7i+dJO9a+9+H7evCsv99oPXk46kqml/Ck -D77/NejdvtmzMm09+fFlrDL1uSTZDp/e+7RVlumn1rO9Zy/sTB9f+P3xqiNiM9MXT7sDVyvLnvXJ -/d7jXkmm73utlw9fXCzJ9PjoxZP77wd5pgvLhWxft452SzN9Of517VtZpg9brz9duGFn+mR0YWH5 -9crSrzfNZ31z9fX50kzf3Fr56WxZprut369c/5Rn6p6lkO2vD8d/Lm1fWjEz/bh15mlppt+v7V14 -VJLph5vuS/706VbPftZnl88cXnJ10sz0j+7bldJMz7z7dGktz1R6sWIDsTSZrG98l0wvo9I86/xy -+czw522X6bW/dJt03N5/nWT6fXRJZbqw/NfnwY+Jz7Zz4cbKg7Cn2bh87eDonmR6hTX15drys92n -z12mv0z1k9779bCVZHp087J7L2FTuNw69zmuNJ2PR9ceha3Sb617916tS6arKtPJ8R/LSxfGK4N3 -LtP1Y5WptPxrV9/E2d5sP76qMj3z8tHL5z7T7s1XT54UM+0c7S917hxtS6YtPOnr7oc/3979+ZLL -9NHSwrIu4Mnk3uW0V934oX661Bk9/FL+0+72w6vWT5Ne7PKN6wd7pb/tmt7zk9Kftu79vHMl/ekL -dMtPfnnwPmth7r9GA//k+cvPFT/d+WO7/KdPl/a+5j9FibWe9s6tlv/2s+Pvf5b/9MXr0cj6aVJi -rRff7t0u/+2Xzw+elf50cnSlk3Zq99+h9r5+NfgrL7EPuqK1Xn+9c1z+0zfnNs5V/LT/YSX/KUvs -zYNvd8t/+/fo/eXyn378vvLM+mlaYp9Wem/Lf/vT10/j0p+67v3GjfKf9l5f3awosfb11S+vyn96 -e9Trlf/01xvdg4oSaz/769pPpb997fzhwefSny6dv3wnSn/6eYISWzr39Mb39Odbuu1b6rTu/ij9 -6eWfO0/uVvz0p+freYnFPz8sjg17VzwkPi8Zmj3drxyaPbj+0g3t7txee/RmYfnu2fGjF3dvXn7x -cnh16fyx+9v9DTdUvHBn/e2H9R3XG5y563/RXeLsBWNgfnZt9/rWRfcJnLnneoObz4N2c3Kmc+H6 -xtWkxKZnX7/bKDzrjbPdC34gGQ93rt15/y5vrNeeDvcvuNH522M/2HGF8eVnK1PXG1xrq34/yTZh -1NalpyWZusHO4PnFjyWZvvtgZbqwHD/rmfXDrvWsyXDn7O+vSjO98HBr9Wua6f29YqY/L130mWb9 -fu/FuWIBb0SdQqY758+fzTOdXhiczz/TbpBp9O3iys33eypTofGkgD8WnzXM9Mz65mpppn7sUJJp -/6yMHP7I+/3wWXvvPldkev9cvzxTGTmoTD2NJ5+SEMlmWabPyzMd/vr4dXmmwiNBC+OyPSc/v5L9 -7WoCW5eur9VK173TstLJswQpW39cunarxhU9qOWthUxu9eLfYMW9gNmeG6P7b+90LtxsPZSC6eqp -uBtX7l0p/HHn6qU72VDftUndc7/Jvz3Pa5Mr1MjVl8u3D6a/xnfh/nZXhv/3fM6qaXLZv9pw/3le -xrvHl9IMYoBOMijczcb5wzTJi1+SsVje7LUeRcvL+R83Dld2Xia87a+TV1yX2N3oL3/FSYL5Rn/D -t9e+je8uyx+Ok7PSuWRN1bkneH+3vXnuwoOsAIslf+PGveXkjytPD0pvScb78U2tTytv6mz7yqv2 -FfnjfXG+JrmvZ4Uiv7ly77Eq8qTEioXu/9h8ezcfk1vP1z330+Mns55P/pCX42dISt/ghTP5Gyx9 -f1I/3xSHYXw+P6e08aPGG6zx/lrjP8evre9zYbmssKouNv3+Zq6PPW5hrM/9oH3v4/R+ky8r/a5+ -Wl1YPp2S92hUWu4Ly/OV/Jc7q+/nbxmkfzEan3sfblwKm557uunJnr5G05OPxKW83w== - - - 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 -UGlBYVemqB6EruARBzwYzO3mA/8LKtOkrA== - - - From bcb95539251a619ad60dc830b88c905d7837dc6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Thu, 25 Jan 2018 13:42:08 +0100 Subject: [PATCH 137/138] Use Qt5DBus_FOUND instead of the old WITH_DBUS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WITH_DBUS was removed in 257d8142b1af06e1a3892be5110b7b69e38a0659 Signed-off-by: Julius Härtl --- shell_integration/libcloudproviders/CMakeLists.txt | 2 +- src/gui/CMakeLists.txt | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/shell_integration/libcloudproviders/CMakeLists.txt b/shell_integration/libcloudproviders/CMakeLists.txt index 8a6cab2fa..4c7af0042 100644 --- a/shell_integration/libcloudproviders/CMakeLists.txt +++ b/shell_integration/libcloudproviders/CMakeLists.txt @@ -41,7 +41,7 @@ macro(libcloudproviders_add_config _sources) endmacro(libcloudproviders_add_config _sources) -IF (UNIX AND WITH_DBUS AND LIBCLOUDPROVIDERS_FOUND) +IF (UNIX AND Qt5DBus_FOUND AND LIBCLOUDPROVIDERS_FOUND) STRING(TOLOWER "${APPLICATION_VENDOR}" DBUS_VENDOR) STRING(REGEX REPLACE "[^A-z0-9]" "" DBUS_VENDOR "${DBUS_VENDOR}") STRING(REGEX REPLACE "[^A-z0-9]" "" DBUS_APPLICATION_NAME "${APPLICATION_SHORTNAME}") diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index ff0e961d1..22b313b5d 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -173,8 +173,7 @@ else() list(APPEND 3rdparty_SRC ../3rdparty/qtlockedfile/qtlockedfile_win.cpp ) endif() - -IF( NOT WIN32 AND NOT APPLE AND WITH_DBUS AND LIBCLOUDPROVIDERS_FOUND) +IF( NOT WIN32 AND NOT APPLE AND LIBCLOUDPROVIDERS_FOUND) message("Building with libcloudproviderssupport") add_definitions(-DWITH_LIBCLOUDPROVIDERS) set(client_SRCS ${client_SRCS} cloudproviders/cloudprovidermanager.cpp) @@ -295,7 +294,7 @@ set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES ) # Only relevant for Linux? On OS X it by default properly checks in the bundle directory next to the exe set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES - INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE};${CMAKE_INSTALL_RPATH}" ) + INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE};${CMAKE_INSTALL_RPATH}" ) target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::Widgets Qt5::Network Qt5::Xml) target_link_libraries( ${APPLICATION_EXECUTABLE} ${synclib_NAME} ) From e2e99da4469a85e725495db381adc27b38981eda Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Thu, 25 Jan 2018 14:31:14 +0100 Subject: [PATCH 138/138] Bump appimage drone image Signed-off-by: Roeland Jago Douma --- .drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index 1da24e760..6e99b36d5 100644 --- a/.drone.yml +++ b/.drone.yml @@ -81,7 +81,7 @@ pipeline: TESTS: qt-5.9 AppImage-5.9: - image: nextcloudci/client-appimage-ci:client-appimage-ci-6 + image: nextcloudci/client-appimage-ci:client-appimage-ci-8 commands: - /bin/bash -c "./admin/linux/build-appimage.sh" when: