Export mailboxes (e.g. Cyrus IMAP) to organized Markdown files with decoded attachments and metadata. Perfect to archive your emails into a file structure for long time storage. Enables you to cleanup your mail server.
- π Markdown Conversion: Converts emails to readable Markdown format with proper formatting
- π Attachment Handling: Extracts and saves all attachments with proper decoding (base64, quoted-printable)
- ποΈ Organized Structure: Creates logical folder structures preserving email organization
- π Metadata Preservation: Saves complete email headers and metadata as JSON
- π Date Filtering: Export only emails older than a specific date
- π Smart Folder Discovery: Automatically finds matching folders in Cyrus IMAP structure
- π·οΈ HTML & Plaintext Support: Handles both HTML and plaintext email content
- π Robust Error Handling: Gracefully handles corrupted or malformed emails
- Python 3.7+
- mailparser library for email parsing
- dateutil library for date parsing
- pathlib (included in Python 3.4+)
-
Clone the repository:
git clone https://github.com/ogmueller/email-exporter.git cd email-exporter -
Install dependencies:
pip install mailparser python-dateutil
or use your Linux distributions' packages if exist
# example for debian based Linux apt install python3-dateutil
python email-exporter.py <maildir_root> <folder_path> <output_directory>maildir_root: Path to the Cyrus mail root directory (e.g.,/var/spool/cyrus/mail)folder_path: Logical mail folder path (e.g.,/shop/customeror justshop)output_directory: Path where the exported files will be saved--older-than: (Optional) Only export emails older than specified date
python email-exporter.py /var/spool/cyrus/mail /shop/customer ./my-archivepython email-exporter.py /var/spool/cyrus/mail /user/john ./john-backuppython email-exporter.py /var/spool/cyrus/mail /user/jane ./jane-archive --older-than 2023-01-01python email-exporter.py /var/spool/cyrus/mail shop ./shop-archiveThe tool creates a well-organized directory structure for your exported emails:
output-directory/
βββ shop/
β βββ customer/
β βββ 2023-10-15T14:30:00_Important_Meeting_a1b2c3d4/
β β βββ message.md # Plaintext email content
β β βββ html.md # HTML email content (if available)
β β βββ metadata.json # Complete email metadata
β β βββ attachment1.pdf # Decoded attachment
β β βββ attachment2.jpg # Decoded attachment
β βββ 2023-10-16T09:15:00_Project_Update_e5f6g7h8/
β βββ message.md
β βββ metadata.json
β βββ report.xlsx
message.md: Contains the email content in Markdown format with headershtml.md: HTML version of the email (when available)metadata.json: Complete email metadata including headers, recipients, dates, attachment info- Attachment files: All email attachments decoded and saved with original filenames
# Important Project Meeting
> **From:** John Doe <[email protected]>
> **To:** Jane Smith <[email protected]>
> **Date:** 2023-10-15T14:30:00+00:00
> **Message ID:** <[email protected]>
Hi Jane,
I wanted to follow up on our project discussion. Please review the attached documents before our meeting tomorrow.
Best regards,
John
---
## Attachments:
- `project-proposal.pdf`
- `budget-overview.xlsx`json
{
"source_file": "/var/spool/cyrus/mail/c/shop/customer/1234",
"subject": "Important Project Meeting",
"from": ["John Doe <[email protected]>"],
"to": ["Jane Smith <[email protected]>"],
"cc": [],
"date": "2023-10-15T14:30:00+00:00",
"message_id": "<[email protected]>",
"has_html": true,
"has_plaintext": true,
"attachment_count": 2,
"attachments": [
{
"filename": "project-proposal.pdf",
"content_type": "application/pdf",
"size": 245760,
"is_inline": false
}
]
}
The tool automatically handles Cyrus IMAP's hashing scheme where folders are organized by the first letter of the folder name:
- Logical path:
/shop/customerβ Filesystem:/c/shop/customer/ - Logical path:
/user/johnβ Filesystem:/j/user/john/
Use various date formats with the --older-than option:
bash
# Different supported date formats
--older-than 2023-01-01
--older-than "2023-01-01 15:30:00"
--older-than 2023/01/01
--older-than 01.01.2023
The folder search supports pattern matching:
shop- Finds all folders containing "shop"/specific/path- Exact path matchingcustomer- Finds all folders named "customer" across all hash directories
- "No folders found": Check that the maildir root path is correct and accessible
- Permission errors: Ensure you have read access to the Cyrus mail directories
- Attachment decoding errors: The tool handles most encoding issues gracefully and creates error files for problematic attachments
The tool provides detailed output during execution:
π₯ Cyrus mail root: /var/spool/cyrus/mail
π Looking for folder pattern: shop/customer
π Found 1 matching folder(s):
- /var/spool/cyrus/mail/c/shop/customer -> /shop/customer
π€ Writing archive to: ./output
π Processing folder: /var/spool/cyrus/mail/c/shop/customer
βοΈ Processed: /var/spool/cyrus/mail/c/shop/customer/1234
π Processing attachment: report.pdf
π β
Saved attachment: report.pdf (245760 bytes)
π Export complete!
π Total: 15 emails processed, 3 emails skipped
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
This project is licensed under the MIT License - see the LICENSE file for details.
Oliver G. Mueller
- GitHub: @ogmueller
- Repository: https://github.com/ogmueller/email-exporter
- Built with mailparser for robust email parsing
- Uses python-dateutil for flexible date handling