file_manager: use the job queue to start gcode uploads
If a print cannot be started then it will be queued. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
b135f48867
commit
7a8aeae673
|
@ -30,6 +30,7 @@ from typing import (
|
||||||
TypeVar,
|
TypeVar,
|
||||||
cast,
|
cast,
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from inotify_simple import Event as InotifyEvent
|
from inotify_simple import Event as InotifyEvent
|
||||||
from moonraker import Server
|
from moonraker import Server
|
||||||
|
@ -38,6 +39,7 @@ if TYPE_CHECKING:
|
||||||
from components import database
|
from components import database
|
||||||
from components import klippy_apis
|
from components import klippy_apis
|
||||||
from components import shell_command
|
from components import shell_command
|
||||||
|
from components.job_queue import JobQueue
|
||||||
DBComp = database.MoonrakerDatabase
|
DBComp = database.MoonrakerDatabase
|
||||||
APIComp = klippy_apis.KlippyAPI
|
APIComp = klippy_apis.KlippyAPI
|
||||||
SCMDComp = shell_command.ShellCommandFactory
|
SCMDComp = shell_command.ShellCommandFactory
|
||||||
|
@ -65,6 +67,8 @@ class FileManager:
|
||||||
self.write_mutex = asyncio.Lock()
|
self.write_mutex = asyncio.Lock()
|
||||||
self.notify_sync_lock: Optional[NotifySyncLock] = None
|
self.notify_sync_lock: Optional[NotifySyncLock] = None
|
||||||
self.fixed_path_args: Dict[str, Any] = {}
|
self.fixed_path_args: Dict[str, Any] = {}
|
||||||
|
self.queue_gcodes: bool = config.getboolean('queue_gcode_uploads',
|
||||||
|
False)
|
||||||
|
|
||||||
# Register file management endpoints
|
# Register file management endpoints
|
||||||
self.server.register_endpoint(
|
self.server.register_endpoint(
|
||||||
|
@ -287,21 +291,21 @@ class FileManager:
|
||||||
# Get virtual_sdcard status
|
# Get virtual_sdcard status
|
||||||
kapis: APIComp = self.server.lookup_component('klippy_apis')
|
kapis: APIComp = self.server.lookup_component('klippy_apis')
|
||||||
result: Dict[str, Any]
|
result: Dict[str, Any]
|
||||||
result = await kapis.query_objects({'print_stats': None})
|
result = await kapis.query_objects({'print_stats': None}, {})
|
||||||
pstats = result.get('print_stats', {})
|
pstats = result.get('print_stats', {})
|
||||||
loaded_file: str = pstats.get('filename', "")
|
loaded_file: str = pstats.get('filename', "")
|
||||||
state: str = pstats.get('state', "")
|
state: str = pstats.get('state', "")
|
||||||
gc_path = self.file_paths.get('gcodes', "")
|
gc_path = self.file_paths.get('gcodes', "")
|
||||||
full_path = os.path.join(gc_path, loaded_file)
|
full_path = os.path.join(gc_path, loaded_file)
|
||||||
if loaded_file and state != "complete":
|
is_printing = state in ["printing", "paused"]
|
||||||
|
if loaded_file and is_printing:
|
||||||
if os.path.isdir(requested_path):
|
if os.path.isdir(requested_path):
|
||||||
# Check to see of the loaded file is in the request
|
# Check to see of the loaded file is in the request
|
||||||
if full_path.startswith(requested_path):
|
if full_path.startswith(requested_path):
|
||||||
raise self.server.error("File currently in use", 403)
|
raise self.server.error("File currently in use", 403)
|
||||||
elif full_path == requested_path:
|
elif full_path == requested_path:
|
||||||
raise self.server.error("File currently in use", 403)
|
raise self.server.error("File currently in use", 403)
|
||||||
ongoing = state in ["printing", "paused"]
|
return not is_printing
|
||||||
return ongoing
|
|
||||||
|
|
||||||
def _convert_request_path(self, request_path: str) -> Tuple[str, str]:
|
def _convert_request_path(self, request_path: str) -> Tuple[str, str]:
|
||||||
# Parse the root, relative path, and disk path from a remote request
|
# Parse the root, relative path, and disk path from a remote request
|
||||||
|
@ -504,43 +508,48 @@ class FileManager:
|
||||||
async def _finish_gcode_upload(self,
|
async def _finish_gcode_upload(self,
|
||||||
upload_info: Dict[str, Any]
|
upload_info: Dict[str, Any]
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
print_ongoing: bool = False
|
|
||||||
start_print: bool = upload_info['start_print']
|
|
||||||
# Verify that the operation can be done if attempting to upload a gcode
|
# Verify that the operation can be done if attempting to upload a gcode
|
||||||
|
can_start: bool = False
|
||||||
try:
|
try:
|
||||||
check_path: str = upload_info['dest_path']
|
check_path: str = upload_info['dest_path']
|
||||||
print_ongoing = await self._handle_operation_check(
|
can_start = await self._handle_operation_check(check_path)
|
||||||
check_path)
|
|
||||||
except self.server.error as e:
|
except self.server.error as e:
|
||||||
if e.status_code == 403:
|
if e.status_code == 403:
|
||||||
raise self.server.error(
|
raise self.server.error(
|
||||||
"File is loaded, upload not permitted", 403)
|
"File is loaded, upload not permitted", 403)
|
||||||
else:
|
|
||||||
# Couldn't reach Klippy, so it should be safe
|
|
||||||
# to permit the upload but not start
|
|
||||||
start_print = False
|
|
||||||
# Don't start if another print is currently in progress
|
|
||||||
start_print = start_print and not print_ongoing
|
|
||||||
self.notify_sync_lock = NotifySyncLock(upload_info['dest_path'])
|
self.notify_sync_lock = NotifySyncLock(upload_info['dest_path'])
|
||||||
finfo = await self._process_uploaded_file(upload_info)
|
finfo = await self._process_uploaded_file(upload_info)
|
||||||
await self.gcode_metadata.parse_metadata(
|
await self.gcode_metadata.parse_metadata(
|
||||||
upload_info['filename'], finfo).wait()
|
upload_info['filename'], finfo).wait()
|
||||||
if start_print:
|
started: bool = False
|
||||||
# Make a Klippy Request to "Start Print"
|
queued: bool = False
|
||||||
kapis: APIComp = self.server.lookup_component('klippy_apis')
|
if upload_info['start_print']:
|
||||||
try:
|
if self.queue_gcodes:
|
||||||
await kapis.start_print(upload_info['filename'])
|
job_queue: JobQueue = self.server.lookup_component('job_queue')
|
||||||
except self.server.error:
|
started = await job_queue.queue_job(
|
||||||
# Attempt to start print failed
|
upload_info['filename'], check_exists=False)
|
||||||
start_print = False
|
queued = not started
|
||||||
|
elif can_start:
|
||||||
|
kapis: APIComp = self.server.lookup_component('klippy_apis')
|
||||||
|
try:
|
||||||
|
await kapis.start_print(upload_info['filename'])
|
||||||
|
except self.server.error:
|
||||||
|
# Attempt to start print failed
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
started = True
|
||||||
await self.notify_sync_lock.wait(300.)
|
await self.notify_sync_lock.wait(300.)
|
||||||
self.notify_sync_lock = None
|
self.notify_sync_lock = None
|
||||||
|
if queued:
|
||||||
|
self.server.send_event("file_manager:upload_queued",
|
||||||
|
upload_info['filename'])
|
||||||
return {
|
return {
|
||||||
'item': {
|
'item': {
|
||||||
'path': upload_info['filename'],
|
'path': upload_info['filename'],
|
||||||
'root': "gcodes"
|
'root': "gcodes"
|
||||||
},
|
},
|
||||||
'print_started': start_print,
|
'print_started': started,
|
||||||
|
'print_queued': queued,
|
||||||
'action': "create_file"
|
'action': "create_file"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue