New events: FileAdded, FileRemoved, FolderAdded, FolderRemoved

Closes #1092
This commit is contained in:
Gina Häußge 2017-04-03 11:44:20 +02:00
parent 1219939189
commit b24851ca05
5 changed files with 143 additions and 20 deletions

View file

@ -152,7 +152,7 @@ File handling
-------------
Upload
A file has been uploaded.
A file has been uploaded through the web interface.
Payload:
* ``name``: the file's name
@ -165,19 +165,74 @@ Upload
Still available for reasons of backwards compatibility. Will be removed with 1.4.0.
FileAdded
A file has been added to a storage.
Payload:
* ``storage``: the storage's identifier
* ``path``: the file's path within its storage location
* ``name``: the file's name
* ``type``: the file's type, a list of the path within the type hierarchy, e.g. ``["machinecode", "gcode"]`` or
``["model", "stl"]``
.. note::
A copied file triggers this for its new path. A moved file first triggers ``FileRemoved`` for its original
path and then ``FileAdded`` for the new one.
FileRemoved
A file has been removed from a storage.
Payload:
* ``storage``: the storage's identifier
* ``path``: the file's path within its storage location
* ``name``: the file's name
* ``type``: the file's type, a list of the path within the type hierarchy, e.g. ``["machinecode", "gcode"]`` or
``["model", "stl"]``
.. note::
A moved file first triggers ``FileRemoved`` for its original path and then ``FileAdded`` for the new one.
FolderAdded
A folder has been added to a storage.
Payload:
* ``storage``: the storage's identifier
* ``path``: the folders's path within its storage location
* ``name``: the folders's name
.. note::
A copied folder triggers this for its new path. A moved folder first triggers ``FolderRemoved`` for its original
path and then ``FolderAdded`` for the new one.
FolderRemoved
A folder has been removed from a storage.
Payload:
* ``storage``: the storage's identifier
* ``path``: the folders's path within its storage location
* ``name``: the folders's name
.. note::
A moved folder first triggers ``FolderRemoved`` for its original path and then ``FolderAdded`` for the new one.
UpdatedFiles
A file list was modified.
Payload:
* ``type``: the type of file list that was modified. Currently only ``printables`` and ``gcode`` (DEPRECATED) are supported here.
* ``type``: the type of file list that was modified. Only ``printables`` is supported here. See the deprecation
note below.
.. note::
.. deprecated:: 1.2.0
The ``gcode`` modification type has been superceeded by ``printables``. It is currently still available for
reasons of backwards compatibility and will also be sent on modification of ``printables``. It will however
be removed with 1.4.0.
The type ``gcode`` has been renamed to ``printables`` with the introduction of a new file management layer that
supports STL files as first class citizens as well. For reasons of backwards compatibility the ``UpdatedFiles``
event for printable files will be fired twice, once with ``type`` set to ``gcode``, once set to ``printables``.
Support for the ``gcode`` type will be removed in the next release after version 1.2.0.
MetadataAnalysisStarted
The metadata analysis of a file has started.

View file

@ -53,6 +53,11 @@ class Events(object):
METADATA_ANALYSIS_FINISHED = "MetadataAnalysisFinished"
METADATA_STATISTICS_UPDATED = "MetadataStatisticsUpdated"
FILE_ADDED = "FileAdded",
FILE_REMOVED = "FileRemoved",
FOLDER_ADDED = "FolderAdded",
FOLDER_REMOVED = "FolderRemoved",
# SD Upload
TRANSFER_STARTED = "TransferStarted"
TRANSFER_DONE = "TransferDone"

View file

@ -409,30 +409,47 @@ class FileManager(object):
queue_entry = self._analysis_queue_entry(destination, path)
self._analysis_queue.dequeue(queue_entry)
file_path = self._storage(destination).add_file(path, file_object, links=links, printer_profile=printer_profile, allow_overwrite=allow_overwrite)
path_in_storage = self._storage(destination).add_file(path, file_object, links=links, printer_profile=printer_profile, allow_overwrite=allow_overwrite)
if analysis is None:
queue_entry = self._analysis_queue_entry(destination, file_path, printer_profile=printer_profile)
queue_entry = self._analysis_queue_entry(destination, path_in_storage, printer_profile=printer_profile)
if queue_entry:
self._analysis_queue.enqueue(queue_entry, high_priority=True)
else:
self._add_analysis_result(destination, path, analysis)
_, name = self._storage(destination).split_path(path_in_storage)
eventManager().fire(Events.FILE_ADDED, dict(storage=destination,
path=path_in_storage,
name=name,
type=get_file_type(name)))
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
return file_path
return path_in_storage
def remove_file(self, destination, path):
queue_entry = self._analysis_queue_entry(destination, path)
self._analysis_queue.dequeue(queue_entry)
self._storage(destination).remove_file(path)
_, name = self._storage(destination).split_path(path)
eventManager().fire(Events.FILE_REMOVED, dict(storage=destination,
path=path,
name=name,
type=get_file_type(name)))
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
def copy_file(self, destination, 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)
path_in_storage = self._storage(destination).copy_file(source, dst)
if not self.has_analysis(destination, path_in_storage):
queue_entry = self._analysis_queue_entry(destination, path_in_storage)
if queue_entry:
self._analysis_queue.enqueue(queue_entry)
_, name = self._storage(destination).split_path(path_in_storage)
eventManager().fire(Events.FILE_ADDED, dict(storage=destination,
path=path_in_storage,
name=name,
type=get_file_type(name)))
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
def move_file(self, destination, source, dst):
@ -443,23 +460,52 @@ class FileManager(object):
queue_entry = self._analysis_queue_entry(destination, path)
if queue_entry:
self._analysis_queue.enqueue(queue_entry)
source_path_in_storage = self._storage(destination).path_in_storage(source)
_, source_name = self._storage(destination).split_path(source_path_in_storage)
dst_path_in_storage = self._storage(destination).path_in_storage(dst)
_, dst_name = self._storage(destination).split_path(dst_path_in_storage)
eventManager().fire(Events.FILE_REMOVED, dict(storage=destination,
path=source_path_in_storage,
name=source_name,
type=get_file_type(source_name)))
eventManager().fire(Events.FILE_ADDED, dict(storage=destination,
path=dst_path_in_storage,
name=dst_name,
type=get_file_type(dst_name)))
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
def add_folder(self, destination, path, ignore_existing=True):
folder_path = self._storage(destination).add_folder(path, ignore_existing=ignore_existing)
path_in_storage = self._storage(destination).add_folder(path, ignore_existing=ignore_existing)
_, name = self._storage(destination).split_path(path_in_storage)
eventManager().fire(Events.FOLDER_ADDED, dict(storage=destination,
path=path_in_storage,
name=name))
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
return folder_path
return path_in_storage
def remove_folder(self, destination, path, recursive=True):
self._analysis_queue.dequeue_folder(destination, path)
self._analysis_queue.pause()
self._storage(destination).remove_folder(path, recursive=recursive)
self._analysis_queue.resume()
_, name = self._storage(destination).split_path(path)
eventManager().fire(Events.FOLDER_REMOVED, dict(storage=destination,
path=path,
name=name))
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
def copy_folder(self, destination, source, dst):
self._storage(destination).copy_folder(source, dst)
path_in_storage = self._storage(destination).copy_folder(source, dst)
self._determine_analysis_backlog(destination, self._storage(destination), root=dst)
_, name = self._storage(destination).split_path(path_in_storage)
eventManager().fire(Events.FOLDER_ADDED, dict(storage=destination,
path=path_in_storage,
name=name))
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
def move_folder(self, destination, source, dst):
@ -468,6 +514,18 @@ class FileManager(object):
self._storage(destination).move_folder(source, dst)
self._determine_analysis_backlog(destination, self._storage(destination), root=dst)
self._analysis_queue.resume()
source_path_in_storage = self._storage(destination).path_in_storage(source)
_, source_name = self._storage(destination).split_path(source_path_in_storage)
dst_path_in_storage = self._storage(destination).path_in_storage(destination)
_, dst_name = self._storage(destination).split_path(dst_path_in_storage)
eventManager().fire(Events.FOLDER_REMOVED, dict(storage=destination,
path=source_path_in_storage,
name=source_name))
eventManager().fire(Events.FOLDER_ADDED, dict(storage=destination,
path=dst_path_in_storage,
name=dst_name))
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
def has_analysis(self, destination, path):

View file

@ -29,7 +29,6 @@ class StorageInterface(object):
Interface of storage adapters for OctoPrint.
"""
@property
def analysis_backlog(self):
"""
@ -155,7 +154,9 @@ class StorageInterface(object):
def add_folder(self, path, ignore_existing=True):
"""
Adds a folder as ``path``. The ``path`` will be sanitized.
Adds a folder as ``path``
The ``path`` will be sanitized.
:param string path: the path of the new folder
:param bool ignore_existing: if set to True, no error will be raised if the folder to be added already exists
@ -165,7 +166,7 @@ class StorageInterface(object):
def remove_folder(self, path, recursive=True):
"""
Removes the folder at ``path``.
Removes the folder at ``path``
:param string path: the path of the folder to remove
:param bool recursive: if set to True, contained folders and files will also be removed, otherwise and error will
@ -212,7 +213,9 @@ class StorageInterface(object):
def remove_file(self, path):
"""
Removes the file at ``path``. Will also take care of deleting the corresponding entries
Removes the file at ``path``
Will also take care of deleting the corresponding entries
in the metadata and deleting all links pointing to the file.
:param string path: path of the file to remove

View file

@ -194,8 +194,10 @@ class Server(object):
eventManager = events.eventManager()
analysisQueue = octoprint.filemanager.analysis.AnalysisQueue()
slicingManager = octoprint.slicing.SlicingManager(self._settings.getBaseFolder("slicingProfiles"), printerProfileManager)
storage_managers = dict()
storage_managers[octoprint.filemanager.FileDestinations.LOCAL] = octoprint.filemanager.storage.LocalFileStorage(self._settings.getBaseFolder("uploads"))
fileManager = octoprint.filemanager.FileManager(analysisQueue, slicingManager, printerProfileManager, initial_storage_managers=storage_managers)
appSessionManager = util.flask.AppSessionManager()
pluginLifecycleManager = LifecycleManager(pluginManager)