70 lines
2.7 KiB
Python
70 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
from time import sleep
|
|
|
|
from app.db.bootstrap import create_all_tables
|
|
from app.db.models import CampaignJob, JobImapStatus, JobSendStatus
|
|
from app.db.session import SessionLocal
|
|
from app.mailer.sending.jobs import append_sent_for_job
|
|
from app.security.api_keys import authenticate_api_key
|
|
from app.settings import settings
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(description="Append sent campaign messages to the configured IMAP Sent folder.")
|
|
parser.add_argument("--campaign-id", required=True, help="Database campaign UUID")
|
|
parser.add_argument("--api-key", default=settings.dev_bootstrap_api_key)
|
|
parser.add_argument("--limit", type=int, default=0, help="Maximum jobs to process; 0 means all pending/failed IMAP appends")
|
|
parser.add_argument("--dry-run", action="store_true")
|
|
parser.add_argument("--include-failed", action="store_true", help="Also retry jobs with imap_status=failed")
|
|
parser.add_argument("--json", action="store_true")
|
|
args = parser.parse_args()
|
|
|
|
create_all_tables()
|
|
results = []
|
|
with SessionLocal() as session:
|
|
api_key = authenticate_api_key(session, args.api_key)
|
|
if not api_key:
|
|
raise SystemExit("Invalid API key")
|
|
|
|
statuses = [JobImapStatus.PENDING.value]
|
|
if args.include_failed:
|
|
statuses.append(JobImapStatus.FAILED.value)
|
|
|
|
query = (
|
|
session.query(CampaignJob)
|
|
.filter(
|
|
CampaignJob.tenant_id == api_key.tenant_id,
|
|
CampaignJob.campaign_id == args.campaign_id,
|
|
CampaignJob.send_status == JobSendStatus.SENT.value,
|
|
CampaignJob.imap_status.in_(statuses),
|
|
)
|
|
.order_by(CampaignJob.entry_index.asc())
|
|
)
|
|
if args.limit > 0:
|
|
query = query.limit(args.limit)
|
|
|
|
jobs = query.all()
|
|
for job in jobs:
|
|
try:
|
|
result = append_sent_for_job(session, job_id=job.id, dry_run=args.dry_run)
|
|
results.append(result.as_dict())
|
|
if not args.json:
|
|
print(f"{job.entry_index}: {result.status} ({job.recipient_email}) folder={result.folder or '-'}")
|
|
except Exception as exc:
|
|
results.append({"job_id": job.id, "status": "error", "error": str(exc)})
|
|
if not args.json:
|
|
print(f"{job.entry_index}: ERROR {exc} ({job.recipient_email})")
|
|
sleep(0.1)
|
|
|
|
if args.json:
|
|
print(json.dumps({"processed": len(results), "results": results}, indent=2))
|
|
elif not jobs:
|
|
print("No pending IMAP append jobs found")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|