License the email forwarder under GNU General Public License v3 to
ensure free software distribution and modification rights.
Changes:
- Add LICENSE file with full GPLv3 text
WorkingDirectory is required to set the cwd to the project dir for
relative paths like ./state. It was accidentally removed in a previous
edit.
Changes:
- Add WorkingDirectory= to [Service] section
OnFailure directive must be in [Unit], not [Service], for systemd
user services to recognize it.
Changes:
- Move OnFailure from [Service] to [Unit] in email_forwarder.service
Remove local exception handling for IMAP operations to ensure script
exits on any server failure (e.g., auth, connection, search errors).
This allows systemd OnFailure to notify on fixable issues.
Changes:
- Remove try-except in check_duplicate, sync_folder, sync_all_folders
- Let IMAP exceptions propagate to main() for exit(1)
Call ensure_folder_exists before check_duplicate to select the dest
folder, allowing IMAP SEARCH to work in SELECTED state.
Changes:
- Move dest.ensure_folder_exists(folder) before check_duplicate in process_email
- Add logging to check_duplicate for debugging
Ensure ./state resolves to project_dir/state by setting WorkingDirectory
to the absolute PROJECT_DIR path.
Changes:
- Add WorkingDirectory= to email_forwarder.service
Move processed_message_ids.txt and last_run.txt to STATE_DIR,
configurable via .env. Install script creates ./state by default.
Changes:
- Add STATE_DIR to .env.example and config loading
- Update EmailForwarder to use os.path.join for file paths
- Add os.makedirs for state dir creation
- Update README with STATE_DIR option
Change remaining .connect() and .disconnect() calls to private
._connect() and ._disconnect() after removing public methods.
Changes:
- Update EmailForwarder.sync_all_folders to use _connect/_disconnect
Wrap ExecStartPost in /bin/sh -c to enable variable expansion for
UPTIME_SUCCESS_URL. Add EnvironmentFile to load vars from .env.
Changes:
- Update ExecStartPost to use shell for expansion
- Add EnvironmentFile=/.env to service
- Update fail service ExecStart similarly
Eliminate drop-in dependency by having install.sh replace
with absolute paths in the service file. EnvironmentFile loads vars from
.env directly.
Changes:
- Remove email_forwarder.service.d/ directory
- Update install.sh to sed service file for absolute paths
- Simplify README to rely on install.sh
Convert email_forwarder.py to a package with __main__.py for module execution.
Update systemd service to use -m email_forwarder.
Configure pyproject.toml to exclude state/ from packaging.
Changes:
- Create email_forwarder/ package with __init__.py and __main__.py
- Move main script to email_forwarder/email_forwarder.py
- Update ExecStart to python -m email_forwarder
- Add setuptools config to exclude state/ directory
- Rename main.py to email_forwarder.py for better readability
- Update systemd service to use in ExecStart and EnvironmentFile,
remove WorkingDirectory to fix expansion issues
- Update install.sh and README references
- Drop-in sets PROJECT_DIR for runtime expansion
Changes:
- File rename: main.py -> email_forwarder.py
- Service: ExecStart and EnvironmentFile now use
- Docs: Updated to reflect new script name
Change default from INBOX to INBOX,Sent for better out-of-the-box
experience, as Sent is commonly forwarded alongside inbox.
Changes:
- Update FOLDERS in .env.example
- Update README to reflect new default
Since ENV_FILE is no longer replaced, remove the variable and its echo
to simplify the script.
Changes:
- Remove ENV_FILE definition
- Remove Env file echo in main
Correct STATE_DIR to project dir, remove unnecessary pip3 check and ENV_FILE
replacement for cleaner, accurate installation.
Changes:
- Set STATE_DIR to ./state in install.sh
- Remove pip3 dependency check (included in venv)
- Remove redundant ENV_FILE sed replacement
- Update .gitignore to ignore state/ directory
Replace duplicate strip() calls with filter(None, generator) for
cleaner and more efficient processing of processed Message-IDs.
Changes:
- Use set(filter(None, (line.strip() for line in f))) to avoid calling
strip() twice and filter empty lines
Make all attributes private (_host, _imap, etc.) and remove redundant
public connect/disconnect methods. Connection management is now handled
internally by the orchestrator calling private _connect/_disconnect.
Changes:
- Privatize ImapClient attributes and methods
- Update EmailForwarder to call private connection methods
- Enhance encapsulation without changing functionality
Introduce class-based architecture with inheritance for IMAP clients:
- ImapClient base class with private low-level methods
- SourceImap and DestImap subclasses for specific operations
- EmailForwarder orchestrator class for coordination
- Global load_config and main functions
Improvements:
- Clear separation of concerns and encapsulation
- Private methods for internal IMAP calls
- Better error handling and logging
- Maintains all original functionality
Add support for syncing multiple IMAP folders with auto-creation of missing
dest folders and configurable folder selection.
Changes:
- Update main.py to loop over folders, with auto-create for dest
- Add FOLDERS env var for all or specific folders
- Update .env.example and README for FOLDERS config
Provide automated installation for Linux users to set up venv and systemd
services with proper path configuration.
Changes:
- Add install.sh with dependency checks, venv setup, and systemd configuration
- Update README to highlight automated install option
Provide override.conf.sample as a template for customizing systemd
environment paths.
Changes:
- Rename override.conf to override.conf.sample with placeholders and comments
- Update README to instruct copying the sample
Remove PROCESSED_FILE references and update .env.example with placeholder
Uptime URLs for privacy.
Changes:
- Remove unused processed_file variable and loading in main.py
- Update .env.example to use generic Uptime URLs
- Remove processed_uids.txt from .gitignore
Add core IMAP forwarding logic with time-based searches and Message-ID
deduplication to prevent duplicates in destination mailbox.
Changes:
- Implement SINCE-based email search using last_run.txt for incremental forwarding
- Add Message-ID extraction and IMAP checks for deduplication
- Configure systemd user services with drop-in overrides for portability
- Integrate Uptime Kuma pings for monitoring
- Set up virtual environment for dependency isolation
- Update documentation and configuration templates