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
130
131
132
133
134
135
136
137
138
139
140
# -*- coding: utf-8 -*-
# © 2015-2016 Matthieu Dietrich (Camptocamp SA)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
import datetime
from openerp import api, fields, models
from dateutil.relativedelta import relativedelta
from openerp.addons.server_environment import serv_config
_logger = logging.getLogger(__name__)
class FetchmailServer(models.Model):
"""Incoming POP/IMAP mail server account"""
_inherit = 'fetchmail.server'
cleanup_days = fields.Integer(
compute='_get_cleanup_conf',
string='Expiration days',
help="Number of days before marking an e-mail as read")
cleanup_folder = fields.Char(
compute='_get_cleanup_conf',
string='Expiration folder',
help="Folder where an e-mail marked as read will be moved.")
purge_days = fields.Integer(
compute='_get_cleanup_conf',
string='Deletion days',
help="Number of days before removing an e-mail")
@api.multi
def _get_cleanup_conf(self):
"""
Return configuration
"""
for fetchmail in self:
global_section_name = 'incoming_mail'
# default vals
config_vals = {'cleanup_days': False,
'purge_days': False,
'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))
# convert string values to integer
if config_vals['cleanup_days']:
config_vals['cleanup_days'] = int(config_vals['cleanup_days'])
if config_vals['purge_days']:
config_vals['purge_days'] = int(config_vals['purge_days'])
for field in ['cleanup_days', 'purge_days', 'cleanup_folder']:
fetchmail[field] = config_vals[field]
def _cleanup_fetchmail_server(self, server, imap_server):
count, failed = 0, 0
expiration_date = datetime.date.today()
expiration_date -= relativedelta(days=server.cleanup_days)
search_text = expiration_date.strftime('(UNSEEN BEFORE %d-%b-%Y)')
imap_server.select()
result, data = imap_server.search(None, search_text)
for num in data[0].split():
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')
except Exception:
_logger.exception('Failed to cleanup mail from %s server %s.',
server.type, server.name)
failed += 1
count += 1
_logger.info("Marked %d email(s) as read on %s server %s; "
"%d succeeded, %d failed.", count, server.type,
server.name, (count - failed), failed)
def _purge_fetchmail_server(self, server, imap_server):
# Purging e-mails older than the purge date, if available
count, failed = 0, 0
purge_date = datetime.date.today()
purge_date -= relativedelta(days=server.purge_days)
search_text = purge_date.strftime('(BEFORE %d-%b-%Y)')
imap_server.select()
result, data = imap_server.search(None, search_text)
for num in data[0].split():
try:
# Delete message
imap_server.store(num, '+FLAGS', '\\Deleted')
except Exception:
_logger.exception('Failed to remove mail from %s server %s.',
server.type, server.name)
failed += 1
count += 1
_logger.info("Removed %d email(s) on %s server %s; "
"%d succeeded, %d failed.", count, server.type,
server.name, (count - failed), failed)
@api.multi
def fetch_mail(self):
""" Called before the fetch, in order to clean up
right before retrieving emails. """
context = self.env.context.copy()
context['fetchmail_cron_running'] = True
for server in self:
_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':
try:
imap_server = server.connect()
if server.cleanup_days > 0:
self._cleanup_fetchmail_server(server, imap_server)
if server.purge_days > 0:
self._purge_fetchmail_server(server, imap_server)
# Do the final cleanup: delete all messages
# flagged as deleted
imap_server.expunge()
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()