File: Profile.py

package info (click to toggle)
cura 5.0.0-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 122,888 kB
  • sloc: python: 44,572; sh: 81; xml: 32; makefile: 16
file content (130 lines) | stat: -rw-r--r-- 6,977 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.

import configparser #To read config files.
import io #To write config files to strings as if they were files.
from typing import Dict, List, Optional, Tuple

import UM.VersionUpgrade


##  Creates a new profile instance by parsing a serialised profile in version 1
#   of the file format.
#
#   \param serialised The serialised form of a profile in version 1.
#   \param filename The supposed filename of the profile, without extension.
#   \return A profile instance, or None if the file format is incorrect.
def importFrom(serialised: str, filename: str) -> Optional["Profile"]:
    try:
        return Profile(serialised, filename)
    except (configparser.Error, UM.VersionUpgrade.FormatException, UM.VersionUpgrade.InvalidVersionException):
        return None


##  A representation of a profile used as intermediary form for conversion from
#   one format to the other.
class Profile:
    ##  Reads version 1 of the file format, storing it in memory.
    #
    #   \param serialised A string with the contents of a profile.
    #   \param filename The supposed filename of the profile, without extension.
    def __init__(self, serialised: str, filename: str) -> None:
        self._filename = filename

        parser = configparser.ConfigParser(interpolation = None)
        parser.read_string(serialised)

        # Check correctness.
        if not parser.has_section("general"):
            raise UM.VersionUpgrade.FormatException("No \"general\" section.")
        if not parser.has_option("general", "version"):
            raise UM.VersionUpgrade.FormatException("No \"version\" in the \"general\" section.")
        if int(parser.get("general", "version")) != 1: # Hard-coded profile version here. If this number changes the entire function needs to change.
            raise UM.VersionUpgrade.InvalidVersionException("The version of this profile is wrong. It must be 1.")

        # Parse the general section.
        self._name = parser.get("general", "name")
        self._type = parser.get("general", "type")
        self._weight = None
        if "weight" in parser["general"]:
            self._weight = int(parser.get("general", "weight"))
        self._machine_type_id = parser.get("general", "machine_type")
        self._machine_variant_name = parser.get("general", "machine_variant")
        self._machine_instance_name = parser.get("general", "machine_instance")
        self._material_name = None
        if "material" in parser["general"]: #Note: Material name is unused in this upgrade.
            self._material_name = parser.get("general", "material")
        elif self._type == "material":
            self._material_name = parser.get("general", "name")

        # Parse the settings.
        self._settings = {} # type: Dict[str,str]
        if parser.has_section("settings"):
            for key, value in parser["settings"].items():
                self._settings[key] = value

        # Parse the defaults and the disabled defaults.
        self._changed_settings_defaults = {}    # type: Dict[str,str]
        if parser.has_section("defaults"):
            for key, value in parser["defaults"].items():
                self._changed_settings_defaults[key] = value
        self._disabled_settings_defaults = []   # type: List[str]
        if parser.has_section("disabled_defaults"):
            disabled_defaults_string = parser.get("disabled_defaults", "values")
            self._disabled_settings_defaults = [item for item in disabled_defaults_string.split(",") if item != ""] # Split by comma.

    ##  Serialises this profile as file format version 2.
    #
    #   \return A tuple containing the new filename and a serialised form of
    #   this profile, serialised in version 2 of the file format.
    def export(self) -> Optional[Tuple[List[str], List[str]]]:
        import VersionUpgrade21to22 # Import here to prevent circular dependencies.

        if self._name == "Current settings":
            return None #Can't upgrade these, because the new current profile needs to specify the definition ID and the old file only had the machine instance, not the definition.

        config = configparser.ConfigParser(interpolation = None)

        config.add_section("general")
        config.set("general", "version", "2") #Hard-coded profile version 2.
        config.set("general", "name", self._name)
        if self._machine_type_id:
            translated_machine = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translatePrinter(self._machine_type_id)
            config.set("general", "definition", translated_machine)
        else:
            config.set("general", "definition", "fdmprinter") #In this case, the machine definition is unknown, and it might now have machine-specific profiles, in which case this will fail.

        config.add_section("metadata")
        config.set("metadata", "quality_type", "normal") #This feature doesn't exist in 2.1 yet, so we don't know the actual quality type. For now, always base it on normal.
        config.set("metadata", "type", "quality")
        if self._weight:
            config.set("metadata", "weight", str(self._weight))
        if self._machine_variant_name:
            if self._machine_type_id:
                config.set("metadata", "variant", VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateVariant(self._machine_variant_name, self._machine_type_id))
            else:
                config.set("metadata", "variant", self._machine_variant_name)

        if self._settings:
            self._settings = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateSettings(self._settings)
            config.add_section("values")
            for key, value in self._settings.items():
                config.set("values", key, str(value))

        if self._changed_settings_defaults:
            self._changed_settings_defaults = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateSettings(self._changed_settings_defaults)
            config.add_section("defaults")
            for key, value in self._changed_settings_defaults.items():
                config.set("defaults", key, str(value))

        if self._disabled_settings_defaults:
            disabled_settings_defaults = [VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateSettingName(setting)
                                          for setting in self._disabled_settings_defaults]
            config.add_section("disabled_defaults")
            disabled_defaults_string = str(disabled_settings_defaults[0]) #Must be at least 1 item, otherwise we wouldn't enter this if statement.
            for item in disabled_settings_defaults[1:]:
                disabled_defaults_string += "," + str(item)

        output = io.StringIO()
        config.write(output)
        return [self._filename], [output.getvalue()]