mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-08 06:23:59 -06:00
Merge pull request #12531 from Ultimaker/CURA-8555_link_ufp_to_3mf_in_digital_library
Cura 8555 link ufp to 3mf in digital library
This commit is contained in:
commit
188b63703b
5 changed files with 49 additions and 55 deletions
|
@ -14,6 +14,9 @@ import DigitalFactory 1.0 as DF
|
|||
Item
|
||||
{
|
||||
id: base
|
||||
|
||||
property variant catalog: UM.I18nCatalog { name: "cura" }
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
|
@ -190,53 +193,29 @@ Item
|
|||
text: "Save"
|
||||
enabled: (asProjectCheckbox.checked || asSlicedCheckbox.checked) && dfFilenameTextfield.text.length >= 1 && dfFilenameTextfield.state !== 'invalid'
|
||||
|
||||
onClicked:
|
||||
{
|
||||
let saveAsFormats = [];
|
||||
if (asProjectCheckbox.checked)
|
||||
{
|
||||
saveAsFormats.push("3mf");
|
||||
}
|
||||
if (asSlicedCheckbox.checked)
|
||||
{
|
||||
saveAsFormats.push("ufp");
|
||||
}
|
||||
manager.saveFileToSelectedProject(dfFilenameTextfield.text, saveAsFormats);
|
||||
}
|
||||
onClicked: manager.saveFileToSelectedProject(dfFilenameTextfield.text, asProjectComboBox.currentValue)
|
||||
busy: false
|
||||
}
|
||||
|
||||
Row
|
||||
Cura.ComboBox
|
||||
{
|
||||
id: asProjectComboBox
|
||||
|
||||
id: saveAsFormatRow
|
||||
width: UM.Theme.getSize("combobox_wide").width
|
||||
height: saveButton.height
|
||||
anchors.verticalCenter: saveButton.verticalCenter
|
||||
anchors.right: saveButton.left
|
||||
anchors.rightMargin: UM.Theme.getSize("thin_margin").height
|
||||
width: childrenRect.width
|
||||
spacing: UM.Theme.getSize("default_margin").width
|
||||
|
||||
UM.CheckBox
|
||||
{
|
||||
id: asProjectCheckbox
|
||||
height: UM.Theme.getSize("checkbox").height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: true
|
||||
text: "Save Cura project"
|
||||
font: UM.Theme.getFont("medium")
|
||||
}
|
||||
enabled: UM.Backend.state == UM.Backend.Done
|
||||
currentIndex: UM.Backend.state == UM.Backend.Done ? 0 : 1
|
||||
textRole: "text"
|
||||
valueRole: "value"
|
||||
|
||||
UM.CheckBox
|
||||
{
|
||||
id: asSlicedCheckbox
|
||||
height: UM.Theme.getSize("checkbox").height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
enabled: UM.Backend.state == UM.Backend.Done
|
||||
checked: UM.Backend.state == UM.Backend.Done
|
||||
text: "Save print file"
|
||||
font: UM.Theme.getFont("medium")
|
||||
}
|
||||
model: [
|
||||
{ text: catalog.i18nc("@option", "Save Cura project and print file"), key: "3mf_ufp", value: ["3mf", "ufp"] },
|
||||
{ text: catalog.i18nc("@option", "Save Cura project"), key: "3mf", value: ["3mf"] },
|
||||
]
|
||||
}
|
||||
|
||||
Component.onCompleted:
|
||||
|
|
|
@ -37,17 +37,18 @@ class DFFileExportAndUploadManager:
|
|||
formats: List[str],
|
||||
on_upload_error: Callable[[], Any],
|
||||
on_upload_success: Callable[[], Any],
|
||||
on_upload_finished: Callable[[], Any] ,
|
||||
on_upload_finished: Callable[[], Any],
|
||||
on_upload_progress: Callable[[int], Any]) -> None:
|
||||
|
||||
self._file_handlers = file_handlers # type: Dict[str, FileHandler]
|
||||
self._nodes = nodes # type: List[SceneNode]
|
||||
self._library_project_id = library_project_id # type: str
|
||||
self._library_project_name = library_project_name # type: str
|
||||
self._file_name = file_name # type: str
|
||||
self._upload_jobs = [] # type: List[ExportFileJob]
|
||||
self._formats = formats # type: List[str]
|
||||
self._file_handlers: Dict[str, FileHandler] = file_handlers
|
||||
self._nodes: List[SceneNode] = nodes
|
||||
self._library_project_id: str = library_project_id
|
||||
self._library_project_name: str = library_project_name
|
||||
self._file_name: str = file_name
|
||||
self._upload_jobs: List[ExportFileJob] = []
|
||||
self._formats: List[str] = formats
|
||||
self._api = DigitalFactoryApiClient(application = CuraApplication.getInstance(), on_error = lambda error: Logger.log("e", str(error)))
|
||||
self._source_file_id: Optional[str] = None
|
||||
|
||||
# Functions of the parent class that should be called based on the upload process output
|
||||
self._on_upload_error = on_upload_error
|
||||
|
@ -59,7 +60,7 @@ class DFFileExportAndUploadManager:
|
|||
# show the success message (once both upload jobs are done)
|
||||
self._message_lock = threading.Lock()
|
||||
|
||||
self._file_upload_job_metadata = self.initializeFileUploadJobMetadata() # type: Dict[str, Dict[str, Any]]
|
||||
self._file_upload_job_metadata: Dict[str, Dict[str, Any]] = self.initializeFileUploadJobMetadata()
|
||||
|
||||
self.progress_message = Message(
|
||||
title = "Uploading...",
|
||||
|
@ -113,7 +114,8 @@ class DFFileExportAndUploadManager:
|
|||
content_type = job.getMimeType(),
|
||||
job_name = job.getFileName(),
|
||||
file_size = len(job.getOutput()),
|
||||
library_project_id = self._library_project_id
|
||||
library_project_id = self._library_project_id,
|
||||
source_file_id = self._source_file_id
|
||||
)
|
||||
self._api.requestUploadUFP(request, on_finished = self._uploadFileData, on_error = self._onRequestUploadPrintFileFailed)
|
||||
|
||||
|
@ -125,6 +127,9 @@ class DFFileExportAndUploadManager:
|
|||
"""
|
||||
if isinstance(file_upload_response, DFLibraryFileUploadResponse):
|
||||
file_name = file_upload_response.file_name
|
||||
|
||||
# store the `file_id` so it can be as `source_file_id` when uploading the print file
|
||||
self._source_file_id = file_upload_response.file_id
|
||||
elif isinstance(file_upload_response, DFPrintJobUploadResponse):
|
||||
file_name = file_upload_response.job_name if file_upload_response.job_name is not None else ""
|
||||
else:
|
||||
|
@ -145,6 +150,8 @@ class DFFileExportAndUploadManager:
|
|||
on_progress = self._onUploadProgress,
|
||||
on_error = self._onUploadError)
|
||||
|
||||
self._handleNextUploadJob()
|
||||
|
||||
def _onUploadProgress(self, filename: str, progress: int) -> None:
|
||||
"""
|
||||
Updates the progress message according to the total progress of the two files and displays it to the user. It is
|
||||
|
@ -325,8 +332,13 @@ class DFFileExportAndUploadManager:
|
|||
message.hide()
|
||||
|
||||
def start(self) -> None:
|
||||
for job in self._upload_jobs:
|
||||
job.start()
|
||||
self._handleNextUploadJob()
|
||||
|
||||
def _handleNextUploadJob(self):
|
||||
match self._upload_jobs:
|
||||
case [job, *jobs]:
|
||||
job.start()
|
||||
self._upload_jobs = jobs
|
||||
|
||||
def initializeFileUploadJobMetadata(self) -> Dict[str, Any]:
|
||||
metadata = {}
|
||||
|
|
|
@ -39,8 +39,8 @@ class DFFileUploader:
|
|||
:param on_error: The method to be called when an error occurs.
|
||||
"""
|
||||
|
||||
self._http = http # type: HttpRequestManager
|
||||
self._df_file = df_file # type: Union[DFLibraryFileUploadResponse, DFPrintJobUploadResponse]
|
||||
self._http: HttpRequestManager = http
|
||||
self._df_file: Union[DFLibraryFileUploadResponse, DFPrintJobUploadResponse] = df_file
|
||||
self._file_name = ""
|
||||
if isinstance(self._df_file, DFLibraryFileUploadResponse):
|
||||
self._file_name = self._df_file.file_name
|
||||
|
@ -51,7 +51,7 @@ class DFFileUploader:
|
|||
self._file_name = ""
|
||||
else:
|
||||
raise TypeError("Incorrect input type")
|
||||
self._data = data # type: bytes
|
||||
self._data: bytes = data
|
||||
|
||||
self._on_finished = on_finished
|
||||
self._on_success = on_success
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
# Copyright (c) 2021 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import Optional
|
||||
|
||||
from .BaseModel import BaseModel
|
||||
|
||||
|
||||
# Model that represents the request to upload a print job to the cloud
|
||||
class DFPrintJobUploadRequest(BaseModel):
|
||||
|
||||
def __init__(self, job_name: str, file_size: int, content_type: str, library_project_id: str, **kwargs) -> None:
|
||||
def __init__(self, job_name: str, file_size: int, content_type: str, library_project_id: str, source_file_id: str, **kwargs) -> None:
|
||||
"""Creates a new print job upload request.
|
||||
|
||||
:param job_name: The name of the print job.
|
||||
|
@ -18,4 +20,5 @@ class DFPrintJobUploadRequest(BaseModel):
|
|||
self.file_size = file_size
|
||||
self.content_type = content_type
|
||||
self.library_project_id = library_project_id
|
||||
self.source_file_id = source_file_id
|
||||
super().__init__(**kwargs)
|
||||
|
|
|
@ -40,7 +40,7 @@ class DigitalFactoryApiClient:
|
|||
DEFAULT_REQUEST_TIMEOUT = 10 # seconds
|
||||
|
||||
# In order to avoid garbage collection we keep the callbacks in this list.
|
||||
_anti_gc_callbacks = [] # type: List[Callable[[Any], None]]
|
||||
_anti_gc_callbacks: List[Callable[[Any], None]] = []
|
||||
|
||||
def __init__(self, application: CuraApplication, on_error: Callable[[List[CloudError]], None], projects_limit_per_page: Optional[int] = None) -> None:
|
||||
"""Initializes a new digital factory API client.
|
||||
|
@ -54,7 +54,7 @@ class DigitalFactoryApiClient:
|
|||
self._scope = JsonDecoratorScope(UltimakerCloudScope(application))
|
||||
self._http = HttpRequestManager.getInstance()
|
||||
self._on_error = on_error
|
||||
self._file_uploader = None # type: Optional[DFFileUploader]
|
||||
self._file_uploader: Optional[DFFileUploader] = None
|
||||
self._library_max_private_projects: Optional[int] = None
|
||||
|
||||
self._projects_pagination_mgr = PaginationManager(limit = projects_limit_per_page) if projects_limit_per_page else None # type: Optional[PaginationManager]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue