1
|
|
|
import sqlite3 |
2
|
|
|
import os |
3
|
|
|
import imaplib |
4
|
|
|
import email |
5
|
|
|
from email.header import decode_header |
6
|
|
|
from datetime import datetime |
7
|
|
|
|
8
|
|
|
|
9
|
|
|
# connect to the database for email information |
10
|
|
|
basedir = os.path.abspath(os.path.dirname(__file__)) |
11
|
|
|
sql_database = os.environ.get('DATABASE_URL') or \ |
12
|
|
|
'sqlite:///' + os.path.join(basedir, 'db.sqlite') |
13
|
|
|
sql_database = sql_database[10:] |
14
|
|
|
|
15
|
|
|
conn = sqlite3.connect(sql_database) |
16
|
|
|
|
17
|
|
|
cursor = conn.execute("SELECT email, password, server, subjectstr, startstr, endstr from email") |
18
|
|
|
|
19
|
|
|
for row in cursor: |
20
|
|
|
username = row[0] |
21
|
|
|
password = row[1] |
22
|
|
|
imap_server = row[2] |
23
|
|
|
subjectstr = row[3] |
24
|
|
|
startstr = row[4] |
25
|
|
|
endstr = row[5] |
26
|
|
|
|
27
|
|
|
# create an IMAP4 class with SSL |
28
|
|
|
imap = imaplib.IMAP4_SSL(imap_server) |
29
|
|
|
# authenticate |
30
|
|
|
imap.login(username, password) |
31
|
|
|
|
32
|
|
|
status, messages = imap.select("INBOX", readonly=True) |
33
|
|
|
messages = int(messages[0]) |
34
|
|
|
|
35
|
|
|
email_content = {} |
36
|
|
|
|
37
|
|
|
for i in range(1, messages + 1): |
38
|
|
|
# fetch the email message by ID |
39
|
|
|
try: |
40
|
|
|
res, msg = imap.fetch(str(i), "(RFC822)") |
41
|
|
|
for response in msg: |
42
|
|
|
if isinstance(response, tuple): |
43
|
|
|
# parse a bytes email into a message object |
44
|
|
|
msg = email.message_from_bytes(response[1]) |
45
|
|
|
# decode the email subject |
46
|
|
|
subject, encoding = decode_header(msg["Subject"])[0] |
47
|
|
|
if isinstance(subject, bytes): |
48
|
|
|
# if it's a bytes, decode to str |
49
|
|
|
try: |
50
|
|
|
subject = subject.decode(encoding) |
51
|
|
|
except: |
52
|
|
|
subject = "subject" |
53
|
|
|
# decode email sender |
54
|
|
|
From, encoding = decode_header(msg.get("From"))[0] |
55
|
|
|
if isinstance(From, bytes): |
56
|
|
|
try: |
57
|
|
|
From = From.decode(encoding) |
58
|
|
|
except: |
59
|
|
|
pass |
60
|
|
|
# if the email message is multipart |
61
|
|
|
if msg.is_multipart(): |
62
|
|
|
# iterate over email parts |
63
|
|
|
for part in msg.walk(): |
64
|
|
|
# extract content type of email |
65
|
|
|
content_type = part.get_content_type() |
66
|
|
|
content_disposition = str(part.get("Content-Disposition")) |
67
|
|
|
try: |
68
|
|
|
# get the email body |
69
|
|
|
body = part.get_payload(decode=True).decode() |
70
|
|
|
except: |
71
|
|
|
pass |
72
|
|
|
if content_type == "text/plain" and "attachment" not in content_disposition: |
73
|
|
|
# print text/plain emails and skip attachments |
74
|
|
|
try: |
75
|
|
|
email_content[subject] = body |
76
|
|
|
except: |
77
|
|
|
pass |
78
|
|
|
else: |
79
|
|
|
# extract content type of email |
80
|
|
|
content_type = msg.get_content_type() |
81
|
|
|
# get the email body |
82
|
|
|
body = msg.get_payload(decode=True).decode() |
83
|
|
|
if content_type == "text/plain": |
84
|
|
|
# print only text email parts |
85
|
|
|
try: |
86
|
|
|
email_content[subject] = body |
87
|
|
|
except: |
88
|
|
|
pass |
89
|
|
|
except: |
90
|
|
|
pass |
91
|
|
|
|
92
|
|
|
# Find the email by subject and the balance between the start and end strings and write to database |
93
|
|
|
try: |
94
|
|
|
start_index = email_content[subjectstr].find(startstr) + len(startstr) |
95
|
|
|
end_index = email_content[subjectstr].find(endstr) |
96
|
|
|
new_balance = email_content[subjectstr][start_index:end_index].replace(',', '') |
97
|
|
|
new_balance = new_balance.replace('$', '') |
98
|
|
|
new_balance = float(new_balance) |
99
|
|
|
|
100
|
|
|
conn.execute("INSERT INTO BALANCE (AMOUNT, DATE) VALUES (?,?)", (str(new_balance), |
101
|
|
|
datetime.today().date())) |
102
|
|
|
conn.commit() |
103
|
|
|
except: |
104
|
|
|
pass |
105
|
|
|
|
106
|
|
|
# close the connection and logout |
107
|
|
|
imap.close() |
108
|
|
|
imap.logout() |
109
|
|
|
conn.close() |
110
|
|
|
|