"""function to send email""" import os import sys from email.mime.text import MIMEText from email.header import Header from email.mime.multipart import MIMEMultipart from email.utils import formataddr import re import subprocess import filing from nitpo import Nitpo from sheets import Sheets import docing class Emailer(Nitpo): def __init__(self, do_verbose=False): super().__init__() self.sheets = Sheets() self.repis_fufi = None self.do_verbose = do_verbose # # can be set in the headers self.params = {} # # debug if on local computer self.debug = os.path.isfile('/etc/wpa_supplicant.conf') # self.re_nama = re.compile(r"([^<]+)<([^@]+)@([^>]+)>\s*") self.re_nama = re.compile(r"([^<]+)<([^>]+)>\s*") def prepare(self, maix, empro='repis', in_what='empros', dont_send=False, base='base', only=None): """send the email via file, stores the file in base""" mail_fufi = self.conf['folders']['mail'] + '/' + base + '.mail' if os.path.isfile(mail_fufi) and not dont_send: print(f"emailer sees {mail_fufi}, skip") return None # # save xml, for debugging maix_fufi = self.conf['folders']['mail'] + '/' + base + '.xml' if self.debug and empro == 'repis': filing.prepare(maix_fufi) maix_file = open(maix_fufi, 'w') string = docing.show(maix) maix_file.write(string) maix_file.close() # head_doc = self.sheets.get_result(empro + '_head', maix) # sheet_fufi = self.sheets.get_sheet_fufi(empro + '_head') sheet_fufi = self.get_empro_part(empro, 'head', in_what=in_what) if sheet_fufi is None: print("emailer does not see the empro head.") return None head_doc = self.sheets.via_system(sheet_fufi, maix) msg = MIMEMultipart("alternative") xp = '/n:headers/n:header' header_eles = head_doc.xpath(xp, namespaces={'n': self.const['ns']}) for header_ele in header_eles: if 'name' not in header_ele.attrib: show_head_ele = docing.show(header_ele) print(f"email: no name in {show_head_ele}", file=sys.stderr) continue name = header_ele.attrib['name'] if 'value' not in header_ele.attrib: show_head_ele = docing.show(header_ele) print(f"email: no value in {show_head_ele}", file=sys.stderr) continue value = header_ele.attrib['value'] # # if all uppercase names, it's a parameter if name.upper() == name: self.params[name] = value continue if self.is_it_ascii(value): msg[name] = value continue if header_ele.get('type') == 'address': out = str(self.make_address(value)) if out is not None: msg[name] = out continue msg[name] = Header(value, 'utf-8') if only != 'html': # empro_text = empro + '_text' sheet_fufi = self.get_empro_part(empro, 'text', in_what=in_what) if sheet_fufi is not None: string = self.sheets.via_system(sheet_fufi, maix, is_text=True) # string = docing.show(html) if dont_send: print(string) part = MIMEText(str(string), "plain", _charset='utf-8') msg.attach(part) #if self.has_conf('sheets', empro_text): # # text = self.sheets.get_result(empro_text, maix) # # detour via sytem # sheet_fufi = self.sheets.get_sheet_fufi(empro + '_text') # text = self.sheets.via_system(sheet_fufi, maix, is_text=True) # part = MIMEText(str(text), "plain") # msg.attach(part) if only != 'text': # empro_html = empro + '_html' # if self.has_conf('sheets', empro_html): # # html = self.sheets.get_result(empro_html, maix) # # detour via sytem # sheet_fufi = self.sheets.get_sheet_fufi(empro + '_html') # html = self.sheets.via_system(sheet_fufi, maix) # string = docing.show(html) # part = MIMEText(str(string), "html", # _charset='utf-8') # msg.attach(part) # # print(html) sheet_fufi = self.get_empro_part(empro, 'html', in_what=in_what) if sheet_fufi is not None: html = self.sheets.via_system(sheet_fufi, maix) string = docing.show(html) part = MIMEText(str(string), "html", _charset='utf-8') msg.attach(part) mail_fufi = self.conf['folders']['mail'] + '/' + base + '.mail' filing.prepare(mail_fufi) mail_file = open(mail_fufi, 'w') mail_file.write(msg.as_string()) mail_file.close() if dont_send is True: print(f"emailer wrote {mail_fufi}, not sent") return None # # for the admirable p.o'brien@... #if "'" in mail_fufi: # mail_command = f'cat "{mail_fufi}" | /usr/sbin/exim4 -t' #else: mail_command = f"cat {mail_fufi} | /usr/sbin/exim4 -t" envelope_address = self.get_envelope_address() if envelope_address is not None: mail_command += f" -f {envelope_address}" # # don't send on the test machine if not os.path.isfile('/etc/wpa_supplicant.conf'): out = subprocess.run(mail_command, shell=True, check=True) else: print(f"emailer wrote {mail_fufi}") out = None if empro != 'repis': print(f"emailer wrote {mail_fufi}") return out def get_envelope_address(self): if 'ENVELOPE_ADDRESS' in self.params: return self.params['ENVELOPE_ADDRESS'] if self.has_conf('addresses', 'envelope'): return self.conf['addresses']['envelope'] return None def is_it_ascii(self, string): try: string.encode('ascii') except UnicodeEncodeError: return False return True def make_address(self, nama): out = self.re_nama.match(nama) if(out is None): print(f"emailer can't parse '{nama}'") return None name = out.group(1).strip() emad = out.group(2).strip() # # https://stackoverflow.com/questions/10551933/python-email-module-form-header-from-with-some-unicode-name-email address = formataddr((str(Header(name, 'utf-8')), emad)) return address def has_it_empro(self, empro, in_what='empros'): """is there is empro available""" if self.get_empro_part(empro, 'head', in_what=in_what) is None: return False if self.get_empro_part(empro, 'text', in_what=in_what) is not None: return True if self.get_empro_part(empro, 'html', in_what=in_what) is not None: return True return True def get_empro_part(self, empro, part, in_what='empros'): """empro part either by sheets conf or seen""" target = f"{empro}_{part}" ### check the configuration if self.has_conf('sheets', target): fufi = self.conf['sheets'][target] if not os.path.isfile(fufi): print(f"emailer does not see {fufi}", file=sys.stderr) return None return fufi if not self.has_conf('folders', in_what): print(f"emailer: not [folders][{in_what}] configured.", file=sys.stderr) what_fudi = self.conf['folders'][in_what] fufi = f"{what_fudi}/{target}.xslt.xml" if os.path.isfile(fufi): return fufi # # try empros what_fudi = self.conf['folders']['empros'] fufi = f"{what_fudi}/{target}.xslt.xml" if not os.path.isfile(fufi): print(f"emailer does not see {fufi}", file=sys.stderr) return None return fufi