Browse Source

[REVERT] merged and pushed on 7.0 instead of 6.1 branch...

pull/2/head
Alexandre Fayolle 12 years ago
parent
commit
29812578b7
  1. 25
      fetchmail_attach_from_folder/__init__.py
  2. 45
      fetchmail_attach_from_folder/__openerp__.py
  3. 26
      fetchmail_attach_from_folder/match_algorithm/__init__.py
  4. 43
      fetchmail_attach_from_folder/match_algorithm/base.py
  5. 44
      fetchmail_attach_from_folder/match_algorithm/email_domain.py
  6. 56
      fetchmail_attach_from_folder/match_algorithm/email_exact.py
  7. 51
      fetchmail_attach_from_folder/match_algorithm/openerp_standard.py
  8. 24
      fetchmail_attach_from_folder/model/__init__.py
  9. 287
      fetchmail_attach_from_folder/model/fetchmail_server.py
  10. 120
      fetchmail_attach_from_folder/model/fetchmail_server_folder.py
  11. 58
      fetchmail_attach_from_folder/view/fetchmail_server.xml
  12. 23
      fetchmail_attach_from_folder/wizard/__init__.py
  13. 110
      fetchmail_attach_from_folder/wizard/attach_mail_manually.py
  14. 26
      fetchmail_attach_from_folder/wizard/attach_mail_manually.xml
  15. 22
      mail_client_view/__init__.py
  16. 48
      mail_client_view/__openerp__.py
  17. 1
      mail_client_view/model/__init__.py
  18. 39
      mail_client_view/model/mail_message.py
  19. 11
      mail_client_view/view/mail_user_menu.xml
  20. 98
      mail_client_view/view/mail_user_view.xml

25
fetchmail_attach_from_folder/__init__.py

@ -1,25 +0,0 @@
# -*- 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

45
fetchmail_attach_from_folder/__openerp__.py

@ -1,45 +0,0 @@
# -*- 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': '',
}

26
fetchmail_attach_from_folder/match_algorithm/__init__.py

@ -1,26 +0,0 @@
# -*- 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

43
fetchmail_attach_from_folder/match_algorithm/base.py

@ -1,43 +0,0 @@
# -*- 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)

44
fetchmail_attach_from_folder/match_algorithm/email_domain.py

@ -1,44 +0,0 @@
# -*- 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 get 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

56
fetchmail_attach_from_folder/match_algorithm/email_exact.py

@ -1,56 +0,0 @@
# -*- 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):
'''Search for exactly the mailadress as noted in the email'''
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:
if field in mail_message:
mailaddresses += to_email(mail_message[field])
return [ addr.lower() for addr in 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)]
search_domain = ((['|'] * (len(mailaddresses) - 1)) + [
(conf.model_field, operator, addr) for addr in mailaddresses] +
safe_eval(conf.domain or '[]'))
return search_domain
def search_matches(self, cr, uid, conf, mail_message, mail_message_org):
conf_model = conf.pool.get(conf.model_id.model)
search_domain = self._get_mailaddress_search_domain(conf, mail_message)
return conf_model.search(
cr, uid, search_domain, order=conf.model_order)

51
fetchmail_attach_from_folder/match_algorithm/openerp_standard.py

@ -1,51 +0,0 @@
# -*- 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):
'''No search at all. Use OpenERP's standard mechanism to attach mails to
mail.thread objects. Note that this algorithm always matches.'''
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]

24
fetchmail_attach_from_folder/model/__init__.py

@ -1,24 +0,0 @@
# -*- 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

287
fetchmail_attach_from_folder/model/fetchmail_server.py

@ -1,287 +0,0 @@
# -*- 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 base64
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:
this.handle_folder(connection, folder)
connection.close()
return super(fetchmail_server, self).fetch_mail(
cr, uid, check_original, context)
def handle_folder(self, cr, uid, ids, connection, folder, context=None):
'''Return ids of objects matched'''
matched_object_ids = []
for this in self.browse(cr, uid, ids, context=context):
logger.info('start checking for emails in %s server %s',
folder.path, this.name)
match_algorithm = 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 = this.get_msgids(connection)
if result != 'OK':
logger.error(
'Could not search mailbox %s on %s' % (
folder.path, this.server))
continue
for msgid in msgids[0].split():
matched_object_ids += this.apply_matching(
connection, folder, msgid, match_algorithm)
logger.info('finished checking for emails in %s server %s',
folder.path, this.name)
return matched_object_ids
def get_msgids(self, cr, uid, ids, connection, context=None):
'''Return imap ids of messages to process'''
return connection.search(None, 'UNDELETED')
def apply_matching(self, cr, uid, ids, connection, folder, msgid,
match_algorithm, context=None):
'''Return ids of objects matched'''
matched_object_ids = []
for this in self.browse(cr, uid, ids, context=context):
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 = match_algorithm.search_matches(
cr, uid, folder,
mail_message, msgdata[0][1])
if found_ids and (len(found_ids) == 1 or
folder.match_first):
try:
cr.execute('savepoint apply_matching')
match_algorithm.handle_match(
cr, uid, connection,
found_ids[0], folder, mail_message,
msgdata[0][1], msgid, context)
cr.execute('release savepoint apply_matching')
matched_object_ids += found_ids[:1]
except Exception, e:
cr.execute('rollback to savepoint apply_matching')
logger.exception(
"Failed to fetch mail %s from %s",
msgid, this.name)
elif folder.flag_nonmatching:
connection.store(msgid, '+FLAGS', '\\FLAGGED')
return matched_object_ids
def attach_mail(
self, cr, uid, ids, connection, object_id, folder,
mail_message, msgid, context=None):
'''Return ids of messages created'''
mail_message_ids = []
for this in self.browse(cr, uid, ids, context):
partner_id = None
if folder.model_id.model == 'res.partner':
partner_id = object_id
if 'partner_id' in self.pool.get(folder.model_id.model)._columns:
partner_id = self.pool.get(
folder.model_id.model).browse(
cr, uid, object_id, context
).partner_id.id
attachments=[]
if this.attach and mail_message.get('attachments'):
for attachment in mail_message['attachments']:
fname, fcontent = attachment
if isinstance(fcontent, unicode):
fcontent = fcontent.encode('utf-8')
data_attach = {
'name': fname,
'datas': base64.b64encode(str(fcontent)),
'datas_fname': fname,
'description': _('Mail attachment'),
'res_model': folder.model_id.model,
'res_id': object_id,
}
attachments.append(
self.pool.get('ir.attachment').create(
cr, uid, data_attach, context=context))
mail_message_ids.append(
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'),
'state': folder.msg_state,
'attachment_ids': [(6, 0, attachments)],
},
context))
if folder.delete_matching:
connection.store(msgid, '+FLAGS', '\\DELETED')
return mail_message_ids
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']['form']['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.name) + '\n' + _(algorithm.__doc__) + \
'\n\n'
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']['form']['arch'] = \
etree.tostring(view)
return result

120
fetchmail_attach_from_folder/model/fetchmail_server_folder.py

@ -1,120 +0,0 @@
# -*- 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))
algorithms.sort()
return algorithms
_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,
help='The model to attach emails to'),
'model_field': fields.char(
'Field (model)', size=128,
help='The field in your model that contains the field to match '
'against.\n'
'Examples:\n'
"'email' if your model is res.partner, or "
"'partner_id.email' if you're matching sale orders"),
'model_order': fields.char(
'Order (model)', size=128,
help='Fields to order by, this mostly useful in conjunction '
"with 'Use 1st match'"),
'match_algorithm': fields.selection(
_get_match_algorithms_sel,
'Match algorithm', required=True, translate=True,
help='The algorithm used to determine which object an email '
'matches.'),
'mail_field': fields.char(
'Field (email)', size=128,
help='The field in the email used for matching. Typically '
"this is 'to' or 'from'"),
'server_id': fields.many2one('fetchmail.server', 'Server'),
'delete_matching': fields.boolean(
'Delete matches',
help='Delete matched emails from server'),
'flag_nonmatching': fields.boolean(
'Flag nonmatching',
help="Flag emails in the server that don't match any object "
'in OpenERP'),
'match_first': fields.boolean(
'Use 1st match',
help='If there are multiple matches, use the first one. If '
'not checked, multiple matches count as no match at all'),
'domain': fields.char(
'Domain', size=128, help='Fill in a search '
'filter to narrow down objects to match'),
'msg_state': fields.selection(
[
('sent', 'Sent'),
('received', 'Received'),
],
'Message state',
help='The state messages fetched from this folder should be '
'assigned in OpenERP'),
}
_defaults = {
'flag_nonmatching': True,
'msg_state': 'received',
}
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',
}

58
fetchmail_attach_from_folder/view/fetchmail_server.xml

@ -1,58 +0,0 @@
<?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 &amp; 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>
<field name="sequence" invisible="1" />
<field name="path" />
<field name="model_id" />
<field name="model_field" />
<field name="match_algorithm" />
<field name="mail_field" />
</tree>
<form col="6">
<field name="path" />
<field name="model_id" />
<field name="model_field" />
<field name="match_algorithm" />
<field name="mail_field" />
<newline />
<field name="delete_matching" />
<field name="flag_nonmatching" />
<field name="match_first" />
<field name="msg_state" />
<field name="model_order" attrs="{'readonly': [('match_first','==',False)], 'required': [('match_first','==',True)]}" />
<field name="domain" />
<newline />
<label />
<label />
<label />
<label />
<label />
<button type="object" name="button_attach_mail_manually" string="Attach mail manually" icon="gtk-redo" />
</form>
</field>
</group>
</xpath>
</data>
</field>
</record>
</data>
</openerp>

23
fetchmail_attach_from_folder/wizard/__init__.py

@ -1,23 +0,0 @@
# -*- 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

110
fetchmail_attach_from_folder/wizard/attach_mail_manually.py

@ -1,110 +0,0 @@
# -*- 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,
'FLAGGED' if folder.flag_nonmatching else '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),
}

26
fetchmail_attach_from_folder/wizard/attach_mail_manually.xml

@ -1,26 +0,0 @@
<?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>

22
mail_client_view/__init__.py

@ -1,22 +0,0 @@
# -*- 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 model

48
mail_client_view/__openerp__.py

@ -1,48 +0,0 @@
# -*- 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': 'User email access',
'version': '6.1.r0025',
'description': '''
Adds a menu to the customer address book that enables ordinary users to
look at customer or other mail. Also adds an 'action needed' boolean to
mail messages, to quickly select all mails that still have to be acted on.
The action_needed flag will be shown to users in a tree view as a red
circle, no action needed will be green. In a form users either have the
button 'confirm action done' (if action needed), or the button 'set
action needed.
''',
'author': 'Therp BV',
'website': 'http://www.therp.nl',
'category': 'Tools',
'depends': ['mail'],
'data': [
'view/mail_user_menu.xml',
'view/mail_user_view.xml',
],
'js': [],
'installable': True,
'active': False,
'certificate': '',
}

1
mail_client_view/model/__init__.py

@ -1 +0,0 @@
import mail_message

39
mail_client_view/model/mail_message.py

@ -1,39 +0,0 @@
# -*- coding: UTF-8 -*-
'''
Created on 16 apr. 2013
@author: Therp BV
http://www.therp.nl
'''
from openerp.osv.orm import Model
from openerp.osv import fields
class mail_message(Model):
'''Extend mail_message with action_needed flag'''
_inherit = 'mail.message'
def set_action_needed_off(self, cr, user, ids, context=None):
self.write(cr, user, ids, {'action_needed': False}, context=context)
return True
def set_action_needed_on(self, cr, user, ids, context=None):
self.write(cr, user, ids, {'action_needed': True}, context=context)
return True
def create(self, cr, user, vals, context=None):
# Set newly received messages as needing action, unless an
# explicit value for action_needed has been passed.
if ((not 'action_needed' in vals)
and ('state' in vals) and (vals['state'] == 'received')):
vals['action_needed'] = True
mm_id = super(mail_message, self).create(
cr, user, vals, context=context)
return mm_id
_columns = {
'action_needed': fields.boolean('Action needed',
help='Action needed is True whenever a new mail is received, or'
' when a user flags a message as needing attention.'),
}

11
mail_client_view/view/mail_user_menu.xml

@ -1,11 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data>
<menuitem
id="mail_user_menu"
name="Messages"
parent="base.menu_address_book"
action="mail.action_view_mail_message"
sequence="80" />
</data>
</openerp>

98
mail_client_view/view/mail_user_view.xml

@ -1,98 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record
id="view_mail_action_needed_search"
model="ir.ui.view">
<field name="name">view_mail_action_needed_search</field>
<field name="model">mail.message</field>
<field
name="inherit_id"
ref="mail.view_email_message_search" />
<field
name="arch"
type="xml">
<data>
<field
name="email_from"
position="before">
<separator orientation="vertical"/>
<filter
icon="terp-check"
name="action"
string="Action needed"
domain="[('action_needed','=',True)]" />
</field>
</data>
</field>
</record>
<record
id="view_mail_action_needed_tree"
model="ir.ui.view">
<field name="name">view_mail_action_needed_tree</field>
<field name="model">mail.message</field>
<field
name="inherit_id"
ref="mail.view_email_message_tree" />
<field
name="arch"
type="xml">
<data>
<field
name="state"
position="after">
<field
name="action_needed"
invisible="True" />
<button
name="set_action_needed_off"
attrs="{'invisible': [('action_needed','=',False)]}"
string="confirm action done"
icon="gtk-no"
type="object" />
<button
name="set_action_needed_on"
attrs="{'invisible': [('action_needed','=',True)]}"
string="set action needed"
icon="gtk-yes"
type="object" />
</field>
</data>
</field>
</record>
<record
id="view_mail_action_needed_form"
model="ir.ui.view">
<field name="name">view_mail_action_needed_form</field>
<field name="model">mail.message</field>
<field
name="inherit_id"
ref="mail.view_email_message_form" />
<field
name="arch"
type="xml">
<data>
<button
name="%(mail.action_email_compose_message_wizard)d"
position="after">
<field
name="action_needed"
invisible="True" />
<button
name="set_action_needed_off"
attrs="{'invisible': [('action_needed','=',False)]}"
string="confirm action done"
icon="gtk-no"
type="object" />
<button
name="set_action_needed_on"
attrs="{'invisible': [('action_needed','=',True)]}"
string="set action needed"
icon="gtk-yes"
type="object" />
</button>
</data>
</field>
</record>
</data>
</openerp>
Loading…
Cancel
Save