from nitpo import Nitpo import copy import filing from datetime import datetime # import subprocess # import json # only needed for testnig # import time # debugging # import docing from reports import Reports import lxml.etree as etree from anpro import Anpro from nixer import Nixer from profile import Profile from surks import Surks from vakis import Vakis from xpaths import Xpaths class Fecha(Nitpo): def __init__(self, do_verbose=False): super().__init__() self.do_verbose = do_verbose self.anpro = Anpro() self.nixer = Nixer() self.profile = Profile() self.reports = Reports() self.surks = Surks() self.vakis = Vakis() self.xpaths = Xpaths() self.out = {} return None def output(self, env, preps): is_it_parsed = self.parse_uri(env, preps) if not is_it_parsed: ## signals error return {} return self.out def parse_uri(self, env, preps): raw_uri = env['RAW_URI'] self.out['raw_uri'] = env['RAW_URI'] repcode = None emad = None out = preps['res']['re'].fullmatch(raw_uri) if out is None: # # let server.py generate a human response return False #else: # self.out['perid'] = out.groups(0)[2] repcode = out.groups(0)[0] ## syntax check for repcode, if it fails, ## we use a human-readable page if not preps['res']['repcode'].fullmatch(repcode): return False ## now we need to get started with proding a fetcha output web_ele = copy.deepcopy(preps['web_ele']) emad = out.groups(0)[1] # # questionable whether we should # if not self.reports.does_it_exist(repcode): if not self.reports.does_it_exist(repcode): web_ele.attrib['status'] = 'bad_report' # time.sleep(6) web_ele.attrib['repcode'] = repcode self.out['repcode'] = repcode web_ele.attrib['emad'] = emad self.out['emad'] = emad web_ele = self.deal_with_profile(repcode, emad, web_ele) ## for debugging # filing.install_xml(web_ele, '/tmp/fecha.xml') web_doc = etree.ElementTree(web_ele) message = str(preps['sheets']['fecha'](web_doc)) self.out['message'] = message return True def deal_with_profile(self, repcode, emad, web_ele): profile_doc = self.profile.load(emad) bounced = self.profile.is_bounced(profile_doc) if bounced is not None: web_ele.attrib['bounced'] = bounced self.out['bounced'] = bounced ## web_ele contains the profile_doc ## goes to fecha version ## web_ele = self.surks.fecha_add(profile_doc, repcode, emad, web_ele) ## new, makes it local web_ele = self.add(profile_doc, repcode, emad, web_ele) if 'changed' not in web_ele.attrib: return web_ele profile_ele = self.xpaths.none_or_one(web_ele, '/n:web/n:profile') if profile_ele is None: # # nothing to write, should not be the case return web_ele #print(etree.tostring(web_ele, pretty_print=True).decode()) if 'status' in web_ele.attrib: if web_ele.attrib['status'] == 'already_subscribed': return web_ele self.profile.doc = etree.ElementTree(profile_ele) ## register vakis profile_fufi = self.profile.fufi_from_emad(emad) self.profile.write(profile_doc) now = self.now() web_doc = etree.ElementTree(web_ele) self.anpro.from_doc(web_doc, source="fecha", time=now) self.out['anpro'] = 'done' self.vakis.read_single(profile_fufi) return web_ele def add(self, profile_doc, repcode, emad, web_ele): """a reduced version of surks.register_add""" xp = '/n:profile/n:live/n:surk[@repcode="' + repcode + '"]' surk_ele = self.xpaths.none_or_one(profile_doc, xp) ## bounced, checked first even though it is rarer baunz_doc = self.nixer.load(emad) if self.nixer.load(emad) is not None: ## also used for legacy in-profile bounces web_ele.attrib['status'] = 'bounced' self.nixer.baufi(emad, baunz_doc, profile_doc, repcode) return web_ele if surk_ele is not None: web_ele.attrib['status'] = 'already_subscribed' web_ele.append(profile_doc.getroot()) ## by default, resent only, i.e. if the mail file ## already exists latest = self.surks.emailer.send_latest(repcode, emad) # print(latest) if latest is True: web_ele.attrib['sent'] = 'resent' return web_ele web_ele.attrib['changed'] = 'true' surk_ele = etree.Element(self.surks.N + 'surk') surk_ele.attrib['repcode'] = repcode surk_ele.attrib['from'] = datetime.today().strftime(self.const['tf']) self.surks.add_kapro(surk_ele, emad) xp = '/n:profile/n:live' live_ele = self.xpaths.none_or_one(profile_doc, xp) if live_ele is None: # # create live element, should have been there xp = '/n:profile' profile_ele = self.xpaths.none_or_one(profile_doc, xp) live_ele = self.surks.E(self.surks.N + 'live') profile_ele.append(live_ele) ## first addition before the change ## only do the changed profile, the stylesheet is not smart enough ## for two profiles. ## web_ele.append(profile_doc.getroot()) live_ele.append(surk_ele) profile_doc = self.surks.add_kisus(profile_doc) web_ele.attrib['status'] = 'welcome' ## second append after the change web_ele.append(profile_doc.getroot()) return web_ele