about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--README.md10
-rw-r--r--pyproject.toml4
-rw-r--r--src/formbox.py25
3 files changed, 26 insertions, 13 deletions
diff --git a/README.md b/README.md
index 00b8858..4984b78 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # formbox
 
-This tiny script formats an [mbox] as HTML or XML.  It is intended
-for rendering email replies on websites and their [RSS] feed.
+This tiny script formats an [mbox] file or a [maildir] as HTML or XML.
+It is intended for rendering email replies on web sites and their [RSS] feed.
 
 ## Prerequisites
 
@@ -18,12 +18,12 @@ such as [nixpkgs].
 
 ```console
 $ formbox --help
-usage: formbox [-h] mbox id template
+usage: formbox [-h] mailbox id template
 
-format mbox as HTML/XML
+format mailbox as HTML/XML
 
 positional arguments:
-  mbox        path to mbox file
+  mailbox     path to mbox file of maildir
   id          root message ID
   template    path to template
 
diff --git a/pyproject.toml b/pyproject.toml
index eb08fab..f009a16 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"
 
 [project]
 name = "formbox"
-version = "0.4.3"
+version = "1.0.0"
 description = "Format mbox as HTML/XML"
 readme = "README.md"
 requires-python = ">=3.6"
@@ -13,7 +13,7 @@ authors = [ { name = "Nguyễn Gia Phong", email = "cnx@loang.net" } ]
 maintainers = [ { name = "Nguyễn Gia Phong", email = "cnx@loang.net" } ]
 keywords = [ "email", "format", "html", "mbox", "template", "xml" ]
 classifiers = [
-    "Development Status :: 4 - Beta",
+    "Development Status :: 5 - Production/Stable",
     "Environment :: Console",
     "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
     "Operating System :: OS Independent",
diff --git a/src/formbox.py b/src/formbox.py
index b9da5a1..a1e3a58 100644
--- a/src/formbox.py
+++ b/src/formbox.py
@@ -1,5 +1,5 @@
-# Format mbox as HTML/XML
-# Copyright (C) 2021-2023  Nguyễn Gia Phong
+# Format mailbox as HTML/XML
+# Copyright (C) 2021-2024  Nguyễn Gia Phong
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published
@@ -19,7 +19,7 @@ from collections import defaultdict
 from email.header import decode_header
 from email.utils import parsedate_to_datetime
 from functools import partial
-from mailbox import mbox
+from mailbox import Maildir, mbox
 from pathlib import Path
 from urllib.parse import quote, unquote, urlencode
 
@@ -33,6 +33,17 @@ sanitise = partial(clean, tags={'a', 'code', 'em', 'strong', 'sub', 'sup',
                                 'irc', 'ircs', 'mailto', 'matrix', 'xmpp'})
 
 
+def mailbox(path):
+    """Parse and return the mailbox at given path.
+
+    Supported formats are Maildir and mbox.
+    """
+    try:
+        return mbox(path, create=False)
+    except IsADirectoryError:
+        return Maildir(path, create=False)
+
+
 def get_body(message):
     """Return the Markdown message body converted to HTML."""
     if message.is_multipart():
@@ -86,14 +97,16 @@ def render(template, archive, parent):
 
 def main():
     """Parse command-line arguments and pass them to routines."""
-    parser = ArgumentParser(description='format mbox as HTML/XML')
-    parser.add_argument('mbox', type=mbox, help='path to mbox file')
+    parser = ArgumentParser(description='format mailbox as HTML/XML')
+    parser.add_argument('mailbox', type=mailbox,
+                        help='path to mbox file or maildir')
     parser.add_argument('id', type=unquote, help='root message ID')
     parser.add_argument('template', type=Path, help='path to template')
     args = parser.parse_args()
 
     archive = defaultdict(list)
-    for message in args.mbox: archive[message['In-Reply-To']].append(message)
+    for message in args.mailbox:
+        archive[message['In-Reply-To']].append(message)
     template = args.template.read_text()
     print(*render(template, archive, args.id), sep='', end='')