Merge pull request #19644 from Ultimaker/CURA-12138-Export_for_support_option

Cura 12138 export for support option
This commit is contained in:
HellAholic 2024-10-07 16:08:23 +02:00 committed by GitHub
commit b9344f29c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 46 additions and 3 deletions

View File

@ -8,9 +8,12 @@ from io import StringIO
from threading import Lock from threading import Lock
import zipfile import zipfile
from typing import Dict, Any from typing import Dict, Any
from pathlib import Path
from zipfile import ZipFile
from UM.Application import Application from UM.Application import Application
from UM.Logger import Logger from UM.Logger import Logger
from UM.PluginRegistry import PluginRegistry
from UM.Preferences import Preferences from UM.Preferences import Preferences
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Workspace.WorkspaceWriter import WorkspaceWriter from UM.Workspace.WorkspaceWriter import WorkspaceWriter
@ -33,7 +36,7 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
if self._ucp_model != model: if self._ucp_model != model:
self._ucp_model = model self._ucp_model = model
def _write(self, stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode): def _write(self, stream, nodes, mode, include_log):
application = Application.getInstance() application = Application.getInstance()
machine_manager = application.getMachineManager() machine_manager = application.getMachineManager()
@ -79,6 +82,11 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
if self._ucp_model is not None: if self._ucp_model is not None:
user_settings_data = self._getUserSettings(self._ucp_model) user_settings_data = self._getUserSettings(self._ucp_model)
ThreeMFWriter._storeMetadataJson(user_settings_data, archive, USER_SETTINGS_PATH) ThreeMFWriter._storeMetadataJson(user_settings_data, archive, USER_SETTINGS_PATH)
# Write log file
if include_log:
ThreeMFWorkspaceWriter._writeLogFile(archive)
except PermissionError: except PermissionError:
self.setInformation(catalog.i18nc("@error:zip", "No permission to write the workspace here.")) self.setInformation(catalog.i18nc("@error:zip", "No permission to write the workspace here."))
Logger.error("No permission to write workspace to this stream.") Logger.error("No permission to write workspace to this stream.")
@ -125,8 +133,8 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
return True return True
def write(self, stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode): def write(self, stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode, **kwargs):
success = self._write(stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode) success = self._write(stream, nodes, WorkspaceWriter.OutputMode.BinaryMode, kwargs.get("include_log", False))
self._ucp_model = None self._ucp_model = None
return success return success
@ -191,6 +199,17 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
Logger.error("File became inaccessible while writing to it: {archive_filename}".format(archive_filename = archive.fp.name)) Logger.error("File became inaccessible while writing to it: {archive_filename}".format(archive_filename = archive.fp.name))
return return
@staticmethod
def _writeLogFile(archive: ZipFile) -> None:
"""Helper function that writes the Cura log file to the archive.
:param archive: The archive to write to.
"""
file_logger = PluginRegistry.getInstance().getPluginObject("FileLogger")
file_logger.flush()
for file_path in file_logger.getFilesPaths():
archive.write(file_path, arcname=f"log/{Path(file_path).name}")
@staticmethod @staticmethod
def _getUserSettings(model: SettingsExportModel) -> Dict[str, Dict[str, Any]]: def _getUserSettings(model: SettingsExportModel) -> Dict[str, Dict[str, Any]]:
user_settings = {} user_settings = {}

View File

@ -77,6 +77,7 @@ Item
property alias paste: pasteAction property alias paste: pasteAction
property alias copy: copyAction property alias copy: copyAction
property alias cut: cutAction property alias cut: cutAction
property alias exportProjectForSupport: exportProjectForSupportAction
readonly property bool copy_paste_enabled: { readonly property bool copy_paste_enabled: {
const all_enabled_packages = CuraApplication.getPackageManager().allEnabledPackages; const all_enabled_packages = CuraApplication.getPackageManager().allEnabledPackages;
@ -549,4 +550,25 @@ Item
text: "&Marketplace" text: "&Marketplace"
icon.name: "plugins_browse" icon.name: "plugins_browse"
} }
Action
{
id: exportProjectForSupportAction
text: catalog.i18nc("@action:inmenu menubar:help", "Export Package For Technical Support")
onTriggered:
{
var exportName = Qt.formatDateTime(new Date(), "'export-'yyyyMMdd-HHmmss")
var args = {
"filter_by_machine": false,
"file_type": "workspace",
"preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml",
"limit_mimetypes": ["application/vnd.ms-package.3dmanufacturing-3dmodel+xml"],
"silent_save": true,
"writer_args": {
"include_log": true
}
};
UM.OutputDeviceManager.requestWriteToDevice("local_file", exportName, args)
}
}
} }

View File

@ -18,6 +18,8 @@ Cura.Menu
Cura.MenuItem { action: Cura.Actions.reportBug } Cura.MenuItem { action: Cura.Actions.reportBug }
Cura.MenuItem { action: Cura.Actions.openSponsershipPage } Cura.MenuItem { action: Cura.Actions.openSponsershipPage }
Cura.MenuSeparator { } Cura.MenuSeparator { }
Cura.MenuItem { action: Cura.Actions.exportProjectForSupport }
Cura.MenuSeparator { }
Cura.MenuItem { action: Cura.Actions.whatsNew } Cura.MenuItem { action: Cura.Actions.whatsNew }
Cura.MenuItem { action: Cura.Actions.about } Cura.MenuItem { action: Cura.Actions.about }
} }