Files
procyon/emailer.py
2026-10-06 23:43:21 -07:00

72 lines
2.5 KiB
Python

# Procyon — email sending via SMTP. Configurable; safe when unconfigured.
import smtplib
import ssl
from email.message import EmailMessage
import db
def configured():
return bool(db.get_setting('smtp_user', '')) and bool(db.get_setting('smtp_pass', ''))
def send(subject, body, to_email, attachment_path=None):
host = db.get_setting('smtp_host', 'smtp.mail.me.com')
port = int(db.get_setting('smtp_port', '587'))
user = db.get_setting('smtp_user', '')
pw = db.get_setting('smtp_pass', '')
from_email = db.get_setting('from_email', 'indianaholmes1@icloud.com')
from_name = db.get_setting('from_name', 'Indiana Holmes')
if not (user and pw):
raise RuntimeError('SMTP not configured — add iCloud app-specific password in Settings')
msg = EmailMessage()
msg['Subject'] = subject
msg['From'] = f'{from_name} <{from_email}>'
msg['To'] = to_email
msg['Reply-To'] = from_email
msg.set_content(body)
if attachment_path:
import os
with open(attachment_path, 'rb') as f:
data = f.read()
msg.add_attachment(data, maintype='application', subtype='pdf',
filename=os.path.basename(attachment_path))
ctx = ssl.create_default_context()
with smtplib.SMTP(host, port, timeout=30) as s:
s.starttls(context=ctx)
s.login(user, pw)
s.send_message(msg)
return True
def auto_send(app_id):
"""Auto-approve + send a prepared application to its scraped contact email — no human
gate. Guarded: only sends when a contact email was scraped, SMTP is configured, and the
self-audit passes (no fabrication/garbage). Returns (sent: bool, message: str)."""
import audit
app = db.get_application(app_id)
if not app:
return False, 'app not found'
job = db.get_job(app['job_id'])
to_email = (job.get('contact_email') or '').strip() if job else ''
if not to_email:
return False, 'no contact email scraped'
if not configured():
return False, 'SMTP not configured'
checks = db.get_audit(app_id)
if not audit.all_pass(checks):
return False, 'audit has FAIL items'
try:
send(app['email_subject'], app['email_body'], to_email,
attachment_path=app.get('tailored_pdf') or app.get('resume_path'))
db.update_application(app_id, status='sent', notes=f'auto-sent to {to_email}')
db.set_job_status(app['job_id'], 'sent')
return True, f'sent to {to_email}'
except Exception as e:
return False, f'send error: {e}'