Added sending material profiles to LegacyUM3

CL-541
This commit is contained in:
Jaime van Kessel 2017-11-23 10:31:39 +01:00
parent 7465a6551a
commit 96d5c7152b
2 changed files with 73 additions and 9 deletions

View file

@ -7,7 +7,7 @@ from PyQt5.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetwork
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, pyqtSignal, QUrl from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, pyqtSignal, QUrl
from time import time from time import time
from typing import Callable, Any from typing import Callable, Any, Optional
from enum import IntEnum from enum import IntEnum
@ -39,6 +39,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
self._onFinishedCallbacks = {} self._onFinishedCallbacks = {}
self._authentication_state = AuthState.NotAuthenticated self._authentication_state = AuthState.NotAuthenticated
self._cached_multiparts = {}
def setAuthenticationState(self, authentication_state): def setAuthenticationState(self, authentication_state):
if self._authentication_state != authentication_state: if self._authentication_state != authentication_state:
self._authentication_state = authentication_state self._authentication_state = authentication_state
@ -79,29 +81,35 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent)
return request return request
def _put(self, target: str, data: str, onFinished: Callable[[Any, QNetworkReply], None]): def _clearCachedMultiPart(self, reply):
if id(reply) in self._cached_multiparts:
del self._cached_multiparts[id(reply)]
def _put(self, target: str, data: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]):
if self._manager is None: if self._manager is None:
self._createNetworkManager() self._createNetworkManager()
request = self._createEmptyRequest(target) request = self._createEmptyRequest(target)
self._last_request_time = time() self._last_request_time = time()
reply = self._manager.put(request, data.encode()) reply = self._manager.put(request, data.encode())
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished if onFinished is not None:
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished
def _get(self, target: str, onFinished: Callable[[Any, QNetworkReply], None]): def _get(self, target: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]):
if self._manager is None: if self._manager is None:
self._createNetworkManager() self._createNetworkManager()
request = self._createEmptyRequest(target) request = self._createEmptyRequest(target)
self._last_request_time = time() self._last_request_time = time()
reply = self._manager.get(request) reply = self._manager.get(request)
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished if onFinished is not None:
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished
def _delete(self, target: str, onFinished: Callable[[Any, QNetworkReply], None]): def _delete(self, target: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]):
if self._manager is None: if self._manager is None:
self._createNetworkManager() self._createNetworkManager()
self._last_request_time = time() self._last_request_time = time()
pass pass
def _post(self, target: str, data: str, onFinished: Callable[[Any, QNetworkReply], None], onProgress: Callable = None): def _post(self, target: str, data: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]], onProgress: Callable = None):
if self._manager is None: if self._manager is None:
self._createNetworkManager() self._createNetworkManager()
request = self._createEmptyRequest(target) request = self._createEmptyRequest(target)
@ -109,7 +117,31 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
reply = self._manager.post(request, data) reply = self._manager.post(request, data)
if onProgress is not None: if onProgress is not None:
reply.uploadProgress.connect(onProgress) reply.uploadProgress.connect(onProgress)
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished if onFinished is not None:
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished
def _postForm(self, target: str, header_data: str, body_data: bytes, onFinished: Optional[Callable[[Any, QNetworkReply], None]], onProgress: Callable = None):
if self._manager is None:
self._createNetworkManager()
request = self._createEmptyRequest(target)
multi_post_part = QHttpMultiPart()
post_part = QHttpPart()
post_part.setHeader(QNetworkRequest.ContentDispositionHeader, header_data)
post_part.setBody(body_data)
multi_post_part.append(post_part)
self._last_request_time = time()
reply = self._manager.post(request, multi_post_part)
# Due to garbage collection on python doing some weird stuff, we need to keep hold of a reference
self._cached_multiparts[id(reply)] = (post_part, multi_post_part, reply)
if onProgress is not None:
reply.uploadProgress.connect(onProgress)
if onFinished is not None:
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished
def _onAuthenticationRequired(self, reply, authenticator): def _onAuthenticationRequired(self, reply, authenticator):
Logger.log("w", "Request to {url} required authentication, which was not implemented".format(url = reply.url().toString())) Logger.log("w", "Request to {url} required authentication, which was not implemented".format(url = reply.url().toString()))
@ -128,6 +160,11 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
#self._manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged) # for debug purposes #self._manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged) # for debug purposes
def __handleOnFinished(self, reply: QNetworkReply): def __handleOnFinished(self, reply: QNetworkReply):
# Due to garbage collection, we need to cache certain bits of post operations.
# As we don't want to keep them around forever, delete them if we get a reply.
if reply.operation() == QNetworkAccessManager.PostOperation:
self._clearCachedMultiPart(reply)
if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None: if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None:
# No status code means it never even reached remote. # No status code means it never even reached remote.
return return
@ -137,8 +174,10 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
if self._connection_state == ConnectionState.connecting: if self._connection_state == ConnectionState.connecting:
self.setConnectionState(ConnectionState.connected) self.setConnectionState(ConnectionState.connected)
callback_key = reply.url().toString() + str(reply.operation())
try: try:
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())](reply) if callback_key in self._onFinishedCallbacks:
self._onFinishedCallbacks[callback_key](reply)
except Exception: except Exception:
Logger.logException("w", "something went wrong with callback") Logger.logException("w", "something went wrong with callback")

View file

@ -3,6 +3,8 @@ from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
from cura.Settings.ContainerManager import ContainerManager
from UM.Logger import Logger from UM.Logger import Logger
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Application import Application from UM.Application import Application
@ -97,6 +99,29 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
## Send all material profiles to the printer. ## Send all material profiles to the printer.
def sendMaterialProfiles(self): def sendMaterialProfiles(self):
Logger.log("i", "Sending material profiles to printer")
# TODO: Might want to move this to a job...
for container in ContainerRegistry.getInstance().findInstanceContainers(type="material"):
try:
xml_data = container.serialize()
if xml_data == "" or xml_data is None:
continue
names = ContainerManager.getInstance().getLinkedMaterials(container.getId())
if names:
# There are other materials that share this GUID.
if not container.isReadOnly():
continue # If it's not readonly, it's created by user, so skip it.
file_name = "none.xml"
self._postForm("materials", "form-data; name=\"file\";filename=\"%s\"" % file_name, xml_data.encode(), onFinished=None)
except NotImplementedError:
# If the material container is not the most "generic" one it can't be serialized an will raise a
# NotImplementedError. We can simply ignore these.
pass
# TODO # TODO
pass pass