You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

122 lines
4.8 KiB

# -*- coding: utf-8 -*-
# Copyright 2015 Innoviu srl <http://www.innoviu.it>
# Copyright 2015 Agile Business Group <http://www.agilebg.com>
# Copyright 2017 Eficent Business and IT Consulting Services, S.L.
# <http://www.eficent.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
import imaplib
from datetime import datetime
import time
from openerp import api, fields, models
_logger = logging.getLogger(__name__)
class FetchmailServer(models.Model):
_inherit = "fetchmail.server"
last_internal_date = fields.Datetime(
'Last Download Date',
help="Remote emails with a date greater than this will be "
"downloaded. Only available with IMAP")
@api.model
def _fetch_from_date_imap(self, imap_server, count, failed):
MailThread = self.env['mail.thread']
messages = []
date_uids = {}
last_date = False
last_internal_date = datetime.strptime(self.last_internal_date,
"%Y-%m-%d %H:%M:%S")
search_status, uids = imap_server.search(
None,
'SINCE', '%s' % last_internal_date.strftime('%d-%b-%Y')
)
new_uids = uids[0].split()
for new_uid in new_uids:
fetch_status, date = imap_server.fetch(
int(new_uid),
'INTERNALDATE'
)
internaldate = imaplib.Internaldate2tuple(date[0])
internaldate_msg = datetime.fromtimestamp(
time.mktime(internaldate)
)
if internaldate_msg > last_internal_date:
messages.append(new_uid)
date_uids[new_uid] = internaldate_msg
for num in messages:
# SEARCH command *always* returns at least the most
# recent message, even if it has already been synced
res_id = None
result, data = imap_server.fetch(num, '(RFC822)')
if data and data[0]:
try:
res_id = MailThread.message_process(
self.object_id.model,
data[0][1],
save_original=self.original,
strip_attachments=(not self.attach))
except Exception:
_logger.exception(
'Failed to process mail \
from %s server %s.',
self.type,
self.name)
failed += 1
if res_id and self.action_id:
self.action_id.run({
'active_id': res_id,
'active_ids': [res_id],
'active_model': self.env.context.get(
"thread_model", self.object_id.model)
})
imap_server.store(num, '+FLAGS', '\\Seen')
self._cr.commit()
count += 1
last_date = not failed and date_uids[num] or False
return count, failed, last_date
@api.multi
def fetch_mail(self):
context = self.env.context.copy()
context['fetchmail_cron_running'] = True
for server in self:
if server.type == 'imap' and server.last_internal_date:
_logger.info(
'start checking for new emails, starting from %s on %s '
'server %s',
server.last_internal_date, server.type, server.name)
context.update({'fetchmail_server_id': server.id,
'server_type': server.type})
count, failed = 0, 0
last_date = False
imap_server = False
try:
imap_server = server.connect()
imap_server.select()
count, failed, last_date = server._fetch_from_date_imap(
imap_server, count, failed)
except Exception:
_logger.exception(
"General failure when trying to fetch mail by date \
from %s server %s.",
server.type,
server.name
)
finally:
if imap_server:
imap_server.close()
imap_server.logout()
if last_date:
_logger.info(
"Fetched %d email(s) on %s server %s, starting from "
"%s; %d succeeded, %d failed.", count,
server.type, server.name, last_date,
(count - failed), failed)
vals = {'last_internal_date': last_date}
server.write(vals)
return super(FetchmailServer, self).fetch_mail()