file_manager: add JSON-RPC "directory" APIs

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Arksine 2020-07-04 14:33:17 -04:00
parent 43c8affadf
commit 0e79b6f3f7
3 changed files with 24 additions and 10 deletions

View File

@ -297,9 +297,10 @@ that uses promises to return responses and errors (see json-rcp.js).
## File Operations ## File Operations
While all file transfer operations are available via the HTTP API, only Most file operations are available over both APIs, however file upload,
"get_file_list" and "get_metadata" are available over the websocket. Aside from file download, and file delete are currently only available via HTTP APIs.
the log files, currently the only root available is "gcodes" (at `http:\\host\server\files\gcodes\*`), however support for other "root" Aside from the log files, currently the only root available is "gcodes"
(at `http:\\host\server\files\gcodes\*`), however support for other "root"
directories may be added in the future. File upload, file delete, and directories may be added in the future. File upload, file delete, and
directory manipulation(mkdir and rmdir) will only be available on the "gcodes" directory manipulation(mkdir and rmdir) will only be available on the "gcodes"
root. root.
@ -385,7 +386,11 @@ subdirectories.
the "gcodes" file list by default. the "gcodes" file list by default.
- Websocket command:\ - Websocket command:\
Not Available `{jsonrpc: "2.0", method: "get_directory", params: {path: "gcodes/my_subdir"}
, id: <request id>}`
If the "params" are omitted then the command will return
the "gcodes" file list by default.
- Returns:\ - Returns:\
An object containing file and subdirectory information in the An object containing file and subdirectory information in the
@ -416,7 +421,8 @@ Creates a new directory at the specified path.
`POST /server/files/directory?path=gcodes/my_new_dir` `POST /server/files/directory?path=gcodes/my_new_dir`
- Websocket command:\ - Websocket command:\
Not Available `{jsonrpc: "2.0", method: "post_directory", params:
{path: "gcodes/my_new_dir"}, id: <request id>}`
Returns:\ Returns:\
`ok` if successful `ok` if successful
@ -428,13 +434,18 @@ Deletes a directory at the specified path.
`DELETE /server/files/directory?path=gcodes/my_subdir` `DELETE /server/files/directory?path=gcodes/my_subdir`
- Websocket command:\ - Websocket command:\
Not Available `{jsonrpc: "2.0", method: "delete_directory", params: {path: "gcodes/my_subdir"}
, id: <request id>}`
If the specified directory contains files then the delete request If the specified directory contains files then the delete request
will fail, however it is possible to "force" deletion of the directory will fail, however it is possible to "force" deletion of the directory
and all files in it with and additional argument in the query string:\ and all files in it with and additional argument in the query string:\
`DELETE /server/files/directory?path=gcodes/my_subdir&force=true` `DELETE /server/files/directory?path=gcodes/my_subdir&force=true`
OR to the JSON-RPC params:\
`{jsonrpc: "2.0", method: "get_directory", params:
{path: "gcodes/my_subdir", force: True}, id: <request id>}`
Note that a forced deletion will still check in with Klippy to be sure Note that a forced deletion will still check in with Klippy to be sure
that a file in the requested directory is not loaded by the virtual_sdcard. that a file in the requested directory is not loaded by the virtual_sdcard.

View File

@ -30,8 +30,8 @@ class FileManager:
"/server/files/metadata", "file_metadata", ['GET'], "/server/files/metadata", "file_metadata", ['GET'],
self._handle_metadata_request) self._handle_metadata_request)
self.server.register_endpoint( self.server.register_endpoint(
"/server/files/directory", None, ['GET', 'POST', 'DELETE'], "/server/files/directory", "directory", ['GET', 'POST', 'DELETE'],
self._handle_directory_request, http_only=True) self._handle_directory_request)
def _register_static_files(self, gcode_path): def _register_static_files(self, gcode_path):
self.server.register_static_file_handler( self.server.register_static_file_handler(
@ -93,7 +93,10 @@ class FileManager:
if not os.path.isdir(dir_path): if not os.path.isdir(dir_path):
raise self.server.error( raise self.server.error(
"Directory does not exist (%s)" % (directory)) "Directory does not exist (%s)" % (directory))
if args.get('force', "false").lower() == "true": force = args.get('force', False)
if isinstance(force, str):
force = force.lower() == "true"
if force:
# Make sure that the directory does not contain a file # Make sure that the directory does not contain a file
# loaded by the virtual_sdcard # loaded by the virtual_sdcard
await self._handle_operation_check(dir_path) await self._handle_operation_check(dir_path)

View File

@ -138,7 +138,7 @@ class WebsocketManager:
self.rpc.register_method(cmd, rpc_cb) self.rpc.register_method(cmd, rpc_cb)
def remove_handler(self, ws_method): def remove_handler(self, ws_method):
for prefix in ["get", "post"]: for prefix in ["get", "post", "delete"]:
self.rpc.remove_method(prefix + "_" + ws_method) self.rpc.remove_method(prefix + "_" + ws_method)
def _generate_callback(self, endpoint, request_method): def _generate_callback(self, endpoint, request_method):