Browse Source

Convert doxygen to rst for UM3NetworkPrinting

Nino van Hooff 4 years ago
parent
commit
5eb5ffd916

+ 77 - 45
plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py

@@ -20,13 +20,15 @@ from ..Models.Http.CloudPrintJobResponse import CloudPrintJobResponse
 from ..Models.Http.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest
 from ..Models.Http.CloudPrintResponse import CloudPrintResponse
 
-## The generic type variable used to document the methods below.
 CloudApiClientModel = TypeVar("CloudApiClientModel", bound=BaseModel)
+"""The generic type variable used to document the methods below."""
 
 
-## The cloud API client is responsible for handling the requests and responses from the cloud.
-#  Each method should only handle models instead of exposing Any HTTP details.
 class CloudApiClient:
+    """The cloud API client is responsible for handling the requests and responses from the cloud.
+    
+    Each method should only handle models instead of exposing Any HTTP details.
+    """
 
     # The cloud URL to use for this remote cluster.
     ROOT_PATH = UltimakerCloudAuthentication.CuraCloudAPIRoot
@@ -36,54 +38,70 @@ class CloudApiClient:
     # In order to avoid garbage collection we keep the callbacks in this list.
     _anti_gc_callbacks = []  # type: List[Callable[[], None]]
 
-    ## Initializes a new cloud API client.
-    #  \param account: The user's account object
-    #  \param on_error: The callback to be called whenever we receive errors from the server.
     def __init__(self, account: Account, on_error: Callable[[List[CloudError]], None]) -> None:
+        """Initializes a new cloud API client.
+        
+        :param account: The user's account object
+        :param on_error: The callback to be called whenever we receive errors from the server.
+        """
         super().__init__()
         self._manager = QNetworkAccessManager()
         self._account = account
         self._on_error = on_error
         self._upload = None  # type: Optional[ToolPathUploader]
 
-    ## Gets the account used for the API.
     @property
     def account(self) -> Account:
+        """Gets the account used for the API."""
+
         return self._account
 
-    ## Retrieves all the clusters for the user that is currently logged in.
-    #  \param on_finished: The function to be called after the result is parsed.
     def getClusters(self, on_finished: Callable[[List[CloudClusterResponse]], Any], failed: Callable) -> None:
+        """Retrieves all the clusters for the user that is currently logged in.
+        
+        :param on_finished: The function to be called after the result is parsed.
+        """
+
         url = "{}/clusters?status=active".format(self.CLUSTER_API_ROOT)
         reply = self._manager.get(self._createEmptyRequest(url))
         self._addCallback(reply, on_finished, CloudClusterResponse, failed)
 
-    ## Retrieves the status of the given cluster.
-    #  \param cluster_id: The ID of the cluster.
-    #  \param on_finished: The function to be called after the result is parsed.
     def getClusterStatus(self, cluster_id: str, on_finished: Callable[[CloudClusterStatus], Any]) -> None:
+        """Retrieves the status of the given cluster.
+        
+        :param cluster_id: The ID of the cluster.
+        :param on_finished: The function to be called after the result is parsed.
+        """
+
         url = "{}/clusters/{}/status".format(self.CLUSTER_API_ROOT, cluster_id)
         reply = self._manager.get(self._createEmptyRequest(url))
         self._addCallback(reply, on_finished, CloudClusterStatus)
 
-    ## Requests the cloud to register the upload of a print job mesh.
-    #  \param request: The request object.
-    #  \param on_finished: The function to be called after the result is parsed.
     def requestUpload(self, request: CloudPrintJobUploadRequest,
                       on_finished: Callable[[CloudPrintJobResponse], Any]) -> None:
+
+        """Requests the cloud to register the upload of a print job mesh.
+        
+        :param request: The request object.
+        :param on_finished: The function to be called after the result is parsed.
+        """
+
         url = "{}/jobs/upload".format(self.CURA_API_ROOT)
         body = json.dumps({"data": request.toDict()})
         reply = self._manager.put(self._createEmptyRequest(url), body.encode())
         self._addCallback(reply, on_finished, CloudPrintJobResponse)
 
-    ## Uploads a print job tool path to the cloud.
-    #  \param print_job: The object received after requesting an upload with `self.requestUpload`.
-    #  \param mesh: The tool path data to be uploaded.
-    #  \param on_finished: The function to be called after the upload is successful.
-    #  \param on_progress: A function to be called during upload progress. It receives a percentage (0-100).
-    #  \param on_error: A function to be called if the upload fails.
     def uploadToolPath(self, print_job: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[], Any],
                        on_progress: Callable[[int], Any], on_error: Callable[[], Any]):
+        """Uploads a print job tool path to the cloud.
+        
+        :param print_job: The object received after requesting an upload with `self.requestUpload`.
+        :param mesh: The tool path data to be uploaded.
+        :param on_finished: The function to be called after the upload is successful.
+        :param on_progress: A function to be called during upload progress. It receives a percentage (0-100).
+        :param on_error: A function to be called if the upload fails.
+        """
+
         self._upload = ToolPathUploader(self._manager, print_job, mesh, on_finished, on_progress, on_error)
         self._upload.start()
 
@@ -96,20 +114,27 @@ class CloudApiClient:
         reply = self._manager.post(self._createEmptyRequest(url), b"")
         self._addCallback(reply, on_finished, CloudPrintResponse)
 
-    ##  Send a print job action to the cluster for the given print job.
-    #  \param cluster_id: The ID of the cluster.
-    #  \param cluster_job_id: The ID of the print job within the cluster.
-    #  \param action: The name of the action to execute.
     def doPrintJobAction(self, cluster_id: str, cluster_job_id: str, action: str,
                          data: Optional[Dict[str, Any]] = None) -> None:
+
+        """Send a print job action to the cluster for the given print job.
+        
+        :param cluster_id: The ID of the cluster.
+        :param cluster_job_id: The ID of the print job within the cluster.
+        :param action: The name of the action to execute.
+        """
+
         body = json.dumps({"data": data}).encode() if data else b""
         url = "{}/clusters/{}/print_jobs/{}/action/{}".format(self.CLUSTER_API_ROOT, cluster_id, cluster_job_id, action)
         self._manager.post(self._createEmptyRequest(url), body)
 
-    ##  We override _createEmptyRequest in order to add the user credentials.
-    #   \param url: The URL to request
-    #   \param content_type: The type of the body contents.
     def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest:
+        """We override _createEmptyRequest in order to add the user credentials.
+        
+        :param url: The URL to request
+        :param content_type: The type of the body contents.
+        """
+
         request = QNetworkRequest(QUrl(path))
         if content_type:
             request.setHeader(QNetworkRequest.ContentTypeHeader, content_type)
@@ -118,11 +143,14 @@ class CloudApiClient:
             request.setRawHeader(b"Authorization", "Bearer {}".format(access_token).encode())
         return request
 
-    ## Parses the given JSON network reply into a status code and a dictionary, handling unexpected errors as well.
-    #  \param reply: The reply from the server.
-    #  \return A tuple with a status code and a dictionary.
     @staticmethod
     def _parseReply(reply: QNetworkReply) -> Tuple[int, Dict[str, Any]]:
+        """Parses the given JSON network reply into a status code and a dictionary, handling unexpected errors as well.
+        
+        :param reply: The reply from the server.
+        :return: A tuple with a status code and a dictionary.
+        """
+
         status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
         try:
             response = bytes(reply.readAll()).decode()
@@ -133,14 +161,15 @@ class CloudApiClient:
             Logger.logException("e", "Could not parse the stardust response: %s", error.toDict())
             return status_code, {"errors": [error.toDict()]}
 
-    ## Parses the given models and calls the correct callback depending on the result.
-    #  \param response: The response from the server, after being converted to a dict.
-    #  \param on_finished: The callback in case the response is successful.
-    #  \param model_class: The type of the model to convert the response to. It may either be a single record or a list.
-    def _parseModels(self, response: Dict[str, Any],
-                     on_finished: Union[Callable[[CloudApiClientModel], Any],
-                                        Callable[[List[CloudApiClientModel]], Any]],
-                     model_class: Type[CloudApiClientModel]) -> None:
+    def _parseModels(self, response: Dict[str, Any], on_finished: Union[Callable[[CloudApiClientModel], Any],
+                     Callable[[List[CloudApiClientModel]], Any]], model_class: Type[CloudApiClientModel]) -> None:
+        """Parses the given models and calls the correct callback depending on the result.
+        
+        :param response: The response from the server, after being converted to a dict.
+        :param on_finished: The callback in case the response is successful.
+        :param model_class: The type of the model to convert the response to. It may either be a single record or a list.
+        """
+
         if "data" in response:
             data = response["data"]
             if isinstance(data, list):
@@ -156,18 +185,21 @@ class CloudApiClient:
         else:
             Logger.log("e", "Cannot find data or errors in the cloud response: %s", response)
 
-    ## Creates a callback function so that it includes the parsing of the response into the correct model.
-    #  The callback is added to the 'finished' signal of the reply.
-    #  \param reply: The reply that should be listened to.
-    #  \param on_finished: The callback in case the response is successful. Depending on the endpoint it will be either
-    #       a list or a single item.
-    #  \param model: The type of the model to convert the response to.
     def _addCallback(self,
                      reply: QNetworkReply,
                      on_finished: Union[Callable[[CloudApiClientModel], Any],
                                         Callable[[List[CloudApiClientModel]], Any]],
                      model: Type[CloudApiClientModel],
                      on_error: Optional[Callable] = None) -> None:
+        """Creates a callback function so that it includes the parsing of the response into the correct model.
+        
+        The callback is added to the 'finished' signal of the reply.
+        :param reply: The reply that should be listened to.
+        :param on_finished: The callback in case the response is successful. Depending on the endpoint it will be either
+        a list or a single item.
+        :param model: The type of the model to convert the response to.
+        """
+
         def parse() -> None:
             self._anti_gc_callbacks.remove(parse)
 

+ 58 - 31
plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py

@@ -35,11 +35,13 @@ from ..Models.Http.ClusterPrintJobStatus import ClusterPrintJobStatus
 I18N_CATALOG = i18nCatalog("cura")
 
 
-##  The cloud output device is a network output device that works remotely but has limited functionality.
-#   Currently it only supports viewing the printer and print job status and adding a new job to the queue.
-#   As such, those methods have been implemented here.
-#   Note that this device represents a single remote cluster, not a list of multiple clusters.
 class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
+    """The cloud output device is a network output device that works remotely but has limited functionality.
+    
+    Currently it only supports viewing the printer and print job status and adding a new job to the queue.
+    As such, those methods have been implemented here.
+    Note that this device represents a single remote cluster, not a list of multiple clusters.
+    """
 
     # The interval with which the remote cluster is checked.
     # We can do this relatively often as this API call is quite fast.
@@ -56,11 +58,13 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
     # Therefore we create a private signal used to trigger the printersChanged signal.
     _cloudClusterPrintersChanged = pyqtSignal()
 
-    ## Creates a new cloud output device
-    #  \param api_client: The client that will run the API calls
-    #  \param cluster: The device response received from the cloud API.
-    #  \param parent: The optional parent of this output device.
     def __init__(self, api_client: CloudApiClient, cluster: CloudClusterResponse, parent: QObject = None) -> None:
+        """Creates a new cloud output device
+        
+        :param api_client: The client that will run the API calls
+        :param cluster: The device response received from the cloud API.
+        :param parent: The optional parent of this output device.
+        """
 
         # The following properties are expected on each networked output device.
         # Because the cloud connection does not off all of these, we manually construct this version here.
@@ -99,8 +103,9 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
         self._tool_path = None  # type: Optional[bytes]
         self._uploaded_print_job = None  # type: Optional[CloudPrintJobResponse]
 
-    ## Connects this device.
     def connect(self) -> None:
+        """Connects this device."""
+
         if self.isConnected():
             return
         super().connect()
@@ -108,21 +113,24 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
         CuraApplication.getInstance().getBackend().backendStateChange.connect(self._onBackendStateChange)
         self._update()
 
-    ## Disconnects the device
     def disconnect(self) -> None:
+        """Disconnects the device"""
+
         if not self.isConnected():
             return
         super().disconnect()
         Logger.log("i", "Disconnected from cluster %s", self.key)
         CuraApplication.getInstance().getBackend().backendStateChange.disconnect(self._onBackendStateChange)
 
-    ## Resets the print job that was uploaded to force a new upload, runs whenever the user re-slices.
     def _onBackendStateChange(self, _: BackendState) -> None:
+        """Resets the print job that was uploaded to force a new upload, runs whenever the user re-slices."""
+
         self._tool_path = None
         self._uploaded_print_job = None
 
-    ## Checks whether the given network key is found in the cloud's host name
     def matchesNetworkKey(self, network_key: str) -> bool:
+        """Checks whether the given network key is found in the cloud's host name"""
+
         # Typically, a network key looks like "ultimakersystem-aabbccdd0011._ultimaker._tcp.local."
         # the host name should then be "ultimakersystem-aabbccdd0011"
         if network_key.startswith(str(self.clusterData.host_name or "")):
@@ -133,15 +141,17 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
             return True
         return False
 
-    ## Set all the interface elements and texts for this output device.
     def _setInterfaceElements(self) -> None:
+        """Set all the interface elements and texts for this output device."""
+
         self.setPriority(2)  # Make sure we end up below the local networking and above 'save to file'.
         self.setShortDescription(I18N_CATALOG.i18nc("@action:button", "Print via Cloud"))
         self.setDescription(I18N_CATALOG.i18nc("@properties:tooltip", "Print via Cloud"))
         self.setConnectionText(I18N_CATALOG.i18nc("@info:status", "Connected via Cloud"))
 
-    ## Called when the network data should be updated.
     def _update(self) -> None:
+        """Called when the network data should be updated."""
+
         super()._update()
         if time() - self._time_of_last_request < self.CHECK_CLUSTER_INTERVAL:
             return  # avoid calling the cloud too often
@@ -153,9 +163,11 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
         else:
             self.setAuthenticationState(AuthState.NotAuthenticated)
 
-    ## Method called when HTTP request to status endpoint is finished.
-    #  Contains both printers and print jobs statuses in a single response.
     def _onStatusCallFinished(self, status: CloudClusterStatus) -> None:
+        """Method called when HTTP request to status endpoint is finished.
+        
+        Contains both printers and print jobs statuses in a single response.
+        """
         self._responseReceived()
         if status.printers != self._received_printers:
             self._received_printers = status.printers
@@ -164,10 +176,11 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
             self._received_print_jobs = status.print_jobs
             self._updatePrintJobs(status.print_jobs)
 
-    ##  Called when Cura requests an output device to receive a (G-code) file.
     def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False,
                      file_handler: Optional[FileHandler] = None, filter_by_machine: bool = False, **kwargs) -> None:
 
+        """Called when Cura requests an output device to receive a (G-code) file."""
+
         # Show an error message if we're already sending a job.
         if self._progress.visible:
             PrintJobUploadBlockedMessage().show()
@@ -187,9 +200,11 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
         job.finished.connect(self._onPrintJobCreated)
         job.start()
 
-    ## Handler for when the print job was created locally.
-    #  It can now be sent over the cloud.
     def _onPrintJobCreated(self, job: ExportFileJob) -> None:
+        """Handler for when the print job was created locally.
+        
+        It can now be sent over the cloud.
+        """
         output = job.getOutput()
         self._tool_path = output  # store the tool path to prevent re-uploading when printing the same file again
         file_name = job.getFileName()
@@ -200,9 +215,11 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
         )
         self._api.requestUpload(request, self._uploadPrintJob)
 
-    ## Uploads the mesh when the print job was registered with the cloud API.
-    #  \param job_response: The response received from the cloud API.
     def _uploadPrintJob(self, job_response: CloudPrintJobResponse) -> None:
+        """Uploads the mesh when the print job was registered with the cloud API.
+        
+        :param job_response: The response received from the cloud API.
+        """
         if not self._tool_path:
             return self._onUploadError()
         self._progress.show()
@@ -210,38 +227,45 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
         self._api.uploadToolPath(job_response, self._tool_path, self._onPrintJobUploaded, self._progress.update,
                                  self._onUploadError)
 
-    ## Requests the print to be sent to the printer when we finished uploading the mesh.
     def _onPrintJobUploaded(self) -> None:
+        """Requests the print to be sent to the printer when we finished uploading the mesh."""
+
         self._progress.update(100)
         print_job = cast(CloudPrintJobResponse, self._uploaded_print_job)
         self._api.requestPrint(self.key, print_job.job_id, self._onPrintUploadCompleted)
 
-    ## Shows a message when the upload has succeeded
-    #  \param response: The response from the cloud API.
     def _onPrintUploadCompleted(self, response: CloudPrintResponse) -> None:
+        """Shows a message when the upload has succeeded
+        
+        :param response: The response from the cloud API.
+        """
         self._progress.hide()
         PrintJobUploadSuccessMessage().show()
         self.writeFinished.emit()
 
-    ## Displays the given message if uploading the mesh has failed
-    #  \param message: The message to display.
     def _onUploadError(self, message: str = None) -> None:
+        """Displays the given message if uploading the mesh has failed
+        
+        :param message: The message to display.
+        """
         self._progress.hide()
         self._uploaded_print_job = None
         PrintJobUploadErrorMessage(message).show()
         self.writeError.emit()
 
-    ##  Whether the printer that this output device represents supports print job actions via the cloud.
     @pyqtProperty(bool, notify=_cloudClusterPrintersChanged)
     def supportsPrintJobActions(self) -> bool:
+        """Whether the printer that this output device represents supports print job actions via the cloud."""
+
         if not self._printers:
             return False
         version_number = self.printers[0].firmwareVersion.split(".")
         firmware_version = Version([version_number[0], version_number[1], version_number[2]])
         return firmware_version >= self.PRINT_JOB_ACTIONS_MIN_VERSION
 
-    ##  Set the remote print job state.
     def setJobState(self, print_job_uuid: str, state: str) -> None:
+        """Set the remote print job state."""
+
         self._api.doPrintJobAction(self._cluster.cluster_id, print_job_uuid, state)
 
     @pyqtSlot(str, name="sendJobToTop")
@@ -265,18 +289,21 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
     def openPrinterControlPanel(self) -> None:
         QDesktopServices.openUrl(QUrl(self.clusterCloudUrl))
 
-    ## Gets the cluster response from which this device was created.
     @property
     def clusterData(self) -> CloudClusterResponse:
+        """Gets the cluster response from which this device was created."""
+
         return self._cluster
 
-    ## Updates the cluster data from the cloud.
     @clusterData.setter
     def clusterData(self, value: CloudClusterResponse) -> None:
+        """Updates the cluster data from the cloud."""
+
         self._cluster = value
 
-    ## Gets the URL on which to monitor the cluster via the cloud.
     @property
     def clusterCloudUrl(self) -> str:
+        """Gets the URL on which to monitor the cluster via the cloud."""
+
         root_url_prefix = "-staging" if self._account.is_staging else ""
         return "https://mycloud{}.ultimaker.com/app/jobs/{}".format(root_url_prefix, self.clusterData.cluster_id)

+ 37 - 21
plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py

@@ -10,8 +10,9 @@ from UM.Logger import Logger
 from ..Models.Http.CloudPrintJobResponse import CloudPrintJobResponse
 
 
-## Class responsible for uploading meshes to the cloud in separate requests.
 class ToolPathUploader:
+    """Class responsible for uploading meshes to the cloud in separate requests."""
+
 
     # The maximum amount of times to retry if the server returns one of the RETRY_HTTP_CODES
     MAX_RETRIES = 10
@@ -22,16 +23,19 @@ class ToolPathUploader:
     # The amount of bytes to send per request
     BYTES_PER_REQUEST = 256 * 1024
 
-    ## Creates a mesh upload object.
-    #  \param manager: The network access manager that will handle the HTTP requests.
-    #  \param print_job: The print job response that was returned by the cloud after registering the upload.
-    #  \param data: The mesh bytes to be uploaded.
-    #  \param on_finished: The method to be called when done.
-    #  \param on_progress: The method to be called when the progress changes (receives a percentage 0-100).
-    #  \param on_error: The method to be called when an error occurs.
     def __init__(self, manager: QNetworkAccessManager, print_job: CloudPrintJobResponse, data: bytes,
                  on_finished: Callable[[], Any], on_progress: Callable[[int], Any], on_error: Callable[[], Any]
                  ) -> None:
+        """Creates a mesh upload object.
+        
+        :param manager: The network access manager that will handle the HTTP requests.
+        :param print_job: The print job response that was returned by the cloud after registering the upload.
+        :param data: The mesh bytes to be uploaded.
+        :param on_finished: The method to be called when done.
+        :param on_progress: The method to be called when the progress changes (receives a percentage 0-100).
+        :param on_error: The method to be called when an error occurs.
+        """
+
         self._manager = manager
         self._print_job = print_job
         self._data = data
@@ -45,13 +49,15 @@ class ToolPathUploader:
         self._finished = False
         self._reply = None  # type: Optional[QNetworkReply]
 
-    ## Returns the print job for which this object was created.
     @property
     def printJob(self):
+        """Returns the print job for which this object was created."""
+
         return self._print_job
 
-    ##  Creates a network request to the print job upload URL, adding the needed content range header.
     def _createRequest(self) -> QNetworkRequest:
+        """Creates a network request to the print job upload URL, adding the needed content range header."""
+
         request = QNetworkRequest(QUrl(self._print_job.upload_url))
         request.setHeader(QNetworkRequest.ContentTypeHeader, self._print_job.content_type)
 
@@ -62,14 +68,17 @@ class ToolPathUploader:
 
         return request
 
-    ## Determines the bytes that should be uploaded next.
-    #  \return: A tuple with the first and the last byte to upload.
     def _chunkRange(self) -> Tuple[int, int]:
+        """Determines the bytes that should be uploaded next.
+        
+        :return: A tuple with the first and the last byte to upload.
+        """
         last_byte = min(len(self._data), self._sent_bytes + self.BYTES_PER_REQUEST)
         return self._sent_bytes, last_byte
 
-    ## Starts uploading the mesh.
     def start(self) -> None:
+        """Starts uploading the mesh."""
+
         if self._finished:
             # reset state.
             self._sent_bytes = 0
@@ -77,13 +86,15 @@ class ToolPathUploader:
             self._finished = False
         self._uploadChunk()
 
-    ## Stops uploading the mesh, marking it as finished.
     def stop(self):
+        """Stops uploading the mesh, marking it as finished."""
+
         Logger.log("i", "Stopped uploading")
         self._finished = True
 
-    ## Uploads a chunk of the mesh to the cloud.
     def _uploadChunk(self) -> None:
+        """Uploads a chunk of the mesh to the cloud."""
+
         if self._finished:
             raise ValueError("The upload is already finished")
 
@@ -96,25 +107,29 @@ class ToolPathUploader:
         self._reply.uploadProgress.connect(self._progressCallback)
         self._reply.error.connect(self._errorCallback)
 
-    ## Handles an update to the upload progress
-    #  \param bytes_sent: The amount of bytes sent in the current request.
-    #  \param bytes_total: The amount of bytes to send in the current request.
     def _progressCallback(self, bytes_sent: int, bytes_total: int) -> None:
+        """Handles an update to the upload progress
+        
+        :param bytes_sent: The amount of bytes sent in the current request.
+        :param bytes_total: The amount of bytes to send in the current request.
+        """
         Logger.log("i", "Progress callback %s / %s", bytes_sent, bytes_total)
         if bytes_total:
             total_sent = self._sent_bytes + bytes_sent
             self._on_progress(int(total_sent / len(self._data) * 100))
 
-    ## Handles an error uploading.
     def _errorCallback(self) -> None:
+        """Handles an error uploading."""
+
         reply = cast(QNetworkReply, self._reply)
         body = bytes(reply.readAll()).decode()
         Logger.log("e", "Received error while uploading: %s", body)
         self.stop()
         self._on_error()
 
-    ## Checks whether a chunk of data was uploaded successfully, starting the next chunk if needed.
     def _finishedCallback(self) -> None:
+        """Checks whether a chunk of data was uploaded successfully, starting the next chunk if needed."""
+
         reply = cast(QNetworkReply, self._reply)
         Logger.log("i", "Finished callback %s %s",
                    reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url().toString())
@@ -140,8 +155,9 @@ class ToolPathUploader:
                    [bytes(header).decode() for header in reply.rawHeaderList()], bytes(reply.readAll()).decode())
         self._chunkUploaded()
 
-    ## Handles a chunk of data being uploaded, starting the next chunk if needed.
     def _chunkUploaded(self) -> None:
+        """Handles a chunk of data being uploaded, starting the next chunk if needed."""
+
         # We got a successful response. Let's start the next chunk or report the upload is finished.
         first_byte, last_byte = self._chunkRange()
         self._sent_bytes += last_byte - first_byte

+ 5 - 3
plugins/UM3NetworkPrinting/src/ExportFileJob.py

@@ -9,8 +9,8 @@ from cura.CuraApplication import CuraApplication
 from .MeshFormatHandler import MeshFormatHandler
 
 
-## Job that exports the build plate to the correct file format for the target cluster.
 class ExportFileJob(WriteFileJob):
+    """Job that exports the build plate to the correct file format for the target cluster."""
 
     def __init__(self, file_handler: Optional[FileHandler], nodes: List[SceneNode], firmware_version: str) -> None:
 
@@ -27,12 +27,14 @@ class ExportFileJob(WriteFileJob):
         extension = self._mesh_format_handler.preferred_format.get("extension", "")
         self.setFileName("{}.{}".format(job_name, extension))
 
-    ## Get the mime type of the selected export file type.
     def getMimeType(self) -> str:
+        """Get the mime type of the selected export file type."""
+
         return self._mesh_format_handler.mime_type
 
-    ## Get the job result as bytes as that is what we need to upload to the cluster.
     def getOutput(self) -> bytes:
+        """Get the job result as bytes as that is what we need to upload to the cluster."""
+
         output = self.getStream().getvalue()
         if isinstance(output, str):
             output = output.encode("utf-8")

+ 29 - 16
plugins/UM3NetworkPrinting/src/MeshFormatHandler.py

@@ -16,8 +16,9 @@ from cura.CuraApplication import CuraApplication
 I18N_CATALOG = i18nCatalog("cura")
 
 
-## This class is responsible for choosing the formats used by the connected clusters.
 class MeshFormatHandler:
+    """This class is responsible for choosing the formats used by the connected clusters."""
+
 
     def __init__(self, file_handler: Optional[FileHandler], firmware_version: str) -> None:
         self._file_handler = file_handler or CuraApplication.getInstance().getMeshFileHandler()
@@ -28,42 +29,50 @@ class MeshFormatHandler:
     def is_valid(self) -> bool:
         return bool(self._writer)
 
-    ## Chooses the preferred file format.
-    #  \return A dict with the file format details, with the following keys:
-    #       {id: str, extension: str, description: str, mime_type: str, mode: int, hide_in_file_dialog: bool}
     @property
     def preferred_format(self) -> Dict[str, Union[str, int, bool]]:
+        """Chooses the preferred file format.
+        
+        :return: A dict with the file format details, with the following keys:
+        {id: str, extension: str, description: str, mime_type: str, mode: int, hide_in_file_dialog: bool}
+        """
         return self._preferred_format
 
-    ## Gets the file writer for the given file handler and mime type.
-    #  \return A file writer.
     @property
     def writer(self) -> Optional[FileWriter]:
+        """Gets the file writer for the given file handler and mime type.
+        
+        :return: A file writer.
+        """
         return self._writer
 
     @property
     def mime_type(self) -> str:
         return cast(str, self._preferred_format["mime_type"])
 
-    ## Gets the file mode (FileWriter.OutputMode.TextMode or FileWriter.OutputMode.BinaryMode)
     @property
     def file_mode(self) -> int:
+        """Gets the file mode (FileWriter.OutputMode.TextMode or FileWriter.OutputMode.BinaryMode)"""
+
         return cast(int, self._preferred_format["mode"])
 
-    ## Gets the file extension
     @property
     def file_extension(self) -> str:
+        """Gets the file extension"""
+
         return cast(str, self._preferred_format["extension"])
 
-    ## Creates the right kind of stream based on the preferred format.
     def createStream(self) -> Union[io.BytesIO, io.StringIO]:
+        """Creates the right kind of stream based on the preferred format."""
+
         if self.file_mode == FileWriter.OutputMode.TextMode:
             return io.StringIO()
         else:
             return io.BytesIO()
 
-    ## Writes the mesh and returns its value.
     def getBytes(self, nodes: List[SceneNode]) -> bytes:
+        """Writes the mesh and returns its value."""
+
         if self.writer is None:
             raise ValueError("There is no writer for the mesh format handler.")
         stream = self.createStream()
@@ -73,10 +82,12 @@ class MeshFormatHandler:
             value = value.encode()
         return value
 
-    ## Chooses the preferred file format for the given file handler.
-    #  \param firmware_version: The version of the firmware.
-    #  \return A dict with the file format details.
     def _getPreferredFormat(self, firmware_version: str) -> Dict[str, Union[str, int, bool]]:
+        """Chooses the preferred file format for the given file handler.
+        
+        :param firmware_version: The version of the firmware.
+        :return: A dict with the file format details.
+        """
         # Formats supported by this application (file types that we can actually write).
         application = CuraApplication.getInstance()
 
@@ -108,9 +119,11 @@ class MeshFormatHandler:
             )
         return file_formats[0]
 
-    ## Gets the file writer for the given file handler and mime type.
-    #  \param mime_type: The mine type.
-    #  \return A file writer.
     def _getWriter(self, mime_type: str) -> Optional[FileWriter]:
+        """Gets the file writer for the given file handler and mime type.
+        
+        :param mime_type: The mine type.
+        :return: A file writer.
+        """
         # Just take the first file format available.
         return self._file_handler.getWriterByMimeType(mime_type)

+ 4 - 4
plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py

@@ -7,12 +7,12 @@ from UM.Message import Message
 I18N_CATALOG = i18nCatalog("cura")
 
 
-## Message shown when trying to connect to a legacy printer device.
 class LegacyDeviceNoLongerSupportedMessage(Message):
-    
-    # Singleton used to prevent duplicate messages of this type at the same time.
+    """Message shown when trying to connect to a legacy printer device."""
+
     __is_visible = False
-    
+    """Singleton used to prevent duplicate messages of this type at the same time."""
+
     def __init__(self) -> None:
         super().__init__(
             text = I18N_CATALOG.i18nc("@info:status", "You are attempting to connect to a printer that is not "

+ 2 - 2
plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py

@@ -13,11 +13,11 @@ if TYPE_CHECKING:
 I18N_CATALOG = i18nCatalog("cura")
 
 
-## Message shown when sending material files to cluster host.
 class MaterialSyncMessage(Message):
+    """Message shown when sending material files to cluster host."""
 
-    # Singleton used to prevent duplicate messages of this type at the same time.
     __is_visible = False
+    """Singleton used to prevent duplicate messages of this type at the same time."""
 
     def __init__(self, device: "UltimakerNetworkedPrinterOutputDevice") -> None:
         super().__init__(

+ 2 - 2
plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py

@@ -16,11 +16,11 @@ if TYPE_CHECKING:
 I18N_CATALOG = i18nCatalog("cura")
 
 
-## Message shown when trying to connect to a printer that is not a host.
 class NotClusterHostMessage(Message):
+    """Message shown when trying to connect to a printer that is not a host."""
 
-    # Singleton used to prevent duplicate messages of this type at the same time.
     __is_visible = False
+    """Singleton used to prevent duplicate messages of this type at the same time."""
 
     def __init__(self, device: "UltimakerNetworkedPrinterOutputDevice") -> None:
         super().__init__(

+ 2 - 2
plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py

@@ -7,9 +7,9 @@ from UM.Message import Message
 I18N_CATALOG = i18nCatalog("cura")
 
 
-## Message shown when uploading a print job to a cluster is blocked because another upload is already in progress.
 class PrintJobUploadBlockedMessage(Message):
-    
+    """Message shown when uploading a print job to a cluster is blocked because another upload is already in progress."""
+
     def __init__(self) -> None:
         super().__init__(
             text = I18N_CATALOG.i18nc("@info:status", "Please wait until the current job has been sent."),

+ 2 - 2
plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py

@@ -7,9 +7,9 @@ from UM.Message import Message
 I18N_CATALOG = i18nCatalog("cura")
 
 
-## Message shown when uploading a print job to a cluster failed.
 class PrintJobUploadErrorMessage(Message):
-    
+    """Message shown when uploading a print job to a cluster failed."""
+
     def __init__(self, message: str = None) -> None:
         super().__init__(
             text = message or I18N_CATALOG.i18nc("@info:text", "Could not upload the data to the printer."),

Some files were not shown because too many files changed in this diff