Created
May 19, 2016 18:42
-
-
Save asyndrige/17d330f1a532264431120a363a93fc1e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding=utf-8 | |
import imaplib | |
import os | |
import email | |
import base64 | |
from datetime import datetime | |
from importlib import import_module | |
from email.header import decode_header | |
from django.db import transaction | |
from lib.models import FileKoodoo | |
from base.functions import email_re | |
from base.functions import model_from_cache | |
def get_connection(box): | |
if box.ssl: | |
m = imaplib.IMAP4_SSL(box.server, box.port) | |
else: | |
m = imaplib.IMAP4(box.server, box.port) | |
m.login(box.login, box.password) | |
return m | |
@transaction.commit_on_success | |
def move_to_folder(box, message, folder, connection=None, uid=None): | |
u""" move message to folder """ | |
message.folder = folder | |
message.save(update_fields=('folder',)) | |
if connection is None: | |
connection = get_connection(box) | |
connection.select(folder.name) | |
if uid is None: | |
result, uids = connection.uid('search', 'HEADER', 'Message-ID', message.imap_id) | |
if result != 'ОК': | |
raise Exception(u'not find message in mail folder by message-id') | |
uid = uids[0] | |
result = connection.uid('copy', uid, folder.name)[0] | |
if result == 'OK': | |
connection.uid('store', uid, '+FLAGS', '\\Deleted') | |
def mail_to_photoarchive(message_object, n_loss, document_id, ent_id, obj_id, type_id): | |
u""" save mail into photoarchive""" | |
# Прикрепить сообщения в старый фотоархив | |
#file_path = 'dfsroot/CO/App/ScanDoc04/SED/%s' % datetime.now().strftime('%Y/%m/%d') //Нерабочий ScanDoc | |
file_path = 'dfsroot/CO/App/ScanDoc05/SED/%s' % datetime.now().strftime('%Y/%m/%d') | |
file_name = 'mail_%s.eml' % message_object.id | |
file_path_save = '/mnt/' + file_path | |
file_path_save_full = file_path_save + '/' + file_name | |
if not os.path.exists(file_path_save): | |
os.makedirs(file_path_save) | |
from io import BufferedWriter, FileIO | |
with BufferedWriter(FileIO(file_path_save_full, "wb")) as dest: | |
dest.write(base64.b64decode(message_object.raw_body)) | |
new_file = FileKoodoo(file_type_id=type_id, | |
file_path=('//koodoo.ru/%s/%s' % (file_path, file_name)).replace('/', '\\'), | |
file_size=os.path.getsize(file_path_save_full), | |
file_name_original='mail_%s' % message_object.id, | |
n_loss=n_loss, | |
document_id=document_id, | |
object_ent_id=ent_id, | |
object_obj_id=obj_id, | |
date_typing=datetime.now(), | |
created_from=u'py_mail') | |
new_file.save() | |
def get_box_manager(box, user=None, folder=None, email_message=None, request=None): | |
u""" get manager class """ | |
module_name = 'mailer.box_managers.box_%s' % box.id | |
module = import_module(module_name) | |
return module.BoxManager(user, folder, email_message, request, box) | |
def get_model(box_id, model_name): | |
u""" Достает модель из кэша """ | |
return model_from_cache('mailer', '%s%s' % (model_name, box_id)) | |
def decode_value(value_raw, message_charset=None): | |
u""" return decoded raw value. | |
if value is multi-row, decode row-by-row """ | |
if message_charset and message_charset != 'utf-8': | |
value_raw = value_raw.decode(message_charset) | |
lines = [] | |
for w, e in decode_header(value_raw): | |
if e is not None and e != 'uft-8': | |
w = w.decode(e) | |
lines.append(w) | |
return u' '.join(lines) | |
@transaction.commit_on_success | |
def process_email(m, mail_uid, folder, Message, box_manager): | |
# get raw content | |
result, data = m.uid('fetch', mail_uid, '(RFC822)') | |
raw_mail = data[0][1] | |
mail = email.message_from_string(raw_mail) | |
# parse mail | |
mail_data = parse_message(mail) | |
if mail_data is None: | |
print 'mail_data is None' | |
return | |
imap_id = mail_data['imap_id'] | |
subject = mail_data['subject'] | |
sender = mail_data['sender'] | |
email_body = mail_data['email_body'] | |
# if message already uploaded and marked as unseen | |
if Message.objects.filter(imap_id=imap_id).exists(): | |
m.uid('store', mail_uid, '+FLAGS', '\\Seen') | |
return | |
# create object | |
msg_object = Message(folder=folder, | |
raw_body=base64.b64encode(raw_mail), | |
subject=subject, | |
sender=sender, | |
imap_id=imap_id, | |
body=email_body, | |
deleted=False) | |
msg_object.save() | |
conf = open(os.path.join('/', 'home', 'www', 'py_docflow', 'fail.log'), 'a') | |
conf.write(subject) | |
conf.write("/") | |
conf.write(sender) | |
conf.write("------------------------------------------------------------\n") | |
conf.close() | |
# if message move to another folder in box_manager, unseen error | |
try: | |
# mark seen | |
m.uid('store', mail_uid, '+FLAGS', '\\Seen') | |
# send signal create document | |
box_manager.message_created(msg_object, m, mail_uid) | |
m.expunge() | |
except: | |
m.uid('store', mail_uid, '-FLAGS', '\\Seen') | |
raise | |
def get_emails(box): | |
u""" get emails from server and store to database """ | |
m = get_connection(box) | |
i = 0 | |
Message = get_model(box.id, 'Message') | |
Folder = get_model(box.id, 'Folder') | |
# Получение объекта BoxManager | |
box_manager = get_box_manager(box) | |
for folder in Folder.objects.filter(download=True): | |
result, message = m.select(folder.name) | |
if result != 'OK': | |
raise Exception(message) | |
result, data = m.uid('search', None, 'UNSEEN') # UNSEEN | |
mail_uids = data[0].split() | |
for mail_uid in mail_uids: | |
if i >= 20: | |
break | |
process_email(m, mail_uid, folder, Message, box_manager) | |
i += 1 | |
m.close() | |
m.logout() | |
return i | |
def parse_message(mail): | |
u""" parse message and get message items """ | |
subject_raw = mail['subject'] | |
subject, message_charset = decode_header(subject_raw)[0] | |
if message_charset: | |
subject = subject.decode(message_charset) | |
subject = subject[:249] | |
imap_id = mail['message-id'] | |
sender = mail['from'] | |
if sender is None: | |
return None | |
sender = email_re.search(sender).group() | |
email_body = None | |
if mail.is_multipart(): | |
for part in mail.walk(): | |
if part.get_content_type() == 'text/plain': | |
email_body = part.get_payload(decode=True) | |
charset = part.get_content_charset() | |
if charset: | |
email_body = email_body.decode(charset) | |
break | |
else: | |
email_body = mail.get_payload(decode=True) | |
charset = mail.get_content_charset() | |
if charset is not None: | |
email_body = email_body.decode(charset) | |
return {'subject': subject, | |
'imap_id': imap_id, | |
'sender': sender, | |
'email_body': email_body} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment