import json import os import sys import lxml.etree as etree from nitpo import Nitpo import filing import uuid import subprocess class Sheets(Nitpo): def __init__(self, do_verbose=False): super().__init__() # # complied stylesheets, done once self.sheets = {} if not self.has_conf('folders', 'style'): print("sheets need a folder to continue.") sys.exit() return None # def fufi_to_json(self, shena, in_fufi, out_fufi, params=None): # sheet_fufi = self.get_sheet_fufi(shena) # if not filer.donere(out_fufi, [sheet_fufi, in_fufi]): # return False # in_doc = etree.parse(in_fufi) # out_doc = self.get_result(shena, in_doc) # out_bytes = bytes(out_doc) # out_string = out_bytes.decode('utf-8') # del in_doc # del out_bytes # # def doc_to_json(self, shena, in_doc, params=None): # out_doc = self.get_result(shena, in_doc) # out_bytes = bytes(out_doc) # out_string = out_bytes.decode('utf-8') # del in_doc # del out_bytes # # data = json.loads(out_string) # return out_string # # def ingest_to_fufi(self, shena, ingest, out_fufi, params=None): # if ingest is None: # ingest = etree.fromstring('') # if isinstance(ingest, str): # ingest = etree.parse(ingest) # out_doc = self.get_result(shena, ingest, params=params) # out_doc.write(out_fufi, pretty_print=True) # return out_doc # # def doc_to_text(self, shena, in_doc, params=None): # if in_doc is None: # in_doc = et.fromstring('') # out_doc = self.get_result(shena, in_doc) # out_bytes = bytes(out_doc) # out_string = out_bytes.decode('utf-8') # del in_doc # del out_bytes # gc.collect() # return out_string def load_sheet(self, shena): sheet_fufi = self.get_sheet_fufi(shena) sheet_doc = etree.parse(sheet_fufi) sheet = etree.XSLT(sheet_doc) sheet.set_global_max_depth(1000000) self.sheets[shena] = sheet return sheet def get_result(self, shena, in_doc, params=None): """uses a sheet name""" if shena not in self.sheets: print(f"sheets loads {shena}") self.load_sheet(shena) this_sheet = self.sheets[shena] if params is None: result = this_sheet(in_doc) else: # # don't know what the ** means here result = this_sheet(in_doc, **params) return result def get_sheet_fufi(self, shena): """get a sheet, in two ways""" if self.has_conf('sheets', shena): sheet_fufi = self.conf['sheets'][shena] return sheet_fufi if self.has_conf('folders', 'xslt'): sheet_fufi = self.conf['folders']['xslt'] + '/' + shena + '.xslt.xml' print(sheet_fufi) if os.path.isfile(sheet_fufi): return sheet_fufi sheet_fufi = self.conf['folders']['style'] + '/' + shena + '.xslt.xml' if os.path.isfile(sheet_fufi): return sheet_fufi raise Exception(f"I don't see a sheet file for {shena}") def fufi_to_fufi(self, shena, in_fufi, out_fufi, params=None): sheet_fufi = self.get_sheet_fufi(shena) if not filing.donere(out_fufi, [sheet_fufi, in_fufi]): return False in_doc = etree.parse(in_fufi) out_doc = self.get_result(shena, in_doc) out_bytes = bytes(out_doc) out_string = out_bytes.decode('utf-8') filing.prepare(out_fufi) filing.srite(out_fufi, out_string) return out_string def fufi_to_docu(self, shena, in_fufi, out_fufi, params=None): sheet_fufi = self.get_sheet_fufi(shena) if not filing.donere(out_fufi, [sheet_fufi, in_fufi]): return False in_doc = etree.parse(in_fufi) out_doc = self.get_result(shena, in_doc) out_bytes = bytes(out_doc) out_string = out_bytes.decode('utf-8') filing.prepare(out_fufi) filing.srite(out_fufi, out_string) return out_string def via_system(self, sheet_fufi, in_doc, is_text=False): """for papers screen transformation because so maxvars in lxml""" randna = '/tmp/' + str(uuid.uuid4())[:8] out_fufi = randna + 'out.xml' in_fufi = randna + 'in.xml' in_doc.write(in_fufi, pretty_print=True) err_fufi = randna + '.err' args = '--maxvars 1000000 --maxdepth 1000000' s = f"/usr/bin/xsltproc {args} {sheet_fufi} {in_fufi}" s += f" > {out_fufi} 2> {err_fufi}" subprocess.run(s, check=True, shell=True) if is_text: out_file = open(out_fufi, 'r') doc = out_file.read() else: doc = etree.parse(out_fufi) if os.path.isfile(out_fufi): os.remove(out_fufi) if os.path.isfile(err_fufi): os.remove(err_fufi) return doc