Implement configurable STATE_DIR for state files
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
This commit is contained in:
parent
4adce1079f
commit
a32f79980e
3 changed files with 13 additions and 10 deletions
|
|
@ -7,6 +7,7 @@ DEST_PORT=993
|
|||
DEST_USER=your@mxroute.com
|
||||
DEST_PASS=password
|
||||
FOLDERS=INBOX,Sent
|
||||
STATE_DIR=./state
|
||||
DRY_RUN=false
|
||||
UPTIME_SUCCESS_URL=https://your-uptime-instance.com/api/push/your-token?status=up&msg=OK&ping=
|
||||
UPTIME_FAIL_URL=https://your-uptime-instance.com/api/push/your-token?status=down&msg=Failed
|
||||
|
|
@ -19,6 +19,7 @@ This will set up the virtual environment, systemd services, and provide post-ins
|
|||
- `DEST_USER`: Destination email/username
|
||||
- `DEST_PASS`: Destination password
|
||||
- `FOLDERS`: Folders to sync (default "INBOX,Sent"; use "all" for all folders or comma-separated list)
|
||||
- `STATE_DIR`: Directory for state files (default "./state")
|
||||
- `DRY_RUN`: Set to `true` for testing without forwarding (default false)
|
||||
- `UPTIME_SUCCESS_URL`: URL for success ping
|
||||
- `UPTIME_FAIL_URL`: URL for failure ping
|
||||
|
|
|
|||
|
|
@ -126,6 +126,10 @@ class EmailForwarder:
|
|||
|
||||
def __init__(self, config: dict):
|
||||
self.config = config
|
||||
self.state_dir = config["state_dir"]
|
||||
os.makedirs(self.state_dir, exist_ok=True)
|
||||
self.processed_file = os.path.join(self.state_dir, "processed_message_ids.txt")
|
||||
self.last_run_file = os.path.join(self.state_dir, "last_run.txt")
|
||||
self.source = SourceImap(
|
||||
config["source_host"],
|
||||
config["source_port"],
|
||||
|
|
@ -144,23 +148,21 @@ class EmailForwarder:
|
|||
|
||||
def load_state(self):
|
||||
"""Load last run and processed IDs."""
|
||||
last_run_file = self.config["last_run_file"]
|
||||
if os.path.exists(last_run_file):
|
||||
with open(last_run_file) as f:
|
||||
if os.path.exists(self.last_run_file):
|
||||
with open(self.last_run_file) as f:
|
||||
last_run_str = f.read().strip()
|
||||
self.last_run = datetime.fromisoformat(last_run_str)
|
||||
else:
|
||||
self.last_run = datetime.now(timezone.utc)
|
||||
|
||||
processed_file = self.config["processed_file"]
|
||||
if os.path.exists(processed_file):
|
||||
with open(processed_file, "r") as f:
|
||||
if os.path.exists(self.processed_file):
|
||||
with open(self.processed_file, "r") as f:
|
||||
self.processed_ids = set(filter(None, (line.strip() for line in f)))
|
||||
|
||||
def save_state(self):
|
||||
"""Save last run and processed IDs."""
|
||||
if not self.dry_run:
|
||||
with open(self.config["last_run_file"], "w") as f:
|
||||
with open(self.last_run_file, "w") as f:
|
||||
f.write(datetime.now(timezone.utc).isoformat())
|
||||
|
||||
def sync_all_folders(self):
|
||||
|
|
@ -209,7 +211,7 @@ class EmailForwarder:
|
|||
if not self.dry_run:
|
||||
self.dest.append_email(folder, raw_msg)
|
||||
self.processed_ids.add(msg_id)
|
||||
with open(self.config["processed_file"], "a") as f:
|
||||
with open(self.processed_file, "a") as f:
|
||||
f.write(msg_id + "\n")
|
||||
forwarded += 1
|
||||
logging.info(f"Forwarded {msg_id} from {folder}")
|
||||
|
|
@ -239,8 +241,7 @@ def load_config():
|
|||
"dest_user": os.getenv("DEST_USER"),
|
||||
"dest_pass": os.getenv("DEST_PASS"),
|
||||
"folders": os.getenv("FOLDERS", "INBOX"),
|
||||
"processed_file": "processed_message_ids.txt",
|
||||
"last_run_file": "last_run.txt",
|
||||
"state_dir": os.getenv("STATE_DIR", "./state"),
|
||||
"dry_run": os.getenv("DRY_RUN", "false").lower() == "true",
|
||||
}
|
||||
# Validate required
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue