[ADD] make retrieval configurable per folder; use msgid to exclude
duplicates; don't break existing configurationspull/2800/head
parent
38296f3e65
commit
cfe406a223
|
@ -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>
|
Loading…
Reference in New Issue