diff --git a/Shared/Sync.py b/Shared/Sync.py index 8856150..27a58a5 100644 --- a/Shared/Sync.py +++ b/Shared/Sync.py @@ -37,6 +37,8 @@ def get_name_from_path(path): def get_file_content(path): return open(path, "rb+").read() +def base64_str_decode(path): + return base64.b64encode(get_file_content(path)).decode() class ReloadHandler(FileSystemEventHandler): def __init__(self, sync): @@ -65,7 +67,7 @@ class SyncClient(Routing.ClientRoute): self.route = route self.exclude = exclude self.files = relative_recursive_ls(folder, folder, exclude=self.exclude) - self.surpressed_fs_events = [] + self.suppressed_fs_events = [] observer = Observer() observer.schedule(ReloadHandler(self), path=self.folder, recursive=True) observer.start() @@ -74,8 +76,8 @@ class SyncClient(Routing.ClientRoute): def start(self): out = {"list" : {}} for file in self.files: - out["list"].update({file : {"mtime" : os.path.getmtime(self.folder + file), "md5" : md5(self.folder + file)}}) - print(out) + out["list"].update({file : {"mtime" : os.path.getmtime(self.folder + file), + "md5" : md5(self.folder + file)}}) self.sock.send(out, self.route) self.started = True @@ -83,115 +85,53 @@ class SyncClient(Routing.ClientRoute): self.started = False - def surpress_fs_event(self, file): - if not file in self.surpressed_fs_events: - self.surpressed_fs_events.append(file) + def suppress_fs_event(self, file): + if not file in self.suppressed_fs_events: + self.suppressed_fs_events.append(file) - def unsurpess_fs_event(self, file): - if file in self.surpressed_fs_events: - del self.surpressed_fs_events[self.surpressed_fs_events.index(file)] + def unsuppress_fs_event(self, file): + if file in self.suppressed_fs_events: + del self.suppressed_fs_events[self.suppressed_fs_events.index(file)] def run(self, data, handler): if type(data) is dict: if "add" in data: for file in data["add"]: - self.surpress_fs_event(file) - open(file, "wb+").write(base64.b64decode(data["add"][file]["content"])) - os.utime(file, data["add"][file]["mtime"]) - self.unsupress_fs_event(file) + if not file in self.suppressed_fs_events: + self.suppress_fs_event(file) + folder_path = self.folder + os.path.dirname(file) + if not os.path.exists(folder_path): + os.makedirs(folder_path) + if os.path.exists: + open(self.folder + file, "wb+").write(base64.b64decode(data["add"][file]["content"])) + else: + open(self.folder + file, "ab+").write(base64.b64decode(data["add"][file]["content"])) + os.utime(self.folder + file, (data["add"][file]["mtime"], data["add"][file]["mtime"])) + else: + self.unsuppress_fs_event(file) elif "del" in data: - self.surpress_fs_event(file) - os.remove(file) - self.unsupress_fs_event(file) + for file in data["del"]: + if not file in self.suppressed_fs_events: + os.remove(self.folder + file) + else: + self.unsuppress_fs_event(file) elif "req" in data: for file in data["req"]: if file in self.files: - self.sock.send({"add" : {"content" : base64.b64encode(get_file_content(file)).encode(), "mtime" : os.path.getmtime(file)}}, self.route) - - - def modified(self, event): - if self.started: - relpath = os.path.relpath(event.src_path, self.folder) - if relpath not in self.files: - self.files.append(relpath) - if not relpath in self.surpressed_fs_events: - self.sock.send({"add" : {"content" : base64.b64encode(get_file_content(event.src_path)).encode(), "mtime" : os.path.getmtime(event.src_path)}}, self.route) - - - def created(self, event): - self.modified(event) - - - def deleted(self, event): - if self.started: - relpath = os.path.relpath(event.src_path, self.folder) - if relpath in self.files: - del self.files[self.files.index(relpath)] - if not relpath in self.surpressed_fs_events: - self.sock.send({"del" : [relpath]}, self.route) - - -class SyncServer: - def __init__(self, folder, exclude=[".DS_Store", ".git"]): - self.folder = folder if folder[-1] == "/" else folder + "/" - self.exclude = exclude - self.files = relative_recursive_ls(folder, folder, exclude=self.exclude) - self.surpressed_fs_events = [] - - - - def start(self): - self.files = relative_recursive_ls(folder, folder, exclude=self.exclude) - observer = Observer() - observer.schedule(ReloadHandler(self), path=self.folder, recursive=True) - observer.start() - - - def surpress_fs_event(self, file): - if not file in self.surpressed_fs_events: - self.surpressed_fs_events.append(file) - - - def unsurpess_fs_event(self, file): - if file in self.surpressed_fs_events: - del self.surpressed_fs_events[self.surpressed_fs_events.index(file)] - - - def run(self, data, handler): - if type(data) is dict: - if "list" in data: - for file in data["list"]: - print(file) - if data["list"][file]["mtime"] < handler.last_stop_time: - if file in self.files: - if data["list"][file]["md5"] != md5(file): - handler.sock.send({"del" : [file]}, handler.get_route(self)) - else: - handler.sock.send({"del" : [file]}, handler.get_route(self)) - else: - handler.sock.send({"req" : [file]}, handler.get_route(self)) - elif "add" in data: - for file in data["add"]: - self.surpress_fs_event(file) - open(file, "wb+").write(base64.b64decode(data["add"][file]["content"].decode())) - os.utime(file, data["add"][file]["mtime"]) - self.unsupress_fs_event(file) - elif "del" in data: - self.surpress_fs_event(file) - os.remove(file) - self.unsupress_fs_event(file) + self.sock.send({"add" : {file : {"content" : base64_str_decode(self.folder + file), + "mtime" : os.path.getmtime(self.folder + file)}}}, self.route) def modified(self, event): relpath = os.path.relpath(event.src_path, self.folder) if relpath not in self.files: self.files.append(relpath) - if not relpath in self.surpressed_fs_events: - handler.broadcast({"add" : { - "content" : base64.b64encode(get_file_content(event.src_path)).encode(), - "mtime" : os.path.getmtime(event.src_path)}}, handler.get_route(self), channel) + self.sock.send({"add" : {relpath : {"content" : base64_str_decode(event.src_path), + "mtime" : os.path.getmtime(event.src_path)}}}, self.route) + self.suppress_fs_event(relpath) + def created(self, event): @@ -202,5 +142,92 @@ class SyncServer: relpath = os.path.relpath(event.src_path, self.folder) if relpath in self.files: del self.files[self.files.index(relpath)] - if not relpath in self.surpressed_fs_events: - handler.broadcast({"del" : [relpath]}, handler.get_route(self), channel) \ No newline at end of file + self.sock.send({"del" : [relpath]}, self.route) + self.suppress_fs_event(relpath) + + +class SyncServer(Routing.ServerRoute): + REQUIRED = (Routing.BROADCAST, Routing.ROUTE) + + def __init__(self, folder, channel, exclude=[".DS_Store", ".git"]): + self.folder = folder if folder[-1] == "/" else folder + "/" + self.channel = channel + self.exclude = exclude + self.suppressed_fs_events = [] + self.route = None # Set by REQUIRED + self.broadcast = None # Set by REQUIRED + + + def start(self): + self.files = relative_recursive_ls(self.folder, self.folder, exclude=self.exclude) + observer = Observer() + observer.schedule(ReloadHandler(self), path=self.folder, recursive=True) + observer.start() + + + def suppress_fs_event(self, file): + if not file in self.suppressed_fs_events: + self.suppressed_fs_events.append(file) + + + def unsuppress_fs_event(self, file): + if file in self.suppressed_fs_events: + del self.suppressed_fs_events[self.suppressed_fs_events.index(file)] + + + def run(self, data, handler): + if type(data) is dict: + if "list" in data: + for file in data["list"]: + if data["list"][file]["mtime"] < handler.last_stop: + if file in self.files: + if data["list"][file]["mtime"] < os.path.getmtime(self.folder + file): + handler.sock.send({"add" : {relpath : { + "content" : base64_str_decode(event.src_path), + "mtime" : os.path.getmtime(event.src_path)}}}, self.route) + elif data["list"][file]["mtime"] > os.path.getmtime(self.folder + file): + handler.sock.send({"req" : [file]}, self.route) + else: + handler.sock.send({"del" : [file]}, self.route) + else: + if file not in self.files: + handler.sock.send({"req" : [file]}, self.route) + elif "add" in data: + for file in data["add"]: + if not file in self.suppressed_fs_events: + self.suppress_fs_event(file) + folder_path = self.folder + os.path.dirname(file) + if not os.path.exists(folder_path): + os.makedirs(folder_path) + if os.path.exists: + open(self.folder + file, "wb+").write(base64.b64decode(data["add"][file]["content"])) + else: + open(self.folder + file, "ab+").write(base64.b64decode(data["add"][file]["content"])) + os.utime(self.folder + file, (data["add"][file]["mtime"], data["add"][file]["mtime"])) + else: + self.unsuppress_fs_event(file) + elif "del" in data: + for file in data["del"]: + os.remove(self.folder + file) + + + def modified(self, event): + relpath = os.path.relpath(event.src_path, self.folder) + if relpath not in self.files: + self.files.append(relpath) + self.broadcast.broadcast({"add" : {relpath : { + "content" : base64_str_decode(event.src_path), + "mtime" : os.path.getmtime(event.src_path)}}}, self.route, self.channel) + suppress_fs_event(relpath) + + + def created(self, event): + self.modified(event) + + + def deleted(self, event): + relpath = os.path.relpath(event.src_path, self.folder) + if relpath in self.files: + del self.files[self.files.index(relpath)] + self.broadcast.broadcast({"del" : [relpath]}, self.route, self.channel) + self.suppress_fs_event(relpath) \ No newline at end of file