summaryrefslogtreecommitdiff
path: root/emailcanary
diff options
context:
space:
mode:
authorJesse Morgan <jesse@jesterpm.net>2015-10-24 13:28:24 -0700
committerJesse Morgan <jesse@jesterpm.net>2015-10-24 13:28:24 -0700
commit95ee2046715024e7eedf663e09161933689a7aef (patch)
tree9a0bf8dfaa91ef97f24671a53d51d0829ce2a48f /emailcanary
Initial commit.
Diffstat (limited to 'emailcanary')
-rw-r--r--emailcanary/__init__.py0
-rw-r--r--emailcanary/canary.py33
-rw-r--r--emailcanary/canarydb.py41
-rw-r--r--emailcanary/email-digest-sender.py38
-rw-r--r--emailcanary/emailutils.py19
5 files changed, 131 insertions, 0 deletions
diff --git a/emailcanary/__init__.py b/emailcanary/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/emailcanary/__init__.py
diff --git a/emailcanary/canary.py b/emailcanary/canary.py
new file mode 100644
index 0000000..d07e2e9
--- /dev/null
+++ b/emailcanary/canary.py
@@ -0,0 +1,33 @@
+import uuid, datetime, time
+import email
+import re
+
+class Canary:
+ def __init__(self, db, smtp, fromaddress):
+ self.db = db
+ self.smtp = smtp
+ self.fromaddress = fromaddress
+
+ def chirp(self, list, expectedreceipients):
+ uuid = uuid.uuid4()
+ now = datetime.datetime.now()
+
+ self.send(list, now, uuid)
+ for dest in expectedreceipients:
+ self.db.ping(dest, now, uuid)
+
+ def echo(self, receipient, msg):
+ uuid = re.match('Canary Email (.+)', msg['Subject']).group(1)
+ now = datetime.datetime.now()
+
+ self.db.pong(receipient, now, uuid)
+
+
+ def send(self, dest, date, uuid):
+ msg = email.message.Message()
+ msg['From'] = self.fromaddress
+ msg['To'] = dest
+ msg['Subject'] = "Canary Email " + str(uuid)
+ msg['Date'] = email.utils.formatdate(time.mktime(date.timetuple()))
+
+ self.smtp.sendmail(self.fromaddress, dest, msg.as_string()) \ No newline at end of file
diff --git a/emailcanary/canarydb.py b/emailcanary/canarydb.py
new file mode 100644
index 0000000..112b8f5
--- /dev/null
+++ b/emailcanary/canarydb.py
@@ -0,0 +1,41 @@
+import sqlite3
+from datetime import datetime
+
+class CanaryDB:
+ def __init__(self, filename):
+ self.conn = sqlite3.connect(filename, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
+
+ # Create Tables if necessary
+ cursor = self.conn.cursor()
+ cursor.execute("CREATE TABLE IF NOT EXISTS pings (address, uuid, timesent timestamp, timereceived timestamp)")
+
+ def close(self):
+ self.conn.close()
+
+ def ping(self, address, time, uuid):
+ cursor = self.conn.cursor()
+ cursor.execute("INSERT INTO pings (address, timesent, uuid) VALUES (?, ?, ?)", \
+ (address, time, uuid))
+ self.conn.commit()
+
+ def pong(self, address, time, uuid):
+ cursor = self.conn.cursor()
+ cursor.execute("UPDATE pings SET timereceived=? WHERE address=? AND uuid=?", \
+ (time, address, uuid))
+ self.conn.commit()
+
+ def get_missing_pongs(self):
+ '''Return a list of tupls of missing pongs.
+ Each tupl contains (uuid, address, time since send)'''
+ cursor = self.conn.cursor()
+ cursor.execute("SELECT uuid, address, timesent FROM pings WHERE timereceived IS NULL");
+
+ now = datetime.now()
+ results = list()
+ for row in cursor:
+ uuid = row[0]
+ address = row[1]
+ delta = now - row[2]
+ results.append((uuid, address, delta))
+
+ return results
diff --git a/emailcanary/email-digest-sender.py b/emailcanary/email-digest-sender.py
new file mode 100644
index 0000000..f1583c0
--- /dev/null
+++ b/emailcanary/email-digest-sender.py
@@ -0,0 +1,38 @@
+import emailutils
+import smtplib
+from email import message
+
+PASSWORD="secret"
+ACCOUNTS = [('mail.example.com', 'email@example.com', PASSWORD)]
+DESTINATION="other@example.com"
+
+youve_got_mail = False
+all_subjects = {}
+
+for account in ACCOUNTS:
+ mail = emailutils.get_imap(account)
+ these_subjects = []
+ for uid in emailutils.get_mail_uids(mail):
+ message = emailutils.get_message(mail, uid)
+ these_subjects.append(message['subject'])
+ youve_got_mail = True
+ all_subjects[account[1]] = these_subjects
+
+
+if youve_got_mail:
+ msg = ""
+ for account in all_subjects:
+ msg = msg + "# Messages for %s\n" % account
+ for subject in all_subjects[account]:
+ msg = msg + " * %s\n" % subject
+ msg = msg + "\n"
+
+ digest_message = message.Message()
+ digest_message.set_payload(msg)
+ digest_message['From'] = DESTINATION
+ digest_message['To'] = DESTINATION
+ digest_message['Subject'] = "Email Digest"
+
+ s = smtplib.SMTP_SSL('localhost', 2465)
+ s.sendmail(DESTINATION, DESTINATION, digest_message.as_string())
+ s.quit() \ No newline at end of file
diff --git a/emailcanary/emailutils.py b/emailcanary/emailutils.py
new file mode 100644
index 0000000..6646c1e
--- /dev/null
+++ b/emailcanary/emailutils.py
@@ -0,0 +1,19 @@
+import imaplib, email
+
+def get_imap(account):
+ '''Connect and login via IMAP'''
+ mail = imaplib.IMAP4_SSL(account[0])
+ mail.login(account[1], account[2])
+ return mail
+
+def get_mail_uids(mail):
+ '''Return a list of message UIDs in the inbox'''
+ mail.select("inbox") # connect to inbox.
+ result, data = mail.uid('search', None, "ALL") # search and return uids instead
+ return data[0].split()
+
+def get_message(mail, uid):
+ '''Get a single email message object by UID'''
+ result, data = mail.uid('fetch', uid, '(RFC822)')
+ raw_email = data[0][1]
+ return email.message_from_string(raw_email) \ No newline at end of file