From c335b62d26db63630e8a8f1521f467852ddd08a8 Mon Sep 17 00:00:00 2001 From: Arksine Date: Thu, 20 May 2021 08:35:26 -0400 Subject: [PATCH] file_manager: fix sync issues with hidden directories While inotify watches are not applied to hidden directories it is still valid to use Moonraker's endpoints to perform operations on them. When performing an operation on an item within a hidden directory, or on a hidden directory itself, do not sync the request with inotify. Signed-off-by: Eric Callahan --- moonraker/components/file_manager.py | 31 +++++++++++++++++++++------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/moonraker/components/file_manager.py b/moonraker/components/file_manager.py index ddc2d93..1f1a0f6 100644 --- a/moonraker/components/file_manager.py +++ b/moonraker/components/file_manager.py @@ -192,6 +192,13 @@ class FileManager: return "" return os.path.relpath(full_path, start=root_dir) + def has_hidden_dir(self, rel_path: str) -> bool: + parts = rel_path.split("/") + for part in parts: + if part and part[0] == '.': + return True + return False + def check_file_exists(self, root: str, filename: str) -> bool: root_dir = self.file_paths.get(root, "") file_path = os.path.join(root_dir, filename) @@ -267,7 +274,8 @@ class FileManager: self.notify_sync_lock.cancel() self.notify_sync_lock = None raise - await self.notify_sync_lock.wait(30.) + if not self.has_hidden_dir(directory): + await self.notify_sync_lock.wait(30.) self.notify_sync_lock = None else: try: @@ -363,7 +371,9 @@ class FileManager: self.notify_sync_lock = None raise self.server.error(str(e)) self.notify_sync_lock.update_dest(full_dest) - await self.notify_sync_lock.wait(600.) + if not self.has_hidden_dir(self.get_relative_path( + dest_root, full_dest)): + await self.notify_sync_lock.wait(600.) self.notify_sync_lock = None result['item']['path'] = self.get_relative_path(dest_root, full_dest) return result @@ -420,7 +430,7 @@ class FileManager: try: upload_info = self._parse_upload_args(form_args) root = upload_info['root'] - if root == "gcodes": + if root == "gcodes" and upload_info['ext'] in VALID_GCODE_EXTS: result = await self._finish_gcode_upload(upload_info) elif root in FULL_ACCESS_ROOTS: result = await self._finish_standard_upload(upload_info) @@ -472,7 +482,8 @@ class FileManager: 'dest_path': dest_path, 'tmp_file_path': upload_args['tmp_file_path'], 'start_print': start_print, - 'unzip_ufp': unzip_ufp + 'unzip_ufp': unzip_ufp, + 'ext': f_ext } async def _finish_gcode_upload(self, @@ -507,7 +518,9 @@ class FileManager: except self.server.error: # Attempt to start print failed start_print = False - await self.notify_sync_lock.wait(300.) + rel_dir_path = os.path.dirname(upload_info['filename']) + if not self.has_hidden_dir(rel_dir_path): + await self.notify_sync_lock.wait(300.) self.notify_sync_lock = None return { 'item': { @@ -521,7 +534,12 @@ class FileManager: async def _finish_standard_upload(self, upload_info: Dict[str, Any] ) -> Dict[str, Any]: + self.notify_sync_lock = NotifySyncLock(upload_info['dest_path']) self._process_uploaded_file(upload_info) + rel_dir_path = os.path.dirname(upload_info['filename']) + if not self.has_hidden_dir(rel_dir_path): + await self.notify_sync_lock.wait(5.) + self.notify_sync_lock = None return { 'item': { 'path': upload_info['filename'], @@ -1211,9 +1229,6 @@ class INotifyHandler: ext: str = os.path.splitext(evt.name)[-1].lower() root = node.get_root() node_path = node.get_path() - if root == "gcodes" and ext not in VALID_GCODE_EXTS: - # Don't notify files with invalid gcode extensions - return if evt.mask & iFlags.CREATE: logging.debug(f"Inotify file create: {root}, " f"{node_path}, {evt.name}")