Moved internal filters to the base class.
So they can be used not only for internal BoM purposes.
This commit is contained in:
parent
d5fe46ab8e
commit
7882cb0f4f
|
|
@ -4,8 +4,23 @@
|
|||
# License: GPL-3.0
|
||||
# Project: KiBot (formerly KiPlot)
|
||||
from .registrable import RegFilter, Registrable, RegOutput
|
||||
from .misc import IFILL_MECHANICAL
|
||||
from .error import KiPlotConfigurationError
|
||||
from .bom.columnlist import ColumnList
|
||||
from .macros import macros, document # noqa: F401
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
DEFAULT_EXCLUDE = [{'column': ColumnList.COL_REFERENCE, 'regex': '^TP[0-9]*'},
|
||||
{'column': ColumnList.COL_REFERENCE, 'regex': '^FID'},
|
||||
{'column': ColumnList.COL_PART, 'regex': 'mount.*hole'},
|
||||
{'column': ColumnList.COL_PART, 'regex': 'solder.*bridge'},
|
||||
{'column': ColumnList.COL_PART, 'regex': 'solder.*jump'},
|
||||
{'column': ColumnList.COL_PART, 'regex': 'test.*point'},
|
||||
{'column': ColumnList.COL_FP, 'regex': 'test.*point'},
|
||||
{'column': ColumnList.COL_FP, 'regex': 'mount.*hole'},
|
||||
{'column': ColumnList.COL_FP, 'regex': 'fiducial'},
|
||||
]
|
||||
|
||||
|
||||
class DummyFilter(Registrable):
|
||||
|
|
@ -54,6 +69,7 @@ class BaseFilter(RegFilter):
|
|||
def __init__(self):
|
||||
super().__init__()
|
||||
self._unkown_is_error = True
|
||||
self._internal = False
|
||||
with document:
|
||||
self.name = ''
|
||||
""" Used to identify this particular filter definition """
|
||||
|
|
@ -62,8 +78,56 @@ class BaseFilter(RegFilter):
|
|||
self.comment = ''
|
||||
""" A comment for documentation purposes """
|
||||
|
||||
def config(self):
|
||||
super().config()
|
||||
if self.name[0] == '_' and not self._internal:
|
||||
raise KiPlotConfigurationError('Filter names starting with `_` are reserved ({})'.format(self.name))
|
||||
|
||||
@staticmethod
|
||||
def solve_filter(names, def_key, def_real, creator, target_name):
|
||||
def _create_mechanical(name):
|
||||
o_tree = {'name': name}
|
||||
o_tree['type'] = 'generic'
|
||||
o_tree['comment'] = 'Internal default mechanical filter'
|
||||
o_tree['exclude_any'] = DEFAULT_EXCLUDE
|
||||
logger.debug('Creating internal filter: '+str(o_tree))
|
||||
return o_tree
|
||||
|
||||
@staticmethod
|
||||
def _create_kibom_dnx(name):
|
||||
type = name[7:10]
|
||||
if len(name) > 11:
|
||||
subtype = name[11:]
|
||||
else:
|
||||
subtype = 'config'
|
||||
o_tree = {'name': name}
|
||||
o_tree['type'] = 'generic'
|
||||
o_tree['comment'] = 'Internal KiBoM '+type.upper()+' filter ('+subtype+')'
|
||||
o_tree['config_field'] = subtype
|
||||
o_tree['exclude_value'] = True
|
||||
o_tree['exclude_config'] = True
|
||||
o_tree['keys'] = type+'_list'
|
||||
if type[-1] == 'c':
|
||||
o_tree['invert'] = True
|
||||
logger.debug('Creating internal filter: '+str(o_tree))
|
||||
return o_tree
|
||||
|
||||
@staticmethod
|
||||
def _create_internal_filter(name):
|
||||
if name == IFILL_MECHANICAL:
|
||||
tree = BaseFilter._create_mechanical(name)
|
||||
elif name.startswith('_kibom_dn') and len(name) >= 10:
|
||||
tree = BaseFilter._create_kibom_dnx(name)
|
||||
else:
|
||||
return None
|
||||
filter = RegFilter.get_class_for(tree['type'])()
|
||||
filter._internal = True
|
||||
filter.set_tree(tree)
|
||||
filter.config()
|
||||
RegOutput.add_filter(filter)
|
||||
return filter
|
||||
|
||||
@staticmethod
|
||||
def solve_filter(names, target_name, default=None):
|
||||
""" Name can be:
|
||||
- A class, meaning we have to use a default.
|
||||
- A string, the name of a filter.
|
||||
|
|
@ -72,42 +136,33 @@ class BaseFilter(RegFilter):
|
|||
If def_real is not None we pass this name to creator. """
|
||||
if isinstance(names, type):
|
||||
# Nothing specified, use the default
|
||||
names = [def_key]
|
||||
if default is None:
|
||||
return None
|
||||
names = [default]
|
||||
elif isinstance(names, str):
|
||||
# User provided, but only one, make a list
|
||||
names = [names]
|
||||
# Here we should have a list of strings
|
||||
filters = []
|
||||
for name in names:
|
||||
if name and name[0] == '!':
|
||||
if not name:
|
||||
continue
|
||||
if name[0] == '!':
|
||||
invert = True
|
||||
name = name[1:]
|
||||
else:
|
||||
invert = False
|
||||
filter = None
|
||||
if name == def_key:
|
||||
# Matched the default name, translate it to the real name
|
||||
if def_real:
|
||||
name = def_real
|
||||
# Is already defined?
|
||||
if RegOutput.is_filter(name):
|
||||
filter = RegOutput.get_filter(name)
|
||||
else: # Nope, create it
|
||||
tree = creator(name)
|
||||
filter = RegFilter.get_class_for(tree['type'])()
|
||||
filter.set_tree(tree)
|
||||
filter.config()
|
||||
RegOutput.add_filter(filter)
|
||||
elif name:
|
||||
# A filter that is supposed to exist
|
||||
if not RegOutput.is_filter(name):
|
||||
raise KiPlotConfigurationError("Unknown filter `{}` used for `{}`".format(name, target_name))
|
||||
# Is already defined?
|
||||
if RegOutput.is_filter(name):
|
||||
filter = RegOutput.get_filter(name)
|
||||
if filter:
|
||||
if invert:
|
||||
filters.append(NotFilter(filter))
|
||||
else:
|
||||
filters.append(filter)
|
||||
else: # Nope, can be created?
|
||||
filter = BaseFilter._create_internal_filter(name)
|
||||
if filter is None:
|
||||
raise KiPlotConfigurationError("Unknown filter `{}` used for `{}`".format(name, target_name))
|
||||
if invert:
|
||||
filters.append(NotFilter(filter))
|
||||
else:
|
||||
filters.append(filter)
|
||||
# Finished collecting filters
|
||||
if not filters:
|
||||
return DummyFilter()
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ URL_PCBDRAW = 'https://github.com/INTI-CMNB/pcbdraw'
|
|||
EXAMPLE_CFG = 'example.kibot.yaml'
|
||||
AUTO_SCALE = 0
|
||||
|
||||
# Internal filter names
|
||||
IFILL_MECHANICAL = '_mechanical'
|
||||
|
||||
# Supported values for "do not fit"
|
||||
DNF = {
|
||||
"dnf": 1,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from .gs import GS
|
|||
from .optionable import Optionable, BaseOptions
|
||||
from .registrable import RegOutput
|
||||
from .error import KiPlotConfigurationError
|
||||
from .misc import IFILL_MECHANICAL
|
||||
from .macros import macros, document, output_class # noqa: F401
|
||||
from .bom.columnlist import ColumnList, BoMError
|
||||
from .bom.bom import do_bom
|
||||
|
|
@ -174,17 +175,6 @@ class GroupFields(Optionable):
|
|||
|
||||
|
||||
class BoMOptions(BaseOptions):
|
||||
DEFAULT_EXCLUDE = [{'column': ColumnList.COL_REFERENCE, 'regex': '^TP[0-9]*'},
|
||||
{'column': ColumnList.COL_REFERENCE, 'regex': '^FID'},
|
||||
{'column': ColumnList.COL_PART, 'regex': 'mount.*hole'},
|
||||
{'column': ColumnList.COL_PART, 'regex': 'solder.*bridge'},
|
||||
{'column': ColumnList.COL_PART, 'regex': 'solder.*jump'},
|
||||
{'column': ColumnList.COL_PART, 'regex': 'test.*point'},
|
||||
{'column': ColumnList.COL_FP, 'regex': 'test.*point'},
|
||||
{'column': ColumnList.COL_FP, 'regex': 'mount.*hole'},
|
||||
{'column': ColumnList.COL_FP, 'regex': 'fiducial'},
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
with document:
|
||||
self.number = 1
|
||||
|
|
@ -282,31 +272,7 @@ class BoMOptions(BaseOptions):
|
|||
self.variant.config_field = self.fit_field
|
||||
self.variant.variant = []
|
||||
self.variant.name = 'default'
|
||||
|
||||
@staticmethod
|
||||
def _create_mechanical(name):
|
||||
o_tree = {'name': name}
|
||||
o_tree['type'] = 'generic'
|
||||
o_tree['comment'] = 'Internal default mechanical filter'
|
||||
o_tree['exclude_any'] = BoMOptions.DEFAULT_EXCLUDE
|
||||
logger.debug('Creating internal filter: '+str(o_tree))
|
||||
return o_tree
|
||||
|
||||
@staticmethod
|
||||
def _create_kibom_dnx(name):
|
||||
type = name[7:10]
|
||||
subtype = name[11:]
|
||||
o_tree = {'name': name}
|
||||
o_tree['type'] = 'generic'
|
||||
o_tree['comment'] = 'Internal KiBoM '+type.upper()+' filter ('+subtype+')'
|
||||
o_tree['config_field'] = subtype
|
||||
o_tree['exclude_value'] = True
|
||||
o_tree['exclude_config'] = True
|
||||
o_tree['keys'] = type+'_list'
|
||||
if type[-1] == 'c':
|
||||
o_tree['invert'] = True
|
||||
logger.debug('Creating internal filter: '+str(o_tree))
|
||||
return o_tree
|
||||
self.variant.config() # Fill or adjust any detail
|
||||
|
||||
def config(self):
|
||||
super().config()
|
||||
|
|
@ -335,15 +301,10 @@ class BoMOptions(BaseOptions):
|
|||
# component_aliases
|
||||
if isinstance(self.component_aliases, type):
|
||||
self.component_aliases = DEFAULT_ALIASES
|
||||
# exclude_filter
|
||||
self.exclude_filter = BaseFilter.solve_filter(self.exclude_filter, '_mechanical', None,
|
||||
BoMOptions._create_mechanical, 'exclude_filter')
|
||||
# dnf_filter
|
||||
self.dnf_filter = BaseFilter.solve_filter(self.dnf_filter, '_kibom_dnf', '_kibom_dnf_'+self.fit_field,
|
||||
BoMOptions._create_kibom_dnx, 'dnf_filter')
|
||||
# dnc_filter
|
||||
self.dnc_filter = BaseFilter.solve_filter(self.dnc_filter, '_kibom_dnc', '_kibom_dnc_'+self.fit_field,
|
||||
BoMOptions._create_kibom_dnx, 'dnc_filter')
|
||||
# Filters
|
||||
self.exclude_filter = BaseFilter.solve_filter(self.exclude_filter, 'exclude_filter', IFILL_MECHANICAL)
|
||||
self.dnf_filter = BaseFilter.solve_filter(self.dnf_filter, 'dnf_filter', '_kibom_dnf_'+self.fit_field)
|
||||
self.dnc_filter = BaseFilter.solve_filter(self.dnc_filter, 'dnc_filter', '_kibom_dnc_'+self.fit_field)
|
||||
# Variants, make it an object
|
||||
self._normalize_variant()
|
||||
# Field names are handled in lowercase
|
||||
|
|
|
|||
Loading…
Reference in New Issue