def requestWrite(self, node, fileName=None, *args, **kwargs):
        if self._stage != OutputStage.ready or self._qidi._isPrinting:
            Message(catalog.i18nc('@info:status',
                                  'Cannot Print, printer is busy'),
                    title=catalog.i18nc("@info:title", "BUSY")).show()
            raise OutputDeviceError.DeviceBusyError()

        # Make sure post-processing plugin are run on the gcode
        self.writeStarted.emit(self)
        if fileName:
            fileName = os.path.splitext(fileName)[0]
        else:
            fileName = "%s" % Application.getInstance().getPrintInformation(
            ).jobName
        self.targetSendFileName = fileName

        path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'qml',
                            'UploadFilename.qml')
        self._dialog = CuraApplication.getInstance().createQmlComponent(
            path, {"manager": self})
        self._dialog.textChanged.connect(self.onFilenameChanged)
        self._dialog.accepted.connect(self.onFilenameAccepted)
        self._dialog.show()
        self._dialog.findChild(QObject, "autoPrint").setProperty(
            'checked', self._autoPrint)
        self._dialog.findChild(QObject, "nameField").setProperty(
            'text', self.targetSendFileName)
        self._dialog.findChild(QObject, "nameField").select(
            0, len(self.targetSendFileName))
        self._dialog.findChild(QObject, "nameField").setProperty('focus', True)
Example #2
0
    def requestWrite(self,
                     nodes: List[SceneNode],
                     file_name: Optional[str] = None,
                     limit_mimetypes: bool = False,
                     file_handler: Optional[FileHandler] = None,
                     **kwargs) -> None:
        """Request the specified nodes to be written.

        Function called every time the 'To Digital Factory' option of the 'Save Project' submenu is triggered or when the
        "Save to Library" action button is pressed (upon slicing).

        :param nodes: A collection of scene nodes that should be written to the file.
        :param file_name: A suggestion for the file name to write to.
        :param limit_mimetypes: Limit the possible mimetypes to use for writing to these types.
        :param file_handler: The handler responsible for reading and writing mesh files.
        :param kwargs: Keyword arguments.
        """

        if self._writing:
            raise OutputDeviceError.DeviceBusyError()
        self.loadWindow()

        if self._account.isLoggedIn and self._controller.userAccountHasLibraryAccess(
        ):
            self._controller.nodes = nodes

            df_workspace_information = self._current_workspace_information.getPluginMetadata(
                "digital_factory")
            self._controller.initialize(
                preselected_project_id=df_workspace_information.get(
                    "library_project_id"))
            self._dialog.show()
    def requestWrite(self, node, fileName=None, *args, **kwargs):
        if self._stage != OutputStage.ready:
            raise OutputDeviceError.DeviceBusyError()

        if fileName:
            fileName = os.path.splitext(fileName)[0] + '.gcode'
        else:
            fileName = "%s.gcode" % Application.getInstance(
            ).getPrintInformation().jobName
        self._fileName = fileName

        path = QUrl.fromLocalFile(
            os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'UploadFilename.qml'))
        self._component = QQmlComponent(Application.getInstance()._engine,
                                        path)
        Logger.log("d", "Errors:", self._component.errors())
        self._context = QQmlContext(
            Application.getInstance()._engine.rootContext())
        self._context.setContextProperty("manager", self)
        self._dialog = self._component.create(self._context)
        self._dialog.textChanged.connect(self.onFilenameChanged)
        self._dialog.accepted.connect(self.onFilenameAccepted)
        self._dialog.open()
        self._dialog.findChild(QObject, "nameField").setProperty(
            'text', self._fileName)
        self._dialog.findChild(QObject,
                               "nameField").select(0,
                                                   len(self._fileName) - 6)
        self._dialog.findChild(QObject, "nameField").setProperty('focus', True)
Example #4
0
    def sendPrintJob(self):
        nodes, file_name, filter_by_machine, file_handler, kwargs = self._request_job
        output_build_plate_number = self._job_list.pop(0)
        gcode = getattr(Application.getInstance().getController().getScene(), "gcode_list")[output_build_plate_number]

        self._send_gcode_start = time.time()
        Logger.log("d", "Sending print job [%s] to host, build plate [%s]..." % (file_name, output_build_plate_number))

        if self._stage != OutputStage.ready:
            Logger.log("d", "Unable to send print job as the state is %s", self._stage)
            raise OutputDeviceError.DeviceBusyError()
        self._stage = OutputStage.uploading

        if self._add_build_plate_number:
            self._file_name = "%s_%d.gcode.gz" % (file_name, output_build_plate_number)
        else:
            self._file_name = "%s.gcode.gz" % (file_name)
        self._showProgressMessage()

        require_printer_name = self._selected_printer["unique_name"]

        new_request = self._buildSendPrintJobHttpRequest(require_printer_name, gcode)
        if new_request is None or self._stage != OutputStage.uploading:
            return
        self._request = new_request
        self._reply = self._manager.post(self._request, self._multipart)
        self._reply.uploadProgress.connect(self._onUploadProgress)
Example #5
0
    def requestWrite(self, node, fileName=None, *args, **kwargs):
        if self._stage != OutputStage.ready:
            raise OutputDeviceError.DeviceBusyError()

        # Make sure post-processing plugin are run on the gcode
        self.writeStarted.emit(self)

        # The presliced print should always be send using `GCodeWriter`
        print_info = CuraApplication.getInstance().getPrintInformation()
        if self._output_format != "ufp" or not print_info or print_info.preSliced:
            self._output_format = "gcode"
            code_writer = cast(
                MeshWriter,
                PluginRegistry.getInstance().getPluginObject("GCodeWriter"))
            self._stream = StringIO()
        else:
            code_writer = cast(
                MeshWriter,
                PluginRegistry.getInstance().getPluginObject("UFPWriter"))
            self._stream = BytesIO()

        if not code_writer.write(self._stream, None):
            Logger.log("e",
                       "MeshWriter failed: %s" % code_writer.getInformation())
            return

        # Prepare filename for upload
        if fileName:
            fileName = os.path.basename(fileName)
        else:
            fileName = "%s." % Application.getInstance().getPrintInformation(
            ).jobName

        # Translate filename
        if self._trans_input and self._trans_output:
            transFileName = fileName.translate(
                fileName.maketrans(
                    self._trans_input, self._trans_output,
                    self._trans_remove if self._trans_remove else ""))
            fileName = transFileName

        self._fileName = fileName + "." + self._output_format

        # Display upload dialog
        path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                            'resources', 'qml', 'MoonrakerUpload.qml')
        self._dialog = CuraApplication.getInstance().createQmlComponent(
            path, {"manager": self})
        self._dialog.textChanged.connect(self.onFilenameChanged)
        self._dialog.accepted.connect(self.onFilenameAccepted)
        self._dialog.show()
        self._dialog.findChild(QObject, "nameField").setProperty(
            'text', self._fileName)
        self._dialog.findChild(QObject, "nameField").select(
            0,
            len(self._fileName) - len(self._output_format) - 1)
        self._dialog.findChild(QObject, "nameField").setProperty('focus', True)
        self._dialog.findChild(QObject, "printField").setProperty(
            'checked', self._upload_start_print_job)
Example #6
0
    def requestWrite(self, node, file_name=None):
        if self._writing:
            raise OutputDeviceError.DeviceBusyError()

        gcode_writer = Application.getInstance().getMeshFileHandler(
        ).getWriterByMimeType("text/x-gcode")
        if not gcode_writer:
            Logger.log(
                "e",
                "Could not find GCode writer, not writing to removable drive %s",
                self.getName())
            raise OutputDeviceError.WriteRequestFailedError()

        if file_name == None:
            for n in BreadthFirstIterator(node):
                if n.getMeshData():
                    file_name = n.getName()
                    if file_name:
                        break

        if not file_name:
            Logger.log(
                "e",
                "Could not determine a proper file name when trying to write to %s, aborting",
                self.getName())
            raise OutputDeviceError.WriteRequestFailedError()

        file_name = os.path.join(self.getId(),
                                 os.path.splitext(file_name)[0] + ".gcode")

        try:
            Logger.log("d", "Writing to %s", file_name)
            stream = open(file_name, "wt")
            job = WriteMeshJob(gcode_writer, stream, node,
                               MeshWriter.OutputMode.TextMode)
            job.setFileName(file_name)
            job.progress.connect(self._onProgress)
            job.finished.connect(self._onFinished)

            message = Message(
                catalog.i18nc(
                    "@info:progress",
                    "Saving to Removable Drive <filename>{0}</filename>").
                format(self.getName()), 0, False, -1)
            message.show()

            self.writeStarted.emit(self)

            job._message = message
            self._writing = True
            job.start()
        except PermissionError as e:
            raise OutputDeviceError.PermissionDeniedError() from e
        except OSError as e:
            raise OutputDeviceError.WriteRequestFailedError() from e
Example #7
0
    def requestWrite(self, node, file_name = None, filter_by_machine = False):
        filter_by_machine = True # This plugin is indended to be used by machine (regardless of what it was told to do)
        if self._writing:
            raise OutputDeviceError.DeviceBusyError()

        file_formats = Application.getInstance().getMeshFileHandler().getSupportedFileTypesWrite() #Formats supported by this application.
        if filter_by_machine:
            machine_file_formats = Application.getInstance().getMachineManager().getActiveMachineInstance().getMachineDefinition().getFileFormats()
            file_formats = list(filter(lambda file_format: file_format["mime_type"] in machine_file_formats, file_formats)) #Take the intersection between file_formats and machine_file_formats.
        if len(file_formats) == 0:
            Logger.log("e", "There are no file formats available to write with!")
            raise OutputDeviceError.WriteRequestFailedError()
        writer = Application.getInstance().getMeshFileHandler().getWriterByMimeType(file_formats[0]["mime_type"]) #Just take the first file format available.
        extension = file_formats[0]["extension"]

        if file_name == None:
            for n in BreadthFirstIterator(node):
                if n.getMeshData():
                    file_name = n.getName()
                    if file_name:
                        break

        if not file_name:
            Logger.log("e", "Could not determine a proper file name when trying to write to %s, aborting", self.getName())
            raise OutputDeviceError.WriteRequestFailedError()

        if extension: #Not empty string.
            extension = "." + extension
        file_name = os.path.join(self.getId(), os.path.splitext(file_name)[0] + extension)

        try:
            Logger.log("d", "Writing to %s", file_name)
            stream = open(file_name, "wt")
            job = WriteMeshJob(writer, stream, node, MeshWriter.OutputMode.TextMode)
            job.setFileName(file_name)
            job.progress.connect(self._onProgress)
            job.finished.connect(self._onFinished)

            message = Message(catalog.i18nc("@info:progress", "Saving to Removable Drive <filename>{0}</filename>").format(self.getName()), 0, False, -1)
            message.show()

            self.writeStarted.emit(self)

            job._message = message
            self._writing = True
            job.start()
        except PermissionError as e:
            Logger.log("e", "Permission denied when trying to write to %s: %s", file_name, str(e))
            raise OutputDeviceError.PermissionDeniedError() from e
        except OSError as e:
            Logger.log("e", "Operating system would not let us write to %s: %s", file_name, str(e))
            raise OutputDeviceError.WriteRequestFailedError() from e
Example #8
0
 def deleteMacros(self):
     if self._stage != OutputStage.ready:
         raise OutputDeviceError.DeviceBusyError()
     self.fileStructer(self._url, 'macros')
     Logger.log('i', 'Macs: '+ str(self._macStruct))
     Logger.log('i', 'Dirs: '+str(self._dirStruct))
     for mac in self._macStruct:
         Logger.log('i','1')
         self._send('delete',[('name',"0:/"+mac),self._timestamp()], self.onMacroDeleted)
         sleep(.1)
     for dir in self._dirStruct:
         Logger.log('i','1')
         self._send('delete',[('name',"0:/"+dir),self._timestamp()], self.onMacroDeleted)
         sleep(.1)
     self.updateMacros()
Example #9
0
    def requestWrite(self, node, fileName=None, *args, **kwargs):
        if self._stage != OutputStage.ready:
            raise OutputDeviceError.DeviceBusyError()

        if fileName:
            fileName = self.nameMaker() + '.gcode'
        else:
            fileName = "%s.gcode" % Application.getInstance().getPrintInformation().jobName
        self._fileName = fileName
        self._baseLength = len(Application.getInstance().getPrintInformation().baseName)
        path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'qml', 'UploadFilename.qml')
        self._dialog = CuraApplication.getInstance().createQmlComponent(path, {"manager": self})
        self._dialog.textChanged.connect(self.onFilenameChanged)
        self._dialog.accepted.connect(self.onFilenameAccepted)
        self._dialog.show()
        self._dialog.findChild(QObject, "nameField").setProperty('text', self._fileName)
        self._dialog.findChild(QObject, "nameField").select(0, self._baseLength)
        self._dialog.findChild(QObject, "nameField").setProperty('focus', True)
    def sendPrintJob(self):
        nodes, file_name, filter_by_machine, file_handler, kwargs = self._request_job
        require_printer_name = self._selected_printer["unique_name"]

        self._send_gcode_start = time.time()
        Logger.log("d", "Sending print job [%s] to host..." % file_name)

        if self._stage != OutputStage.ready:
            Logger.log("d", "Unable to send print job as the state is %s",
                       self._stage)
            raise OutputDeviceError.DeviceBusyError()
        self._stage = OutputStage.uploading

        self._file_name = "%s.gcode.gz" % file_name
        self._showProgressMessage()

        self._request = self._buildSendPrintJobHttpRequest(
            require_printer_name)
        self._reply = self._manager.post(self._request, self._multipart)
        self._reply.uploadProgress.connect(self._onUploadProgress)
Example #11
0
    def requestWrite(self, node, file_name=None, filter_by_machine=False):
        if self._writing:
            raise OutputDeviceError.DeviceBusyError()

        self.writeStarted.emit(self)
        mesh_writer = Application.getInstance().getMeshFileHandler(
        ).getWriterByMimeType("text/x-gcode")

        job = OctoprintUploadJob(mesh_writer, node)
        job.setFileName(file_name + ".gcode")
        job.progress.connect(self._onJobProgress)
        job.finished.connect(self._onWriteJobFinished)

        message = Message("Uploading {0} to {1}".format(
            job.getFileName(),
            Preferences.getInstance().getValue("octoprint/base_url")),
                          0,
                          progress=-1)
        message.show()

        job._message = message
        self._writing = True
        job.start()
Example #12
0
    def requestWrite(self, node, fileName=None, *args, **kwargs):
        if self._stage != OutputStage.ready:
            raise OutputDeviceError.DeviceBusyError()

        if fileName:
            fileName = os.path.splitext(fileName)[0] + '.gcode'
        else:
            fileName = "%s.gcode" % Application.getInstance(
            ).getPrintInformation().jobName
        self._fileName = fileName

        # create the temp file for the gcode
        self._stream = StringIO()
        self._stage = OutputStage.writing
        self.writeStarted.emit(self)

        # show a progress message
        message = Message(
            catalog.i18nc("@info:progress",
                          "Saving to <filename>{0}</filename>").format(
                              self.getName()), 0, False, -1)
        message.show()
        self._message = message

        # send all the gcode to self._stream
        gcode = getattr(Application.getInstance().getController().getScene(),
                        "gcode_list")
        lines = len(gcode)
        nextYield = time() + 0.05
        i = 0
        for line in gcode:
            i += 1
            self._stream.write(line)
            if time() > nextYield:
                self._onProgress(i / lines)
                QCoreApplication.processEvents()
                nextYield = time() + 0.05

        # self._stream now contains the gcode, now upload it
        self._stage = OutputStage.uploading
        self._stream.seek(0)

        # set up a multi-part post
        self._multipart = QtNetwork.QHttpMultiPart(
            QtNetwork.QHttpMultiPart.FormDataType)

        # add the file part
        part = QtNetwork.QHttpPart()
        part.setHeader(QtNetwork.QNetworkRequest.ContentDispositionHeader,
                       'form-data; name="file"; filename="%s"' % fileName)
        part.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader,
                       "application/octet-stream")
        part.setBody(self._stream.getvalue().encode())
        self._multipart.append(part)

        # send the post
        url = "http://" + self._address + "/print"
        Logger.log("d", url)

        self._request = QtNetwork.QNetworkRequest(QUrl(url))
        self._request.setRawHeader('User-agent'.encode(),
                                   'Cura WirelessPrinting Plugin'.encode())
        self._reply = self._qnam.post(self._request, self._multipart)

        # connect the reply signals
        self._reply.error.connect(self._onNetworkError)
        self._reply.uploadProgress.connect(self._onUploadProgress)
        self._reply.downloadProgress.connect(self._onDownloadProgress)
    def requestWrite(self, node, fileName=None, *args, **kwargs):
        if self._stage != OutputStage.ready:
            raise OutputDeviceError.DeviceBusyError()

        if fileName:
            fileName = os.path.splitext(fileName)[0] + '.gcode'
        else:
            fileName = "%s.gcode" % Application.getInstance(
            ).getPrintInformation().jobName
        self._fileName = fileName

        # create the temp file for the gcode
        self._stream = StringIO()
        self._stage = OutputStage.writing
        self.writeStarted.emit(self)

        # show a progress message
        message = Message(
            catalog.i18nc("@info:progress",
                          "Saving to <filename>{0}</filename>").format(
                              self.getName()), 0, False, -1)
        message.show()
        self._message = message

        # send all the gcode to self._stream
        gcode = getattr(Application.getInstance().getController().getScene(),
                        "gcode_list")
        lines = len(gcode)
        nextYield = time() + 0.05
        i = 0
        for line in gcode:
            i += 1
            self._stream.write(line)
            if time() > nextYield:
                self._onProgress(i / lines)
                QCoreApplication.processEvents()
                nextYield = time() + 0.05

        # self._stream now contains the gcode, now upload it
        self._stage = OutputStage.uploading
        self._stream.seek(0)

        # set up a multi-part post
        self._multipart = QtNetwork.QHttpMultiPart(
            QtNetwork.QHttpMultiPart.FormDataType)

        # add the file part
        part = QtNetwork.QHttpPart()
        part.setHeader(QtNetwork.QNetworkRequest.ContentDispositionHeader,
                       'form-data; name="file"; filename="%s"' % fileName)
        part.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader,
                       "application/octet-stream")
        part.setBody(self._stream.getvalue().encode())
        self._multipart.append(part)

        # send the post
        url = "http://" + self._address + "/print"
        Logger.log("d", url)

        self._update_timer.stop()

        ####################################################
        # This is working but ugly. Pull Requests welcome.

        fd = open('/tmp/' + fileName, "w")
        fd.write(self._stream.getvalue())
        fd.close()

        command = 'curl -F "file=@/tmp/' + fileName + '" ' + url
        Logger.log("d", command)

        import subprocess, shlex
        subprocess.Popen(shlex.split(command))

        self._stage = OutputStage.ready
        if self._message:
            self._message.hide()
        self._message = None
Example #14
0
    def requestWrite(self, node, fileName=None, *args, **kwargs):
        if self._stage != OutputStage.ready:
            raise OutputDeviceError.DeviceBusyError()

        if fileName:
            fileName = os.path.splitext(fileName)[0] + '.gcode'
        else:
            fileName = "%s.gcode" % Application.getInstance(
            ).getPrintInformation().jobName
        self._fileName = fileName

        # create the temp file for the gcode
        self._stream = StringIO()
        self._stage = OutputStage.writing
        self.writeStarted.emit(self)

        # show a progress message
        message = Message(
            catalog.i18nc("@info:progress",
                          "Saving to <filename>{0}</filename>").format(
                              self.getName()), 0, False, -1)
        message.show()
        self._message = message

        # find the G-code for the active build plate to print
        active_build_plate_id = Application.getInstance().getBuildPlateModel(
        ).activeBuildPlate
        gcode_dict = getattr(
            Application.getInstance().getController().getScene(), "gcode_dict")
        gcode = gcode_dict[active_build_plate_id]

        # send all the gcode to self._stream
        lines = len(gcode)
        nextYield = time() + 0.05
        i = 0
        for line in gcode:
            i += 1
            self._stream.write(line)
            if time() > nextYield:
                self._onProgress(i / lines)
                QCoreApplication.processEvents()
                nextYield = time() + 0.05

        # self._stream now contains the gcode, now upload it
        self._stage = OutputStage.uploading
        self._stream.seek(0)

        # set up a multi-part post
        self._multipart = QtNetwork.QHttpMultiPart(
            QtNetwork.QHttpMultiPart.FormDataType)

        # add the form variables
        formvalues = {'select': 'false', 'print': 'false'}
        for key, value in formvalues.items():
            part = QtNetwork.QHttpPart()
            part.setHeader(QtNetwork.QNetworkRequest.ContentDispositionHeader,
                           'form-data; name="%s"' % key)
            part.setBody(value.encode())
            self._multipart.append(part)

        # add the file part
        part = QtNetwork.QHttpPart()
        part.setHeader(QtNetwork.QNetworkRequest.ContentDispositionHeader,
                       'form-data; name="file"; filename="%s"' % fileName)
        part.setBody(self._stream.getvalue().encode())
        self._multipart.append(part)

        # send the post
        self._request = QtNetwork.QNetworkRequest(
            QUrl(self._host + "/api/files/local"))
        self._request.setRawHeader(
            'User-agent'.encode(),
            'Cura OctoPrintOutputDevice Plugin'.encode())
        self._request.setRawHeader('X-Api-Key'.encode(), self._apiKey.encode())
        self._reply = self._qnam.post(self._request, self._multipart)

        # connect the reply signals
        self._reply.error.connect(self._onNetworkError)
        self._reply.uploadProgress.connect(self._onUploadProgress)
        self._reply.downloadProgress.connect(self._onDownloadProgress)
    def requestWrite(self,
                     nodes,
                     file_name=None,
                     limit_mimetypes=None,
                     file_handler=None,
                     **kwargs):
        if self._writing:
            raise OutputDeviceError.DeviceBusyError()

            # Set up and display file dialog
        dialog = QFileDialog()

        dialog.setWindowTitle(catalog.i18nc("@title:window", "Save to File"))
        dialog.setFileMode(QFileDialog.AnyFile)
        dialog.setAcceptMode(QFileDialog.AcceptSave)

        # Ensure platform never ask for overwrite confirmation since we do this ourselves
        dialog.setOption(QFileDialog.DontConfirmOverwrite)

        if sys.platform == "linux" and "KDE_FULL_SESSION" in os.environ:
            dialog.setOption(QFileDialog.DontUseNativeDialog)

        filters = []
        mime_types = []
        selected_filter = None
        last_used_type = self._preferences.getValue(
            "local_file/last_used_type")

        if not file_handler:
            file_handler = Application.getInstance().getMeshFileHandler()

        file_types = file_handler.getSupportedFileTypesWrite()

        file_types.sort(key=lambda k: k["description"])
        if limit_mimetypes:
            file_types = list(
                filter(lambda i: i["mime_type"] in limit_mimetypes,
                       file_types))

        if len(file_types) == 0:
            Logger.log("e", "There are no file types available to write with!")
            raise OutputDeviceError.WriteRequestFailedError()

        for item in file_types:
            type_filter = "{0} (*.{1})".format(item["description"],
                                               item["extension"])
            filters.append(type_filter)
            mime_types.append(item["mime_type"])
            if last_used_type == item["mime_type"]:
                selected_filter = type_filter
                if file_name:
                    file_name += "." + item["extension"]

        dialog.setNameFilters(filters)
        if selected_filter is not None:
            dialog.selectNameFilter(selected_filter)

        if file_name is not None:
            dialog.selectFile(file_name)

        stored_directory = self._preferences.getValue(
            "local_file/dialog_save_path")
        dialog.setDirectory(stored_directory)

        if not dialog.exec_():
            raise OutputDeviceError.UserCanceledError()

        save_path = dialog.directory().absolutePath()
        self._preferences.setValue("local_file/dialog_save_path", save_path)

        selected_type = file_types[filters.index(dialog.selectedNameFilter())]
        self._preferences.setValue("local_file/last_used_type",
                                   selected_type["mime_type"])

        # Get file name from file dialog
        file_name = dialog.selectedFiles()[0]
        active_build_plate = Application.getInstance().getMultiBuildPlateModel(
        ).activeBuildPlate
        scene = Application.getInstance().getController().getScene()
        gcode_dict = getattr(scene, "gcode_dict", None)
        if not gcode_dict:
            return
        _gcode = gcode_dict.get(active_build_plate, None)
        self.save_gcode(file_name, _gcode)
Example #16
0
    def requestWrite(self, node, file_name=None, filter_by_machine=False):
        if self._writing:
            raise OutputDeviceError.DeviceBusyError()

        self._writing = True

        # load settings
        if Preferences.getInstance().getValue("MPSelectMini/ip"):
            ip = Preferences.getInstance().getValue("MPSelectMini/ip")
        if Preferences.getInstance().getValue("MPSelectMini/start_print"):
            start_print = Preferences.getInstance().getValue(
                "MPSelectMini/start_print")

        try:
            start_print
        except NameError:
            start_print = False

        # check for valid ip
        if not ip:
            raise OutputDeviceError.WriteRequestFailedError(
                catalog.i18nc("@info:status", "Invalid IP"))

        # Get GCode
        file_formats = Application.getInstance().getMeshFileHandler(
        ).getSupportedFileTypesWrite()
        mesh_writer = Application.getInstance().getMeshFileHandler(
        ).getWriterByMimeType("text/x-gcode")
        stream = io.StringIO()

        mesh_writer.write(stream, node, MeshWriter.OutputMode.TextMode)
        gcode = stream.getvalue()

        try:
            # Upload GCode
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect((ip, 80))
            s.send(bytes('POST /upload HTTP/1.1\r\n', 'ascii'))
            s.send(
                bytes(
                    'Content-Type: multipart/form-data; boundary=------------------------2d30fc993bb09c6a\r\n',
                    'ascii'))
            s.send(bytes('\r\n', 'ascii'))
            s.send(
                bytes('--------------------------2d30fc993bb09c6a\r\n',
                      'ascii'))
            s.send(
                bytes(
                    'Content-Disposition: form-data; name="filedata"; filename="cache.gc"\r\n',
                    'ascii'))
            s.send(bytes('Content-Type: application/octet-stream\r\n',
                         'ascii'))
            s.send(bytes('\r\n', 'ascii'))
            s.send(bytes(gcode, 'ascii'))
            s.send(bytes('\r\n', 'ascii'))
            s.send(
                bytes('--------------------------2d30fc993bb09c6a--\r\n',
                      'ascii'))
            response = str(s.recv(1024), 'ascii')
            s.close()

            # Check upload response
            if response.startswith('HTTP/1.1 200 OK'):
                message = Message(
                    catalog.i18nc("@info:status", "Upload Success"))
                message.show()
            else:
                Logger.log(
                    "e", "Invalid http response uploading gcode:\n" + response)
                raise OutputDeviceError.WriteRequestFailedError(
                    catalog.i18nc("@info:status", "Upload Failed"))

            # Send cancel print (prevents upload bug where printer will start before heating extruder)
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect((ip, 80))
            s.send(bytes('GET /set?cmd={P:X} HTTP/1.1\r\n', 'ascii'))
            s.send(bytes('\r\n', 'ascii'))
            response = str(s.recv(1024), 'ascii')
            s.close()

            if start_print:
                # Send start print
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                s.connect((ip, 80))
                s.send(bytes('GET /set?code=M565 HTTP/1.1\r\n', 'ascii'))
                s.send(bytes('\r\n', 'ascii'))
                response = str(s.recv(1024), 'ascii')
                s.close()

                # Check start print response
                if response.startswith('HTTP/1.1 200 OK'):
                    message = Message(
                        catalog.i18nc("@info:status",
                                      "<b>Printing Started</b>"))
                    message.show()
                else:
                    Logger.log(
                        "e", "Invalid http response starting print job:\n" +
                        response)
                    raise OutputDeviceError.WriteRequestFailedError(
                        catalog.i18nc("@info:status", "Start Print Failed"))

        except (TimeoutError):
            raise OutputDeviceError.WriteRequestFailedError(
                catalog.i18nc("@info:status", "Connection Timeout"))

        self._writing = False
Example #17
0
    def requestWrite(self, nodes, file_name = None, limit_mimetypes = None, file_handler = None, **kwargs):
        """Request the specified nodes to be written to a file.

        :param nodes: A collection of scene nodes that should be written to the
        file.
        :param file_name: A suggestion for the file name to write
        to. Can be freely ignored if providing a file name makes no sense.
        :param limit_mimetypes: Should we limit the available MIME types to the
        MIME types available to the currently active machine?
        :param kwargs: Keyword arguments.
        """

        if self._writing:
            raise OutputDeviceError.DeviceBusyError()

        # Set up and display file dialog
        dialog = QFileDialog()

        dialog.setWindowTitle(catalog.i18nc("@title:window", "Save to Disk"))
        dialog.setFileMode(QFileDialog.FileMode.AnyFile)
        dialog.setAcceptMode(QFileDialog.AcceptMode.AcceptSave)

        # Ensure platform never ask for overwrite confirmation since we do this ourselves
        dialog.setOption(QFileDialog.Option.DontConfirmOverwrite)

        filters = []
        mime_types = []
        selected_filter = None

        if "preferred_mimetypes" in kwargs and kwargs["preferred_mimetypes"] is not None:
            preferred_mimetypes = kwargs["preferred_mimetypes"]
        else:
            preferred_mimetypes = Application.getInstance().getPreferences().getValue("local_file/last_used_type")
        preferred_mimetype_list = preferred_mimetypes.split(";")

        if not file_handler:
            file_handler = Application.getInstance().getMeshFileHandler()

        file_types = file_handler.getSupportedFileTypesWrite()

        file_types.sort(key = lambda k: k["description"])
        if limit_mimetypes:
            file_types = list(filter(lambda i: i["mime_type"] in limit_mimetypes, file_types))

        file_types = [ft for ft in file_types if not ft["hide_in_file_dialog"]]

        if len(file_types) == 0:
            Logger.log("e", "There are no file types available to write with!")
            raise OutputDeviceError.WriteRequestFailedError(catalog.i18nc("@info:warning", "There are no file types available to write with!"))

        # Find the first available preferred mime type
        preferred_mimetype = None
        for mime_type in preferred_mimetype_list:
            if any(ft["mime_type"] == mime_type for ft in file_types):
                preferred_mimetype = mime_type
                break

        extension_added = False
        for item in file_types:
            type_filter = "{0} (*.{1})".format(item["description"], item["extension"])
            filters.append(type_filter)
            mime_types.append(item["mime_type"])
            if preferred_mimetype == item["mime_type"]:
                selected_filter = type_filter
                if file_name and not extension_added:
                    extension_added = True
                    file_name += "." + item["extension"]

        # CURA-6411: This code needs to be before dialog.selectFile and the filters, because otherwise in macOS (for some reason) the setDirectory call doesn't work.
        stored_directory = Application.getInstance().getPreferences().getValue("local_file/dialog_save_path")

        if stored_directory and stored_directory != "" and os.path.exists(stored_directory):
            dialog.setDirectory(stored_directory)

        # Add the file name before adding the extension to the dialog
        if file_name is not None:
            dialog.selectFile(file_name)

        dialog.setNameFilters(filters)
        if selected_filter is not None:
            dialog.selectNameFilter(selected_filter)

        if not dialog.exec():
            raise OutputDeviceError.UserCanceledError()

        save_path = dialog.directory().absolutePath()
        Application.getInstance().getPreferences().setValue("local_file/dialog_save_path", save_path)

        selected_type = file_types[filters.index(dialog.selectedNameFilter())]
        Application.getInstance().getPreferences().setValue("local_file/last_used_type", selected_type["mime_type"])

        # Get file name from file dialog
        file_name = dialog.selectedFiles()[0]
        Logger.log("d", "Writing to [%s]..." % file_name)

        if os.path.exists(file_name):
            result = QMessageBox.question(None, catalog.i18nc("@title:window", "File Already Exists"), catalog.i18nc("@label Don't translate the XML tag <filename>!", "The file <filename>{0}</filename> already exists. Are you sure you want to overwrite it?").format(file_name))
            if result == QMessageBox.StandardButton.No:
                raise OutputDeviceError.UserCanceledError()

        # Actually writing file
        if file_handler:
            file_writer = file_handler.getWriter(selected_type["id"])
        else:
            file_writer = Application.getInstance().getMeshFileHandler().getWriter(selected_type["id"])

        if isinstance(file_writer, WorkspaceWriter):
            self.setLastOutputName(file_name)
        self.writeStarted.emit(self)

        try:
            mode = selected_type["mode"]
            if mode == MeshWriter.OutputMode.TextMode:
                Logger.log("d", "Writing to Local File %s in text mode", file_name)
                stream = open(file_name, "wt", encoding = "utf-8")
            elif mode == MeshWriter.OutputMode.BinaryMode:
                Logger.log("d", "Writing to Local File %s in binary mode", file_name)
                stream = open(file_name, "wb")
            else:
                Logger.log("e", "Unrecognised OutputMode.")
                return None

            job = WriteFileJob(file_writer, stream, nodes, mode)
            job.setFileName(file_name)
            job.setAddToRecentFiles(True)  # The file will be added into the "recent files" list upon success
            job.progress.connect(self._onJobProgress)
            job.finished.connect(self._onWriteJobFinished)

            message = Message(catalog.i18nc("@info:progress Don't translate the XML tags <filename>!",
                                            "Saving to <filename>{0}</filename>").format(file_name),
                              0, False, -1 , catalog.i18nc("@info:title", "Saving"))
            message.show()

            job.setMessage(message)
            self._writing = True
            job.start()
        except PermissionError as e:
            Logger.log("e", "Permission denied when trying to write to %s: %s", file_name, str(e))
            raise OutputDeviceError.PermissionDeniedError(catalog.i18nc("@info:status Don't translate the XML tags <filename>!", "Permission denied when trying to save <filename>{0}</filename>").format(file_name)) from e
        except OSError as e:
            Logger.log("e", "Operating system would not let us write to %s: %s", file_name, str(e))
            raise OutputDeviceError.WriteRequestFailedError(catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "Could not save to <filename>{0}</filename>: <message>{1}</message>").format(file_name, str(e))) from e
Example #18
0
    def requestWrite(self,
                     nodes,
                     file_name=None,
                     filter_by_machine=False,
                     file_handler=None,
                     **kwargs):
        filter_by_machine = True  # This plugin is intended to be used by machine (regardless of what it was told to do)
        if self._writing:
            raise OutputDeviceError.DeviceBusyError()

        # Formats supported by this application (File types that we can actually write)
        if file_handler:
            file_formats = file_handler.getSupportedFileTypesWrite()
        else:
            file_formats = Application.getInstance().getMeshFileHandler(
            ).getSupportedFileTypesWrite()

        if filter_by_machine:
            container = Application.getInstance().getGlobalContainerStack(
            ).findContainer({"file_formats": "*"})
            # Create a list from supported file formats string
            machine_file_formats = [
                file_type.strip() for file_type in container.getMetaDataEntry(
                    "file_formats").split(";")
            ]
            # Take the intersection between file_formats and machine_file_formats.
            format_by_mimetype = {
                format["mime_type"]: format
                for format in file_formats
            }
            file_formats = [
                format_by_mimetype[mimetype]
                for mimetype in machine_file_formats
            ]  #Keep them ordered according to the preference in machine_file_formats.

        if len(file_formats) == 0:
            Logger.log("e",
                       "There are no file formats available to write with!")
            raise OutputDeviceError.WriteRequestFailedError(
                catalog.i18nc(
                    "@info:status",
                    "There are no file formats available to write with!"))
        preferred_format = file_formats[0]

        # Just take the first file format available.
        if file_handler is not None:
            writer = file_handler.getWriterByMimeType(
                preferred_format["mime_type"])
        else:
            writer = Application.getInstance().getMeshFileHandler(
            ).getWriterByMimeType(preferred_format["mime_type"])

        extension = preferred_format["extension"]

        if file_name is None:
            file_name = self._automaticFileName(nodes)

        if extension:  # Not empty string.
            extension = "." + extension
        file_name = os.path.join(self.getId(),
                                 os.path.splitext(file_name)[0] + extension)

        try:
            Logger.log("d", "Writing to %s", file_name)
            # Using buffering greatly reduces the write time for many lines of gcode
            if preferred_format["mode"] == FileWriter.OutputMode.TextMode:
                self._stream = open(file_name,
                                    "wt",
                                    buffering=1,
                                    encoding="utf-8")
            else:  #Binary mode.
                self._stream = open(file_name, "wb", buffering=1)
            job = WriteFileJob(writer, self._stream, nodes,
                               preferred_format["mode"])
            job.setFileName(file_name)
            job.progress.connect(self._onProgress)
            job.finished.connect(self._onFinished)
            message = Message(
                catalog.i18nc(
                    "@info:progress Don't translate the XML tags <filename>!",
                    "Saving to Removable Drive <filename>{0}</filename>").
                format(self.getName()), 0, False, -1,
                catalog.i18nc("@info:title", "Saving"))
            message.show()
            self.writeStarted.emit(self)
            job.setMessage(message)
            self._writing = True
            job.start()
        except PermissionError as e:
            Logger.log("e", "Permission denied when trying to write to %s: %s",
                       file_name, str(e))
            raise OutputDeviceError.PermissionDeniedError(
                catalog.i18nc(
                    "@info:status Don't translate the XML tags <filename> or <message>!",
                    "Could not save to <filename>{0}</filename>: <message>{1}</message>"
                ).format(file_name, str(e))) from e
        except OSError as e:
            Logger.log("e",
                       "Operating system would not let us write to %s: %s",
                       file_name, str(e))
            raise OutputDeviceError.WriteRequestFailedError(
                catalog.i18nc(
                    "@info:status Don't translate the XML tags <filename> or <message>!",
                    "Could not save to <filename>{0}</filename>: <message>{1}</message>"
                ).format(file_name, str(e))) from e
    def requestWrite(self,
                     nodes,
                     file_name=None,
                     limit_mimetypes=None,
                     file_handler=None):
        if self._writing:
            raise OutputDeviceError.DeviceBusyError()

        dialog = QFileDialog()

        dialog.setWindowTitle(catalog.i18nc("@title:window", "Save to File"))
        dialog.setFileMode(QFileDialog.AnyFile)
        dialog.setAcceptMode(QFileDialog.AcceptSave)

        # Ensure platform never ask for overwrite confirmation since we do this ourselves
        dialog.setOption(QFileDialog.DontConfirmOverwrite)

        if sys.platform == "linux" and "KDE_FULL_SESSION" in os.environ:
            dialog.setOption(QFileDialog.DontUseNativeDialog)

        filters = []
        mime_types = []
        selected_filter = None
        last_used_type = Preferences.getInstance().getValue(
            "local_file/last_used_type")

        if not file_handler:
            file_handler = Application.getInstance().getMeshFileHandler()

        file_types = file_handler.getSupportedFileTypesWrite()

        file_types.sort(key=lambda k: k["description"])
        if limit_mimetypes:
            file_types = list(
                filter(lambda i: i["mime_type"] in limit_mimetypes,
                       file_types))

        if len(file_types) == 0:
            Logger.log("e", "There are no file types available to write with!")
            raise OutputDeviceError.WriteRequestFailedError()

        for item in file_types:
            type_filter = "{0} (*.{1})".format(item["description"],
                                               item["extension"])
            filters.append(type_filter)
            mime_types.append(item["mime_type"])
            if last_used_type == item["mime_type"]:
                selected_filter = type_filter
                if file_name:
                    file_name += "." + item["extension"]

        dialog.setNameFilters(filters)
        if selected_filter is not None:
            dialog.selectNameFilter(selected_filter)

        if file_name is not None:
            dialog.selectFile(file_name)

        stored_directory = Preferences.getInstance().getValue(
            "local_file/dialog_save_path")
        dialog.setDirectory(stored_directory)

        if not dialog.exec_():
            raise OutputDeviceError.UserCanceledError()

        save_path = dialog.directory().absolutePath()
        Preferences.getInstance().setValue("local_file/dialog_save_path",
                                           save_path)

        selected_type = file_types[filters.index(dialog.selectedNameFilter())]
        Preferences.getInstance().setValue("local_file/last_used_type",
                                           selected_type["mime_type"])

        file_name = dialog.selectedFiles()[0]

        if os.path.exists(file_name):
            result = QMessageBox.question(
                None, catalog.i18nc("@title:window", "File Already Exists"),
                catalog.i18nc(
                    "@label",
                    "The file <filename>{0}</filename> already exists. Are you sure you want to overwrite it?"
                ).format(file_name))
            if result == QMessageBox.No:
                raise OutputDeviceError.UserCanceledError()

        self.writeStarted.emit(self)

        if file_handler:
            file_writer = file_handler.getWriter(selected_type["id"])
        else:
            file_writer = Application.getInstance().getMeshFileHandler(
            ).getWriter(selected_type["id"])

        try:
            mode = selected_type["mode"]
            if mode == MeshWriter.OutputMode.TextMode:
                Logger.log("d", "Writing to Local File %s in text mode",
                           file_name)
                stream = open(file_name, "wt", encoding="utf-8")
            elif mode == MeshWriter.OutputMode.BinaryMode:
                Logger.log("d", "Writing to Local File %s in binary mode",
                           file_name)
                stream = open(file_name, "wb")

            job = WriteFileJob(file_writer, stream, nodes, mode)
            job.setFileName(file_name)
            job.progress.connect(self._onJobProgress)
            job.finished.connect(self._onWriteJobFinished)

            message = Message(
                catalog.i18nc(
                    "@info:progress",
                    "Saving to <filename>{0}</filename>").format(file_name), 0,
                False, -1)
            message.show()

            job._message = message
            self._writing = True
            job.start()
        except PermissionError as e:
            Logger.log("e", "Permission denied when trying to write to %s: %s",
                       file_name, str(e))
            raise OutputDeviceError.PermissionDeniedError(
                catalog.i18nc(
                    "@info:status",
                    "Permission denied when trying to save <filename>{0}</filename>"
                ).format(file_name)) from e
        except OSError as e:
            Logger.log("e",
                       "Operating system would not let us write to %s: %s",
                       file_name, str(e))
            raise OutputDeviceError.WriteRequestFailedError(
                catalog.i18nc(
                    "@info:status",
                    "Could not save to <filename>{0}</filename>: <message>{1}</message>"
                ).format()) from e
    def requestWrite(self,
                     nodes,
                     file_name=None,
                     limit_mimetypes=None,
                     file_handler=None,
                     **kwargs):
        """Request the specified nodes to be written to a file.

        :param nodes: A collection of scene nodes that should be written to the
        file.
        :param file_name: A suggestion for the file name to write
        to. Can be freely ignored if providing a file name makes no sense.
        :param limit_mimetypes: Should we limit the available MIME types to the
        MIME types available to the currently active machine?
        :param kwargs: Keyword arguments.
        """

        if self._writing:
            raise OutputDeviceError.DeviceBusyError()

        # Set up and display file dialog
        dialog = QFileDialog()

        dialog.setWindowTitle(catalog.i18nc("@title:window", "Save to File"))
        dialog.setFileMode(QFileDialog.AnyFile)
        dialog.setAcceptMode(QFileDialog.AcceptSave)

        # Ensure platform never ask for overwrite confirmation since we do this ourselves
        dialog.setOption(QFileDialog.DontConfirmOverwrite)

        if sys.platform == "linux" and "KDE_FULL_SESSION" in os.environ:
            dialog.setOption(QFileDialog.DontUseNativeDialog)

        filters = []
        mime_types = []
        selected_filter = None

        if "preferred_mimetypes" in kwargs and kwargs[
                "preferred_mimetypes"] is not None:
            preferred_mimetypes = kwargs["preferred_mimetypes"]
        else:
            preferred_mimetypes = Application.getInstance().getPreferences(
            ).getValue("local_file/last_used_type")
        preferred_mimetype_list = preferred_mimetypes.split(";")

        if not file_handler:
            file_handler = Application.getInstance().getMeshFileHandler()

        file_types = file_handler.getSupportedFileTypesWrite()

        file_types.sort(key=lambda k: k["description"])
        if limit_mimetypes:
            file_types = list(
                filter(lambda i: i["mime_type"] in limit_mimetypes,
                       file_types))

        file_types = [ft for ft in file_types if not ft["hide_in_file_dialog"]]

        if len(file_types) == 0:
            Logger.log("e", "There are no file types available to write with!")
            raise OutputDeviceError.WriteRequestFailedError(
                catalog.i18nc(
                    "@info:warning",
                    "There are no file types available to write with!"))

        # Find the first available preferred mime type
        preferred_mimetype = None
        for mime_type in preferred_mimetype_list:
            if any(ft["mime_type"] == mime_type for ft in file_types):
                preferred_mimetype = mime_type
                break

        extension_added = False
        for item in file_types:
            type_filter = "{0} (*.{1})".format(item["description"],
                                               item["extension"])
            filters.append(type_filter)
            mime_types.append(item["mime_type"])
            if preferred_mimetype == item["mime_type"]:
                selected_filter = type_filter
                if file_name and not extension_added:
                    extension_added = True
                    file_name += "." + item["extension"]

        # CURA-6411: This code needs to be before dialog.selectFile and the filters, because otherwise in macOS (for some reason) the setDirectory call doesn't work.
        stored_directory = Application.getInstance().getPreferences().getValue(
            "local_file/dialog_save_path")
        dialog.setDirectory(stored_directory)

        # Add the file name before adding the extension to the dialog
        if file_name is not None:
            dialog.selectFile(file_name)

        dialog.setNameFilters(filters)
        if selected_filter is not None:
            dialog.selectNameFilter(selected_filter)

        if not dialog.exec_():
            raise OutputDeviceError.UserCanceledError()

        save_path = dialog.directory().absolutePath()
        Application.getInstance().getPreferences().setValue(
            "local_file/dialog_save_path", save_path)

        selected_type = file_types[filters.index(dialog.selectedNameFilter())]
        Application.getInstance().getPreferences().setValue(
            "local_file/last_used_type", selected_type["mime_type"])

        # Get file name from file dialog
        file_name = dialog.selectedFiles()[0]
        Logger.log("d", "Writing to [%s]..." % file_name)
        #file_name = file_name.replace('.gcode','.s3d')
        print(file_name)

        if os.path.exists(file_name):
            result = QMessageBox.question(
                None, catalog.i18nc("@title:window", "File Already Exists"),
                catalog.i18nc(
                    "@label Don't translate the XML tag <filename>!",
                    "The file <filename>{0}</filename> already exists. Are you sure you want to overwrite it?"
                ).format(file_name))
            if result == QMessageBox.No:
                raise OutputDeviceError.UserCanceledError()

        self.writeStarted.emit(self)

        # Actually writing file
        if file_handler:
            file_writer = file_handler.getWriter(selected_type["id"])
        else:
            file_writer = Application.getInstance().getMeshFileHandler(
            ).getWriter(selected_type["id"])

        try:
            mode = selected_type["mode"]
            if mode == MeshWriter.OutputMode.TextMode:
                Logger.log("d", "Writing to Local File %s in text mode",
                           file_name)
                stream = open(file_name, "wt", encoding="utf-8")
            elif mode == MeshWriter.OutputMode.BinaryMode:
                Logger.log("d", "Writing to Local File %s in binary mode",
                           file_name)
                stream = open(file_name, "wb")
            else:
                Logger.log("e", "Unrecognised OutputMode.")
                return None
            #print("HELLO WRITE FILE")
            #print(file_writer)
            #print(stream)
            #print(nodes)
            #print(mode)
            #print("HELLO WRITE FILE DONE")
            job = WriteFileJob(file_writer, stream, nodes, mode)
            job.setFileName(file_name)
            job.setAddToRecentFiles(
                True
            )  # The file will be added into the "recent files" list upon success
            job.progress.connect(self._onJobProgress)
            job.finished.connect(self._onWriteJobFinished)
            save_name = file_name.replace('.gcode', '.s3d')
            message = Message(
                catalog.i18nc(
                    "@info:progress Don't translate the XML tags <filename>!",
                    "Saving to <filename>{0}</filename>").format(save_name), 0,
                False, -1, catalog.i18nc("@info:title", "Saving"))
            message.show()

            job.setMessage(message)
            self._writing = True
            import base64
            from cryptography.hazmat.backends import default_backend
            from cryptography.hazmat.primitives import hashes
            from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
            from cryptography.fernet import Fernet, InvalidToken
            key = b'fWn9BDrXryrtcxjXhaO2BR9Oc_bS_zk1k4b6aL_0rbI='
            input_file = file_name
            if '.gcode' in file_name:
                output_file = file_name.replace('.gcode', '.s3d')
            else:
                output_file = file_name + '.s3d'
            #with open(input_file, 'rb') as f:
            #    data = f.read()  # Read the bytes of the input file
#f.close()
#print(data)
            fernet = Fernet(key)
            #encrypted = fernet.encrypt(data)
            #print(len(encrypted))

            #with open(output_file, 'wb') as f:
            #    f.write(encrypted)  # Write the encrypted bytes to the output file

            job.start()
            with open(input_file, 'rb') as f:
                data = f.read()
            #print(data)
            encrypted = fernet.encrypt(data)
            with open(output_file, 'wb') as f:
                f.write(encrypted)
            #import os
            if os.path.exists(input_file):
                os.remove(input_file)
#            os.remove('/home/akshay/STLS/*')
            else:
                print("GCODE FILE MOVED OR TAMPERED WITH")

        except PermissionError as e:
            Logger.log("e", "Permission denied when trying to write to %s: %s",
                       file_name, str(e))
            raise OutputDeviceError.PermissionDeniedError(
                catalog.i18nc(
                    "@info:status Don't translate the XML tags <filename>!",
                    "Permission denied when trying to save <filename>{0}</filename>"
                ).format(file_name)) from e
        except OSError as e:
            Logger.log("e",
                       "Operating system would not let us write to %s: %s",
                       file_name, str(e))
            raise OutputDeviceError.WriteRequestFailedError(
                catalog.i18nc(
                    "@info:status Don't translate the XML tags <filename> or <message>!",
                    "Could not save to <filename>{0}</filename>: <message>{1}</message>"
                ).format(file_name, str(e))) from e
Example #21
0
    def requestWrite(self,
                     nodes,
                     file_name=None,
                     limit_mimetypes=None,
                     file_handler=None,
                     **kwargs):
        application = cast(CuraApplication, Application.getInstance())
        machine_manager = application.getMachineManager()
        global_stack = machine_manager.activeMachine

        filename_format = Application.getInstance().getPreferences().getValue(
            "gcode_filename_format/filename_format")

        Logger.log("d", "filename_format = %s", filename_format)

        if filename_format is "":
            filename_format = DEFAULT_FILENAME_FORMAT

        if self._writing:
            raise OutputDeviceError.DeviceBusyError()

        self.getModifiedPrintSettings(application, global_stack)

        dialog = QFileDialog()

        dialog.setWindowTitle(catalog.i18nc("@title:window", "Save to File"))
        dialog.setFileMode(QFileDialog.AnyFile)
        dialog.setAcceptMode(QFileDialog.AcceptSave)

        dialog.setOption(QFileDialog.DontConfirmOverwrite)

        if sys.platform == "linux" and "KDE_FULL_SESSION" in os.environ:
            dialog.setOption(QFileDialog.DontUseNativeDialog)

        filters = []
        mime_types = []
        selected_filter = None

        if "preferred_mimetypes" in kwargs and kwargs[
                "preferred_mimetypes"] is not None:
            preferred_mimetypes = kwargs["preferred_mimetypes"]
        else:
            preferred_mimetypes = Application.getInstance().getPreferences(
            ).getValue("gcode_filename_format/last_used_type")
        preferred_mimetype_list = preferred_mimetypes.split(";")

        if not file_handler:
            file_handler = Application.getInstance().getMeshFileHandler()

        file_types = file_handler.getSupportedFileTypesWrite()

        file_types.sort(key=lambda k: k["description"])
        if limit_mimetypes:
            file_types = list(
                filter(lambda i: i["mime_type"] in limit_mimetypes,
                       file_types))

        file_types = [ft for ft in file_types if not ft["hide_in_file_dialog"]]

        if len(file_types) == 0:
            Logger.log("e", "There are no file types available to write with!")
            raise OutputDeviceError.WriteRequestFailedError(
                catalog.i18nc(
                    "@info:warning",
                    "There are no file types available to write with!"))

        preferred_mimetype = None
        for mime_type in preferred_mimetype_list:
            if any(ft["mime_type"] == mime_type for ft in file_types):
                preferred_mimetype = mime_type
                break

        for item in file_types:
            type_filter = "{0} (*.{1})".format(item["description"],
                                               item["extension"])
            filters.append(type_filter)
            mime_types.append(item["mime_type"])
            if preferred_mimetype == item["mime_type"]:
                selected_filter = type_filter
                file_name = self.parseFilenameFormat(filename_format,
                                                     file_name, application,
                                                     global_stack)
                #file_name += self.filenameTackOn(print_setting)
                if file_name:
                    file_name += "." + item["extension"]

        stored_directory = Application.getInstance().getPreferences().getValue(
            "gcode_filename_format/dialog_save_path")
        dialog.setDirectory(stored_directory)

        if file_name is not None:
            dialog.selectFile(file_name)

        dialog.setNameFilters(filters)
        if selected_filter is not None:
            dialog.selectNameFilter(selected_filter)

        if not dialog.exec_():
            raise OutputDeviceError.UserCanceledError()

        save_path = dialog.directory().absolutePath()
        Application.getInstance().getPreferences().setValue(
            "gcode_filename_format/dialog_save_path", save_path)

        selected_type = file_types[filters.index(dialog.selectedNameFilter())]
        Application.getInstance().getPreferences().setValue(
            "gcode_filename_format/last_used_type", selected_type["mime_type"])

        file_name = dialog.selectedFiles()[0]
        Logger.log("d", "Writing to [%s]..." % file_name)

        if os.path.exists(file_name):
            result = QMessageBox.question(
                None, catalog.i18nc("@title:window", "File Already Exists"),
                catalog.i18nc(
                    "@label Don't translate the XML tag <filename>!",
                    "The file <filename>{0}</filename> already exists. Are you sure you want to overwrite it?"
                ).format(file_name))
            if result == QMessageBox.No:
                raise OutputDeviceError.UserCanceledError()

        self.writeStarted.emit(self)

        if file_handler:
            file_writer = file_handler.getWriter(selected_type["id"])
        else:
            file_writer = Application.getInstance().getMeshFileHandler(
            ).getWriter(selected_type["id"])

        try:
            mode = selected_type["mode"]
            if mode == MeshWriter.OutputMode.TextMode:
                Logger.log("d", "Writing to Local File %s in text mode",
                           file_name)
                stream = open(file_name, "wt", encoding="utf-8")
            elif mode == MeshWriter.OutputMode.BinaryMode:
                Logger.log("d", "Writing to Local File %s in binary mode",
                           file_name)
                stream = open(file_name, "wb")
            else:
                Logger.log("e", "Unrecognised OutputMode.")
                return None

            job = WriteFileJob(file_writer, stream, nodes, mode)
            job.setFileName(file_name)
            job.setAddToRecentFiles(True)
            job.progress.connect(self._onJobProgress)
            job.finished.connect(self._onWriteJobFinished)

            message = Message(
                catalog.i18nc(
                    "@info:progress Don't translate the XML tags <filename>!",
                    "Saving to <filename>{0}</filename>").format(file_name), 0,
                False, -1, catalog.i18nc("@info:title", "Saving"))
            message.show()

            job.setMessage(message)
            self._writing = True
            job.start()
        except PermissionError as e:
            Logger.log("e", "Permission denied when trying to write to %s: %s",
                       file_name, str(e))
            raise OutputDeviceError.PermissionDeniedError(
                catalog.i18nc(
                    "@info:status Don't translate the XML tags <filename>!",
                    "Permission denied when trying to save <filename>{0}</filename>"
                ).format(file_name)) from e
        except OSError as e:
            Logger.log("e",
                       "Operating system would not let us write to %s: %s",
                       file_name, str(e))
            raise OutputDeviceError.WriteRequestFailedError(
                catalog.i18nc(
                    "@info:status Don't translate the XML tags <filename> or <message>!",
                    "Could not save to <filename>{0}</filename>: <message>{1}</message>"
                ).format()) from e
    def requestWrite(self,
                     nodes,
                     file_name=None,
                     limit_mimetypes=None,
                     file_handler=None,
                     **kwargs):
        if self._writing:
            raise OutputDeviceError.DeviceBusyError()

        # Set up and display file dialog
        dialog = QFileDialog()

        dialog.setWindowTitle(self._translations.get("save_file_window"))
        dialog.setFileMode(QFileDialog.AnyFile)
        dialog.setAcceptMode(QFileDialog.AcceptSave)

        # Ensure platform never ask for overwrite confirmation since we do this ourselves
        dialog.setOption(QFileDialog.DontConfirmOverwrite)

        if sys.platform == "linux" and "KDE_FULL_SESSION" in os.environ:
            dialog.setOption(QFileDialog.DontUseNativeDialog)

        filters = []
        mime_types = []
        selected_filter = None

        if "preferred_mimetypes" in kwargs and kwargs[
                "preferred_mimetypes"] is not None:
            preferred_mimetypes = kwargs["preferred_mimetypes"]
        else:
            preferred_mimetypes = Application.getInstance().getPreferences(
            ).getValue("local_file/last_used_type")
        preferred_mimetype_list = preferred_mimetypes.split(";")

        if not file_handler:
            file_handler = Application.getInstance().getMeshFileHandler()

        file_types = file_handler.getSupportedFileTypesWrite()

        file_types.sort(key=lambda k: k["description"])
        if limit_mimetypes:
            file_types = list(
                filter(lambda i: i["mime_type"] in limit_mimetypes,
                       file_types))

        file_types = [ft for ft in file_types if not ft["hide_in_file_dialog"]]

        if len(file_types) == 0:
            Logger.log("e", "There are no file types available to write with!")
            raise OutputDeviceError.WriteRequestFailedError(
                self._translations.get("no_file_warning"))

        # Find the first available preferred mime type
        preferred_mimetype = None
        for mime_type in preferred_mimetype_list:
            if any(ft["mime_type"] == mime_type for ft in file_types):
                preferred_mimetype = mime_type
                break

        for item in file_types:
            type_filter = "{0} (*.{1})".format(item["description"],
                                               item["extension"])
            filters.append(type_filter)
            mime_types.append(item["mime_type"])
            if preferred_mimetype == item["mime_type"]:
                selected_filter = type_filter
                if file_name:
                    file_name += "." + item["extension"]

        # CURA-6411: This code needs to be before dialog.selectFile and the filters, because otherwise in macOS (for some reason) the setDirectory call doesn't work.
        stored_directory = Application.getInstance().getPreferences().getValue(
            "local_file/dialog_save_path")
        dialog.setDirectory(stored_directory)

        # Add the file name before adding the extension to the dialog
        if file_name is not None:
            dialog.selectFile(file_name)

        dialog.setNameFilters(filters)
        if selected_filter is not None:
            dialog.selectNameFilter(selected_filter)

        if not dialog.exec_():
            raise OutputDeviceError.UserCanceledError()

        save_path = dialog.directory().absolutePath()
        Application.getInstance().getPreferences().setValue(
            "local_file/dialog_save_path", save_path)

        selected_type = file_types[filters.index(dialog.selectedNameFilter())]
        Application.getInstance().getPreferences().setValue(
            "local_file/last_used_type", selected_type["mime_type"])

        # Get file name from file dialog
        file_name = dialog.selectedFiles()[0]
        Logger.log("d", "Writing to [%s]..." % file_name)

        if os.path.exists(file_name):
            result = QMessageBox.question(
                None,
                self._translations.get("file_exists_window").format(
                    file_name[file_name.rfind("/") + 1:]),
                self._translations.get("file_overwrite_label").format(
                    file_name[file_name.rfind("/") + 1:]))
            if result == QMessageBox.No:
                raise OutputDeviceError.UserCanceledError()

        self.writeStarted.emit(self)

        # Actually writing file
        if file_handler:
            file_writer = file_handler.getWriter(selected_type["id"])
        else:
            file_writer = Application.getInstance().getMeshFileHandler(
            ).getWriter(selected_type["id"])

        try:
            mode = selected_type["mode"]
            if mode == MeshWriter.OutputMode.TextMode:
                Logger.log("d", "Writing to Local File %s in text mode",
                           file_name)
                stream = open(file_name, "wt", encoding="utf-8")
            elif mode == MeshWriter.OutputMode.BinaryMode:
                Logger.log("d", "Writing to Local File %s in binary mode",
                           file_name)
                stream = open(file_name, "wb")
            else:
                Logger.log("e", "Unrecognised OutputMode.")
                return None

            # Adding screeshot section
            screenshot_string = utils.add_screenshot()

            if screenshot_string != "":
                stream.write(screenshot_string)
            # End of screeshot section

            job = WriteFileJob(file_writer, stream, nodes, mode)
            job.setFileName(file_name)
            # The file will be added into the "recent files" list upon success
            job.setAddToRecentFiles(True)
            job.progress.connect(self._onJobProgress)
            job.finished.connect(self._onWriteJobFinished)

            message = Message(
                self._translations.get("file_saving_progress").format(
                    file_name), 0, False, -1,
                self._translations.get("file_saving_title"))
            message.show()

            job.setMessage(message)
            self._writing = True
            job.start()
        except PermissionError as e:
            Logger.log("e", "Permission denied when trying to write to %s: %s",
                       file_name, str(e))
            raise OutputDeviceError.PermissionDeniedError(
                self._translations.get("permission_denied").format(
                    file_name)) from e
        except OSError as e:
            Logger.log("e",
                       "Operating system would not let us write to %s: %s",
                       file_name, str(e))
            raise OutputDeviceError.WriteRequestFailedError(
                self._translations.get("permission_denied2").format(
                    file_name, str(e))) from e