123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- import json
- import re
- from pathlib import Path
- from pycs import db
- from pycs.database.base import NamedBaseModel
- from pycs.interfaces.LabelProvider import LabelProvider as LabelProviderInterface
- class LabelProvider(NamedBaseModel):
- """
- DB model for label providers
- """
- description = db.Column(db.String)
- root_folder = db.Column(db.String, nullable=False)
- configuration_file = db.Column(db.String, nullable=False)
- # relationships to other models
- projects = db.relationship("Project", backref="label_provider", lazy="dynamic")
- # contraints
- __table_args__ = (
- db.UniqueConstraint('root_folder', 'configuration_file'),
- )
- serialize_only = NamedBaseModel.serialize_only + (
- "description",
- "root_folder",
- "configuration_file",
- )
- @classmethod
- def discover(cls, root: Path):
- """
- searches for label providers under the given path
- and stores them in the database
- """
- for folder, conf_path in _find_files(root):
- with open(conf_path) as conf_file:
- config = json.load(conf_file)
- provider, _ = cls.get_or_create(
- root_folder=str(folder),
- configuration_file=conf_path.name
- )
- provider.name = config['name']
- # returns None if not present
- provider.description = config.get('description')
- provider.flush()
- db.session.commit()
- @property
- def root(self) -> Path:
- """ returns the root folder as Path object """
- return Path(self.root_folder)
- @property
- def configuration_file_path(self) -> str:
- """ return the configuration file as Path object """
- return str(self.root / self.configuration_file)
- def load(self) -> LabelProviderInterface:
- """
- load configuration.json and create an instance from the included code object
- :return: LabelProvider instance
- """
- # load configuration.json
- with open(self.configuration_file_path) as configuration_file:
- configuration = json.load(configuration_file)
- # load code
- code_path = str(self.root / configuration['code']['module'])
- module_name = code_path.replace('/', '.').replace('\\', '.')
- class_name = configuration['code']['class']
- imported_module = __import__(module_name, fromlist=[class_name])
- class_attr = getattr(imported_module, class_name)
- # return instance
- return class_attr(self.root_folder, configuration)
- def _find_files(root: str, config_regex=re.compile(r'^configuration(\d+)?\.json$')):
- """ generator for config files found under the given path """
- for folder in Path(root).glob('*'):
- # list files
- for file_path in folder.iterdir():
- # filter configuration files
- if not file_path.is_file():
- continue
- if config_regex.match(file_path.name) is None:
- continue
- # yield element
- yield folder, file_path
|