Browse Source
Merge pull request #932 from Eficent/9.0-mig-fetchmail_bydate
Merge pull request #932 from Eficent/9.0-mig-fetchmail_bydate
[9.0][mig] fetchmail_bydatepull/991/head
Jordi Ballester Alomar
7 years ago
committed by
GitHub
6 changed files with 280 additions and 0 deletions
-
98fetchmail_bydate/README.rst
-
4fetchmail_bydate/__init__.py
-
29fetchmail_bydate/__openerp__.py
-
4fetchmail_bydate/models/__init__.py
-
122fetchmail_bydate/models/fetchmail.py
-
23fetchmail_bydate/views/fetchmail_view.xml
@ -0,0 +1,98 @@ |
|||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
|||
:target: http://www.gnu.org/licenses/agpl |
|||
:alt: License: AGPL-3 |
|||
|
|||
================ |
|||
Fetchmail Bydate |
|||
================ |
|||
|
|||
This module allows to fetch new emails (using IMAP) received from the last |
|||
time they were downloaded and successfully processed, in addition to 'unseen' |
|||
status. |
|||
|
|||
Users with authorization to edit the email server in Odoo can introduce a |
|||
new date and time to download from. |
|||
|
|||
In case of errors found during the processing of an email Odoo will |
|||
re-attempt to fetch the emails from the last date and time they were |
|||
successfully received and processed. |
|||
|
|||
|
|||
|
|||
Configuration |
|||
============= |
|||
|
|||
To enable this, you have to set a 'Last Download Date' in the fetchmail.server |
|||
After that, emails with an internal date greater than the saved one will be |
|||
downloaded. |
|||
|
|||
|
|||
Usage |
|||
===== |
|||
|
|||
Odoo will attempt to fetch emails starting from the 'Last Download Date' |
|||
defined in the email server. If all mails have been processed successfully, |
|||
it will update this date with the latest message received. |
|||
|
|||
System administrators need to be attentive to the Odoo logs, looking for errors |
|||
raised during the processing of emails, in order to avoid situations where |
|||
lots of emails are downloaded and reprocessed every time, due to errors found |
|||
in a few old emails that were unattended. |
|||
|
|||
|
|||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
|||
:alt: Try me on Runbot |
|||
:target: https://runbot.odoo-community.org/runbot/149/9.0 |
|||
|
|||
|
|||
Known issues / Roadmap |
|||
====================== |
|||
|
|||
* This module should not be used together with the OCA module |
|||
`fetchmail_notify_error_to_sender <https://github.com/OCA/server-tools/tree/9 |
|||
.0/fetchmail_notify_error_to_sender>`_, because this other module sends an |
|||
email to the author of an email when it could not be processed. And you |
|||
would be spamming to the original authors every time Odoo tries to |
|||
re-process the email. |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues |
|||
<https://github.com/OCA/server-tools/issues>`_. In case of trouble, please |
|||
check there if your issue has already been reported. If you spotted it first, |
|||
help us smash it by providing detailed and welcomed feedback. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Images |
|||
------ |
|||
|
|||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Lorenzo Battistini <lorenzo.battistini@agilebg.com> |
|||
* Alessio Gerace |
|||
* Jordi Ballester <jordi.ballester@eficent.com> |
|||
|
|||
|
|||
Do not contact contributors directly about support or help with technical issues. |
|||
|
|||
|
|||
Maintainer |
|||
---------- |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: https://odoo-community.org |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
OCA, or the Odoo Community Association, is a nonprofit organization whose |
|||
mission is to support the collaborative development of Odoo features and |
|||
promote its widespread use. |
|||
|
|||
To contribute to this module, please visit https://odoo-community.org. |
@ -0,0 +1,4 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from . import models |
@ -0,0 +1,29 @@ |
|||
# -*- 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). |
|||
|
|||
|
|||
{ |
|||
"name": "Fetchmail by Date", |
|||
"summary": 'Fetchmail by date and unseen messages', |
|||
"version": "9.0.1.0.0", |
|||
"category": "Discuss", |
|||
"author": "Innoviu, " |
|||
"Agile Business Group, " |
|||
"Eficent, " |
|||
"Odoo Community Association (OCA)", |
|||
"website": "https://github.com/OCA/server-tools/tree/9.0", |
|||
"license": 'AGPL-3', |
|||
"application": False, |
|||
"installable": True, |
|||
"depends": [ |
|||
'fetchmail', |
|||
'mail', |
|||
], |
|||
"data": [ |
|||
'views/fetchmail_view.xml', |
|||
], |
|||
} |
@ -0,0 +1,4 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from . import fetchmail |
@ -0,0 +1,122 @@ |
|||
# -*- 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() |
@ -0,0 +1,23 @@ |
|||
<?xml version="1.0" encoding="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). --> |
|||
|
|||
<odoo> |
|||
|
|||
<record model="ir.ui.view" id="view_fethmail_bydate_form"> |
|||
<field name="name">fetchmail.bydate.form</field> |
|||
<field name="model">fetchmail.server</field> |
|||
<field name="priority" eval="1"/> |
|||
<field name="inherit_id" ref="fetchmail.view_email_server_form"/> |
|||
<field name="arch" type="xml"> |
|||
<field name="date" position="after" > |
|||
<field name="last_internal_date" |
|||
attrs="{'invisible':[('type','!=','imap')]}"/> |
|||
</field> |
|||
</field> |
|||
</record> |
|||
|
|||
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue