Browse Source

Add new module "mail_cleanup" in order to move/mark as read old messages

pull/213/head
Matthieu Dietrich 9 years ago
parent
commit
ecdb4ac880
  1. 63
      mail_cleanup/README.rst
  2. 1
      mail_cleanup/__init__.py
  3. 88
      mail_cleanup/__openerp__.py
  4. 135
      mail_cleanup/mail_cleanup.py
  5. 21
      mail_cleanup/mail_view.xml

63
mail_cleanup/README.rst

@ -0,0 +1,63 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License: AGPL-3
Mail cleanup
===========
This module allows to mark e-mails older than x days as read
and optionally move them on IMAP servers, just before fetching them.
Since the main "mail" module does not mark unroutable e-mails as read,
this means that if junk mail arrives in the catch-all address without
any default route, fetching newer e-mails will happen after re-parsing
those unroutable e-mails.
Configuration
=============
This module depends on ``mail_environment`` in order to add "expiration dates"
per server.
Example of a configuration file (add those values to your server)::
[incoming_mail.openerp_pop_mail1]
cleanup_days = 30 # default value
cleanup_folder = NotParsed # optional parameter
Known issues / Roadmap
======================
* None
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 smashing it by providing a detailed and welcomed feedback
`here <https://github.com/OCA/server-tools/issues/new?body=module:%20mail_cleanup%0Aversion:%207.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
Contributors
------------
* Matthieu Dietrich <matthieu.dietrich@camptocamp.com>
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 http://odoo-community.org.

1
mail_cleanup/__init__.py

@ -0,0 +1 @@
from . import mail_cleanup

88
mail_cleanup/__openerp__.py

@ -0,0 +1,88 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Matthieu Dietrich
# Copyright 2015 Camptocamp SA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Mail cleanup',
'version': '0.1',
'category': 'Tools',
'author': "Camptocamp,Odoo Community Association (OCA)",
'summary': 'Clean up mails regularly',
'description': """
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License: AGPL-3
Mail cleanup
===========
This module allows to mark e-mails older than x days as read
and optionally move them on IMAP servers, just before fetching them.
Since the main "mail" module does not mark unroutable e-mails as read,
this means that if junk mail arrives in the catch-all address without
any default route, fetching newer e-mails will happen after re-parsing
those unroutable e-mails.
Configuration
=============
This module depends on ``mail_environment`` in order to add "expiration dates"
per server.
Example of a configuration file (add those values to your server)::
[incoming_mail.openerp_pop_mail1]
cleanup_days = 30 # default value
cleanup_folder = NotParsed # optional parameter
Known issues / Roadmap
======================
* None
Credits
=======
Contributors
------------
* Matthieu Dietrich <matthieu.dietrich@camptocamp.com>
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 http://odoo-community.org.
""",
'license': 'AGPL-3',
'website': 'http://openerp.camptocamp.com',
'depends': ['mail_environment'],
'data': ['mail_view.xml'],
'installable': True,
}

135
mail_cleanup/mail_cleanup.py

@ -0,0 +1,135 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Matthieu Dietrich
# Copyright 2015 Camptocamp SA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import logging
from osv import fields
from osv import osv
from dateutil import relativedelta
from datetime import datetime
from server_environment import serv_config
_logger = logging.getLogger(__name__)
class FetchmailServer(osv.osv):
"""Incoming POP/IMAP mail server account"""
_inherit = 'fetchmail.server'
def _get_cleanup_conf(self, cursor, uid, ids, name, args, context=None):
"""
Return configuration
"""
res = {}
for fetchmail in self.browse(cursor, uid, ids):
global_section_name = 'incoming_mail'
# default vals
config_vals = {'cleanup_days': 30,
'cleanup_folder': False}
if serv_config.has_section(global_section_name):
config_vals.update(serv_config.items(global_section_name))
custom_section_name = '.'.join((global_section_name,
fetchmail.name))
if serv_config.has_section(custom_section_name):
config_vals.update(serv_config.items(custom_section_name))
if config_vals.get('cleanup_days'):
config_vals['cleanup_days'] = \
int(config_vals['cleanup_days'])
if config_vals.get('cleanup_folder'):
config_vals['cleanup_folder'] = \
config_vals['cleanup_folder']
res[fetchmail.id] = config_vals
return res
_columns = {
'cleanup_days': fields.function(
_get_cleanup_conf,
method=True,
string='Expiration days',
type="integer",
multi='outgoing_mail_config',
help="Number of days before discarding an e-mail"),
'cleanup_folder': fields.function(
_get_cleanup_conf,
method=True,
string='Expiration folder',
type="char",
multi='outgoing_mail_config',
help="Folder where the discarded e-mail will be moved.")
}
def _cleanup_fetchmail_server(self, server, imap_server):
count, failed = 0, 0
expiration_date = (datetime.now() + relativedelta.relativedelta(
days=-(server.cleanup_days))).strftime('%d-%b-%Y')
search_text = '(UNSEEN BEFORE %s)' % expiration_date
imap_server.select()
result, data = imap_server.search(None, search_text)
for num in data[0].split():
result, data = imap_server.fetch(num, '(RFC822)')
try:
# Mark message as read
imap_server.store(num, '+FLAGS', '\\Seen')
if server.cleanup_folder:
# To move a message, you have to COPY
# then DELETE the message
result = imap_server.copy(num, server.cleanup_folder)
if result[0] == 'OK':
imap_server.store(num, '+FLAGS', '\\Deleted')
imap_server.expunge()
except Exception:
_logger.exception('Failed to cleanup mail from %s server %s.',
server.type, server.name)
failed += 1
count += 1
_logger.info("Fetched %d email(s) on %s server %s; "
"%d succeeded, %d failed.", count, server.type,
server.name, (count - failed), failed)
def fetch_mail(self, cr, uid, ids, context=None):
""" Called before the fetch, in order to clean up
right before retrieving emails. """
if context is None:
context = {}
context['fetchmail_cron_running'] = True
for server in self.browse(cr, uid, ids, context=context):
_logger.info('start cleaning up emails on %s server %s',
server.type, server.name)
context.update({'fetchmail_server_id': server.id,
'server_type': server.type})
imap_server = False
if server.type == 'imap' and server.cleanup_days > 0:
try:
imap_server = server.connect()
self._cleanup_fetchmail_server(server, imap_server)
except Exception:
_logger.exception("General failure when trying to cleanup "
"mail from %s server %s.",
server.type, server.name)
finally:
if imap_server:
imap_server.close()
imap_server.logout()
return super(FetchmailServer, self).fetch_mail(cr, uid, ids,
context=context)

21
mail_cleanup/mail_view.xml

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="ir.ui.view" id="inherit_fetchmail_cleanup">
<!-- must be unique in this module. -->
<field name="name">inherit_fetchmail_for cleanup</field>
<field name="model">fetchmail.server</field>
<!--parent python entity -->
<field name="inherit_id" ref="mail_environment.inherit_fetchmail"/>
<!-- modulename.view -->
<field name="arch" type="xml">
<field name="is_ssl" position="after">
<field name="cleanup_days"/>
</field>
<field name="password" position="after">
<field name="cleanup_folder"/>
</field>
</field>
</record>
</data>
</openerp>
Loading…
Cancel
Save