Comparar commits
154 Commits
folderwatcher
..
cmd
| Autor | SHA1 | Data | |
|---|---|---|---|
| e6eca69b3e | |||
| 68f99bcc27 | |||
| 7523db354d | |||
| 4919c9e7b1 | |||
| 045498c71a | |||
| 679ac0d26a | |||
| 2e3a3bcf84 | |||
| ad437a49f9 | |||
| 6b2282bf0d | |||
| 42aed56a5a | |||
| ca9ec46253 | |||
| a92eec160a | |||
| cc91c42dfa | |||
| d22d0e7e30 | |||
| 4998303c42 | |||
| ceef2f2d46 | |||
| 8b18600d7e | |||
| 6cc63462b3 | |||
| a1dc4069c9 | |||
| 86846af59d | |||
| 5bfa02602d | |||
| 9be23984eb | |||
| eb8de8e3c0 | |||
| ec7333a4bf | |||
| e485c5c008 | |||
| 6451eb3ade | |||
| 01528427b5 | |||
| cec4d7b9ff | |||
| efa7821dd2 | |||
| 89f55cf9df | |||
| 52552a4204 | |||
| 2f3db04e87 | |||
| 2d6e473a40 | |||
| 92027e8692 | |||
| 2723cd225e | |||
| acd151102c | |||
| 77e790d2ee | |||
| 899c675f0a | |||
| fb76487e76 | |||
| 0c0a3ca0a5 | |||
| 5377d1e283 | |||
| 676ad530e7 | |||
| fbcb01ed27 | |||
| c2b006e857 | |||
| 0e7ccea588 | |||
| c16deb3e44 | |||
| 019544fcfd | |||
| 5f0167b19e | |||
| 29d3c33eb2 | |||
| 469eca1f5f | |||
| 0864d67a9a | |||
| e9503664f5 | |||
| 58cee61624 | |||
| d23d07f99b | |||
| d70db810dd | |||
| 842129f99d | |||
| 36d61ef3a9 | |||
| f1f27221a7 | |||
| eb012d26ee | |||
| 9ee8187083 | |||
| b0c45cfc89 | |||
| 90cea69692 | |||
| 155bdfbffe | |||
| 0e2782d369 | |||
| 6b3d0e69aa | |||
| f30aee6d4e | |||
| 82f86eb019 | |||
| 9573c5e64d | |||
| 15f2b911d9 | |||
| f5aff70398 | |||
| e3a4c3989a | |||
| 3e954bc17f | |||
| 2527569bb8 | |||
| 1e197531cb | |||
| 8b876576eb | |||
| a2287c9657 | |||
| 34c59ba9ed | |||
| c8014a0afd | |||
| 456d82715e | |||
| 8ca3eb7883 | |||
| c110745330 | |||
| 19521863a0 | |||
| c256896165 | |||
| ef922f60fa | |||
| 733ea90e6b | |||
| a4e1fa9dcf | |||
| 1a1684ca2a | |||
| 9c8572e335 | |||
| e675a34fbb | |||
| 5f47c01346 | |||
| 10644d3568 | |||
| 9ee3144358 | |||
| cf48ea2e00 | |||
| db24f60ae3 | |||
| 6026148692 | |||
| a2222228c9 | |||
| 9e2d3f5bc7 | |||
| fe984b61d7 | |||
| ffac3f6213 | |||
| 4f1feab845 | |||
| f738cfd7fe | |||
| e6be670e49 | |||
| 46ce2f4722 | |||
| 166a0f60ca | |||
| a9019ccbad | |||
| 0a4806af44 | |||
| e33b89c222 | |||
| 6b899be895 | |||
| 641785298f | |||
| 092c935422 | |||
| 273590fdfc | |||
| 0960058842 | |||
| 1f78ea0fd1 | |||
| 72d8175032 | |||
| 2fd9767892 | |||
| 69a1e46d0c | |||
| e020a5327e | |||
| 1b04489887 | |||
| 36a19703db | |||
| f3a345a23b | |||
| 826459eae7 | |||
| c2c36b85cb | |||
| 7b2f8ae6f7 | |||
| d600fdc89b | |||
| 8c5ea8dc90 | |||
| 0eddcd6384 | |||
| 9f2ae5dd17 | |||
| 766d9ae1ac | |||
| 21128ed762 | |||
| 5000d40619 | |||
| 0d321050a6 | |||
| 089ecf8222 | |||
| d54f8adac5 | |||
| d35ecafa0b | |||
| 2ca807280a | |||
| e1a01c75d9 | |||
| 6a4adbc87e | |||
| 89974ab1d4 | |||
| 8d0c313486 | |||
| aab0cdf12a | |||
| a89520043e | |||
| 02c403e360 | |||
| da26e59770 | |||
| 3c24d5a148 | |||
| c222793525 | |||
| 28018e8590 | |||
| 4c79ce2ae6 | |||
| 7c75a39bc1 | |||
| c41f6ed76b | |||
| 818b5854ce | |||
| 79abb8b4e3 | |||
| fad387b6b8 | |||
| a1558100b8 | |||
| 4f3f642da6 |
+1
-1
@@ -27,7 +27,7 @@ https://github.com/owncloud/client.
|
|||||||
|
|
||||||
## Building the source code
|
## Building the source code
|
||||||
|
|
||||||
[Building the Client](http://doc.owncloud.org/desktop/2.0/building.html)
|
[Building the Client](http://doc.owncloud.org/desktop/2.2/building.html)
|
||||||
in the ownCloud Desktop Client manual.
|
in the ownCloud Desktop Client manual.
|
||||||
|
|
||||||
## Maintainers and Contributors
|
## Maintainers and Contributors
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
#
|
#
|
||||||
# ownCloud is free software: you can redistribute it and/or modify
|
# ownCloud is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation; version 2 of the License.
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# ownCLoud is distributed in the hope that it will be useful,
|
# ownCLoud is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ StrCpy $PageReinstall_NEW_Field_3 "No instal·lar"
|
|||||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Ja instal·lat"
|
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Ja instal·lat"
|
||||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Trieu la manera com voleu instal·lar ${APPLICATION_NAME}."
|
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Trieu la manera com voleu instal·lar ${APPLICATION_NAME}."
|
||||||
StrCpy $PageReinstall_OLD_Field_1 "Una versió més recent de ${APPLICATION_NAME} ja està instal.lada!! No es recomana instal.lar una versió més antiga. Si realment voleu instal.lar una versió més antiga, és millor primer desinstal.lar la versió actual. Seleccioni l'operació que desitjeu realitzar i feu clic a Següent per a continuar."
|
StrCpy $PageReinstall_OLD_Field_1 "Una versió més recent de ${APPLICATION_NAME} ja està instal.lada!! No es recomana instal.lar una versió més antiga. Si realment voleu instal.lar una versió més antiga, és millor primer desinstal.lar la versió actual. Seleccioni l'operació que desitjeu realitzar i feu clic a Següent per a continuar."
|
||||||
|
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} ja està instal·lat.$\n$\nSeleccioneu la operació que voleu fer i feu clic a Següent per continuar."
|
||||||
StrCpy $PageReinstall_SAME_Field_2 "Afegir/Reinstal.lar components"
|
StrCpy $PageReinstall_SAME_Field_2 "Afegir/Reinstal.lar components"
|
||||||
StrCpy $PageReinstall_SAME_Field_3 "Desinstal.lar ${APPLICATION_NAME}"
|
StrCpy $PageReinstall_SAME_Field_3 "Desinstal.lar ${APPLICATION_NAME}"
|
||||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Desinstal.lar ${APPLICATION_NAME}"
|
StrCpy $UNINSTALLER_APPDATA_TITLE "Desinstal.lar ${APPLICATION_NAME}"
|
||||||
@@ -37,7 +38,6 @@ StrCpy $UAC_ERROR_ELEVATE "No es pot elevar, error:"
|
|||||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Aquest instal·lador requereix accés d'administrador, intenteu-ho de nou"
|
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Aquest instal·lador requereix accés d'administrador, intenteu-ho de nou"
|
||||||
StrCpy $INIT_INSTALLER_RUNNING "L'instal·lador ja s'està executant."
|
StrCpy $INIT_INSTALLER_RUNNING "L'instal·lador ja s'està executant."
|
||||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Aquest desinstal·lador requereix accés d'administrador, intenteu-ho de nou."
|
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Aquest desinstal·lador requereix accés d'administrador, intenteu-ho de nou."
|
||||||
|
StrCpy $UAC_ERROR_LOGON_SERVICE "El servei de inici de sessió no s'està executant, s'està abortant!"
|
||||||
StrCpy $INIT_UNINSTALLER_RUNNING "El desinstal·lador ja s'està executant."
|
StrCpy $INIT_UNINSTALLER_RUNNING "El desinstal·lador ja s'està executant."
|
||||||
StrCpy $SectionGroup_Shortcuts "Dreceres"
|
StrCpy $SectionGroup_Shortcuts "Dreceres"
|
||||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
|
|
||||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar las notas de la versión"
|
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar las notas de la versión"
|
||||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "El/los proceso/s ${APPLICATION_EXECUTABLE} debe/n ser detenidos.$\n¿Quiere que el instalador lo haga por usted?"
|
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "El/los proceso/s ${APPLICATION_EXECUTABLE} debe/n ser detenidos.$\n¿Quiere que el instalador lo haga por usted?"
|
||||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Deteniendo el/los proceso/s ${APPLICATION_EXECUTABLE}."
|
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Deteniendo el/los proceso/s ${APPLICATION_EXECUTABLE}."
|
||||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "¡Proceso para finalizar no encontrado!"
|
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "¡Proceso a finalizar no encontrado!"
|
||||||
StrCpy $PageReinstall_NEW_Field_1 "Una versión anterior de ${APPLICATION_NAME} se encuentra instalada en el sistema. Se recomienda de instalar la versión actual antes de instalar la nueva. Seleccione la operacion deseada y haga click en Siguiente para continuar."
|
StrCpy $PageReinstall_NEW_Field_1 "Una versión anterior de ${APPLICATION_NAME} se encuentra instalada en el sistema. Se recomienda de instalar la versión actual antes de instalar la nueva. Seleccione la operacion deseada y haga click en Siguiente para continuar."
|
||||||
StrCpy $PageReinstall_NEW_Field_2 "Desinstalar antes de instalar"
|
StrCpy $PageReinstall_NEW_Field_2 "Desinstalar antes de instalar"
|
||||||
StrCpy $PageReinstall_NEW_Field_3 "No desinstalar"
|
StrCpy $PageReinstall_NEW_Field_3 "No desinstalar"
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ find_library(CMOCKA_LIBRARY
|
|||||||
NAMES
|
NAMES
|
||||||
cmocka
|
cmocka
|
||||||
PATHS
|
PATHS
|
||||||
${CMOCKA_ROOT_DIR}/include
|
${CMOCKA_ROOT_DIR}/lib
|
||||||
)
|
)
|
||||||
|
|
||||||
if (CMOCKA_LIBRARY)
|
if (CMOCKA_LIBRARY)
|
||||||
|
|||||||
+2
-9
@@ -89,7 +89,7 @@ static int _data_cmp(const void *key, const void *data) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void csync_create(CSYNC **csync, const char *local, const char *remote) {
|
void csync_create(CSYNC **csync, const char *local) {
|
||||||
CSYNC *ctx;
|
CSYNC *ctx;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
@@ -103,12 +103,6 @@ void csync_create(CSYNC **csync, const char *local, const char *remote) {
|
|||||||
|
|
||||||
ctx->local.uri = c_strndup(local, len);
|
ctx->local.uri = c_strndup(local, len);
|
||||||
|
|
||||||
/* remove trailing slashes */
|
|
||||||
len = strlen(remote);
|
|
||||||
while(len > 0 && remote[len - 1] == '/') --len;
|
|
||||||
|
|
||||||
ctx->remote.uri = c_strndup(remote, len);
|
|
||||||
|
|
||||||
ctx->status_code = CSYNC_STATUS_OK;
|
ctx->status_code = CSYNC_STATUS_OK;
|
||||||
|
|
||||||
ctx->current_fs = NULL;
|
ctx->current_fs = NULL;
|
||||||
@@ -199,7 +193,7 @@ int csync_update(CSYNC *ctx) {
|
|||||||
ctx->current = REMOTE_REPLICA;
|
ctx->current = REMOTE_REPLICA;
|
||||||
ctx->replica = ctx->remote.type;
|
ctx->replica = ctx->remote.type;
|
||||||
|
|
||||||
rc = csync_ftw(ctx, ctx->remote.uri, csync_walker, MAX_DEPTH);
|
rc = csync_ftw(ctx, "", csync_walker, MAX_DEPTH);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
if(ctx->status_code == CSYNC_STATUS_OK) {
|
if(ctx->status_code == CSYNC_STATUS_OK) {
|
||||||
ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_UPDATE_ERROR);
|
ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_UPDATE_ERROR);
|
||||||
@@ -579,7 +573,6 @@ int csync_destroy(CSYNC *ctx) {
|
|||||||
_csync_clean_ctx(ctx);
|
_csync_clean_ctx(ctx);
|
||||||
|
|
||||||
SAFE_FREE(ctx->local.uri);
|
SAFE_FREE(ctx->local.uri);
|
||||||
SAFE_FREE(ctx->remote.uri);
|
|
||||||
SAFE_FREE(ctx->error_string);
|
SAFE_FREE(ctx->error_string);
|
||||||
|
|
||||||
#ifdef WITH_ICONV
|
#ifdef WITH_ICONV
|
||||||
|
|||||||
+1
-1
@@ -317,7 +317,7 @@ typedef const char* (*csync_checksum_hook) (
|
|||||||
*
|
*
|
||||||
* @param csync The context variable to allocate.
|
* @param csync The context variable to allocate.
|
||||||
*/
|
*/
|
||||||
void OCSYNC_EXPORT csync_create(CSYNC **csync, const char *local, const char *remote);
|
void OCSYNC_EXPORT csync_create(CSYNC **csync, const char *local);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the file synchronizer.
|
* @brief Initialize the file synchronizer.
|
||||||
|
|||||||
@@ -126,7 +126,6 @@ struct csync_s {
|
|||||||
} local;
|
} local;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
char *uri;
|
|
||||||
c_rbtree_t *tree;
|
c_rbtree_t *tree;
|
||||||
enum csync_replica_e type;
|
enum csync_replica_e type;
|
||||||
int read_from_db;
|
int read_from_db;
|
||||||
|
|||||||
@@ -65,7 +65,21 @@ static c_rbnode_t *_csync_check_ignored(c_rbtree_t *tree, const char *path, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
* The main function in the reconcile pass.
|
||||||
|
*
|
||||||
|
* It's called for each entry in the local and remote rbtrees by
|
||||||
|
* csync_reconcile()
|
||||||
|
*
|
||||||
|
* Before the reconcile phase the trees already know about changes
|
||||||
|
* relative to the sync journal. This function's job is to spot conflicts
|
||||||
|
* between local and remote changes and adjust the nodes accordingly.
|
||||||
|
*
|
||||||
|
* See doc/dev/sync-algorithm.md for an overview.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Older detail comment:
|
||||||
|
*
|
||||||
* We merge replicas at the file level. The merged replica contains the
|
* We merge replicas at the file level. The merged replica contains the
|
||||||
* superset of files that are on the local machine and server copies of
|
* superset of files that are on the local machine and server copies of
|
||||||
* the replica. In the case where the same file is in both the local
|
* the replica. In the case where the same file is in both the local
|
||||||
|
|||||||
+34
-74
@@ -56,26 +56,13 @@ static uint64_t _hash_of_file(CSYNC *ctx, const char *file) {
|
|||||||
|
|
||||||
if( ctx && file ) {
|
if( ctx && file ) {
|
||||||
path = file;
|
path = file;
|
||||||
switch (ctx->current) {
|
if (ctx->current == LOCAL_REPLICA) {
|
||||||
case LOCAL_REPLICA:
|
|
||||||
if (strlen(path) <= strlen(ctx->local.uri)) {
|
if (strlen(path) <= strlen(ctx->local.uri)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
path += strlen(ctx->local.uri) + 1;
|
path += strlen(ctx->local.uri) + 1;
|
||||||
break;
|
|
||||||
case REMOTE_REPLICA:
|
|
||||||
if (strlen(path) <= strlen(ctx->remote.uri)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
path += strlen(ctx->remote.uri) + 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
path = NULL;
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
len = strlen(path);
|
len = strlen(path);
|
||||||
|
|
||||||
h = c_jhash64((uint8_t *) path, len, 0);
|
h = c_jhash64((uint8_t *) path, len, 0);
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
@@ -158,7 +145,19 @@ static bool _csync_mtime_equal(time_t a, time_t b)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main function of the discovery/update pass.
|
||||||
|
*
|
||||||
|
* It's called (indirectly) by csync_update(), once for each entity in the
|
||||||
|
* local filesystem and once for each entity in the server data.
|
||||||
|
*
|
||||||
|
* It has two main jobs:
|
||||||
|
* - figure out whether anything happened compared to the sync journal
|
||||||
|
* and set (primarily) the instruction flag accordingly
|
||||||
|
* - build the ctx->local.tree / ctx->remote.tree
|
||||||
|
*
|
||||||
|
* See doc/dev/sync-algorithm.md for an overview.
|
||||||
|
*/
|
||||||
static int _csync_detect_update(CSYNC *ctx, const char *file,
|
static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||||
const csync_vio_file_stat_t *fs, const int type) {
|
const csync_vio_file_stat_t *fs, const int type) {
|
||||||
uint64_t h = 0;
|
uint64_t h = 0;
|
||||||
@@ -176,25 +175,12 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
path = file;
|
path = file;
|
||||||
switch (ctx->current) {
|
if (ctx->current == LOCAL_REPLICA) {
|
||||||
case LOCAL_REPLICA:
|
|
||||||
if (strlen(path) <= strlen(ctx->local.uri)) {
|
if (strlen(path) <= strlen(ctx->local.uri)) {
|
||||||
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
|
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
path += strlen(ctx->local.uri) + 1;
|
path += strlen(ctx->local.uri) + 1;
|
||||||
break;
|
|
||||||
case REMOTE_REPLICA:
|
|
||||||
if (strlen(path) <= strlen(ctx->remote.uri)) {
|
|
||||||
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
path += strlen(ctx->remote.uri) + 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
path = NULL;
|
|
||||||
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(path);
|
len = strlen(path);
|
||||||
@@ -617,16 +603,7 @@ int csync_walker(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs,
|
|||||||
|
|
||||||
static bool fill_tree_from_db(CSYNC *ctx, const char *uri)
|
static bool fill_tree_from_db(CSYNC *ctx, const char *uri)
|
||||||
{
|
{
|
||||||
const char *path = NULL;
|
if( csync_statedb_get_below_path(ctx, uri) < 0 ) {
|
||||||
|
|
||||||
if( strlen(uri) < strlen(ctx->remote.uri)+1) {
|
|
||||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "name does not contain remote uri!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = uri + strlen(ctx->remote.uri)+1;
|
|
||||||
|
|
||||||
if( csync_statedb_get_below_path(ctx, path) < 0 ) {
|
|
||||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "StateDB could not be read!");
|
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "StateDB could not be read!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -668,12 +645,6 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
|||||||
|
|
||||||
bool do_read_from_db = (ctx->current == REMOTE_REPLICA && ctx->remote.read_from_db);
|
bool do_read_from_db = (ctx->current == REMOTE_REPLICA && ctx->remote.read_from_db);
|
||||||
|
|
||||||
if (uri[0] == '\0') {
|
|
||||||
errno = ENOENT;
|
|
||||||
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
read_from_db = ctx->remote.read_from_db;
|
read_from_db = ctx->remote.read_from_db;
|
||||||
|
|
||||||
// if the etag of this dir is still the same, its content is restored from the
|
// if the etag of this dir is still the same, its content is restored from the
|
||||||
@@ -687,16 +658,7 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *uri_for_vio = uri;
|
if ((dh = csync_vio_opendir(ctx, uri)) == NULL) {
|
||||||
if (ctx->current == REMOTE_REPLICA) {
|
|
||||||
uri_for_vio += strlen(ctx->remote.uri);
|
|
||||||
if (strlen(uri_for_vio) > 0 && uri_for_vio[0] == '/') {
|
|
||||||
uri_for_vio++; // cut leading slash
|
|
||||||
}
|
|
||||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "URI without fuzz for %s is \"%s\"", uri, uri_for_vio);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((dh = csync_vio_opendir(ctx, uri_for_vio)) == NULL) {
|
|
||||||
if (ctx->abort) {
|
if (ctx->abort) {
|
||||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Aborted!");
|
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Aborted!");
|
||||||
ctx->status_code = CSYNC_STATUS_ABORTED;
|
ctx->status_code = CSYNC_STATUS_ABORTED;
|
||||||
@@ -769,34 +731,32 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
flen = asprintf(&filename, "%s/%s", uri, d_name);
|
if (uri[0] == '\0') {
|
||||||
if (flen < 0) {
|
filename = c_strdup(d_name);
|
||||||
|
flen = strlen(d_name);
|
||||||
|
} else {
|
||||||
|
flen = asprintf(&filename, "%s/%s", uri, d_name);
|
||||||
|
}
|
||||||
|
if (flen < 0 || !filename) {
|
||||||
csync_vio_file_stat_destroy(dirent);
|
csync_vio_file_stat_destroy(dirent);
|
||||||
dirent = NULL;
|
dirent = NULL;
|
||||||
ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
|
ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create relative path */
|
/* Create relative path: For local replica, we need to remove the base path. */
|
||||||
switch (ctx->current) {
|
path = filename;
|
||||||
case LOCAL_REPLICA:
|
if (ctx->current == LOCAL_REPLICA) {
|
||||||
ulen = strlen(ctx->local.uri) + 1;
|
ulen = strlen(ctx->local.uri) + 1;
|
||||||
break;
|
if (((size_t)flen) < ulen) {
|
||||||
case REMOTE_REPLICA:
|
csync_vio_file_stat_destroy(dirent);
|
||||||
ulen = strlen(ctx->remote.uri) + 1;
|
dirent = NULL;
|
||||||
break;
|
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||||
default:
|
goto error;
|
||||||
break;
|
}
|
||||||
|
path += ulen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((size_t)flen) < ulen) {
|
|
||||||
csync_vio_file_stat_destroy(dirent);
|
|
||||||
dirent = NULL;
|
|
||||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = filename + ulen;
|
|
||||||
|
|
||||||
/* skip ".csync_journal.db" and ".csync_journal.db.ctmp" */
|
/* skip ".csync_journal.db" and ".csync_journal.db.ctmp" */
|
||||||
/* Isn't this done via csync_exclude already? */
|
/* Isn't this done via csync_exclude already? */
|
||||||
|
|||||||
@@ -30,10 +30,7 @@ static void setup(void **state) {
|
|||||||
rc = system("mkdir -p /tmp/check_csync1");
|
rc = system("mkdir -p /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
|
|
||||||
rc = system("mkdir -p /tmp/check_csync2");
|
csync_create(&csync, "/tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
|
|
||||||
csync_create(&csync, "/tmp/check_csync1", "/tmp/check_csync2");
|
|
||||||
|
|
||||||
*state = csync;
|
*state = csync;
|
||||||
}
|
}
|
||||||
@@ -45,10 +42,7 @@ static void setup_module(void **state) {
|
|||||||
rc = system("mkdir -p /tmp/check_csync1");
|
rc = system("mkdir -p /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
|
|
||||||
rc = system("mkdir -p /tmp/check_csync2");
|
csync_create(&csync, "/tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
|
|
||||||
csync_create(&csync, "/tmp/check_csync1", "dummy://foo/bar");
|
|
||||||
|
|
||||||
csync_init(csync);
|
csync_init(csync);
|
||||||
*state = csync;
|
*state = csync;
|
||||||
@@ -66,9 +60,6 @@ static void teardown(void **state) {
|
|||||||
rc = system("rm -rf /tmp/check_csync1");
|
rc = system("rm -rf /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
|
|
||||||
rc = system("rm -rf /tmp/check_csync2");
|
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
|
|
||||||
*state = NULL;
|
*state = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ static void check_csync_create(void **state)
|
|||||||
|
|
||||||
(void) state; /* unused */
|
(void) state; /* unused */
|
||||||
|
|
||||||
csync_create(&csync, "/tmp/csync1", "/tmp/csync2");
|
csync_create(&csync, "/tmp/csync1");
|
||||||
|
|
||||||
rc = csync_destroy(csync);
|
rc = csync_destroy(csync);
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
static void setup(void **state) {
|
static void setup(void **state) {
|
||||||
CSYNC *csync;
|
CSYNC *csync;
|
||||||
|
|
||||||
csync_create(&csync, "/tmp/check_csync1", "/tmp/check_csync2");
|
csync_create(&csync, "/tmp/check_csync1");
|
||||||
|
|
||||||
*state = csync;
|
*state = csync;
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ static void setup_init(void **state) {
|
|||||||
CSYNC *csync;
|
CSYNC *csync;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
csync_create(&csync, "/tmp/check_csync1", "/tmp/check_csync2");
|
csync_create(&csync, "/tmp/check_csync1");
|
||||||
|
|
||||||
rc = csync_exclude_load(EXCLUDE_LIST_FILE, &(csync->excludes));
|
rc = csync_exclude_load(EXCLUDE_LIST_FILE, &(csync->excludes));
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
|
|||||||
@@ -30,10 +30,7 @@ static void setup(void **state) {
|
|||||||
rc = system("mkdir -p /tmp/check_csync1");
|
rc = system("mkdir -p /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
|
|
||||||
rc = system("mkdir -p /tmp/check_csync2");
|
csync_create(&csync, "/tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
|
|
||||||
csync_create(&csync, "/tmp/check_csync1", "/tmp/check_csync2");
|
|
||||||
|
|
||||||
*state = csync;
|
*state = csync;
|
||||||
}
|
}
|
||||||
@@ -45,10 +42,7 @@ static void setup_module(void **state) {
|
|||||||
rc = system("mkdir -p /tmp/check_csync1");
|
rc = system("mkdir -p /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
|
|
||||||
rc = system("mkdir -p /tmp/check_csync2");
|
csync_create(&csync, "/tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
|
|
||||||
csync_create(&csync, "/tmp/check_csync1", "dummy://foo/bar");
|
|
||||||
|
|
||||||
*state = csync;
|
*state = csync;
|
||||||
}
|
}
|
||||||
@@ -65,9 +59,6 @@ static void teardown(void **state) {
|
|||||||
rc = system("rm -rf /tmp/check_csync1");
|
rc = system("rm -rf /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
|
|
||||||
rc = system("rm -rf /tmp/check_csync2");
|
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
|
|
||||||
*state = NULL;
|
*state = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,7 @@ static void setup(void **state) {
|
|||||||
rc = system("mkdir -p /tmp/check_csync1");
|
rc = system("mkdir -p /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
|
|
||||||
rc = system("mkdir -p /tmp/check_csync2");
|
csync_create(&csync, "/tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
|
|
||||||
csync_create(&csync, "/tmp/check_csync1", "/tmp/check_csync2");
|
|
||||||
|
|
||||||
*state = csync;
|
*state = csync;
|
||||||
}
|
}
|
||||||
@@ -53,9 +50,6 @@ static void teardown(void **state) {
|
|||||||
rc = system("rm -rf /tmp/check_csync1");
|
rc = system("rm -rf /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
|
|
||||||
rc = system("rm -rf /tmp/check_csync2");
|
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
|
|
||||||
*state = NULL;
|
*state = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ static void setup(void **state) {
|
|||||||
rc = system("mkdir -p /tmp/check_csync1");
|
rc = system("mkdir -p /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
|
|
||||||
csync_create(&csync, "/tmp/check_csync1", "/tmp/check_csync2");
|
csync_create(&csync, "/tmp/check_csync1");
|
||||||
|
|
||||||
csync->statedb.file = c_strdup( TESTDB );
|
csync->statedb.file = c_strdup( TESTDB );
|
||||||
*state = csync;
|
*state = csync;
|
||||||
|
|||||||
@@ -34,15 +34,11 @@ static void setup(void **state)
|
|||||||
|
|
||||||
rc = system("rm -rf /tmp/check_csync1");
|
rc = system("rm -rf /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
rc = system("rm -rf /tmp/check_csync2");
|
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
rc = system("mkdir -p /tmp/check_csync1");
|
rc = system("mkdir -p /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
rc = system("mkdir -p /tmp/check_csync2");
|
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
rc = system("mkdir -p /tmp/check_csync");
|
rc = system("mkdir -p /tmp/check_csync");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
csync_create(&csync, "/tmp/check_csync1", "/tmp/check_csync2");
|
csync_create(&csync, "/tmp/check_csync1");
|
||||||
csync_init(csync);
|
csync_init(csync);
|
||||||
|
|
||||||
sqlite3 *db = NULL;
|
sqlite3 *db = NULL;
|
||||||
@@ -106,8 +102,6 @@ static void teardown(void **state) {
|
|||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
rc = system("rm -rf /tmp/check_csync1");
|
rc = system("rm -rf /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
rc = system("rm -rf /tmp/check_csync2");
|
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
|
|
||||||
*state = NULL;
|
*state = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,9 +91,7 @@ static void setup(void **state)
|
|||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
rc = system("mkdir -p /tmp/check_csync1");
|
rc = system("mkdir -p /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
rc = system("mkdir -p /tmp/check_csync2");
|
csync_create(&csync, "/tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
csync_create(&csync, "/tmp/check_csync1", "/tmp/check_csync2");
|
|
||||||
csync_init(csync);
|
csync_init(csync);
|
||||||
|
|
||||||
/* Create a new db with metadata */
|
/* Create a new db with metadata */
|
||||||
@@ -122,9 +120,7 @@ static void setup_ftw(void **state)
|
|||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
rc = system("mkdir -p /tmp/check_csync1");
|
rc = system("mkdir -p /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
rc = system("mkdir -p /tmp/check_csync2");
|
csync_create(&csync, "/tmp");
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
csync_create(&csync, "/tmp", "/tmp");
|
|
||||||
csync_init(csync);
|
csync_init(csync);
|
||||||
|
|
||||||
sqlite3 *db = NULL;
|
sqlite3 *db = NULL;
|
||||||
@@ -162,8 +158,6 @@ static void teardown_rm(void **state) {
|
|||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
rc = system("rm -rf /tmp/check_csync1");
|
rc = system("rm -rf /tmp/check_csync1");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
rc = system("rm -rf /tmp/check_csync2");
|
|
||||||
assert_int_equal(rc, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create a file stat, caller must free memory */
|
/* create a file stat, caller must free memory */
|
||||||
|
|||||||
@@ -232,6 +232,37 @@ assertLocalAndRemoteDir( '', 0);
|
|||||||
system("sqlite3 " . localDir().'.csync_journal.db .dump');
|
system("sqlite3 " . localDir().'.csync_journal.db .dump');
|
||||||
|
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
printInfo( "multiple restores of a file create different conflict files" );
|
||||||
|
|
||||||
|
system("sleep 1"); #make sure changes have different mtime
|
||||||
|
|
||||||
|
system("echo 'modified_1' > ". localDir() . "readonlyDirectory_PERM_M_/canotBeModified_PERM_DVN_.data");
|
||||||
|
|
||||||
|
#do the sync
|
||||||
|
csync();
|
||||||
|
assertCsyncJournalOk(localDir());
|
||||||
|
|
||||||
|
system("sleep 1"); #make sure changes have different mtime
|
||||||
|
|
||||||
|
system("echo 'modified_2' > ". localDir() . "readonlyDirectory_PERM_M_/canotBeModified_PERM_DVN_.data");
|
||||||
|
|
||||||
|
#do the sync
|
||||||
|
csync();
|
||||||
|
assertCsyncJournalOk(localDir());
|
||||||
|
|
||||||
|
# there should be two conflict files
|
||||||
|
# TODO check that the conflict file has the right content
|
||||||
|
my @conflicts = glob(localDir().'readonlyDirectory_PERM_M_/canotBeModified_PERM_DVN__conflict-*.data' );
|
||||||
|
assert( scalar @conflicts == 2 );
|
||||||
|
# remove the conflicts for the next assertLocalAndRemoteDir
|
||||||
|
system("rm " . localDir().'readonlyDirectory_PERM_M_/canotBeModified_PERM_DVN__conflict-*.data' );
|
||||||
|
|
||||||
|
### Both side should still be the same
|
||||||
|
assertLocalAndRemoteDir( '', 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ static void setup(void **state)
|
|||||||
rc = system("rm -rf /tmp/csync_test");
|
rc = system("rm -rf /tmp/csync_test");
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
|
|
||||||
csync_create(&csync, "/tmp/csync1", "/tmp/csync2");
|
csync_create(&csync, "/tmp/csync1");
|
||||||
|
|
||||||
csync->replica = LOCAL_REPLICA;
|
csync->replica = LOCAL_REPLICA;
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ static void setup_testenv(void **state) {
|
|||||||
statevar *mystate = malloc( sizeof(statevar) );
|
statevar *mystate = malloc( sizeof(statevar) );
|
||||||
mystate->result = NULL;
|
mystate->result = NULL;
|
||||||
|
|
||||||
csync_create(&(mystate->csync), "/tmp/csync1", "/tmp/csync2");
|
csync_create(&(mystate->csync), "/tmp/csync1");
|
||||||
|
|
||||||
mystate->csync->replica = LOCAL_REPLICA;
|
mystate->csync->replica = LOCAL_REPLICA;
|
||||||
|
|
||||||
|
|||||||
+31
-4
@@ -42,7 +42,8 @@ repositories`_ to see all the Linux client repos.
|
|||||||
echo 'deb-src
|
echo 'deb-src
|
||||||
http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/Debian_8.0/ /' >> /etc/apt/sources.list.d/owncloud-client.list
|
http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/Debian_8.0/ /' >> /etc/apt/sources.list.d/owncloud-client.list
|
||||||
|
|
||||||
2. Install the dependencies using the following commands for your specific Linux distribution:
|
2. Install the dependencies using the following commands for your specific Linux
|
||||||
|
distribution. Make sure the repositories for source packages are enabled.
|
||||||
|
|
||||||
* Debian/Ubuntu: ``apt-get update; apt-get build-dep owncloud-client``
|
* Debian/Ubuntu: ``apt-get update; apt-get build-dep owncloud-client``
|
||||||
* openSUSE/SLES: ``zypper ref; zypper si -d owncloud-client``
|
* openSUSE/SLES: ``zypper ref; zypper si -d owncloud-client``
|
||||||
@@ -65,11 +66,26 @@ recipes.
|
|||||||
|
|
||||||
To set up your build environment for development using HomeBrew_:
|
To set up your build environment for development using HomeBrew_:
|
||||||
|
|
||||||
1. Add the ownCloud repository using the following command::
|
1. Install Xcode
|
||||||
|
2. Install Xcode command line tools::
|
||||||
|
<<<<<<< HEAD
|
||||||
|
xcode-select --install
|
||||||
|
|
||||||
|
3. Install homebrew::
|
||||||
|
=======
|
||||||
|
|
||||||
|
xcode-select --install
|
||||||
|
|
||||||
|
3. Install homebrew::
|
||||||
|
|
||||||
|
>>>>>>> ca9ec4625391ae23940b3a62aaa0afe89f3d98e8
|
||||||
|
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||||
|
|
||||||
|
4. Add the ownCloud repository using the following command::
|
||||||
|
|
||||||
brew tap owncloud/owncloud
|
brew tap owncloud/owncloud
|
||||||
|
|
||||||
2. Install any missing dependencies::
|
5. Install any missing dependencies::
|
||||||
|
|
||||||
brew install $(brew deps owncloud-client)
|
brew install $(brew deps owncloud-client)
|
||||||
|
|
||||||
@@ -79,6 +95,9 @@ To set up your build environment for development using HomeBrew_:
|
|||||||
|
|
||||||
Where ``x.z`` is the current version of Qt 5 that brew has installed
|
Where ``x.z`` is the current version of Qt 5 that brew has installed
|
||||||
on your machine.
|
on your machine.
|
||||||
|
4. Install qtkeychain from here: git clone https://github.com/frankosterfeld/qtkeychain.git
|
||||||
|
make sure you make the same install prefix as later while building the client e.g. -
|
||||||
|
``DCMAKE_INSTALL_PREFIX=/Path/to/client-install``
|
||||||
|
|
||||||
5. For compilation of the client, follow the :ref:`generic-build-instructions`.
|
5. For compilation of the client, follow the :ref:`generic-build-instructions`.
|
||||||
|
|
||||||
@@ -89,7 +108,7 @@ To set up your build environment for development using HomeBrew_:
|
|||||||
its Common Name as a third parameter (use quotes) to have the package
|
its Common Name as a third parameter (use quotes) to have the package
|
||||||
signed automatically.
|
signed automatically.
|
||||||
|
|
||||||
.. note:: Contrary to earlier versions, ownCloud 1.7 and later are packaged
|
.. note:: Contrary to earlier versions, ownCloud 1.7 and later are packaged
|
||||||
as a ``pkg`` installer. Do not call "make package" at any time when
|
as a ``pkg`` installer. Do not call "make package" at any time when
|
||||||
compiling for OS X, as this will build a disk image, and will not
|
compiling for OS X, as this will build a disk image, and will not
|
||||||
work correctly.
|
work correctly.
|
||||||
@@ -233,6 +252,14 @@ To build the most up-to-date version of the client:
|
|||||||
.. note:: On Mac OS X, you need to specify ``-DCMAKE_INSTALL_PREFIX=target``,
|
.. note:: On Mac OS X, you need to specify ``-DCMAKE_INSTALL_PREFIX=target``,
|
||||||
where ``target`` is a private location, i.e. in parallel to your build
|
where ``target`` is a private location, i.e. in parallel to your build
|
||||||
dir by specifying ``../install``.
|
dir by specifying ``../install``.
|
||||||
|
|
||||||
|
..note:: qtkeychain must be compiled with the same prefix e.g CMAKE_INSTALL_PREFIX=/Users/path/to/client/install/
|
||||||
|
|
||||||
|
.. note:: Example:: cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5 -DCMAKE_INSTALL_PREFIX=/Users/path/to/client/install/ -D_OPENSSL_LIBDIR=/usr/local/opt/openssl/lib/ -D_OPENSSL_INCLUDEDIR=/usr/local/opt/openssl/include/ -DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl/include/ -DNO_SHIBBOLETH=1
|
||||||
|
|
||||||
|
.. note:: Example:: cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5 -DCMAKE_INSTALL_PREFIX=/Users/path/to/client/install/ -D_OPENSSL_LIBDIR=/usr/local/opt/openssl/lib/ -D_OPENSSL_INCLUDEDIR=/usr/local/opt/openssl/include/ -D_OPENSSL_VERSION=1.0.2a -DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl/include/ -DNO_SHIBBOLETH=1
|
||||||
|
|
||||||
|
qtkeychain must be compiled with the same prefix e.g CMAKE_INSTALL_PREFIX=/Users/path/to/client/install/ .
|
||||||
|
|
||||||
4. Call ``make``.
|
4. Call ``make``.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
Sync Algorithm
|
||||||
|
==============
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
This is a technical description of the synchronization (sync) algorithm used by the ownCloud client.
|
||||||
|
|
||||||
|
The sync algorithm is the thing that looks at the local and remote file system trees and the sync journal and decides which steps need to be taken to bring the two trees into synchronization. It's different from the propagator, whose job it is to actually execute these steps.
|
||||||
|
|
||||||
|
|
||||||
|
Definitions
|
||||||
|
-----------
|
||||||
|
|
||||||
|
- local tree: The files and directories on the local file system that shall be kept in sync with the remote tree.
|
||||||
|
- remote tree: The files and directories on the ownCloud server that shall be kept in sync with the local tree.
|
||||||
|
- sync journal (journal): A snapshot of file and directory metadata that the sync algorithm uses as a baseline to detect local or remote changes. Typically stored in a database.
|
||||||
|
- file and directory metadata:
|
||||||
|
- mtimes
|
||||||
|
- sizes
|
||||||
|
- inodes (journal and local only): Representation of filesystem object. Useful for rename detection.
|
||||||
|
- etags (journal and remote only): The server assigns a new etag when a file or directory changes.
|
||||||
|
- checksums (journal and remote only): Checksum algorithm applied to a file's contents.
|
||||||
|
- permissions (journal and remote only)
|
||||||
|
|
||||||
|
|
||||||
|
Phases
|
||||||
|
------
|
||||||
|
|
||||||
|
### Discovery (aka Update)
|
||||||
|
|
||||||
|
The discovery phase collects file and directory metadata from the local and remote trees, detecting differences between each tree and the journal.
|
||||||
|
|
||||||
|
Afterwards, we have two trees that tell us what happened relative to the journal. But there may still be conflicts if something happened to an entity both locally and on the remote.
|
||||||
|
|
||||||
|
- Input: file system, server data, journal
|
||||||
|
- Output: two c_rbtree_t*, representing the local and remote trees
|
||||||
|
|
||||||
|
- Note on remote discovery: Since a change to a file on the server causes the etags of all parent folders to change, folders with an unchanged etag can be read from the journal directly and don't need to be walked into.
|
||||||
|
|
||||||
|
- Details
|
||||||
|
- csync_update() uses csync_ftw() on the local and remote trees, one after the other.
|
||||||
|
- csync_ftw() iterates through the entities in a tree and calls csync_walker() for each.
|
||||||
|
- csync_walker() calls _csync_detect_update() on each.
|
||||||
|
- _csync_detect_update() compares the item to its journal entry (if any) to detect new, changed or renamed files. This is the main function of this pass.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Reconcile
|
||||||
|
|
||||||
|
The reconcile phase compares and adjusts the local and remote trees (in both directions), detecting conflicts.
|
||||||
|
|
||||||
|
Afterwards, there are still two trees, but conflicts are marked in them.
|
||||||
|
|
||||||
|
- Input: c_rbtree_t* for the local and remote trees, journal (for some rename-related queries)
|
||||||
|
- Output: changes c_rbtree_t* in-place
|
||||||
|
|
||||||
|
- Details
|
||||||
|
- csync_reconcile() runs csync_reconcile_updates() for the local and remote trees, one after the other.
|
||||||
|
- csync_reconcile_updates() uses c_rbtree_walk() to iterate through the entries, calling _csync_merge_algorithm_visitor() for each.
|
||||||
|
- _csync_merge_algorithm_visitor() checks whether the other tree also has an entry for that node and merges the actions, detecting conflicts. This is the main function of this pass.
|
||||||
|
|
||||||
|
|
||||||
|
### Post-Reconcile
|
||||||
|
|
||||||
|
The post-reconcile phase merges the two trees into one set of SyncFileItems.
|
||||||
|
|
||||||
|
Afterwards, there is a list of items that can tell the propagator what needs to be done.
|
||||||
|
|
||||||
|
- Input: c_rbtree_t* for the local and remote trees
|
||||||
|
- Output: QMap<QString, SyncFileItemPtr>
|
||||||
|
|
||||||
|
- Note that some "propagations", specifically cheap metadata-only updates, are already done at this stage.
|
||||||
|
|
||||||
|
- Details
|
||||||
|
- csync_walk_local_tree() and csync_walk_remote_tree() are called.
|
||||||
|
- They use _csync_walk_tree() to run SyncEngine::treewalkFile() on each entry.
|
||||||
|
- treewalkFile() creates and fills SyncFileItems for each entry, ensuring that each file only has a single instance. This is the main function of this pass.
|
||||||
|
|
||||||
|
|
||||||
|
See Also
|
||||||
|
--------
|
||||||
|
|
||||||
|
An overview of the propagation steps is still missing. The sync protocol is documented at https://github.com/cernbox/smashbox/blob/master/protocol/protocol.md.
|
||||||
@@ -12,7 +12,7 @@ Desktop Sync client enables you to:
|
|||||||
Your files are always automatically synchronized between your ownCloud server
|
Your files are always automatically synchronized between your ownCloud server
|
||||||
and local PC.
|
and local PC.
|
||||||
|
|
||||||
Because of various technical issues, desktop sync clients older than 1.7 will
|
Because of various technical issues, desktop sync clients older than 2.2.1 will
|
||||||
not allowed to connect and sync with the ownCloud 8.1+ server. It is highly
|
not allowed to connect and sync with the ownCloud 8.1+ server. It is highly
|
||||||
recommended to keep your client updated.
|
recommended to keep your client updated.
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation; version 2 of the License.
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but
|
# This program is distributed in the hope that it will be useful, but
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
+170
-4
@@ -355,6 +355,171 @@ X-GNOME-Autostart-Delay=3
|
|||||||
# Translations
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
|
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
|
||||||
GenericName[oc]=Dorsièr de Sincronizacion
|
GenericName[oc]=Dorsièr de Sincronizacion
|
||||||
@@ -445,10 +610,10 @@ Comment[cs_CZ]=@APPLICATION_NAME@ počítačový synchronizační klient
|
|||||||
GenericName[cs_CZ]=Synchronizace adresáře
|
GenericName[cs_CZ]=Synchronizace adresáře
|
||||||
Name[cs_CZ]=@APPLICATION_NAME@ počítačový synchronizační klient
|
Name[cs_CZ]=@APPLICATION_NAME@ počítačový synchronizační klient
|
||||||
Icon[cs_CZ]=@APPLICATION_EXECUTABLE@
|
Icon[cs_CZ]=@APPLICATION_EXECUTABLE@
|
||||||
Comment[ru]=Настольный клиент синхронизации @НАЗВАНИЕ_ПРИЛОЖЕНИЯ@
|
Comment[ru]=Настольный клиент синхронизации @APPLICATION_NAME@
|
||||||
GenericName[ru]=Синхронизация папки
|
GenericName[ru]=Синхронизация каталогов
|
||||||
Name[ru]=Настольный клиент синхронизации @НАЗВАНИЕ_ПРИЛОЖЕНИЯ@
|
Name[ru]=Настольный клиент синхронизации @APPLICATION_NAME@
|
||||||
Icon[ru]=@ВЫПОЛНЯЕМОЕ_ПРИЛОЖЕНИЕ@
|
Icon[ru]=@APPLICATION_EXECUTABLE@
|
||||||
Comment[sl]=@APPLICATION_NAME@ ‒ Program za usklajevanje datotek z namizjem
|
Comment[sl]=@APPLICATION_NAME@ ‒ Program za usklajevanje datotek z namizjem
|
||||||
GenericName[sl]=Usklajevanje map
|
GenericName[sl]=Usklajevanje map
|
||||||
Name[sl]=@APPLICATION_NAME@ ‒ Program za usklajevanje datotek z namizjem
|
Name[sl]=@APPLICATION_NAME@ ‒ Program za usklajevanje datotek z namizjem
|
||||||
@@ -490,6 +655,7 @@ Comment[th_TH]=@APPLICATION_NAME@ ไคลเอนต์ประสานข
|
|||||||
GenericName[th_TH]=ประสานข้อมูลโฟลเดอร์
|
GenericName[th_TH]=ประสานข้อมูลโฟลเดอร์
|
||||||
Name[th_TH]= @APPLICATION_NAME@ ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
|
Name[th_TH]= @APPLICATION_NAME@ ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
|
||||||
Icon[th_TH]=@APPLICATION_EXECUTABLE@
|
Icon[th_TH]=@APPLICATION_EXECUTABLE@
|
||||||
|
GenericName[es_MX]=Sincronización de Carpetas
|
||||||
Comment[nb_NO]=@APPLICATION_NAME@ skrivebordssynkroniseringsklient
|
Comment[nb_NO]=@APPLICATION_NAME@ skrivebordssynkroniseringsklient
|
||||||
GenericName[nb_NO]=Mappesynkronisering
|
GenericName[nb_NO]=Mappesynkronisering
|
||||||
Name[nb_NO]=@APPLICATION_NAME@ skrivebordssynkroniseringsklient
|
Name[nb_NO]=@APPLICATION_NAME@ skrivebordssynkroniseringsklient
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ if( UNIX AND NOT APPLE )
|
|||||||
|
|
||||||
configure_file(syncstate.py syncstate.py COPYONLY)
|
configure_file(syncstate.py syncstate.py COPYONLY)
|
||||||
configure_file(syncstate.py syncstate_nemo.py COPYONLY)
|
configure_file(syncstate.py syncstate_nemo.py COPYONLY)
|
||||||
|
configure_file(syncstate.py syncstate_caja.py COPYONLY)
|
||||||
|
|
||||||
# Call the setupappname.sh script to set the custom app name.
|
# Call the setupappname.sh script to set the custom app name.
|
||||||
set (cmd "${CMAKE_CURRENT_SOURCE_DIR}/setappname.sh")
|
set (cmd "${CMAKE_CURRENT_SOURCE_DIR}/setappname.sh")
|
||||||
@@ -18,9 +19,17 @@ if( UNIX AND NOT APPLE )
|
|||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
ERROR_VARIABLE errors OUTPUT_VARIABLE out)
|
ERROR_VARIABLE errors OUTPUT_VARIABLE out)
|
||||||
|
|
||||||
|
# Create a caja plugin script from the nautilus one.
|
||||||
|
# cajacmd copies the syncstate.py and performs string replacement.
|
||||||
|
set (cajacmd "${CMAKE_CURRENT_SOURCE_DIR}/createcajaplugin.sh")
|
||||||
|
execute_process(COMMAND ${cajacmd}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
ERROR_VARIABLE errors OUTPUT_VARIABLE out)
|
||||||
|
|
||||||
|
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate.py DESTINATION ${DATADIR}/nautilus-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate.py DESTINATION ${DATADIR}/nautilus-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py)
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate_nemo.py DESTINATION ${DATADIR}/nemo-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate_nemo.py DESTINATION ${DATADIR}/nemo-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py)
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate_caja.py DESTINATION ${DATADIR}/caja-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Arquivo executável
+7
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# this script creates a plugin for caja, just by replacing
|
||||||
|
# all occurences of Nautilus with Caja (case sensitive).
|
||||||
|
|
||||||
|
sed -i.org -e 's/Nautilus/Caja/g' syncstate_caja.py
|
||||||
|
sed -i.org -e 's/nautilus/caja/g' syncstate_caja.py
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
import os
|
import os
|
||||||
import urllib
|
import urllib
|
||||||
import socket
|
import socket
|
||||||
|
import tempfile
|
||||||
|
|
||||||
from gi.repository import GObject, Nautilus
|
from gi.repository import GObject, Nautilus
|
||||||
|
|
||||||
@@ -43,7 +44,7 @@ def get_runtime_dir():
|
|||||||
try:
|
try:
|
||||||
return os.environ['XDG_RUNTIME_DIR']
|
return os.environ['XDG_RUNTIME_DIR']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
fallback = '/tmp/runtime-' + os.environ['USER']
|
fallback = os.path.join(tempfile.gettempdir(), 'runtime-' + os.environ['USER'])
|
||||||
return fallback
|
return fallback
|
||||||
|
|
||||||
|
|
||||||
@@ -86,22 +87,17 @@ class SocketConnect(GObject.GObject):
|
|||||||
def _connectToSocketServer(self):
|
def _connectToSocketServer(self):
|
||||||
try:
|
try:
|
||||||
self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
postfix = "/" + appname + "/socket" # Should use os.path.join instead
|
sock_file = os.path.join(get_runtime_dir(), appname, "socket")
|
||||||
sock_file = get_runtime_dir() + postfix
|
try:
|
||||||
print ("Socket: " + sock_file + " <=> " + postfix)
|
print("Socket File: " + sock_file)
|
||||||
if sock_file != postfix:
|
self._sock.connect(sock_file) # fails if sock_file doesn't exist
|
||||||
try:
|
self.connected = True
|
||||||
print("Socket File: " + sock_file)
|
print("Setting connected to %r." % self.connected )
|
||||||
self._sock.connect(sock_file)
|
self._watch_id = GObject.io_add_watch(self._sock, GObject.IO_IN, self._handle_notify)
|
||||||
self.connected = True
|
print("Socket watch id: " + str(self._watch_id))
|
||||||
print("Setting connected to %r." % self.connected )
|
return False # Don't run again
|
||||||
self._watch_id = GObject.io_add_watch(self._sock, GObject.IO_IN, self._handle_notify)
|
except Exception as e:
|
||||||
print("Socket watch id: " + str(self._watch_id))
|
print("Could not connect to unix socket. " + str(e))
|
||||||
return False # Don't run again
|
|
||||||
except Exception as e:
|
|
||||||
print("Could not connect to unix socket. " + str(e))
|
|
||||||
else:
|
|
||||||
print("Sock-File not valid: " + sock_file)
|
|
||||||
except Exception as e: # Bad habbit
|
except Exception as e: # Bad habbit
|
||||||
print("Connect could not be established, try again later.")
|
print("Connect could not be established, try again later.")
|
||||||
self._sock.close()
|
self._sock.close()
|
||||||
@@ -157,32 +153,65 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
GObject.GObject.__init__(self)
|
GObject.GObject.__init__(self)
|
||||||
|
|
||||||
|
def check_registered_paths(self, filename):
|
||||||
|
topLevelFolder = False
|
||||||
|
internalFile = False
|
||||||
|
for reg_path in socketConnect.registered_paths:
|
||||||
|
if filename == reg_path:
|
||||||
|
topLevelFolder = True
|
||||||
|
break
|
||||||
|
if filename.startswith(reg_path):
|
||||||
|
internalFile = True
|
||||||
|
# you can't have a registered path below another so it is save to break here
|
||||||
|
break
|
||||||
|
return (topLevelFolder, internalFile)
|
||||||
|
|
||||||
def get_file_items(self, window, files):
|
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:
|
if len(files) != 1:
|
||||||
return
|
return
|
||||||
file = files[0]
|
file = files[0]
|
||||||
items = []
|
items = []
|
||||||
|
|
||||||
# Internal or external file?!
|
filename = get_local_path(file.get_uri())
|
||||||
syncedFile = False
|
# Check if its a folder (ends with an /), if yes add a "/"
|
||||||
for reg_path in socketConnect.registered_paths:
|
# otherwise it will not find the entry in the table
|
||||||
topLevelFolder = False
|
isDir = os.path.isdir(filename + os.sep)
|
||||||
filename = get_local_path(file.get_uri())
|
if isDir:
|
||||||
# Check if its a folder (ends with an /), if yes add a "/"
|
filename += os.sep
|
||||||
# otherwise it will not find the entry in the table
|
|
||||||
if os.path.isdir(filename + "/"):
|
|
||||||
filename += "/"
|
|
||||||
# Check if toplevel folder, we need to ignore those as they cannot be shared
|
|
||||||
if filename == reg_path:
|
|
||||||
topLevelFolder=True
|
|
||||||
# Only show the menu extension if the file is synced and the sync
|
|
||||||
# status is ok. Not for ignored files etc.
|
|
||||||
# ignore top level folders
|
|
||||||
if filename.startswith(reg_path) and topLevelFolder == False and socketConnect.nautilusVFSFile_table[filename]['state'].startswith('OK'):
|
|
||||||
syncedFile = True
|
|
||||||
|
|
||||||
# If it is neither in a synced folder or is a directory
|
# Check if toplevel folder, we need to ignore those as they cannot be shared
|
||||||
if not syncedFile:
|
topLevelFolder, internalFile = self.check_registered_paths(filename)
|
||||||
|
if topLevelFolder or not internalFile:
|
||||||
|
return items
|
||||||
|
|
||||||
|
entry = socketConnect.nautilusVFSFile_table.get(filename)
|
||||||
|
if not entry:
|
||||||
|
return items
|
||||||
|
|
||||||
|
shareable = False
|
||||||
|
state = entry['state']
|
||||||
|
state_ok = state.startswith('OK')
|
||||||
|
state_sync = state.startswith('SYNC')
|
||||||
|
if state_ok:
|
||||||
|
shareable = True
|
||||||
|
elif state_sync and isDir:
|
||||||
|
# some file below is OK or SYNC
|
||||||
|
for key, value in socketConnect.nautilusVFSFile_table.items():
|
||||||
|
if key != filename and key.startswith(filename):
|
||||||
|
state = value['state']
|
||||||
|
if state.startswith('OK') or state.startswith('SYNC'):
|
||||||
|
shareable = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if not shareable:
|
||||||
return items
|
return items
|
||||||
|
|
||||||
# Create a menu item
|
# Create a menu item
|
||||||
@@ -303,7 +332,7 @@ class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
|
|||||||
|
|
||||||
filename = get_local_path(item.get_uri())
|
filename = get_local_path(item.get_uri())
|
||||||
if item.is_directory():
|
if item.is_directory():
|
||||||
filename += '/'
|
filename += os.sep
|
||||||
|
|
||||||
inScope = False
|
inScope = False
|
||||||
for reg_path in socketConnect.registered_paths:
|
for reg_path in socketConnect.registered_paths:
|
||||||
|
|||||||
+17
-161
@@ -1,165 +1,21 @@
|
|||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
The MIT License (MIT)
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
Copyright (c) 2011 Morgan Leborgne
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
This version of the GNU Lesser General Public License incorporates
|
The above copyright notice and this permission notice shall be included in all
|
||||||
the terms and conditions of version 3 of the GNU General Public
|
copies or substantial portions of the Software.
|
||||||
License, supplemented by the additional permissions listed below.
|
|
||||||
|
|
||||||
0. Additional Definitions.
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
General Public License.
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
"The Library" refers to a covered work governed by this License,
|
SOFTWARE.
|
||||||
other than an Application or a Combined Work as defined below.
|
|
||||||
|
|
||||||
An "Application" is any work that makes use of an interface provided
|
|
||||||
by the Library, but which is not otherwise based on the Library.
|
|
||||||
Defining a subclass of a class defined by the Library is deemed a mode
|
|
||||||
of using an interface provided by the Library.
|
|
||||||
|
|
||||||
A "Combined Work" is a work produced by combining or linking an
|
|
||||||
Application with the Library. The particular version of the Library
|
|
||||||
with which the Combined Work was made is also called the "Linked
|
|
||||||
Version".
|
|
||||||
|
|
||||||
The "Minimal Corresponding Source" for a Combined Work means the
|
|
||||||
Corresponding Source for the Combined Work, excluding any source code
|
|
||||||
for portions of the Combined Work that, considered in isolation, are
|
|
||||||
based on the Application, and not on the Linked Version.
|
|
||||||
|
|
||||||
The "Corresponding Application Code" for a Combined Work means the
|
|
||||||
object code and/or source code for the Application, including any data
|
|
||||||
and utility programs needed for reproducing the Combined Work from the
|
|
||||||
Application, but excluding the System Libraries of the Combined Work.
|
|
||||||
|
|
||||||
1. Exception to Section 3 of the GNU GPL.
|
|
||||||
|
|
||||||
You may convey a covered work under sections 3 and 4 of this License
|
|
||||||
without being bound by section 3 of the GNU GPL.
|
|
||||||
|
|
||||||
2. Conveying Modified Versions.
|
|
||||||
|
|
||||||
If you modify a copy of the Library, and, in your modifications, a
|
|
||||||
facility refers to a function or data to be supplied by an Application
|
|
||||||
that uses the facility (other than as an argument passed when the
|
|
||||||
facility is invoked), then you may convey a copy of the modified
|
|
||||||
version:
|
|
||||||
|
|
||||||
a) under this License, provided that you make a good faith effort to
|
|
||||||
ensure that, in the event an Application does not supply the
|
|
||||||
function or data, the facility still operates, and performs
|
|
||||||
whatever part of its purpose remains meaningful, or
|
|
||||||
|
|
||||||
b) under the GNU GPL, with none of the additional permissions of
|
|
||||||
this License applicable to that copy.
|
|
||||||
|
|
||||||
3. Object Code Incorporating Material from Library Header Files.
|
|
||||||
|
|
||||||
The object code form of an Application may incorporate material from
|
|
||||||
a header file that is part of the Library. You may convey such object
|
|
||||||
code under terms of your choice, provided that, if the incorporated
|
|
||||||
material is not limited to numerical parameters, data structure
|
|
||||||
layouts and accessors, or small macros, inline functions and templates
|
|
||||||
(ten or fewer lines in length), you do both of the following:
|
|
||||||
|
|
||||||
a) Give prominent notice with each copy of the object code that the
|
|
||||||
Library is used in it and that the Library and its use are
|
|
||||||
covered by this License.
|
|
||||||
|
|
||||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
|
||||||
document.
|
|
||||||
|
|
||||||
4. Combined Works.
|
|
||||||
|
|
||||||
You may convey a Combined Work under terms of your choice that,
|
|
||||||
taken together, effectively do not restrict modification of the
|
|
||||||
portions of the Library contained in the Combined Work and reverse
|
|
||||||
engineering for debugging such modifications, if you also do each of
|
|
||||||
the following:
|
|
||||||
|
|
||||||
a) Give prominent notice with each copy of the Combined Work that
|
|
||||||
the Library is used in it and that the Library and its use are
|
|
||||||
covered by this License.
|
|
||||||
|
|
||||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
|
||||||
document.
|
|
||||||
|
|
||||||
c) For a Combined Work that displays copyright notices during
|
|
||||||
execution, include the copyright notice for the Library among
|
|
||||||
these notices, as well as a reference directing the user to the
|
|
||||||
copies of the GNU GPL and this license document.
|
|
||||||
|
|
||||||
d) Do one of the following:
|
|
||||||
|
|
||||||
0) Convey the Minimal Corresponding Source under the terms of this
|
|
||||||
License, and the Corresponding Application Code in a form
|
|
||||||
suitable for, and under terms that permit, the user to
|
|
||||||
recombine or relink the Application with a modified version of
|
|
||||||
the Linked Version to produce a modified Combined Work, in the
|
|
||||||
manner specified by section 6 of the GNU GPL for conveying
|
|
||||||
Corresponding Source.
|
|
||||||
|
|
||||||
1) Use a suitable shared library mechanism for linking with the
|
|
||||||
Library. A suitable mechanism is one that (a) uses at run time
|
|
||||||
a copy of the Library already present on the user's computer
|
|
||||||
system, and (b) will operate properly with a modified version
|
|
||||||
of the Library that is interface-compatible with the Linked
|
|
||||||
Version.
|
|
||||||
|
|
||||||
e) Provide Installation Information, but only if you would otherwise
|
|
||||||
be required to provide such information under section 6 of the
|
|
||||||
GNU GPL, and only to the extent that such information is
|
|
||||||
necessary to install and execute a modified version of the
|
|
||||||
Combined Work produced by recombining or relinking the
|
|
||||||
Application with a modified version of the Linked Version. (If
|
|
||||||
you use option 4d0, the Installation Information must accompany
|
|
||||||
the Minimal Corresponding Source and Corresponding Application
|
|
||||||
Code. If you use option 4d1, you must provide the Installation
|
|
||||||
Information in the manner specified by section 6 of the GNU GPL
|
|
||||||
for conveying Corresponding Source.)
|
|
||||||
|
|
||||||
5. Combined Libraries.
|
|
||||||
|
|
||||||
You may place library facilities that are a work based on the
|
|
||||||
Library side by side in a single library together with other library
|
|
||||||
facilities that are not Applications and are not covered by this
|
|
||||||
License, and convey such a combined library under terms of your
|
|
||||||
choice, if you do both of the following:
|
|
||||||
|
|
||||||
a) Accompany the combined library with a copy of the same work based
|
|
||||||
on the Library, uncombined with any other library facilities,
|
|
||||||
conveyed under the terms of this License.
|
|
||||||
|
|
||||||
b) Give prominent notice with the combined library that part of it
|
|
||||||
is a work based on the Library, and explaining where to find the
|
|
||||||
accompanying uncombined form of the same work.
|
|
||||||
|
|
||||||
6. Revised Versions of the GNU Lesser General Public License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the GNU Lesser General Public License from time to time. Such new
|
|
||||||
versions will be similar in spirit to the present version, but may
|
|
||||||
differ in detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Library as you received it specifies that a certain numbered version
|
|
||||||
of the GNU Lesser General Public License "or any later version"
|
|
||||||
applies to it, you have the option of following the terms and
|
|
||||||
conditions either of that published version or of any later version
|
|
||||||
published by the Free Software Foundation. If the Library as you
|
|
||||||
received it does not specify a version number of the GNU Lesser
|
|
||||||
General Public License, you may choose any version of the GNU Lesser
|
|
||||||
General Public License ever published by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Library as you received it specifies that a proxy can decide
|
|
||||||
whether future versions of the GNU Lesser General Public License shall
|
|
||||||
apply, that proxy's public statement of acceptance of any version is
|
|
||||||
permanent authorization for you to choose that version for the
|
|
||||||
Library.
|
|
||||||
|
|||||||
+23
-20
@@ -1,24 +1,27 @@
|
|||||||
/*
|
/*
|
||||||
*
|
* The MIT License (MIT)
|
||||||
* This file is part of QProgressIndicator,
|
*
|
||||||
* an open-source recent files menu widget
|
* Copyright (c) 2011 Morgan Leborgne
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 - 2010 Morgan Leborgne
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
*
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* in the Software without restriction, including without limitation the rights
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* (at your option) any later version.
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* copies or substantial portions of the Software.
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
*
|
||||||
* GNU Lesser General Public License for more details.
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
*
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* along with QRecentFilesMenu. If not, see <http://www.gnu.org/licenses/>.
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
*
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
*/
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "QProgressIndicator.h"
|
#include "QProgressIndicator.h"
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|||||||
+27
-24
@@ -1,24 +1,27 @@
|
|||||||
/*
|
/*
|
||||||
*
|
* The MIT License (MIT)
|
||||||
* This file is part of QProgressIndicator,
|
*
|
||||||
* an open-source recent files menu widget
|
* Copyright (c) 2011 Morgan Leborgne
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 - 2010 Morgan Leborgne
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
*
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* in the Software without restriction, including without limitation the rights
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* (at your option) any later version.
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* copies or substantial portions of the Software.
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
*
|
||||||
* GNU Lesser General Public License for more details.
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
*
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* along with QRecentFilesMenu. If not, see <http://www.gnu.org/licenses/>.
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
*
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
*/
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef QPROGRESSINDICATOR_H
|
#ifndef QPROGRESSINDICATOR_H
|
||||||
#define QPROGRESSINDICATOR_H
|
#define QPROGRESSINDICATOR_H
|
||||||
|
|
||||||
@@ -64,8 +67,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
const QColor & color() const { return m_color; }
|
const QColor & color() const { return m_color; }
|
||||||
|
|
||||||
virtual QSize sizeHint() const Q_DECL_OVERRIDE;
|
virtual QSize sizeHint() const;
|
||||||
int heightForWidth(int w) const Q_DECL_OVERRIDE;
|
int heightForWidth(int w) const;
|
||||||
public slots:
|
public slots:
|
||||||
/*! Starts the spin animation.
|
/*! Starts the spin animation.
|
||||||
\sa stopAnimation isAnimated
|
\sa stopAnimation isAnimated
|
||||||
@@ -95,8 +98,8 @@ public slots:
|
|||||||
*/
|
*/
|
||||||
void setColor(const QColor & color);
|
void setColor(const QColor & color);
|
||||||
protected:
|
protected:
|
||||||
virtual void timerEvent(QTimerEvent * event) Q_DECL_OVERRIDE;
|
virtual void timerEvent(QTimerEvent * event);
|
||||||
virtual void paintEvent(QPaintEvent * event) Q_DECL_OVERRIDE;
|
virtual void paintEvent(QPaintEvent * event);
|
||||||
private:
|
private:
|
||||||
int m_angle;
|
int m_angle;
|
||||||
int m_timerId;
|
int m_timerId;
|
||||||
|
|||||||
+1
-1
@@ -11,4 +11,4 @@ Qt 4.4.x.
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
LGPL
|
MIT
|
||||||
|
|||||||
+2
-11
@@ -329,8 +329,7 @@ int main(int argc, char **argv) {
|
|||||||
if( !options.target_url.contains( account->davPath() )) {
|
if( !options.target_url.contains( account->davPath() )) {
|
||||||
options.target_url.append(account->davPath());
|
options.target_url.append(account->davPath());
|
||||||
}
|
}
|
||||||
if (options.target_url.startsWith("http"))
|
|
||||||
options.target_url.replace(0, 4, "owncloud");
|
|
||||||
QUrl url = QUrl::fromUserInput(options.target_url);
|
QUrl url = QUrl::fromUserInput(options.target_url);
|
||||||
|
|
||||||
// Order of retrieval attempt (later attempts override earlier ones):
|
// Order of retrieval attempt (later attempts override earlier ones):
|
||||||
@@ -371,14 +370,6 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ### ensure URL is free of credentials
|
|
||||||
if (url.userName().isEmpty()) {
|
|
||||||
url.setUserName(user);
|
|
||||||
}
|
|
||||||
if (url.password().isEmpty()) {
|
|
||||||
url.setPassword(password);
|
|
||||||
}
|
|
||||||
|
|
||||||
// take the unmodified url to pass to csync_create()
|
// take the unmodified url to pass to csync_create()
|
||||||
QByteArray remUrl = options.target_url.toUtf8();
|
QByteArray remUrl = options.target_url.toUtf8();
|
||||||
|
|
||||||
@@ -475,7 +466,7 @@ restart_sync:
|
|||||||
selectiveSyncFixup(&db, selectiveSyncList);
|
selectiveSyncFixup(&db, selectiveSyncList);
|
||||||
}
|
}
|
||||||
|
|
||||||
SyncEngine engine(account, options.source_dir, QUrl(options.target_url), folder, &db);
|
SyncEngine engine(account, options.source_dir, folder, &db);
|
||||||
engine.setIgnoreHiddenFiles(options.ignoreHiddenFiles);
|
engine.setIgnoreHiddenFiles(options.ignoreHiddenFiles);
|
||||||
QObject::connect(&engine, SIGNAL(finished(bool)), &app, SLOT(quit()));
|
QObject::connect(&engine, SIGNAL(finished(bool)), &app, SLOT(quit()));
|
||||||
QObject::connect(&engine, SIGNAL(transmissionProgress(ProgressInfo)), &cmd, SLOT(transmissionProgressSlot()));
|
QObject::connect(&engine, SIGNAL(transmissionProgress(ProgressInfo)), &cmd, SLOT(transmissionProgressSlot()));
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -199,6 +199,9 @@ IF( WIN32 )
|
|||||||
${CMAKE_CURRENT_BINARY_DIR}/version.rc
|
${CMAKE_CURRENT_BINARY_DIR}/version.rc
|
||||||
@ONLY)
|
@ONLY)
|
||||||
set(client_version ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
set(client_version ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
||||||
|
IF(NOT MSVC)
|
||||||
|
set(client_manifest ${CMAKE_CURRENT_SOURCE_DIR}/manifest-mingw.rc)
|
||||||
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
set( final_src
|
set( final_src
|
||||||
@@ -206,6 +209,7 @@ set( final_src
|
|||||||
${client_SRCS}
|
${client_SRCS}
|
||||||
${client_UI_SRCS}
|
${client_UI_SRCS}
|
||||||
${client_version}
|
${client_version}
|
||||||
|
${client_manifest}
|
||||||
${guiMoc}
|
${guiMoc}
|
||||||
${client_I18N}
|
${client_I18N}
|
||||||
${3rdparty_SRC}
|
${3rdparty_SRC}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
@@ -44,7 +45,7 @@ AccountManager *AccountManager::instance()
|
|||||||
|
|
||||||
bool AccountManager::restore()
|
bool AccountManager::restore()
|
||||||
{
|
{
|
||||||
auto settings = Account::settingsWithGroup(QLatin1String(accountsC));
|
auto settings = Utility::settingsWithGroup(QLatin1String(accountsC));
|
||||||
|
|
||||||
// If there are no accounts, check the old format.
|
// If there are no accounts, check the old format.
|
||||||
if (settings->childGroups().isEmpty()
|
if (settings->childGroups().isEmpty()
|
||||||
@@ -69,9 +70,7 @@ bool AccountManager::restore()
|
|||||||
bool AccountManager::restoreFromLegacySettings()
|
bool AccountManager::restoreFromLegacySettings()
|
||||||
{
|
{
|
||||||
// try to open the correctly themed settings
|
// try to open the correctly themed settings
|
||||||
auto settings = Account::settingsWithGroup(Theme::instance()->appName());
|
auto settings = Utility::settingsWithGroup(Theme::instance()->appName());
|
||||||
|
|
||||||
bool migratedCreds = false;
|
|
||||||
|
|
||||||
// if the settings file could not be opened, the childKeys list is empty
|
// if the settings file could not be opened, the childKeys list is empty
|
||||||
// then try to load settings from a very old place
|
// then try to load settings from a very old place
|
||||||
@@ -102,7 +101,6 @@ bool AccountManager::restoreFromLegacySettings()
|
|||||||
qDebug() << "Migrate oC config if " << oCUrl << " == " << overrideUrl << ":"
|
qDebug() << "Migrate oC config if " << oCUrl << " == " << overrideUrl << ":"
|
||||||
<< (oCUrl == overrideUrl ? "Yes" : "No");
|
<< (oCUrl == overrideUrl ? "Yes" : "No");
|
||||||
if( oCUrl == overrideUrl ) {
|
if( oCUrl == overrideUrl ) {
|
||||||
migratedCreds = true;
|
|
||||||
settings.reset( oCSettings );
|
settings.reset( oCSettings );
|
||||||
} else {
|
} else {
|
||||||
delete oCSettings;
|
delete oCSettings;
|
||||||
@@ -114,9 +112,6 @@ bool AccountManager::restoreFromLegacySettings()
|
|||||||
// Try to load the single account.
|
// Try to load the single account.
|
||||||
if (!settings->childKeys().isEmpty()) {
|
if (!settings->childKeys().isEmpty()) {
|
||||||
if (auto acc = loadAccountHelper(*settings)) {
|
if (auto acc = loadAccountHelper(*settings)) {
|
||||||
if (migratedCreds) {
|
|
||||||
acc->setMigrated(true);
|
|
||||||
}
|
|
||||||
addAccount(acc);
|
addAccount(acc);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -126,7 +121,7 @@ bool AccountManager::restoreFromLegacySettings()
|
|||||||
|
|
||||||
void AccountManager::save(bool saveCredentials)
|
void AccountManager::save(bool saveCredentials)
|
||||||
{
|
{
|
||||||
auto settings = Account::settingsWithGroup(QLatin1String(accountsC));
|
auto settings = Utility::settingsWithGroup(QLatin1String(accountsC));
|
||||||
settings->setValue(QLatin1String(versionC), 2);
|
settings->setValue(QLatin1String(versionC), 2);
|
||||||
foreach (const auto &acc, _accounts) {
|
foreach (const auto &acc, _accounts) {
|
||||||
settings->beginGroup(acc->account()->id());
|
settings->beginGroup(acc->account()->id());
|
||||||
@@ -142,7 +137,7 @@ void AccountManager::save(bool saveCredentials)
|
|||||||
void AccountManager::saveAccount(Account* a)
|
void AccountManager::saveAccount(Account* a)
|
||||||
{
|
{
|
||||||
qDebug() << "Saving account" << a->url().toString();
|
qDebug() << "Saving account" << a->url().toString();
|
||||||
auto settings = Account::settingsWithGroup(QLatin1String(accountsC));
|
auto settings = Utility::settingsWithGroup(QLatin1String(accountsC));
|
||||||
settings->beginGroup(a->id());
|
settings->beginGroup(a->id());
|
||||||
saveAccountHelper(a, *settings, false); // don't save credentials they might not have been loaded yet
|
saveAccountHelper(a, *settings, false); // don't save credentials they might not have been loaded yet
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
@@ -154,7 +149,7 @@ void AccountManager::saveAccount(Account* a)
|
|||||||
void AccountManager::saveAccountState(AccountState* a)
|
void AccountManager::saveAccountState(AccountState* a)
|
||||||
{
|
{
|
||||||
qDebug() << "Saving account state" << a->account()->url().toString();
|
qDebug() << "Saving account state" << a->account()->url().toString();
|
||||||
auto settings = Account::settingsWithGroup(QLatin1String(accountsC));
|
auto settings = Utility::settingsWithGroup(QLatin1String(accountsC));
|
||||||
settings->beginGroup(a->account()->id());
|
settings->beginGroup(a->account()->id());
|
||||||
a->writeToSettings(*settings);
|
a->writeToSettings(*settings);
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
@@ -280,7 +275,7 @@ void AccountManager::deleteAccount(AccountState* account)
|
|||||||
auto copy = *it; // keep a reference to the shared pointer so it does not delete it just yet
|
auto copy = *it; // keep a reference to the shared pointer so it does not delete it just yet
|
||||||
_accounts.erase(it);
|
_accounts.erase(it);
|
||||||
|
|
||||||
auto settings = Account::settingsWithGroup(QLatin1String(accountsC));
|
auto settings = Utility::settingsWithGroup(QLatin1String(accountsC));
|
||||||
settings->remove(account->account()->id());
|
settings->remove(account->account()->id());
|
||||||
|
|
||||||
emit accountRemoved(account);
|
emit accountRemoved(account);
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
#include "owncloudsetupwizard.h"
|
#include "owncloudsetupwizard.h"
|
||||||
#include "creds/abstractcredentials.h"
|
#include "creds/abstractcredentials.h"
|
||||||
#include "tooltipupdater.h"
|
#include "tooltipupdater.h"
|
||||||
|
#include "filesystem.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@@ -109,7 +111,7 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent) :
|
|||||||
|
|
||||||
QAction *syncNowAction = new QAction(this);
|
QAction *syncNowAction = new QAction(this);
|
||||||
syncNowAction->setShortcut(QKeySequence(Qt::Key_F6));
|
syncNowAction->setShortcut(QKeySequence(Qt::Key_F6));
|
||||||
connect(syncNowAction, SIGNAL(triggered()), SLOT(slotSyncCurrentFolderNow()));
|
connect(syncNowAction, SIGNAL(triggered()), SLOT(slotScheduleCurrentFolder()));
|
||||||
addAction(syncNowAction);
|
addAction(syncNowAction);
|
||||||
|
|
||||||
connect(ui->_folderList, SIGNAL(clicked(const QModelIndex &)),
|
connect(ui->_folderList, SIGNAL(clicked(const QModelIndex &)),
|
||||||
@@ -227,6 +229,11 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos)
|
|||||||
connect(ac, SIGNAL(triggered(bool)), this, SLOT(doExpand()));
|
connect(ac, SIGNAL(triggered(bool)), this, SLOT(doExpand()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!folderPaused) {
|
||||||
|
ac = menu->addAction(tr("Force sync now"));
|
||||||
|
connect(ac, SIGNAL(triggered(bool)), this, SLOT(slotForceSyncCurrentFolder()));
|
||||||
|
}
|
||||||
|
|
||||||
ac = menu->addAction(folderPaused ? tr("Resume sync") : tr("Pause sync"));
|
ac = menu->addAction(folderPaused ? tr("Resume sync") : tr("Pause sync"));
|
||||||
connect(ac, SIGNAL(triggered(bool)), this, SLOT(slotEnableCurrentFolder()));
|
connect(ac, SIGNAL(triggered(bool)), this, SLOT(slotEnableCurrentFolder()));
|
||||||
|
|
||||||
@@ -299,8 +306,9 @@ void AccountSettings::slotFolderWizardAccepted()
|
|||||||
tr("<p>Could not create local folder <i>%1</i>.")
|
tr("<p>Could not create local folder <i>%1</i>.")
|
||||||
.arg(QDir::toNativeSeparators(definition.localPath)));
|
.arg(QDir::toNativeSeparators(definition.localPath)));
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
FileSystem::setFolderMinimumPermissions(definition.localPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,7 +329,7 @@ void AccountSettings::slotFolderWizardAccepted()
|
|||||||
// The user already accepted the selective sync dialog. everything is in the white list
|
// The user already accepted the selective sync dialog. everything is in the white list
|
||||||
f->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList,
|
f->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList,
|
||||||
QStringList() << QLatin1String("/"));
|
QStringList() << QLatin1String("/"));
|
||||||
folderMan->slotScheduleAllFolders();
|
folderMan->scheduleAllFolders();
|
||||||
emit folderChanged();
|
emit folderChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -360,7 +368,7 @@ void AccountSettings::slotRemoveCurrentFolder()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
folderMan->slotRemoveFolder( folderMan->folder(alias) );
|
folderMan->removeFolder( folderMan->folder(alias) );
|
||||||
_model->removeRow(row);
|
_model->removeRow(row);
|
||||||
|
|
||||||
// single folder fix to show add-button and hide remove-button
|
// single folder fix to show add-button and hide remove-button
|
||||||
@@ -460,7 +468,7 @@ void AccountSettings::slotEnableCurrentFolder()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountSettings::slotSyncCurrentFolderNow()
|
void AccountSettings::slotScheduleCurrentFolder()
|
||||||
{
|
{
|
||||||
QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
|
QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
|
||||||
if( !selected.isValid() )
|
if( !selected.isValid() )
|
||||||
@@ -468,7 +476,25 @@ void AccountSettings::slotSyncCurrentFolderNow()
|
|||||||
QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
|
QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
|
||||||
FolderMan *folderMan = FolderMan::instance();
|
FolderMan *folderMan = FolderMan::instance();
|
||||||
|
|
||||||
folderMan->slotScheduleSync(folderMan->folder(alias));
|
folderMan->scheduleFolder(folderMan->folder(alias));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccountSettings::slotForceSyncCurrentFolder()
|
||||||
|
{
|
||||||
|
QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
|
||||||
|
if( !selected.isValid() )
|
||||||
|
return;
|
||||||
|
QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
|
||||||
|
FolderMan *folderMan = FolderMan::instance();
|
||||||
|
|
||||||
|
// Terminate and reschedule any running sync
|
||||||
|
if (Folder* current = folderMan->currentSyncFolder()) {
|
||||||
|
folderMan->terminateSyncProcess();
|
||||||
|
folderMan->scheduleFolder(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the selected folder at the front of the queue
|
||||||
|
folderMan->scheduleFolderNext(folderMan->folder(alias));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountSettings::slotOpenOC()
|
void AccountSettings::slotOpenOC()
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
@@ -70,7 +71,8 @@ public slots:
|
|||||||
protected slots:
|
protected slots:
|
||||||
void slotAddFolder();
|
void slotAddFolder();
|
||||||
void slotEnableCurrentFolder();
|
void slotEnableCurrentFolder();
|
||||||
void slotSyncCurrentFolderNow();
|
void slotScheduleCurrentFolder();
|
||||||
|
void slotForceSyncCurrentFolder();
|
||||||
void slotRemoveCurrentFolder();
|
void slotRemoveCurrentFolder();
|
||||||
void slotOpenCurrentFolder();
|
void slotOpenCurrentFolder();
|
||||||
void slotFolderWizardAccepted();
|
void slotFolderWizardAccepted();
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
@@ -306,7 +307,7 @@ void AccountState::slotCredentialsAsked(AbstractCredentials* credentials)
|
|||||||
|
|
||||||
std::unique_ptr<QSettings> AccountState::settings()
|
std::unique_ptr<QSettings> AccountState::settings()
|
||||||
{
|
{
|
||||||
auto s = _account->settingsWithGroup(QLatin1String("Accounts"));
|
auto s = Utility::settingsWithGroup(QLatin1String("Accounts"));
|
||||||
s->beginGroup(_account->id());
|
s->beginGroup(_account->id());
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
@@ -616,7 +617,7 @@ void ActivitySettings::slotCopyToClipboard()
|
|||||||
message = tr("The sync activity list has been copied to the clipboard.");
|
message = tr("The sync activity list has been copied to the clipboard.");
|
||||||
} else if(idx == 2 ) {
|
} else if(idx == 2 ) {
|
||||||
// issues Widget
|
// issues Widget
|
||||||
message = tr("The list of unsynched items has been copied to the clipboard.");
|
message = tr("The list of unsynced items has been copied to the clipboard.");
|
||||||
_protocolWidget->storeSyncIssues(ts);
|
_protocolWidget->storeSyncIssues(ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ void Application::slotownCloudWizardDone( int res )
|
|||||||
shouldSetAutoStart = shouldSetAutoStart
|
shouldSetAutoStart = shouldSetAutoStart
|
||||||
&& QCoreApplication::applicationDirPath().startsWith("/Applications/");
|
&& QCoreApplication::applicationDirPath().startsWith("/Applications/");
|
||||||
#endif
|
#endif
|
||||||
Utility::setLaunchOnStartup(_theme->appName(), _theme->appNameGUI(), true);
|
Utility::setLaunchOnStartup(_theme->appName(), _theme->appNameGUI(), shouldSetAutoStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
@@ -79,21 +80,6 @@ void ShibbolethCredentials::setAccount(Account* account)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShibbolethCredentials::changed(AbstractCredentials* credentials) const
|
|
||||||
{
|
|
||||||
ShibbolethCredentials* other(qobject_cast< ShibbolethCredentials* >(credentials));
|
|
||||||
|
|
||||||
if (!other) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_shibCookie != other->_shibCookie || _user != other->_user) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ShibbolethCredentials::authType() const
|
QString ShibbolethCredentials::authType() const
|
||||||
{
|
{
|
||||||
return QString::fromLatin1("shibboleth");
|
return QString::fromLatin1("shibboleth");
|
||||||
@@ -142,7 +128,7 @@ void ShibbolethCredentials::fetchFromKeychain()
|
|||||||
} else {
|
} else {
|
||||||
_url = _account->url();
|
_url = _account->url();
|
||||||
ReadPasswordJob *job = new ReadPasswordJob(Theme::instance()->appName());
|
ReadPasswordJob *job = new ReadPasswordJob(Theme::instance()->appName());
|
||||||
job->setSettings(_account->settingsWithGroup(Theme::instance()->appName(), job).release());
|
job->setSettings(Utility::settingsWithGroup(Theme::instance()->appName(), job).release());
|
||||||
job->setInsecureFallback(false);
|
job->setInsecureFallback(false);
|
||||||
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
|
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
|
||||||
connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotReadJobDone(QKeychain::Job*)));
|
connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotReadJobDone(QKeychain::Job*)));
|
||||||
@@ -261,7 +247,7 @@ void ShibbolethCredentials::slotReadJobDone(QKeychain::Job *job)
|
|||||||
addToCookieJar(_shibCookie);
|
addToCookieJar(_shibCookie);
|
||||||
}
|
}
|
||||||
// access
|
// access
|
||||||
job->setSettings(_account->settingsWithGroup(Theme::instance()->appName(), job).release());
|
job->setSettings(Utility::settingsWithGroup(Theme::instance()->appName(), job).release());
|
||||||
|
|
||||||
_ready = true;
|
_ready = true;
|
||||||
_stillValid = true;
|
_stillValid = true;
|
||||||
@@ -320,7 +306,7 @@ QByteArray ShibbolethCredentials::shibCookieName()
|
|||||||
void ShibbolethCredentials::storeShibCookie(const QNetworkCookie &cookie)
|
void ShibbolethCredentials::storeShibCookie(const QNetworkCookie &cookie)
|
||||||
{
|
{
|
||||||
WritePasswordJob *job = new WritePasswordJob(Theme::instance()->appName());
|
WritePasswordJob *job = new WritePasswordJob(Theme::instance()->appName());
|
||||||
job->setSettings(_account->settingsWithGroup(Theme::instance()->appName(), job).release());
|
job->setSettings(Utility::settingsWithGroup(Theme::instance()->appName(), job).release());
|
||||||
// we don't really care if it works...
|
// we don't really care if it works...
|
||||||
//connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotWriteJobDone(QKeychain::Job*)));
|
//connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotWriteJobDone(QKeychain::Job*)));
|
||||||
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
|
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
|
||||||
@@ -331,7 +317,7 @@ void ShibbolethCredentials::storeShibCookie(const QNetworkCookie &cookie)
|
|||||||
void ShibbolethCredentials::removeShibCookie()
|
void ShibbolethCredentials::removeShibCookie()
|
||||||
{
|
{
|
||||||
DeletePasswordJob *job = new DeletePasswordJob(Theme::instance()->appName());
|
DeletePasswordJob *job = new DeletePasswordJob(Theme::instance()->appName());
|
||||||
job->setSettings(_account->settingsWithGroup(Theme::instance()->appName(), job).release());
|
job->setSettings(Utility::settingsWithGroup(Theme::instance()->appName(), job).release());
|
||||||
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
|
job->setKey(keychainKey(_account->url().toString(), "shibAssertion"));
|
||||||
job->start();
|
job->start();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
@@ -48,7 +49,6 @@ public:
|
|||||||
ShibbolethCredentials(const QNetworkCookie &cookie);
|
ShibbolethCredentials(const QNetworkCookie &cookie);
|
||||||
|
|
||||||
void setAccount(Account* account) Q_DECL_OVERRIDE;
|
void setAccount(Account* account) Q_DECL_OVERRIDE;
|
||||||
bool changed(AbstractCredentials* credentials) const Q_DECL_OVERRIDE;
|
|
||||||
QString authType() const Q_DECL_OVERRIDE;
|
QString authType() const Q_DECL_OVERRIDE;
|
||||||
QString user() const Q_DECL_OVERRIDE;
|
QString user() const Q_DECL_OVERRIDE;
|
||||||
QNetworkAccessManager* getQNAM() const Q_DECL_OVERRIDE;
|
QNetworkAccessManager* getQNAM() const Q_DECL_OVERRIDE;
|
||||||
|
|||||||
+37
-60
@@ -58,7 +58,6 @@ Folder::Folder(const FolderDefinition& definition,
|
|||||||
, _wipeDb(false)
|
, _wipeDb(false)
|
||||||
, _proxyDirty(true)
|
, _proxyDirty(true)
|
||||||
, _lastSyncDuration(0)
|
, _lastSyncDuration(0)
|
||||||
, _forceSyncOnPollTimeout(false)
|
|
||||||
, _consecutiveFailingSyncs(0)
|
, _consecutiveFailingSyncs(0)
|
||||||
, _consecutiveFollowUpSyncs(0)
|
, _consecutiveFollowUpSyncs(0)
|
||||||
, _journal(definition.localPath)
|
, _journal(definition.localPath)
|
||||||
@@ -82,7 +81,7 @@ Folder::Folder(const FolderDefinition& definition,
|
|||||||
|
|
||||||
_syncResult.setFolder(_definition.alias);
|
_syncResult.setFolder(_definition.alias);
|
||||||
|
|
||||||
_engine.reset(new SyncEngine(_accountState->account(), path(), remoteUrl(), remotePath(), &_journal));
|
_engine.reset(new SyncEngine(_accountState->account(), path(), remotePath(), &_journal));
|
||||||
// pass the setting if hidden files are to be ignored, will be read in csync_update
|
// pass the setting if hidden files are to be ignored, will be read in csync_update
|
||||||
_engine->setIgnoreHiddenFiles(_definition.ignoreHiddenFiles);
|
_engine->setIgnoreHiddenFiles(_definition.ignoreHiddenFiles);
|
||||||
|
|
||||||
@@ -112,6 +111,11 @@ Folder::Folder(const FolderDefinition& definition,
|
|||||||
connect(_engine.data(), SIGNAL(seenLockedFile(QString)), FolderMan::instance(), SLOT(slotSyncOnceFileUnlocks(QString)));
|
connect(_engine.data(), SIGNAL(seenLockedFile(QString)), FolderMan::instance(), SLOT(slotSyncOnceFileUnlocks(QString)));
|
||||||
connect(_engine.data(), SIGNAL(aboutToPropagate(SyncFileItemVector&)),
|
connect(_engine.data(), SIGNAL(aboutToPropagate(SyncFileItemVector&)),
|
||||||
SLOT(slotLogPropagationStart()));
|
SLOT(slotLogPropagationStart()));
|
||||||
|
|
||||||
|
_scheduleSelfTimer.setSingleShot(true);
|
||||||
|
_scheduleSelfTimer.setInterval(SyncEngine::minimumFileAgeForUpload);
|
||||||
|
connect(&_scheduleSelfTimer, SIGNAL(timeout()),
|
||||||
|
SLOT(slotScheduleThisFolder()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Folder::~Folder()
|
Folder::~Folder()
|
||||||
@@ -188,7 +192,7 @@ QString Folder::shortGuiLocalPath() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Folder::ignoreHiddenFiles() const
|
bool Folder::ignoreHiddenFiles()
|
||||||
{
|
{
|
||||||
bool re(_definition.ignoreHiddenFiles);
|
bool re(_definition.ignoreHiddenFiles);
|
||||||
return re;
|
return re;
|
||||||
@@ -221,7 +225,7 @@ QString Folder::remotePath() const
|
|||||||
|
|
||||||
QUrl Folder::remoteUrl() const
|
QUrl Folder::remoteUrl() const
|
||||||
{
|
{
|
||||||
return Account::concatUrlPath(_accountState->account()->davUrl(), remotePath());
|
return Utility::concatUrlPath(_accountState->account()->davUrl(), remotePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Folder::syncPaused() const
|
bool Folder::syncPaused() const
|
||||||
@@ -275,7 +279,7 @@ void Folder::slotRunEtagJob()
|
|||||||
|
|
||||||
AccountPtr account = _accountState->account();
|
AccountPtr account = _accountState->account();
|
||||||
|
|
||||||
if (!_requestEtagJob.isNull()) {
|
if (_requestEtagJob) {
|
||||||
qDebug() << Q_FUNC_INFO << remoteUrl().toString() << "has ETag job queued, not trying to sync";
|
qDebug() << Q_FUNC_INFO << remoteUrl().toString() << "has ETag job queued, not trying to sync";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -285,47 +289,15 @@ void Folder::slotRunEtagJob()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool forceSyncIntervalExpired =
|
// Do the ordinary etag check for the root folder and schedule a
|
||||||
quint64(_timeSinceLastSyncDone.elapsed()) > ConfigFile().forceSyncInterval();
|
// sync if it's different.
|
||||||
bool syncAgainAfterFail = _consecutiveFailingSyncs > 0 && _consecutiveFailingSyncs < 3;
|
|
||||||
|
|
||||||
// There are several conditions under which we trigger a full-discovery sync:
|
_requestEtagJob = new RequestEtagJob(account, remotePath(), this);
|
||||||
// * When a suitably long time has passed since the last sync finished
|
_requestEtagJob->setTimeout(60*1000);
|
||||||
// * When the last sync failed (only a couple of times)
|
// check if the etag is different when retrieved
|
||||||
// * When the last sync requested another sync to be done (only a couple of times)
|
QObject::connect(_requestEtagJob, SIGNAL(etagRetreived(QString)), this, SLOT(etagRetreived(QString)));
|
||||||
//
|
FolderMan::instance()->slotScheduleETagJob(alias(), _requestEtagJob);
|
||||||
// Note that the etag check (see below) and the file watcher may also trigger
|
// The _requestEtagJob is auto deleting itself on finish. Our guard pointer _requestEtagJob will then be null.
|
||||||
// syncs.
|
|
||||||
if (forceSyncIntervalExpired
|
|
||||||
|| _forceSyncOnPollTimeout
|
|
||||||
|| syncAgainAfterFail) {
|
|
||||||
|
|
||||||
if (forceSyncIntervalExpired) {
|
|
||||||
qDebug() << "** Force Sync, because it has been " << _timeSinceLastSyncDone.elapsed() << "ms "
|
|
||||||
<< "since the last sync";
|
|
||||||
}
|
|
||||||
if (_forceSyncOnPollTimeout) {
|
|
||||||
qDebug() << "** Force Sync, because it was requested";
|
|
||||||
}
|
|
||||||
if (syncAgainAfterFail) {
|
|
||||||
qDebug() << "** Force Sync, because the last"
|
|
||||||
<< _consecutiveFailingSyncs << "syncs failed, last status:"
|
|
||||||
<< _syncResult.statusString();
|
|
||||||
}
|
|
||||||
_forceSyncOnPollTimeout = false;
|
|
||||||
emit scheduleToSync(this);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Do the ordinary etag check for the root folder and only schedule a real
|
|
||||||
// sync if it's different.
|
|
||||||
|
|
||||||
_requestEtagJob = new RequestEtagJob(account, remotePath(), this);
|
|
||||||
_requestEtagJob->setTimeout(60*1000);
|
|
||||||
// check if the etag is different
|
|
||||||
QObject::connect(_requestEtagJob, SIGNAL(etagRetreived(QString)), this, SLOT(etagRetreived(QString)));
|
|
||||||
FolderMan::instance()->slotScheduleETagJob(alias(), _requestEtagJob);
|
|
||||||
// The _requestEtagJob is auto deleting itself on finish. Our guard pointer _requestEtagJob will then be null.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Folder::etagRetreived(const QString& etag)
|
void Folder::etagRetreived(const QString& etag)
|
||||||
@@ -338,7 +310,7 @@ void Folder::etagRetreived(const QString& etag)
|
|||||||
if (_lastEtag != etag) {
|
if (_lastEtag != etag) {
|
||||||
qDebug() << "* Compare etag with previous etag: last:" << _lastEtag << ", received:" << etag << "-> CHANGED";
|
qDebug() << "* Compare etag with previous etag: last:" << _lastEtag << ", received:" << etag << "-> CHANGED";
|
||||||
_lastEtag = etag;
|
_lastEtag = etag;
|
||||||
emit scheduleToSync(this);
|
slotScheduleThisFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
_accountState->tagLastSuccessfullETagRequest();
|
_accountState->tagLastSuccessfullETagRequest();
|
||||||
@@ -598,7 +570,10 @@ void Folder::slotWatchedPathChanged(const QString& path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
emit watchedFileChangedExternally(path);
|
emit watchedFileChangedExternally(path);
|
||||||
emit scheduleToSync(this);
|
|
||||||
|
// Also schedule this folder for a sync, but only after some delay:
|
||||||
|
// The sync will not upload files that were changed too recently.
|
||||||
|
scheduleThisFolderSoon();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Folder::slotThreadTreeWalkResult(const SyncFileItemVector& items)
|
void Folder::slotThreadTreeWalkResult(const SyncFileItemVector& items)
|
||||||
@@ -758,8 +733,6 @@ void Folder::startSync(const QStringList &pathList)
|
|||||||
|
|
||||||
QMetaObject::invokeMethod(_engine.data(), "startSync", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(_engine.data(), "startSync", Qt::QueuedConnection);
|
||||||
|
|
||||||
// disable events until syncing is done
|
|
||||||
// _watcher->setEventsEnabled(false);
|
|
||||||
emit syncStarted();
|
emit syncStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -823,9 +796,6 @@ void Folder::slotSyncFinished(bool success)
|
|||||||
bubbleUpSyncResult();
|
bubbleUpSyncResult();
|
||||||
|
|
||||||
bool anotherSyncNeeded = _engine->isAnotherSyncNeeded();
|
bool anotherSyncNeeded = _engine->isAnotherSyncNeeded();
|
||||||
// _watcher->setEventsEnabledDelayed(2000);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (_csyncError) {
|
if (_csyncError) {
|
||||||
_syncResult.setStatus(SyncResult::Error);
|
_syncResult.setStatus(SyncResult::Error);
|
||||||
@@ -884,11 +854,10 @@ void Folder::slotSyncFinished(bool success)
|
|||||||
// Maybe force a follow-up sync to take place, but only a couple of times.
|
// Maybe force a follow-up sync to take place, but only a couple of times.
|
||||||
if (anotherSyncNeeded && _consecutiveFollowUpSyncs <= 3)
|
if (anotherSyncNeeded && _consecutiveFollowUpSyncs <= 3)
|
||||||
{
|
{
|
||||||
_forceSyncOnPollTimeout = true;
|
// Sometimes another sync is requested because a local file is still
|
||||||
// We will make sure that the poll timer occurs soon enough.
|
// changing, so wait at least a small amount of time before syncing
|
||||||
// delay 1s, 4s, 9s
|
// the folder again.
|
||||||
int c = _consecutiveFollowUpSyncs;
|
scheduleThisFolderSoon();
|
||||||
QTimer::singleShot(c*c * 1000, this, SLOT(slotRunEtagJob() ));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -969,7 +938,17 @@ void Folder::slotLogPropagationStart()
|
|||||||
_fileLog->logLap("Propagation starts");
|
_fileLog->logLap("Propagation starts");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Folder::slotScheduleThisFolder()
|
||||||
|
{
|
||||||
|
FolderMan::instance()->scheduleFolder(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Folder::scheduleThisFolderSoon()
|
||||||
|
{
|
||||||
|
if (!_scheduleSelfTimer.isActive()) {
|
||||||
|
_scheduleSelfTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction, bool *cancel)
|
void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction, bool *cancel)
|
||||||
{
|
{
|
||||||
@@ -993,10 +972,8 @@ void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction, bool *cancel)
|
|||||||
*cancel = msgBox.clickedButton() == keepBtn;
|
*cancel = msgBox.clickedButton() == keepBtn;
|
||||||
if (*cancel) {
|
if (*cancel) {
|
||||||
wipe();
|
wipe();
|
||||||
// speed up next sync
|
|
||||||
_lastEtag.clear();
|
_lastEtag.clear();
|
||||||
_forceSyncOnPollTimeout = true;
|
slotScheduleThisFolder();
|
||||||
QTimer::singleShot(50, this, SLOT(slotRunEtagJob()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-3
@@ -167,7 +167,7 @@ public:
|
|||||||
* Ignore syncing of hidden files or not. This is defined in the
|
* Ignore syncing of hidden files or not. This is defined in the
|
||||||
* folder definition
|
* folder definition
|
||||||
*/
|
*/
|
||||||
bool ignoreHiddenFiles() const;
|
bool ignoreHiddenFiles();
|
||||||
void setIgnoreHiddenFiles(bool ignore);
|
void setIgnoreHiddenFiles(bool ignore);
|
||||||
|
|
||||||
// Used by the Socket API
|
// Used by the Socket API
|
||||||
@@ -178,6 +178,7 @@ public:
|
|||||||
qint64 msecSinceLastSync() const { return _timeSinceLastSyncDone.elapsed(); }
|
qint64 msecSinceLastSync() const { return _timeSinceLastSyncDone.elapsed(); }
|
||||||
qint64 msecLastSyncDuration() const { return _lastSyncDuration; }
|
qint64 msecLastSyncDuration() const { return _lastSyncDuration; }
|
||||||
int consecutiveFollowUpSyncs() const { return _consecutiveFollowUpSyncs; }
|
int consecutiveFollowUpSyncs() const { return _consecutiveFollowUpSyncs; }
|
||||||
|
int consecutiveFailingSyncs() const { return _consecutiveFailingSyncs; }
|
||||||
|
|
||||||
/// Saves the folder data in the account's settings.
|
/// Saves the folder data in the account's settings.
|
||||||
void saveToSettings() const;
|
void saveToSettings() const;
|
||||||
@@ -194,11 +195,21 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isFileExcludedRelative(const QString& relativePath) const;
|
bool isFileExcludedRelative(const QString& relativePath) const;
|
||||||
|
|
||||||
|
/** Calls schedules this folder on the FolderMan after a short delay.
|
||||||
|
*
|
||||||
|
* This should be used in situations where a sync should be triggered
|
||||||
|
* because a local file was modified. Syncs don't upload files that were
|
||||||
|
* modified too recently, and this delay ensures the modification is
|
||||||
|
* far enough in the past.
|
||||||
|
*
|
||||||
|
* The delay doesn't reset with subsequent calls.
|
||||||
|
*/
|
||||||
|
void scheduleThisFolderSoon();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void syncStateChange();
|
void syncStateChange();
|
||||||
void syncStarted();
|
void syncStarted();
|
||||||
void syncFinished(const SyncResult &result);
|
void syncFinished(const SyncResult &result);
|
||||||
void scheduleToSync(Folder*);
|
|
||||||
void progressInfo(const ProgressInfo& progress);
|
void progressInfo(const ProgressInfo& progress);
|
||||||
void newBigFolderDiscovered(const QString &); // A new folder bigger than the threshold was discovered
|
void newBigFolderDiscovered(const QString &); // A new folder bigger than the threshold was discovered
|
||||||
void syncPausedChanged(Folder*, bool paused);
|
void syncPausedChanged(Folder*, bool paused);
|
||||||
@@ -266,6 +277,11 @@ private slots:
|
|||||||
|
|
||||||
void slotLogPropagationStart();
|
void slotLogPropagationStart();
|
||||||
|
|
||||||
|
/** Adds this folder to the list of scheduled folders in the
|
||||||
|
* FolderMan.
|
||||||
|
*/
|
||||||
|
void slotScheduleThisFolder();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool setIgnoredFiles();
|
bool setIgnoredFiles();
|
||||||
|
|
||||||
@@ -302,7 +318,6 @@ private:
|
|||||||
QElapsedTimer _timeSinceLastSyncDone;
|
QElapsedTimer _timeSinceLastSyncDone;
|
||||||
QElapsedTimer _timeSinceLastSyncStart;
|
QElapsedTimer _timeSinceLastSyncStart;
|
||||||
qint64 _lastSyncDuration;
|
qint64 _lastSyncDuration;
|
||||||
bool _forceSyncOnPollTimeout;
|
|
||||||
|
|
||||||
/// The number of syncs that failed in a row.
|
/// The number of syncs that failed in a row.
|
||||||
/// Reset when a sync is successful.
|
/// Reset when a sync is successful.
|
||||||
@@ -317,6 +332,8 @@ private:
|
|||||||
ClientProxy _clientProxy;
|
ClientProxy _clientProxy;
|
||||||
|
|
||||||
QScopedPointer<SyncRunFileLog> _fileLog;
|
QScopedPointer<SyncRunFileLog> _fileLog;
|
||||||
|
|
||||||
|
QTimer _scheduleSelfTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+108
-52
@@ -64,11 +64,17 @@ FolderMan::FolderMan(QObject *parent) :
|
|||||||
connect(&_startScheduledSyncTimer, SIGNAL(timeout()),
|
connect(&_startScheduledSyncTimer, SIGNAL(timeout()),
|
||||||
SLOT(slotStartScheduledFolderSync()));
|
SLOT(slotStartScheduledFolderSync()));
|
||||||
|
|
||||||
|
_timeScheduler.setInterval(5000);
|
||||||
|
_timeScheduler.setSingleShot(false);
|
||||||
|
connect(&_timeScheduler, SIGNAL(timeout()),
|
||||||
|
SLOT(slotScheduleFolderByTime()));
|
||||||
|
_timeScheduler.start();
|
||||||
|
|
||||||
connect(AccountManager::instance(), SIGNAL(accountRemoved(AccountState*)),
|
connect(AccountManager::instance(), SIGNAL(accountRemoved(AccountState*)),
|
||||||
SLOT(slotRemoveFoldersForAccount(AccountState*)));
|
SLOT(slotRemoveFoldersForAccount(AccountState*)));
|
||||||
|
|
||||||
connect(_lockWatcher.data(), SIGNAL(fileUnlocked(QString)),
|
connect(_lockWatcher.data(), SIGNAL(fileUnlocked(QString)),
|
||||||
SLOT(slotScheduleFolderOwningFile(QString)));
|
SLOT(slotWatchedFileUnlocked(QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
FolderMan *FolderMan::instance()
|
FolderMan *FolderMan::instance()
|
||||||
@@ -100,8 +106,6 @@ void FolderMan::unloadFolder( Folder *f )
|
|||||||
}
|
}
|
||||||
_folderMap.remove( f->alias() );
|
_folderMap.remove( f->alias() );
|
||||||
|
|
||||||
disconnect(f, SIGNAL(scheduleToSync(Folder*)),
|
|
||||||
this, SLOT(slotScheduleSync(Folder*)));
|
|
||||||
disconnect(f, SIGNAL(syncStarted()),
|
disconnect(f, SIGNAL(syncStarted()),
|
||||||
this, SLOT(slotFolderSyncStarted()));
|
this, SLOT(slotFolderSyncStarted()));
|
||||||
disconnect(f, SIGNAL(syncFinished(SyncResult)),
|
disconnect(f, SIGNAL(syncFinished(SyncResult)),
|
||||||
@@ -131,7 +135,7 @@ int FolderMan::unloadAndDeleteAllFolders()
|
|||||||
}
|
}
|
||||||
_lastSyncFolder = 0;
|
_lastSyncFolder = 0;
|
||||||
_currentSyncFolder = 0;
|
_currentSyncFolder = 0;
|
||||||
_scheduleQueue.clear();
|
_scheduledFolders.clear();
|
||||||
emit scheduleQueueChanged();
|
emit scheduleQueueChanged();
|
||||||
|
|
||||||
Q_ASSERT(_folderMap.count() == 0);
|
Q_ASSERT(_folderMap.count() == 0);
|
||||||
@@ -187,7 +191,7 @@ int FolderMan::setupFolders()
|
|||||||
{
|
{
|
||||||
unloadAndDeleteAllFolders();
|
unloadAndDeleteAllFolders();
|
||||||
|
|
||||||
auto settings = Account::settingsWithGroup(QLatin1String("Accounts"));
|
auto settings = Utility::settingsWithGroup(QLatin1String("Accounts"));
|
||||||
const auto accountsWithSettings = settings->childGroups();
|
const auto accountsWithSettings = settings->childGroups();
|
||||||
if (accountsWithSettings.isEmpty()) {
|
if (accountsWithSettings.isEmpty()) {
|
||||||
int r = setupFoldersMigration();
|
int r = setupFoldersMigration();
|
||||||
@@ -211,7 +215,7 @@ int FolderMan::setupFolders()
|
|||||||
if (FolderDefinition::load(*settings, folderAlias, &folderDefinition)) {
|
if (FolderDefinition::load(*settings, folderAlias, &folderDefinition)) {
|
||||||
Folder* f = addFolderInternal(std::move(folderDefinition), account.data());
|
Folder* f = addFolderInternal(std::move(folderDefinition), account.data());
|
||||||
if (f) {
|
if (f) {
|
||||||
slotScheduleSync(f);
|
scheduleFolder(f);
|
||||||
emit folderSyncStateChange(f);
|
emit folderSyncStateChange(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,7 +248,7 @@ int FolderMan::setupFoldersMigration()
|
|||||||
foreach ( const QString& alias, list ) {
|
foreach ( const QString& alias, list ) {
|
||||||
Folder *f = setupFolderFromOldConfigFile( alias, accountState );
|
Folder *f = setupFolderFromOldConfigFile( alias, accountState );
|
||||||
if( f ) {
|
if( f ) {
|
||||||
slotScheduleSync(f);
|
scheduleFolder(f);
|
||||||
emit folderSyncStateChange(f);
|
emit folderSyncStateChange(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -334,6 +338,7 @@ QString FolderMan::unescapeAlias( const QString& alias )
|
|||||||
|
|
||||||
// filename is the name of the file only, it does not include
|
// filename is the name of the file only, it does not include
|
||||||
// the configuration directory path
|
// the configuration directory path
|
||||||
|
// WARNING: Do not remove this code, it is used for predefined/automated deployments (2016)
|
||||||
Folder* FolderMan::setupFolderFromOldConfigFile(const QString &file, AccountState *accountState )
|
Folder* FolderMan::setupFolderFromOldConfigFile(const QString &file, AccountState *accountState )
|
||||||
{
|
{
|
||||||
Folder *folder = 0;
|
Folder *folder = 0;
|
||||||
@@ -404,6 +409,8 @@ Folder* FolderMan::setupFolderFromOldConfigFile(const QString &file, AccountStat
|
|||||||
//migrate settings
|
//migrate settings
|
||||||
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, blackList);
|
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, blackList);
|
||||||
settings.remove(QLatin1String("blackList"));
|
settings.remove(QLatin1String("blackList"));
|
||||||
|
// FIXME: If you remove this codepath, you need to provide another way to do
|
||||||
|
// this via theme.h or the normal FolderMan::setupFolders
|
||||||
}
|
}
|
||||||
|
|
||||||
folder->saveToSettings();
|
folder->saveToSettings();
|
||||||
@@ -422,7 +429,7 @@ void FolderMan::slotFolderSyncPaused( Folder *f, bool paused )
|
|||||||
|
|
||||||
if (!paused) {
|
if (!paused) {
|
||||||
_disabledFolders.remove(f);
|
_disabledFolders.remove(f);
|
||||||
slotScheduleSync(f);
|
scheduleFolder(f);
|
||||||
} else {
|
} else {
|
||||||
_disabledFolders.insert(f);
|
_disabledFolders.insert(f);
|
||||||
}
|
}
|
||||||
@@ -462,11 +469,11 @@ Folder *FolderMan::folder( const QString& alias )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FolderMan::slotScheduleAllFolders()
|
void FolderMan::scheduleAllFolders()
|
||||||
{
|
{
|
||||||
foreach( Folder *f, _folderMap.values() ) {
|
foreach( Folder *f, _folderMap.values() ) {
|
||||||
if (f && f->canSync()) {
|
if (f && f->canSync()) {
|
||||||
slotScheduleSync( f );
|
scheduleFolder( f );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -486,7 +493,7 @@ void FolderMan::slotSyncOnceFileUnlocks(const QString& path)
|
|||||||
* if a folder wants to be synced, it calls this slot and is added
|
* if a folder wants to be synced, it calls this slot and is added
|
||||||
* to the queue. The slot to actually start a sync is called afterwards.
|
* to the queue. The slot to actually start a sync is called afterwards.
|
||||||
*/
|
*/
|
||||||
void FolderMan::slotScheduleSync( Folder *f )
|
void FolderMan::scheduleFolder( Folder *f )
|
||||||
{
|
{
|
||||||
if( !f ) {
|
if( !f ) {
|
||||||
qWarning() << "slotScheduleSync called with null folder";
|
qWarning() << "slotScheduleSync called with null folder";
|
||||||
@@ -496,7 +503,7 @@ void FolderMan::slotScheduleSync( Folder *f )
|
|||||||
|
|
||||||
qDebug() << "Schedule folder " << alias << " to sync!";
|
qDebug() << "Schedule folder " << alias << " to sync!";
|
||||||
|
|
||||||
if( ! _scheduleQueue.contains(f) ) {
|
if( ! _scheduledFolders.contains(f) ) {
|
||||||
if( !f->canSync() ) {
|
if( !f->canSync() ) {
|
||||||
qDebug() << "Folder is not ready to sync, not scheduled!";
|
qDebug() << "Folder is not ready to sync, not scheduled!";
|
||||||
_socketApi->slotUpdateFolderView(f);
|
_socketApi->slotUpdateFolderView(f);
|
||||||
@@ -504,7 +511,7 @@ void FolderMan::slotScheduleSync( Folder *f )
|
|||||||
}
|
}
|
||||||
f->prepareToSync();
|
f->prepareToSync();
|
||||||
emit folderSyncStateChange(f);
|
emit folderSyncStateChange(f);
|
||||||
_scheduleQueue.enqueue(f);
|
_scheduledFolders.enqueue(f);
|
||||||
emit scheduleQueueChanged();
|
emit scheduleQueueChanged();
|
||||||
} else {
|
} else {
|
||||||
qDebug() << " II> Sync for folder " << alias << " already scheduled, do not enqueue!";
|
qDebug() << " II> Sync for folder " << alias << " already scheduled, do not enqueue!";
|
||||||
@@ -513,6 +520,26 @@ void FolderMan::slotScheduleSync( Folder *f )
|
|||||||
startScheduledSyncSoon();
|
startScheduledSyncSoon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FolderMan::scheduleFolderNext(Folder* f)
|
||||||
|
{
|
||||||
|
auto alias = f->alias();
|
||||||
|
qDebug() << "Schedule folder " << alias << " to sync! Front-of-queue.";
|
||||||
|
|
||||||
|
if( !f->canSync() ) {
|
||||||
|
qDebug() << "Folder is not ready to sync, not scheduled!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduledFolders.removeAll(f);
|
||||||
|
|
||||||
|
f->prepareToSync();
|
||||||
|
emit folderSyncStateChange(f);
|
||||||
|
_scheduledFolders.prepend(f);
|
||||||
|
emit scheduleQueueChanged();
|
||||||
|
|
||||||
|
startScheduledSyncSoon();
|
||||||
|
}
|
||||||
|
|
||||||
void FolderMan::slotScheduleETagJob(const QString &/*alias*/, RequestEtagJob *job)
|
void FolderMan::slotScheduleETagJob(const QString &/*alias*/, RequestEtagJob *job)
|
||||||
{
|
{
|
||||||
QObject::connect(job, SIGNAL(destroyed(QObject*)), this, SLOT(slotEtagJobDestroyed(QObject*)));
|
QObject::connect(job, SIGNAL(destroyed(QObject*)), this, SLOT(slotEtagJobDestroyed(QObject*)));
|
||||||
@@ -568,7 +595,7 @@ void FolderMan::slotAccountStateChanged()
|
|||||||
if (f
|
if (f
|
||||||
&& f->canSync()
|
&& f->canSync()
|
||||||
&& f->accountState() == accountState) {
|
&& f->accountState() == accountState) {
|
||||||
slotScheduleSync(f);
|
scheduleFolder(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -580,7 +607,7 @@ void FolderMan::slotAccountStateChanged()
|
|||||||
_currentSyncFolder->slotTerminateSync();
|
_currentSyncFolder->slotTerminateSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutableListIterator<Folder*> it(_scheduleQueue);
|
QMutableListIterator<Folder*> it(_scheduledFolders);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
Folder* f = it.next();
|
Folder* f = it.next();
|
||||||
if (f->accountState() == accountState) {
|
if (f->accountState() == accountState) {
|
||||||
@@ -595,7 +622,7 @@ void FolderMan::slotAccountStateChanged()
|
|||||||
// this is not the same as Pause and Resume of folders.
|
// this is not the same as Pause and Resume of folders.
|
||||||
void FolderMan::setSyncEnabled( bool enabled )
|
void FolderMan::setSyncEnabled( bool enabled )
|
||||||
{
|
{
|
||||||
if (!_syncEnabled && enabled && !_scheduleQueue.isEmpty()) {
|
if (!_syncEnabled && enabled && !_scheduledFolders.isEmpty()) {
|
||||||
// We have things in our queue that were waiting for the connection to come back on.
|
// We have things in our queue that were waiting for the connection to come back on.
|
||||||
startScheduledSyncSoon();
|
startScheduledSyncSoon();
|
||||||
}
|
}
|
||||||
@@ -604,19 +631,19 @@ void FolderMan::setSyncEnabled( bool enabled )
|
|||||||
emit( folderSyncStateChange(0) );
|
emit( folderSyncStateChange(0) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void FolderMan::startScheduledSyncSoon(qint64 msMinimumDelay)
|
void FolderMan::startScheduledSyncSoon()
|
||||||
{
|
{
|
||||||
if (_startScheduledSyncTimer.isActive()) {
|
if (_startScheduledSyncTimer.isActive()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_scheduleQueue.empty()) {
|
if (_scheduledFolders.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_currentSyncFolder) {
|
if (_currentSyncFolder) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 msDelay = msMinimumDelay;
|
qint64 msDelay = 100; // 100ms minimum delay
|
||||||
qint64 msSinceLastSync = 0;
|
qint64 msSinceLastSync = 0;
|
||||||
|
|
||||||
// Require a pause based on the duration of the last sync run.
|
// Require a pause based on the duration of the last sync run.
|
||||||
@@ -631,15 +658,6 @@ void FolderMan::startScheduledSyncSoon(qint64 msMinimumDelay)
|
|||||||
msDelay = qMax(msDelay, pause);
|
msDelay = qMax(msDelay, pause);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Punish consecutive follow-up syncs with longer delays.
|
|
||||||
if (Folder* nextFolder = _scheduleQueue.head()) {
|
|
||||||
int followUps = nextFolder->consecutiveFollowUpSyncs();
|
|
||||||
if (followUps >= 2) {
|
|
||||||
// This is okay due to the 1min maximum delay limit below.
|
|
||||||
msDelay *= qPow(followUps, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delays beyond one minute seem too big, particularly since there
|
// Delays beyond one minute seem too big, particularly since there
|
||||||
// could be things later in the queue that shouldn't be punished by a
|
// could be things later in the queue that shouldn't be punished by a
|
||||||
// long delay!
|
// long delay!
|
||||||
@@ -648,11 +666,7 @@ void FolderMan::startScheduledSyncSoon(qint64 msMinimumDelay)
|
|||||||
// Time since the last sync run counts against the delay
|
// Time since the last sync run counts against the delay
|
||||||
msDelay = qMax(1ll, msDelay - msSinceLastSync);
|
msDelay = qMax(1ll, msDelay - msSinceLastSync);
|
||||||
|
|
||||||
// A minimum of delay here is essential as the sync will not upload
|
qDebug() << "Starting the next scheduled sync in" << (msDelay/1000) << "seconds";
|
||||||
// files that were changed too recently.
|
|
||||||
msDelay = qMax(SyncEngine::minimumFileAgeForUpload, msDelay);
|
|
||||||
|
|
||||||
qDebug() << "Scheduling a sync in" << (msDelay/1000) << "seconds";
|
|
||||||
_startScheduledSyncTimer.start(msDelay);
|
_startScheduledSyncTimer.start(msDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,18 +687,17 @@ void FolderMan::slotStartScheduledFolderSync()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "XX slotScheduleFolderSync: folderQueue size: " << _scheduleQueue.count();
|
qDebug() << "XX slotScheduleFolderSync: folderQueue size: " << _scheduledFolders.count();
|
||||||
if( _scheduleQueue.isEmpty() ) {
|
if( _scheduledFolders.isEmpty() ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the first folder in the queue that can be synced.
|
// Find the first folder in the queue that can be synced.
|
||||||
Folder* f = 0;
|
Folder* folder = 0;
|
||||||
while( !_scheduleQueue.isEmpty() ) {
|
while( !_scheduledFolders.isEmpty() ) {
|
||||||
f = _scheduleQueue.dequeue();
|
Folder* g = _scheduledFolders.dequeue();
|
||||||
Q_ASSERT(f);
|
if( g->canSync() ) {
|
||||||
|
folder = g;
|
||||||
if( f->canSync() ) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -692,9 +705,9 @@ void FolderMan::slotStartScheduledFolderSync()
|
|||||||
emit scheduleQueueChanged();
|
emit scheduleQueueChanged();
|
||||||
|
|
||||||
// Start syncing this folder!
|
// Start syncing this folder!
|
||||||
if( f ) {
|
if( folder ) {
|
||||||
_currentSyncFolder = f;
|
_currentSyncFolder = folder;
|
||||||
f->startSync( QStringList() );
|
folder->startSync( QStringList() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,7 +724,7 @@ void FolderMan::slotEtagPollTimerTimeout()
|
|||||||
if (_currentSyncFolder == f) {
|
if (_currentSyncFolder == f) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (_scheduleQueue.contains(f)) {
|
if (_scheduledFolders.contains(f)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (_disabledFolders.contains(f)) {
|
if (_disabledFolders.contains(f)) {
|
||||||
@@ -740,7 +753,7 @@ void FolderMan::slotRemoveFoldersForAccount(AccountState* accountState)
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach (const auto &f, foldersToRemove) {
|
foreach (const auto &f, foldersToRemove) {
|
||||||
slotRemoveFolder(f);
|
removeFolder(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,10 +779,54 @@ void FolderMan::slotServerVersionChanged(Account *account)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FolderMan::slotScheduleFolderOwningFile(const QString& path)
|
void FolderMan::slotWatchedFileUnlocked(const QString& path)
|
||||||
{
|
{
|
||||||
if (Folder* f = folderForPath(path)) {
|
if (Folder* f = folderForPath(path)) {
|
||||||
slotScheduleSync(f);
|
f->scheduleThisFolderSoon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FolderMan::slotScheduleFolderByTime()
|
||||||
|
{
|
||||||
|
foreach (auto& f, _folderMap) {
|
||||||
|
// Never schedule if syncing is disabled or when we're currently
|
||||||
|
// querying the server for etags
|
||||||
|
if (!f->canSync() || f->etagJob()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto msecsSinceSync = f->msecSinceLastSync();
|
||||||
|
|
||||||
|
// Possibly it's just time for a new sync run
|
||||||
|
bool forceSyncIntervalExpired =
|
||||||
|
quint64(msecsSinceSync) > ConfigFile().forceSyncInterval();
|
||||||
|
if (forceSyncIntervalExpired) {
|
||||||
|
qDebug() << "** scheduling folder" << f->alias()
|
||||||
|
<< "because it has been" << msecsSinceSync << "ms "
|
||||||
|
<< "since the last sync";
|
||||||
|
|
||||||
|
scheduleFolder(f);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retry a couple of times after failure
|
||||||
|
bool syncAgainAfterFail = f->consecutiveFailingSyncs() > 0 && f->consecutiveFailingSyncs() < 3;
|
||||||
|
qint64 syncAgainAfterFailDelay = 10 * 1000; // 10s for the first retry-after-fail
|
||||||
|
if (f->consecutiveFailingSyncs() > 1)
|
||||||
|
syncAgainAfterFailDelay = 60 * 1000; // 60s for each further attempt
|
||||||
|
if (syncAgainAfterFail
|
||||||
|
&& msecsSinceSync > syncAgainAfterFailDelay) {
|
||||||
|
qDebug() << "** scheduling folder" << f->alias()
|
||||||
|
<< "because the last"
|
||||||
|
<< f->consecutiveFailingSyncs() << "syncs failed, last status:"
|
||||||
|
<< f->syncResult().statusString()
|
||||||
|
<< "time since last sync:" << msecsSinceSync;
|
||||||
|
|
||||||
|
scheduleFolder(f);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do we want to retry failing syncs or another-sync-needed runs more often?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,7 +884,6 @@ Folder* FolderMan::addFolderInternal(FolderDefinition folderDefinition, AccountS
|
|||||||
}
|
}
|
||||||
|
|
||||||
// See matching disconnects in unloadFolder().
|
// See matching disconnects in unloadFolder().
|
||||||
connect(folder, SIGNAL(scheduleToSync(Folder*)), SLOT(slotScheduleSync(Folder*)));
|
|
||||||
connect(folder, SIGNAL(syncStarted()), SLOT(slotFolderSyncStarted()));
|
connect(folder, SIGNAL(syncStarted()), SLOT(slotFolderSyncStarted()));
|
||||||
connect(folder, SIGNAL(syncFinished(SyncResult)), SLOT(slotFolderSyncFinished(SyncResult)));
|
connect(folder, SIGNAL(syncFinished(SyncResult)), SLOT(slotFolderSyncFinished(SyncResult)));
|
||||||
connect(folder, SIGNAL(syncStateChange()), SLOT(slotForwardFolderSyncStateChange()));
|
connect(folder, SIGNAL(syncStateChange()), SLOT(slotForwardFolderSyncStateChange()));
|
||||||
@@ -880,7 +936,7 @@ QStringList FolderMan::findFileInLocalFolders( const QString& relPath, const Acc
|
|||||||
return re;
|
return re;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FolderMan::slotRemoveFolder( Folder *f )
|
void FolderMan::removeFolder( Folder *f )
|
||||||
{
|
{
|
||||||
if( !f ) {
|
if( !f ) {
|
||||||
qWarning() << "!! Can not remove null folder";
|
qWarning() << "!! Can not remove null folder";
|
||||||
@@ -895,7 +951,7 @@ void FolderMan::slotRemoveFolder( Folder *f )
|
|||||||
terminateSyncProcess();
|
terminateSyncProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_scheduleQueue.removeAll(f) > 0) {
|
if (_scheduledFolders.removeAll(f) > 0) {
|
||||||
emit scheduleQueueChanged();
|
emit scheduleQueueChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1262,7 +1318,7 @@ void FolderMan::setIgnoreHiddenFiles(bool ignore)
|
|||||||
|
|
||||||
QQueue<Folder*> FolderMan::scheduleQueue() const
|
QQueue<Folder*> FolderMan::scheduleQueue() const
|
||||||
{
|
{
|
||||||
return _scheduleQueue;
|
return _scheduledFolders;
|
||||||
}
|
}
|
||||||
|
|
||||||
Folder *FolderMan::currentSyncFolder() const
|
Folder *FolderMan::currentSyncFolder() const
|
||||||
|
|||||||
+96
-41
@@ -37,6 +37,26 @@ class LockWatcher;
|
|||||||
/**
|
/**
|
||||||
* @brief The FolderMan class
|
* @brief The FolderMan class
|
||||||
* @ingroup gui
|
* @ingroup gui
|
||||||
|
*
|
||||||
|
* The FolderMan knows about all loaded folders and is responsible for
|
||||||
|
* scheduling them when necessary.
|
||||||
|
*
|
||||||
|
* A folder is scheduled if:
|
||||||
|
* - The configured force-sync-interval has expired
|
||||||
|
* (_timeScheduler and slotScheduleFolderByTime())
|
||||||
|
*
|
||||||
|
* - A folder watcher receives a notification about a file change
|
||||||
|
* (_folderWatchers and Folder::slotWatchedPathChanged())
|
||||||
|
*
|
||||||
|
* - The folder etag on the server has changed
|
||||||
|
* (_etagPollTimer)
|
||||||
|
*
|
||||||
|
* - The locks of a monitored file are released
|
||||||
|
* (_lockWatcher and slotWatchedFileUnlocked())
|
||||||
|
*
|
||||||
|
* - There was a sync error or a follow-up sync is requested
|
||||||
|
* (_timeScheduler and slotScheduleFolderByTime()
|
||||||
|
* and Folder::slotSyncFinished())
|
||||||
*/
|
*/
|
||||||
class FolderMan : public QObject
|
class FolderMan : public QObject
|
||||||
{
|
{
|
||||||
@@ -54,6 +74,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
Folder* addFolder(AccountState* accountState, const FolderDefinition& folderDefinition);
|
Folder* addFolder(AccountState* accountState, const FolderDefinition& folderDefinition);
|
||||||
|
|
||||||
|
/** Removes a folder */
|
||||||
|
void removeFolder( Folder* );
|
||||||
|
|
||||||
/** Returns the folder which the file or directory stored in path is in */
|
/** Returns the folder which the file or directory stored in path is in */
|
||||||
Folder* folderForPath(const QString& path);
|
Folder* folderForPath(const QString& path);
|
||||||
|
|
||||||
@@ -126,6 +149,34 @@ public:
|
|||||||
*/
|
*/
|
||||||
Folder* currentSyncFolder() const;
|
Folder* currentSyncFolder() const;
|
||||||
|
|
||||||
|
/** Removes all folders */
|
||||||
|
int unloadAndDeleteAllFolders();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If enabled is set to false, no new folders will start to sync.
|
||||||
|
* The current one will finish.
|
||||||
|
*/
|
||||||
|
void setSyncEnabled( bool );
|
||||||
|
|
||||||
|
/** Queues a folder for syncing. */
|
||||||
|
void scheduleFolder(Folder*);
|
||||||
|
|
||||||
|
/** Puts a folder in the very front of the queue. */
|
||||||
|
void scheduleFolderNext(Folder*);
|
||||||
|
|
||||||
|
/** Queues all folders for syncing. */
|
||||||
|
void scheduleAllFolders();
|
||||||
|
|
||||||
|
void setDirtyProxy(bool value = true);
|
||||||
|
void setDirtyNetworkLimits();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terminates the current folder sync.
|
||||||
|
*
|
||||||
|
* It does not switch the folder to paused state.
|
||||||
|
*/
|
||||||
|
void terminateSyncProcess();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
* signal to indicate a folder has changed its sync state.
|
* signal to indicate a folder has changed its sync state.
|
||||||
@@ -139,41 +190,12 @@ signals:
|
|||||||
*/
|
*/
|
||||||
void scheduleQueueChanged();
|
void scheduleQueueChanged();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted whenever the list of configured folders changes.
|
||||||
|
*/
|
||||||
void folderListChanged(const Folder::Map &);
|
void folderListChanged(const Folder::Map &);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void slotRemoveFolder( Folder* );
|
|
||||||
void slotFolderSyncPaused(Folder *, bool paused);
|
|
||||||
void slotFolderCanSyncChanged();
|
|
||||||
|
|
||||||
void slotFolderSyncStarted();
|
|
||||||
void slotFolderSyncFinished( const SyncResult& );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Terminates the current folder sync.
|
|
||||||
*
|
|
||||||
* It does not switch the folder to paused state.
|
|
||||||
*/
|
|
||||||
void terminateSyncProcess();
|
|
||||||
|
|
||||||
/* delete all folder objects */
|
|
||||||
int unloadAndDeleteAllFolders();
|
|
||||||
|
|
||||||
// if enabled is set to false, no new folders will start to sync.
|
|
||||||
// the current one will finish.
|
|
||||||
void setSyncEnabled( bool );
|
|
||||||
|
|
||||||
void slotScheduleAllFolders();
|
|
||||||
|
|
||||||
void setDirtyProxy(bool value = true);
|
|
||||||
void setDirtyNetworkLimits();
|
|
||||||
|
|
||||||
// slot to add a folder to the syncing queue
|
|
||||||
void slotScheduleSync(Folder*);
|
|
||||||
// slot to schedule an ETag job
|
|
||||||
void slotScheduleETagJob ( const QString &alias, RequestEtagJob *job);
|
|
||||||
void slotEtagJobDestroyed (QObject*);
|
|
||||||
void slotRunOneEtagJob();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules folders of newly connected accounts, terminates and
|
* Schedules folders of newly connected accounts, terminates and
|
||||||
@@ -190,10 +212,22 @@ public slots:
|
|||||||
* Triggers a sync run once the lock on the given file is removed.
|
* Triggers a sync run once the lock on the given file is removed.
|
||||||
*
|
*
|
||||||
* Automatically detemines the folder that's responsible for the file.
|
* Automatically detemines the folder that's responsible for the file.
|
||||||
|
* See slotWatchedFileUnlocked().
|
||||||
*/
|
*/
|
||||||
void slotSyncOnceFileUnlocks(const QString& path);
|
void slotSyncOnceFileUnlocks(const QString& path);
|
||||||
|
|
||||||
|
// slot to schedule an ETag job (from Folder only)
|
||||||
|
void slotScheduleETagJob ( const QString &alias, RequestEtagJob *job);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void slotFolderSyncPaused(Folder *, bool paused);
|
||||||
|
void slotFolderCanSyncChanged();
|
||||||
|
void slotFolderSyncStarted();
|
||||||
|
void slotFolderSyncFinished( const SyncResult& );
|
||||||
|
|
||||||
|
void slotRunOneEtagJob();
|
||||||
|
void slotEtagJobDestroyed (QObject*);
|
||||||
|
|
||||||
// slot to take the next folder from queue and start syncing.
|
// slot to take the next folder from queue and start syncing.
|
||||||
void slotStartScheduledFolderSync();
|
void slotStartScheduledFolderSync();
|
||||||
void slotEtagPollTimerTimeout();
|
void slotEtagPollTimerTimeout();
|
||||||
@@ -207,12 +241,23 @@ private slots:
|
|||||||
void slotServerVersionChanged(Account* account);
|
void slotServerVersionChanged(Account* account);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules the folder for synchronization that contains
|
* A file whose locks were being monitored has become unlocked.
|
||||||
|
*
|
||||||
|
* This schedules the folder for synchronization that contains
|
||||||
* the file with the given path.
|
* the file with the given path.
|
||||||
*/
|
*/
|
||||||
void slotScheduleFolderOwningFile(const QString& path);
|
void slotWatchedFileUnlocked(const QString& path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules folders whose time to sync has come.
|
||||||
|
*
|
||||||
|
* Either because a long time has passed since the last sync or
|
||||||
|
* because of previous failures.
|
||||||
|
*/
|
||||||
|
void slotScheduleFolderByTime();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** Adds a new folder, does not add it to the account settings and
|
/** Adds a new folder, does not add it to the account settings and
|
||||||
* does not set an account on the new folder.
|
* does not set an account on the new folder.
|
||||||
*/
|
*/
|
||||||
@@ -222,7 +267,7 @@ private:
|
|||||||
void unloadFolder( Folder * );
|
void unloadFolder( Folder * );
|
||||||
|
|
||||||
/** Will start a sync after a bit of delay. */
|
/** Will start a sync after a bit of delay. */
|
||||||
void startScheduledSyncSoon(qint64 msMinimumDelay = 0);
|
void startScheduledSyncSoon();
|
||||||
|
|
||||||
// finds all folder configuration files
|
// finds all folder configuration files
|
||||||
// and create the folders
|
// and create the folders
|
||||||
@@ -238,19 +283,29 @@ private:
|
|||||||
Folder *_currentSyncFolder;
|
Folder *_currentSyncFolder;
|
||||||
QPointer<Folder> _lastSyncFolder;
|
QPointer<Folder> _lastSyncFolder;
|
||||||
bool _syncEnabled;
|
bool _syncEnabled;
|
||||||
QTimer _etagPollTimer;
|
|
||||||
QPointer<RequestEtagJob> _currentEtagJob; // alias of Folder running the current RequestEtagJob
|
|
||||||
|
|
||||||
|
/// Watching for file changes in folders
|
||||||
QMap<QString, FolderWatcher*> _folderWatchers;
|
QMap<QString, FolderWatcher*> _folderWatchers;
|
||||||
|
|
||||||
|
/// Starts regular etag query jobs
|
||||||
|
QTimer _etagPollTimer;
|
||||||
|
/// The currently running etag query
|
||||||
|
QPointer<RequestEtagJob> _currentEtagJob;
|
||||||
|
|
||||||
|
/// Watches files that couldn't be synced due to locks
|
||||||
QScopedPointer<LockWatcher> _lockWatcher;
|
QScopedPointer<LockWatcher> _lockWatcher;
|
||||||
QScopedPointer<SocketApi> _socketApi;
|
|
||||||
|
|
||||||
/** The aliases of folders that shall be synced. */
|
/// Occasionally schedules folders
|
||||||
QQueue<Folder*> _scheduleQueue;
|
QTimer _timeScheduler;
|
||||||
|
|
||||||
/** When the timer expires one of the scheduled syncs will be started. */
|
/// Scheduled folders that should be synced as soon as possible
|
||||||
|
QQueue<Folder*> _scheduledFolders;
|
||||||
|
|
||||||
|
/// Picks the next scheduled folder and starts the sync
|
||||||
QTimer _startScheduledSyncTimer;
|
QTimer _startScheduledSyncTimer;
|
||||||
|
|
||||||
|
QScopedPointer<SocketApi> _socketApi;
|
||||||
|
|
||||||
bool _appRestartRequired;
|
bool _appRestartRequired;
|
||||||
|
|
||||||
static FolderMan *_instance;
|
static FolderMan *_instance;
|
||||||
|
|||||||
@@ -295,7 +295,11 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
|||||||
pBRect.setHeight(barHeight);
|
pBRect.setHeight(barHeight);
|
||||||
pBRect.setWidth( overallWidth - 2 * margin );
|
pBRect.setWidth( overallWidth - 2 * margin );
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
|
||||||
QStyleOptionProgressBarV2 pBarOpt;
|
QStyleOptionProgressBarV2 pBarOpt;
|
||||||
|
#else
|
||||||
|
QStyleOptionProgressBar pBarOpt;
|
||||||
|
#endif
|
||||||
|
|
||||||
pBarOpt.state = option.state | QStyle::State_Horizontal;
|
pBarOpt.state = option.state | QStyle::State_Horizontal;
|
||||||
pBarOpt.minimum = 0;
|
pBarOpt.minimum = 0;
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ FolderStatusModel::FolderStatusModel(QObject *parent)
|
|||||||
FolderStatusModel::~FolderStatusModel()
|
FolderStatusModel::~FolderStatusModel()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
static bool sortByFolderHeader(const FolderStatusModel::SubFolderInfo& lhs, const FolderStatusModel::SubFolderInfo& rhs)
|
||||||
|
{
|
||||||
|
return QString::compare(lhs._folder->shortGuiRemotePathOrAppName(),
|
||||||
|
rhs._folder->shortGuiRemotePathOrAppName(),
|
||||||
|
Qt::CaseInsensitive) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
void FolderStatusModel::setAccountState(const AccountState* accountState)
|
void FolderStatusModel::setAccountState(const AccountState* accountState)
|
||||||
{
|
{
|
||||||
@@ -58,7 +64,6 @@ void FolderStatusModel::setAccountState(const AccountState* accountState)
|
|||||||
if (f->accountState() != accountState)
|
if (f->accountState() != accountState)
|
||||||
continue;
|
continue;
|
||||||
SubFolderInfo info;
|
SubFolderInfo info;
|
||||||
info._pathIdx << _folders.size();
|
|
||||||
info._name = f->alias();
|
info._name = f->alias();
|
||||||
info._path = "/";
|
info._path = "/";
|
||||||
info._folder = f;
|
info._folder = f;
|
||||||
@@ -69,6 +74,14 @@ void FolderStatusModel::setAccountState(const AccountState* accountState)
|
|||||||
connect(f, SIGNAL(newBigFolderDiscovered(QString)), this, SLOT(slotNewBigFolder()), Qt::UniqueConnection);
|
connect(f, SIGNAL(newBigFolderDiscovered(QString)), this, SLOT(slotNewBigFolder()), Qt::UniqueConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort by header text
|
||||||
|
qSort(_folders.begin(), _folders.end(), sortByFolderHeader);
|
||||||
|
|
||||||
|
// Set the root _pathIdx after the sorting
|
||||||
|
for (int i = 0; i < _folders.size(); ++i) {
|
||||||
|
_folders[i]._pathIdx << i;
|
||||||
|
}
|
||||||
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
emit dirtyChanged();
|
emit dirtyChanged();
|
||||||
}
|
}
|
||||||
@@ -375,12 +388,13 @@ QModelIndex FolderStatusModel::indexForPath(Folder *f, const QString& path) cons
|
|||||||
if (slashPos == -1) {
|
if (slashPos == -1) {
|
||||||
// first level folder
|
// first level folder
|
||||||
for (int i = 0; i < _folders.size(); ++i) {
|
for (int i = 0; i < _folders.size(); ++i) {
|
||||||
if (_folders.at(i)._folder == f) {
|
auto& info = _folders.at(i);
|
||||||
|
if (info._folder == f) {
|
||||||
if( path.isEmpty() ) { // the folder object
|
if( path.isEmpty() ) { // the folder object
|
||||||
return index(i, 0);
|
return index(i, 0);
|
||||||
}
|
}
|
||||||
for (int j = 0; j < _folders.at(i)._subs.size(); ++j) {
|
for (int j = 0; j < info._subs.size(); ++j) {
|
||||||
const QString subName = _folders.at(i)._subs.at(j)._name;
|
const QString subName = info._subs.at(j)._name;
|
||||||
if (subName == path) {
|
if (subName == path) {
|
||||||
return index(j, 0, index(i));
|
return index(j, 0, index(i));
|
||||||
}
|
}
|
||||||
@@ -785,32 +799,13 @@ void FolderStatusModel::slotApplySelectiveSync()
|
|||||||
foreach(const auto &it, changes) {
|
foreach(const auto &it, changes) {
|
||||||
folder->journalDb()->avoidReadFromDbOnNextSync(it);
|
folder->journalDb()->avoidReadFromDbOnNextSync(it);
|
||||||
}
|
}
|
||||||
FolderMan::instance()->slotScheduleSync(folder);
|
FolderMan::instance()->scheduleFolder(folder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resetFolders();
|
resetFolders();
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString shortenFilename( Folder *f, const QString& file )
|
|
||||||
{
|
|
||||||
// strip off the server prefix from the file name
|
|
||||||
QString shortFile(file);
|
|
||||||
if( shortFile.isEmpty() ) {
|
|
||||||
return QString::null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(shortFile.startsWith(QLatin1String("ownclouds://")) ||
|
|
||||||
shortFile.startsWith(QLatin1String("owncloud://")) ) {
|
|
||||||
// rip off the whole ownCloud URL.
|
|
||||||
if( f ) {
|
|
||||||
QString remotePathUrl = f->remoteUrl().toString();
|
|
||||||
shortFile.remove(Utility::toCSyncScheme(remotePathUrl));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return shortFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderStatusModel::slotSetProgress(const ProgressInfo &progress)
|
void FolderStatusModel::slotSetProgress(const ProgressInfo &progress)
|
||||||
{
|
{
|
||||||
auto par = qobject_cast<QWidget*>(QObject::parent());
|
auto par = qobject_cast<QWidget*>(QObject::parent());
|
||||||
@@ -884,7 +879,7 @@ void FolderStatusModel::slotSetProgress(const ProgressInfo &progress)
|
|||||||
curItemProgress = curItem._size;
|
curItemProgress = curItem._size;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString itemFileName = shortenFilename(f, curItem._file);
|
QString itemFileName = curItem._file;
|
||||||
QString kindString = Progress::asActionString(curItem);
|
QString kindString = Progress::asActionString(curItem);
|
||||||
|
|
||||||
QString fileProgressString;
|
QString fileProgressString;
|
||||||
@@ -986,10 +981,12 @@ void FolderStatusModel::slotFolderSyncStateChange(Folder *f)
|
|||||||
}
|
}
|
||||||
if (folderIndex < 0) { return; }
|
if (folderIndex < 0) { return; }
|
||||||
|
|
||||||
|
auto& pi = _folders[folderIndex]._progress;
|
||||||
|
|
||||||
SyncResult::Status state = f->syncResult().status();
|
SyncResult::Status state = f->syncResult().status();
|
||||||
if (f->syncPaused()) {
|
if (f->syncPaused()) {
|
||||||
// Reset progress info.
|
// Reset progress info.
|
||||||
_folders[folderIndex]._progress = SubFolderInfo::Progress();
|
pi = SubFolderInfo::Progress();
|
||||||
} else if (state == SyncResult::NotYetStarted) {
|
} else if (state == SyncResult::NotYetStarted) {
|
||||||
FolderMan* folderMan = FolderMan::instance();
|
FolderMan* folderMan = FolderMan::instance();
|
||||||
int pos = folderMan->scheduleQueue().indexOf(f);
|
int pos = folderMan->scheduleQueue().indexOf(f);
|
||||||
@@ -1003,16 +1000,16 @@ void FolderStatusModel::slotFolderSyncStateChange(Folder *f)
|
|||||||
} else {
|
} else {
|
||||||
message = tr("Waiting for %n other folder(s)...", "", pos);
|
message = tr("Waiting for %n other folder(s)...", "", pos);
|
||||||
}
|
}
|
||||||
_folders[folderIndex]._progress = SubFolderInfo::Progress();
|
pi = SubFolderInfo::Progress();
|
||||||
_folders[folderIndex]._progress._overallSyncString = message;
|
pi._overallSyncString = message;
|
||||||
} else if (state == SyncResult::SyncPrepare) {
|
} else if (state == SyncResult::SyncPrepare) {
|
||||||
_folders[folderIndex]._progress = SubFolderInfo::Progress();
|
pi = SubFolderInfo::Progress();
|
||||||
_folders[folderIndex]._progress._overallSyncString = tr("Preparing to sync...");
|
pi._overallSyncString = tr("Preparing to sync...");
|
||||||
} else if (state == SyncResult::Problem || state == SyncResult::Success) {
|
} else if (state == SyncResult::Problem || state == SyncResult::Success) {
|
||||||
// Reset the progress info after a sync.
|
// Reset the progress info after a sync.
|
||||||
_folders[folderIndex]._progress = SubFolderInfo::Progress();
|
pi = SubFolderInfo::Progress();
|
||||||
} else if (state == SyncResult::Error) {
|
} else if (state == SyncResult::Error) {
|
||||||
_folders[folderIndex]._progress = SubFolderInfo::Progress();
|
pi = SubFolderInfo::Progress();
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the icon etc. now
|
// update the icon etc. now
|
||||||
@@ -1099,7 +1096,7 @@ void FolderStatusModel::slotSyncAllPendingBigFolders()
|
|||||||
foreach (const auto &it, undecidedList) {
|
foreach (const auto &it, undecidedList) {
|
||||||
folder->journalDb()->avoidReadFromDbOnNextSync(it);
|
folder->journalDb()->avoidReadFromDbOnNextSync(it);
|
||||||
}
|
}
|
||||||
FolderMan::instance()->slotScheduleSync(folder);
|
FolderMan::instance()->scheduleFolder(folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
resetFolders();
|
resetFolders();
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
@@ -23,7 +24,6 @@
|
|||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QVarLengthArray>
|
#include <QVarLengthArray>
|
||||||
#include <syncengine.h>
|
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
@@ -49,6 +49,31 @@ FolderWatcherPrivate::~FolderWatcherPrivate()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// attention: result list passed by reference!
|
||||||
|
bool FolderWatcherPrivate::findFoldersBelow( const QDir& dir, QStringList& fullList )
|
||||||
|
{
|
||||||
|
bool ok = true;
|
||||||
|
if( !(dir.exists() && dir.isReadable()) ) {
|
||||||
|
qDebug() << "Non existing path coming in: " << dir.absolutePath();
|
||||||
|
ok = false;
|
||||||
|
} else {
|
||||||
|
QStringList nameFilter;
|
||||||
|
nameFilter << QLatin1String("*");
|
||||||
|
QDir::Filters filter = QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks | QDir::Hidden;
|
||||||
|
const QStringList pathes = dir.entryList(nameFilter, filter);
|
||||||
|
|
||||||
|
QStringList::const_iterator constIterator;
|
||||||
|
for (constIterator = pathes.constBegin(); constIterator != pathes.constEnd();
|
||||||
|
++constIterator) {
|
||||||
|
const QString fullPath(dir.path()+QLatin1String("/")+(*constIterator));
|
||||||
|
fullList.append(fullPath);
|
||||||
|
ok = findFoldersBelow(QDir(fullPath), fullList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
void FolderWatcherPrivate::inotifyRegisterPath(const QString& path)
|
void FolderWatcherPrivate::inotifyRegisterPath(const QString& path)
|
||||||
{
|
{
|
||||||
if( !path.isEmpty()) {
|
if( !path.isEmpty()) {
|
||||||
@@ -64,46 +89,40 @@ void FolderWatcherPrivate::inotifyRegisterPath(const QString& path)
|
|||||||
|
|
||||||
void FolderWatcherPrivate::slotAddFolderRecursive(const QString &path)
|
void FolderWatcherPrivate::slotAddFolderRecursive(const QString &path)
|
||||||
{
|
{
|
||||||
|
int subdirs = 0;
|
||||||
qDebug() << "(+) Watcher:" << path;
|
qDebug() << "(+) Watcher:" << path;
|
||||||
|
|
||||||
|
QDir inPath(path);
|
||||||
|
inotifyRegisterPath(inPath.absolutePath());
|
||||||
|
|
||||||
const QStringList watchedFolders = _watches.values();
|
const QStringList watchedFolders = _watches.values();
|
||||||
int subdirs = addFolderRecursiveHelper(path, watchedFolders.toSet());
|
|
||||||
if (subdirs >0) {
|
QStringList allSubfolders;
|
||||||
qDebug() << " `-> and" << subdirs << "subdirectories";
|
if( !findFoldersBelow(QDir(path), allSubfolders)) {
|
||||||
|
qDebug() << "Could not traverse all sub folders";
|
||||||
}
|
}
|
||||||
}
|
// qDebug() << "currently watching " << watchedFolders;
|
||||||
|
QStringListIterator subfoldersIt(allSubfolders);
|
||||||
int FolderWatcherPrivate::addFolderRecursiveHelper(const QString &path, const QSet<QString> &watchedFolders)
|
while (subfoldersIt.hasNext()) {
|
||||||
{
|
QString subfolder = subfoldersIt.next();
|
||||||
QDir dir(path);
|
// qDebug() << " (**) subfolder: " << subfolder;
|
||||||
if( !(dir.exists() && dir.isReadable()) ) {
|
QDir folder (subfolder);
|
||||||
qDebug() << "Non existing path coming in: " << dir.absolutePath();
|
if (folder.exists() && !watchedFolders.contains(folder.absolutePath())) {
|
||||||
return 0;
|
subdirs++;
|
||||||
}
|
if( _parent->pathIsIgnored(subfolder) ) {
|
||||||
int subdirs = 1;
|
|
||||||
|
|
||||||
inotifyRegisterPath(dir.absolutePath());
|
|
||||||
|
|
||||||
QDir::Filters filter = QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks | QDir::Hidden;
|
|
||||||
const QStringList pathes = dir.entryList(filter);
|
|
||||||
for (auto constIterator = pathes.constBegin(); constIterator != pathes.constEnd(); ++constIterator) {
|
|
||||||
const QString subfolder = path + QLatin1String("/") + (*constIterator);
|
|
||||||
QDir folder(subfolder);
|
|
||||||
if (folder.exists() && !watchedFolders.contains(subfolder)) {
|
|
||||||
#ifndef OWNCLOUD_TEST // InotifyWatcherTest is not interested in ignored files and does not link against the folder
|
|
||||||
if( _parent->_folder->syncEngine().excludedFiles().isExcluded(
|
|
||||||
subfolder, path, _parent->_folder->ignoreHiddenFiles())) {
|
|
||||||
qDebug() << "* Not adding" << folder.path();
|
qDebug() << "* Not adding" << folder.path();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
inotifyRegisterPath(folder.absolutePath());
|
||||||
subdirs += addFolderRecursiveHelper(subfolder, watchedFolders);
|
|
||||||
} else {
|
} else {
|
||||||
qDebug() << " `-> discarded:" << folder.path();
|
qDebug() << " `-> discarded:" << folder.path();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return subdirs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (subdirs >0) {
|
||||||
|
qDebug() << " `-> and" << subdirs << "subdirectories";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FolderWatcherPrivate::slotReceivedNotification(int fd)
|
void FolderWatcherPrivate::slotReceivedNotification(int fd)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
@@ -33,6 +34,7 @@ class FolderWatcherPrivate : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
FolderWatcherPrivate() { }
|
||||||
FolderWatcherPrivate(FolderWatcher *p, const QString &path);
|
FolderWatcherPrivate(FolderWatcher *p, const QString &path);
|
||||||
~FolderWatcherPrivate();
|
~FolderWatcherPrivate();
|
||||||
|
|
||||||
@@ -44,9 +46,10 @@ protected slots:
|
|||||||
void slotAddFolderRecursive(const QString &path);
|
void slotAddFolderRecursive(const QString &path);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int addFolderRecursiveHelper(const QString &path, const QSet<QString> &watchedFolders);
|
bool findFoldersBelow( const QDir& dir, QStringList& fullList );
|
||||||
void inotifyRegisterPath(const QString& path);
|
void inotifyRegisterPath(const QString& path);
|
||||||
|
|
||||||
|
private:
|
||||||
FolderWatcher *_parent;
|
FolderWatcher *_parent;
|
||||||
|
|
||||||
QString _folder;
|
QString _folder;
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
@@ -126,7 +127,7 @@ void IgnoreListEditor::slotUpdateLocalIgnoreList()
|
|||||||
// ignored (because the remote etag did not change) (issue #3172)
|
// ignored (because the remote etag did not change) (issue #3172)
|
||||||
foreach (Folder* folder, folderMan->map()) {
|
foreach (Folder* folder, folderMan->map()) {
|
||||||
folder->journalDb()->forceRemoteDiscoveryNextSync();
|
folder->journalDb()->forceRemoteDiscoveryNextSync();
|
||||||
folderMan->slotScheduleSync(folder);
|
folderMan->scheduleFolder(folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExcludedFiles::instance().reloadExcludes();
|
ExcludedFiles::instance().reloadExcludes();
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#include "winuser.h"
|
||||||
|
|
||||||
|
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "owncloud.exe.manifest-mingw"
|
||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
@@ -66,7 +67,7 @@ void OcsJob::start()
|
|||||||
req.setRawHeader("Ocs-APIREQUEST", "true");
|
req.setRawHeader("Ocs-APIREQUEST", "true");
|
||||||
req.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
|
req.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
QUrl url = Account::concatUrlPath(account()->url(), path());
|
QUrl url = Utility::concatUrlPath(account()->url(), path());
|
||||||
QBuffer *buffer = new QBuffer;
|
QBuffer *buffer = new QBuffer;
|
||||||
|
|
||||||
if (_verb == "GET") {
|
if (_verb == "GET") {
|
||||||
@@ -107,7 +108,7 @@ bool OcsJob::finished()
|
|||||||
if (!success) {
|
if (!success) {
|
||||||
qDebug() << "Could not parse reply to"
|
qDebug() << "Could not parse reply to"
|
||||||
<< _verb
|
<< _verb
|
||||||
<< Account::concatUrlPath(account()->url(), path())
|
<< Utility::concatUrlPath(account()->url(), path())
|
||||||
<< _params
|
<< _params
|
||||||
<< ":" << replyData;
|
<< ":" << replyData;
|
||||||
}
|
}
|
||||||
@@ -117,7 +118,7 @@ bool OcsJob::finished()
|
|||||||
if (!_passStatusCodes.contains(statusCode)) {
|
if (!_passStatusCodes.contains(statusCode)) {
|
||||||
qDebug() << "Reply to"
|
qDebug() << "Reply to"
|
||||||
<< _verb
|
<< _verb
|
||||||
<< Account::concatUrlPath(account()->url(), path())
|
<< Utility::concatUrlPath(account()->url(), path())
|
||||||
<< _params
|
<< _params
|
||||||
<< "has unexpected status code:" << statusCode << replyData;
|
<< "has unexpected status code:" << statusCode << replyData;
|
||||||
emit ocsError(statusCode, message);
|
emit ocsError(statusCode, message);
|
||||||
|
|||||||
+2
-1
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
|
||||||
|
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
|
||||||
|
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<security>
|
||||||
|
<requestedPrivileges>
|
||||||
|
<requestedExecutionLevel level='asInvoker' uiAccess='false' />
|
||||||
|
</requestedPrivileges>
|
||||||
|
</security>
|
||||||
|
</trustInfo>
|
||||||
|
</assembly>
|
||||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário