84 lines
3.1 KiB
Python
84 lines
3.1 KiB
Python
from __future__ import annotations
|
|
import tempfile
|
|
from pathlib import Path
|
|
from typing import Any, TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from .parser import ExprNode
|
|
|
|
class Profile:
|
|
def __init__(
|
|
self,
|
|
key: str,
|
|
category: str,
|
|
path: Path,
|
|
has_header: bool,
|
|
conf_dict: dict[str, Any]
|
|
):
|
|
self.key = key
|
|
self.category = category
|
|
self.path = path
|
|
self.has_header = has_header
|
|
self.conf_dict = conf_dict
|
|
|
|
self.id = self.key.split(':')[1] if len(self.key.split(':')) > 1 else self.key
|
|
self.vendor = ""
|
|
self.all_conf_dict: dict[str, Any] = {}
|
|
self.compatibility_expression: ExprNode | None = None
|
|
|
|
self.compatible_profiles: list[Profile] = []
|
|
|
|
@property
|
|
def compatible_print_profiles(self) -> list[Profile]:
|
|
return [k for k in self.compatible_profiles if k.category == 'print']
|
|
|
|
@property
|
|
def compatible_filament_profiles(self) -> list[Profile]:
|
|
return [k for k in self.compatible_profiles if k.category == 'filament']
|
|
|
|
def generate_inherited_conf(self, all_profiles: dict[str, Profile]):
|
|
"""Calculates the full configuration dictionary by resolving inheritance."""
|
|
from .utils import generate_conf
|
|
from .parser import Parser
|
|
|
|
self.all_conf_dict = generate_conf(all_profiles, self.key)
|
|
self.vendor = self.all_conf_dict.get('filament_vendor', '')
|
|
|
|
if self.category == 'printer':
|
|
nozzle_diameters = self.all_conf_dict.get('nozzle_diameter', '0.4')
|
|
self.all_conf_dict['num_extruders'] = str(len(nozzle_diameters.split(',')))
|
|
|
|
if exp := self.all_conf_dict.get('compatible_printers_condition'):
|
|
try:
|
|
self.compatibility_expression = Parser(exp).parse()
|
|
except Exception as e:
|
|
print(f'Expression parsing failed for {self.id}: {exp} - {e}')
|
|
|
|
def evaluate_compatibility(self, profiles: dict[str, Profile]):
|
|
"""Checks which of the provided profiles are compatible with this one."""
|
|
self.compatible_profiles = []
|
|
for key, p in profiles.items():
|
|
compat = p.compatibility_expression
|
|
if not compat or compat.eval(self.all_conf_dict):
|
|
self.compatible_profiles += [p]
|
|
|
|
class ConfigWriter:
|
|
def __init__(self, conf: dict[str, str | list[str]]) -> None:
|
|
self.config_dict: dict[str, str | list[str]] = conf
|
|
self.temp_dir = tempfile.gettempdir()
|
|
|
|
def write_ini_3mf(self, config_local_path: Path):
|
|
with open(config_local_path, 'w') as file:
|
|
for key, val in dict(sorted(self.config_dict.items())).items():
|
|
if key == "wipe_tower_position":
|
|
continue
|
|
file.write(f"; {key} = {val}\n")
|
|
|
|
def get(self, key: str, default: str = "") -> str | list[str]:
|
|
return self.config_dict.get(key, default)
|
|
|
|
@property
|
|
def checksum(self) -> int:
|
|
import json, zlib
|
|
data = json.dumps(self.config_dict, sort_keys=True).encode("utf-8")
|
|
return zlib.crc32(data) & 0xFFFFFFFF
|