Skip to content

Commit dc01699

Browse files
committed
[Alternatives][Fixed] Missing implementation
1 parent 24af08e commit dc01699

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

kibot/fil_alternatives.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright (c) 2026 Salvador E. Tropea
3+
# Copyright (c) 2026 Instituto Nacional de Tecnología Industrial
4+
# License: AGPL-3.0
5+
# Project: KiBot (formerly KiPlot)
6+
# Description: Extracts information from the distributor spec and fills fields
7+
from .error import KiPlotConfigurationError
8+
from .misc import pretty_list, W_NONUMBER, W_UNKFLD
9+
# from .gs import GS
10+
from .optionable import Optionable
11+
from .macros import macros, document, filter_class # noqa: F401
12+
from . import log
13+
14+
logger = log.get_logger()
15+
16+
17+
class AlternativesSymbols(Optionable):
18+
""" A symbol and the fields to affect """
19+
def __init__(self):
20+
super().__init__()
21+
self._unknown_is_error = True
22+
with document:
23+
self.library_link = ''
24+
""" Full name for the symbol (LIBRARY:SYMBOL) to apply the `fields` """
25+
self.fields = Optionable
26+
""" *[list(string_dict)=[]] List of alternatives """
27+
self._library_link_example = 'Device:R100K'
28+
29+
def config(self, parent):
30+
super().config(parent)
31+
if not self.library_link:
32+
raise KiPlotConfigurationError(f"Missing or empty `library_link` in alternatives filter ({self._tree})")
33+
# if not self.fields:
34+
# raise KiPlotConfigurationError(f"Missing or empty `fields` in alternatives filter ({self._tree})")
35+
36+
def __str__(self):
37+
return self.library_link+' -> '+pretty_list([f.name for f in self.fields])
38+
39+
40+
@filter_class
41+
class Alternatives(BaseFilter): # noqa: F821
42+
""" Alternatives
43+
This filter automatically fills alternative fields for symbols.
44+
You can have various alternative manufacturers, part numbers, etc.
45+
The names of the alternative fields are created using the `pattern` option.
46+
To avoid warnings at least one component in the schematic should define the alternative fields,
47+
you can leave their value empty. In this way KiBot will know these names are valid even before
48+
running the filter.
49+
"""
50+
def __init__(self):
51+
super().__init__()
52+
self._is_transform = True
53+
with document:
54+
self.pattern = '%f%d'
55+
""" Pattern used to generate the alternative field.
56+
%f is the current field name.
57+
%d is the alternative number """
58+
self.number_from = 2
59+
""" First number used for the alternative number (%d) """
60+
self.parts = AlternativesSymbols
61+
""" *[dict|list(dict)=[]] List of symbols to process """
62+
63+
def config(self, parent):
64+
super().config(parent)
65+
if '%d' not in self.pattern:
66+
logger.warning(W_NONUMBER+"The alternative pattern should contain `%d` ({self.pattern})")
67+
self._lib_ids = {p.library_link: p for p in self.parts}
68+
69+
def get_expanded_name(self, name, n):
70+
res = self.pattern
71+
res = res.replace('%f', name)
72+
res = res.replace('%d', str(n))
73+
return res
74+
75+
def filter(self, comp):
76+
# Hay que armar una config e implementarlo
77+
logger.debug(f'- Match for {comp.ref}')
78+
# Check if this matches any of the defined rules
79+
rule = self._lib_ids.get(comp.lib_id)
80+
if not rule:
81+
return
82+
# Add alternatives
83+
n = self.number_from
84+
for fields in rule.fields:
85+
for name, value in fields.items():
86+
full_name = self.get_expanded_name(name, n)
87+
if not name.lower() in comp.dfields:
88+
logger.warning(W_UNKFLD+f"Defining alternative `{full_name}` for `{comp.ref}`, but it doesn't "
89+
f"have `{name}` field")
90+
logger.debug(f' - {full_name} = {value}')
91+
comp.set_field(full_name, value)
92+
n += 1

0 commit comments

Comments
 (0)