Rewrite from Python to Go for single-binary cross-platform builds
Replaces imapdown.py with a multi-file Go implementation using github.com/emersion/go-imap/v2. All features preserved: SSL/STARTTLS, incremental UID-based downloads, attachment extraction to zip, modified UTF-7 folder name decoding, and full-mode safety checks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,52 +1,78 @@
|
||||
# IMAP Downloader
|
||||
|
||||
A simple Python script to download all emails from an IMAP server into individual EML files, preserving the folder structure.
|
||||
Download all emails from an IMAP server into individual EML files, preserving the folder structure.
|
||||
|
||||
Single self-contained binary written in Go - fast, cross-platform, no dependencies.
|
||||
|
||||
## Quickstart
|
||||
|
||||
```bash
|
||||
# Build the binary
|
||||
make build
|
||||
|
||||
# Download all emails (creates a folder named after your email address)
|
||||
./imapdown -server imap.gmail.com -email you@gmail.com -user you@gmail.com -password "your-password" -ssl
|
||||
|
||||
# Subsequent runs only download new emails
|
||||
./imapdown -server imap.gmail.com -email you@gmail.com -user you@gmail.com -password "your-password" -ssl
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- Downloads emails as standard `.eml` files
|
||||
- Downloads emails as standard `.eml` files (open in any email client)
|
||||
- Preserves IMAP folder hierarchy locally
|
||||
- Extracts attachments into zip files alongside each email
|
||||
- Supports SSL and STARTTLS connections
|
||||
- Supports SSL/TLS and STARTTLS connections
|
||||
- Incremental updates using UID tracking (only download new emails)
|
||||
- Multi-account support (separate folders per email address)
|
||||
- Automatic state tracking - never re-downloads the same email
|
||||
- Configurable download limit for testing/debugging
|
||||
- Works with Gmail, Outlook, FastMail, and any IMAP server
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3.6+
|
||||
- No external dependencies (uses only standard library)
|
||||
- Go 1.21+ (for building from source)
|
||||
- OR use pre-compiled binaries (no requirements)
|
||||
|
||||
## Installation
|
||||
|
||||
Download from releases page (coming soon) or build from source:
|
||||
|
||||
```bash
|
||||
# Clone or download the script
|
||||
# Clone repository
|
||||
git clone <repo-url>
|
||||
cd imapdown
|
||||
|
||||
# Create virtual environment (optional but recommended)
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
# Build the binary
|
||||
make build
|
||||
|
||||
# Or cross-compile for all platforms
|
||||
make build-all
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage
|
||||
|
||||
By default, the script only downloads new emails since the last run (incremental mode). On first run, it downloads everything.
|
||||
By default, only new emails since the last run are downloaded (incremental mode). On first run, everything is downloaded.
|
||||
|
||||
```bash
|
||||
# Download emails using SSL (most common)
|
||||
./imapdown.py --server imap.example.com --email me@example.com --user me@example.com --password "secret" --ssl
|
||||
# Generic IMAP server with SSL (most common)
|
||||
./imapdown -server imap.example.com -email me@example.com -user me@example.com -password "secret" -ssl
|
||||
|
||||
# Using STARTTLS
|
||||
./imapdown.py --server imap.example.com --email me@example.com --user me@example.com --password "secret" --starttls
|
||||
# Gmail (requires app-specific password if 2FA enabled)
|
||||
./imapdown -server imap.gmail.com -email you@gmail.com -user you@gmail.com -password "app-password" -ssl
|
||||
|
||||
# Custom port
|
||||
./imapdown.py --server imap.example.com --email me@example.com --user me@example.com --password "secret" --ssl --port 12993
|
||||
# Outlook/Office 365
|
||||
./imapdown -server outlook.office365.com -email you@outlook.com -user you@outlook.com -password "password" -ssl
|
||||
|
||||
# Custom storage directory
|
||||
./imapdown.py --server imap.example.com --email me@example.com --user me@example.com --password "secret" --ssl --store /path/to/backup
|
||||
./imapdown -server imap.example.com -email me@example.com -user me@example.com -password "secret" -ssl -output /path/to/backup
|
||||
|
||||
# Using STARTTLS instead of SSL
|
||||
./imapdown -server imap.example.com -email me@example.com -user me@example.com -password "secret" -starttls
|
||||
|
||||
# Custom port
|
||||
./imapdown -server imap.example.com -email me@example.com -user me@example.com -password "secret" -ssl -port 12993
|
||||
```
|
||||
|
||||
### Full Download
|
||||
@@ -54,14 +80,13 @@ By default, the script only downloads new emails since the last run (incremental
|
||||
To force a complete download of all emails (ignoring previous state):
|
||||
|
||||
```bash
|
||||
./imapdown.py --server imap.example.com --email me@example.com --user me@example.com --password "secret" --ssl --full
|
||||
./imapdown -server imap.example.com -email me@example.com -user me@example.com -password "secret" -ssl -full
|
||||
```
|
||||
|
||||
**Note:** As a safety measure, `--full` will refuse to run if the download folder already contains emails. This prevents accidental duplicates. To re-download everything, first delete the folder:
|
||||
**Note:** As a safety measure, `-full` will refuse to run if the download folder already contains emails. This prevents accidental duplicates. To re-download everything, first delete the folder:
|
||||
|
||||
```bash
|
||||
rm -rf download/me@example.com/
|
||||
./imapdown.py --server imap.example.com --email me@example.com --user me@example.com --password "secret" --ssl --full
|
||||
rm -rf me@example.com/
|
||||
```
|
||||
|
||||
### Debugging/Testing
|
||||
@@ -69,44 +94,55 @@ rm -rf download/me@example.com/
|
||||
Limit the number of emails downloaded:
|
||||
|
||||
```bash
|
||||
./imapdown.py --server imap.example.com --email me@example.com --user me@example.com --password "secret" --ssl --limit 10
|
||||
./imapdown -server imap.example.com -email me@example.com -user me@example.com -password "secret" -ssl -limit 10
|
||||
```
|
||||
|
||||
## Command Line Arguments
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `--server` | Yes | IMAP server hostname |
|
||||
| `--email` | Yes | Email address (used for folder organization) |
|
||||
| `--user` | Yes | Username for authentication |
|
||||
| `--password` | Yes | Password for authentication |
|
||||
| `--ssl` | No | Use implicit SSL/TLS (default port 993) |
|
||||
| `--starttls` | No | Use STARTTLS (default port 143) |
|
||||
| `--port` | No | Custom port (overrides defaults) |
|
||||
| `--limit` | No | Maximum number of emails to download |
|
||||
| `--full` | No | Download all emails (default: only new since last run) |
|
||||
| `--store` | No | Directory to store downloaded emails (default: ./download) |
|
||||
| Argument | Flag | Required | Description |
|
||||
|----------|------|----------|-------------|
|
||||
| Server | `-server` | Yes | IMAP server hostname |
|
||||
| Email | `-email` | Yes | Email address (used for folder organization) |
|
||||
| User | `-user` | Yes | Username for authentication |
|
||||
| Password | `-password` | Yes | Password for authentication |
|
||||
| SSL | `-ssl` | No | Use implicit SSL/TLS (default port 993) |
|
||||
| STARTTLS | `-starttls` | No | Use STARTTLS (default port 143) |
|
||||
| Port | `-port` | No | Custom port (overrides defaults) |
|
||||
| Limit | `-limit` | No | Maximum number of emails to download |
|
||||
| Full | `-full` | No | Download all emails (default: only new since last run) |
|
||||
| Output | `-output` | No | Directory to store downloaded emails (default: ./{email}) |
|
||||
|
||||
Note: `--ssl` and `--starttls` are mutually exclusive.
|
||||
**Notes:**
|
||||
- `-ssl` and `-starttls` are mutually exclusive
|
||||
|
||||
## Output Structure
|
||||
|
||||
The default output structure (when `--store` is not specified):
|
||||
|
||||
**Without `-output` flag** (default: `./{email_address}/`):
|
||||
```
|
||||
./download/
|
||||
├── user@example.com/
|
||||
│ ├── .imapdown_state.json # Tracks last downloaded UID per folder
|
||||
│ ├── INBOX/
|
||||
│ │ ├── 123_20240115_Meeting_notes.eml
|
||||
│ │ ├── 124_20240116_Report.eml
|
||||
│ │ └── 124_20240116_Report.zip # Attachments (if any)
|
||||
│ ├── Sent/
|
||||
│ │ └── 456_20240114_RE_Question.eml
|
||||
│ └── Archive/
|
||||
│ └── 789_20240101_Old_email.eml
|
||||
└── another@example.com/
|
||||
└── ...
|
||||
./user@example.com/
|
||||
├── .imapdown_state.json # Tracks last downloaded UID per folder
|
||||
├── INBOX/
|
||||
│ ├── 123_20240115_Meeting_notes.eml
|
||||
│ ├── 124_20240116_Report.eml
|
||||
│ └── 124_20240116_Report.zip # Attachments (if any)
|
||||
├── Sent/
|
||||
│ └── 456_20240114_RE_Question.eml
|
||||
└── Archive/
|
||||
└── 789_20240101_Old_email.eml
|
||||
```
|
||||
|
||||
**With `-output /path/to/backup`** (emails go directly into specified directory):
|
||||
```
|
||||
/path/to/backup/
|
||||
├── .imapdown_state.json
|
||||
├── INBOX/
|
||||
│ ├── 123_20240115_Meeting_notes.eml
|
||||
│ ├── 124_20240116_Report.eml
|
||||
│ └── 124_20240116_Report.zip
|
||||
├── Sent/
|
||||
│ └── 456_20240114_RE_Question.eml
|
||||
└── Archive/
|
||||
└── 789_20240101_Old_email.eml
|
||||
```
|
||||
|
||||
### File Naming
|
||||
@@ -123,7 +159,7 @@ When an email contains attachments, they are extracted and saved in a zip file w
|
||||
|
||||
## State Tracking
|
||||
|
||||
The script maintains a `.imapdown_state.json` file in each email account's folder. This file tracks the highest downloaded UID for each IMAP folder, enabling efficient incremental updates with `--update`.
|
||||
A `.imapdown_state.json` file is maintained in the download folder. This file tracks the highest downloaded UID for each IMAP folder, enabling efficient incremental updates.
|
||||
|
||||
Example state file:
|
||||
```json
|
||||
@@ -134,6 +170,61 @@ Example state file:
|
||||
}
|
||||
```
|
||||
|
||||
## Building from Source
|
||||
|
||||
```bash
|
||||
# Build for current platform
|
||||
make build
|
||||
|
||||
# Cross-compile for all platforms
|
||||
make build-all
|
||||
# Produces: imapdown-linux-amd64, imapdown-linux-arm64,
|
||||
# imapdown-darwin-amd64, imapdown-darwin-arm64,
|
||||
# imapdown-windows-amd64.exe
|
||||
|
||||
# Install to $GOPATH/bin
|
||||
make install
|
||||
|
||||
# Clean build artifacts
|
||||
make clean
|
||||
|
||||
# Or use Go directly
|
||||
go build -ldflags="-s -w" -o imapdown
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Gmail Authentication
|
||||
|
||||
Gmail requires an app-specific password if you have 2-factor authentication enabled:
|
||||
1. Go to Google Account Settings → Security → 2-Step Verification → App passwords
|
||||
2. Generate a new app password for "Mail"
|
||||
3. Use this password instead of your regular password
|
||||
|
||||
### Connection Issues
|
||||
|
||||
- **SSL errors**: Make sure you're using the correct port (993 for SSL, 143 for STARTTLS)
|
||||
- **Authentication failed**: Verify username and password are correct
|
||||
- **Timeout**: Some servers require STARTTLS instead of SSL - try `-starttls` flag
|
||||
|
||||
### First Run Not Downloading
|
||||
|
||||
If the first run doesn't download anything:
|
||||
1. Check the folder actually contains emails on the server
|
||||
2. Try with `-limit 10` to test with a small batch first
|
||||
3. Verify your credentials work by logging into webmail
|
||||
|
||||
### Re-downloading Everything
|
||||
|
||||
To start fresh and re-download all emails:
|
||||
```bash
|
||||
# Delete the email folder (and state file)
|
||||
rm -rf ./your-email@example.com/
|
||||
|
||||
# Run with -full flag
|
||||
./imapdown -server imap.example.com -email your-email@example.com -user your-email@example.com -password "password" -ssl -full
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
Reference in New Issue
Block a user