mailer.py 3.26 KB
import os
import sys
import json
from logging import getLogger
from argparse import ArgumentParser
from configparser import ConfigParser
import smtplib
from base64 import b64decode
from opensipkd.string import exception_message
from .tools import (
    make_pid_file,
    clean_log,
    create_doc,
    )
from .logger import setup_logging


registry = dict()


def send(doc=None):
    conf = registry['conf']
    log = getLogger('send')
    try:
        with smtplib.SMTP(conf['host'], conf['port']) as server:
            if conf['tls']:
                server.starttls()
            err = None
            log.debug(f'Login sebagai {conf["username"]}')
            try:
                server.login(conf['username'], conf['password'])
            except OSError as err:
                return dict(status=-1, jawaban=str(err).strip())
            except smtplib.SMTPAuthenticationError as err:
                return dict(status=-2, jawaban=str(err).strip())
            if doc:
                log.info(f'KIRIM {clean_log(doc._data)}')
                server.sendmail(
                    conf['username'], doc._data['penerima'], doc.as_string())
    except ConnectionRefusedError as err:
        return dict(status=-1, jawaban=str(err).strip())
    return dict(status=0, jawaban='OK')


def job_file_to_doc(filename):
    log = getLogger('job_file_to_doc')
    with open(filename) as f:
        s = f.read()
    os.remove(filename)
    try:
        d = json.loads(s)
    except Exception:
        log.error(f'eval({s}): {exception_message()}')
        return
    cf = registry['conf']
    files = []
    for fname, content in d.get('files', []):
        data = base64.b64decode(content)
        files.append([fname, data])
    doc = create_doc(
            cf['username'], d['penerima'], d.get('subject'), d['pesan'],
            cf['name'], d.get('name'), files)
    # Hack
    doc._data = d
    return doc


def save_result(d, filename):
    result_dir = registry['conf']['result_dir']
    fullpath = os.path.join(result_dir, filename)
    with open(fullpath, 'w') as f:
        f.write(json.dumps(d))


def do_job():
    job_dir = registry['conf']['job_dir']
    job_files = os.listdir(job_dir)
    if not job_files:
        return
    job_files.sort()
    job_file = os.path.join(job_dir, job_files[0])
    doc = job_file_to_doc(job_file)
    if not doc:
        return
    log = getLogger('do_job')
    result_file = os.path.split(job_file)[-1]
    result = send(doc)
    if result['status'] == 0:
        log.info(result)
    else:
        log.error(result)
    save_result(result, result_file)


def get_option(argv):
    pars = ArgumentParser()
    pars.add_argument('conf')
    return pars.parse_args(argv)


def main(argv=sys.argv[1:]):
    option = get_option(argv)
    conf = ConfigParser()
    conf.read(option.conf)
    registry['conf'] = cf = dict(conf.items('main'))
    if not make_pid_file(cf['pid_file']):
        return
    setup_logging(option.conf)
    log = getLogger()
    cf['tls'] = cf['tls'] == 'true'
    cf['port'] = int(cf['port'])
    # result = send()
    # save_result(result, 'status.json')
    try:
        do_job()
    except Exception as err:
        d = dict(status=-9, jawaban=exception_message())
        save_result(d, 'status.json')
        log.error(d['jawaban'])
    os.remove(cf['pid_file'])