Browse Source
[ADD] make retrieval configurable per folder; use msgid to exclude
[ADD] make retrieval configurable per folder; use msgid to exclude
duplicates; don't break existing configurationspull/78/head
Holger Brunn
12 years ago
14 changed files with 823 additions and 0 deletions
-
25fetchmail_attach_from_folder/__init__.py
-
45fetchmail_attach_from_folder/__openerp__.py
-
26fetchmail_attach_from_folder/match_algorithm/__init__.py
-
43fetchmail_attach_from_folder/match_algorithm/base.py
-
44fetchmail_attach_from_folder/match_algorithm/email_domain.py
-
52fetchmail_attach_from_folder/match_algorithm/email_exact.py
-
48fetchmail_attach_from_folder/match_algorithm/openerp_standard.py
-
24fetchmail_attach_from_folder/model/__init__.py
-
224fetchmail_attach_from_folder/model/fetchmail_server.py
-
86fetchmail_attach_from_folder/model/fetchmail_server_folder.py
-
48fetchmail_attach_from_folder/view/fetchmail_server.xml
-
23fetchmail_attach_from_folder/wizard/__init__.py
-
109fetchmail_attach_from_folder/wizard/attach_mail_manually.py
-
26fetchmail_attach_from_folder/wizard/attach_mail_manually.xml
@ -0,0 +1,25 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
|||
# All Rights Reserved |
|||
# |
|||
# 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 match_algorithm |
|||
import model |
|||
import wizard |
@ -0,0 +1,45 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
|||
# All Rights Reserved |
|||
# |
|||
# 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': 'Attach mails in an IMAP folder to existing objects', |
|||
'version': '1.0', |
|||
'description': """ |
|||
Adds the possibility to attach emails from a certain IMAP folder to objects, |
|||
ie partners. Matching is done via several algorithms, ie email address. |
|||
|
|||
This gives a simple possibility to archive emails in OpenERP without a mail |
|||
client integration. |
|||
""", |
|||
'author': 'Therp BV', |
|||
'website': 'http://www.therp.nl', |
|||
"category": "Tools", |
|||
"depends": ['fetchmail'], |
|||
'data': [ |
|||
'view/fetchmail_server.xml', |
|||
'wizard/attach_mail_manually.xml', |
|||
], |
|||
'js': [], |
|||
'installable': True, |
|||
'active': False, |
|||
'certificate': '', |
|||
} |
@ -0,0 +1,26 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
|||
# All Rights Reserved |
|||
# |
|||
# 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 base |
|||
import email_exact |
|||
import email_domain |
|||
import openerp_standard |
@ -0,0 +1,43 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
|||
# All Rights Reserved |
|||
# |
|||
# 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/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
class base(object): |
|||
name = None |
|||
'''Name shown to the user''' |
|||
|
|||
required_fields = [] |
|||
'''Fields on fetchmail_server folder that are required for this algorithm''' |
|||
|
|||
readonly_fields = [] |
|||
'''Fields on fetchmail_server folder that are readonly for this algorithm''' |
|||
|
|||
|
|||
def search_matches(self, cr, uid, conf, mail_message, mail_message_org): |
|||
'''Returns ids found for model with mail_message''' |
|||
return [] |
|||
|
|||
def handle_match( |
|||
self, cr, uid, connection, object_id, folder, |
|||
mail_message, mail_message_org, msgid, context=None): |
|||
'''Do whatever it takes to handle a match''' |
|||
return folder.server_id.attach_mail(connection, object_id, folder, |
|||
mail_message, msgid) |
@ -0,0 +1,44 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
|||
# All Rights Reserved |
|||
# |
|||
# 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/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
from email_exact import email_exact |
|||
|
|||
class email_domain(email_exact): |
|||
'''Search objects by domain name of email address. |
|||
Beware of match_first here, this is most likely to ge it wrong (gmail...)''' |
|||
name = 'Domain of email address' |
|||
|
|||
def search_matches(self, cr, uid, conf, mail_message, mail_message_org): |
|||
ids = super(email_domain, self).search_matches( |
|||
cr, uid, conf, mail_message, mail_message_org) |
|||
if not ids: |
|||
domains = [] |
|||
for addr in self._get_mailaddresses(conf, mail_message): |
|||
domains.append(addr.split('@')[-1]) |
|||
ids = conf.pool.get(conf.model_id.model).search( |
|||
cr, uid, |
|||
self._get_mailaddress_search_domain( |
|||
conf, mail_message, |
|||
operator='like', |
|||
values=['%@'+domain for domain in set(domains)]), |
|||
order=conf.model_order) |
|||
return ids |
@ -0,0 +1,52 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
|||
# All Rights Reserved |
|||
# |
|||
# 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/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
from base import base |
|||
from openerp.tools.safe_eval import safe_eval |
|||
from openerp.addons.mail.mail_message import to_email |
|||
|
|||
class email_exact(base): |
|||
name = 'Exact mailadress' |
|||
required_fields = ['model_field', 'mail_field'] |
|||
|
|||
def _get_mailaddresses(self, conf, mail_message): |
|||
mailaddresses = [] |
|||
fields = conf.mail_field.split(',') |
|||
for field in fields: |
|||
mailaddresses+=to_email(mail_message[field]) |
|||
return mailaddresses |
|||
|
|||
def _get_mailaddress_search_domain( |
|||
self, conf, mail_message, operator='=', values=None): |
|||
mailaddresses = values or self._get_mailaddresses( |
|||
conf, mail_message) |
|||
if not mailaddresses: |
|||
return [(0,'=',1)] |
|||
return ((['|'] * (len(mailaddresses) - 1)) + [ |
|||
(conf.model_field, operator, addr) for addr in mailaddresses] + |
|||
safe_eval(conf.domain or '[]')) |
|||
|
|||
def search_matches(self, cr, uid, conf, mail_message, mail_message_org): |
|||
return conf.pool.get(conf.model_id.model).search( |
|||
cr, uid, |
|||
self._get_mailaddress_search_domain(conf, mail_message), |
|||
order=conf.model_order) |
@ -0,0 +1,48 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
|||
# All Rights Reserved |
|||
# |
|||
# 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/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
from base import base |
|||
from openerp.tools.safe_eval import safe_eval |
|||
|
|||
class openerp_standard(base): |
|||
name = 'OpenERP standard' |
|||
readonly_fields = ['model_field', 'mail_field', 'match_first', 'domain', |
|||
'model_order', 'flag_nonmatching'] |
|||
|
|||
def search_matches(self, cr, uid, conf, mail_message, mail_message_org): |
|||
'''Always match. Duplicates will be fished out by message_id''' |
|||
return [True] |
|||
|
|||
def handle_match( |
|||
self, cr, uid, connection, object_id, folder, |
|||
mail_message, mail_message_org, msgid, context): |
|||
result = folder.pool.get('mail.thread').message_process( |
|||
cr, uid, |
|||
folder.model_id.model, mail_message_org, |
|||
save_original=folder.server_id.original, |
|||
strip_attachments=(not folder.server_id.attach), |
|||
context=context) |
|||
|
|||
if folder.delete_matching: |
|||
connection.store(msgid, '+FLAGS', '\\DELETED') |
|||
|
|||
return result |
@ -0,0 +1,24 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
|||
# All Rights Reserved |
|||
# |
|||
# 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 fetchmail_server |
|||
import fetchmail_server_folder |
@ -0,0 +1,224 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
|||
# All Rights Reserved |
|||
# |
|||
# 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 simplejson |
|||
from lxml import etree |
|||
from openerp.osv.orm import Model, except_orm, browse_null |
|||
from openerp.tools.translate import _ |
|||
from openerp.osv import fields |
|||
from openerp.addons.fetchmail.fetchmail import logger |
|||
from openerp.tools.misc import UnquoteEvalContext |
|||
from openerp.tools.safe_eval import safe_eval |
|||
|
|||
class fetchmail_server(Model): |
|||
_inherit = 'fetchmail.server' |
|||
|
|||
_columns = { |
|||
'folder_ids': fields.one2many( |
|||
'fetchmail.server.folder', 'server_id', 'Folders'), |
|||
} |
|||
|
|||
_defaults = { |
|||
'type': 'imap', |
|||
} |
|||
|
|||
def __init__(self, pool, cr): |
|||
self._columns['object_id'].required=False |
|||
return super(fetchmail_server, self).__init__(pool, cr) |
|||
|
|||
def onchange_server_type( |
|||
self, cr, uid, ids, server_type=False, ssl=False, |
|||
object_id=False): |
|||
retval = super( |
|||
fetchmail_server, self).onchange_server_type(cr, uid, |
|||
ids, server_type, ssl, object_id) |
|||
retval['value']['state']='draft' |
|||
return retval |
|||
|
|||
def fetch_mail(self, cr, uid, ids, context=None): |
|||
if context is None: |
|||
context = {} |
|||
|
|||
check_original = [] |
|||
|
|||
for this in self.browse(cr, uid, ids, context): |
|||
if this.object_id: |
|||
check_original.append(this.id) |
|||
|
|||
context.update( |
|||
{ |
|||
'fetchmail_server_id': this.id, |
|||
'server_type': this.type |
|||
}) |
|||
|
|||
connection = this.connect() |
|||
for folder in this.folder_ids: |
|||
logger.info('start checking for emails in %s server %s', |
|||
folder.path, this.name) |
|||
matcher = folder.get_algorithm() |
|||
|
|||
if connection.select(folder.path)[0] != 'OK': |
|||
logger.error( |
|||
'Could not open mailbox %s on %s' % ( |
|||
folder.path, this.server)) |
|||
connection.select() |
|||
continue |
|||
result, msgids = connection.search(None, 'UNDELETED') |
|||
if result != 'OK': |
|||
logger.error( |
|||
'Could not search mailbox %s on %s' % ( |
|||
folder.path, this.server)) |
|||
continue |
|||
for msgid in msgids[0].split(): |
|||
result, msgdata = connection.fetch(msgid, '(RFC822)') |
|||
if result != 'OK': |
|||
logger.error( |
|||
'Could not fetch %s in %s on %s' % ( |
|||
msgid, folder.path, this.server)) |
|||
continue |
|||
|
|||
mail_message = self.pool.get('mail.message').parse_message( |
|||
msgdata[0][1], this.original) |
|||
|
|||
if self.pool.get('mail.message').search(cr, uid, [ |
|||
('message_id','=',mail_message['message-id'])]): |
|||
continue |
|||
|
|||
found_ids = matcher.search_matches( |
|||
cr, uid, folder, |
|||
mail_message, msgdata[0][1]) |
|||
|
|||
if found_ids and (len(found_ids) == 1 or |
|||
folder.match_first): |
|||
try: |
|||
matcher.handle_match( |
|||
cr, uid, connection, |
|||
found_ids[0], folder, mail_message, |
|||
msgdata[0][1], msgid, context) |
|||
cr.commit() |
|||
except Exception, e: |
|||
cr.rollback() |
|||
logger.exception( |
|||
"Failed to fetch mail %s from %s", |
|||
msgid, this.name) |
|||
elif folder.flag_nonmatching: |
|||
connection.store(msgid, '+FLAGS', '\\FLAGGED') |
|||
connection.close() |
|||
|
|||
return super(fetchmail_server, self).fetch_mail( |
|||
cr, uid, check_original, context) |
|||
|
|||
def attach_mail( |
|||
self, cr, uid, ids, connection, object_id, folder, |
|||
mail_message, msgid, context=None): |
|||
for this in self.browse(cr, uid, ids, context): |
|||
partner_id = None |
|||
if folder.model_id.model == 'res.partner': |
|||
partner_id = object_id |
|||
if self.pool.get(folder.model_id.model)._columns.\ |
|||
has_key('partner_id'): |
|||
partner_id=self.pool.get( |
|||
folder.model_id.model).browse( |
|||
cr, uid, object_id, context |
|||
).partner_id.id |
|||
|
|||
self.pool.get('mail.message').create( |
|||
cr, uid, |
|||
{ |
|||
'partner_id': partner_id, |
|||
'model': folder.model_id.model, |
|||
'res_id': object_id, |
|||
'body_text': mail_message.get('body'), |
|||
'body_html': mail_message.get('body_html'), |
|||
'subject': mail_message.get('subject'), |
|||
'email_to': mail_message.get('to'), |
|||
'email_from': mail_message.get('from'), |
|||
'email_cc': mail_message.get('cc'), |
|||
'reply_to': mail_message.get('reply'), |
|||
'date': mail_message.get('date'), |
|||
'message_id': mail_message.get('message-id'), |
|||
'subtype': mail_message.get('subtype'), |
|||
'headers': mail_message.get('headers'), |
|||
}, |
|||
context) |
|||
if this.attach: |
|||
#TODO: create attachments |
|||
pass |
|||
if folder.delete_matching: |
|||
connection.store(msgid, '+FLAGS', '\\DELETED') |
|||
|
|||
def button_confirm_login(self, cr, uid, ids, context=None): |
|||
retval = super(fetchmail_server, self).button_confirm_login(cr, uid, |
|||
ids, context) |
|||
|
|||
for this in self.browse(cr, uid, ids, context): |
|||
this.write({'state': 'draft'}) |
|||
connection = this.connect() |
|||
connection.select() |
|||
for folder in this.folder_ids: |
|||
if connection.select(folder.path)[0] != 'OK': |
|||
raise except_orm( |
|||
_('Error'), _('Mailbox %s not found!') % |
|||
folder.path) |
|||
folder.get_algorithm().search_matches( |
|||
cr, uid, folder, browse_null(), '') |
|||
connection.close() |
|||
this.write({'state': 'done'}) |
|||
|
|||
return retval |
|||
|
|||
def fields_view_get(self, cr, user, view_id=None, view_type='form', |
|||
context=None, toolbar=False, submenu=False): |
|||
result = super(fetchmail_server, self).fields_view_get( |
|||
cr, user, view_id, view_type, context, toolbar, submenu) |
|||
|
|||
if view_type == 'form': |
|||
view = etree.fromstring( |
|||
result['fields']['folder_ids']['views']['tree']['arch']) |
|||
modifiers={} |
|||
docstr='' |
|||
for algorithm in self.pool.get('fetchmail.server.folder')\ |
|||
._get_match_algorithms().itervalues(): |
|||
for modifier in ['required', 'readonly']: |
|||
for field in getattr(algorithm, modifier + '_fields'): |
|||
modifiers.setdefault(field, {}) |
|||
modifiers[field].setdefault(modifier, []) |
|||
if modifiers[field][modifier]: |
|||
modifiers[field][modifier].insert(0, '|') |
|||
modifiers[field][modifier].append( |
|||
("match_algorithm","==",algorithm.__name__)) |
|||
docstr+=_(algorithm.__doc__) or '' |
|||
|
|||
for field in view: |
|||
if field.tag == 'field' and field.get('name') in modifiers: |
|||
field.set('modifiers', simplejson.dumps( |
|||
dict( |
|||
eval(field.attrib['modifiers'], |
|||
UnquoteEvalContext({})), |
|||
**modifiers[field.attrib['name']]))) |
|||
if (field.tag == 'field' and |
|||
field.get('name') == 'match_algorithm'): |
|||
field.set('help', docstr) |
|||
result['fields']['folder_ids']['views']['tree']['arch'] = \ |
|||
etree.tostring(view) |
|||
|
|||
return result |
@ -0,0 +1,86 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
|||
# All Rights Reserved |
|||
# |
|||
# 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/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
from openerp.osv import fields |
|||
from openerp.osv.orm import Model |
|||
from .. import match_algorithm |
|||
|
|||
class fetchmail_server_folder(Model): |
|||
_name = 'fetchmail.server.folder' |
|||
_rec_name = 'path' |
|||
|
|||
def _get_match_algorithms(self): |
|||
def get_all_subclasses(cls): |
|||
return cls.__subclasses__() + [subsub |
|||
for sub in cls.__subclasses__() |
|||
for subsub in get_all_subclasses(sub)] |
|||
return dict([(cls.__name__, cls) for cls in get_all_subclasses( |
|||
match_algorithm.base.base)]) |
|||
|
|||
def _get_match_algorithms_sel(self, cr, uid, context=None): |
|||
algorithms=[] |
|||
for cls in self._get_match_algorithms().itervalues(): |
|||
algorithms.append((cls.__name__, cls.name)) |
|||
return tuple(sorted(algorithms, lambda a, b: cmp(a[0], b[0]))) |
|||
|
|||
_columns = { |
|||
'sequence': fields.integer('Sequence'), |
|||
'path': fields.char( |
|||
'Path', size=256, help='The path to your mail ' |
|||
'folder. Typically would be something like \'INBOX.myfolder\'', |
|||
required=True), |
|||
'model_id': fields.many2one('ir.model', 'Model', required=True), |
|||
'model_field': fields.char('Field (model)', size=128), |
|||
'model_order': fields.char('Order (model)', size=128), |
|||
'match_algorithm': fields.selection( |
|||
_get_match_algorithms_sel, |
|||
'Match algorithm', required=True, translate=True), |
|||
'mail_field': fields.char('Field (email)', size=128), |
|||
'server_id': fields.many2one('fetchmail.server', 'Server'), |
|||
'delete_matching': fields.boolean('Delete matches'), |
|||
'flag_nonmatching': fields.boolean('Flag nonmatching'), |
|||
'match_first': fields.boolean('Use 1st match'), |
|||
'domain': fields.char( |
|||
'Domain', size=128, help='Fill in a search ' |
|||
'filter to narrow down objects to match') |
|||
} |
|||
|
|||
_defaults = { |
|||
'flag_nonmatching': True, |
|||
} |
|||
|
|||
def get_algorithm(self, cr, uid, ids, context=None): |
|||
for this in self.browse(cr, uid, ids, context): |
|||
return self._get_match_algorithms()[this.match_algorithm]() |
|||
|
|||
def button_attach_mail_manually(self, cr, uid, ids, context=None): |
|||
for this in self.browse(cr, uid, ids, context): |
|||
context.update({'default_folder_id': this.id}) |
|||
return { |
|||
'type': 'ir.actions.act_window', |
|||
'res_model': 'fetchmail.attach.mail.manually', |
|||
'target': 'new', |
|||
'context': context, |
|||
'view_type': 'form', |
|||
'view_mode': 'form', |
|||
} |
|||
|
@ -0,0 +1,48 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
<record model="ir.ui.view" id="view_email_server_form"> |
|||
<field name="name">fetchmail.server.form</field> |
|||
<field name="model">fetchmail.server</field> |
|||
<field name="type">form</field> |
|||
<field name="inherit_id" ref="fetchmail.view_email_server_form" /> |
|||
<field name="arch" type="xml"> |
|||
<data> |
|||
<field name="object_id" position="attributes"> |
|||
<attribute name="attrs">{'required': [('type', '!=', 'imap')]}</attribute> |
|||
</field> |
|||
<xpath expr="//page[@string='Server & Login']/group[3]" position="after"> |
|||
<group col="2" colspan="2" attrs="{'invisible': [('type','!=','imap')]}"> |
|||
<separator string="Folders to monitor" colspan="2"/> |
|||
<field |
|||
name="folder_ids" |
|||
nolabel="1" |
|||
colspan="2" |
|||
on_change="onchange_server_type(type, is_ssl, object_id)"> |
|||
<tree editable="bottom"> |
|||
<field name="sequence" invisible="1" /> |
|||
<field name="path" /> |
|||
<field name="model_id" /> |
|||
<field name="model_field" /> |
|||
<field name="match_algorithm" /> |
|||
<field name="mail_field" /> |
|||
<field name="delete_matching" /> |
|||
<field name="flag_nonmatching" /> |
|||
<field name="match_first" /> |
|||
<field |
|||
name="model_order" |
|||
attrs="{'readonly': [('match_first','==',False)], 'required': [('match_first','==',True)]}" /> |
|||
<field name="domain" /> |
|||
<button type="object" |
|||
name="button_attach_mail_manually" |
|||
string="Attach mail manually" |
|||
icon="gtk-redo" /> |
|||
</tree> |
|||
</field> |
|||
</group> |
|||
</xpath> |
|||
</data> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</openerp> |
@ -0,0 +1,23 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
|||
# All Rights Reserved |
|||
# |
|||
# 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 attach_mail_manually |
@ -0,0 +1,109 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
|||
# All Rights Reserved |
|||
# |
|||
# 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/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
from openerp.osv import fields |
|||
from openerp.osv.orm import TransientModel |
|||
|
|||
|
|||
class attach_mail_manually(TransientModel): |
|||
_name = 'fetchmail.attach.mail.manually' |
|||
|
|||
_columns = { |
|||
'folder_id': fields.many2one('fetchmail.server.folder', 'Folder', |
|||
readonly=True), |
|||
'mail_ids': fields.one2many( |
|||
'fetchmail.attach.mail.manually.mail', 'wizard_id', 'Emails'), |
|||
} |
|||
|
|||
def default_get(self, cr, uid, fields_list, context=None): |
|||
if context is None: |
|||
context = {} |
|||
|
|||
defaults = super(attach_mail_manually, self).default_get(cr, uid, |
|||
fields_list, context) |
|||
|
|||
for folder in self.pool.get('fetchmail.server.folder').browse(cr, uid, |
|||
[context.get('default_folder_id')], context): |
|||
defaults['mail_ids']=[] |
|||
connection = folder.server_id.connect() |
|||
connection.select(folder.path) |
|||
result, msgids = connection.search(None, 'UNDELETED') |
|||
if result != 'OK': |
|||
logger.error('Could not search mailbox %s on %s' % ( |
|||
folder.path, this.server)) |
|||
continue |
|||
attach_mail_manually_mail._columns['object_id'].selection=[ |
|||
(folder.model_id.model, folder.model_id.name)] |
|||
for msgid in msgids[0].split(): |
|||
result, msgdata = connection.fetch(msgid, '(RFC822)') |
|||
if result != 'OK': |
|||
logger.error('Could not fetch %s in %s on %s' % ( |
|||
msgid, folder.path, this.server)) |
|||
continue |
|||
mail_message = self.pool.get('mail.message').parse_message( |
|||
msgdata[0][1]) |
|||
defaults['mail_ids'].append((0, 0, { |
|||
'msgid': msgid, |
|||
'subject': mail_message.get('subject', ''), |
|||
'date': mail_message.get('date', ''), |
|||
'object_id': folder.model_id.model+',False' |
|||
})) |
|||
connection.close() |
|||
|
|||
return defaults |
|||
|
|||
def attach_mails(self, cr, uid, ids, context=None): |
|||
for this in self.browse(cr, uid, ids, context): |
|||
for mail in this.mail_ids: |
|||
connection = this.folder_id.server_id.connect() |
|||
connection.select(this.folder_id.path) |
|||
result, msgdata = connection.fetch(mail.msgid, '(RFC822)') |
|||
if result != 'OK': |
|||
logger.error('Could not fetch %s in %s on %s' % ( |
|||
msgid, folder.path, this.server)) |
|||
continue |
|||
|
|||
mail_message = self.pool.get('mail.message').parse_message( |
|||
msgdata[0][1], this.folder_id.server_id.original) |
|||
|
|||
this.folder_id.server_id.attach_mail(connection, |
|||
mail.object_id.id, this.folder_id, mail_message, |
|||
mail.msgid) |
|||
connection.close() |
|||
return {'type': 'ir.actions.act_window_close'} |
|||
|
|||
class attach_mail_manually_mail(TransientModel): |
|||
_name = 'fetchmail.attach.mail.manually.mail' |
|||
|
|||
_columns = { |
|||
'wizard_id': fields.many2one('fetchmail.attach.mail.manually', |
|||
readonly=True), |
|||
'msgid': fields.char('Message id', size=16, readonly=True), |
|||
'subject': fields.char('Subject', size=128, readonly=True), |
|||
'date': fields.datetime('Date', readonly=True), |
|||
'object_id': fields.reference('Object', |
|||
selection=lambda self, cr, uid, context: |
|||
[(m.model, m.name) for m in |
|||
self.pool.get('ir.model').browse(cr, uid, |
|||
self.pool.get('ir.model').search(cr, uid, []), |
|||
context)], size=128), |
|||
} |
@ -0,0 +1,26 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
<record model="ir.ui.view" id="view_attach_mail_manually"> |
|||
<field name="name">fetchmail.attach.mail.manually</field> |
|||
<field name="model">fetchmail.attach.mail.manually</field> |
|||
<field name="type">form</field> |
|||
<field name="arch" type="xml"> |
|||
<form col="4"> |
|||
<field name="folder_id" colspan="4" /> |
|||
<field name="mail_ids" nolabel="1" colspan="4"> |
|||
<tree editable="top"> |
|||
<field name="subject" /> |
|||
<field name="date" /> |
|||
<field name="object_id" /> |
|||
</tree> |
|||
</field> |
|||
<label string="" /> |
|||
<label string="" /> |
|||
<button special="cancel" string="Cancel" icon="gtk-cancel" /> |
|||
<button string="Save" type="object" name="attach_mails" icon="gtk-ok" /> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue