Profile.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. # Copyright (c) 2018 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. import configparser #To read config files.
  4. import io #To write config files to strings as if they were files.
  5. from typing import Dict, List, Optional, Tuple
  6. import UM.VersionUpgrade
  7. from UM.Logger import Logger
  8. ## Creates a new profile instance by parsing a serialised profile in version 1
  9. # of the file format.
  10. #
  11. # \param serialised The serialised form of a profile in version 1.
  12. # \param filename The supposed filename of the profile, without extension.
  13. # \return A profile instance, or None if the file format is incorrect.
  14. def importFrom(serialised: str, filename: str) -> Optional["Profile"]:
  15. try:
  16. return Profile(serialised, filename)
  17. except (configparser.Error, UM.VersionUpgrade.FormatException, UM.VersionUpgrade.InvalidVersionException):
  18. return None
  19. ## A representation of a profile used as intermediary form for conversion from
  20. # one format to the other.
  21. class Profile:
  22. ## Reads version 1 of the file format, storing it in memory.
  23. #
  24. # \param serialised A string with the contents of a profile.
  25. # \param filename The supposed filename of the profile, without extension.
  26. def __init__(self, serialised: str, filename: str) -> None:
  27. self._filename = filename
  28. parser = configparser.ConfigParser(interpolation = None)
  29. parser.read_string(serialised)
  30. # Check correctness.
  31. if not parser.has_section("general"):
  32. raise UM.VersionUpgrade.FormatException("No \"general\" section.")
  33. if not parser.has_option("general", "version"):
  34. raise UM.VersionUpgrade.FormatException("No \"version\" in the \"general\" section.")
  35. if int(parser.get("general", "version")) != 1: # Hard-coded profile version here. If this number changes the entire function needs to change.
  36. raise UM.VersionUpgrade.InvalidVersionException("The version of this profile is wrong. It must be 1.")
  37. # Parse the general section.
  38. self._name = parser.get("general", "name")
  39. self._type = parser.get("general", "type")
  40. self._weight = None
  41. if "weight" in parser["general"]:
  42. self._weight = int(parser.get("general", "weight"))
  43. self._machine_type_id = parser.get("general", "machine_type")
  44. self._machine_variant_name = parser.get("general", "machine_variant")
  45. self._machine_instance_name = parser.get("general", "machine_instance")
  46. self._material_name = None
  47. if "material" in parser["general"]: #Note: Material name is unused in this upgrade.
  48. self._material_name = parser.get("general", "material")
  49. elif self._type == "material":
  50. self._material_name = parser.get("general", "name")
  51. # Parse the settings.
  52. self._settings = {} # type: Dict[str,str]
  53. if parser.has_section("settings"):
  54. for key, value in parser["settings"].items():
  55. self._settings[key] = value
  56. # Parse the defaults and the disabled defaults.
  57. self._changed_settings_defaults = {} # type: Dict[str,str]
  58. if parser.has_section("defaults"):
  59. for key, value in parser["defaults"].items():
  60. self._changed_settings_defaults[key] = value
  61. self._disabled_settings_defaults = [] # type: List[str]
  62. if parser.has_section("disabled_defaults"):
  63. disabled_defaults_string = parser.get("disabled_defaults", "values")
  64. self._disabled_settings_defaults = [item for item in disabled_defaults_string.split(",") if item != ""] # Split by comma.
  65. ## Serialises this profile as file format version 2.
  66. #
  67. # \return A tuple containing the new filename and a serialised form of
  68. # this profile, serialised in version 2 of the file format.
  69. def export(self) -> Optional[Tuple[List[str], List[str]]]:
  70. import VersionUpgrade21to22 # Import here to prevent circular dependencies.
  71. if self._name == "Current settings":
  72. 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.
  73. config = configparser.ConfigParser(interpolation = None)
  74. config.add_section("general")
  75. config.set("general", "version", "2") #Hard-coded profile version 2.
  76. config.set("general", "name", self._name)
  77. if self._machine_type_id:
  78. translated_machine = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translatePrinter(self._machine_type_id)
  79. config.set("general", "definition", translated_machine)
  80. else:
  81. 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.
  82. config.add_section("metadata")
  83. 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.
  84. config.set("metadata", "type", "quality")
  85. if self._weight:
  86. config.set("metadata", "weight", str(self._weight))
  87. if self._machine_variant_name:
  88. if self._machine_type_id:
  89. config.set("metadata", "variant", VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateVariant(self._machine_variant_name, self._machine_type_id))
  90. else:
  91. config.set("metadata", "variant", self._machine_variant_name)
  92. if self._settings:
  93. self._settings = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateSettings(self._settings)
  94. config.add_section("values")
  95. for key, value in self._settings.items():
  96. config.set("values", key, str(value))
  97. if self._changed_settings_defaults:
  98. self._changed_settings_defaults = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateSettings(self._changed_settings_defaults)
  99. config.add_section("defaults")
  100. for key, value in self._changed_settings_defaults.items():
  101. config.set("defaults", key, str(value))
  102. if self._disabled_settings_defaults:
  103. disabled_settings_defaults = [VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateSettingName(setting)
  104. for setting in self._disabled_settings_defaults]
  105. config.add_section("disabled_defaults")
  106. disabled_defaults_string = str(disabled_settings_defaults[0]) #Must be at least 1 item, otherwise we wouldn't enter this if statement.
  107. for item in disabled_settings_defaults[1:]:
  108. disabled_defaults_string += "," + str(item)
  109. output = io.StringIO()
  110. config.write(output)
  111. return [self._filename], [output.getvalue()]