Fix file list update. Decouple filesystem from printer file structure.
This commit is contained in:
parent
4ea98036e5
commit
f42d3167c5
@ -21,6 +21,7 @@ from octoprint.server.util.tornado import (
|
|||||||
from octoprint.access.permissions import Permissions
|
from octoprint.access.permissions import Permissions
|
||||||
from octoprint.logging.handlers import CleaningTimedRotatingFileHandler
|
from octoprint.logging.handlers import CleaningTimedRotatingFileHandler
|
||||||
|
|
||||||
|
from octoprint_bambu_printer.printer.file_system.cached_file_view import CachedFileView
|
||||||
from pybambu import BambuCloud
|
from pybambu import BambuCloud
|
||||||
|
|
||||||
from octoprint_bambu_printer.printer.file_system.remote_sd_card_file_list import (
|
from octoprint_bambu_printer.printer.file_system.remote_sd_card_file_list import (
|
||||||
@ -50,9 +51,15 @@ class BambuPrintPlugin(
|
|||||||
_logger: logging.Logger
|
_logger: logging.Logger
|
||||||
_plugin_manager: octoprint.plugin.PluginManager
|
_plugin_manager: octoprint.plugin.PluginManager
|
||||||
_bambu_file_system: RemoteSDCardFileList
|
_bambu_file_system: RemoteSDCardFileList
|
||||||
|
_timelapse_files_view: CachedFileView
|
||||||
|
|
||||||
def on_settings_initialized(self):
|
def on_settings_initialized(self):
|
||||||
self._bambu_file_system = RemoteSDCardFileList(self._settings)
|
self._bambu_file_system = RemoteSDCardFileList(self._settings)
|
||||||
|
self._timelapse_files_view = CachedFileView(self._bambu_file_system)
|
||||||
|
if self._settings.get(["device_type"]) in ["X1", "X1C"]:
|
||||||
|
self._timelapse_files_view.with_filter("timelapse/", ".mp4")
|
||||||
|
else:
|
||||||
|
self._timelapse_files_view.with_filter("timelapse/", ".avi")
|
||||||
|
|
||||||
def get_assets(self):
|
def get_assets(self):
|
||||||
return {"js": ["js/bambu_printer.js"]}
|
return {"js": ["js/bambu_printer.js"]}
|
||||||
@ -196,7 +203,7 @@ class BambuPrintPlugin(
|
|||||||
|
|
||||||
def process():
|
def process():
|
||||||
return_file_list = []
|
return_file_list = []
|
||||||
for file_info in self._bambu_file_system.get_all_timelapse_files():
|
for file_info in self._timelapse_files_view.get_all_info():
|
||||||
timelapse_info = BambuTimelapseFileInfo.from_file_info(file_info)
|
timelapse_info = BambuTimelapseFileInfo.from_file_info(file_info)
|
||||||
return_file_list.append(timelapse_info.to_dict())
|
return_file_list.append(timelapse_info.to_dict())
|
||||||
self._plugin_manager.send_plugin_message(
|
self._plugin_manager.send_plugin_message(
|
||||||
|
@ -3,10 +3,13 @@ from __future__ import annotations
|
|||||||
import collections
|
import collections
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
import math
|
import math
|
||||||
|
from pathlib import Path
|
||||||
import queue
|
import queue
|
||||||
import re
|
import re
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
from octoprint_bambu_printer.printer.file_system.cached_file_view import CachedFileView
|
||||||
|
from octoprint_bambu_printer.printer.file_system.file_info import FileInfo
|
||||||
from octoprint_bambu_printer.printer.print_job import PrintJob
|
from octoprint_bambu_printer.printer.print_job import PrintJob
|
||||||
from pybambu import BambuClient, commands
|
from pybambu import BambuClient, commands
|
||||||
import logging
|
import logging
|
||||||
@ -55,6 +58,11 @@ class BambuVirtualPrinter:
|
|||||||
read_timeout=5.0,
|
read_timeout=5.0,
|
||||||
faked_baudrate=115200,
|
faked_baudrate=115200,
|
||||||
):
|
):
|
||||||
|
self._settings = settings
|
||||||
|
self._printer_profile_manager = printer_profile_manager
|
||||||
|
self._faked_baudrate = faked_baudrate
|
||||||
|
self._data_folder = data_folder
|
||||||
|
self._last_hms_errors = None
|
||||||
self._log = logging.getLogger("octoprint.plugins.bambu_printer.BambuPrinter")
|
self._log = logging.getLogger("octoprint.plugins.bambu_printer.BambuPrinter")
|
||||||
|
|
||||||
self._state_idle = IdleState(self)
|
self._state_idle = IdleState(self)
|
||||||
@ -85,12 +93,12 @@ class BambuVirtualPrinter:
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.file_system = RemoteSDCardFileList(settings)
|
self.file_system = RemoteSDCardFileList(settings)
|
||||||
|
self._selected_project_file: FileInfo | None = None
|
||||||
self._settings = settings
|
self._project_files_view = (
|
||||||
self._printer_profile_manager = printer_profile_manager
|
CachedFileView(self.file_system, on_update=self._list_cached_project_files)
|
||||||
self._faked_baudrate = faked_baudrate
|
.with_filter("", ".3mf")
|
||||||
|
.with_filter("cache/", ".3mf")
|
||||||
self._last_hms_errors = None
|
)
|
||||||
|
|
||||||
self._serial_io.start()
|
self._serial_io.start()
|
||||||
self._printer_thread.start()
|
self._printer_thread.start()
|
||||||
@ -117,6 +125,44 @@ class BambuVirtualPrinter:
|
|||||||
def current_print_job(self, value):
|
def current_print_job(self, value):
|
||||||
self._current_print_job = value
|
self._current_print_job = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def selected_file(self):
|
||||||
|
return self._selected_project_file
|
||||||
|
|
||||||
|
@property
|
||||||
|
def has_selected_file(self):
|
||||||
|
return self._selected_project_file is not None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def timeout(self):
|
||||||
|
return self._serial_io._read_timeout
|
||||||
|
|
||||||
|
@timeout.setter
|
||||||
|
def timeout(self, value):
|
||||||
|
self._log.debug(f"Setting read timeout to {value}s")
|
||||||
|
self._serial_io._read_timeout = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def write_timeout(self):
|
||||||
|
return self._serial_io._write_timeout
|
||||||
|
|
||||||
|
@write_timeout.setter
|
||||||
|
def write_timeout(self, value):
|
||||||
|
self._log.debug(f"Setting write timeout to {value}s")
|
||||||
|
self._serial_io._write_timeout = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port(self):
|
||||||
|
return "BAMBU"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def baudrate(self):
|
||||||
|
return self._faked_baudrate
|
||||||
|
|
||||||
|
@property
|
||||||
|
def project_files(self):
|
||||||
|
return self._project_files_view
|
||||||
|
|
||||||
def change_state(self, new_state: APrinterState):
|
def change_state(self, new_state: APrinterState):
|
||||||
self._state_change_queue.put(new_state)
|
self._state_change_queue.put(new_state)
|
||||||
|
|
||||||
@ -238,32 +284,6 @@ class BambuVirtualPrinter:
|
|||||||
|
|
||||||
self._serial_io.reset()
|
self._serial_io.reset()
|
||||||
|
|
||||||
@property
|
|
||||||
def timeout(self):
|
|
||||||
return self._serial_io._read_timeout
|
|
||||||
|
|
||||||
@timeout.setter
|
|
||||||
def timeout(self, value):
|
|
||||||
self._log.debug(f"Setting read timeout to {value}s")
|
|
||||||
self._serial_io._read_timeout = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def write_timeout(self):
|
|
||||||
return self._serial_io._write_timeout
|
|
||||||
|
|
||||||
@write_timeout.setter
|
|
||||||
def write_timeout(self, value):
|
|
||||||
self._log.debug(f"Setting write timeout to {value}s")
|
|
||||||
self._serial_io._write_timeout = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def port(self):
|
|
||||||
return "BAMBU"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def baudrate(self):
|
|
||||||
return self._faked_baudrate
|
|
||||||
|
|
||||||
def write(self, data: bytes) -> int:
|
def write(self, data: bytes) -> int:
|
||||||
return self._serial_io.write(data)
|
return self._serial_io.write(data)
|
||||||
|
|
||||||
@ -283,6 +303,22 @@ class BambuVirtualPrinter:
|
|||||||
self._serial_io.flush()
|
self._serial_io.flush()
|
||||||
self._wait_for_state_change()
|
self._wait_for_state_change()
|
||||||
|
|
||||||
|
##~~ project file functions
|
||||||
|
|
||||||
|
def remove_project_selection(self):
|
||||||
|
self._selected_project_file = None
|
||||||
|
|
||||||
|
def select_project_file(self, file_path: str) -> bool:
|
||||||
|
self._log.debug(f"Select project file: {file_path}")
|
||||||
|
file_info = self._project_files_view.get_cached_file_data(file_path)
|
||||||
|
if file_info is None:
|
||||||
|
self._log.error(f"Cannot select not existing file: {file_path}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
self._selected_project_file = file_info
|
||||||
|
self._send_file_selected_message()
|
||||||
|
return True
|
||||||
|
|
||||||
##~~ command implementations
|
##~~ command implementations
|
||||||
|
|
||||||
@gcode_executor.register_no_data("M21")
|
@gcode_executor.register_no_data("M21")
|
||||||
@ -292,19 +328,18 @@ class BambuVirtualPrinter:
|
|||||||
@gcode_executor.register("M23")
|
@gcode_executor.register("M23")
|
||||||
def _select_sd_file(self, data: str) -> bool:
|
def _select_sd_file(self, data: str) -> bool:
|
||||||
filename = data.split(maxsplit=1)[1].strip()
|
filename = data.split(maxsplit=1)[1].strip()
|
||||||
self._list_sd()
|
self._list_project_files()
|
||||||
if not self.file_system.select_project_file(filename):
|
return self.select_project_file(filename)
|
||||||
return False
|
|
||||||
|
|
||||||
assert self.file_system.selected_file is not None
|
def _send_file_selected_message(self):
|
||||||
self._current_state.update_print_job_info()
|
if self.selected_file is None:
|
||||||
|
return
|
||||||
|
|
||||||
self.sendIO(
|
self.sendIO(
|
||||||
f"File opened: {self.file_system.selected_file.file_name} "
|
f"File opened: {self.selected_file.file_name} "
|
||||||
f"Size: {self.file_system.selected_file.size}"
|
f"Size: {self.selected_file.size}"
|
||||||
)
|
)
|
||||||
self.sendIO("File selected")
|
self.sendIO("File selected")
|
||||||
return True
|
|
||||||
|
|
||||||
@gcode_executor.register("M26")
|
@gcode_executor.register("M26")
|
||||||
def _set_sd_position(self, data: str) -> bool:
|
def _set_sd_position(self, data: str) -> bool:
|
||||||
@ -336,9 +371,9 @@ class BambuVirtualPrinter:
|
|||||||
|
|
||||||
@gcode_executor.register("M30")
|
@gcode_executor.register("M30")
|
||||||
def _delete_sd_file(self, data: str) -> bool:
|
def _delete_sd_file(self, data: str) -> bool:
|
||||||
filename = data.split(None, 1)[1].strip()
|
file_path = data.split(None, 1)[1].strip()
|
||||||
self._list_sd()
|
self._list_project_files()
|
||||||
self.file_system.delete_file(filename)
|
self.file_system.delete_file(Path(file_path))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@gcode_executor.register("M105")
|
@gcode_executor.register("M105")
|
||||||
@ -429,14 +464,17 @@ class BambuVirtualPrinter:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
@gcode_executor.register("M20")
|
@gcode_executor.register("M20")
|
||||||
def _list_sd(self, data: str = ""):
|
def _list_project_files(self, data: str = ""):
|
||||||
|
self._project_files_view.update()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _list_cached_project_files(self):
|
||||||
self.sendIO("Begin file list")
|
self.sendIO("Begin file list")
|
||||||
for item in map(
|
for item in map(
|
||||||
lambda f: f.get_log_info(), self.file_system.get_all_project_files()
|
FileInfo.get_gcode_info, self._project_files_view.get_all_cached_info()
|
||||||
):
|
):
|
||||||
self.sendIO(item)
|
self.sendIO(item)
|
||||||
self.sendIO("End file list")
|
self.sendIO("End file list")
|
||||||
return True
|
|
||||||
|
|
||||||
@gcode_executor.register_no_data("M24")
|
@gcode_executor.register_no_data("M24")
|
||||||
def _start_print(self):
|
def _start_print(self):
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, Callable
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from octoprint_bambu_printer.printer.file_system.remote_sd_card_file_list import (
|
from octoprint_bambu_printer.printer.file_system.remote_sd_card_file_list import (
|
||||||
@ -16,10 +16,11 @@ from octoprint_bambu_printer.printer.file_system.file_info import FileInfo
|
|||||||
class CachedFileView:
|
class CachedFileView:
|
||||||
file_system: RemoteSDCardFileList
|
file_system: RemoteSDCardFileList
|
||||||
folder_view: set[tuple[str, str | list[str] | None]] = field(default_factory=set)
|
folder_view: set[tuple[str, str | list[str] | None]] = field(default_factory=set)
|
||||||
|
on_update: Callable[[], None] | None = None
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
self._file_alias_cache = {}
|
self._file_alias_cache: dict[str, str] = {}
|
||||||
self._file_data_cache = {}
|
self._file_data_cache: dict[str, FileInfo] = {}
|
||||||
|
|
||||||
def with_filter(
|
def with_filter(
|
||||||
self, folder: str, extensions: str | list[str] | None = None
|
self, folder: str, extensions: str | list[str] | None = None
|
||||||
@ -28,8 +29,8 @@ class CachedFileView:
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
def list_all_views(self):
|
def list_all_views(self):
|
||||||
existing_files = []
|
existing_files: list[str] = []
|
||||||
result = []
|
result: list[FileInfo] = []
|
||||||
|
|
||||||
with self.file_system.get_ftps_client() as ftp:
|
with self.file_system.get_ftps_client() as ftp:
|
||||||
for filter in self.folder_view:
|
for filter in self.folder_view:
|
||||||
@ -38,10 +39,17 @@ class CachedFileView:
|
|||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
file_info_list = self.list_all_views()
|
file_info_list = self.list_all_views()
|
||||||
self._file_alias_cache = {
|
self._update_file_list_cache(file_info_list)
|
||||||
info.dosname: info.file_name for info in file_info_list
|
if self.on_update:
|
||||||
}
|
self.on_update()
|
||||||
self._file_data_cache = {info.file_name: info for info in file_info_list}
|
|
||||||
|
def _update_file_list_cache(self, files: list[FileInfo]):
|
||||||
|
self._file_alias_cache = {info.dosname: info.file_name for info in files}
|
||||||
|
self._file_data_cache = {info.file_name: info for info in files}
|
||||||
|
|
||||||
|
def get_all_info(self):
|
||||||
|
self.update()
|
||||||
|
return self.get_all_cached_info()
|
||||||
|
|
||||||
def get_all_cached_info(self):
|
def get_all_cached_info(self):
|
||||||
return list(self._file_data_cache.values())
|
return list(self._file_data_cache.values())
|
||||||
|
@ -26,7 +26,7 @@ class FileInfo:
|
|||||||
def timestamp_m20(self) -> str:
|
def timestamp_m20(self) -> str:
|
||||||
return unix_timestamp_to_m20_timestamp(int(self.timestamp))
|
return unix_timestamp_to_m20_timestamp(int(self.timestamp))
|
||||||
|
|
||||||
def get_log_info(self) -> str:
|
def get_gcode_info(self) -> str:
|
||||||
return f'{self.dosname} {self.size} {self.timestamp_m20} "{self.file_name}"'
|
return f'{self.dosname} {self.size} {self.timestamp_m20} "{self.file_name}"'
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
|
@ -17,63 +17,13 @@ class RemoteSDCardFileList:
|
|||||||
|
|
||||||
def __init__(self, settings) -> None:
|
def __init__(self, settings) -> None:
|
||||||
self._settings = settings
|
self._settings = settings
|
||||||
self._file_alias_cache = {}
|
|
||||||
self._file_data_cache = {}
|
|
||||||
self._selected_project_file: FileInfo | None = None
|
self._selected_project_file: FileInfo | None = None
|
||||||
self._logger = logging.getLogger("octoprint.plugins.bambu_printer.BambuPrinter")
|
self._logger = logging.getLogger("octoprint.plugins.bambu_printer.BambuPrinter")
|
||||||
self._project_files_view = (
|
|
||||||
CachedFileView(self).with_filter("", ".3mf").with_filter("cache/", ".3mf")
|
|
||||||
)
|
|
||||||
self._timelapse_files_view = CachedFileView(self)
|
|
||||||
if self._settings.get(["device_type"]) in ["X1", "X1C"]:
|
|
||||||
self._timelapse_files_view.with_filter("timelapse/", ".mp4")
|
|
||||||
else:
|
|
||||||
self._timelapse_files_view.with_filter("timelapse/", ".avi")
|
|
||||||
|
|
||||||
@property
|
def delete_file(self, file_path: Path) -> None:
|
||||||
def selected_file(self):
|
|
||||||
return self._selected_project_file
|
|
||||||
|
|
||||||
@property
|
|
||||||
def has_selected_file(self):
|
|
||||||
return self._selected_project_file is not None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def project_files(self):
|
|
||||||
return self._project_files_view
|
|
||||||
|
|
||||||
def remove_file_selection(self):
|
|
||||||
self._selected_project_file = None
|
|
||||||
|
|
||||||
def get_all_project_files(self):
|
|
||||||
self._project_files_view.update()
|
|
||||||
files = self._project_files_view.get_all_cached_info()
|
|
||||||
self._logger.debug(f"get project files return: {files}")
|
|
||||||
return files
|
|
||||||
|
|
||||||
def get_all_timelapse_files(self):
|
|
||||||
self._timelapse_files_view.update()
|
|
||||||
files = self._timelapse_files_view.get_all_cached_info()
|
|
||||||
self._logger.debug(f"get timelapse files return: {files}")
|
|
||||||
return files
|
|
||||||
|
|
||||||
def select_project_file(self, file_path: str) -> bool:
|
|
||||||
self._logger.debug(f"_selectSdFile: {file_path}")
|
|
||||||
file_name = Path(file_path).name
|
|
||||||
file_info = self._project_files_view.get_cached_file_data(file_name)
|
|
||||||
if file_info is None:
|
|
||||||
self._logger.error(f"{file_name} open failed")
|
|
||||||
return False
|
|
||||||
|
|
||||||
self._selected_project_file = file_info
|
|
||||||
return True
|
|
||||||
|
|
||||||
def delete_file(self, file_path: str) -> None:
|
|
||||||
file_info = self._project_files_view.get_cached_file_data(file_path)
|
|
||||||
if file_info is not None:
|
|
||||||
try:
|
try:
|
||||||
with self.get_ftps_client() as ftp:
|
with self.get_ftps_client() as ftp:
|
||||||
if ftp.delete_file(str(file_info.path)):
|
if ftp.delete_file(str(file_path)):
|
||||||
self._logger.debug(f"{file_path} deleted")
|
self._logger.debug(f"{file_path} deleted")
|
||||||
else:
|
else:
|
||||||
raise RuntimeError(f"Deleting file {file_path} failed")
|
raise RuntimeError(f"Deleting file {file_path} failed")
|
||||||
|
@ -6,12 +6,8 @@ from octoprint_bambu_printer.printer.states.a_printer_state import APrinterState
|
|||||||
|
|
||||||
class IdleState(APrinterState):
|
class IdleState(APrinterState):
|
||||||
|
|
||||||
def init(self):
|
|
||||||
if self._printer.file_system.has_selected_file:
|
|
||||||
self.update_print_job_info()
|
|
||||||
|
|
||||||
def start_new_print(self):
|
def start_new_print(self):
|
||||||
selected_file = self._printer.file_system.selected_file
|
selected_file = self._printer.selected_file
|
||||||
if selected_file is None:
|
if selected_file is None:
|
||||||
self._log.warn("Cannot start print job if file was not selected")
|
self._log.warn("Cannot start print job if file was not selected")
|
||||||
return
|
return
|
||||||
@ -55,9 +51,3 @@ class IdleState(APrinterState):
|
|||||||
}
|
}
|
||||||
|
|
||||||
return print_command
|
return print_command
|
||||||
|
|
||||||
def update_print_job_info(self):
|
|
||||||
if self._printer.file_system.selected_file is not None:
|
|
||||||
self._printer.current_print_job = PrintJob(
|
|
||||||
self._printer.file_system.selected_file, 0
|
|
||||||
)
|
|
||||||
|
@ -27,7 +27,7 @@ class PrintingState(APrinterState):
|
|||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self._is_printing = True
|
self._is_printing = True
|
||||||
self._printer.file_system.remove_file_selection()
|
self._printer.remove_project_selection()
|
||||||
self.update_print_job_info()
|
self.update_print_job_info()
|
||||||
self._start_worker_thread()
|
self._start_worker_thread()
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ class PrintingState(APrinterState):
|
|||||||
def update_print_job_info(self):
|
def update_print_job_info(self):
|
||||||
print_job_info = self._printer.bambu_client.get_device().print_job
|
print_job_info = self._printer.bambu_client.get_device().print_job
|
||||||
task_name: str = print_job_info.subtask_name
|
task_name: str = print_job_info.subtask_name
|
||||||
project_file_info = self._printer.file_system.project_files.get_file_by_suffix(
|
project_file_info = self._printer.project_files.get_file_by_suffix(
|
||||||
task_name, [".3mf", ".gcode.3mf"]
|
task_name, [".3mf", ".gcode.3mf"]
|
||||||
)
|
)
|
||||||
if project_file_info is None:
|
if project_file_info is None:
|
||||||
@ -74,6 +74,7 @@ class PrintingState(APrinterState):
|
|||||||
|
|
||||||
progress = print_job_info.print_percentage
|
progress = print_job_info.print_percentage
|
||||||
self._printer.current_print_job = PrintJob(project_file_info, progress)
|
self._printer.current_print_job = PrintJob(project_file_info, progress)
|
||||||
|
self._printer.select_project_file(project_file_info.file_name)
|
||||||
|
|
||||||
def pause_print(self):
|
def pause_print(self):
|
||||||
if self._printer.bambu_client.connected:
|
if self._printer.bambu_client.connected:
|
||||||
@ -98,5 +99,6 @@ class PrintingState(APrinterState):
|
|||||||
f"SD File Print finishing: {self._printer.current_print_job.file_info.file_name}"
|
f"SD File Print finishing: {self._printer.current_print_job.file_info.file_name}"
|
||||||
)
|
)
|
||||||
self._printer.sendIO("Done printing file")
|
self._printer.sendIO("Done printing file")
|
||||||
|
self._printer.current_print_job = None
|
||||||
|
|
||||||
self._printer.change_state(self._printer._state_idle)
|
self._printer.change_state(self._printer._state_idle)
|
||||||
|
@ -5,6 +5,7 @@ from pathlib import Path
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
from octoprint_bambu_printer.printer.file_system.cached_file_view import CachedFileView
|
||||||
import pybambu
|
import pybambu
|
||||||
import pybambu.commands
|
import pybambu.commands
|
||||||
from octoprint_bambu_printer.printer.bambu_virtual_printer import BambuVirtualPrinter
|
from octoprint_bambu_printer.printer.bambu_virtual_printer import BambuVirtualPrinter
|
||||||
@ -190,9 +191,9 @@ def test_list_sd_card(printer: BambuVirtualPrinter):
|
|||||||
assert result[4] == b"ok"
|
assert result[4] == b"ok"
|
||||||
|
|
||||||
|
|
||||||
def test_list_ftp_paths_bambu_p1(settings, ftps_session_mock):
|
def test_list_ftp_paths_p1s(settings, ftps_session_mock):
|
||||||
settings.get.side_effect.options[("device_type",)] = "P1S"
|
|
||||||
file_system = RemoteSDCardFileList(settings)
|
file_system = RemoteSDCardFileList(settings)
|
||||||
|
file_view = CachedFileView(file_system).with_filter("timelapse/", ".avi")
|
||||||
|
|
||||||
timelapse_files = ["timelapse/video.avi", "timelapse/video2.avi"]
|
timelapse_files = ["timelapse/video.avi", "timelapse/video2.avi"]
|
||||||
ftps_session_mock.size.side_effect = DictGetter(
|
ftps_session_mock.size.side_effect = DictGetter(
|
||||||
@ -209,15 +210,15 @@ def test_list_ftp_paths_bambu_p1(settings, ftps_session_mock):
|
|||||||
)
|
)
|
||||||
|
|
||||||
timelapse_paths = list(map(Path, timelapse_files))
|
timelapse_paths = list(map(Path, timelapse_files))
|
||||||
result_files = file_system.get_all_timelapse_files()
|
result_files = file_view.get_all_info()
|
||||||
assert len(timelapse_files) == len(result_files) and all(
|
assert len(timelapse_files) == len(result_files) and all(
|
||||||
file_info.path in timelapse_paths for file_info in result_files
|
file_info.path in timelapse_paths for file_info in result_files
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_list_ftp_paths_bambu_x1(settings, ftps_session_mock):
|
def test_list_ftp_paths_x1(settings, ftps_session_mock):
|
||||||
settings.get.side_effect.options[("device_type",)] = "X1"
|
|
||||||
file_system = RemoteSDCardFileList(settings)
|
file_system = RemoteSDCardFileList(settings)
|
||||||
|
file_view = CachedFileView(file_system).with_filter("timelapse/", ".mp4")
|
||||||
|
|
||||||
timelapse_files = ["timelapse/video.mp4", "timelapse/video2.mp4"]
|
timelapse_files = ["timelapse/video.mp4", "timelapse/video2.mp4"]
|
||||||
ftps_session_mock.size.side_effect = DictGetter(
|
ftps_session_mock.size.side_effect = DictGetter(
|
||||||
@ -232,7 +233,7 @@ def test_list_ftp_paths_bambu_x1(settings, ftps_session_mock):
|
|||||||
ftps_session_mock.nlst.side_effect = DictGetter({"timelapse/": timelapse_files})
|
ftps_session_mock.nlst.side_effect = DictGetter({"timelapse/": timelapse_files})
|
||||||
|
|
||||||
timelapse_paths = list(map(Path, timelapse_files))
|
timelapse_paths = list(map(Path, timelapse_files))
|
||||||
result_files = file_system.get_all_timelapse_files()
|
result_files = file_view.get_all_info()
|
||||||
assert len(timelapse_files) == len(result_files) and all(
|
assert len(timelapse_files) == len(result_files) and all(
|
||||||
file_info.path in timelapse_paths for file_info in result_files
|
file_info.path in timelapse_paths for file_info in result_files
|
||||||
)
|
)
|
||||||
@ -247,18 +248,18 @@ def test_cannot_start_print_without_file(printer: BambuVirtualPrinter):
|
|||||||
|
|
||||||
|
|
||||||
def test_non_existing_file_not_selected(printer: BambuVirtualPrinter):
|
def test_non_existing_file_not_selected(printer: BambuVirtualPrinter):
|
||||||
assert printer.file_system.selected_file is None
|
assert printer.selected_file is None
|
||||||
|
|
||||||
printer.write(b"M23 non_existing.3mf\n")
|
printer.write(b"M23 non_existing.3mf\n")
|
||||||
printer.flush()
|
printer.flush()
|
||||||
result = printer.readlines()
|
result = printer.readlines()
|
||||||
assert result[-2] != b"File selected"
|
assert result[-2] != b"File selected"
|
||||||
assert result[-1] == b"ok"
|
assert result[-1] == b"ok"
|
||||||
assert printer.file_system.selected_file is None
|
assert printer.selected_file is None
|
||||||
|
|
||||||
|
|
||||||
def test_print_started_with_selected_file(printer: BambuVirtualPrinter, print_job_mock):
|
def test_print_started_with_selected_file(printer: BambuVirtualPrinter, print_job_mock):
|
||||||
assert printer.file_system.selected_file is None
|
assert printer.selected_file is None
|
||||||
|
|
||||||
printer.write(b"M20\n")
|
printer.write(b"M20\n")
|
||||||
printer.flush()
|
printer.flush()
|
||||||
@ -270,8 +271,8 @@ def test_print_started_with_selected_file(printer: BambuVirtualPrinter, print_jo
|
|||||||
assert result[-2] == b"File selected"
|
assert result[-2] == b"File selected"
|
||||||
assert result[-1] == b"ok"
|
assert result[-1] == b"ok"
|
||||||
|
|
||||||
assert printer.file_system.selected_file is not None
|
assert printer.selected_file is not None
|
||||||
assert printer.file_system.selected_file.file_name == "print.3mf"
|
assert printer.selected_file.file_name == "print.3mf"
|
||||||
|
|
||||||
print_job_mock.subtask_name = "print.3mf"
|
print_job_mock.subtask_name = "print.3mf"
|
||||||
|
|
||||||
@ -403,12 +404,12 @@ def test_finished_print_job_reset_after_new_file_selected(
|
|||||||
printer.new_update("event_printer_data_update")
|
printer.new_update("event_printer_data_update")
|
||||||
printer.flush()
|
printer.flush()
|
||||||
assert isinstance(printer.current_state, IdleState)
|
assert isinstance(printer.current_state, IdleState)
|
||||||
assert printer.current_print_job is not None
|
assert printer.current_print_job is None
|
||||||
assert printer.current_print_job.file_info.file_name == "print.3mf"
|
assert printer.selected_file is not None
|
||||||
assert printer.current_print_job.progress == 100
|
assert printer.selected_file.file_name == "print.3mf"
|
||||||
|
|
||||||
printer.write(b"M23 print2.3mf\n")
|
printer.write(b"M23 print2.3mf\n")
|
||||||
printer.flush()
|
printer.flush()
|
||||||
assert printer.current_print_job is not None
|
assert printer.current_print_job is None
|
||||||
assert printer.current_print_job.file_info.file_name == "print2.3mf"
|
assert printer.selected_file is not None
|
||||||
assert printer.current_print_job.progress == 0
|
assert printer.selected_file.file_name == "print2.3mf"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user