From 1f9b8f40cdd4e85107073372c2fe421b2568f6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Wed, 15 Feb 2017 17:35:42 +0100 Subject: [PATCH] Enqueue copied/moved files/folders for analysis Fixes #1775 --- src/octoprint/filemanager/__init__.py | 34 +++++++++++++++++++----- src/octoprint/filemanager/storage.py | 38 ++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/octoprint/filemanager/__init__.py b/src/octoprint/filemanager/__init__.py index c7702993..f1db3460 100644 --- a/src/octoprint/filemanager/__init__.py +++ b/src/octoprint/filemanager/__init__.py @@ -205,17 +205,26 @@ class FileManager(object): # callback was not registered pass - def _determine_analysis_backlog(self, storage_type, storage_manager): + def _determine_analysis_backlog(self, storage_type, storage_manager, root=None, high_priority=False): counter = 0 - for entry, path, printer_profile in storage_manager.analysis_backlog: + + backlog_generator = storage_manager.analysis_backlog + if root is not None: + backlog_generator = storage_manager.analysis_backlog_for_path(path=root) + + for entry, path, printer_profile in backlog_generator: file_type = get_file_type(path)[-1] file_name = storage_manager.split_path(path) # we'll use the default printer profile for the backlog since we don't know better queue_entry = QueueEntry(file_name, entry, file_type, storage_type, path, self._printer_profile_manager.get_default()) - if self._analysis_queue.enqueue(queue_entry, high_priority=False): + if self._analysis_queue.enqueue(queue_entry, high_priority=high_priority): counter += 1 - self._logger.info("Added {counter} items from storage type \"{storage_type}\" to analysis queue".format(**locals())) + + if root: + self._logger.info("Added {counter} items from storage type \"{storage_type}\" and root \"{root}\" to analysis queue".format(**locals())) + else: + self._logger.info("Added {counter} items from storage type \"{storage_type}\" to analysis queue".format(**locals())) def add_storage(self, storage_type, storage_manager): self._storage_managers[storage_type] = storage_manager @@ -415,13 +424,21 @@ class FileManager(object): eventManager().fire(Events.UPDATED_FILES, dict(type="printables")) def copy_file(self, destination, source, dst): - self._storage(destination).copy_file(source, dst) + path = self._storage(destination).copy_file(source, dst) + if not self.has_analysis(destination, path): + queue_entry = self._analysis_queue_entry(destination, path) + if queue_entry: + self._analysis_queue.enqueue(queue_entry) eventManager().fire(Events.UPDATED_FILES, dict(type="printables")) def move_file(self, destination, source, dst): queue_entry = self._analysis_queue_entry(destination, source) self._analysis_queue.dequeue(queue_entry) - self._storage(destination).move_file(source, dst) + path = self._storage(destination).move_file(source, dst) + if not self.has_analysis(destination, path): + queue_entry = self._analysis_queue_entry(destination, path) + if queue_entry: + self._analysis_queue.enqueue(queue_entry) eventManager().fire(Events.UPDATED_FILES, dict(type="printables")) def add_folder(self, destination, path, ignore_existing=True): @@ -438,15 +455,20 @@ class FileManager(object): def copy_folder(self, destination, source, dst): self._storage(destination).copy_folder(source, dst) + self._determine_analysis_backlog(destination, self._storage(destination), root=dst) eventManager().fire(Events.UPDATED_FILES, dict(type="printables")) def move_folder(self, destination, source, dst): self._analysis_queue.dequeue_folder(destination, source) self._analysis_queue.pause() self._storage(destination).move_folder(source, dst) + self._determine_analysis_backlog(destination, self._storage(destination), root=dst) self._analysis_queue.resume() eventManager().fire(Events.UPDATED_FILES, dict(type="printables")) + def has_analysis(self, destination, path): + return self._storage(destination).has_analysis(path) + def get_metadata(self, destination, path): return self._storage(destination).get_metadata(path) diff --git a/src/octoprint/filemanager/storage.py b/src/octoprint/filemanager/storage.py index 404416ba..46a3d63f 100644 --- a/src/octoprint/filemanager/storage.py +++ b/src/octoprint/filemanager/storage.py @@ -44,6 +44,11 @@ class StorageInterface(object): return yield + def analysis_backlog_for_path(self, path=None): + # empty generator pattern, yield is intentionally unreachable + return + yield + def last_modified(self, path=None, recursive=False): """ Get the last modification date of the specified ``path`` or ``path``'s subtree. @@ -174,6 +179,8 @@ class StorageInterface(object): :param string source: path to the source folder :param string destination: path to destination + + :return: the path in the storage to the copy of the folder """ raise NotImplementedError() @@ -183,6 +190,8 @@ class StorageInterface(object): :param string source: path to the source folder :param string destination: path to destination + + :return: the new path in the storage to the folder """ raise NotImplementedError() @@ -216,6 +225,8 @@ class StorageInterface(object): :param string source: path to the source file :param string destination: path to destination + + :return: the path in the storage to the copy of the file """ raise NotImplementedError() @@ -225,6 +236,16 @@ class StorageInterface(object): :param string source: path to the source file :param string destination: path to destination + + :return: the new path in the storage to the file + """ + raise NotImplementedError() + + def has_analysis(self, path): + """ + Returns whether the file at path has been analysed yet + + :param path: virtual path to the file for which to retrieve the metadata """ raise NotImplementedError() @@ -462,7 +483,10 @@ class LocalFileStorage(StorageInterface): @property def analysis_backlog(self): - for entry in self._analysis_backlog_generator(): + return self.analysis_backlog_for_path() + + def analysis_backlog_for_path(self, path=None): + for entry in self._analysis_backlog_generator(path): yield entry def _analysis_backlog_generator(self, path=None): @@ -604,6 +628,8 @@ class LocalFileStorage(StorageInterface): except Exception as e: raise StorageError("Could not copy %s in %s to %s in %s" % (source_data["name"], source_data["path"], destination_data["name"], destination_data["path"]), cause=e) + return self.path_in_storage(destination_data["fullpath"]) + def move_folder(self, source, destination): source_data, destination_data = self._get_source_destination_data(source, destination) @@ -614,6 +640,8 @@ class LocalFileStorage(StorageInterface): self._delete_metadata(source_data["fullpath"]) + return self.path_in_storage(destination_data["fullpath"]) + def add_file(self, path, file_object, printer_profile=None, links=None, allow_overwrite=False): path, name = self.sanitize(path) if not octoprint.filemanager.valid_file_type(name): @@ -687,6 +715,8 @@ class LocalFileStorage(StorageInterface): self._copy_metadata_entry(source_data["path"], source_data["name"], destination_data["path"], destination_data["name"]) + return self.path_in_storage(destination_data["fullpath"]) + def move_file(self, source, destination, allow_overwrite=False): source_data, destination_data = self._get_source_destination_data(source, destination) @@ -699,6 +729,12 @@ class LocalFileStorage(StorageInterface): destination_data["path"], destination_data["name"], delete_source=True) + return self.path_in_storage(destination_data["fullpath"]) + + def has_analysis(self, path): + metadata = self.get_metadata(path) + return "analysis" in metadata + def get_metadata(self, path): path, name = self.sanitize(path) return self._get_metadata_entry(path, name)