Compare commits
	
		
			29 Commits
		
	
	
		
			0.1.0
			...
			fd9ce76275
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| fd9ce76275 | |||
| 8dafb9fa5a | |||
| 094959335a | |||
| f64fa7aea2 | |||
| fea0f0ed25 | |||
| c7c089ef68 | |||
| ba43df279d | |||
| f5e6b3d0dd | |||
| 9358533ce8 | |||
| 92e11cdbf3 | |||
| 61c9332f15 | |||
| ad08d3eb9a | |||
| 5661c11190 | |||
| 3690767ced | |||
| eb397ff7b7 | |||
| 3a615cfafe | |||
| e9c06bb4b5 | |||
| 3ccce10648 | |||
| c99eb38655 | |||
| 698f8f4151 | |||
| 7a0293bac7 | |||
| 
						 | 
					d0fd4a5434 | ||
| 
						 | 
					3c218a548d | ||
| 
						 | 
					03af51608d | ||
| 
						 | 
					c00285b1b2 | ||
| 
						 | 
					7f1ae5a24b | ||
| 
						 | 
					5754e81b72 | ||
| 
						 | 
					cd4103cc71 | ||
| 
						 | 
					01c6cacf15 | 
							
								
								
									
										3
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					github: [jneilliii]
 | 
				
			||||||
 | 
					patreon: jneilliii
 | 
				
			||||||
 | 
					custom: ['https://www.paypal.me/jneilliii']
 | 
				
			||||||
							
								
								
									
										26
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					name: Bug report
 | 
				
			||||||
 | 
					about: Please make sure to check other issues, including closed ones, prior to submitting a bug report. Debug logs are required and any bug report submitted without them will be ignored and closed. 
 | 
				
			||||||
 | 
					title: "[BUG]: "
 | 
				
			||||||
 | 
					labels: ''
 | 
				
			||||||
 | 
					assignees: ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Describe the Bug**
 | 
				
			||||||
 | 
					<!-- A clear and concise description of what the bug is. -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Expected Behavior**
 | 
				
			||||||
 | 
					<!-- A clear and concise description of what you expected to happen. -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Debug Logs**
 | 
				
			||||||
 | 
					<!-- If logs are not included in your bug report it will be closed. Enable debug logging for octoprint.plugins.bambu_printer in OctoPrint's logging section of settings and recreate the issue then attach octoprint.log and plugin_bambu_printer_serial.log to this bug report. -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Screenshots**
 | 
				
			||||||
 | 
					<!-- Please share any relevant screenshots related to the issue. -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Printer and Plugin Setting Details**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Printer model?
 | 
				
			||||||
 | 
					* Is your printer connected to Bambu Cloud? 
 | 
				
			||||||
 | 
					* Is the  plugin configured for local access only?
 | 
				
			||||||
							
								
								
									
										20
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					name: Feature request
 | 
				
			||||||
 | 
					about: Create a feature request for an improvement or change you'd like implemented.
 | 
				
			||||||
 | 
					title: "[FR]: "
 | 
				
			||||||
 | 
					labels: ''
 | 
				
			||||||
 | 
					assignees: ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Is your feature request related to a problem? Please describe.**
 | 
				
			||||||
 | 
					<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Describe the solution you'd like**
 | 
				
			||||||
 | 
					<!-- A clear and concise description of what you want to happen. -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Describe alternatives you've considered**
 | 
				
			||||||
 | 
					<!-- A clear and concise description of any alternative solutions or features you've considered. -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Additional context**
 | 
				
			||||||
 | 
					<!-- Add any other context or screenshots about the feature request here. -->
 | 
				
			||||||
							
								
								
									
										16
									
								
								.github/stale.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								.github/stale.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					# Number of days of inactivity before an issue becomes stale
 | 
				
			||||||
 | 
					daysUntilStale: 14
 | 
				
			||||||
 | 
					# Number of days of inactivity before a stale issue is closed
 | 
				
			||||||
 | 
					daysUntilClose: 7
 | 
				
			||||||
 | 
					# Issues with these labels will never be considered stale
 | 
				
			||||||
 | 
					exemptLabels:
 | 
				
			||||||
 | 
					  - enhancement
 | 
				
			||||||
 | 
					  - bug
 | 
				
			||||||
 | 
					# Label to use when marking an issue as stale
 | 
				
			||||||
 | 
					staleLabel: stale
 | 
				
			||||||
 | 
					# Comment to post when marking an issue as stale. Set to `false` to disable
 | 
				
			||||||
 | 
					markComment: >
 | 
				
			||||||
 | 
					  This issue has been automatically marked as stale because it has not had
 | 
				
			||||||
 | 
					  activity in 14 days. It will be closed if no further activity occurs in 7 days.
 | 
				
			||||||
 | 
					# Comment to post when closing a stale issue. Set to `false` to disable
 | 
				
			||||||
 | 
					closeComment: false
 | 
				
			||||||
							
								
								
									
										27
									
								
								.github/workflows/stale.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								.github/workflows/stale.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					name: Mark Stale Issues
 | 
				
			||||||
 | 
					on:
 | 
				
			||||||
 | 
					  workflow_dispatch:
 | 
				
			||||||
 | 
					  schedule:
 | 
				
			||||||
 | 
					  - cron: "0 0 * * *"
 | 
				
			||||||
 | 
					permissions:
 | 
				
			||||||
 | 
					  actions: write
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  stale:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					    - uses: actions/stale@v9
 | 
				
			||||||
 | 
					      with:
 | 
				
			||||||
 | 
					        repo-token: ${{ secrets.GITHUB_TOKEN }}
 | 
				
			||||||
 | 
					        stale-issue-message: 'This issue has been automatically marked as stale because it has not had activity in 14 days. It will be closed if no further activity occurs in 7 days'
 | 
				
			||||||
 | 
					        days-before-stale: 14
 | 
				
			||||||
 | 
					        days-before-close: 7
 | 
				
			||||||
 | 
					        stale-issue-label: 'stale'
 | 
				
			||||||
 | 
					        days-before-issue-stale: 14
 | 
				
			||||||
 | 
					        days-before-pr-stale: -1
 | 
				
			||||||
 | 
					        days-before-issue-close: 7
 | 
				
			||||||
 | 
					        days-before-pr-close: -1
 | 
				
			||||||
 | 
					        exempt-issue-labels: 'bug,enhancement'
 | 
				
			||||||
 | 
					    - uses: actions/checkout@v4
 | 
				
			||||||
 | 
					    - uses: gautamkrishnar/keepalive-workflow@v2
 | 
				
			||||||
 | 
					      with:
 | 
				
			||||||
 | 
					        use_api: true
 | 
				
			||||||
@@ -85,7 +85,7 @@ class BambuPrintPlugin(
 | 
				
			|||||||
            "serial": "",
 | 
					            "serial": "",
 | 
				
			||||||
            "host": "",
 | 
					            "host": "",
 | 
				
			||||||
            "access_code": "",
 | 
					            "access_code": "",
 | 
				
			||||||
            "username": "bblp",
 | 
					            "username": "octobambu",
 | 
				
			||||||
            "timelapse": False,
 | 
					            "timelapse": False,
 | 
				
			||||||
            "bed_leveling": True,
 | 
					            "bed_leveling": True,
 | 
				
			||||||
            "flow_cali": False,
 | 
					            "flow_cali": False,
 | 
				
			||||||
@@ -286,10 +286,10 @@ class BambuPrintPlugin(
 | 
				
			|||||||
    def get_update_information(self):
 | 
					    def get_update_information(self):
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            "bambu_printer": {
 | 
					            "bambu_printer": {
 | 
				
			||||||
                "displayName": "Bambu Printer",
 | 
					                "displayName": "Manus Bambu Printer",
 | 
				
			||||||
                "displayVersion": self._plugin_version,
 | 
					                "displayVersion": self._plugin_version,
 | 
				
			||||||
                "type": "github_release",
 | 
					                "type": "github_release",
 | 
				
			||||||
                "user": "jneilliii",
 | 
					                "user": "ManuelW",
 | 
				
			||||||
                "repo": "OctoPrint-BambuPrinter",
 | 
					                "repo": "OctoPrint-BambuPrinter",
 | 
				
			||||||
                "current": self._plugin_version,
 | 
					                "current": self._plugin_version,
 | 
				
			||||||
                "stable_branch": {
 | 
					                "stable_branch": {
 | 
				
			||||||
@@ -304,6 +304,6 @@ class BambuPrintPlugin(
 | 
				
			|||||||
                        "comittish": ["rc", "master"],
 | 
					                        "comittish": ["rc", "master"],
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
                "pip": "https://github.com/jneilliii/OctoPrint-BambuPrinter/archive/{target_version}.zip",
 | 
					                "pip": "https://gitlab.fire-devils.org/3D-Druck/OctoPrint-BambuPrinter/archive/{target_version}.zip",
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
from __future__ import annotations
 | 
					from __future__ import annotations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from typing import TYPE_CHECKING, Callable
 | 
					from typing import TYPE_CHECKING, Callable, List, Optional
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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 (
 | 
				
			||||||
@@ -12,83 +12,59 @@ from pathlib import Path
 | 
				
			|||||||
from octoprint_bambu_printer.printer.file_system.file_info import FileInfo
 | 
					from octoprint_bambu_printer.printer.file_system.file_info import FileInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@dataclass
 | 
					 | 
				
			||||||
class CachedFileView:
 | 
					class CachedFileView:
 | 
				
			||||||
    file_system: RemoteSDCardFileList
 | 
					    def __init__(
 | 
				
			||||||
    folder_view: dict[tuple[str, str | list[str] | None], None] = field(
 | 
					        self, file_system, on_update: Optional[Callable] = None, base_path: str = ""
 | 
				
			||||||
        default_factory=dict
 | 
					    ):
 | 
				
			||||||
    )  # dict preserves order, but set does not. We use only dict keys as storage
 | 
					        self._filters = []
 | 
				
			||||||
    on_update: Callable[[], None] | None = None
 | 
					        self._file_system = file_system
 | 
				
			||||||
 | 
					        self._base_path = base_path
 | 
				
			||||||
 | 
					        self._update_complete_callback = on_update
 | 
				
			||||||
 | 
					        self._file_info_cache = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __post_init__(self):
 | 
					    def with_filter(self, path: str, extension: str):
 | 
				
			||||||
        self._file_alias_cache: dict[str, str] = {}
 | 
					        self._filters.append({"path": path, "extension": extension})
 | 
				
			||||||
        self._file_data_cache: dict[str, FileInfo] = {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def with_filter(
 | 
					 | 
				
			||||||
        self, folder: str, extensions: str | list[str] | None = None
 | 
					 | 
				
			||||||
    ) -> "CachedFileView":
 | 
					 | 
				
			||||||
        self.folder_view[(folder, extensions)] = None
 | 
					 | 
				
			||||||
        return self
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def list_all_views(self):
 | 
					    def update(self) -> None:
 | 
				
			||||||
        existing_files: list[str] = []
 | 
					        try:
 | 
				
			||||||
        result: list[FileInfo] = []
 | 
					            file_info_list = self.list_all_views()
 | 
				
			||||||
 | 
					            self._file_info_cache = file_info_list
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        with self.file_system.get_ftps_client() as ftp:
 | 
					            # Rufe Callback auf, wenn vorhanden
 | 
				
			||||||
            for filter in self.folder_view.keys():
 | 
					            if self._update_complete_callback is not None:
 | 
				
			||||||
                result.extend(self.file_system.list_files(*filter, ftp, existing_files))
 | 
					                self._update_complete_callback()
 | 
				
			||||||
        return result
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            import logging
 | 
				
			||||||
 | 
					            logging.getLogger("octoprint.plugins.bambu_printer.BambuPrinter").error(
 | 
				
			||||||
 | 
					                f"Error updating file list: {e}", exc_info=True
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def update(self):
 | 
					    def list_all_views(self) -> List[FileInfo]:
 | 
				
			||||||
        file_info_list = self.list_all_views()
 | 
					        # Verwende die Mock-Implementation von get_file_list statt FTPS
 | 
				
			||||||
        self._update_file_list_cache(file_info_list)
 | 
					        try:
 | 
				
			||||||
        if self.on_update:
 | 
					            return self._file_system.get_file_list(self._base_path)
 | 
				
			||||||
            self.on_update()
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            import logging
 | 
				
			||||||
 | 
					            logging.getLogger("octoprint.plugins.bambu_printer.BambuPrinter").error(
 | 
				
			||||||
 | 
					                f"Error listing files: {e}", exc_info=True
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            return []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _update_file_list_cache(self, files: list[FileInfo]):
 | 
					    def get_all_cached_info(self) -> List[FileInfo]:
 | 
				
			||||||
        self._file_alias_cache = {info.dosname: info.path.as_posix() for info in files}
 | 
					        return self._file_info_cache
 | 
				
			||||||
        self._file_data_cache = {info.path.as_posix(): info for info in files}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_all_info(self):
 | 
					    def get_file_by_stem(self, file_stem: str, extensions: list[str]) -> FileInfo | None:
 | 
				
			||||||
        self.update()
 | 
					        """Get file info by file name without extension"""
 | 
				
			||||||
        return self.get_all_cached_info()
 | 
					        for file_info in self._file_info_cache:
 | 
				
			||||||
 | 
					            for extension in extensions:
 | 
				
			||||||
 | 
					                if file_info.file_name.lower().startswith(f"{file_stem.lower()}{extension}"):
 | 
				
			||||||
 | 
					                    return file_info
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_all_cached_info(self):
 | 
					        return None
 | 
				
			||||||
        return list(self._file_data_cache.values())
 | 
					
 | 
				
			||||||
 | 
					    def get_file_data(self, file_path: str) -> FileInfo | None:
 | 
				
			||||||
    def get_file_data(self, file_path: str | Path) -> FileInfo | None:
 | 
					        for file_info in self._file_info_cache:
 | 
				
			||||||
        file_data = self.get_file_data_cached(file_path)
 | 
					            if file_info.path.lower() == file_path.lower() or file_info.file_name.lower() == file_path.lower():
 | 
				
			||||||
        if file_data is None:
 | 
					                return file_info
 | 
				
			||||||
            self.update()
 | 
					 | 
				
			||||||
            file_data = self.get_file_data_cached(file_path)
 | 
					 | 
				
			||||||
        return file_data
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_file_data_cached(self, file_path: str | Path) -> FileInfo | None:
 | 
					 | 
				
			||||||
        if isinstance(file_path, str):
 | 
					 | 
				
			||||||
            file_path = Path(file_path).as_posix().strip("/")
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            file_path = file_path.as_posix().strip("/")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if file_path not in self._file_data_cache:
 | 
					 | 
				
			||||||
            file_path = self._file_alias_cache.get(file_path, file_path)
 | 
					 | 
				
			||||||
        return self._file_data_cache.get(file_path, None)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_file_by_stem(self, file_stem: str, allowed_suffixes: list[str]):
 | 
					 | 
				
			||||||
        if file_stem == "":
 | 
					 | 
				
			||||||
            return None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        file_stem = Path(file_stem).with_suffix("").stem
 | 
					 | 
				
			||||||
        file_data = self._get_file_by_stem_cached(file_stem, allowed_suffixes)
 | 
					 | 
				
			||||||
        if file_data is None:
 | 
					 | 
				
			||||||
            self.update()
 | 
					 | 
				
			||||||
            file_data = self._get_file_by_stem_cached(file_stem, allowed_suffixes)
 | 
					 | 
				
			||||||
        return file_data
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _get_file_by_stem_cached(self, file_stem: str, allowed_suffixes: list[str]):
 | 
					 | 
				
			||||||
        for file_path_str in self._file_data_cache.keys():
 | 
					 | 
				
			||||||
            file_path = Path(file_path_str)
 | 
					 | 
				
			||||||
            if file_stem == file_path.with_suffix("").stem and all(
 | 
					 | 
				
			||||||
                suffix in allowed_suffixes for suffix in file_path.suffixes
 | 
					 | 
				
			||||||
            ):
 | 
					 | 
				
			||||||
                return self.get_file_data_cached(file_path)
 | 
					 | 
				
			||||||
        return None
 | 
					        return None
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -117,7 +117,7 @@ class IoTFTPSConnection:
 | 
				
			|||||||
                        # But since we operate in prot p mode
 | 
					                        # But since we operate in prot p mode
 | 
				
			||||||
                        # we can close the connection always.
 | 
					                        # we can close the connection always.
 | 
				
			||||||
                        # This is cursed but it works.
 | 
					                        # This is cursed but it works.
 | 
				
			||||||
                        if "vsFTPd" in self.welcome:
 | 
					                        if "vsFTPd" in self.ftps_session.welcome:
 | 
				
			||||||
                            conn.unwrap()
 | 
					                            conn.unwrap()
 | 
				
			||||||
                        else:
 | 
					                        else:
 | 
				
			||||||
                            conn.shutdown(socket.SHUT_RDWR)
 | 
					                            conn.shutdown(socket.SHUT_RDWR)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ from __future__ import annotations
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import datetime
 | 
					import datetime
 | 
				
			||||||
from pathlib import Path
 | 
					from pathlib import Path
 | 
				
			||||||
from typing import Iterable, Iterator
 | 
					from typing import Iterable, Iterator, List
 | 
				
			||||||
import logging.handlers
 | 
					import logging.handlers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from octoprint.util import get_dos_filename
 | 
					from octoprint.util import get_dos_filename
 | 
				
			||||||
@@ -17,6 +17,7 @@ class RemoteSDCardFileList:
 | 
				
			|||||||
        self._settings = settings
 | 
					        self._settings = settings
 | 
				
			||||||
        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._mock_files = []  # Lokales Cache für Mock-Dateien
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def delete_file(self, file_path: Path) -> None:
 | 
					    def delete_file(self, file_path: Path) -> None:
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
@@ -80,8 +81,56 @@ class RemoteSDCardFileList:
 | 
				
			|||||||
                self._logger.exception(e, exc_info=False)
 | 
					                self._logger.exception(e, exc_info=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_ftps_client(self):
 | 
					    def get_ftps_client(self):
 | 
				
			||||||
        host = self._settings.get(["host"])
 | 
					        """
 | 
				
			||||||
        access_code = self._settings.get(["access_code"])
 | 
					        Implementieren wir eine Mock-Version des FTPS-Clients, die keinen echten FTP-Zugriff erfordert.
 | 
				
			||||||
        return IoTFTPSClient(
 | 
					        """
 | 
				
			||||||
            f"{host}", 990, "bblp", f"{access_code}", ssl_implicit=True
 | 
					        class MockFTPSClient:
 | 
				
			||||||
        )
 | 
					            def __enter__(self):
 | 
				
			||||||
 | 
					                return self
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            def __exit__(self, exc_type, exc_val, exc_tb):
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            def get_file_list(self, path=""):
 | 
				
			||||||
 | 
					                """Gibt die Mock-Dateiliste zurück"""
 | 
				
			||||||
 | 
					                return self._mock_files
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					        mock_client = MockFTPSClient()
 | 
				
			||||||
 | 
					        mock_client._mock_files = self._mock_files
 | 
				
			||||||
 | 
					        return mock_client
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def is_available(self) -> bool:
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Da wir kein FTP verwenden, ist dieser Service immer verfügbar
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_file_list(self, path: str) -> List[FileInfo]:
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Gibt eine Liste von Dateien im angegebenen Pfad zurück.
 | 
				
			||||||
 | 
					        Da wir kein FTP verwenden, geben wir eine leere Liste oder gespeicherte Mock-Dateien zurück.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self._logger.debug(f"Listing files in path: {path}")
 | 
				
			||||||
 | 
					        return self._mock_files
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add_mock_file(self, file_info: FileInfo):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Fügt eine Mock-Datei zur Liste hinzu (für Tests oder wenn keine FTP-Verbindung möglich ist)
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self._mock_files.append(file_info)
 | 
				
			||||||
 | 
					        self._logger.debug(f"Added mock file: {file_info.file_name}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def clear_mock_files(self):
 | 
				
			||||||
 | 
					        """Löscht alle gespeicherten Mock-Dateien"""
 | 
				
			||||||
 | 
					        self._mock_files = []
 | 
				
			||||||
 | 
					        self._logger.debug("Mock file list cleared")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def delete_file(self, path: str) -> bool:
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Simuliert das Löschen einer Datei, entfernt sie aus der Mock-Liste
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self._logger.debug(f"Deleting file: {path}")
 | 
				
			||||||
 | 
					        before_count = len(self._mock_files)
 | 
				
			||||||
 | 
					        self._mock_files = [f for f in self._mock_files if f.path != path]
 | 
				
			||||||
 | 
					        return before_count > len(self._mock_files)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,6 @@
 | 
				
			|||||||
from __future__ import annotations
 | 
					from __future__ import annotations
 | 
				
			||||||
from pathlib import Path
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from octoprint_bambu_printer.printer.file_system.file_info import FileInfo
 | 
					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.states.a_printer_state import APrinterState
 | 
					from octoprint_bambu_printer.printer.states.a_printer_state import APrinterState
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,7 +24,7 @@ class IdleState(APrinterState):
 | 
				
			|||||||
        # URL to print. Root path, protocol can vary. E.g., if sd card, "ftp:///myfile.3mf", "ftp:///cache/myotherfile.3mf"
 | 
					        # URL to print. Root path, protocol can vary. E.g., if sd card, "ftp:///myfile.3mf", "ftp:///cache/myotherfile.3mf"
 | 
				
			||||||
        filesystem_root = (
 | 
					        filesystem_root = (
 | 
				
			||||||
            "file:///mnt/sdcard/"
 | 
					            "file:///mnt/sdcard/"
 | 
				
			||||||
            if self._printer._settings.get_boolean(["device_type"]) in ["X1", "X1C"]
 | 
					            if self._printer._settings.get(["device_type"]) in ["X1", "X1C"]
 | 
				
			||||||
            else "file:///"
 | 
					            else "file:///"
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,7 @@ class PrintingState(APrinterState):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def __init__(self, printer: BambuVirtualPrinter) -> None:
 | 
					    def __init__(self, printer: BambuVirtualPrinter) -> None:
 | 
				
			||||||
        super().__init__(printer)
 | 
					        super().__init__(printer)
 | 
				
			||||||
 | 
					        self._current_print_job = None
 | 
				
			||||||
        self._is_printing = False
 | 
					        self._is_printing = False
 | 
				
			||||||
        self._sd_printing_thread = None
 | 
					        self._sd_printing_thread = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -36,6 +37,7 @@ class PrintingState(APrinterState):
 | 
				
			|||||||
            self._is_printing = False
 | 
					            self._is_printing = False
 | 
				
			||||||
            self._sd_printing_thread.join()
 | 
					            self._sd_printing_thread.join()
 | 
				
			||||||
            self._sd_printing_thread = None
 | 
					            self._sd_printing_thread = None
 | 
				
			||||||
 | 
					        self._printer.current_print_job = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _start_worker_thread(self):
 | 
					    def _start_worker_thread(self):
 | 
				
			||||||
        if self._sd_printing_thread is None:
 | 
					        if self._sd_printing_thread is None:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,3 +7,11 @@
 | 
				
			|||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.
 | 
					.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pytest~=7.4.4
 | 
				
			||||||
 | 
					pybambu~=1.0.1
 | 
				
			||||||
 | 
					OctoPrint~=1.10.2
 | 
				
			||||||
 | 
					setuptools~=70.0.0
 | 
				
			||||||
 | 
					pyserial~=3.5
 | 
				
			||||||
 | 
					Flask~=2.2.5
 | 
				
			||||||
 | 
					paho-mqtt~=2.1.0
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								setup.py
									
									
									
									
									
								
							@@ -14,20 +14,20 @@ plugin_package = "octoprint_bambu_printer"
 | 
				
			|||||||
plugin_name = "OctoPrint-BambuPrinter"
 | 
					plugin_name = "OctoPrint-BambuPrinter"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
 | 
					# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
 | 
				
			||||||
plugin_version = "0.1.0"
 | 
					plugin_version = "1.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
 | 
					# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
 | 
				
			||||||
# module
 | 
					# module
 | 
				
			||||||
plugin_description = """Connects OctoPrint to BambuLabs printers."""
 | 
					plugin_description = """Connects OctoPrint to BambuLabs printers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The plugin's author. Can be overwritten within OctoPrint's internal data via __plugin_author__ in the plugin module
 | 
					# The plugin's author. Can be overwritten within OctoPrint's internal data via __plugin_author__ in the plugin module
 | 
				
			||||||
plugin_author = "jneilliii"
 | 
					plugin_author = "ManuelW"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The plugin's author's mail address.
 | 
					# The plugin's author's mail address.
 | 
				
			||||||
plugin_author_email = "jneilliii+github@gmail.com"
 | 
					plugin_author_email = "manuelw@example.com"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The plugin's homepage URL. Can be overwritten within OctoPrint's internal data via __plugin_url__ in the plugin module
 | 
					# The plugin's homepage URL. Can be overwritten within OctoPrint's internal data via __plugin_url__ in the plugin module
 | 
				
			||||||
plugin_url = "https://github.com/jneilliii/OctoPrint-BambuPrinter"
 | 
					plugin_url = "https://gitlab.fire-devils.org/3D-Druck/OctoPrint-BambuPrinter"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The plugin's license. Can be overwritten within OctoPrint's internal data via __plugin_license__ in the plugin module
 | 
					# The plugin's license. Can be overwritten within OctoPrint's internal data via __plugin_license__ in the plugin module
 | 
				
			||||||
plugin_license = "AGPLv3"
 | 
					plugin_license = "AGPLv3"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user