[Mac] Delay updates to opened MS Office files.

This commit is contained in:
Jonathan Xu 2018-06-27 14:29:46 +08:00
parent d16c6ac0f7
commit 79aba80c85
3 changed files with 69 additions and 18 deletions

View File

@ -1270,7 +1270,7 @@ add_file (const char *repo_id,
if (!is_writable || is_locked)
return ret;
#ifdef WIN32
#if defined WIN32 || defined __APPLE__
if (options && options->fset) {
LockedFile *file = locked_file_set_lookup (options->fset, path);
if (file) {
@ -1896,7 +1896,7 @@ out:
static gboolean
check_locked_file_before_remove (LockedFileSet *fset, const char *path)
{
#ifdef WIN32
#if defined WIN32 || defined __APPLE__
if (!fset)
return TRUE;
@ -3821,7 +3821,7 @@ index_add (SeafRepo *repo, struct index_state *istate, gboolean is_force_commit)
crypt = seafile_crypt_new (repo->enc_version, repo->enc_key, repo->enc_iv);
}
#ifdef WIN32
#if defined WIN32 || defined __APPLE__
if (repo->version > 0)
fset = seaf_repo_manager_get_locked_file_set (seaf->repo_mgr, repo->id);
#endif
@ -3840,7 +3840,7 @@ index_add (SeafRepo *repo, struct index_state *istate, gboolean is_force_commit)
seaf_repo_free_ignore_files (ignore_list);
#ifdef WIN32
#if defined WIN32 || defined __APPLE__
locked_file_set_free (fset);
#endif
@ -4511,7 +4511,7 @@ checkout_file_http (FileTxData *data,
locked_on_server = seaf_filelock_manager_is_file_locked (seaf->filelock_mgr,
repo_id, de->name);
#ifdef WIN32
#if defined WIN32 || defined __APPLE__
if (do_check_file_locked (de->name, worktree, locked_on_server)) {
if (!locked_file_set_lookup (fset, de->name))
send_file_sync_error_notification (repo_id, NULL, de->name,
@ -5383,7 +5383,7 @@ seaf_repo_fetch_and_checkout (HttpTxTask *http_task, const char *remote_head_id)
struct cache_entry *ce;
#ifdef WIN32
#if defined WIN32 || defined __APPLE__
fset = seaf_repo_manager_get_locked_file_set (seaf->repo_mgr, repo_id);
#endif
@ -5409,7 +5409,7 @@ seaf_repo_fetch_and_checkout (HttpTxTask *http_task, const char *remote_head_id)
seaf_filelock_manager_unlock_wt_file (seaf->filelock_mgr,
repo_id, de->name);
#ifdef WIN32
#if defined WIN32 || defined __APPLE__
if (!do_check_file_locked (de->name, worktree, locked_on_server)) {
locked_file_set_remove (fset, de->name, FALSE);
delete_path (worktree, de->name, de->mode, ce->ce_mtime.sec);
@ -5546,7 +5546,7 @@ out:
if (ignore_list)
seaf_repo_free_ignore_files (ignore_list);
#ifdef WIN32
#if defined WIN32 || defined __APPLE__
locked_file_set_free (fset);
#endif
@ -6006,11 +6006,9 @@ seaf_repo_manager_remove_repo_ondisk (SeafRepoManager *mgr,
repo_id);
sqlite_query_exec (mgr->priv->db, sql);
#ifdef WIN32
snprintf (sql, sizeof(sql), "DELETE FROM LockedFiles WHERE repo_id = '%s'",
repo_id);
sqlite_query_exec (mgr->priv->db, sql);
#endif
snprintf (sql, sizeof(sql), "DELETE FROM FolderUserPerms WHERE repo_id = '%s'",
repo_id);
@ -6521,12 +6519,10 @@ open_db (SeafRepoManager *manager, const char *seaf_dir)
sql = "CREATE TABLE IF NOT EXISTS GarbageRepos (repo_id TEXT PRIMARY KEY);";
sqlite_query_exec (db, sql);
#ifdef WIN32
sql = "CREATE TABLE IF NOT EXISTS LockedFiles (repo_id TEXT, path TEXT, "
"operation TEXT, old_mtime INTEGER, file_id TEXT, new_path TEXT, "
"PRIMARY KEY (repo_id, path));";
sqlite_query_exec (db, sql);
#endif
sql = "CREATE TABLE IF NOT EXISTS FolderUserPerms ("
"repo_id TEXT, path TEXT, permission TEXT);";

View File

@ -693,7 +693,7 @@ repo_block_store_exists (SeafRepo *repo)
return ret;
}
#ifdef WIN32
#if defined WIN32 || defined __APPLE__
static GHashTable *
load_locked_files_blocks (const char *repo_id)
@ -760,9 +760,7 @@ remove_repo_blocks (void *vtask)
{
SyncTask *task = vtask;
#ifndef WIN32
seaf_block_manager_remove_store (seaf->block_mgr, task->repo->id);
#else
#if defined WIN32 || defined __APPLE__
GHashTable *block_hash;
block_hash = load_locked_files_blocks (task->repo->id);
@ -779,6 +777,8 @@ remove_repo_blocks (void *vtask)
block_hash);
g_hash_table_destroy (block_hash);
#else
seaf_block_manager_remove_store (seaf->block_mgr, task->repo->id);
#endif
return vtask;
@ -1387,7 +1387,7 @@ cmp_repos_by_sync_time (gconstpointer a, gconstpointer b, gpointer user_data)
return (repo_a->last_sync_time - repo_b->last_sync_time);
}
#ifdef WIN32
#if defined WIN32 || defined __APPLE__
static void
cleanup_file_blocks (const char *repo_id, int version, const char *file_id)
@ -1961,7 +1961,7 @@ auto_sync_pulse (void *vmanager)
if (!manager->priv->auto_sync_enabled || !repo->auto_sync)
continue;
#ifdef WIN32
#if defined WIN32 || defined __APPLE__
if (repo->version > 0) {
if (repo->checking_locked_files)
continue;

View File

@ -635,3 +635,58 @@ files_locked_on_windows (struct index_state *index, const char *worktree)
#endif /* WIN32 */
#ifdef __APPLE__
/* On Mac, we only check whether an office file is opened and locked.
* The detection is done by checking ~$* tmp file.
*/
gboolean
do_check_file_locked (const char *path, const char *worktree, gboolean locked_on_server)
{
#define OFFICE_FILE_PATTERN ".*\\.(docx|xlsx|pptx|doc|xls|ppt|vsdx)"
char *dir_name = NULL, *file_name = NULL;
char *fullpath = NULL;
char *tmp_name = NULL;
int ret = FALSE;
if (!g_regex_match_simple (OFFICE_FILE_PATTERN, path, 0, 0))
return FALSE;
dir_name = g_path_get_dirname (path);
if (strcmp (dir_name, ".") == 0) {
g_free (dir_name);
dir_name = g_strdup("");
}
file_name = g_path_get_basename (path);
tmp_name = g_strconcat ("~$", file_name, NULL);
fullpath = g_build_path ("/", worktree, dir_name, tmp_name, NULL);
if (g_file_test (fullpath, G_FILE_TEST_IS_REGULAR)) {
ret = TRUE;
goto out;
}
g_free (tmp_name);
g_free (fullpath);
/* Sometimes the first two characters are replaced by ~$. */
if (g_utf8_strlen(file_name, -1) < 2)
goto out;
char *ptr = g_utf8_find_next_char(g_utf8_find_next_char (file_name, NULL), NULL);
tmp_name = g_strconcat ("~$", ptr, NULL);
fullpath = g_build_path ("/", worktree, dir_name, tmp_name, NULL);
if (g_file_test (fullpath, G_FILE_TEST_IS_REGULAR)) {
ret = TRUE;
goto out;
}
out:
g_free (fullpath);
g_free (tmp_name);
g_free (dir_name);
g_free (file_name);
return ret;
}
#endif