From 259c5199d6f94d6fb5bae40e063cbf30c35aefb4 Mon Sep 17 00:00:00 2001 From: shortcutme Date: Sat, 2 Feb 2019 00:11:47 +0100 Subject: [PATCH] siteListModifiedFiles admin command --- src/Content/ContentManager.py | 20 +++++++++++++ src/Ui/UiWebsocket.py | 54 +++++++++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/Content/ContentManager.py b/src/Content/ContentManager.py index 6b10b4b0..e2e2860a 100644 --- a/src/Content/ContentManager.py +++ b/src/Content/ContentManager.py @@ -349,6 +349,26 @@ class ContentManager(object): hash_id = self.hashfield.getHashId(file_info["sha512"]) return hash_id in self.hashfield + # Is modified since signing + def isModified(self, inner_path): + s = time.time() + if inner_path.endswith("content.json"): + try: + is_valid = self.verifyFile(inner_path, self.site.storage.open(inner_path), ignore_same=False) + if is_valid: + is_modified = False + else: + is_modified = True + except VerifyError: + is_modified = True + else: + try: + self.verifyFile(inner_path, self.site.storage.open(inner_path), ignore_same=False) + is_modified = False + except VerifyError: + is_modified = True + return is_modified + # Find the file info line from self.contents # Return: { "sha512": "c29d73d...21f518", "size": 41 , "content_inner_path": "content.json"} def getFileInfo(self, inner_path, new_file=False): diff --git a/src/Ui/UiWebsocket.py b/src/Ui/UiWebsocket.py index a155eb41..12b86c4d 100644 --- a/src/Ui/UiWebsocket.py +++ b/src/Ui/UiWebsocket.py @@ -23,11 +23,11 @@ from Content.ContentManager import VerifyError, SignError @PluginManager.acceptPlugins class UiWebsocket(object): admin_commands = set([ - "sitePause", "siteResume", "siteDelete", "siteList", "siteSetLimit", "siteAdd", + "sitePause", "siteResume", "siteDelete", "siteList", "siteSetLimit", "siteAdd", "siteListModifiedFiles", "channelJoinAllsite", "serverUpdate", "serverPortcheck", "serverShutdown", "serverShowdirectory", "serverGetWrapperNonce", "certSet", "certList", "configSet", "permissionAdd", "permissionRemove", "announcerStats", "userSetGlobalSettings" ]) - async_commands = set(["fileGet", "fileList", "dirList", "fileNeed", "serverPortcheck"]) + async_commands = set(["fileGet", "fileList", "dirList", "fileNeed", "serverPortcheck", "siteListModifiedFiles"]) def __init__(self, ws, site, server, user, request): self.ws = ws @@ -1002,6 +1002,56 @@ class UiWebsocket(object): else: return {"error": "Invalid address"} + def actionSiteListModifiedFiles(self, to, content_inner_path="content.json"): + content = self.site.content_manager.contents[content_inner_path] + min_mtime = content.get("modified", 0) + site_path = self.site.storage.directory + modified_files = [] + + # Load cache if not signed since last modified check + if content.get("modified", 0) < self.site.settings["cache"].get("time_modified_files_check"): + min_mtime = self.site.settings["cache"].get("time_modified_files_check") + modified_files = self.site.settings["cache"].get("modified_files", []) + + inner_paths = [content_inner_path] + content.get("includes", {}).keys() + content.get("files", {}).keys() + + for relative_inner_path in inner_paths: + inner_path = helper.getDirname(content_inner_path) + relative_inner_path + try: + is_mtime_newer = os.path.getmtime(self.site.storage.getPath(inner_path)) > min_mtime + 1 + if is_mtime_newer: + if inner_path.endswith("content.json"): + is_modified = self.site.content_manager.isModified(inner_path) + else: + previous_size = content["files"][inner_path]["size"] + is_same_size = self.site.storage.getSize(inner_path) == previous_size + ext = inner_path.rsplit(".", 1)[-1] + is_text_file = ext in ["json", "txt", "html", "js", "css"] + if is_same_size: + if is_text_file: + is_modified = self.site.content_manager.isModified(inner_path) # Check sha512 hash + else: + is_modified = False + else: + is_modified = True + + # Check ran, modified back to original value, but in the cache + if not is_modified and inner_path in modified_files: + modified_files.remove(inner_path) + else: + is_modified = False + except Exception as err: + if not self.site.storage.isFile(inner_path): # File deleted + is_modified = True + else: + raise err + if is_modified and inner_path not in modified_files: + modified_files.append(inner_path) + + self.site.settings["cache"]["time_modified_files_check"] = time.time() + self.site.settings["cache"]["modified_files"] = modified_files + return {"modified_files": modified_files} + def actionUserGetSettings(self, to): settings = self.user.sites.get(self.site.address, {}).get("settings", {}) self.response(to, settings)