-
Notifications
You must be signed in to change notification settings - Fork 179
/
clock.py
105 lines (77 loc) · 3.17 KB
/
clock.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
"""Check emails to [email protected], lint them, and reply."""
from apscheduler.schedulers.blocking import BlockingScheduler
import gmail
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from worker import conn
import requests
import hashlib
import json
import os
import logging
import re
logging.basicConfig()
scheduler = BlockingScheduler()
# Settings
user = "[email protected]"
user_to = "[email protected]"
name = "proselint"
password = os.environ['gmail_password']
tagline = "Proselint, a linter for prose."
url = "http://proselint.com"
api_url = "http://api.proselint.com/v0/"
def quoted(string, every=64):
"""Insert a quote before linebreaks."""
return "> " + re.sub("\r\n(?=[^\r\n])", "\r\n> ", string)
@scheduler.scheduled_job('interval', minutes=0.25)
def check_email():
"""Check the mail account and lint new mail."""
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.ehlo()
server.login(user, password)
g = gmail.login(user, password)
# Check for unread messages.
unread = g.inbox().mail(unread=True)
# Submit a job to lint each email sent to [email protected]. Record the
# resulting job_ids somewhere (in Redis, I suppose), keyed by a hash of the
# email.
for u in unread:
u.fetch()
signature = (u.fr.decode('utf-8') +
u.subject.decode('utf-8') +
u.body.decode('utf-8'))
hash = hashlib.sha256(signature.encode('utf-8')).hexdigest()
if user_to in u.to or user_to in u.headers.get('Cc', []):
job_id = conn.get(hash)
if not job_id:
# If the email hasn't been sent for processing, send it.
r = requests.post(api_url, data={"text": u.body})
conn.set(hash, r.json()["job_id"])
print("Email {} sent for processing.".format(hash))
else:
# Otherwise, check whether the results are ready, and if so,
# reply with them.
r = requests.get(api_url, params={"job_id": job_id})
if r.json()["status"] == "success":
reply = quoted(u.body)
errors = r.json()['data']['errors']
reply += "\r\n\r\n".join([json.dumps(e) for e in errors])
msg = MIMEMultipart()
msg["From"] = "{} <{}>".format(name, user)
msg["To"] = u.fr
msg["Subject"] = "Re: " + u.subject
if u.headers.get('Message-ID'):
msg.add_header("In-Reply-To", u.headers['Message-ID'])
msg.add_header("References", u.headers['Message-ID'])
body = reply + "\r\n\r\n--\r\n" + tagline + "\r\n" + url
msg.attach(MIMEText(body, "plain"))
text = msg.as_string()
server.sendmail(user, u.fr, text)
# Mark the email as read.
u.read()
u.archive()
print("Email {} has been replied to.".format(hash))
scheduler.start()