Enqueue copied/moved files/folders for analysis

Fixes #1775
This commit is contained in:
Gina Häußge 2017-02-15 17:35:42 +01:00
parent 8630ec5beb
commit 1f9b8f40cd
2 changed files with 65 additions and 7 deletions

View file

@ -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)

View file

@ -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)