Improve filament spool metadata parsing

This commit is contained in:
2026-04-15 20:21:28 +03:00
parent ec0a0bf9af
commit f861db762b

View File

@@ -512,7 +512,7 @@ class FilamentTrackingService:
def _spool_payload_for_stock(self, stock_item: dict[str, Any]) -> dict[str, Any]:
part = stock_item.get("part_detail") or {}
part_name = str(part.get("full_name") or part.get("name") or f"InvenTree stock {stock_item.get('pk')}")
material, color_name, brand = self._parse_part_name(part_name)
material, color_name, brand, subtype = self._parse_part_name(part_name)
remaining = self._stock_quantity(stock_item)
label_weight = self._label_weight_for_stock(remaining)
weight_used = max(label_weight - remaining, 0)
@@ -522,6 +522,7 @@ class FilamentTrackingService:
"material": material[:50] or self.settings.filament_default_material,
"color_name": color_name,
"brand": brand,
"subtype": subtype,
"label_weight": label_weight,
"core_weight": self.settings.filament_default_core_weight,
"weight_used": round(weight_used, 3),
@@ -540,6 +541,7 @@ class FilamentTrackingService:
"material",
"color_name",
"brand",
"subtype",
"label_weight",
"core_weight",
"weight_used",
@@ -624,13 +626,46 @@ class FilamentTrackingService:
return default_weight
return int(((remaining + 99) // 100) * 100)
def _parse_part_name(self, part_name: str) -> tuple[str, str | None, str | None]:
tokens = [token for token in re.split(r"[_\-\s]+", part_name.strip()) if token]
material = tokens[0] if tokens else self.settings.filament_default_material
brand = tokens[-1] if len(tokens) >= 3 else None
color_tokens = tokens[1:-1] if brand else tokens[1:]
def _parse_part_name(self, part_name: str) -> tuple[str, str | None, str | None, str | None]:
tokens = [token for token in re.split(r"[_\-\s|]+", part_name.strip()) if token]
material_index = self._material_token_index(tokens)
if material_index is None:
material = tokens[0] if tokens else self.settings.filament_default_material
content_tokens = tokens[1:]
else:
material = tokens[material_index]
content_tokens = tokens[material_index + 1 :]
subtype = None
if content_tokens and content_tokens[-1].upper() in {"REFIL", "REFILL"}:
subtype = content_tokens.pop(-1).upper()
brand = content_tokens[-1] if len(content_tokens) >= 2 else None
color_tokens = content_tokens[:-1] if brand else content_tokens
color_name = " ".join(color_tokens).title() if color_tokens else None
return material[:50], color_name, brand
return material[:50], color_name, brand, subtype
@staticmethod
def _material_token_index(tokens: list[str]) -> int | None:
known_materials = {
"ABS",
"ABS+",
"ASA",
"HIPS",
"NYLON",
"PA",
"PBT",
"PC",
"PET",
"PETG",
"PLA",
"PVA",
"TPU",
}
for index, token in enumerate(tokens):
if token.upper() in known_materials:
return index
return None
@staticmethod
def _values_differ(current: Any, expected: Any) -> bool: