72 lines
2.5 KiB
Python
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}'
|