mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-08 07:27:29 -06:00
STAR-322: Extracting models to be able for converting themselves
This commit is contained in:
parent
163226f940
commit
b693b9d98f
20 changed files with 324 additions and 254 deletions
0
__init__.py
Normal file
0
__init__.py
Normal file
|
@ -9,10 +9,13 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply
|
|||
from UM.Logger import Logger
|
||||
from cura.API import Account
|
||||
from cura.NetworkClient import NetworkClient
|
||||
from plugins.UM3NetworkPrinting.src.Models import BaseModel
|
||||
from plugins.UM3NetworkPrinting.src.Cloud.Models import (
|
||||
CloudCluster, CloudErrorObject, CloudClusterStatus, CloudJobUploadRequest, CloudPrintResponse, CloudJobResponse
|
||||
)
|
||||
from ..Models import BaseModel
|
||||
from .Models.CloudCluster import CloudCluster
|
||||
from .Models.CloudErrorObject import CloudErrorObject
|
||||
from .Models.CloudClusterStatus import CloudClusterStatus
|
||||
from .Models.CloudJobUploadRequest import CloudJobUploadRequest
|
||||
from .Models.CloudPrintResponse import CloudPrintResponse
|
||||
from .Models.CloudJobResponse import CloudJobResponse
|
||||
|
||||
|
||||
## The cloud API client is responsible for handling the requests and responses from the cloud.
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
import os
|
||||
from time import time
|
||||
from typing import List, Optional, Dict, Set
|
||||
from typing import Dict, List, Optional, Set
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtSignal, QUrl, pyqtProperty, pyqtSlot
|
||||
from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot
|
||||
|
||||
from UM import i18nCatalog
|
||||
from UM.FileHandler.FileHandler import FileHandler
|
||||
|
@ -12,18 +12,19 @@ from UM.Logger import Logger
|
|||
from UM.Message import Message
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
||||
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
|
||||
from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice
|
||||
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
from plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient import CloudApiClient
|
||||
from plugins.UM3NetworkPrinting.src.MeshFormatHandler import MeshFormatHandler
|
||||
from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel
|
||||
from .Models import (
|
||||
CloudClusterPrinter, CloudClusterPrintJob, CloudJobUploadRequest, CloudJobResponse, CloudClusterStatus,
|
||||
CloudClusterPrinterConfigurationMaterial, CloudErrorObject,
|
||||
CloudPrintResponse
|
||||
)
|
||||
from ..MeshFormatHandler import MeshFormatHandler
|
||||
from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel
|
||||
from .CloudApiClient import CloudApiClient
|
||||
from .Models.CloudErrorObject import CloudErrorObject
|
||||
from .Models.CloudClusterStatus import CloudClusterStatus
|
||||
from .Models.CloudJobUploadRequest import CloudJobUploadRequest
|
||||
from .Models.CloudPrintResponse import CloudPrintResponse
|
||||
from .Models.CloudJobResponse import CloudJobResponse
|
||||
from .Models.CloudClusterPrinter import CloudClusterPrinter
|
||||
from .Models.CloudClusterPrintJob import CloudClusterPrintJob
|
||||
|
||||
|
||||
## Class that contains all the translations for this module.
|
||||
|
@ -180,80 +181,23 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
|
|||
remote_printers = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinter]
|
||||
current_printers = {p.key: p for p in self._printers} # type: Dict[str, PrinterOutputModel]
|
||||
|
||||
removed_printer_ids = set(current_printers).difference(remote_printers)
|
||||
new_printer_ids = set(remote_printers).difference(current_printers)
|
||||
updated_printer_ids = set(current_printers).intersection(remote_printers)
|
||||
remote_printer_ids = set(remote_printers) # type: Set[str]
|
||||
current_printer_ids = set(current_printers) # type: Set[str]
|
||||
|
||||
for printer_guid in removed_printer_ids:
|
||||
self._printers.remove(current_printers[printer_guid])
|
||||
for removed_printer_id in current_printer_ids.difference(remote_printer_ids):
|
||||
removed_printer = current_printers[removed_printer_id]
|
||||
self._printers.remove(removed_printer)
|
||||
|
||||
for printer_guid in new_printer_ids:
|
||||
self._addPrinter(remote_printers[printer_guid])
|
||||
for new_printer_id in remote_printer_ids.difference(current_printer_ids):
|
||||
new_printer = remote_printers[new_printer_id]
|
||||
controller = PrinterOutputController(self)
|
||||
self._printers.append(new_printer.createOutputModel(controller))
|
||||
|
||||
for printer_guid in updated_printer_ids:
|
||||
self._updatePrinter(current_printers[printer_guid], remote_printers[printer_guid])
|
||||
for updated_printer_guid in current_printer_ids.intersection(remote_printer_ids):
|
||||
remote_printers[updated_printer_guid].updateOutputModel(current_printers[updated_printer_guid])
|
||||
|
||||
self.clusterPrintersChanged.emit()
|
||||
|
||||
def _addPrinter(self, printer: CloudClusterPrinter) -> None:
|
||||
model = PrinterOutputModel(
|
||||
PrinterOutputController(self), len(printer.configuration), firmware_version = printer.firmware_version
|
||||
)
|
||||
self._printers.append(model)
|
||||
self._updatePrinter(model, printer)
|
||||
|
||||
def _updatePrinter(self, model: PrinterOutputModel, printer: CloudClusterPrinter) -> None:
|
||||
model.updateKey(printer.uuid)
|
||||
model.updateName(printer.friendly_name)
|
||||
model.updateType(printer.machine_variant)
|
||||
model.updateState(printer.status if printer.enabled else "disabled")
|
||||
|
||||
for index in range(0, len(printer.configuration)):
|
||||
try:
|
||||
extruder = model.extruders[index]
|
||||
extruder_data = printer.configuration[index]
|
||||
except IndexError:
|
||||
break
|
||||
|
||||
extruder.updateHotendID(extruder_data.print_core_id)
|
||||
|
||||
if extruder.activeMaterial is None or extruder.activeMaterial.guid != extruder_data.material.guid:
|
||||
material = self._createMaterialOutputModel(extruder_data.material)
|
||||
extruder.updateActiveMaterial(material)
|
||||
|
||||
@staticmethod
|
||||
def _createMaterialOutputModel(material: CloudClusterPrinterConfigurationMaterial) -> MaterialOutputModel:
|
||||
material_manager = CuraApplication.getInstance().getMaterialManager()
|
||||
material_group_list = material_manager.getMaterialGroupListByGUID(material.guid) or []
|
||||
|
||||
# Sort the material groups by "is_read_only = True" first, and then the name alphabetically.
|
||||
read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list))
|
||||
non_read_only_material_group_list = list(filter(lambda x: not x.is_read_only, material_group_list))
|
||||
material_group = None
|
||||
if read_only_material_group_list:
|
||||
read_only_material_group_list = sorted(read_only_material_group_list, key = lambda x: x.name)
|
||||
material_group = read_only_material_group_list[0]
|
||||
elif non_read_only_material_group_list:
|
||||
non_read_only_material_group_list = sorted(non_read_only_material_group_list, key = lambda x: x.name)
|
||||
material_group = non_read_only_material_group_list[0]
|
||||
|
||||
if material_group:
|
||||
container = material_group.root_material_node.getContainer()
|
||||
color = container.getMetaDataEntry("color_code")
|
||||
brand = container.getMetaDataEntry("brand")
|
||||
material_type = container.getMetaDataEntry("material")
|
||||
name = container.getName()
|
||||
else:
|
||||
Logger.log("w", "Unable to find material with guid {guid}. Using data as provided by cluster"
|
||||
.format(guid = material.guid))
|
||||
color = material.color
|
||||
brand = material.brand
|
||||
material_type = material.material
|
||||
name = "Empty" if material.material == "empty" else "Unknown"
|
||||
|
||||
return MaterialOutputModel(guid = material.guid, type = material_type, brand = brand, color = color,
|
||||
name = name)
|
||||
|
||||
def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None:
|
||||
remote_jobs = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob]
|
||||
current_jobs = {j.key: j for j in self._print_jobs} # type: Dict[str, UM3PrintJobOutputModel]
|
||||
|
@ -264,11 +208,11 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
|
|||
for removed_job_id in current_job_ids.difference(remote_job_ids):
|
||||
self._print_jobs.remove(current_jobs[removed_job_id])
|
||||
|
||||
for new_job_id in remote_job_ids.difference(current_jobs):
|
||||
for new_job_id in remote_job_ids.difference(current_job_ids):
|
||||
self._addPrintJob(remote_jobs[new_job_id])
|
||||
|
||||
for updated_job_id in current_job_ids.intersection(remote_job_ids):
|
||||
self._updateUM3PrintJobOutputModel(current_jobs[updated_job_id], remote_jobs[updated_job_id])
|
||||
remote_jobs[updated_job_id].updateOutputModel(current_jobs[updated_job_id])
|
||||
|
||||
# We only have to update when jobs are added or removed
|
||||
# updated jobs push their changes via their output model
|
||||
|
@ -282,16 +226,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
|
|||
return Logger.log("w", "Missing printer %s for job %s in %s", job.printer_uuid, job.uuid,
|
||||
[p.key for p in self._printers])
|
||||
|
||||
model = UM3PrintJobOutputModel(printer.getController(), job.uuid, job.name)
|
||||
model.updateAssignedPrinter(printer)
|
||||
self._print_jobs.append(model)
|
||||
|
||||
@staticmethod
|
||||
def _updateUM3PrintJobOutputModel(model: UM3PrintJobOutputModel, job: CloudClusterPrintJob) -> None:
|
||||
model.updateTimeTotal(job.time_total)
|
||||
model.updateTimeElapsed(job.time_elapsed)
|
||||
model.updateOwner(job.owner)
|
||||
model.updateState(job.status)
|
||||
self._print_jobs.append(job.createOutputModel(printer))
|
||||
|
||||
def _onPrintJobCreated(self, mesh: bytes, job_response: CloudJobResponse) -> None:
|
||||
self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._updateUploadProgress,
|
||||
|
|
|
@ -8,9 +8,10 @@ from UM import i18nCatalog
|
|||
from UM.Logger import Logger
|
||||
from UM.Message import Message
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient import CloudApiClient
|
||||
from .CloudApiClient import CloudApiClient
|
||||
from .CloudOutputDevice import CloudOutputDevice
|
||||
from .Models import CloudCluster, CloudErrorObject
|
||||
from .Models.CloudCluster import CloudCluster
|
||||
from .Models.CloudErrorObject import CloudErrorObject
|
||||
|
||||
|
||||
## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters.
|
||||
|
|
|
@ -1,153 +0,0 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import List, Dict
|
||||
|
||||
from ..Models import BaseModel
|
||||
|
||||
|
||||
## Class representing errors generated by the cloud servers, according to the json-api standard.
|
||||
class CloudErrorObject(BaseModel):
|
||||
def __init__(self, **kwargs):
|
||||
self.id = None # type: str
|
||||
self.code = None # type: str
|
||||
self.http_status = None # type: str
|
||||
self.title = None # type: str
|
||||
self.detail = None # type: str
|
||||
self.meta = None # type: Dict[str, any]
|
||||
super().__init__(**kwargs)
|
||||
|
||||
|
||||
## Class representing a cloud connected cluster.
|
||||
class CloudCluster(BaseModel):
|
||||
def __init__(self, **kwargs):
|
||||
self.cluster_id = None # type: str
|
||||
self.host_guid = None # type: str
|
||||
self.host_name = None # type: str
|
||||
self.host_version = None # type: str
|
||||
self.status = None # type: str
|
||||
self.is_online = None # type: bool
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def validate(self):
|
||||
if not self.cluster_id:
|
||||
raise ValueError("cluster_id is required on CloudCluster")
|
||||
|
||||
|
||||
## Class representing a cloud cluster printer configuration
|
||||
class CloudClusterPrinterConfigurationMaterial(BaseModel):
|
||||
def __init__(self, **kwargs):
|
||||
self.guid = None # type: str
|
||||
self.brand = None # type: str
|
||||
self.color = None # type: str
|
||||
self.material = None # type: str
|
||||
super().__init__(**kwargs)
|
||||
|
||||
|
||||
## Class representing a cloud cluster printer configuration
|
||||
class CloudClusterPrinterConfiguration(BaseModel):
|
||||
def __init__(self, **kwargs):
|
||||
self.extruder_index = None # type: str
|
||||
self.material = None # type: CloudClusterPrinterConfigurationMaterial
|
||||
self.nozzle_diameter = None # type: str
|
||||
self.print_core_id = None # type: str
|
||||
super().__init__(**kwargs)
|
||||
|
||||
if isinstance(self.material, dict):
|
||||
self.material = CloudClusterPrinterConfigurationMaterial(**self.material)
|
||||
|
||||
|
||||
## Class representing a cluster printer
|
||||
class CloudClusterPrinter(BaseModel):
|
||||
def __init__(self, **kwargs):
|
||||
self.configuration = [] # type: List[CloudClusterPrinterConfiguration]
|
||||
self.enabled = None # type: str
|
||||
self.firmware_version = None # type: str
|
||||
self.friendly_name = None # type: str
|
||||
self.ip_address = None # type: str
|
||||
self.machine_variant = None # type: str
|
||||
self.status = None # type: str
|
||||
self.unique_name = None # type: str
|
||||
self.uuid = None # type: str
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.configuration = [CloudClusterPrinterConfiguration(**c)
|
||||
if isinstance(c, dict) else c for c in self.configuration]
|
||||
|
||||
|
||||
## Class representing a cloud cluster print job constraint
|
||||
class CloudClusterPrintJobConstraint(BaseModel):
|
||||
def __init__(self, **kwargs):
|
||||
self.require_printer_name = None # type: str
|
||||
super().__init__(**kwargs)
|
||||
|
||||
|
||||
## Class representing a print job
|
||||
class CloudClusterPrintJob(BaseModel):
|
||||
def __init__(self, **kwargs):
|
||||
self.assigned_to = None # type: str
|
||||
self.configuration = [] # type: List[CloudClusterPrinterConfiguration]
|
||||
self.constraints = [] # type: List[CloudClusterPrintJobConstraint]
|
||||
self.created_at = None # type: str
|
||||
self.force = None # type: str
|
||||
self.last_seen = None # type: str
|
||||
self.machine_variant = None # type: str
|
||||
self.name = None # type: str
|
||||
self.network_error_count = None # type: int
|
||||
self.owner = None # type: str
|
||||
self.printer_uuid = None # type: str
|
||||
self.started = None # type: str
|
||||
self.status = None # type: str
|
||||
self.time_elapsed = None # type: str
|
||||
self.time_total = None # type: str
|
||||
self.uuid = None # type: str
|
||||
super().__init__(**kwargs)
|
||||
self.printers = [CloudClusterPrinterConfiguration(**c) if isinstance(c, dict) else c
|
||||
for c in self.configuration]
|
||||
self.printers = [CloudClusterPrintJobConstraint(**p) if isinstance(p, dict) else p
|
||||
for p in self.constraints]
|
||||
|
||||
|
||||
# Model that represents the status of the cluster for the cloud
|
||||
class CloudClusterStatus(BaseModel):
|
||||
def __init__(self, **kwargs):
|
||||
# a list of the printers
|
||||
self.printers = [] # type: List[CloudClusterPrinter]
|
||||
# a list of the print jobs
|
||||
self.print_jobs = [] # type: List[CloudClusterPrintJob]
|
||||
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# converting any dictionaries into models
|
||||
self.printers = [CloudClusterPrinter(**p) if isinstance(p, dict) else p for p in self.printers]
|
||||
self.print_jobs = [CloudClusterPrintJob(**j) if isinstance(j, dict) else j for j in self.print_jobs]
|
||||
|
||||
|
||||
# Model that represents the request to upload a print job to the cloud
|
||||
class CloudJobUploadRequest(BaseModel):
|
||||
def __init__(self, **kwargs):
|
||||
self.file_size = None # type: int
|
||||
self.job_name = None # type: str
|
||||
self.content_type = None # type: str
|
||||
super().__init__(**kwargs)
|
||||
|
||||
|
||||
# Model that represents the response received from the cloud after requesting to upload a print job
|
||||
class CloudJobResponse(BaseModel):
|
||||
def __init__(self, **kwargs):
|
||||
self.download_url = None # type: str
|
||||
self.job_id = None # type: str
|
||||
self.job_name = None # type: str
|
||||
self.slicing_details = None # type: str
|
||||
self.status = None # type: str
|
||||
self.upload_url = None # type: str
|
||||
self.content_type = None # type: str
|
||||
super().__init__(**kwargs)
|
||||
|
||||
|
||||
# Model that represents the responses received from the cloud after requesting a job to be printed.
|
||||
class CloudPrintResponse(BaseModel):
|
||||
def __init__(self, **kwargs):
|
||||
self.cluster_job_id = None # type: str
|
||||
self.job_id = None # type: str
|
||||
self.status = None # type: str
|
||||
super().__init__(**kwargs)
|
21
plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py
Normal file
21
plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from ...Models import BaseModel
|
||||
|
||||
|
||||
## Class representing a cloud connected cluster.
|
||||
class CloudCluster(BaseModel):
|
||||
def __init__(self, **kwargs):
|
||||
self.cluster_id = None # type: str
|
||||
self.host_guid = None # type: str
|
||||
self.host_name = None # type: str
|
||||
self.host_version = None # type: str
|
||||
self.status = None # type: str
|
||||
self.is_online = None # type: bool
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Validates the model, raising an exception if the model is invalid.
|
||||
def validate(self) -> None:
|
||||
super().validate()
|
||||
if not self.cluster_id:
|
||||
raise ValueError("cluster_id is required on CloudCluster")
|
|
@ -0,0 +1,52 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import List
|
||||
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration
|
||||
from .CloudClusterPrintJobConstraint import CloudClusterPrintJobConstraint
|
||||
from ...Models import BaseModel
|
||||
|
||||
|
||||
## Class representing a print job
|
||||
from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel
|
||||
|
||||
|
||||
class CloudClusterPrintJob(BaseModel):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.assigned_to = None # type: str
|
||||
self.configuration = [] # type: List[CloudClusterPrinterConfiguration]
|
||||
self.constraints = [] # type: List[CloudClusterPrintJobConstraint]
|
||||
self.created_at = None # type: str
|
||||
self.force = None # type: str
|
||||
self.last_seen = None # type: str
|
||||
self.machine_variant = None # type: str
|
||||
self.name = None # type: str
|
||||
self.network_error_count = None # type: int
|
||||
self.owner = None # type: str
|
||||
self.printer_uuid = None # type: str
|
||||
self.started = None # type: str
|
||||
self.status = None # type: str
|
||||
self.time_elapsed = None # type: str
|
||||
self.time_total = None # type: str
|
||||
self.uuid = None # type: str
|
||||
super().__init__(**kwargs)
|
||||
self.printers = [CloudClusterPrinterConfiguration(**c) if isinstance(c, dict) else c
|
||||
for c in self.configuration]
|
||||
self.printers = [CloudClusterPrintJobConstraint(**p) if isinstance(p, dict) else p
|
||||
for p in self.constraints]
|
||||
|
||||
## Creates an UM3 print job output model based on this cloud cluster print job.
|
||||
# \param printer: The output model of the printer
|
||||
def createOutputModel(self, printer: PrinterOutputModel) -> UM3PrintJobOutputModel:
|
||||
model = UM3PrintJobOutputModel(printer.getController(), self.uuid, self.name)
|
||||
model.updateAssignedPrinter(printer)
|
||||
return model
|
||||
|
||||
## Updates an UM3 print job output model based on this cloud cluster print job.
|
||||
# \param model: The model to update.
|
||||
def updateOutputModel(self, model: UM3PrintJobOutputModel) -> None:
|
||||
model.updateTimeTotal(self.time_total)
|
||||
model.updateTimeElapsed(self.time_elapsed)
|
||||
model.updateOwner(self.owner)
|
||||
model.updateState(self.status)
|
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from ...Models import BaseModel
|
||||
|
||||
|
||||
## Class representing a cloud cluster print job constraint
|
||||
class CloudClusterPrintJobConstraint(BaseModel):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.require_printer_name = None # type: str
|
||||
super().__init__(**kwargs)
|
|
@ -0,0 +1,44 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import List
|
||||
|
||||
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration
|
||||
from ...Models import BaseModel
|
||||
|
||||
|
||||
## Class representing a cluster printer
|
||||
class CloudClusterPrinter(BaseModel):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.configuration = [] # type: List[CloudClusterPrinterConfiguration]
|
||||
self.enabled = None # type: str
|
||||
self.firmware_version = None # type: str
|
||||
self.friendly_name = None # type: str
|
||||
self.ip_address = None # type: str
|
||||
self.machine_variant = None # type: str
|
||||
self.status = None # type: str
|
||||
self.unique_name = None # type: str
|
||||
self.uuid = None # type: str
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.configuration = [CloudClusterPrinterConfiguration(**c)
|
||||
if isinstance(c, dict) else c for c in self.configuration]
|
||||
|
||||
## Creates a new output model.
|
||||
# \param controller - The controller of the model.
|
||||
def createOutputModel(self, controller: PrinterOutputController) -> PrinterOutputModel:
|
||||
model = PrinterOutputModel(controller, len(self.configuration), firmware_version = self.firmware_version)
|
||||
self.updateOutputModel(model)
|
||||
return model
|
||||
|
||||
## Updates the given output model.
|
||||
# \param model - The output model to update.
|
||||
def updateOutputModel(self, model: PrinterOutputModel) -> None:
|
||||
model.updateKey(self.uuid)
|
||||
model.updateName(self.friendly_name)
|
||||
model.updateType(self.machine_variant)
|
||||
model.updateState(self.status if self.enabled else "disabled")
|
||||
|
||||
for configuration, extruder in zip(self.configuration, model.extruders):
|
||||
configuration.updateOutputModel(extruder)
|
|
@ -0,0 +1,27 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel
|
||||
from .CloudClusterPrinterConfigurationMaterial import CloudClusterPrinterConfigurationMaterial
|
||||
from ...Models import BaseModel
|
||||
|
||||
|
||||
## Class representing a cloud cluster printer configuration
|
||||
class CloudClusterPrinterConfiguration(BaseModel):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.extruder_index = None # type: str
|
||||
self.material = None # type: CloudClusterPrinterConfigurationMaterial
|
||||
self.nozzle_diameter = None # type: str
|
||||
self.print_core_id = None # type: str
|
||||
super().__init__(**kwargs)
|
||||
|
||||
if isinstance(self.material, dict):
|
||||
self.material = CloudClusterPrinterConfigurationMaterial(**self.material)
|
||||
|
||||
## Updates the given output model.
|
||||
# \param model - The output model to update.
|
||||
def updateOutputModel(self, model: ExtruderOutputModel) -> None:
|
||||
model.updateHotendID(self.print_core_id)
|
||||
|
||||
if model.activeMaterial is None or model.activeMaterial.guid != self.material.guid:
|
||||
material = self.material.createOutputModel()
|
||||
model.updateActiveMaterial(material)
|
|
@ -0,0 +1,46 @@
|
|||
from UM.Logger import Logger
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
|
||||
from ...Models import BaseModel
|
||||
|
||||
|
||||
## Class representing a cloud cluster printer configuration
|
||||
class CloudClusterPrinterConfigurationMaterial(BaseModel):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.guid = None # type: str
|
||||
self.brand = None # type: str
|
||||
self.color = None # type: str
|
||||
self.material = None # type: str
|
||||
super().__init__(**kwargs)
|
||||
|
||||
## Creates a material output model based on this cloud printer material.
|
||||
def createOutputModel(self) -> MaterialOutputModel:
|
||||
material_manager = CuraApplication.getInstance().getMaterialManager()
|
||||
material_group_list = material_manager.getMaterialGroupListByGUID(self.guid) or []
|
||||
|
||||
# Sort the material groups by "is_read_only = True" first, and then the name alphabetically.
|
||||
read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list))
|
||||
non_read_only_material_group_list = list(filter(lambda x: not x.is_read_only, material_group_list))
|
||||
material_group = None
|
||||
if read_only_material_group_list:
|
||||
read_only_material_group_list = sorted(read_only_material_group_list, key = lambda x: x.name)
|
||||
material_group = read_only_material_group_list[0]
|
||||
elif non_read_only_material_group_list:
|
||||
non_read_only_material_group_list = sorted(non_read_only_material_group_list, key = lambda x: x.name)
|
||||
material_group = non_read_only_material_group_list[0]
|
||||
|
||||
if material_group:
|
||||
container = material_group.root_material_node.getContainer()
|
||||
color = container.getMetaDataEntry("color_code")
|
||||
brand = container.getMetaDataEntry("brand")
|
||||
material_type = container.getMetaDataEntry("material")
|
||||
name = container.getName()
|
||||
else:
|
||||
Logger.log("w", "Unable to find material with guid {guid}. Using data as provided by cluster"
|
||||
.format(guid = self.guid))
|
||||
color = self.color
|
||||
brand = self.brand
|
||||
material_type = self.material
|
||||
name = "Empty" if self.material == "empty" else "Unknown"
|
||||
|
||||
return MaterialOutputModel(guid = self.guid, type = material_type, brand = brand, color = color, name = name)
|
|
@ -0,0 +1,22 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import List
|
||||
|
||||
from .CloudClusterPrinter import CloudClusterPrinter
|
||||
from .CloudClusterPrintJob import CloudClusterPrintJob
|
||||
from ...Models import BaseModel
|
||||
|
||||
|
||||
# Model that represents the status of the cluster for the cloud
|
||||
class CloudClusterStatus(BaseModel):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
# a list of the printers
|
||||
self.printers = [] # type: List[CloudClusterPrinter]
|
||||
# a list of the print jobs
|
||||
self.print_jobs = [] # type: List[CloudClusterPrintJob]
|
||||
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# converting any dictionaries into models
|
||||
self.printers = [CloudClusterPrinter(**p) if isinstance(p, dict) else p for p in self.printers]
|
||||
self.print_jobs = [CloudClusterPrintJob(**j) if isinstance(j, dict) else j for j in self.print_jobs]
|
|
@ -0,0 +1,17 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import Dict
|
||||
|
||||
from ...Models import BaseModel
|
||||
|
||||
|
||||
## Class representing errors generated by the cloud servers, according to the json-api standard.
|
||||
class CloudErrorObject(BaseModel):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.id = None # type: str
|
||||
self.code = None # type: str
|
||||
self.http_status = None # type: str
|
||||
self.title = None # type: str
|
||||
self.detail = None # type: str
|
||||
self.meta = None # type: Dict[str, any]
|
||||
super().__init__(**kwargs)
|
|
@ -0,0 +1,16 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from ...Models import BaseModel
|
||||
|
||||
|
||||
# Model that represents the response received from the cloud after requesting to upload a print job
|
||||
class CloudJobResponse(BaseModel):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.download_url = None # type: str
|
||||
self.job_id = None # type: str
|
||||
self.job_name = None # type: str
|
||||
self.slicing_details = None # type: str
|
||||
self.status = None # type: str
|
||||
self.upload_url = None # type: str
|
||||
self.content_type = None # type: str
|
||||
super().__init__(**kwargs)
|
|
@ -0,0 +1,12 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from ...Models import BaseModel
|
||||
|
||||
|
||||
# Model that represents the request to upload a print job to the cloud
|
||||
class CloudJobUploadRequest(BaseModel):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.file_size = None # type: int
|
||||
self.job_name = None # type: str
|
||||
self.content_type = None # type: str
|
||||
super().__init__(**kwargs)
|
|
@ -0,0 +1,12 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from ...Models import BaseModel
|
||||
|
||||
|
||||
# Model that represents the responses received from the cloud after requesting a job to be printed.
|
||||
class CloudPrintResponse(BaseModel):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.cluster_job_id = None # type: str
|
||||
self.job_id = None # type: str
|
||||
self.status = None # type: str
|
||||
super().__init__(**kwargs)
|
2
plugins/UM3NetworkPrinting/src/Cloud/Models/__init__.py
Normal file
2
plugins/UM3NetworkPrinting/src/Cloud/Models/__init__.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
|
@ -25,11 +25,11 @@ from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationM
|
|||
from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
|
||||
from plugins.UM3NetworkPrinting.src.MeshFormatHandler import MeshFormatHandler
|
||||
|
||||
from .ClusterUM3PrinterOutputController import ClusterUM3PrinterOutputController
|
||||
from .SendMaterialJob import SendMaterialJob
|
||||
from .ConfigurationChangeModel import ConfigurationChangeModel
|
||||
from .MeshFormatHandler import MeshFormatHandler
|
||||
from .SendMaterialJob import SendMaterialJob
|
||||
from .UM3PrintJobOutputModel import UM3PrintJobOutputModel
|
||||
|
||||
from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply
|
||||
|
|
|
@ -8,6 +8,7 @@ class BaseModel:
|
|||
self.__dict__.update(kwargs)
|
||||
self.validate()
|
||||
|
||||
# Validates the model, raising an exception if the model is invalid.
|
||||
def validate(self) -> None:
|
||||
pass
|
||||
|
||||
|
@ -34,7 +35,9 @@ class LocalMaterial(BaseModel):
|
|||
self.version = version # type: int
|
||||
super().__init__(**kwargs)
|
||||
|
||||
#
|
||||
def validate(self) -> None:
|
||||
super().validate()
|
||||
if not self.GUID:
|
||||
raise ValueError("guid is required on LocalMaterial")
|
||||
if not self.version:
|
||||
|
|
|
@ -10,7 +10,7 @@ from PyQt5.QtCore import QByteArray
|
|||
|
||||
from UM.MimeTypeDatabase import MimeType
|
||||
from UM.Application import Application
|
||||
from plugins.UM3NetworkPrinting.src.SendMaterialJob import SendMaterialJob
|
||||
from ..src.SendMaterialJob import SendMaterialJob
|
||||
|
||||
|
||||
@patch("builtins.open", lambda _, __: io.StringIO("<xml></xml>"))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue