diff options
Diffstat (limited to 'main.py')
-rw-r--r-- | main.py | 110 |
1 files changed, 3 insertions, 107 deletions
@@ -1,47 +1,21 @@ -import subprocess -import email -import email.message from email.message import EmailMessage from email.headerregistry import Address -from subprocess import PIPE -import html -from email.parser import BytesParser -import email.policy from urllib.parse import urlparse, urlencode, parse_qs from http.cookies import BaseCookie import http.cookies import password from password import Passwords from uuid import uuid4 -import xml.dom.minidom -import xml.dom import os from typing import ( - TypeAlias, - Union, - Callable, Optional, cast, ) +from mu import mu_search, get_mail +from html_render import HTML, render_document from http.server import HTTPServer, BaseHTTPRequestHandler -HTML: TypeAlias = Union[tuple, list, Callable[[], str], None, - str, int, float] - -parser = BytesParser(policy=email.policy.default) - - -def get_mail(id: str) -> email.message.Message: - cmd = subprocess.run(['mu', 'find', '-u', f'i:{id}', - '--fields', 'l'], - stdout=PIPE) - filename = cmd.stdout.decode('UTF-8').strip() - - with open(filename, "rb") as f: - mail = parser.parse(f) - return mail - def mailto(addr: str) -> HTML: return ('a', {'href': f'mailto:{addr}'}, addr) @@ -66,40 +40,6 @@ def header_format(key: str, value) -> HTML: return value -standalones = ['hr', 'br', 'meta'] - - -def _render_document(document: HTML) -> str: - if type(document) == tuple: - tag, *body = document - if body and type(body[0]) == dict: - print(body[0]) - attributes = ' '.join(f'{a}="{html.escape(b)}"' - for a, b in body[0].items()) - body = body[1:] - start = f'<{tag} {attributes}>' - else: - start = f'<{tag}>' - if tag in standalones: - return start - else: - items = ''.join(_render_document(b) for b in body) - return start + f'{items}</{tag}>' - elif callable(document): - return str(document()) - elif type(document) == list: - return ''.join(_render_document(e) for e in document) - elif document is None: - return '' - else: - # strings, and everything else - return html.escape(str(document)) - - -def render_document(document: HTML) -> str: - return '<!doctype html>\n' + _render_document(document) - - style: HTML = lambda: """ nav { display: block; @@ -242,51 +182,6 @@ def search_field(q: str) -> HTML: ('input', {'type': 'Submit'})) -class MuError(Exception): - codes = { - 1: 'General Error', - 2: 'No Matches', - 4: 'Database is corrupted' - } - - def __init__(self, returncode: int): - self.returncode: int = returncode - self.msg: str = MuError.codes.get(returncode, 'Unknown Error') - - def __repr__(self): - return f'MuError({self.returncode}, "{self.msg}")' - - -def mu_search(query, sortfield='subject', reverse=False): - if not query: - raise ValueError('Query required for mu_search') - cmdline = ['mu', 'find', - '--format=xml', - query, - '--sortfield', sortfield] - if reverse: - cmdline.append('--reverse') - cmd = subprocess.Popen(cmdline, stdout=subprocess.PIPE) - dom = xml.dom.minidom.parse(cmd.stdout) - if returncode := cmd.wait(): - raise MuError(returncode) - - message_list = [] - messages = dom.childNodes[0] - assert messages.localName == 'messages' - for message in messages.childNodes: - msg_dict = {} - if message.nodeType != xml.dom.Node.ELEMENT_NODE: - continue - for kv in message.childNodes: - if kv.nodeType != xml.dom.Node.ELEMENT_NODE: - continue - msg_dict[kv.localName] = kv.childNodes[0].data - message_list.append(msg_dict) - - return message_list - - def search_result(q, by, reverse): keys = ['From', 'To', 'Subject', 'Date', 'Size', 'Maildir', 'Msgid'] @@ -457,6 +352,7 @@ class Handler(BaseHTTPRequestHandler): self.send_header('location', '/') else: self.send_response(302) + self.send_header('location', '/') self.end_headers() |