-
Notifications
You must be signed in to change notification settings - Fork 0
/
get_pics_by_mail.py
executable file
·129 lines (109 loc) · 3.94 KB
/
get_pics_by_mail.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/env python3
import email
import imaplib
import os
import random
import re
import string
from decouple import config
from email.header import decode_header
from helper import validate_picture, DuplicateImageExeption
from pathlib import Path
from PIL import UnidentifiedImageError
from time import time
from tinydb import TinyDB
DEBUG = config('DEBUG', default=False, cast=bool)
db = TinyDB(config('PROJECT_PATH') + '/user_data/db.json')
imap = imaplib.IMAP4_SSL(config('EMAIL_HOST'), config('EMAIL_PORT',
default=993, cast=int))
imap.login(config('EMAIL_USER'), config('EMAIL_PASS'))
imap.select(config('EMAIL_INBOX'))
type, data = imap.search(None, 'ALL')
if DEBUG:
print("FETCH: ", type)
mail_ids = data[0]
id_list = mail_ids.split()
id_list.reverse()
image_added = False
for i, id in enumerate(id_list):
if DEBUG:
print("counter: ", i)
if i == config('FETCH_EMAIL', cast=int):
if DEBUG:
print("bye!")
break
typ, data = imap.fetch(id, '(RFC822)')
msg = email.message_from_bytes(data[0][1])
# decode the email subject
email_subject, encoding = decode_header(msg["Subject"])[0]
if isinstance(email_subject, bytes):
# if it's a bytes, decode to str
email_subject = email_subject.decode(encoding or 'utf8')
if DEBUG:
print("Subject:", email_subject)
# check the email subject for the keyword
email_keyword = config('EMAIL_KEYWORD')
if not re.search(rf'{email_keyword}', email_subject, re.IGNORECASE):
if DEBUG:
print("skip!")
continue
# decode email sender
email_sender, encoding = decode_header(msg.get("From"))[0]
if isinstance(email_sender, bytes):
email_sender = email_sender.decode(encoding)
if DEBUG:
print("From:", email_sender)
# converts byte literal to string removing b''
raw_email = data[0][1]
raw_email_string = raw_email.decode('utf-8')
email_message = email.message_from_string(raw_email_string)
# download attachments
for part in email_message.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get('Content-Disposition') is None:
continue
fileName = part.get_filename()
if bool(fileName):
raw = part.get_payload(decode=True)
# create unique file name
letters = string.ascii_lowercase
rnd_str = ''.join(random.choice(letters) for i in range(7))
fileName = f'{rnd_str}-{fileName}'
if DEBUG:
print("new file name: ", fileName)
# save file (for now)
picture_path = config('PROJECT_PATH') + '/pictures'
filePath = os.path.join(picture_path, fileName)
fp = open(filePath, 'wb')
fp.write(part.get_payload(decode=True))
fp.close()
if DEBUG:
print("attachment: ", filePath)
try:
# verify picture and check for duplicate
hd = validate_picture(filePath)
# write image properties to db
db.insert({'filename': fileName, 'sender': email_sender,
'date': int(time()), 'checksum': hd})
image_added = True
except DuplicateImageExeption:
if DEBUG:
print("duplicate --> skip!")
os.remove(filePath)
pass
except UnidentifiedImageError:
if DEBUG:
print("unkown file: ", fileName)
os.remove(filePath)
pass
if config('DELETE_EMAIL', default=False, cast=bool):
if DEBUG:
print("deleted email: ", id)
imap.store(id, "+FLAGS", "\\Deleted")
# trigger fbi restart
if image_added:
Path(config('PROJECT_PATH') + '/site_run/image_added').touch(exist_ok=True)
imap.expunge()
imap.close()
imap.logout()