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