file_manager: implement file_list_changed notifcation

This notification is moved from moonraker.py.  Instead of sending a filelist, it now updates the file list and sends all relevant information to the client.

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Arksine 2020-07-26 20:05:43 -04:00 committed by Eric Callahan
parent 829dd27aa2
commit b6f8ba775c
4 changed files with 30 additions and 28 deletions

View File

@ -338,8 +338,10 @@ class FileRequestHandler(AuthorizedFileHandler):
403, "File is loaded, DELETE not permitted") 403, "File is loaded, DELETE not permitted")
os.remove(self.absolute_path) os.remove(self.absolute_path)
filename = os.path.basename(self.absolute_path) base = self.request.path.lstrip("/").split("/")[2]
self.server.notify_filelist_changed(filename, 'removed') filename = self.path.lstrip("/")
file_manager = self.server.lookup_plugin('file_manager')
file_manager.notify_filelist_changed(filename, 'removed', base)
self.finish({'result': filename}) self.finish({'result': filename})
class FileUploadHandler(AuthorizedRequestHandler): class FileUploadHandler(AuthorizedRequestHandler):

View File

@ -336,16 +336,6 @@ class Server:
ServerError("Klippy Host not connected", 503)) ServerError("Klippy Host not connected", 503))
return base_request return base_request
def notify_filelist_changed(self, filename, action):
file_manager = self.lookup_plugin('file_manager')
try:
filelist = file_manager.get_file_list(format_list=True)
except ServerError:
filelist = []
result = {'filename': filename, 'action': action,
'filelist': filelist}
self.send_event("server:filelist_changed", result)
async def _kill_server(self): async def _kill_server(self):
# XXX - Currently this function is not used. # XXX - Currently this function is not used.
# Should I expose functionality to shutdown # Should I expose functionality to shutdown

View File

@ -90,18 +90,19 @@ class FileManager:
async def _handle_directory_request(self, path, method, args): async def _handle_directory_request(self, path, method, args):
directory = args.get('path', "gcodes") directory = args.get('path', "gcodes")
base, dir_path = self._convert_path(directory) base, url_path, dir_path = self._convert_path(directory)
method = method.upper() method = method.upper()
if method == 'GET': if method == 'GET':
# Get list of files and subdirectories for this target # Get list of files and subdirectories for this target
return self._list_directory(dir_path) return self._list_directory(dir_path)
elif method == 'POST' and base == "gcodes": elif method == 'POST' and base in ["gcodes", "config"]:
# Create a new directory # Create a new directory
try: try:
os.mkdir(dir_path) os.mkdir(dir_path)
except Exception as e: except Exception as e:
raise self.server.error(str(e)) raise self.server.error(str(e))
elif method == 'DELETE' and base == "gcodes": self.notify_filelist_changed(url_path, "add_directory", base)
elif method == 'DELETE' and base in ["gcodes", "config"]:
# Remove a directory # Remove a directory
if directory.strip("/") == base: if directory.strip("/") == base:
raise self.server.error( raise self.server.error(
@ -117,15 +118,12 @@ class FileManager:
# loaded by the virtual_sdcard # loaded by the virtual_sdcard
await self._handle_operation_check(dir_path) await self._handle_operation_check(dir_path)
shutil.rmtree(dir_path) shutil.rmtree(dir_path)
# since it is possible that the directory contains
# files, send a notification to clients
self.server.notify_filelist_changed(
directory, "delete_directory")
else: else:
try: try:
os.rmdir(dir_path) os.rmdir(dir_path)
except Exception as e: except Exception as e:
raise self.server.error(str(e)) raise self.server.error(str(e))
self.notify_filelist_changed(url_path, "delete_directory", base)
else: else:
raise self.server.error("Operation Not Supported", 405) raise self.server.error("Operation Not Supported", 405)
return "ok" return "ok"
@ -158,10 +156,11 @@ class FileManager:
if base not in self.file_paths: if base not in self.file_paths:
raise self.server.error("Invalid base path (%s)" % (base)) raise self.server.error("Invalid base path (%s)" % (base))
root_path = local_path = self.file_paths[base] root_path = local_path = self.file_paths[base]
url_path = ""
if len(parts) > 1: if len(parts) > 1:
target = "/".join(parts[1:]) url_path = "/".join(parts[1:])
local_path = os.path.join(root_path, target) local_path = os.path.join(root_path, url_path)
return base, local_path return base, url_path, local_path
async def _handle_file_move_copy(self, path, method, args): async def _handle_file_move_copy(self, path, method, args):
source = args.get("source") source = args.get("source")
@ -171,9 +170,9 @@ class FileManager:
if destination is None: if destination is None:
raise self.server.error( raise self.server.error(
"File move/copy request missing destination") "File move/copy request missing destination")
source_base, source_path = self._convert_path(source) source_base, src_url_path, source_path = self._convert_path(source)
dest_base, dest_path = self._convert_path(destination) dest_base, dst_url_path, dest_path = self._convert_path(destination)
if source_base != "gcodes" or dest_base != "gcodes": if source_base != dest_base or source_base not in ["gcodes", "config"]:
raise self.server.error( raise self.server.error(
"Unsupported root directory: source=%s base=%s" % "Unsupported root directory: source=%s base=%s" %
(source_base, dest_base)) (source_base, dest_base))
@ -200,7 +199,8 @@ class FileManager:
except Exception as e: except Exception as e:
raise self.server.error(str(e)) raise self.server.error(str(e))
action = "file_copy" action = "file_copy"
self.server.notify_filelist_changed(destination, action) self.notify_filelist_changed(
dst_url_path, action, dest_base, {'prev_file': src_url_path})
return "ok" return "ok"
def _list_directory(self, path): def _list_directory(self, path):
@ -335,7 +335,7 @@ class FileManager:
except self.server.error: except self.server.error:
# Attempt to start print failed # Attempt to start print failed
start_print = False start_print = False
self.server.notify_filelist_changed(upload['filename'], 'added') self.notify_filelist_changed(upload['filename'], 'added', "gcodes")
return {'result': upload['filename'], 'print_started': start_print} return {'result': upload['filename'], 'print_started': start_print}
def _do_config_upload(self, request): def _do_config_upload(self, request):
@ -348,6 +348,9 @@ class FileManager:
"Printer configuration location on disk not set") "Printer configuration location on disk not set")
upload = self._get_upload_info(request, cfg_path) upload = self._get_upload_info(request, cfg_path)
self._write_file(upload) self._write_file(upload)
if cfg_base == "config":
self.notify_filelist_changed(
upload['filename'], 'added', "config")
return {'result': upload['filename']} return {'result': upload['filename']}
def _get_argument(self, request, name, default=None): def _get_argument(self, request, name, default=None):
@ -466,5 +469,12 @@ class FileManager:
raise self.server.error("Invalid file path: %s" % (path)) raise self.server.error("Invalid file path: %s" % (path))
os.remove(full_path) os.remove(full_path)
def notify_filelist_changed(self, fname, action, base, params={}):
self._update_file_list(base)
result = {'filename': fname, 'action': action, 'root': base}
if params:
result.update(params)
self.server.send_event("file_manager:filelist_changed", result)
def load_plugin(server): def load_plugin(server):
return FileManager(server) return FileManager(server)

View File

@ -110,7 +110,7 @@ class WebsocketManager:
self.server.register_event_handler( self.server.register_event_handler(
"server:status_update", self._handle_status_update) "server:status_update", self._handle_status_update)
self.server.register_event_handler( self.server.register_event_handler(
"server:filelist_changed", self._handle_filelist_changed) "file_manager:filelist_changed", self._handle_filelist_changed)
async def _handle_klippy_state_changed(self, state): async def _handle_klippy_state_changed(self, state):
await self.notify_websockets("klippy_state_changed", state) await self.notify_websockets("klippy_state_changed", state)