diff options
author | Jannis M. Hoffmann <jannis@fehcom.de> | 2024-03-16 13:51:44 +0100 |
---|---|---|
committer | Jannis M. Hoffmann <jannis@fehcom.de> | 2024-03-16 13:51:44 +0100 |
commit | ebff40e10ea7fefd9a84e8709a14048ef288d80a (patch) | |
tree | 51979ecac3d8e00a17b8529fd43d35314e9ef7f5 | |
parent | 59af8165dd3b4fe2453ae4e88a57d0711db5b373 (diff) |
add MaildirMessage properties in list_mails
-rwxr-xr-x | script/extract.py | 102 |
1 files changed, 67 insertions, 35 deletions
diff --git a/script/extract.py b/script/extract.py index 9cd810b..3ab3b53 100755 --- a/script/extract.py +++ b/script/extract.py @@ -44,28 +44,64 @@ import jwebmail.model.jwebmail_pb2 as jwebmail class MyMaildir(Maildir): def __init__(self, dirname, *args, **kwargs): - self.__path = dirname + self.__path = Path(dirname) + self.set_msgtype("MaildirMessage") + super().__init__(dirname, *args, **kwargs) + def set_msgtype(self, typ): + if typ == "MaildirMessage": + self._factory = None + elif typ == "EmailMessage": + self._factory = lambda mail_file: email.parser.BytesParser( + policy=email.policy.default + ).parse(mail_file) + elif typ == "Maildir(EmailMessageHeader)": + + def factory(mail_file): + """ + Copy from implementation. + """ + name = Path(mail_file._file.name).name + msg = MaildirMessage( + email.parser.BytesHeaderParser(policy=email.policy.default).parse( + mail_file + ) + ) + if self.colon in name: + msg.set_info(name.split(self.colon)[-1]) + return msg + + self._factory = factory + + elif typ == "None": + self._factory = lambda _file: MaildirMessage(None) + else: + raise ValueError(typ) + def get_filename(self, mid): - p_cur = glob(path.join(self.__path, "cur", mid + "*")) - p_new = glob(path.join(self.__path, "new", mid + "*")) - res = p_cur + p_new - if len(res) != 1: - raise LookupError( - f"could not uniquely identify file for mail-id {mid!r}", mid - ) - return res[0] + return self.__path / self._lookup(mid) def get_folder(self, folder): - # copy from internal implementation - return MyMaildir( + """ + This is an internal copy of the implementation of Maildir. + + This is because Maildir was not designed with inheritance in mind + and this method does hence not return an instance of itself but + rather only and instance of Maildir. + + This override corrects this but can not anticipate additional state + introduced in more derived classes. + """ + return type(self)( path.join(self._path, "." + folder), - factory=self._factory, create=False, ) def _refresh(self): + """ + This override of internal method _refresh that strips out 'hidden' files. + """ super()._refresh() rm = [r for r in self._toc if r.startswith(".")] for r in rm: @@ -92,7 +128,7 @@ def _adr(addrs): def _get_rcv_time(mid): idx = mid.find(".") - assert idx >= 0 + assert idx > 0 return float(mid[:idx]) @@ -109,25 +145,7 @@ def startup(maildir, su, user, mode): logging.exception("error setting uid") sysexit(5) - def create_messages(mail_file): - if mode == "count": - msg = MaildirMessage(None) - elif mode == "list": - msg = MaildirMessage( - email.parser.BytesHeaderParser(policy=email.policy.default).parse( - mail_file - ) - ) - else: - msg = email.parser.BytesParser(policy=email.policy.default).parse(mail_file) - - return msg - - return MyMaildir( - maildir / user, - create=False, - factory=create_messages, - ) + return MyMaildir(maildir / user, create=False) def _sort_by_sender(midmsg): @@ -221,6 +239,8 @@ def list_mails(f, req): if r.folder: f = f.get_folder(r.folder) + f.set_msgtype("Maildir(EmailMessageHeader)") + if r.start == r.end: return [] @@ -233,7 +253,7 @@ def list_mails(f, req): jwebmail.ListMailHeader( mid=mid, byte_size=path.getsize(f.get_filename(mid)), - unread="S" in msg.get_flags(), + unread="S" not in msg.get_flags(), rec_date=datetime.fromtimestamp(_get_rcv_time(mid)).isoformat(), header=_get_head_info(msg), ) @@ -248,6 +268,8 @@ def count_mails(f, req): if r.folder: f = f.get_folder(r.folder) + f.set_msgtype("None") + resp = jwebmail.StatsResp( mail_count=len(f), unread_count=len([1 for m in f if "S" in m.get_flags()]), @@ -310,11 +332,15 @@ def read_mail(f, req): if r.folder: f = f.get_folder(r.folder) + f.set_msgtype("EmailMessage") + msg = f.get(r.mid, None) if not msg: raise QMAuthError("no such message", mid=r.mid) - msg.add_flag('S') + f.set_msgtype("MaildirMessage") + + f[r.mid].add_flag("S") res = jwebmail.Mail( head=_get_head_info(msg), @@ -341,6 +367,8 @@ def raw_mail(f, req): if r.folder: f = f.get_folder(r.folder) + f.set_msgtype("EmailMessage") + msg = f.get(r.mid, None) if not msg: raise QMAuthError("no such message", mid=r.mid) @@ -392,6 +420,8 @@ def search_mails(f, req): if r.folder: f = f.get_folder(r.folder) + f.set_msgtype("EmailMessage") + res = [ jwebmail.ListMailHeader( header=_get_head_info(msg), @@ -438,6 +468,8 @@ def remove_mail(f, req): if r.folder: f = f.get_folder(r.folder) + f.set_msgtype("MaildirMessage") + f[r.mid].add_flag("T") return jwebmail.RemoveResp().SerializeToString() @@ -499,7 +531,7 @@ def main(): reply = run(s, val) logging.debug("pb method(%s) size(%d)", args["method"], len(reply)) stdout.buffer.write(reply) - #except QMAuthError as qerr: + # except QMAuthError as qerr: # errmsg = dict(error=qerr.msg, **qerr.info) # sysexit(3) except Exception: |