Possible race condition fix
This commit is contained in:
parent
ebd7cbc1a1
commit
5a24c17bc1
1 changed files with 78 additions and 23 deletions
101
Shared/Sync.py
101
Shared/Sync.py
|
@ -5,6 +5,7 @@ import base64
|
||||||
import random
|
import random
|
||||||
import pickle
|
import pickle
|
||||||
import shutil
|
import shutil
|
||||||
|
import _thread
|
||||||
|
|
||||||
import Routing
|
import Routing
|
||||||
import Logging
|
import Logging
|
||||||
|
@ -112,45 +113,70 @@ class ReloadHandler(FileSystemEventHandler):
|
||||||
|
|
||||||
def on_modified(self, event):
|
def on_modified(self, event):
|
||||||
if get_name_from_path(event.src_path) not in self.sync.exclude and not event.is_directory:
|
if get_name_from_path(event.src_path) not in self.sync.exclude and not event.is_directory:
|
||||||
if self.sync.debug:
|
self.sync.action_queue.add(Action(self.sync.modified, {"event" : event}))
|
||||||
Logging.info("Modified file: '%s'" % event.src_path)
|
|
||||||
self.sync.modified(event)
|
|
||||||
|
|
||||||
|
|
||||||
def on_created(self, event):
|
def on_created(self, event):
|
||||||
if get_name_from_path(event.src_path) not in self.sync.exclude and not event.is_directory:
|
if get_name_from_path(event.src_path) not in self.sync.exclude and not event.is_directory:
|
||||||
if self.sync.debug:
|
self.sync.action_queue.add(Action(self.sync.created, {"event" : event}))
|
||||||
Logging.info("Created file: '%s'" % event.src_path)
|
|
||||||
self.sync.created(event)
|
|
||||||
|
|
||||||
|
|
||||||
def on_deleted(self, event):
|
def on_deleted(self, event):
|
||||||
if get_name_from_path(event.src_path) not in self.sync.exclude:
|
if get_name_from_path(event.src_path) not in self.sync.exclude:
|
||||||
if not event.is_directory:
|
if not event.is_directory:
|
||||||
if self.sync.debug:
|
print("deleted")
|
||||||
Logging.info("Deleted file: '%s'" % event.src_path)
|
self.sync.action_queue.add(Action(self.sync.deleted, {"event" : event}))
|
||||||
self.sync.deleted(event)
|
|
||||||
else:
|
else:
|
||||||
if self.sync.debug:
|
self.sync.action_queue.add(Action(self.sync.deleted_dir, {"event" : event}))
|
||||||
Logging.info("Deleted dir: '%s'" % event.src_path)
|
|
||||||
self.sync.deleted_dir(event)
|
|
||||||
|
|
||||||
|
|
||||||
def on_moved(self, event):
|
def on_moved(self, event):
|
||||||
if get_name_from_path(event.src_path) not in self.sync.exclude:
|
if get_name_from_path(event.src_path) not in self.sync.exclude:
|
||||||
if not event.is_directory:
|
if not event.is_directory:
|
||||||
if self.sync.debug:
|
self.sync.action_queue.add(Action(self.sync.moved, {"event" : event}))
|
||||||
Logging.info("Moved file: '%s' -> '%s'" % (event.src_path, event.dest_path))
|
|
||||||
self.sync.moved(event)
|
|
||||||
else:
|
else:
|
||||||
if self.sync.debug:
|
self.sync.action_queue.add(Action(self.sync.moved_dir, {"event" : event}))
|
||||||
Logging.info("Moved dir: '%s' -> '%s'" % (event.src_path, event.dest_path))
|
|
||||||
self.sync.moved_dir(event)
|
|
||||||
|
class ActionQueue:
|
||||||
|
def __init__(self):
|
||||||
|
self.actions = []
|
||||||
|
self.running = False
|
||||||
|
|
||||||
|
def add(self, action):
|
||||||
|
if type(action) is Action:
|
||||||
|
self.actions.append(action)
|
||||||
|
self.start()
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
while self.running:
|
||||||
|
time.sleep(0.01)
|
||||||
|
_thread.start_new_thread(self.run, ())
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.actions[0].run()
|
||||||
|
del self.actions[0]
|
||||||
|
self.running = False
|
||||||
|
|
||||||
|
|
||||||
|
class Action:
|
||||||
|
def __init__(self, function, kwargs):
|
||||||
|
self.function = function
|
||||||
|
self.kwargs = kwargs
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.function(**self.kwargs)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if type(other) is Action:
|
||||||
|
return self.__dict__ == other.__dict__
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class SyncClient(Routing.ClientRoute):
|
class SyncClient(Routing.ClientRoute):
|
||||||
def __init__(self, sock, folder, route, exclude=[".DS_Store", ".fl0w"], debug=False):
|
def __init__(self, sock, folder, route, exclude=[".DS_Store", ".fl0w"], debug=False):
|
||||||
self.sock = sock
|
self.sock = sock
|
||||||
|
self.action_queue = ActionQueue()
|
||||||
self.folder = folder if folder[-1] == "/" else folder + "/"
|
self.folder = folder if folder[-1] == "/" else folder + "/"
|
||||||
self.started = False
|
self.started = False
|
||||||
self.route = route
|
self.route = route
|
||||||
|
@ -164,6 +190,8 @@ class SyncClient(Routing.ClientRoute):
|
||||||
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
|
if self.debug:
|
||||||
|
Logging.info("Sync client started!")
|
||||||
out = {"list" : {}}
|
out = {"list" : {}}
|
||||||
for file in self.files:
|
for file in self.files:
|
||||||
out["list"].update({file : {"mtime" : get_mtime(self.folder + file),
|
out["list"].update({file : {"mtime" : get_mtime(self.folder + file),
|
||||||
|
@ -230,7 +258,9 @@ class SyncClient(Routing.ClientRoute):
|
||||||
"mtime" : os.path.getmtime(self.folder + file)}}}, self.route)
|
"mtime" : os.path.getmtime(self.folder + file)}}}, self.route)
|
||||||
|
|
||||||
|
|
||||||
def modified(self, event):
|
def modified(self, event, created=False):
|
||||||
|
if self.debug and not created:
|
||||||
|
Logging.info("Modified file: '%s'" % event.src_path)
|
||||||
relpath = os.path.relpath(event.src_path, self.folder)
|
relpath = os.path.relpath(event.src_path, self.folder)
|
||||||
if relpath not in self.files:
|
if relpath not in self.files:
|
||||||
self.files.append(relpath)
|
self.files.append(relpath)
|
||||||
|
@ -242,20 +272,27 @@ class SyncClient(Routing.ClientRoute):
|
||||||
|
|
||||||
|
|
||||||
def created(self, event):
|
def created(self, event):
|
||||||
self.modified(event)
|
if self.debug:
|
||||||
|
Logging.info("Created file: '%s'" % event.src_path)
|
||||||
|
self.modified(event, created=True)
|
||||||
|
|
||||||
|
|
||||||
def deleted(self, event):
|
def deleted(self, event):
|
||||||
|
if self.debug:
|
||||||
|
Logging.info("Deleted file: '%s'" % event.src_path)
|
||||||
relpath = os.path.relpath(event.src_path, self.folder)
|
relpath = os.path.relpath(event.src_path, self.folder)
|
||||||
if relpath in self.files:
|
if relpath in self.files:
|
||||||
del self.files[self.files.index(relpath)]
|
del self.files[self.files.index(relpath)]
|
||||||
if not relpath in self.suppressed_fs_events:
|
if not relpath in self.suppressed_fs_events:
|
||||||
self.sock.send({"del" : [relpath]}, self.route)
|
pass
|
||||||
|
#self.sock.send({"del" : [relpath]}, self.route)
|
||||||
else:
|
else:
|
||||||
self.unsuppress_fs_event(relpath)
|
self.unsuppress_fs_event(relpath)
|
||||||
|
|
||||||
|
|
||||||
def deleted_dir(self, event):
|
def deleted_dir(self, event):
|
||||||
|
if self.debug:
|
||||||
|
Logging.info("Deleted folder: '%s'" % event.src_path)
|
||||||
relpath = os.path.relpath(event.src_path, self.folder)
|
relpath = os.path.relpath(event.src_path, self.folder)
|
||||||
if not relpath in self.suppressed_fs_events:
|
if not relpath in self.suppressed_fs_events:
|
||||||
self.sock.send({"deldir" : [relpath]}, self.route)
|
self.sock.send({"deldir" : [relpath]}, self.route)
|
||||||
|
@ -263,6 +300,8 @@ class SyncClient(Routing.ClientRoute):
|
||||||
self.unsuppress_fs_event(relpath)
|
self.unsuppress_fs_event(relpath)
|
||||||
|
|
||||||
def moved(self, event):
|
def moved(self, event):
|
||||||
|
if self.debug:
|
||||||
|
Logging.info("Moved file: '%s'" % event.src_path)
|
||||||
src_relpath = os.path.relpath(event.src_path, self.folder)
|
src_relpath = os.path.relpath(event.src_path, self.folder)
|
||||||
dest_relpath = os.path.relpath(event.dest_path, self.folder)
|
dest_relpath = os.path.relpath(event.dest_path, self.folder)
|
||||||
if src_relpath in self.files:
|
if src_relpath in self.files:
|
||||||
|
@ -284,6 +323,7 @@ class SyncServer(Routing.ServerRoute):
|
||||||
|
|
||||||
def __init__(self, folder, channel, exclude=[".DS_Store", ".fl0w"], debug=False, deleted_db_path="deleted.db", modified_hook=None, deleted_hook=None):
|
def __init__(self, folder, channel, exclude=[".DS_Store", ".fl0w"], debug=False, deleted_db_path="deleted.db", modified_hook=None, deleted_hook=None):
|
||||||
self.folder = folder if folder[-1] == "/" else folder + "/"
|
self.folder = folder if folder[-1] == "/" else folder + "/"
|
||||||
|
self.action_queue = ActionQueue()
|
||||||
self.channel = channel
|
self.channel = channel
|
||||||
self.exclude = exclude
|
self.exclude = exclude
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
|
@ -298,6 +338,8 @@ class SyncServer(Routing.ServerRoute):
|
||||||
|
|
||||||
|
|
||||||
def start(self, handler):
|
def start(self, handler):
|
||||||
|
if self.debug:
|
||||||
|
Logging.info("Sync server on route '%s' started!" % self.route)
|
||||||
self.files = relative_recursive_ls(self.folder, self.folder, exclude=self.exclude)
|
self.files = relative_recursive_ls(self.folder, self.folder, exclude=self.exclude)
|
||||||
observer = Observer()
|
observer = Observer()
|
||||||
observer.schedule(ReloadHandler(self), path=self.folder, recursive=True)
|
observer.schedule(ReloadHandler(self), path=self.folder, recursive=True)
|
||||||
|
@ -363,7 +405,10 @@ class SyncServer(Routing.ServerRoute):
|
||||||
shutil.move(self.folder + file, new_name)
|
shutil.move(self.folder + file, new_name)
|
||||||
|
|
||||||
|
|
||||||
def modified(self, event):
|
def modified(self, event, created=False):
|
||||||
|
if self.debug and not created:
|
||||||
|
Logging.info("Modified file: '%s'" % event.src_path)
|
||||||
|
print(self.broadcast_file_excludes)
|
||||||
relpath = os.path.relpath(event.src_path, self.folder)
|
relpath = os.path.relpath(event.src_path, self.folder)
|
||||||
if relpath not in self.files:
|
if relpath not in self.files:
|
||||||
self.files.append(relpath)
|
self.files.append(relpath)
|
||||||
|
@ -380,11 +425,17 @@ class SyncServer(Routing.ServerRoute):
|
||||||
|
|
||||||
|
|
||||||
def created(self, event):
|
def created(self, event):
|
||||||
self.modified(event)
|
if self.debug:
|
||||||
|
Logging.info("Created file: '%s'" % event.src_path)
|
||||||
|
print(self.broadcast_file_excludes)
|
||||||
|
self.modified(event, created=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def deleted(self, event):
|
def deleted(self, event):
|
||||||
|
if self.debug:
|
||||||
|
Logging.info("Deleted file: '%s'" % event.src_path)
|
||||||
|
print(self.broadcast_file_excludes)
|
||||||
relpath = os.path.relpath(event.src_path, self.folder)
|
relpath = os.path.relpath(event.src_path, self.folder)
|
||||||
if not relpath in self.ignore_events:
|
if not relpath in self.ignore_events:
|
||||||
if relpath in self.files:
|
if relpath in self.files:
|
||||||
|
@ -402,6 +453,8 @@ class SyncServer(Routing.ServerRoute):
|
||||||
|
|
||||||
|
|
||||||
def deleted_dir(self, event):
|
def deleted_dir(self, event):
|
||||||
|
if self.debug:
|
||||||
|
Logging.info("Deleted folder: '%s'" % event.src_path)
|
||||||
relpath = os.path.relpath(event.src_path, self.folder)
|
relpath = os.path.relpath(event.src_path, self.folder)
|
||||||
if not relpath in self.ignore_events:
|
if not relpath in self.ignore_events:
|
||||||
exclude = []
|
exclude = []
|
||||||
|
@ -415,6 +468,8 @@ class SyncServer(Routing.ServerRoute):
|
||||||
|
|
||||||
|
|
||||||
def moved(self, event):
|
def moved(self, event):
|
||||||
|
if self.debug:
|
||||||
|
Logging.info("Moved file: '%s'" % event.src_path)
|
||||||
src_relpath = os.path.relpath(event.src_path, self.folder)
|
src_relpath = os.path.relpath(event.src_path, self.folder)
|
||||||
dest_relpath = os.path.relpath(event.dest_path, self.folder)
|
dest_relpath = os.path.relpath(event.dest_path, self.folder)
|
||||||
if src_relpath in self.files:
|
if src_relpath in self.files:
|
||||||
|
|
Reference in a new issue