import os,string,sys import yaml class MetaGenerator: def __init__(self) -> None: self.__schema = None def set_schema(self,schema = None): self.__schema = schema def get_template(self,field,lang='de'): if 'template' in self.__schema[field]: return self.__schema[field]['template'][lang] else: return "$value" def is_translatable(self,field): if 'translatable' in self.__schema[field]: return self.__schema[field]['translatable'] else: return True def needs_spec(self,field): if 'spec' in self.__schema[field]: return self.__schema[field] else: return False def process_label(self,field,lang='de'): # processes the label of a field item return self.__schema[field]['label'][lang] def process_str(self,meta,field,lang='de'): if self.is_translatable(field): return [self.process_label(field,lang),meta[field][lang]] else: if not 'value' in meta[field]: raise AssertionError(field,'incomplete') return [self.process_label(field,lang),meta[field]['value']] def process_enum(self,meta,field,lang='de'): """ enum have a specification 'specs' option that can be forced by the scheme """ vv = meta[field]['value'] enum_val = self.__schema[field]['values'][vv][lang] if self.needs_spec(field): t = string.Template(self.get_template(field=field,lang=lang)) spec = meta[field]['spec'][lang] return [self.process_label(field,lang),t.substitute({'value': enum_val,'spec': spec})] else: return [self.process_label(field,lang),enum_val] def process_num(self,meta,field,lang='de'): v = meta[field]['value'] t = string.Template(self.get_template(field,lang)) return [self.process_label(field,lang),t.substitute({'value' : v})] def process_multinum(self,meta,field,lang='de'): v = meta[field]['value'] t = string.Template(self.get_template(field,lang)) if hasattr(v, "__len__"): vv = [t.substitute({'value' : ev}) for ev in v] return [self.process_label(field,lang),', '.join(vv)] else: return self.process_num(meta=meta,field=field,lang=lang) def process_multikey(self,meta,field,lang='de'): """ multikey need to assign a numeric value to a key """ vs = meta[field]['value'] t = string.Template(self.get_template(field,lang)) k = self.process_label(field,lang) parts = [] for e in vs: kk = self.__schema[field]['keys'][e][lang] parts.append(t.substitute({'key': kk, 'value' : vs[e]})) return [k,', '.join(parts)] def process(self,meta,fields = [],lang = 'de',pagebreak = False,createTitle=False,header_level=1,template=None): table_items = [] # iterate over requested fields for field in fields: try: # correlate with schema and append match self.__schema[field]['type']: case 'str': table_items.append(self.process_str(meta,field,lang)) case 'enum': table_items.append(self.process_enum(meta,field,lang)) case 'int' | 'num' : table_items.append(self.process_num(meta,field,lang)) case 'multinum' : table_items.append(self.process_multinum(meta,field,lang)) case 'multikey': table_items.append(self.process_multikey(meta,field,lang)) except Exception as exp: print(field,exp,exp.args) # maybe return tableitems as np.Dataframe? return table_items # if template != None: # # use template generator # TemplateGenerator.generate(table_items,pagebreak,createTitle,header_level=header_level) # pass # else: # # conventional MD mode # MarkdownGenerator.generate(table_items,pagebreak,createTitle,header_level=header_level) # def process_book_section(self,section,lang='de'): # pass # book mode # def process_book(self,book,bookpath,create_title,pagebreak,lang='de',header_level=2): # actual_fields = [] # for bi in book['book']: # if 'fields' in bi: # actual_fields = bi['fields'] # if 'sections' in bi: # for section in bi['sections']: # if 'text' in section: # print(section['text'][lang]) # if 'modules' in section: # for m in section['modules']: # mod_path = os.path.join(os.path.dirname(bookpath),m) # with open(mod_path) as fm: # try: # table_items = self.process(yaml.load(fm,Loader=yaml.Loader),fields=actual_fields,lang=lang,pagebreak=pagebreak,createTitle=create_title,header_level=header_level) # print(table_items) # except Exception as exc: # print(f'{type(exc).__name__} in {mod_path}: {exc}',file=sys.stderr)