From 3d9aa88557608a5eed8c96e84822968dfe187206 Mon Sep 17 00:00:00 2001
From: Holger Brunn
Date: Tue, 26 Mar 2013 11:38:56 +0100
Subject: [PATCH 01/79] [ADD] make retrieval configurable per folder; use msgid
to exclude duplicates; don't break existing configurations
---
fetchmail_from_imap_folder/__init__.py | 25 ++
fetchmail_from_imap_folder/__openerp__.py | 45 ++++
.../match_algorithm/__init__.py | 26 ++
.../match_algorithm/base.py | 43 ++++
.../match_algorithm/email_domain.py | 44 ++++
.../match_algorithm/email_exact.py | 52 ++++
.../match_algorithm/openerp_standard.py | 48 ++++
fetchmail_from_imap_folder/model/__init__.py | 24 ++
.../model/fetchmail_server.py | 224 ++++++++++++++++++
.../model/fetchmail_server_folder.py | 86 +++++++
.../view/fetchmail_server.xml | 48 ++++
fetchmail_from_imap_folder/wizard/__init__.py | 23 ++
.../wizard/attach_mail_manually.py | 109 +++++++++
.../wizard/attach_mail_manually.xml | 26 ++
14 files changed, 823 insertions(+)
create mode 100644 fetchmail_from_imap_folder/__init__.py
create mode 100644 fetchmail_from_imap_folder/__openerp__.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/__init__.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/base.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/email_domain.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/email_exact.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
create mode 100644 fetchmail_from_imap_folder/model/__init__.py
create mode 100644 fetchmail_from_imap_folder/model/fetchmail_server.py
create mode 100644 fetchmail_from_imap_folder/model/fetchmail_server_folder.py
create mode 100644 fetchmail_from_imap_folder/view/fetchmail_server.xml
create mode 100644 fetchmail_from_imap_folder/wizard/__init__.py
create mode 100644 fetchmail_from_imap_folder/wizard/attach_mail_manually.py
create mode 100644 fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
diff --git a/fetchmail_from_imap_folder/__init__.py b/fetchmail_from_imap_folder/__init__.py
new file mode 100644
index 000000000..1c91fe478
--- /dev/null
+++ b/fetchmail_from_imap_folder/__init__.py
@@ -0,0 +1,25 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+import match_algorithm
+import model
+import wizard
diff --git a/fetchmail_from_imap_folder/__openerp__.py b/fetchmail_from_imap_folder/__openerp__.py
new file mode 100644
index 000000000..6b0d58087
--- /dev/null
+++ b/fetchmail_from_imap_folder/__openerp__.py
@@ -0,0 +1,45 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+{
+ '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': '',
+}
diff --git a/fetchmail_from_imap_folder/match_algorithm/__init__.py b/fetchmail_from_imap_folder/match_algorithm/__init__.py
new file mode 100644
index 000000000..ff3610863
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/__init__.py
@@ -0,0 +1,26 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+import base
+import email_exact
+import email_domain
+import openerp_standard
diff --git a/fetchmail_from_imap_folder/match_algorithm/base.py b/fetchmail_from_imap_folder/match_algorithm/base.py
new file mode 100644
index 000000000..5116c929a
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/base.py
@@ -0,0 +1,43 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+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)
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_domain.py b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
new file mode 100644
index 000000000..ad86faacd
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
@@ -0,0 +1,44 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+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
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_exact.py b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
new file mode 100644
index 000000000..0e67e7222
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
@@ -0,0 +1,52 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+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)
diff --git a/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py b/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
new file mode 100644
index 000000000..ae8662ef2
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
@@ -0,0 +1,48 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+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
diff --git a/fetchmail_from_imap_folder/model/__init__.py b/fetchmail_from_imap_folder/model/__init__.py
new file mode 100644
index 000000000..d7e030949
--- /dev/null
+++ b/fetchmail_from_imap_folder/model/__init__.py
@@ -0,0 +1,24 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+import fetchmail_server
+import fetchmail_server_folder
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server.py b/fetchmail_from_imap_folder/model/fetchmail_server.py
new file mode 100644
index 000000000..e92bde8e9
--- /dev/null
+++ b/fetchmail_from_imap_folder/model/fetchmail_server.py
@@ -0,0 +1,224 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+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
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server_folder.py b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
new file mode 100644
index 000000000..6515b5528
--- /dev/null
+++ b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
@@ -0,0 +1,86 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+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',
+ }
+
diff --git a/fetchmail_from_imap_folder/view/fetchmail_server.xml b/fetchmail_from_imap_folder/view/fetchmail_server.xml
new file mode 100644
index 000000000..172166d45
--- /dev/null
+++ b/fetchmail_from_imap_folder/view/fetchmail_server.xml
@@ -0,0 +1,48 @@
+
+
+
+
+ fetchmail.server.form
+ fetchmail.server
+ form
+
+
+
+
+ {'required': [('type', '!=', 'imap')]}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fetchmail_from_imap_folder/wizard/__init__.py b/fetchmail_from_imap_folder/wizard/__init__.py
new file mode 100644
index 000000000..376a5b392
--- /dev/null
+++ b/fetchmail_from_imap_folder/wizard/__init__.py
@@ -0,0 +1,23 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+import attach_mail_manually
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
new file mode 100644
index 000000000..7b5c3d23d
--- /dev/null
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
@@ -0,0 +1,109 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+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),
+ }
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
new file mode 100644
index 000000000..437fda4df
--- /dev/null
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ fetchmail.attach.mail.manually
+ fetchmail.attach.mail.manually
+ form
+
+
+
+
+
+
From a8df45d528cbf2cbb78ae66ae219893443bd3f90 Mon Sep 17 00:00:00 2001
From: Holger Brunn
Date: Tue, 26 Mar 2013 12:22:16 +0100
Subject: [PATCH 02/79] [MRG]
lp:~therp-nl/therp-addons/fetchmail_attach_from_folder rev 89
---
.../match_algorithm/email_domain.py | 2 +-
.../match_algorithm/email_exact.py | 2 +
.../match_algorithm/openerp_standard.py | 3 ++
.../model/fetchmail_server.py | 7 ++--
.../model/fetchmail_server_folder.py | 40 +++++++++++++++----
.../view/fetchmail_server.xml | 17 +++++++-
.../wizard/attach_mail_manually.py | 3 +-
7 files changed, 60 insertions(+), 14 deletions(-)
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_domain.py b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
index ad86faacd..66ab66286 100644
--- a/fetchmail_from_imap_folder/match_algorithm/email_domain.py
+++ b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
@@ -24,7 +24,7 @@
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...)'''
+ 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):
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_exact.py b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
index 0e67e7222..db4871f65 100644
--- a/fetchmail_from_imap_folder/match_algorithm/email_exact.py
+++ b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
@@ -25,6 +25,8 @@
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']
diff --git a/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py b/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
index ae8662ef2..f4efcf89f 100644
--- a/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
+++ b/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
@@ -24,6 +24,9 @@
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']
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server.py b/fetchmail_from_imap_folder/model/fetchmail_server.py
index e92bde8e9..5f17b5bb0 100644
--- a/fetchmail_from_imap_folder/model/fetchmail_server.py
+++ b/fetchmail_from_imap_folder/model/fetchmail_server.py
@@ -193,7 +193,7 @@ def fields_view_get(self, cr, user, view_id=None, view_type='form',
if view_type == 'form':
view = etree.fromstring(
- result['fields']['folder_ids']['views']['tree']['arch'])
+ result['fields']['folder_ids']['views']['form']['arch'])
modifiers={}
docstr=''
for algorithm in self.pool.get('fetchmail.server.folder')\
@@ -206,7 +206,8 @@ def fields_view_get(self, cr, user, view_id=None, view_type='form',
modifiers[field][modifier].insert(0, '|')
modifiers[field][modifier].append(
("match_algorithm","==",algorithm.__name__))
- docstr+=_(algorithm.__doc__) or ''
+ docstr += _(algorithm.name) + '\n' + _(algorithm.__doc__) + \
+ '\n\n'
for field in view:
if field.tag == 'field' and field.get('name') in modifiers:
@@ -218,7 +219,7 @@ def fields_view_get(self, cr, user, view_id=None, view_type='form',
if (field.tag == 'field' and
field.get('name') == 'match_algorithm'):
field.set('help', docstr)
- result['fields']['folder_ids']['views']['tree']['arch'] = \
+ result['fields']['folder_ids']['views']['form']['arch'] = \
etree.tostring(view)
return result
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server_folder.py b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
index 6515b5528..0b8926c9b 100644
--- a/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
+++ b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
@@ -48,17 +48,41 @@ def _get_match_algorithms_sel(self, cr, uid, context=None):
'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),
+ '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),
- 'mail_field': fields.char('Field (email)', size=128),
+ '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'),
- 'flag_nonmatching': fields.boolean('Flag nonmatching'),
- 'match_first': fields.boolean('Use 1st match'),
+ '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')
diff --git a/fetchmail_from_imap_folder/view/fetchmail_server.xml b/fetchmail_from_imap_folder/view/fetchmail_server.xml
index 172166d45..043090cb4 100644
--- a/fetchmail_from_imap_folder/view/fetchmail_server.xml
+++ b/fetchmail_from_imap_folder/view/fetchmail_server.xml
@@ -19,7 +19,7 @@
nolabel="1"
colspan="2"
on_change="onchange_server_type(type, is_ssl, object_id)">
-
+
@@ -38,6 +38,21 @@
string="Attach mail manually"
icon="gtk-redo" />
+
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
index 7b5c3d23d..7d03e75d7 100644
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
@@ -46,7 +46,8 @@ def default_get(self, cr, uid, fields_list, context=None):
defaults['mail_ids']=[]
connection = folder.server_id.connect()
connection.select(folder.path)
- result, msgids = connection.search(None, 'UNDELETED')
+ 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))
From f65cd0c1cba1399c5d46ef4a5a334bf181881ebe Mon Sep 17 00:00:00 2001
From: Ronald Portier
Date: Thu, 4 Apr 2013 21:32:01 +0200
Subject: [PATCH 03/79] [IMP] - convert mailadresses to lowercase to increase
change for match - handle situation that optional mail address
componenents not present in mail - slight reorganisation of code to aid
debugging and made pep8 compliant as well.
---
.../match_algorithm/email_exact.py | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_exact.py b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
index db4871f65..b3fabaf5e 100644
--- a/fetchmail_from_imap_folder/match_algorithm/email_exact.py
+++ b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
@@ -34,21 +34,23 @@ 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
+ 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)]
- return ((['|'] * (len(mailaddresses) - 1)) + [
+ 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):
- return conf.pool.get(conf.model_id.model).search(
- cr, uid,
- self._get_mailaddress_search_domain(conf, mail_message),
- order=conf.model_order)
+ 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)
From 2a723f3e23b590d3249b55275596f1ba7406cc31 Mon Sep 17 00:00:00 2001
From: Holger Brunn
Date: Fri, 5 Apr 2013 14:00:35 +0200
Subject: [PATCH 04/79] [IMP] autopep8 [IMP] more efficient sorting of
algorithms [IMP] improve readability of help strings
---
.../model/fetchmail_server.py | 146 +++++++++---------
.../model/fetchmail_server_folder.py | 121 ++++++++-------
2 files changed, 135 insertions(+), 132 deletions(-)
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server.py b/fetchmail_from_imap_folder/model/fetchmail_server.py
index 5f17b5bb0..3448351e8 100644
--- a/fetchmail_from_imap_folder/model/fetchmail_server.py
+++ b/fetchmail_from_imap_folder/model/fetchmail_server.py
@@ -29,29 +29,31 @@
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'),
- }
+ 'folder_ids': fields.one2many(
+ 'fetchmail.server.folder', 'server_id', 'Folders'),
+ }
_defaults = {
- 'type': 'imap',
- }
+ 'type': 'imap',
+ }
def __init__(self, pool, cr):
- self._columns['object_id'].required=False
+ 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'
+ 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):
@@ -65,67 +67,67 @@ def fetch_mail(self, cr, uid, ids, context=None):
check_original.append(this.id)
context.update(
- {
- 'fetchmail_server_id': this.id,
- 'server_type': this.type
- })
+ {
+ '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)
+ 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))
+ '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))
+ '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))
+ '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)
+ msgdata[0][1], this.original)
if self.pool.get('mail.message').search(cr, uid, [
- ('message_id','=',mail_message['message-id'])]):
+ ('message_id', '=', mail_message['message-id'])]):
continue
found_ids = matcher.search_matches(
- cr, uid, folder,
- mail_message, msgdata[0][1])
+ cr, uid, folder,
+ mail_message, msgdata[0][1])
- if found_ids and (len(found_ids) == 1 or
- folder.match_first):
+ 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, 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)
+ "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)
+ cr, uid, check_original, context)
def attach_mail(
self, cr, uid, ids, connection, object_id, folder,
@@ -134,41 +136,41 @@ def attach_mail(
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
+ 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
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)
+ 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
+ # 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)
+ ids,
+ context)
for this in self.browse(cr, uid, ids, context):
this.write({'state': 'draft'})
@@ -177,25 +179,25 @@ def button_confirm_login(self, cr, uid, ids, context=None):
for folder in this.folder_ids:
if connection.select(folder.path)[0] != 'OK':
raise except_orm(
- _('Error'), _('Mailbox %s not found!') %
- folder.path)
+ _('Error'), _('Mailbox %s not found!') %
+ folder.path)
folder.get_algorithm().search_matches(
- cr, uid, folder, browse_null(), '')
+ 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',
+ 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)
+ 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=''
+ 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']:
@@ -205,21 +207,21 @@ def fields_view_get(self, cr, user, view_id=None, view_type='form',
if modifiers[field][modifier]:
modifiers[field][modifier].insert(0, '|')
modifiers[field][modifier].append(
- ("match_algorithm","==",algorithm.__name__))
+ ("match_algorithm", "==", algorithm.__name__))
docstr += _(algorithm.name) + '\n' + _(algorithm.__doc__) + \
- '\n\n'
+ '\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({})),
+ 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)
+ etree.tostring(view)
return result
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server_folder.py b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
index 0b8926c9b..1043a2e41 100644
--- a/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
+++ b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
@@ -18,79 +18,81 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
#
-##############################################################################
+########################################################################
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 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=[]
+ 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])))
+ 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')
- }
+ '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')
+ }
_defaults = {
- 'flag_nonmatching': True,
- }
+ 'flag_nonmatching': True,
+ }
def get_algorithm(self, cr, uid, ids, context=None):
for this in self.browse(cr, uid, ids, context):
@@ -100,11 +102,10 @@ 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',
- }
-
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'fetchmail.attach.mail.manually',
+ 'target': 'new',
+ 'context': context,
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ }
From 8bb3958f75c67a04c904f1648ad8296cde6b38b3 Mon Sep 17 00:00:00 2001
From: Holger Brunn
Date: Mon, 15 Apr 2013 14:23:05 +0200
Subject: [PATCH 05/79] [ADD] msg_state field for folders - set the state of
messages fetched from imap servers [IMP] clean up the folders' treeview
---
.../model/fetchmail_server.py | 1 +
.../model/fetchmail_server_folder.py | 11 ++++++++++-
.../view/fetchmail_server.xml | 17 ++++++-----------
3 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server.py b/fetchmail_from_imap_folder/model/fetchmail_server.py
index 3448351e8..9b9085042 100644
--- a/fetchmail_from_imap_folder/model/fetchmail_server.py
+++ b/fetchmail_from_imap_folder/model/fetchmail_server.py
@@ -159,6 +159,7 @@ def attach_mail(
'message_id': mail_message.get('message-id'),
'subtype': mail_message.get('subtype'),
'headers': mail_message.get('headers'),
+ 'state': folder.msg_state,
},
context)
if this.attach:
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server_folder.py b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
index 1043a2e41..ea0c07a7b 100644
--- a/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
+++ b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
@@ -87,11 +87,20 @@ def _get_match_algorithms_sel(self, cr, uid, context=None):
'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')
+ '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):
diff --git a/fetchmail_from_imap_folder/view/fetchmail_server.xml b/fetchmail_from_imap_folder/view/fetchmail_server.xml
index 043090cb4..1178eec0a 100644
--- a/fetchmail_from_imap_folder/view/fetchmail_server.xml
+++ b/fetchmail_from_imap_folder/view/fetchmail_server.xml
@@ -26,17 +26,6 @@
-
-
-
-
-
-
From 86db0b105082396e0d9ed58f3eca8240da0ebc6f Mon Sep 17 00:00:00 2001
From: Holger Brunn
Date: Mon, 15 Apr 2013 15:04:57 +0200
Subject: [PATCH 06/79] [IMP] refactored fetch_mail [IMP] also log when we're
done with one folder
---
.../model/fetchmail_server.py | 118 ++++++++++--------
1 file changed, 69 insertions(+), 49 deletions(-)
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server.py b/fetchmail_from_imap_folder/model/fetchmail_server.py
index 9b9085042..a18e95319 100644
--- a/fetchmail_from_imap_folder/model/fetchmail_server.py
+++ b/fetchmail_from_imap_folder/model/fetchmail_server.py
@@ -74,61 +74,81 @@ def fetch_mail(self, cr, uid, ids, context=None):
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()
+ this.handle_folder(connection, folder)
- 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 handle_folder(self, cr, uid, ids, connection, folder, context=None):
+ 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():
+ this.apply_matching(connection, folder, msgid, match_algorithm)
+
+ logger.info('finished checking for emails in %s server %s',
+ folder.path, this.name)
+
+ def get_msgids(self, cr, uid, ids, connection, context=None):
+ return connection.search(None, 'UNDELETED')
+
+ def apply_matching(self, cr, uid, ids, connection, folder, msgid,
+ match_algorithm, context=None):
+
+ 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:
+ match_algorithm.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')
+
def attach_mail(
self, cr, uid, ids, connection, object_id, folder,
mail_message, msgid, context=None):
From 9eca00125b31eadf28c7ea3c95aefdc2a6a805dc Mon Sep 17 00:00:00 2001
From: Holger Brunn
Date: Mon, 15 Apr 2013 15:22:42 +0200
Subject: [PATCH 07/79] [FIX] attach mail attachments to matched object in
non-OpenERP case
---
.../model/fetchmail_server.py | 24 ++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server.py b/fetchmail_from_imap_folder/model/fetchmail_server.py
index a18e95319..0d0c60730 100644
--- a/fetchmail_from_imap_folder/model/fetchmail_server.py
+++ b/fetchmail_from_imap_folder/model/fetchmail_server.py
@@ -20,6 +20,7 @@
#
##############################################################################
+import base64
import simplejson
from lxml import etree
from openerp.osv.orm import Model, except_orm, browse_null
@@ -162,6 +163,24 @@ def attach_mail(
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))
+
self.pool.get('mail.message').create(
cr, uid,
{
@@ -180,11 +199,10 @@ def attach_mail(
'subtype': mail_message.get('subtype'),
'headers': mail_message.get('headers'),
'state': folder.msg_state,
+ 'attachment_ids': [(6, 0, attachments)],
},
context)
- if this.attach:
- # TODO: create attachments
- pass
+
if folder.delete_matching:
connection.store(msgid, '+FLAGS', '\\DELETED')
From 5981f068523942a6ed8d0d783d4da13362621405 Mon Sep 17 00:00:00 2001
From: Holger Brunn
Date: Tue, 16 Apr 2013 10:12:57 +0200
Subject: [PATCH 08/79] [IMP] make fetch_mail's refactoring more useful by
returning the ids of mails creates/objects matched [ADD] preliminary
docstrings
---
.../match_algorithm/openerp_standard.py | 2 +-
.../model/fetchmail_server.py | 64 ++++++++++++-------
2 files changed, 43 insertions(+), 23 deletions(-)
diff --git a/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py b/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
index f4efcf89f..24a233d0d 100644
--- a/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
+++ b/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
@@ -48,4 +48,4 @@ def handle_match(
if folder.delete_matching:
connection.store(msgid, '+FLAGS', '\\DELETED')
- return result
+ return [result]
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server.py b/fetchmail_from_imap_folder/model/fetchmail_server.py
index 0d0c60730..c8d620f51 100644
--- a/fetchmail_from_imap_folder/model/fetchmail_server.py
+++ b/fetchmail_from_imap_folder/model/fetchmail_server.py
@@ -83,6 +83,10 @@ def fetch_mail(self, cr, uid, ids, context=None):
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)
@@ -103,16 +107,23 @@ def handle_folder(self, cr, uid, ids, connection, folder, context=None):
continue
for msgid in msgids[0].split():
- this.apply_matching(connection, folder, msgid, match_algorithm)
+ 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)')
@@ -142,6 +153,7 @@ def apply_matching(self, cr, uid, ids, connection, folder, msgid,
found_ids[0], folder, mail_message,
msgdata[0][1], msgid, context)
cr.commit()
+ matched_object_ids += found_ids[:1]
except Exception, e:
cr.rollback()
logger.exception(
@@ -150,9 +162,15 @@ def apply_matching(self, cr, uid, ids, connection, folder, msgid,
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':
@@ -181,30 +199,32 @@ def attach_mail(
self.pool.get('ir.attachment').create(
cr, uid, data_attach, context=context))
- 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)
+ 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,
From d959077b8faacb4069bbcc121e1c5e07c20d6eb8 Mon Sep 17 00:00:00 2001
From: Holger Brunn
Date: Thu, 18 Apr 2013 16:43:25 +0200
Subject: [PATCH 09/79] [FIX] don't rollback() transation, use savepoint. This
fixes concurrency issues with long running cron threads as rollback also
releases the lock
---
fetchmail_from_imap_folder/model/fetchmail_server.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server.py b/fetchmail_from_imap_folder/model/fetchmail_server.py
index c8d620f51..5efdf4754 100644
--- a/fetchmail_from_imap_folder/model/fetchmail_server.py
+++ b/fetchmail_from_imap_folder/model/fetchmail_server.py
@@ -148,14 +148,15 @@ def apply_matching(self, cr, uid, ids, connection, folder, msgid,
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.commit()
+ cr.execute('release savepoint apply_matching')
matched_object_ids += found_ids[:1]
except Exception, e:
- cr.rollback()
+ cr.execute('rollback to savepoint apply_matching')
logger.exception(
"Failed to fetch mail %s from %s",
msgid, this.name)
From 08b5795abfeb066aaa2842c6449182ce2230046c Mon Sep 17 00:00:00 2001
From: Alexandre Fayolle
Date: Fri, 26 Apr 2013 10:07:41 +0200
Subject: [PATCH 10/79] [REVERT] merged and pushed on 7.0 instead of 6.1
branch...
---
fetchmail_from_imap_folder/__init__.py | 25 --
fetchmail_from_imap_folder/__openerp__.py | 45 ---
.../match_algorithm/__init__.py | 26 --
.../match_algorithm/base.py | 43 ---
.../match_algorithm/email_domain.py | 44 ---
.../match_algorithm/email_exact.py | 56 ----
.../match_algorithm/openerp_standard.py | 51 ----
fetchmail_from_imap_folder/model/__init__.py | 24 --
.../model/fetchmail_server.py | 287 ------------------
.../model/fetchmail_server_folder.py | 120 --------
.../view/fetchmail_server.xml | 58 ----
fetchmail_from_imap_folder/wizard/__init__.py | 23 --
.../wizard/attach_mail_manually.py | 110 -------
.../wizard/attach_mail_manually.xml | 26 --
14 files changed, 938 deletions(-)
delete mode 100644 fetchmail_from_imap_folder/__init__.py
delete mode 100644 fetchmail_from_imap_folder/__openerp__.py
delete mode 100644 fetchmail_from_imap_folder/match_algorithm/__init__.py
delete mode 100644 fetchmail_from_imap_folder/match_algorithm/base.py
delete mode 100644 fetchmail_from_imap_folder/match_algorithm/email_domain.py
delete mode 100644 fetchmail_from_imap_folder/match_algorithm/email_exact.py
delete mode 100644 fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
delete mode 100644 fetchmail_from_imap_folder/model/__init__.py
delete mode 100644 fetchmail_from_imap_folder/model/fetchmail_server.py
delete mode 100644 fetchmail_from_imap_folder/model/fetchmail_server_folder.py
delete mode 100644 fetchmail_from_imap_folder/view/fetchmail_server.xml
delete mode 100644 fetchmail_from_imap_folder/wizard/__init__.py
delete mode 100644 fetchmail_from_imap_folder/wizard/attach_mail_manually.py
delete mode 100644 fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
diff --git a/fetchmail_from_imap_folder/__init__.py b/fetchmail_from_imap_folder/__init__.py
deleted file mode 100644
index 1c91fe478..000000000
--- a/fetchmail_from_imap_folder/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-import match_algorithm
-import model
-import wizard
diff --git a/fetchmail_from_imap_folder/__openerp__.py b/fetchmail_from_imap_folder/__openerp__.py
deleted file mode 100644
index 6b0d58087..000000000
--- a/fetchmail_from_imap_folder/__openerp__.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-{
- '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': '',
-}
diff --git a/fetchmail_from_imap_folder/match_algorithm/__init__.py b/fetchmail_from_imap_folder/match_algorithm/__init__.py
deleted file mode 100644
index ff3610863..000000000
--- a/fetchmail_from_imap_folder/match_algorithm/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-import base
-import email_exact
-import email_domain
-import openerp_standard
diff --git a/fetchmail_from_imap_folder/match_algorithm/base.py b/fetchmail_from_imap_folder/match_algorithm/base.py
deleted file mode 100644
index 5116c929a..000000000
--- a/fetchmail_from_imap_folder/match_algorithm/base.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-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)
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_domain.py b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
deleted file mode 100644
index 66ab66286..000000000
--- a/fetchmail_from_imap_folder/match_algorithm/email_domain.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-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
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_exact.py b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
deleted file mode 100644
index b3fabaf5e..000000000
--- a/fetchmail_from_imap_folder/match_algorithm/email_exact.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-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)
diff --git a/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py b/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
deleted file mode 100644
index 24a233d0d..000000000
--- a/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-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]
diff --git a/fetchmail_from_imap_folder/model/__init__.py b/fetchmail_from_imap_folder/model/__init__.py
deleted file mode 100644
index d7e030949..000000000
--- a/fetchmail_from_imap_folder/model/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-import fetchmail_server
-import fetchmail_server_folder
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server.py b/fetchmail_from_imap_folder/model/fetchmail_server.py
deleted file mode 100644
index 5efdf4754..000000000
--- a/fetchmail_from_imap_folder/model/fetchmail_server.py
+++ /dev/null
@@ -1,287 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-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
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server_folder.py b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
deleted file mode 100644
index ea0c07a7b..000000000
--- a/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-########################################################################
-
-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',
- }
diff --git a/fetchmail_from_imap_folder/view/fetchmail_server.xml b/fetchmail_from_imap_folder/view/fetchmail_server.xml
deleted file mode 100644
index 1178eec0a..000000000
--- a/fetchmail_from_imap_folder/view/fetchmail_server.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
- fetchmail.server.form
- fetchmail.server
- form
-
-
-
-
- {'required': [('type', '!=', 'imap')]}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/fetchmail_from_imap_folder/wizard/__init__.py b/fetchmail_from_imap_folder/wizard/__init__.py
deleted file mode 100644
index 376a5b392..000000000
--- a/fetchmail_from_imap_folder/wizard/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-import attach_mail_manually
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
deleted file mode 100644
index 7d03e75d7..000000000
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-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),
- }
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
deleted file mode 100644
index 437fda4df..000000000
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
- fetchmail.attach.mail.manually
- fetchmail.attach.mail.manually
- form
-
-
-
-
-
-
From 6ad58124d23e84b7c8f95a31a26e6cdc92e61132 Mon Sep 17 00:00:00 2001
From: Holger Brunn
Date: Thu, 16 Jan 2014 18:22:08 +0100
Subject: [PATCH 11/79] [ADD] port fetchmail_attach_from_folder to 7.0
---
fetchmail_from_imap_folder/__init__.py | 25 ++
fetchmail_from_imap_folder/__openerp__.py | 46 +++
.../match_algorithm/__init__.py | 26 ++
.../match_algorithm/base.py | 43 +++
.../match_algorithm/email_domain.py | 44 +++
.../match_algorithm/email_exact.py | 56 ++++
.../match_algorithm/openerp_standard.py | 51 ++++
fetchmail_from_imap_folder/model/__init__.py | 24 ++
.../model/fetchmail_server.py | 280 ++++++++++++++++++
.../model/fetchmail_server_folder.py | 120 ++++++++
.../security/ir.model.access.csv | 2 +
.../view/fetchmail_server.xml | 56 ++++
fetchmail_from_imap_folder/wizard/__init__.py | 23 ++
.../wizard/attach_mail_manually.py | 112 +++++++
.../wizard/attach_mail_manually.xml | 28 ++
15 files changed, 936 insertions(+)
create mode 100644 fetchmail_from_imap_folder/__init__.py
create mode 100644 fetchmail_from_imap_folder/__openerp__.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/__init__.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/base.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/email_domain.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/email_exact.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
create mode 100644 fetchmail_from_imap_folder/model/__init__.py
create mode 100644 fetchmail_from_imap_folder/model/fetchmail_server.py
create mode 100644 fetchmail_from_imap_folder/model/fetchmail_server_folder.py
create mode 100755 fetchmail_from_imap_folder/security/ir.model.access.csv
create mode 100644 fetchmail_from_imap_folder/view/fetchmail_server.xml
create mode 100644 fetchmail_from_imap_folder/wizard/__init__.py
create mode 100644 fetchmail_from_imap_folder/wizard/attach_mail_manually.py
create mode 100644 fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
diff --git a/fetchmail_from_imap_folder/__init__.py b/fetchmail_from_imap_folder/__init__.py
new file mode 100644
index 000000000..1c91fe478
--- /dev/null
+++ b/fetchmail_from_imap_folder/__init__.py
@@ -0,0 +1,25 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+import match_algorithm
+import model
+import wizard
diff --git a/fetchmail_from_imap_folder/__openerp__.py b/fetchmail_from_imap_folder/__openerp__.py
new file mode 100644
index 000000000..896701e4e
--- /dev/null
+++ b/fetchmail_from_imap_folder/__openerp__.py
@@ -0,0 +1,46 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+{
+ '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',
+ 'security/ir.model.access.csv',
+ ],
+ 'js': [],
+ 'installable': True,
+ 'active': False,
+ 'certificate': '',
+}
diff --git a/fetchmail_from_imap_folder/match_algorithm/__init__.py b/fetchmail_from_imap_folder/match_algorithm/__init__.py
new file mode 100644
index 000000000..ff3610863
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/__init__.py
@@ -0,0 +1,26 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+import base
+import email_exact
+import email_domain
+import openerp_standard
diff --git a/fetchmail_from_imap_folder/match_algorithm/base.py b/fetchmail_from_imap_folder/match_algorithm/base.py
new file mode 100644
index 000000000..5116c929a
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/base.py
@@ -0,0 +1,43 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+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)
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_domain.py b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
new file mode 100644
index 000000000..66ab66286
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
@@ -0,0 +1,44 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+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
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_exact.py b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
new file mode 100644
index 000000000..728c04461
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
@@ -0,0 +1,56 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+from base import base
+from openerp.tools.safe_eval import safe_eval
+from openerp.tools.mail import email_split
+
+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 += email_split(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)
diff --git a/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py b/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
new file mode 100644
index 000000000..24a233d0d
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
@@ -0,0 +1,51 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+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]
diff --git a/fetchmail_from_imap_folder/model/__init__.py b/fetchmail_from_imap_folder/model/__init__.py
new file mode 100644
index 000000000..d7e030949
--- /dev/null
+++ b/fetchmail_from_imap_folder/model/__init__.py
@@ -0,0 +1,24 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+import fetchmail_server
+import fetchmail_server_folder
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server.py b/fetchmail_from_imap_folder/model/fetchmail_server.py
new file mode 100644
index 000000000..814da703c
--- /dev/null
+++ b/fetchmail_from_imap_folder/model/fetchmail_server.py
@@ -0,0 +1,280 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+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 as 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.thread').message_parse(
+ cr, uid, msgdata[0][1], save_original=this.original,
+ context=context)
+
+ 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,
+ {
+ 'author_id': partner_id,
+ 'model': folder.model_id.model,
+ 'res_id': object_id,
+ 'type': 'email',
+ 'body': mail_message.get('body'),
+ 'subject': mail_message.get('subject'),
+ 'email_from': mail_message.get('from'),
+ 'date': mail_message.get('date'),
+ 'message_id': mail_message.get('message_id'),
+ '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)
+ 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
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server_folder.py b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
new file mode 100644
index 000000000..ea0c07a7b
--- /dev/null
+++ b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
@@ -0,0 +1,120 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+########################################################################
+
+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',
+ }
diff --git a/fetchmail_from_imap_folder/security/ir.model.access.csv b/fetchmail_from_imap_folder/security/ir.model.access.csv
new file mode 100755
index 000000000..c63f46bb8
--- /dev/null
+++ b/fetchmail_from_imap_folder/security/ir.model.access.csv
@@ -0,0 +1,2 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_model_fetchmail_server_folder,fetchmail.server.folder,model_fetchmail_server_folder,base.group_system,1,1,1,1
diff --git a/fetchmail_from_imap_folder/view/fetchmail_server.xml b/fetchmail_from_imap_folder/view/fetchmail_server.xml
new file mode 100644
index 000000000..6b16c2a58
--- /dev/null
+++ b/fetchmail_from_imap_folder/view/fetchmail_server.xml
@@ -0,0 +1,56 @@
+
+
+
+
+ fetchmail.server.form
+ fetchmail.server
+ form
+
+
+
+
+ {'required': [('type', '!=', 'imap')]}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fetchmail_from_imap_folder/wizard/__init__.py b/fetchmail_from_imap_folder/wizard/__init__.py
new file mode 100644
index 000000000..376a5b392
--- /dev/null
+++ b/fetchmail_from_imap_folder/wizard/__init__.py
@@ -0,0 +1,23 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+import attach_mail_manually
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
new file mode 100644
index 000000000..86fadbf62
--- /dev/null
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
@@ -0,0 +1,112 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+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.thread').message_parse(
+ cr, uid, msgdata[0][1],
+ save_original=folder.server_id.original,
+ context=context)
+ 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),
+ }
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
new file mode 100644
index 000000000..4ec434887
--- /dev/null
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ fetchmail.attach.mail.manually
+ fetchmail.attach.mail.manually
+ form
+
+
+
+
+
+
From 0187c17f0eb1a9ede699468106a26540189dda72 Mon Sep 17 00:00:00 2001
From: Holger Brunn
Date: Mon, 27 Jan 2014 12:50:47 +0100
Subject: [PATCH 12/79] [IMP] remove deprecated type field for views
---
fetchmail_from_imap_folder/view/fetchmail_server.xml | 1 -
fetchmail_from_imap_folder/wizard/attach_mail_manually.xml | 1 -
2 files changed, 2 deletions(-)
diff --git a/fetchmail_from_imap_folder/view/fetchmail_server.xml b/fetchmail_from_imap_folder/view/fetchmail_server.xml
index 6b16c2a58..410ebede7 100644
--- a/fetchmail_from_imap_folder/view/fetchmail_server.xml
+++ b/fetchmail_from_imap_folder/view/fetchmail_server.xml
@@ -4,7 +4,6 @@
fetchmail.server.formfetchmail.server
- form
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
index 4ec434887..d33e7b653 100644
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
@@ -4,7 +4,6 @@
fetchmail.attach.mail.manuallyfetchmail.attach.mail.manually
- form
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
index 86fadbf62..d1a16fa1f 100644
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
@@ -85,8 +85,10 @@ def attach_mails(self, cr, uid, ids, context=None):
msgid, folder.path, this.server))
continue
- mail_message = self.pool.get('mail.message').parse_message(
- msgdata[0][1], this.folder_id.server_id.original)
+ mail_message = self.pool.get('mail.thread').message_parse(
+ cr, uid, msgdata[0][1],
+ save_original=this.folder_id.server_id.original,
+ context=context)
this.folder_id.server_id.attach_mail(connection,
mail.object_id.id, this.folder_id, mail_message,
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
index d33e7b653..fbe82eea7 100644
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
@@ -6,20 +6,22 @@
fetchmail.attach.mail.manually
From bdb25376d769bae4805c4bc31c543d8131801339 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Bidoul?=
Date: Sat, 12 Jul 2014 12:02:52 +0200
Subject: [PATCH 14/79] move all modules to __unported__ on master branch and
set installable=False
---
fetchmail_from_imap_folder/__init__.py | 25 --
fetchmail_from_imap_folder/__openerp__.py | 46 ---
.../match_algorithm/__init__.py | 26 --
.../match_algorithm/base.py | 43 ---
.../match_algorithm/email_domain.py | 44 ---
.../match_algorithm/email_exact.py | 56 ----
.../match_algorithm/openerp_standard.py | 51 ----
fetchmail_from_imap_folder/model/__init__.py | 24 --
.../model/fetchmail_server.py | 280 ------------------
.../model/fetchmail_server_folder.py | 120 --------
.../security/ir.model.access.csv | 2 -
.../view/fetchmail_server.xml | 56 ----
fetchmail_from_imap_folder/wizard/__init__.py | 23 --
.../wizard/attach_mail_manually.py | 114 -------
.../wizard/attach_mail_manually.xml | 29 --
15 files changed, 939 deletions(-)
delete mode 100644 fetchmail_from_imap_folder/__init__.py
delete mode 100644 fetchmail_from_imap_folder/__openerp__.py
delete mode 100644 fetchmail_from_imap_folder/match_algorithm/__init__.py
delete mode 100644 fetchmail_from_imap_folder/match_algorithm/base.py
delete mode 100644 fetchmail_from_imap_folder/match_algorithm/email_domain.py
delete mode 100644 fetchmail_from_imap_folder/match_algorithm/email_exact.py
delete mode 100644 fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
delete mode 100644 fetchmail_from_imap_folder/model/__init__.py
delete mode 100644 fetchmail_from_imap_folder/model/fetchmail_server.py
delete mode 100644 fetchmail_from_imap_folder/model/fetchmail_server_folder.py
delete mode 100755 fetchmail_from_imap_folder/security/ir.model.access.csv
delete mode 100644 fetchmail_from_imap_folder/view/fetchmail_server.xml
delete mode 100644 fetchmail_from_imap_folder/wizard/__init__.py
delete mode 100644 fetchmail_from_imap_folder/wizard/attach_mail_manually.py
delete mode 100644 fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
diff --git a/fetchmail_from_imap_folder/__init__.py b/fetchmail_from_imap_folder/__init__.py
deleted file mode 100644
index 1c91fe478..000000000
--- a/fetchmail_from_imap_folder/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-import match_algorithm
-import model
-import wizard
diff --git a/fetchmail_from_imap_folder/__openerp__.py b/fetchmail_from_imap_folder/__openerp__.py
deleted file mode 100644
index 896701e4e..000000000
--- a/fetchmail_from_imap_folder/__openerp__.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-{
- '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',
- 'security/ir.model.access.csv',
- ],
- 'js': [],
- 'installable': True,
- 'active': False,
- 'certificate': '',
-}
diff --git a/fetchmail_from_imap_folder/match_algorithm/__init__.py b/fetchmail_from_imap_folder/match_algorithm/__init__.py
deleted file mode 100644
index ff3610863..000000000
--- a/fetchmail_from_imap_folder/match_algorithm/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-import base
-import email_exact
-import email_domain
-import openerp_standard
diff --git a/fetchmail_from_imap_folder/match_algorithm/base.py b/fetchmail_from_imap_folder/match_algorithm/base.py
deleted file mode 100644
index 5116c929a..000000000
--- a/fetchmail_from_imap_folder/match_algorithm/base.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-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)
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_domain.py b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
deleted file mode 100644
index 66ab66286..000000000
--- a/fetchmail_from_imap_folder/match_algorithm/email_domain.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-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
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_exact.py b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
deleted file mode 100644
index 728c04461..000000000
--- a/fetchmail_from_imap_folder/match_algorithm/email_exact.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-from base import base
-from openerp.tools.safe_eval import safe_eval
-from openerp.tools.mail import email_split
-
-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 += email_split(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)
diff --git a/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py b/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
deleted file mode 100644
index 24a233d0d..000000000
--- a/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-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]
diff --git a/fetchmail_from_imap_folder/model/__init__.py b/fetchmail_from_imap_folder/model/__init__.py
deleted file mode 100644
index d7e030949..000000000
--- a/fetchmail_from_imap_folder/model/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-import fetchmail_server
-import fetchmail_server_folder
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server.py b/fetchmail_from_imap_folder/model/fetchmail_server.py
deleted file mode 100644
index 814da703c..000000000
--- a/fetchmail_from_imap_folder/model/fetchmail_server.py
+++ /dev/null
@@ -1,280 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-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 as 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.thread').message_parse(
- cr, uid, msgdata[0][1], save_original=this.original,
- context=context)
-
- 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,
- {
- 'author_id': partner_id,
- 'model': folder.model_id.model,
- 'res_id': object_id,
- 'type': 'email',
- 'body': mail_message.get('body'),
- 'subject': mail_message.get('subject'),
- 'email_from': mail_message.get('from'),
- 'date': mail_message.get('date'),
- 'message_id': mail_message.get('message_id'),
- '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)
- 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
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server_folder.py b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
deleted file mode 100644
index ea0c07a7b..000000000
--- a/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-########################################################################
-
-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',
- }
diff --git a/fetchmail_from_imap_folder/security/ir.model.access.csv b/fetchmail_from_imap_folder/security/ir.model.access.csv
deleted file mode 100755
index c63f46bb8..000000000
--- a/fetchmail_from_imap_folder/security/ir.model.access.csv
+++ /dev/null
@@ -1,2 +0,0 @@
-id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_model_fetchmail_server_folder,fetchmail.server.folder,model_fetchmail_server_folder,base.group_system,1,1,1,1
diff --git a/fetchmail_from_imap_folder/view/fetchmail_server.xml b/fetchmail_from_imap_folder/view/fetchmail_server.xml
deleted file mode 100644
index 49384b039..000000000
--- a/fetchmail_from_imap_folder/view/fetchmail_server.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
- fetchmail.server.form
- fetchmail.server
-
-
-
-
- {'required': [('type', '!=', 'imap')]}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/fetchmail_from_imap_folder/wizard/__init__.py b/fetchmail_from_imap_folder/wizard/__init__.py
deleted file mode 100644
index 376a5b392..000000000
--- a/fetchmail_from_imap_folder/wizard/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-import attach_mail_manually
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
deleted file mode 100644
index d1a16fa1f..000000000
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
-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.thread').message_parse(
- cr, uid, msgdata[0][1],
- save_original=folder.server_id.original,
- context=context)
- 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.thread').message_parse(
- cr, uid, msgdata[0][1],
- save_original=this.folder_id.server_id.original,
- context=context)
-
- 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),
- }
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
deleted file mode 100644
index fbe82eea7..000000000
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
- fetchmail.attach.mail.manually
- fetchmail.attach.mail.manually
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
From 93dd6bba38a31d581c6f5fe0d9deac83980da578 Mon Sep 17 00:00:00 2001
From: Holger Brunn
Date: Tue, 27 Jan 2015 14:57:38 +0100
Subject: [PATCH 15/79] [REN] preliminary migration of
fetchmail_attach_from_folder
---
fetchmail_from_imap_folder/README.rst | 46 +++
fetchmail_from_imap_folder/__init__.py | 25 ++
fetchmail_from_imap_folder/__openerp__.py | 38 +++
.../match_algorithm/__init__.py | 26 ++
.../match_algorithm/base.py | 43 +++
.../match_algorithm/email_domain.py | 45 +++
.../match_algorithm/email_exact.py | 57 ++++
.../match_algorithm/openerp_standard.py | 58 ++++
fetchmail_from_imap_folder/model/__init__.py | 24 ++
.../model/fetchmail_server.py | 263 ++++++++++++++++++
.../model/fetchmail_server_folder.py | 115 ++++++++
.../security/ir.model.access.csv | 2 +
.../static/description/icon.png | Bin 0 -> 12585 bytes
.../view/fetchmail_server.xml | 56 ++++
fetchmail_from_imap_folder/wizard/__init__.py | 23 ++
.../wizard/attach_mail_manually.py | 129 +++++++++
.../wizard/attach_mail_manually.xml | 29 ++
17 files changed, 979 insertions(+)
create mode 100644 fetchmail_from_imap_folder/README.rst
create mode 100644 fetchmail_from_imap_folder/__init__.py
create mode 100644 fetchmail_from_imap_folder/__openerp__.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/__init__.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/base.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/email_domain.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/email_exact.py
create mode 100644 fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
create mode 100644 fetchmail_from_imap_folder/model/__init__.py
create mode 100644 fetchmail_from_imap_folder/model/fetchmail_server.py
create mode 100644 fetchmail_from_imap_folder/model/fetchmail_server_folder.py
create mode 100755 fetchmail_from_imap_folder/security/ir.model.access.csv
create mode 100644 fetchmail_from_imap_folder/static/description/icon.png
create mode 100644 fetchmail_from_imap_folder/view/fetchmail_server.xml
create mode 100644 fetchmail_from_imap_folder/wizard/__init__.py
create mode 100644 fetchmail_from_imap_folder/wizard/attach_mail_manually.py
create mode 100644 fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
diff --git a/fetchmail_from_imap_folder/README.rst b/fetchmail_from_imap_folder/README.rst
new file mode 100644
index 000000000..f7380d124
--- /dev/null
+++ b/fetchmail_from_imap_folder/README.rst
@@ -0,0 +1,46 @@
+Email gateway - folders
+=======================
+
+Adds the possibility to attach emails from a certain IMAP folder to objects,
+ie partners. Matching is done via several algorithms, ie email address, email
+address's domain or the original Odoo algorithm.
+
+This gives a simple possibility to archive emails in Odoo without a mail
+client integration.
+
+Configuration
+=============
+
+In your fetchmail configuration, you'll find a new field `folders`. Add your
+folders here in IMAP notation [TODO]
+
+Usage
+=====
+
+A widespread configuration is to have a shared mailbox with several folders [TODO]
+
+Credits
+=======
+
+Contributors
+------------
+
+* Holger Brunn
+
+Icon
+----
+
+http://commons.wikimedia.org/wiki/File:Crystal_Clear_filesystem_folder_favorites.png
+
+Maintainer
+----------
+
+.. image:: http://odoo-community.org/logo.png
+ :alt: Odoo Community Association
+ :target: http://odoo-community.org
+
+This module is maintained by the OCA.
+
+OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.
+
+To contribute to this module, please visit http://odoo-community.org.
diff --git a/fetchmail_from_imap_folder/__init__.py b/fetchmail_from_imap_folder/__init__.py
new file mode 100644
index 000000000..2567300b5
--- /dev/null
+++ b/fetchmail_from_imap_folder/__init__.py
@@ -0,0 +1,25 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+from . import match_algorithm
+from . import model
+from . import wizard
diff --git a/fetchmail_from_imap_folder/__openerp__.py b/fetchmail_from_imap_folder/__openerp__.py
new file mode 100644
index 000000000..93b0a022c
--- /dev/null
+++ b/fetchmail_from_imap_folder/__openerp__.py
@@ -0,0 +1,38 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+{
+ 'name': 'Email gateway - folders',
+ 'summary': 'Attach mails in an IMAP folder to existing objects',
+ 'version': '1.0',
+ 'author': 'Therp BV',
+ 'website': 'http://www.therp.nl',
+ "category": "Tools",
+ "depends": ['fetchmail'],
+ 'data': [
+ 'view/fetchmail_server.xml',
+ 'wizard/attach_mail_manually.xml',
+ 'security/ir.model.access.csv',
+ ],
+ 'installable': True,
+ 'active': True,
+}
diff --git a/fetchmail_from_imap_folder/match_algorithm/__init__.py b/fetchmail_from_imap_folder/match_algorithm/__init__.py
new file mode 100644
index 000000000..baa099c37
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/__init__.py
@@ -0,0 +1,26 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+from . import base
+from . import email_exact
+from . import email_domain
+from . import openerp_standard
diff --git a/fetchmail_from_imap_folder/match_algorithm/base.py b/fetchmail_from_imap_folder/match_algorithm/base.py
new file mode 100644
index 000000000..34e7b3dbe
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/base.py
@@ -0,0 +1,43 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+
+class base(object):
+ name = None
+ '''Name shown to the user'''
+
+ required_fields = []
+ '''Fields on fetchmail_server folder required for this algorithm'''
+
+ readonly_fields = []
+ '''Fields on fetchmail_server folder 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)
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_domain.py b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
new file mode 100644
index 000000000..1f06b7e7c
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
@@ -0,0 +1,45 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+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
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_exact.py b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
new file mode 100644
index 000000000..a2225e083
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
@@ -0,0 +1,57 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+from .base import base
+from openerp.tools.safe_eval import safe_eval
+from openerp.tools.mail import email_split
+
+
+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 += email_split(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)
diff --git a/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py b/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
new file mode 100644
index 000000000..217699169
--- /dev/null
+++ b/fetchmail_from_imap_folder/match_algorithm/openerp_standard.py
@@ -0,0 +1,58 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+from .base import base
+
+
+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]
diff --git a/fetchmail_from_imap_folder/model/__init__.py b/fetchmail_from_imap_folder/model/__init__.py
new file mode 100644
index 000000000..1073e5e38
--- /dev/null
+++ b/fetchmail_from_imap_folder/model/__init__.py
@@ -0,0 +1,24 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+from . import fetchmail_server
+from . import fetchmail_server_folder
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server.py b/fetchmail_from_imap_folder/model/fetchmail_server.py
new file mode 100644
index 000000000..60dbdce94
--- /dev/null
+++ b/fetchmail_from_imap_folder/model/fetchmail_server.py
@@ -0,0 +1,263 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+import logging
+import base64
+import simplejson
+from lxml import etree
+from openerp import models, fields, api, exceptions
+from openerp.tools.translate import _
+from openerp.tools.misc import UnquoteEvalContext
+
+
+class fetchmail_server(models.Model):
+ _inherit = 'fetchmail.server'
+
+ folder_ids = fields.One2many(
+ 'fetchmail.server.folder', 'server_id', 'Folders')
+ object_id = fields.Many2one(required=True)
+
+ _defaults = {
+ 'type': 'imap',
+ }
+
+ 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)
+
+ @api.multi
+ def handle_folder(self, connection, folder):
+ '''Return ids of objects matched'''
+
+ matched_object_ids = []
+
+ for this in self:
+ logging.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':
+ logging.error(
+ 'Could not open mailbox %s on %s',
+ folder.path, this.server)
+ connection.select()
+ continue
+ result, msgids = this.get_msgids(connection)
+ if result != 'OK':
+ logging.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)
+
+ logging.info(
+ 'finished checking for emails in %s server %s',
+ folder.path, this.name)
+
+ return matched_object_ids
+
+ @api.multi
+ def get_msgids(self, connection):
+ '''Return imap ids of messages to process'''
+ return connection.search(None, 'UNDELETED')
+
+ @api.multi
+ def apply_matching(self, connection, folder, msgid, match_algorithm):
+ '''Return ids of objects matched'''
+
+ matched_object_ids = []
+
+ for this in self:
+ result, msgdata = connection.fetch(msgid, '(RFC822)')
+
+ if result != 'OK':
+ logging.error(
+ 'Could not fetch %s in %s on %s',
+ msgid, folder.path, this.server)
+ continue
+
+ mail_message = self.env['mail.thread'].message_parse(
+ msgdata[0][1], save_original=this.original)
+
+ if self.env['mail.message'].search(
+ [('message_id', '=', mail_message['message_id'])]):
+ continue
+
+ found_ids = match_algorithm.search_matches(
+ self.env.cr, self.env.uid, folder, mail_message, msgdata[0][1])
+
+ if found_ids and (len(found_ids) == 1 or
+ folder.match_first):
+ try:
+ self.env.cr.execute('savepoint apply_matching')
+ match_algorithm.handle_match(
+ self.env.cr, self.env.uid, connection,
+ found_ids[0], folder, mail_message,
+ msgdata[0][1], msgid, self.env.context)
+ self.env.cr.execute('release savepoint apply_matching')
+ matched_object_ids += found_ids[:1]
+ except Exception:
+ self.env.cr.execute('rollback to savepoint apply_matching')
+ logging.exception(
+ "Failed to fetch mail %s from %s", msgid, this.name)
+ elif folder.flag_nonmatching:
+ connection.store(msgid, '+FLAGS', '\\FLAGGED')
+
+ return matched_object_ids
+
+ @api.multi
+ def attach_mail(self, connection, object_id, folder, mail_message, msgid):
+ '''Return ids of messages created'''
+
+ mail_message_ids = []
+
+ for this in self:
+ partner_id = None
+ if folder.model_id.model == 'res.partner':
+ partner_id = object_id
+ if 'partner_id' in self.env[folder.model_id.model]._columns:
+ partner_id = self.env[folder.model_id.model].browse(object_id)\
+ .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.env['ir.attachment'].create(data_attach))
+
+ mail_message_ids.append(
+ self.env['mail.message'].create({
+ 'author_id': partner_id,
+ 'model': folder.model_id.model,
+ 'res_id': object_id,
+ 'type': 'email',
+ 'body': mail_message.get('body'),
+ 'subject': mail_message.get('subject'),
+ 'email_from': mail_message.get('from'),
+ 'date': mail_message.get('date'),
+ 'message_id': mail_message.get('message_id'),
+ 'attachment_ids': [(6, 0, [a.id for a in attachments])],
+ }))
+
+ 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 exceptions.ValidationError(
+ _('Mailbox %s not found!') % folder.path)
+ 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['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.xpath('//field'):
+ 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
diff --git a/fetchmail_from_imap_folder/model/fetchmail_server_folder.py b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
new file mode 100644
index 000000000..570245572
--- /dev/null
+++ b/fetchmail_from_imap_folder/model/fetchmail_server_folder.py
@@ -0,0 +1,115 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+########################################################################
+from openerp import api, models, fields
+from .. import match_algorithm
+
+
+class fetchmail_server_folder(models.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):
+ algorithms = []
+ for cls in self._get_match_algorithms().itervalues():
+ algorithms.append((cls.__name__, cls.name))
+ algorithms.sort()
+ return algorithms
+
+ sequence = fields.Integer('Sequence')
+ path = fields.Char(
+ 'Path',
+ 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)',
+ 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)',
+ help='Field(s) to order by, this mostly useful in conjunction '
+ "with 'Use 1st match'")
+ match_algorithm = fields.Selection(
+ _get_match_algorithms_sel,
+ 'Match algorithm', required=True,
+ help='The algorithm used to determine which object an email matches.')
+ mail_field = fields.Char(
+ 'Field (email)',
+ 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 Odoo")
+ 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',
+ 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 Odoo')
+
+ _defaults = {
+ 'flag_nonmatching': True,
+ 'msg_state': 'received',
+ }
+
+ @api.multi
+ def get_algorithm(self):
+ return self._get_match_algorithms()[self.match_algorithm]()
+
+ @api.multi
+ def button_attach_mail_manually(self):
+ return {
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'fetchmail.attach.mail.manually',
+ 'target': 'new',
+ 'context': dict(self.env.context, default_folder_id=self.id),
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ }
diff --git a/fetchmail_from_imap_folder/security/ir.model.access.csv b/fetchmail_from_imap_folder/security/ir.model.access.csv
new file mode 100755
index 000000000..c63f46bb8
--- /dev/null
+++ b/fetchmail_from_imap_folder/security/ir.model.access.csv
@@ -0,0 +1,2 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_model_fetchmail_server_folder,fetchmail.server.folder,model_fetchmail_server_folder,base.group_system,1,1,1,1
diff --git a/fetchmail_from_imap_folder/static/description/icon.png b/fetchmail_from_imap_folder/static/description/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..be54e22b8851ded0aa8c0b0f1a016f2631b8f8a3
GIT binary patch
literal 12585
zcmV+^G1ktBP)Y1j~ngf@gi
z!B(Ho*W&jpt$x411)HYnn3k7^fjx)n>T;N#o@Xt=NRT_x)z$aOC!c)p5%!Us(SQ=+
zPXxHUpgI9-zV^~fZ?p%4!5G`GsjMt-$2SZP>}s!{pt^E@4x@9C(Fwt4|<(1ySUTobmqirodkl$
zoh*~wK)}~(-~|FW{XJzzAmFdg-
zg!SY3ls)y-hdvkzg{mm{nM@Yu=TkOW#(nuY@z3USx-UNB^gZV9ZJ&87ZH5cO$TDaU
z0Dr6+C^75DlPinI>mP_lBjy{4L=v*uocTipK>EG~u6T}HE~oD!`&CuXdXNZs9q@Ih
z$Fm|d^GU0
zI#8NT)&&7HO)XRZv1)WkgWqT1udVPD&6Un9XK=SP7e$
zNKpB5%bt;2ZG7Yu0fW5ogh{UsDnnqR20>gBHBq|fs8Q-
zRS6n9P$i-SEER>IDq2beko}QK0wlnPKJ-`c`s+XBZ&X)T@P=R_5k#bp${;cY0Sv|h
z7Wg@v`w##N)sTr{DMl_&P4v&^OoGwZvEez`iDR!pi2tvD|H{`JN?8FM-NMk&00*&uz*)>!6rS9AcF2{EHV^R+J37N
zKye5HZCB&D=Y9{L`OL%1Dt(H_VmfUENzjTH7Sg7AVC50x1|jvhFJcNBU*IOHmVz8|
z&?yKYic|WdPQWWc1Q+~EDhO62R
z2MK5;wUh|pG}={JilljgEWbwITU^Yz5=wke^a%(bF9JK<*E^Q9Wep6$Ztgqo*bYaJ
zp5^4Ls;V%~BVcA5tL+Y`VU%hepeSFaH+PVo6u@ntx)3+u#b-pIh|e)Nl#fRXQur2*
z@so#yp&HPEoV#{yhF4xW23xnb7~tnjbrSKx<=#q#03cNaJ$;#%%)5iEImQk$kp%co
zpK&{;)0jZ4QHZot1dZbJfk1$zw=qtN=H@z>n3(0RfMyCJOz#&w7qa?7Dq;O^)piaj@%#6m!pR_}
z0_i1X3^0BCd#jb!UJWjQoGg|~eYOD@Ue=gz<@pvb)ItWo7^^P^e76hj2EG_u(A|CB
zw05chy1Izpwek$WO;t;BaJ#rjm=6~d&^TMadw}N^40z+V;N5^-PO#@ykg~=asJ7rT5O4=&%rR>x}{*S#{l_t030FgW$`i~
zPNiHoFsRi#T`Q;BfLnm&<@f1x@%yZ}#fb=-CxCCsLXh6KujEblI(qaB@r~-TfOi7Y
zO&*uhp+wKgONr>~^!JJW3)+w2qzcQA0pRK(fVem^0kBuCtE;~t@J?X40q-XJ-o9Qd
zSj6&9CpB9PAP0Z6k3qx(g|e8pSSi>!2*jFR%XI@Hh`eeDAfjTK07#0Fk#QIrnsAkSH(xD3cZ&3jNe{i!y<&j&*ySF
zhvfL=Du@A8a|Vs*B@Ht#n{;x$Y
z8Za)M1Xo=QATE$Kd&iouckEb?IpoT#hj1xAznGZ8>+NEFKke(lM%@=p`8X`G|h6dT-gQCP9tZv(((p}*!vC&pW9XD0`w6<
zV#20q`ZOxPF>yj60im{J=`I#L&1_~eBT8kjR2qbC&P9<=!tmG|G3KkP4u?Z`t
zvv$RMxIZ~L13f*L@~pmC%a<#1g$8&On_d;82BNRS3p`pTrv9A93B@RZTeY)fD}kaE
zOclVIW~~Q&jmhN!#TYx9+0I3lEr+#kaEbKK~A-dLPaR~*iHd12Fr_!nFV^v
zS7{cYkkvL6K7$4uzIW)*>7u~*0=XC^@RENE(Bc$_jt8K@u2Z3jx&gOhm%T5-`hRE7
zUV`D_u~P={YRMBo6oOD9=?EFTZek)QK2k!=&nKa~dtlk%FIE2CELndJ(sRY7vMGYz
zoM+%i=L$F%hBRpqiKPa(T>R
z(P%lJZnfMfeL3Y-x4sGC!dz1@q5%0hzRza$I4Z~j+PD!lC~KK@WNqo6yb731hMt}QPJ+tH$f|+8
z`Yukhm4dBcPBVvriA;bFim_BcHK(@gv64LVIm;)UoH%h7jvw!O{kz}&pLm}DoS?X9
zkihg6rM6C>|3BRUcei9;t&g`YLSlFTZ+^ts?>85Ku-5ET9IXj2U}tA9+;r1c5@qN6
z;H9R1OZq{I_b@csTHQOOXnEKQigkro34ttkg13o5s~;R3oB7d?p846CGrz-I#muob
zZ;(K!fLcllz`c
z>*SKE2ag{5=}-UhMfMTA
zMa;C(W{C>qN=*Sc`1fvt4eRT}x5l?^hiq~du8+O}^P^`08aFc%gt*%hfVwRcFE*?Y
zo;uYJJ9ca;2uRT^H9DuOsF@VQ4X(kB)GBg
+
+
+
+
+
+
+
+
diff --git a/fetchmail_from_imap_folder/wizard/__init__.py b/fetchmail_from_imap_folder/wizard/__init__.py
new file mode 100644
index 000000000..1f98c5a26
--- /dev/null
+++ b/fetchmail_from_imap_folder/wizard/__init__.py
@@ -0,0 +1,23 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+from . import attach_mail_manually
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
new file mode 100644
index 000000000..0c22f0c86
--- /dev/null
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
@@ -0,0 +1,129 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Therp BV ()
+# 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 .
+#
+##############################################################################
+
+from openerp.osv import fields
+from openerp.osv.orm import TransientModel
+import logging
+logger = logging.getLogger(__name__)
+
+
+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, folder.server_id.name))
+ 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, folder.server_id.name))
+ continue
+ mail_message = self.pool.get('mail.thread').message_parse(
+ cr, uid, msgdata[0][1],
+ save_original=folder.server_id.original,
+ context=context
+ )
+ 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' % (
+ mail.msgid, this.folder_id.path, this.server))
+ continue
+
+ mail_message = self.pool.get('mail.thread').message_parse(
+ cr, uid, msgdata[0][1],
+ save_original=this.folder_id.server_id.original,
+ context=context)
+
+ 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,
+ ),
+ }
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
new file mode 100644
index 000000000..fbe82eea7
--- /dev/null
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ fetchmail.attach.mail.manually
+ fetchmail.attach.mail.manually
+
+
+
+
+
+
+
+
+
+
diff --git a/fetchmail_from_imap_folder/wizard/__init__.py b/fetchmail_from_imap_folder/wizard/__init__.py
index 1f98c5a26..f7b0d7875 100644
--- a/fetchmail_from_imap_folder/wizard/__init__.py
+++ b/fetchmail_from_imap_folder/wizard/__init__.py
@@ -1,23 +1,4 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-
+# -*- coding: utf-8 -*-
+# Copyright - 2013-2018 Therp BV .
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import attach_mail_manually
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
index 666de38bf..23b16ebcd 100644
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
@@ -1,30 +1,15 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# This module copyright (C) 2013 Therp BV ()
-# 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 .
-#
-##############################################################################
-from openerp import fields, models
+# -*- coding: utf-8 -*-
+# Copyright - 2013-2018 Therp BV .
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
+
+from odoo import api, fields, models
+
+
_logger = logging.getLogger(__name__)
-class attach_mail_manually(models.TransientModel):
+class AttachMailManually(models.TransientModel):
_name = 'fetchmail.attach.mail.manually'
folder_id = fields.Many2one(
@@ -32,17 +17,13 @@ class attach_mail_manually(models.TransientModel):
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):
+ @api.model
+ def default_get(self, fields_list):
+ folder_model = self.env['fetchmail.server.folder']
+ thread_model = self.env['mail.thread']
+ defaults = super(AttachMailManually, self).default_get(fields_list)
+ default_folder_id = self.env.context.get('default_folder_id')
+ for folder in folder_model.browse([default_folder_id]):
defaults['mail_ids'] = []
connection = folder.server_id.connect()
connection.select(folder.path)
@@ -50,70 +31,72 @@ def default_get(self, cr, uid, fields_list, context=None):
None,
'FLAGGED' if folder.flag_nonmatching else 'UNDELETED')
if result != 'OK':
- _logger.error('Could not search mailbox %s on %s',
- folder.path, folder.server_id.name)
+ _logger.error(
+ 'Could not search mailbox %s on %s',
+ folder.path, folder.server_id.name)
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, folder.server_id.name)
+ _logger.error(
+ 'Could not fetch %s in %s on %s',
+ msgid, folder.path, folder.server_id.name)
continue
- mail_message = self.pool.get('mail.thread').message_parse(
- cr, uid, msgdata[0][1],
- save_original=folder.server_id.original,
- context=context
- )
+ mail_message = thread_model.message_parse(
+ msgdata[0][1],
+ save_original=folder.server_id.original)
defaults['mail_ids'].append((0, 0, {
'msgid': msgid,
'subject': mail_message.get('subject', ''),
'date': mail_message.get('date', ''),
- 'object_id': '%s,-1' % folder.model_id.model,
- }))
+ 'object_id': '%s,-1' % folder.model_id.model}))
connection.close()
-
return defaults
- def attach_mails(self, cr, uid, ids, context=None):
- for this in self.browse(cr, uid, ids, context):
+ @api.multi
+ def attach_mails(self):
+ thread_model = self.env['mail.thread']
+ for this in self:
+ folder = this.folder_id
+ server = folder.server_id
+ connection = server.connect()
+ connection.select(folder.path)
for mail in this.mail_ids:
- connection = this.folder_id.server_id.connect()
- connection.select(this.folder_id.path)
+ if not mail.object_id:
+ continue
result, msgdata = connection.fetch(mail.msgid, '(RFC822)')
if result != 'OK':
- _logger.error('Could not fetch %s in %s on %s',
- mail.msgid, this.folder_id.path, this.server)
+ _logger.error(
+ 'Could not fetch %s in %s on %s',
+ mail.msgid, folder.path, server)
continue
-
- mail_message = self.pool.get('mail.thread').message_parse(
- cr, uid, msgdata[0][1],
- save_original=this.folder_id.server_id.original,
- context=context)
-
- this.folder_id.server_id.attach_mail(
- connection,
- mail.object_id.id, this.folder_id, mail_message,
- mail.msgid
- )
- connection.close()
+ mail_message = thread_model.message_parse(
+ msgdata[0][1], save_original=server.original)
+ folder.attach_mail(mail.object_id, mail_message)
+ if folder.delete_matching:
+ connection.store(mail.msgid, '+FLAGS', '\\DELETED')
+ elif folder.flag_nonmatching:
+ connection.store(mail.msgid, '-FLAGS', '\\FLAGGED')
+ connection.close()
return {'type': 'ir.actions.act_window_close'}
- def fields_view_get(self, cr, user, view_id=None, view_type='form',
- context=None, toolbar=False, submenu=False):
- result = super(attach_mail_manually, self).fields_view_get(
- cr, user, view_id, view_type, context, toolbar, submenu)
-
+ @api.model
+ def fields_view_get(
+ self, view_id=None, view_type='form',
+ toolbar=False, submenu=False):
+ result = super(AttachMailManually, self).fields_view_get(
+ view_id=view_id, view_type=view_type, toolbar=toolbar,
+ submenu=submenu)
tree = result['fields']['mail_ids']['views']['tree']
- for folder in self.pool['fetchmail.server.folder'].browse(
- cr, user, [context.get('default_folder_id')], context):
+ folder_model = self.env['fetchmail.server.folder']
+ default_folder_id = self.env.context.get('default_folder_id')
+ for folder in folder_model.browse([default_folder_id]):
tree['fields']['object_id']['selection'] = [
- (folder.model_id.model, folder.model_id.name)
- ]
-
+ (folder.model_id.model, folder.model_id.name)]
return result
-class attach_mail_manually_mail(models.TransientModel):
+class AttachMailManuallyMail(models.TransientModel):
_name = 'fetchmail.attach.mail.manually.mail'
wizard_id = fields.Many2one(
@@ -124,6 +107,5 @@ class attach_mail_manually_mail(models.TransientModel):
object_id = fields.Reference(
lambda self: [
(m.model, m.name)
- for m in self.env['ir.model'].search([])
- ],
+ for m in self.env['ir.model'].search([])],
string='Object')
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
index 320ccaf4a..72e2eab32 100644
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
@@ -1,28 +1,35 @@
-
-
-
- fetchmail.attach.mail.manually
- fetchmail.attach.mail.manually
-
-
-
+
diff --git a/fetchmail_from_imap_folder/wizard/__init__.py b/fetchmail_from_imap_folder/wizard/__init__.py
index f7b0d7875..adb296dfe 100644
--- a/fetchmail_from_imap_folder/wizard/__init__.py
+++ b/fetchmail_from_imap_folder/wizard/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Copyright - 2013-2018 Therp BV .
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import attach_mail_manually
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
index 122d132cb..b32074bdc 100644
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
@@ -1,51 +1,51 @@
-# -*- coding: utf-8 -*-
# Copyright 2013-2018 Therp BV .
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo import _, api, fields, models
-
_logger = logging.getLogger(__name__)
class AttachMailManually(models.TransientModel):
- _name = 'fetchmail.attach.mail.manually'
+ _name = "fetchmail.attach.mail.manually"
name = fields.Char()
- folder_id = fields.Many2one(
- 'fetchmail.server.folder', 'Folder', readonly=True)
+ folder_id = fields.Many2one("fetchmail.server.folder", "Folder", readonly=True)
mail_ids = fields.One2many(
- 'fetchmail.attach.mail.manually.mail', 'wizard_id', 'Emails')
+ "fetchmail.attach.mail.manually.mail", "wizard_id", "Emails"
+ )
@api.model
def _prepare_mail(self, folder, msgid, mail_message):
return {
- 'msgid': msgid,
- 'subject': mail_message.get('subject', ''),
- 'date': mail_message.get('date', ''),
- 'body': mail_message.get('body', ''),
- 'email_from': mail_message.get('from', ''),
- 'object_id': '%s,-1' % folder.model_id.model}
+ "msgid": msgid,
+ "subject": mail_message.get("subject", ""),
+ "date": mail_message.get("date", ""),
+ "body": mail_message.get("body", ""),
+ "email_from": mail_message.get("from", ""),
+ "object_id": "%s,-1" % folder.model_id.model,
+ }
@api.model
def default_get(self, fields_list):
defaults = super(AttachMailManually, self).default_get(fields_list)
- if not fields_list or 'name' in fields_list:
- defaults['name'] = _('Attach emails manually')
- defaults['mail_ids'] = []
- folder_model = self.env['fetchmail.server.folder']
- folder_id = self.env.context.get('folder_id')
- defaults['folder_id'] = folder_id
+ if not fields_list or "name" in fields_list:
+ defaults["name"] = _("Attach emails manually")
+ defaults["mail_ids"] = []
+ folder_model = self.env["fetchmail.server.folder"]
+ folder_id = self.env.context.get("folder_id")
+ defaults["folder_id"] = folder_id
folder = folder_model.browse([folder_id])
connection = folder.server_id.connect()
connection.select(folder.path)
- criteria = 'FLAGGED' if folder.flag_nonmatching else 'UNDELETED'
+ criteria = "FLAGGED" if folder.flag_nonmatching else "UNDELETED"
msgids = folder.get_msgids(connection, criteria)
for msgid in msgids[0].split():
mail_message, message_org = folder.fetch_msg(connection, msgid)
- defaults['mail_ids'].append(
- (0, 0, self._prepare_mail(folder, msgid, mail_message)))
+ defaults["mail_ids"].append(
+ (0, 0, self._prepare_mail(folder, msgid, mail_message))
+ )
connection.close()
return defaults
@@ -63,41 +63,40 @@ def attach_mails(self):
mail_message, message_org = folder.fetch_msg(connection, msgid)
folder.attach_mail(mail.object_id, mail_message)
folder.update_msg(
- connection, msgid, matched=True,
- flagged=folder.flag_nonmatching)
+ connection, msgid, matched=True, flagged=folder.flag_nonmatching
+ )
connection.close()
- return {'type': 'ir.actions.act_window_close'}
+ return {"type": "ir.actions.act_window_close"}
@api.model
def fields_view_get(
- self, view_id=None, view_type='form',
- toolbar=False, submenu=False):
+ self, view_id=None, view_type="form", toolbar=False, submenu=False
+ ):
result = super(AttachMailManually, self).fields_view_get(
- view_id=view_id, view_type=view_type, toolbar=toolbar,
- submenu=submenu)
- if view_type != 'form':
+ view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu
+ )
+ if view_type != "form":
return result
- folder_model = self.env['fetchmail.server.folder']
- folder_id = self.env.context.get('folder_id')
+ folder_model = self.env["fetchmail.server.folder"]
+ folder_id = self.env.context.get("folder_id")
folder = folder_model.browse([folder_id])
- form = result['fields']['mail_ids']['views']['form']
- form['fields']['object_id']['selection'] = [
- (folder.model_id.model, folder.model_id.name)]
+ form = result["fields"]["mail_ids"]["views"]["form"]
+ form["fields"]["object_id"]["selection"] = [
+ (folder.model_id.model, folder.model_id.name)
+ ]
return result
class AttachMailManuallyMail(models.TransientModel):
- _name = 'fetchmail.attach.mail.manually.mail'
+ _name = "fetchmail.attach.mail.manually.mail"
- wizard_id = fields.Many2one(
- 'fetchmail.attach.mail.manually', readonly=True)
- msgid = fields.Char('Message id', readonly=True)
- subject = fields.Char('Subject', readonly=True)
- date = fields.Datetime('Date', readonly=True)
- email_from = fields.Char('From', readonly=True)
- body = fields.Html('Body', readonly=True)
+ wizard_id = fields.Many2one("fetchmail.attach.mail.manually", readonly=True)
+ msgid = fields.Char("Message id", readonly=True)
+ subject = fields.Char("Subject", readonly=True)
+ date = fields.Datetime("Date", readonly=True)
+ email_from = fields.Char("From", readonly=True)
+ body = fields.Html("Body", readonly=True)
object_id = fields.Reference(
- lambda self: [
- (m.model, m.name)
- for m in self.env['ir.model'].search([])],
- string='Object')
+ lambda self: [(m.model, m.name) for m in self.env["ir.model"].search([])],
+ string="Object",
+ )
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
index ab9d761cd..10750a2a9 100644
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
@@ -1,4 +1,4 @@
-
+
@@ -31,12 +31,10 @@
string="Save"
type="object"
name="attach_mails"
- class="oe_highlight" />
+ class="oe_highlight"
+ />
or
-
+
From 270cf2559890803d1ab13ffeb2a486c3a97178d6 Mon Sep 17 00:00:00 2001
From: Ronald Portier
Date: Mon, 8 Jan 2024 22:53:02 +0100
Subject: [PATCH 44/79] [MIG] fetchmail_attach_from_folder: Migration to 16.0
---
fetchmail_from_imap_folder/README.rst | 134 ++++++++++------
fetchmail_from_imap_folder/__manifest__.py | 6 +-
.../match_algorithm/__init__.py | 3 +-
.../match_algorithm/base.py | 10 +-
.../match_algorithm/email_domain.py | 6 +-
.../match_algorithm/email_exact.py | 5 +-
.../match_algorithm/odoo_standard.py | 12 +-
.../models/fetchmail_server.py | 70 +-------
.../models/fetchmail_server_folder.py | 124 +++++++--------
.../readme/CONFIGURE.md | 28 ++++
.../readme/CONTRIBUTORS.md | 2 +
.../readme/DESCRIPTION.md | 6 +
fetchmail_from_imap_folder/readme/USAGE.md | 12 ++
.../security/ir.model.access.csv | 0
.../tests/test_match_algorithms.py | 9 --
.../views/fetchmail_server.xml | 149 ++++++++++--------
.../wizard/attach_mail_manually.py | 11 +-
17 files changed, 291 insertions(+), 296 deletions(-)
create mode 100644 fetchmail_from_imap_folder/readme/CONFIGURE.md
create mode 100644 fetchmail_from_imap_folder/readme/CONTRIBUTORS.md
create mode 100644 fetchmail_from_imap_folder/readme/DESCRIPTION.md
create mode 100644 fetchmail_from_imap_folder/readme/USAGE.md
mode change 100755 => 100644 fetchmail_from_imap_folder/security/ir.model.access.csv
diff --git a/fetchmail_from_imap_folder/README.rst b/fetchmail_from_imap_folder/README.rst
index 6be026a71..5e0873f7a 100644
--- a/fetchmail_from_imap_folder/README.rst
+++ b/fetchmail_from_imap_folder/README.rst
@@ -1,95 +1,133 @@
+=======================
Email gateway - folders
=======================
-Adds the possibility to attach emails from a certain IMAP folder to objects,
-ie partners. Matching is done via several algorithms, ie email address, email
-address's domain or the original Odoo algorithm.
+..
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! This file is generated by oca-gen-addon-readme !!
+ !! changes will be overwritten. !!
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! source digest: sha256:95f6645118da34dd962fa794f5fca9c8797579a9a585d80228407f4997e9ba91
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
+ :target: https://odoo-community.org/page/development-status
+ :alt: Beta
+.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
+ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
+ :alt: License: AGPL-3
+.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github
+ :target: https://github.com/OCA/server-tools/tree/16.0/fetchmail_attach_from_folder
+ :alt: OCA/server-tools
+.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
+ :target: https://translation.odoo-community.org/projects/server-tools-16-0/server-tools-16-0-fetchmail_attach_from_folder
+ :alt: Translate me on Weblate
+.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=16.0
+ :alt: Try me on Runboat
+
+|badge1| |badge2| |badge3| |badge4| |badge5|
+
+Adds the possibility to attach emails from a certain IMAP folder to
+objects, ie partners. Matching is done via several algorithms, ie email
+address, email address's domain or the original Odoo algorithm.
This gives a simple possibility to archive emails in Odoo without a mail
client integration.
+**Table of contents**
+
+.. contents::
+ :local:
+
Configuration
=============
-In your fetchmail configuration, you'll find a new list field `Folders to
-monitor`. Add your folders here in IMAP notation (usually something like
-`INBOX.your_folder_name.your_subfolder_name`), choose a model to attach mails
-to and a matching algorithm to use.
+In your fetchmail configuration, you'll find a new list field
+``Folders to monitor``. Add your folders here in IMAP notation (usually
+something like ``INBOX.your_folder_name.your_subfolder_name``), choose a
+model to attach mails to and a matching algorithm to use.
Exact mailaddress
-----------------
-Fill in a field to search for the email address in `Field (model)`. For
-partners, this would be `email`. Also fill in the header field from the email
-to look at in `Field (email)`. If you want to match incoming mails from your
-customers, this would be `from`. You can also list header fields, so to match
-partners receiving this email, you might fill in `to,cc,bcc`.
+Fill in a field to search for the email address in ``Field (model)``.
+For partners, this would be ``email``. Also fill in the header field
+from the email to look at in ``Field (email)``. If you want to match
+incoming mails from your customers, this would be ``from``. You can also
+list header fields, so to match partners receiving this email, you might
+fill in ``to,cc,bcc``.
Domain of email addresses
-------------------------
-Match the domain of the email address(es) found in `Field (email)`. This would
-attach a mail to `test1@example.com` to a record with `Field (model)` set to
-`test2@example.com`. Given that this is a fuzzy match, you probably want to
-check `Use 1st match`, because otherwise nothing happens if multiple possible
-matches are found.
+Match the domain of the email address(es) found in ``Field (email)``.
+This would attach a mail to ``test1@example.com`` to a record with
+``Field (model)`` set to ``test2@example.com``. Given that this is a
+fuzzy match, you probably want to check ``Use 1st match``, because
+otherwise nothing happens if multiple possible matches are found.
Odoo standard
-------------
-This is stricly speaking no matching algorithm, but calls the model's standard
-action on new incoming mail, which is usually creating a new record.
+This is stricly speaking no matching algorithm, but calls the model's
+standard action on new incoming mail, which is usually creating a new
+record.
Usage
=====
-A widespread configuration is to have a shared mailbox with several folders,
-i.e. one where users drop mails they want to attach to partners. Let this
-folder be called `From partners`. Then create a folder configuration for your
-server with path `"INBOX.From partners"` (note the quotes because of the space,
-this is server dependent). Choose model `Partners`, set `Field (model)` to
-`email` and `Field (email)` to `from`. In `Domain`, you could fill in
-`[('customer', '=', True)]` to be sure to only match customer records.
-
-Now when your users drop mails into this folder, they will be fetched by Odoo
-and attached to the partner in question. After some testing, you might want to
-check `Delete matches` in your folder configuration so that this folder doesn't
-grow indefinitely.
+A widespread configuration is to have a shared mailbox with several
+folders, i.e. one where users drop mails they want to attach to
+partners. Let this folder be called ``From partners``. Then create a
+folder configuration for your server with path ``"INBOX.From partners"``
+(note the quotes because of the space, this is server dependent). Choose
+model ``Partners``, set ``Field (model)`` to ``email`` and
+``Field (email)`` to ``from``. In ``Domain``, you could fill in
+``[('customer', '=', True)]`` to be sure to only match customer records.
+Now when your users drop mails into this folder, they will be fetched by
+Odoo and attached to the partner in question. After some testing, you
+might want to check ``Delete matches`` in your folder configuration so
+that this folder doesn't grow indefinitely.
Bug Tracker
===========
-Bugs are tracked on `GitHub Issues
-`_. In case of trouble, please
-check there if your issue has already been reported. If you spotted it first,
-help us smashing it by providing a detailed and welcomed feedback.
+Bugs are tracked on `GitHub Issues `_.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us to smash it by providing a detailed and welcomed
+`feedback `_.
+
+Do not contact contributors directly about support or help with technical issues.
Credits
=======
+Authors
+-------
+
+* Therp BV
+
Contributors
------------
-* Holger Brunn
-* Ronald Portier
-
-Icon
-----
+- Holger Brunn hbrunn@therp.nl
+- Ronald Portier ronald@therp.nl
-http://commons.wikimedia.org/wiki/File:Crystal_Clear_filesystem_folder_favorites.png
+Maintainers
+-----------
-Maintainer
-----------
+This module is maintained by the OCA.
-.. image:: http://odoo-community.org/logo.png
+.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
- :target: http://odoo-community.org
-
-This module is maintained by the OCA.
+ :target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
-To contribute to this module, please visit http://odoo-community.org.
+This module is part of the `OCA/server-tools `_ project on GitHub.
+
+You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/fetchmail_from_imap_folder/__manifest__.py b/fetchmail_from_imap_folder/__manifest__.py
index 7a5894224..14e69453c 100644
--- a/fetchmail_from_imap_folder/__manifest__.py
+++ b/fetchmail_from_imap_folder/__manifest__.py
@@ -1,14 +1,14 @@
-# Copyright - 2013-2018 Therp BV .
+# Copyright - 2013-2024 Therp BV .
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "Email gateway - folders",
"summary": "Attach mails in an IMAP folder to existing objects",
- "version": "10.0.1.1.0",
+ "version": "16.0.1.1.0",
"author": "Therp BV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-tools",
"license": "AGPL-3",
"category": "Tools",
- "depends": ["fetchmail"],
+ "depends": ["mail"],
"data": [
"views/fetchmail_server.xml",
"wizard/attach_mail_manually.xml",
diff --git a/fetchmail_from_imap_folder/match_algorithm/__init__.py b/fetchmail_from_imap_folder/match_algorithm/__init__.py
index 0f87298ac..b74ba409c 100644
--- a/fetchmail_from_imap_folder/match_algorithm/__init__.py
+++ b/fetchmail_from_imap_folder/match_algorithm/__init__.py
@@ -1,6 +1,5 @@
-# Copyright - 2013-2018 Therp BV .
+# Copyright - 2013-2024 Therp BV .
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from . import base
from . import email_exact
from . import email_domain
from . import odoo_standard
diff --git a/fetchmail_from_imap_folder/match_algorithm/base.py b/fetchmail_from_imap_folder/match_algorithm/base.py
index 127a405d4..850124a8e 100644
--- a/fetchmail_from_imap_folder/match_algorithm/base.py
+++ b/fetchmail_from_imap_folder/match_algorithm/base.py
@@ -1,16 +1,8 @@
-# Copyright - 2013-2018 Therp BV .
+# Copyright - 2013-2024 Therp BV .
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
class Base(object):
- name = None # Name shown to the user
-
- # Fields on fetchmail_server folder required for this algorithm
- required_fields = []
-
- # Fields on fetchmail_server folder readonly for this algorithm
- readonly_fields = []
-
def search_matches(self, folder, mail_message):
"""Returns recordset found for model with mail_message."""
return []
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_domain.py b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
index b6d463a34..7ad6bfb79 100644
--- a/fetchmail_from_imap_folder/match_algorithm/email_domain.py
+++ b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
@@ -1,4 +1,4 @@
-# Copyright - 2013-2018 Therp BV .
+# Copyright - 2013-2024 Therp BV .
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from .email_exact import EmailExact
@@ -9,11 +9,9 @@ class EmailDomain(EmailExact):
Beware of match_first here, this is most likely to get it wrong (gmail).
"""
- name = "Domain of email address"
-
def search_matches(self, folder, mail_message):
"""Returns recordset of matching objects."""
- matches = super(EmailDomain, self).search_matches(folder, mail_message)
+ matches = super().search_matches(folder, mail_message)
if not matches:
object_model = folder.env[folder.model_id.model]
domains = []
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_exact.py b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
index 77c739a00..ea4ed1e5e 100644
--- a/fetchmail_from_imap_folder/match_algorithm/email_exact.py
+++ b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
@@ -1,4 +1,4 @@
-# Copyright - 2013-2018 Therp BV .
+# Copyright - 2013-2024 Therp BV .
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.tools.mail import email_split
from odoo.tools.safe_eval import safe_eval
@@ -9,9 +9,6 @@
class EmailExact(Base):
"""Search for exactly the mailadress as noted in the email"""
- name = "Exact mailadress"
- required_fields = ["model_field", "mail_field"]
-
def _get_mailaddresses(self, folder, mail_message):
mailaddresses = []
fields = folder.mail_field.split(",")
diff --git a/fetchmail_from_imap_folder/match_algorithm/odoo_standard.py b/fetchmail_from_imap_folder/match_algorithm/odoo_standard.py
index 3705080b6..d2b77dde1 100644
--- a/fetchmail_from_imap_folder/match_algorithm/odoo_standard.py
+++ b/fetchmail_from_imap_folder/match_algorithm/odoo_standard.py
@@ -1,4 +1,4 @@
-# Copyright - 2013-2018 Therp BV .
+# Copyright - 2013-2024 Therp BV .
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from .base import Base
@@ -7,16 +7,6 @@ class OdooStandard(Base):
"""No search at all. Use Odoo's standard mechanism to attach mails to
mail.thread objects. Note that this algorithm always matches."""
- name = "Odoo standard"
- readonly_fields = [
- "model_field",
- "mail_field",
- "match_first",
- "domain",
- "model_order",
- "flag_nonmatching",
- ]
-
def search_matches(self, folder, mail_message):
"""Always match. Duplicates will be fished out by message_id"""
return [True]
diff --git a/fetchmail_from_imap_folder/models/fetchmail_server.py b/fetchmail_from_imap_folder/models/fetchmail_server.py
index 30afefeb7..2e0d93739 100644
--- a/fetchmail_from_imap_folder/models/fetchmail_server.py
+++ b/fetchmail_from_imap_folder/models/fetchmail_server.py
@@ -1,14 +1,9 @@
-# Copyright - 2013-2018 Therp BV .
+# Copyright - 2013-2024 Therp BV .
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-import json
import logging
import re
-from lxml import etree
-
from odoo import _, api, fields, models
-from odoo.tools.misc import UnquoteEvalContext
-from odoo.tools.safe_eval import safe_eval
_logger = logging.getLogger(__name__)
@@ -20,7 +15,6 @@
class FetchmailServer(models.Model):
_inherit = "fetchmail.server"
- @api.multi
def _compute_folders_available(self):
"""Retrieve available folders from IMAP server."""
@@ -40,7 +34,7 @@ def parse_list_response(line):
continue
folders_available = []
for folder_entry in list_result[1]:
- folders_available.append(parse_list_response(folder_entry)[2])
+ folders_available.append(parse_list_response(str(folder_entry))[2])
this.folders_available = "\n".join(folders_available)
connection.logout()
@@ -54,71 +48,23 @@ def parse_list_response(line):
context={"active_test": False},
)
object_id = fields.Many2one(required=False) # comodel_name='ir.model'
- type = fields.Selection(default="imap")
+ server_type = fields.Selection(default="imap")
folders_only = fields.Boolean(
string="Only folders, not inbox",
help="Check this field to leave imap inbox alone"
" and only retrieve mail from configured folders.",
)
- @api.onchange("type", "is_ssl", "object_id")
+ @api.onchange("server_type", "is_ssl", "object_id")
def onchange_server_type(self):
- super(FetchmailServer, self).onchange_server_type()
+ result = super().onchange_server_type()
self.state = "draft"
+ return result
- @api.multi
def fetch_mail(self):
+ result = True
for this in self:
if not this.folders_only:
- super(FetchmailServer, this).fetch_mail()
+ result = result and super(FetchmailServer, this).fetch_mail()
this.folder_ids.fetch_mail()
-
- def fields_view_get(
- self, view_id=None, view_type="form", toolbar=False, submenu=False
- ):
- """Set modifiers for form fields in folder_ids depending on algorithm.
-
- A field will be readonly and/or required if this is specified in the
- algorithm.
- """
- result = super(FetchmailServer, self).fields_view_get(
- view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu
- )
- if view_type == "form":
- view = etree.fromstring(
- result["fields"]["folder_ids"]["views"]["form"]["arch"]
- )
- modifiers = {}
- docstr = ""
- folder_model = self.env["fetchmail.server.folder"]
- match_algorithms = folder_model._get_match_algorithms()
- for algorithm in 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.xpath("//field"):
- if field.tag == "field" and field.get("name") in modifiers:
- patched_modifiers = (
- field.attrib["modifiers"]
- .replace("false", "False")
- .replace("true", "True")
- )
- original_dict = safe_eval(
- patched_modifiers, UnquoteEvalContext({}), nocopy=True
- )
- modifier_dict = modifiers[field.attrib["name"]]
- combined_dict = dict(original_dict, **modifier_dict)
- field.set("modifiers", json.dumps(combined_dict))
- 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
diff --git a/fetchmail_from_imap_folder/models/fetchmail_server_folder.py b/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
index 293b955b4..207dabb10 100644
--- a/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
+++ b/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
@@ -1,9 +1,9 @@
-# Copyright - 2013-2018 Therp BV .
+# Copyright - 2013-2024 Therp BV .
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import base64
import logging
-from odoo import _, api, fields, models
+from odoo import _, fields, models
from odoo.exceptions import UserError, ValidationError
from .. import match_algorithm
@@ -16,28 +16,8 @@ class FetchmailServerFolder(models.Model):
_rec_name = "path"
_order = "sequence"
- 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 {
- cls.__name__: cls
- for cls in get_all_subclasses(match_algorithm.base.Base)
- }
-
- def _get_match_algorithms_sel(self):
- algorithms = []
- for cls in self._get_match_algorithms().itervalues():
- algorithms.append((cls.__name__, cls.name))
- algorithms.sort()
- return algorithms
-
- server_id = fields.Many2one("fetchmail.server", "Server")
- sequence = fields.Integer("Sequence")
+ server_id = fields.Many2one("fetchmail.server")
+ sequence = fields.Integer()
state = fields.Selection(
[("draft", "Not Confirmed"), ("done", "Confirmed")],
string="Status",
@@ -47,18 +27,19 @@ def _get_match_algorithms_sel(self):
default="draft",
)
path = fields.Char(
- "Path",
required=True,
help="The path to your mail folder."
" Typically would be something like 'INBOX.myfolder'",
)
model_id = fields.Many2one(
- "ir.model", "Model", required=True, help="The model to attach emails to"
+ comodel_name="ir.model",
+ required=True,
+ ondelete="cascade",
+ help="The model to attach emails to",
)
model_field = fields.Char(
"Field (model)",
- help="The field in your model that contains the field to match "
- "against.\n"
+ 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",
@@ -69,21 +50,23 @@ def _get_match_algorithms_sel(self):
"with 'Use 1st match'",
)
match_algorithm = fields.Selection(
- _get_match_algorithms_sel,
- "Match algorithm",
+ selection=[
+ ("odoo_standard", "Odoo standard"),
+ ("email_domain", "Domain of email address"),
+ ("email_exact", "Exact mailadress"),
+ ],
required=True,
help="The algorithm used to determine which object an email matches.",
)
mail_field = fields.Char(
"Field (email)",
- help="The field in the email used for matching. Typically "
- "this is 'to' or 'from'",
+ help="The field in the email used for matching."
+ " Typically this is 'to' or 'from'",
)
delete_matching = fields.Boolean(
"Delete matches", help="Delete matched emails from server"
)
flag_nonmatching = fields.Boolean(
- "Flag nonmatching",
default=True,
help="Flag emails in the server that don't match any object in Odoo",
)
@@ -92,26 +75,34 @@ def _get_match_algorithms_sel(self):
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", help="Fill in a search filter to narrow down objects to match"
- )
+ domain = fields.Char(help="Fill in a search filter to narrow down objects to match")
msg_state = fields.Selection(
selection=[("sent", "Sent"), ("received", "Received")],
string="Message state",
default="received",
- help="The state messages fetched from this folder should be "
- "assigned in Odoo",
+ help="The state messages fetched from this folder should be assigned in Odoo",
)
- active = fields.Boolean("Active", default=True)
+ active = fields.Boolean(default=True)
- @api.multi
def get_algorithm(self):
- return self._get_match_algorithms()[self.match_algorithm]()
+ """Translate algorithm code to implementation class.
+
+ We used to load this dynamically, but having it more or less hardcoded
+ allows to adapt the UI to the selected algorithm, withouth needing
+ the (deprecated) fields_view_get trickery we used in the past.
+ """
+ self.ensure_one()
+ if self.match_algorithm == "odoo_standard":
+ return match_algorithm.odoo_standard.OdooStandard
+ if self.match_algorithm == "email_domain":
+ return match_algorithm.email_domain.EmailDomain
+ if self.match_algorithm == "email_exact":
+ return match_algorithm.email_exact.EmailExact
+ return None
- @api.multi
def button_confirm_folder(self):
+ self.write({"state": "draft"})
for this in self:
- this.write({"state": "draft"})
if not this.active:
continue
connection = this.server_id.connect()
@@ -121,7 +112,6 @@ def button_confirm_folder(self):
connection.close()
this.write({"state": "done"})
- @api.multi
def button_attach_mail_manually(self):
self.ensure_one()
return {
@@ -133,52 +123,50 @@ def button_attach_mail_manually(self):
"view_mode": "form",
}
- @api.multi
def set_draft(self):
self.write({"state": "draft"})
return True
- @api.multi
def get_msgids(self, connection, criteria):
"""Return imap ids of messages to process"""
self.ensure_one()
server = self.server_id
_logger.info(
- "start checking for emails in folder %s on server %s",
- self.path,
- server.name,
+ "start checking for emails in folder %(folder)s on server %(server)s",
+ {"folder": self.path, "server": server.name},
)
if connection.select(self.path)[0] != "OK":
raise UserError(
- _("Could not open mailbox %s on %s") % (self.path, server.name)
+ _("Could not open folder %(folder)s on server %(server)s")
+ % {"folder": self.path, "server": server.name}
)
result, msgids = connection.search(None, criteria)
if result != "OK":
raise UserError(
- _("Could not search mailbox %s on %s") % (self.path, server.name)
+ _("Could not search folder %(folder)s on server %(server)s")
+ % {"folder": self.path, "server": server.name}
)
_logger.info(
- "finished checking for emails in %s on server %s", self.path, server.name
+ "finished checking for emails in folder %(folder)s on server %(server)s",
+ {"folder": self.path, "server": server.name},
)
return msgids
- @api.multi
def fetch_msg(self, connection, msgid):
"""Select a single message from a folder."""
self.ensure_one()
- server = self.server_id
result, msgdata = connection.fetch(msgid, "(RFC822)")
if result != "OK":
raise UserError(
- _("Could not fetch %s in %s on %s") % (msgid, self.path, server.server)
+ _("Could not fetch %(msgid)s in folder %(folder)s on server %(server)s")
+ % {"msgid": msgid, "folder": self.path, "server": self.server_id.name}
)
message_org = msgdata[0][1] # rfc822 message source
mail_message = self.env["mail.thread"].message_parse(
- message_org, save_original=server.original
+ message_org, save_original=self.server_id.original
)
return (mail_message, message_org)
- @api.multi
def retrieve_imap_folder(self, connection):
"""Retrieve all mails for one IMAP folder."""
self.ensure_one()
@@ -193,10 +181,10 @@ def retrieve_imap_folder(self, connection):
except Exception:
self.env.cr.execute("rollback to savepoint apply_matching")
_logger.exception(
- "Failed to fetch mail %s from %s", msgid, self.server_id.name
+ "Failed to fetch mail %(msgid)s from server %(server)s",
+ {"msgid": msgid, "server": self.server_id.name},
)
- @api.multi
def fetch_mail(self):
"""Retrieve all mails for IMAP folders.
@@ -213,16 +201,20 @@ def fetch_mail(self):
connection.close()
except Exception:
_logger.error(
- _("General failure when trying to connect to %s server %s."),
- this.server_id.type,
- this.server_id.name,
+ (
+ "General failure when trying to connect to"
+ " %(server_type)s server %(server)s."
+ ),
+ {
+ "server_type": this.server_id.server_type,
+ "server": this.server_id.name,
+ },
exc_info=True,
)
finally:
if connection:
connection.logout()
- @api.multi
def update_msg(self, connection, msgid, matched=True, flagged=False):
"""Update msg in imap folder depending on match and settings."""
if matched:
@@ -234,7 +226,6 @@ def update_msg(self, connection, msgid, matched=True, flagged=False):
if self.flag_nonmatching:
connection.store(msgid, "+FLAGS", "\\FLAGGED")
- @api.multi
def apply_matching(self, connection, msgid, match_algorithm):
"""Return ids of objects matched"""
self.ensure_one()
@@ -252,7 +243,6 @@ def apply_matching(self, connection, msgid, match_algorithm):
)
self.update_msg(connection, msgid, matched=matched)
- @api.multi
def attach_mail(self, match_object, mail_message):
"""Attach mail to match_object."""
self.ensure_one()
@@ -270,11 +260,9 @@ def attach_mail(self, match_object, mail_message):
if len(attachment) < 2:
continue
fname, fcontent = attachment[:2]
- if isinstance(fcontent, unicode):
- fcontent = fcontent.encode("utf-8")
data_attach = {
"name": fname,
- "datas": base64.b64encode(str(fcontent)),
+ "datas": base64.b64encode(fcontent),
"datas_fname": fname,
"description": _("Mail attachment"),
"res_model": model_name,
diff --git a/fetchmail_from_imap_folder/readme/CONFIGURE.md b/fetchmail_from_imap_folder/readme/CONFIGURE.md
new file mode 100644
index 000000000..827592023
--- /dev/null
+++ b/fetchmail_from_imap_folder/readme/CONFIGURE.md
@@ -0,0 +1,28 @@
+In your fetchmail configuration, you'll find a new list field `Folders to
+monitor`. Add your folders here in IMAP notation (usually something like
+`INBOX.your_folder_name.your_subfolder_name`), choose a model to attach mails
+to and a matching algorithm to use.
+
+Exact mailaddress
+-----------------
+
+Fill in a field to search for the email address in `Field (model)`. For
+partners, this would be `email`. Also fill in the header field from the email
+to look at in `Field (email)`. If you want to match incoming mails from your
+customers, this would be `from`. You can also list header fields, so to match
+partners receiving this email, you might fill in `to,cc,bcc`.
+
+Domain of email addresses
+-------------------------
+
+Match the domain of the email address(es) found in `Field (email)`. This would
+attach a mail to `test1@example.com` to a record with `Field (model)` set to
+`test2@example.com`. Given that this is a fuzzy match, you probably want to
+check `Use 1st match`, because otherwise nothing happens if multiple possible
+matches are found.
+
+Odoo standard
+-------------
+
+This is stricly speaking no matching algorithm, but calls the model's standard
+action on new incoming mail, which is usually creating a new record.
diff --git a/fetchmail_from_imap_folder/readme/CONTRIBUTORS.md b/fetchmail_from_imap_folder/readme/CONTRIBUTORS.md
new file mode 100644
index 000000000..20ea12371
--- /dev/null
+++ b/fetchmail_from_imap_folder/readme/CONTRIBUTORS.md
@@ -0,0 +1,2 @@
+- Holger Brunn
+- Ronald Portier
diff --git a/fetchmail_from_imap_folder/readme/DESCRIPTION.md b/fetchmail_from_imap_folder/readme/DESCRIPTION.md
new file mode 100644
index 000000000..d9e7d303f
--- /dev/null
+++ b/fetchmail_from_imap_folder/readme/DESCRIPTION.md
@@ -0,0 +1,6 @@
+Adds the possibility to attach emails from a certain IMAP folder to objects,
+ie partners. Matching is done via several algorithms, ie email address, email
+address's domain or the original Odoo algorithm.
+
+This gives a simple possibility to archive emails in Odoo without a mail
+client integration.
diff --git a/fetchmail_from_imap_folder/readme/USAGE.md b/fetchmail_from_imap_folder/readme/USAGE.md
new file mode 100644
index 000000000..fc8b98e59
--- /dev/null
+++ b/fetchmail_from_imap_folder/readme/USAGE.md
@@ -0,0 +1,12 @@
+A widespread configuration is to have a shared mailbox with several folders,
+i.e. one where users drop mails they want to attach to partners. Let this
+folder be called `From partners`. Then create a folder configuration for your
+server with path `"INBOX.From partners"` (note the quotes because of the space,
+this is server dependent). Choose model `Partners`, set `Field (model)` to
+`email` and `Field (email)` to `from`. In `Domain`, you could fill in
+`[('customer', '=', True)]` to be sure to only match customer records.
+
+Now when your users drop mails into this folder, they will be fetched by Odoo
+and attached to the partner in question. After some testing, you might want to
+check `Delete matches` in your folder configuration so that this folder doesn't
+grow indefinitely.
diff --git a/fetchmail_from_imap_folder/security/ir.model.access.csv b/fetchmail_from_imap_folder/security/ir.model.access.csv
old mode 100755
new mode 100644
diff --git a/fetchmail_from_imap_folder/tests/test_match_algorithms.py b/fetchmail_from_imap_folder/tests/test_match_algorithms.py
index 9cfa6810e..0cfb1f2e3 100644
--- a/fetchmail_from_imap_folder/tests/test_match_algorithms.py
+++ b/fetchmail_from_imap_folder/tests/test_match_algorithms.py
@@ -146,12 +146,3 @@ def test_retrieve_imap_folder_domain(self):
folder.match_algorithm = "EmailDomain"
connection = MockConnection()
folder.retrieve_imap_folder(connection)
-
- def test_field_view_get(self):
- """For the moment just check execution withouth errors."""
- server_model = self.env["fetchmail.server"]
- view = server_model.fields_view_get()
- self.assertTrue(view)
- self.assertIn(
- "match_algorithm", view["fields"]["folder_ids"]["views"]["form"]["arch"]
- )
diff --git a/fetchmail_from_imap_folder/views/fetchmail_server.xml b/fetchmail_from_imap_folder/views/fetchmail_server.xml
index cd5b9a095..24ee8fc51 100644
--- a/fetchmail_from_imap_folder/views/fetchmail_server.xml
+++ b/fetchmail_from_imap_folder/views/fetchmail_server.xml
@@ -4,95 +4,104 @@
fetchmail.server.formfetchmail.server
-
+ {'required': [('type', '!=', 'imap')]}
+ >{'required': [('server_type', '!=', 'imap')]}
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+
+
+
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
index b32074bdc..ad9adf2b7 100644
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
@@ -11,7 +11,7 @@ class AttachMailManually(models.TransientModel):
_name = "fetchmail.attach.mail.manually"
name = fields.Char()
- folder_id = fields.Many2one("fetchmail.server.folder", "Folder", readonly=True)
+ folder_id = fields.Many2one(comodel_name="fetchmail.server.folder", readonly=True)
mail_ids = fields.One2many(
"fetchmail.attach.mail.manually.mail", "wizard_id", "Emails"
)
@@ -49,7 +49,6 @@ def default_get(self, fields_list):
connection.close()
return defaults
- @api.multi
def attach_mails(self):
self.ensure_one()
folder = self.folder_id
@@ -72,6 +71,7 @@ def attach_mails(self):
def fields_view_get(
self, view_id=None, view_type="form", toolbar=False, submenu=False
):
+ # TODO: Change or replace this...
result = super(AttachMailManually, self).fields_view_get(
view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu
)
@@ -92,11 +92,10 @@ class AttachMailManuallyMail(models.TransientModel):
wizard_id = fields.Many2one("fetchmail.attach.mail.manually", readonly=True)
msgid = fields.Char("Message id", readonly=True)
- subject = fields.Char("Subject", readonly=True)
- date = fields.Datetime("Date", readonly=True)
+ subject = fields.Char(readonly=True)
+ date = fields.Datetime(readonly=True)
email_from = fields.Char("From", readonly=True)
- body = fields.Html("Body", readonly=True)
+ body = fields.Html(readonly=True)
object_id = fields.Reference(
lambda self: [(m.model, m.name) for m in self.env["ir.model"].search([])],
- string="Object",
)
From 13d1803dbfeba00bf5b16b6f6f7e6cd765fdbaa3 Mon Sep 17 00:00:00 2001
From: Ronald Portier
Date: Tue, 9 Jan 2024 15:46:44 +0100
Subject: [PATCH 45/79] [MIG] fetchmail_*: adapt tests
---
.../tests/test_match_algorithms.py | 56 ++++++++++++-------
1 file changed, 35 insertions(+), 21 deletions(-)
diff --git a/fetchmail_from_imap_folder/tests/test_match_algorithms.py b/fetchmail_from_imap_folder/tests/test_match_algorithms.py
index 0cfb1f2e3..89bf75981 100644
--- a/fetchmail_from_imap_folder/tests/test_match_algorithms.py
+++ b/fetchmail_from_imap_folder/tests/test_match_algorithms.py
@@ -1,6 +1,5 @@
# Copyright - 2015-2018 Therp BV .
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from odoo import models
from odoo.tests.common import TransactionCase
from ..match_algorithm import email_domain, email_exact, odoo_standard
@@ -49,16 +48,32 @@ def search(self, charset, criteria):
class TestMatchAlgorithms(TransactionCase):
- def _get_base_folder(self):
- server_model = self.env["fetchmail.server"]
- folder_model = self.env["fetchmail.server.folder"]
- folder = folder_model.browse([models.NewId()])
- folder.model_id = self.env.ref("base.model_res_partner").id
- folder.model_field = "email"
- folder.match_algorithm = "EmailExact"
- folder.mail_field = "to,from"
- folder.server_id = server_model.browse([models.NewId()])
- return folder
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+
+ cls.server_model = cls.env["fetchmail.server"]
+ cls.folder_model = cls.env["fetchmail.server.folder"]
+ cls.server = cls.server_model.create(
+ {
+ "name": "Test Fetchmail Server",
+ "server": "imap.example.com",
+ "server_type": "imap",
+ "active": True,
+ "state": "done",
+ }
+ )
+ cls.folder = cls.folder_model.create(
+ {
+ "server_id": cls.server.id,
+ "sequence": 5,
+ "path": "INBOX",
+ "model_id": cls.env.ref("base.model_res_partner").id,
+ "model_field": "email",
+ "match_algorithm": "email_exact",
+ "mail_field": "to,from",
+ }
+ )
def do_matching(
self,
@@ -83,8 +98,7 @@ def test_email_exact(self):
"to": "demo@yourcompany.example.com",
"from": "someone@else.com",
}
- folder = self._get_base_folder()
- folder.match_algorithm = "EmailExact"
+ folder = self.folder
self.do_matching(
email_exact.EmailExact, "base.user_demo_res_partner", folder, mail_message
)
@@ -100,8 +114,8 @@ def test_email_domain(self):
"from": "someone@else.com",
"attachments": [("hello.txt", "Hello World!")],
}
- folder = self._get_base_folder()
- folder.match_algorithm = "EmailDomain"
+ folder = self.folder
+ folder.match_algorithm = "email_domain"
folder.use_first_match = True
self.do_matching(
email_domain.EmailDomain,
@@ -122,8 +136,8 @@ def test_odoo_standard(self):
"Message-Id: 42\n"
"Hello world"
)
- folder = self._get_base_folder()
- folder.match_algorithm = "OdooStandard"
+ folder = self.folder
+ folder.match_algorithm = "odoo_standard"
matcher = odoo_standard.OdooStandard()
matches = matcher.search_matches(folder, None)
self.assertEqual(len(matches), 1)
@@ -134,15 +148,15 @@ def test_odoo_standard(self):
)
def test_apply_matching_exact(self):
- folder = self._get_base_folder()
- folder.match_algorithm = "EmailExact"
+ folder = self.folder
+ folder.match_algorithm = "email_domain"
connection = MockConnection()
msgid = "<485a8041-d560-a981-5afc-d31c1f136748@acme.com>"
matcher = email_exact.EmailExact()
folder.apply_matching(connection, msgid, matcher)
def test_retrieve_imap_folder_domain(self):
- folder = self._get_base_folder()
- folder.match_algorithm = "EmailDomain"
+ folder = self.folder
+ folder.match_algorithm = "email_domain"
connection = MockConnection()
folder.retrieve_imap_folder(connection)
From 23bcaa0e7a326bb91a733c816af27370c457e894 Mon Sep 17 00:00:00 2001
From: Ronald Portier
Date: Wed, 10 Jan 2024 22:56:47 +0100
Subject: [PATCH 46/79] [FIX] fetchmail_*: adapt to Odoo 16.0 and python 3.x
---
.../match_algorithm/__init__.py | 1 -
.../match_algorithm/base.py | 14 --
.../match_algorithm/email_domain.py | 10 +-
.../match_algorithm/email_exact.py | 21 +-
.../match_algorithm/odoo_standard.py | 23 --
fetchmail_from_imap_folder/models/__init__.py | 1 +
.../models/fetchmail_server.py | 12 +-
.../models/fetchmail_server_folder.py | 202 +++++++-----------
.../models/mail_thread.py | 70 ++++++
.../security/ir.model.access.csv | 2 +
.../tests/test_match_algorithms.py | 28 +--
.../views/fetchmail_server.xml | 16 +-
.../wizard/attach_mail_manually.py | 6 +
13 files changed, 188 insertions(+), 218 deletions(-)
delete mode 100644 fetchmail_from_imap_folder/match_algorithm/base.py
delete mode 100644 fetchmail_from_imap_folder/match_algorithm/odoo_standard.py
create mode 100644 fetchmail_from_imap_folder/models/mail_thread.py
diff --git a/fetchmail_from_imap_folder/match_algorithm/__init__.py b/fetchmail_from_imap_folder/match_algorithm/__init__.py
index b74ba409c..93da714ac 100644
--- a/fetchmail_from_imap_folder/match_algorithm/__init__.py
+++ b/fetchmail_from_imap_folder/match_algorithm/__init__.py
@@ -2,4 +2,3 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import email_exact
from . import email_domain
-from . import odoo_standard
diff --git a/fetchmail_from_imap_folder/match_algorithm/base.py b/fetchmail_from_imap_folder/match_algorithm/base.py
deleted file mode 100644
index 850124a8e..000000000
--- a/fetchmail_from_imap_folder/match_algorithm/base.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright - 2013-2024 Therp BV .
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-
-
-class Base(object):
- def search_matches(self, folder, mail_message):
- """Returns recordset found for model with mail_message."""
- return []
-
- def handle_match(
- self, connection, match_object, folder, mail_message, mail_message_org, msgid
- ):
- """Do whatever it takes to handle a match"""
- folder.attach_mail(match_object, mail_message)
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_domain.py b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
index 7ad6bfb79..a25645949 100644
--- a/fetchmail_from_imap_folder/match_algorithm/email_domain.py
+++ b/fetchmail_from_imap_folder/match_algorithm/email_domain.py
@@ -9,21 +9,21 @@ class EmailDomain(EmailExact):
Beware of match_first here, this is most likely to get it wrong (gmail).
"""
- def search_matches(self, folder, mail_message):
+ def search_matches(self, folder, message_dict):
"""Returns recordset of matching objects."""
- matches = super().search_matches(folder, mail_message)
+ matches = super().search_matches(folder, message_dict)
if not matches:
object_model = folder.env[folder.model_id.model]
domains = []
- for addr in self._get_mailaddresses(folder, mail_message):
+ for addr in self._get_mailaddresses(folder, message_dict):
domains.append(addr.split("@")[-1])
matches = object_model.search(
self._get_mailaddress_search_domain(
folder,
- mail_message,
+ message_dict,
operator="like",
values=["%@" + domain for domain in set(domains)],
),
order=folder.model_order,
)
- return matches
+ return matches.ids
diff --git a/fetchmail_from_imap_folder/match_algorithm/email_exact.py b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
index ea4ed1e5e..b454f8d0a 100644
--- a/fetchmail_from_imap_folder/match_algorithm/email_exact.py
+++ b/fetchmail_from_imap_folder/match_algorithm/email_exact.py
@@ -3,24 +3,22 @@
from odoo.tools.mail import email_split
from odoo.tools.safe_eval import safe_eval
-from .base import Base
-
-class EmailExact(Base):
+class EmailExact:
"""Search for exactly the mailadress as noted in the email"""
- def _get_mailaddresses(self, folder, mail_message):
+ def _get_mailaddresses(self, folder, message_dict):
mailaddresses = []
fields = folder.mail_field.split(",")
for field in fields:
- if field in mail_message:
- mailaddresses += email_split(mail_message[field])
+ if field in message_dict:
+ mailaddresses += email_split(message_dict[field])
return [addr.lower() for addr in mailaddresses]
def _get_mailaddress_search_domain(
- self, folder, mail_message, operator="=", values=None
+ self, folder, message_dict, operator="=", values=None
):
- mailaddresses = values or self._get_mailaddresses(folder, mail_message)
+ mailaddresses = values or self._get_mailaddresses(folder, message_dict)
if not mailaddresses:
return [(0, "=", 1)]
search_domain = (
@@ -30,8 +28,9 @@ def _get_mailaddress_search_domain(
)
return search_domain
- def search_matches(self, folder, mail_message):
+ def search_matches(self, folder, message_dict):
"""Returns recordset of matching objects."""
object_model = folder.env[folder.model_id.model]
- search_domain = self._get_mailaddress_search_domain(folder, mail_message)
- return object_model.search(search_domain, order=folder.model_order)
+ search_domain = self._get_mailaddress_search_domain(folder, message_dict)
+ matches = object_model.search(search_domain, order=folder.model_order)
+ return matches.ids
diff --git a/fetchmail_from_imap_folder/match_algorithm/odoo_standard.py b/fetchmail_from_imap_folder/match_algorithm/odoo_standard.py
deleted file mode 100644
index d2b77dde1..000000000
--- a/fetchmail_from_imap_folder/match_algorithm/odoo_standard.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright - 2013-2024 Therp BV .
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from .base import Base
-
-
-class OdooStandard(Base):
- """No search at all. Use Odoo's standard mechanism to attach mails to
- mail.thread objects. Note that this algorithm always matches."""
-
- def search_matches(self, folder, mail_message):
- """Always match. Duplicates will be fished out by message_id"""
- return [True]
-
- def handle_match(
- self, connection, match_object, folder, mail_message, mail_message_org, msgid
- ):
- thread_model = folder.env["mail.thread"]
- thread_model.message_process(
- folder.model_id.model,
- mail_message_org,
- save_original=folder.server_id.original,
- strip_attachments=(not folder.server_id.attach),
- )
diff --git a/fetchmail_from_imap_folder/models/__init__.py b/fetchmail_from_imap_folder/models/__init__.py
index 0340cfd07..c5a9d317e 100644
--- a/fetchmail_from_imap_folder/models/__init__.py
+++ b/fetchmail_from_imap_folder/models/__init__.py
@@ -2,3 +2,4 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import fetchmail_server
from . import fetchmail_server_folder
+from . import mail_thread
diff --git a/fetchmail_from_imap_folder/models/fetchmail_server.py b/fetchmail_from_imap_folder/models/fetchmail_server.py
index 2e0d93739..7d344395a 100644
--- a/fetchmail_from_imap_folder/models/fetchmail_server.py
+++ b/fetchmail_from_imap_folder/models/fetchmail_server.py
@@ -19,7 +19,10 @@ def _compute_folders_available(self):
"""Retrieve available folders from IMAP server."""
def parse_list_response(line):
- flags, delimiter, mailbox_name = list_response_pattern.match(line).groups()
+ string_line = line.decode("utf-8")
+ flags, delimiter, mailbox_name = list_response_pattern.match(
+ string_line
+ ).groups()
mailbox_name = mailbox_name.strip('"')
return (flags, delimiter, mailbox_name)
@@ -34,7 +37,7 @@ def parse_list_response(line):
continue
folders_available = []
for folder_entry in list_result[1]:
- folders_available.append(parse_list_response(str(folder_entry))[2])
+ folders_available.append(parse_list_response(folder_entry)[2])
this.folders_available = "\n".join(folders_available)
connection.logout()
@@ -47,13 +50,14 @@ def parse_list_response(line):
string="Folders",
context={"active_test": False},
)
- object_id = fields.Many2one(required=False) # comodel_name='ir.model'
- server_type = fields.Selection(default="imap")
folders_only = fields.Boolean(
string="Only folders, not inbox",
help="Check this field to leave imap inbox alone"
" and only retrieve mail from configured folders.",
)
+ # Below existing fields, that are modified by this module.
+ object_id = fields.Many2one(required=False) # comodel_name='ir.model'
+ server_type = fields.Selection(default="imap")
@api.onchange("server_type", "is_ssl", "object_id")
def onchange_server_type(self):
diff --git a/fetchmail_from_imap_folder/models/fetchmail_server_folder.py b/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
index 207dabb10..a73359675 100644
--- a/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
+++ b/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
@@ -1,18 +1,18 @@
# Copyright - 2013-2024 Therp BV .
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-import base64
import logging
from odoo import _, fields, models
from odoo.exceptions import UserError, ValidationError
-from .. import match_algorithm
-
_logger = logging.getLogger(__name__)
class FetchmailServerFolder(models.Model):
+ """Define folders (IMAP mailboxes) from which to fetch mail."""
+
_name = "fetchmail.server.folder"
+ _description = __doc__
_rec_name = "path"
_order = "sequence"
@@ -84,22 +84,6 @@ class FetchmailServerFolder(models.Model):
)
active = fields.Boolean(default=True)
- def get_algorithm(self):
- """Translate algorithm code to implementation class.
-
- We used to load this dynamically, but having it more or less hardcoded
- allows to adapt the UI to the selected algorithm, withouth needing
- the (deprecated) fields_view_get trickery we used in the past.
- """
- self.ensure_one()
- if self.match_algorithm == "odoo_standard":
- return match_algorithm.odoo_standard.OdooStandard
- if self.match_algorithm == "email_domain":
- return match_algorithm.email_domain.EmailDomain
- if self.match_algorithm == "email_exact":
- return match_algorithm.email_exact.EmailExact
- return None
-
def button_confirm_folder(self):
self.write({"state": "draft"})
for this in self:
@@ -127,6 +111,53 @@ def set_draft(self):
self.write({"state": "draft"})
return True
+ def fetch_mail(self):
+ """Retrieve all mails for IMAP folders.
+
+ We will use a separate connection for each folder.
+ """
+ for this in self:
+ if not this.active or this.state != "done":
+ continue
+ connection = None
+ try:
+ # New connection per folder
+ connection = this.server_id.connect()
+ this.retrieve_imap_folder(connection)
+ connection.close()
+ except Exception:
+ _logger.error(
+ (
+ "General failure when trying to connect to"
+ " %(server_type)s server %(server)s."
+ ),
+ {
+ "server_type": this.server_id.server_type,
+ "server": this.server_id.name,
+ },
+ exc_info=True,
+ )
+ finally:
+ if connection:
+ connection.logout()
+
+ def retrieve_imap_folder(self, connection):
+ """Retrieve all mails for one IMAP folder."""
+ self.ensure_one()
+ msgids = self.get_msgids(connection, "UNDELETED")
+ for msgid in msgids[0].split():
+ # We will accept exceptions for single messages
+ try:
+ self.env.cr.execute("savepoint apply_matching")
+ self.apply_matching(connection, msgid)
+ self.env.cr.execute("release savepoint apply_matching")
+ except Exception:
+ self.env.cr.execute("rollback to savepoint apply_matching")
+ _logger.exception(
+ "Failed to fetch mail %(msgid)s from server %(server)s",
+ {"msgid": msgid, "server": self.server_id.name},
+ )
+
def get_msgids(self, connection, criteria):
"""Return imap ids of messages to process"""
self.ensure_one()
@@ -152,6 +183,28 @@ def get_msgids(self, connection, criteria):
)
return msgids
+ def apply_matching(self, connection, msgid):
+ """Return ids of objects matched"""
+ self.ensure_one()
+ thread_model = self.env["mail.thread"]
+ message_org = self.fetch_msg(connection, msgid)
+ custom_values = (
+ None
+ if self.match_algorithm == "odoo_standard"
+ else {
+ "folder": self,
+ }
+ )
+ thread_id = thread_model.message_process(
+ self.model_id.model,
+ message_org,
+ custom_values=custom_values,
+ save_original=self.server_id.original,
+ strip_attachments=(not self.server_id.attach),
+ )
+ matched = True if thread_id else False
+ self.update_msg(connection, msgid, matched=matched)
+
def fetch_msg(self, connection, msgid):
"""Select a single message from a folder."""
self.ensure_one()
@@ -162,58 +215,7 @@ def fetch_msg(self, connection, msgid):
% {"msgid": msgid, "folder": self.path, "server": self.server_id.name}
)
message_org = msgdata[0][1] # rfc822 message source
- mail_message = self.env["mail.thread"].message_parse(
- message_org, save_original=self.server_id.original
- )
- return (mail_message, message_org)
-
- def retrieve_imap_folder(self, connection):
- """Retrieve all mails for one IMAP folder."""
- self.ensure_one()
- msgids = self.get_msgids(connection, "UNDELETED")
- match_algorithm = self.get_algorithm()
- for msgid in msgids[0].split():
- # We will accept exceptions for single messages
- try:
- self.env.cr.execute("savepoint apply_matching")
- self.apply_matching(connection, msgid, match_algorithm)
- self.env.cr.execute("release savepoint apply_matching")
- except Exception:
- self.env.cr.execute("rollback to savepoint apply_matching")
- _logger.exception(
- "Failed to fetch mail %(msgid)s from server %(server)s",
- {"msgid": msgid, "server": self.server_id.name},
- )
-
- def fetch_mail(self):
- """Retrieve all mails for IMAP folders.
-
- We will use a separate connection for each folder.
- """
- for this in self:
- if not this.active or this.state != "done":
- continue
- connection = None
- try:
- # New connection per folder
- connection = this.server_id.connect()
- this.retrieve_imap_folder(connection)
- connection.close()
- except Exception:
- _logger.error(
- (
- "General failure when trying to connect to"
- " %(server_type)s server %(server)s."
- ),
- {
- "server_type": this.server_id.server_type,
- "server": this.server_id.name,
- },
- exc_info=True,
- )
- finally:
- if connection:
- connection.logout()
+ return message_org
def update_msg(self, connection, msgid, matched=True, flagged=False):
"""Update msg in imap folder depending on match and settings."""
@@ -225,61 +227,3 @@ def update_msg(self, connection, msgid, matched=True, flagged=False):
else:
if self.flag_nonmatching:
connection.store(msgid, "+FLAGS", "\\FLAGGED")
-
- def apply_matching(self, connection, msgid, match_algorithm):
- """Return ids of objects matched"""
- self.ensure_one()
- mail_message, message_org = self.fetch_msg(connection, msgid)
- if self.env["mail.message"].search(
- [("message_id", "=", mail_message["message_id"])]
- ):
- # Ignore mails that have been handled already
- return
- matches = match_algorithm.search_matches(self, mail_message)
- matched = matches and (len(matches) == 1 or self.match_first)
- if matched:
- match_algorithm.handle_match(
- connection, matches[0], self, mail_message, message_org, msgid
- )
- self.update_msg(connection, msgid, matched=matched)
-
- def attach_mail(self, match_object, mail_message):
- """Attach mail to match_object."""
- self.ensure_one()
- partner = False
- model_name = self.model_id.model
- if model_name == "res.partner":
- partner = match_object
- elif "partner_id" in self.env[model_name]._fields:
- partner = match_object.partner_id
- attachments = []
- if self.server_id.attach and mail_message.get("attachments"):
- for attachment in mail_message["attachments"]:
- # Attachment should at least have filename and data, but
- # might have some extra element(s)
- if len(attachment) < 2:
- continue
- fname, fcontent = attachment[:2]
- data_attach = {
- "name": fname,
- "datas": base64.b64encode(fcontent),
- "datas_fname": fname,
- "description": _("Mail attachment"),
- "res_model": model_name,
- "res_id": match_object.id,
- }
- attachments.append(self.env["ir.attachment"].create(data_attach))
- self.env["mail.message"].create(
- {
- "author_id": partner and partner.id or False,
- "model": model_name,
- "res_id": match_object.id,
- "message_type": "email",
- "body": mail_message.get("body"),
- "subject": mail_message.get("subject"),
- "email_from": mail_message.get("from"),
- "date": mail_message.get("date"),
- "message_id": mail_message.get("message_id"),
- "attachment_ids": [(6, 0, [a.id for a in attachments])],
- }
- )
diff --git a/fetchmail_from_imap_folder/models/mail_thread.py b/fetchmail_from_imap_folder/models/mail_thread.py
new file mode 100644
index 000000000..c39c33046
--- /dev/null
+++ b/fetchmail_from_imap_folder/models/mail_thread.py
@@ -0,0 +1,70 @@
+# Copyright - 2024 Therp BV .
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+import logging
+
+from odoo import api, models
+
+from .. import match_algorithm
+
+_logger = logging.getLogger(__name__)
+
+
+class MailThread(models.AbstractModel):
+ _inherit = "mail.thread"
+
+ @api.model
+ def message_route(
+ self,
+ message,
+ message_dict,
+ model=None,
+ thread_id=None,
+ custom_values=None,
+ ):
+ """Override to apply matching algorithm to determine thread_id if requested."""
+ if not thread_id and custom_values and "folder" in custom_values:
+ thread_id = self._find_match(custom_values, message_dict)
+ if not thread_id:
+ return [] # This will ultimately return thread_id = False
+ return super().message_route(
+ message,
+ message_dict,
+ model=model,
+ thread_id=thread_id,
+ custom_values=custom_values,
+ )
+
+ @api.model
+ def _find_match(self, custom_values, message_dict):
+ """Try to find existing object to link mail to."""
+ folder = custom_values.pop("folder")
+ matcher = self._get_algorithm(folder.match_algorithm)
+ if not matcher:
+ return None
+ matches = matcher.search_matches(folder, message_dict)
+ if not matches:
+ _logger.info(
+ "No match found for message %(subject)s with msgid %(msgid)s",
+ {
+ "subject": message_dict.get("subject", "no subject"),
+ "msgid": message_dict.get("message_id", "no msgid"),
+ },
+ )
+ return None
+ matched = len(matches) == 1 or folder.match_first
+ return matched and matches[0] or None
+
+ @api.model
+ def _get_algorithm(self, algorithm):
+ """Translate algorithm code to implementation class.
+
+ We used to load this dynamically, but having it more or less hardcoded
+ allows to adapt the UI to the selected algorithm, withouth needing
+ the (deprecated) fields_view_get trickery we used in the past.
+ """
+ if algorithm == "email_domain":
+ return match_algorithm.email_domain.EmailDomain()
+ if algorithm == "email_exact":
+ return match_algorithm.email_exact.EmailExact()
+ _logger.error("Unknown algorithm %(algorithm)s", {"algorithm": algorithm})
+ return None
diff --git a/fetchmail_from_imap_folder/security/ir.model.access.csv b/fetchmail_from_imap_folder/security/ir.model.access.csv
index c63f46bb8..50c676fb3 100644
--- a/fetchmail_from_imap_folder/security/ir.model.access.csv
+++ b/fetchmail_from_imap_folder/security/ir.model.access.csv
@@ -1,2 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_model_fetchmail_server_folder,fetchmail.server.folder,model_fetchmail_server_folder,base.group_system,1,1,1,1
+access_fetchmail_attach_mail_manually,access_fetchmail_attach_mail_manually,model_fetchmail_attach_mail_manually,base.group_system,1,1,1,1
+access_fetchmail_attach_mail_manually_mail,access_fetchmail_attach_mail_manually_mail,model_fetchmail_attach_mail_manually_mail,base.group_system,1,1,1,1
diff --git a/fetchmail_from_imap_folder/tests/test_match_algorithms.py b/fetchmail_from_imap_folder/tests/test_match_algorithms.py
index 89bf75981..523e32839 100644
--- a/fetchmail_from_imap_folder/tests/test_match_algorithms.py
+++ b/fetchmail_from_imap_folder/tests/test_match_algorithms.py
@@ -2,7 +2,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.tests.common import TransactionCase
-from ..match_algorithm import email_domain, email_exact, odoo_standard
+from ..match_algorithm import email_domain, email_exact
MSG_BODY = [
(
@@ -116,7 +116,7 @@ def test_email_domain(self):
}
folder = self.folder
folder.match_algorithm = "email_domain"
- folder.use_first_match = True
+ folder.match_first = True
self.do_matching(
email_domain.EmailDomain,
"base.res_partner_address_31",
@@ -128,32 +128,12 @@ def test_email_domain(self):
mail_message["subject"],
)
- def test_odoo_standard(self):
- mail_message_org = (
- "To: demo@yourcompany.example.com\n"
- "From: someone@else.com\n"
- "Subject: testsubject\n"
- "Message-Id: 42\n"
- "Hello world"
- )
- folder = self.folder
- folder.match_algorithm = "odoo_standard"
- matcher = odoo_standard.OdooStandard()
- matches = matcher.search_matches(folder, None)
- self.assertEqual(len(matches), 1)
- matcher.handle_match(None, matches[0], folder, None, mail_message_org, None)
- self.assertIn(
- "Hello world",
- self.env["mail.message"].search([("subject", "=", "testsubject")]).body,
- )
-
def test_apply_matching_exact(self):
folder = self.folder
- folder.match_algorithm = "email_domain"
+ folder.match_algorithm = "email_exact"
connection = MockConnection()
msgid = "<485a8041-d560-a981-5afc-d31c1f136748@acme.com>"
- matcher = email_exact.EmailExact()
- folder.apply_matching(connection, msgid, matcher)
+ folder.apply_matching(connection, msgid)
def test_retrieve_imap_folder_domain(self):
folder = self.folder
diff --git a/fetchmail_from_imap_folder/views/fetchmail_server.xml b/fetchmail_from_imap_folder/views/fetchmail_server.xml
index 24ee8fc51..47a383e3f 100644
--- a/fetchmail_from_imap_folder/views/fetchmail_server.xml
+++ b/fetchmail_from_imap_folder/views/fetchmail_server.xml
@@ -11,14 +11,14 @@
name="attrs"
>{'required': [('server_type', '!=', 'imap')]}
-
-
-
+
+
+
@@ -58,10 +58,12 @@
states="done"
/>
-
-
-
-
+
+
+
+
+
+
Date: Thu, 25 Apr 2024 13:00:31 +0200
Subject: [PATCH 47/79] [IMP] fetchmail_.._folder: optionally archive messages
automatically
---
fetchmail_from_imap_folder/README.rst | 6 +-
.../models/fetchmail_server_folder.py | 27 +
fetchmail_from_imap_folder/readme/USAGE.md | 4 +
.../static/description/index.html | 481 ++++++++++++++++++
.../views/fetchmail_server.xml | 2 +
5 files changed, 519 insertions(+), 1 deletion(-)
create mode 100644 fetchmail_from_imap_folder/static/description/index.html
diff --git a/fetchmail_from_imap_folder/README.rst b/fetchmail_from_imap_folder/README.rst
index 5e0873f7a..431c9a66c 100644
--- a/fetchmail_from_imap_folder/README.rst
+++ b/fetchmail_from_imap_folder/README.rst
@@ -7,7 +7,7 @@ Email gateway - folders
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !! source digest: sha256:95f6645118da34dd962fa794f5fca9c8797579a9a585d80228407f4997e9ba91
+ !! source digest: sha256:907101d997473fcc276317ee6d3bf95f2f005eab22b585dd59644a757959ca10
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
@@ -91,6 +91,10 @@ Odoo and attached to the partner in question. After some testing, you
might want to check ``Delete matches`` in your folder configuration so
that this folder doesn't grow indefinitely.
+Another way to prevent having to process ever more messages from the
+folder to read is to automatically move all processed messages to an
+archive folder that can be specified.
+
Bug Tracker
===========
diff --git a/fetchmail_from_imap_folder/models/fetchmail_server_folder.py b/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
index a73359675..cd7e36b48 100644
--- a/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
+++ b/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
@@ -31,6 +31,9 @@ class FetchmailServerFolder(models.Model):
help="The path to your mail folder."
" Typically would be something like 'INBOX.myfolder'",
)
+ archive_path = fields.Char(
+ help="The path where successfully retrieved messages will be stored.",
+ )
model_id = fields.Many2one(
comodel_name="ir.model",
required=True,
@@ -123,6 +126,7 @@ def fetch_mail(self):
try:
# New connection per folder
connection = this.server_id.connect()
+ this.check_imap_archive_folder(connection)
this.retrieve_imap_folder(connection)
connection.close()
except Exception:
@@ -141,6 +145,20 @@ def fetch_mail(self):
if connection:
connection.logout()
+ def check_imap_archive_folder(self, connection):
+ """If archive folder specified, check existance and create when needed."""
+ self.ensure_one()
+ server = self.server_id
+ if not self.archive_path:
+ return
+ if connection.select(self.archive_path)[0] != "OK":
+ connection.create(self.archive_path)
+ if connection.select(self.archive_path)[0] != "OK":
+ raise UserError(
+ _("Could not create archive folder %(folder)s on server %(server)s")
+ % {"folder": self.archive_path, "server": server.name}
+ )
+
def retrieve_imap_folder(self, connection):
"""Retrieve all mails for one IMAP folder."""
self.ensure_one()
@@ -204,6 +222,8 @@ def apply_matching(self, connection, msgid):
)
matched = True if thread_id else False
self.update_msg(connection, msgid, matched=matched)
+ if self.archive_path:
+ self._archive_msg(connection, msgid)
def fetch_msg(self, connection, msgid):
"""Select a single message from a folder."""
@@ -227,3 +247,10 @@ def update_msg(self, connection, msgid, matched=True, flagged=False):
else:
if self.flag_nonmatching:
connection.store(msgid, "+FLAGS", "\\FLAGGED")
+
+ def _archive_msg(self, connection, msgid):
+ """Archive message. Folder should already have been created."""
+ self.ensure_one()
+ connection.copy(msgid, self.archive_path)
+ connection.store(msgid, "+FLAGS", "\\Deleted")
+ connection.expunge()
diff --git a/fetchmail_from_imap_folder/readme/USAGE.md b/fetchmail_from_imap_folder/readme/USAGE.md
index fc8b98e59..0c7af37f7 100644
--- a/fetchmail_from_imap_folder/readme/USAGE.md
+++ b/fetchmail_from_imap_folder/readme/USAGE.md
@@ -10,3 +10,7 @@ Now when your users drop mails into this folder, they will be fetched by Odoo
and attached to the partner in question. After some testing, you might want to
check `Delete matches` in your folder configuration so that this folder doesn't
grow indefinitely.
+
+Another way to prevent having to process ever more messages from the folder
+to read is to automatically move all processed messages to an archive folder
+that can be specified.
diff --git a/fetchmail_from_imap_folder/static/description/index.html b/fetchmail_from_imap_folder/static/description/index.html
new file mode 100644
index 000000000..a040a917e
--- /dev/null
+++ b/fetchmail_from_imap_folder/static/description/index.html
@@ -0,0 +1,481 @@
+
+
+
+
+
+
+Email gateway - folders
+
+
+
+
+
Email gateway - folders
+
+
+
+
Adds the possibility to attach emails from a certain IMAP folder to
+objects, ie partners. Matching is done via several algorithms, ie email
+address, email address’s domain or the original Odoo algorithm.
+
This gives a simple possibility to archive emails in Odoo without a mail
+client integration.
In your fetchmail configuration, you’ll find a new list field
+Folders to monitor. Add your folders here in IMAP notation (usually
+something like INBOX.your_folder_name.your_subfolder_name), choose a
+model to attach mails to and a matching algorithm to use.
Fill in a field to search for the email address in Field (model).
+For partners, this would be email. Also fill in the header field
+from the email to look at in Field (email). If you want to match
+incoming mails from your customers, this would be from. You can also
+list header fields, so to match partners receiving this email, you might
+fill in to,cc,bcc.
Match the domain of the email address(es) found in Field (email).
+This would attach a mail to test1@example.com to a record with
+Field (model) set to test2@example.com. Given that this is a
+fuzzy match, you probably want to check Use 1st match, because
+otherwise nothing happens if multiple possible matches are found.
This is stricly speaking no matching algorithm, but calls the model’s
+standard action on new incoming mail, which is usually creating a new
+record.
A widespread configuration is to have a shared mailbox with several
+folders, i.e. one where users drop mails they want to attach to
+partners. Let this folder be called From partners. Then create a
+folder configuration for your server with path "INBOX.From partners"
+(note the quotes because of the space, this is server dependent). Choose
+model Partners, set Field (model) to email and
+Field (email) to from. In Domain, you could fill in
+[('customer','=', True)] to be sure to only match customer records.
+
Now when your users drop mails into this folder, they will be fetched by
+Odoo and attached to the partner in question. After some testing, you
+might want to check Delete matches in your folder configuration so
+that this folder doesn’t grow indefinitely.
+
Another way to prevent having to process ever more messages from the
+folder to read is to automatically move all processed messages to an
+archive folder that can be specified.
Bugs are tracked on GitHub Issues.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us to smash it by providing a detailed and welcomed
+feedback.
+
Do not contact contributors directly about support or help with technical issues.
OCA, or the Odoo Community Association, is a nonprofit organization whose
+mission is to support the collaborative development of Odoo features and
+promote its widespread use.
+
+
diff --git a/fetchmail_from_imap_folder/views/fetchmail_server.xml b/fetchmail_from_imap_folder/views/fetchmail_server.xml
index 47a383e3f..9cf93de4b 100644
--- a/fetchmail_from_imap_folder/views/fetchmail_server.xml
+++ b/fetchmail_from_imap_folder/views/fetchmail_server.xml
@@ -24,6 +24,7 @@
+
@@ -98,6 +99,7 @@
+
From 2b227e07166a61d0fac95815ae8f8031304c4b6a Mon Sep 17 00:00:00 2001
From: Ronald Portier
Date: Sat, 11 May 2024 12:37:21 +0200
Subject: [PATCH 48/79] [IMP] fetch..._folder: Add contributor and maintainer
---
fetchmail_from_imap_folder/README.rst | 11 ++++++++++-
fetchmail_from_imap_folder/__manifest__.py | 1 +
fetchmail_from_imap_folder/readme/CONTRIBUTORS.md | 1 +
.../static/description/index.html | 5 ++++-
4 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/fetchmail_from_imap_folder/README.rst b/fetchmail_from_imap_folder/README.rst
index 431c9a66c..4df7f2415 100644
--- a/fetchmail_from_imap_folder/README.rst
+++ b/fetchmail_from_imap_folder/README.rst
@@ -7,7 +7,7 @@ Email gateway - folders
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !! source digest: sha256:907101d997473fcc276317ee6d3bf95f2f005eab22b585dd59644a757959ca10
+ !! source digest: sha256:c6afe0f3176202f575e0bfd827acadf557acced4a2dccdb2a55dafc0337abc87
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
@@ -118,6 +118,7 @@ Contributors
- Holger Brunn hbrunn@therp.nl
- Ronald Portier ronald@therp.nl
+- Alexandre Fayolle alexandre.fayolle@camptocamp.com
Maintainers
-----------
@@ -132,6 +133,14 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
+.. |maintainer-NL66278| image:: https://github.com/NL66278.png?size=40px
+ :target: https://github.com/NL66278
+ :alt: NL66278
+
+Current `maintainer `__:
+
+|maintainer-NL66278|
+
This module is part of the `OCA/server-tools `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/fetchmail_from_imap_folder/__manifest__.py b/fetchmail_from_imap_folder/__manifest__.py
index 14e69453c..4313306f0 100644
--- a/fetchmail_from_imap_folder/__manifest__.py
+++ b/fetchmail_from_imap_folder/__manifest__.py
@@ -5,6 +5,7 @@
"summary": "Attach mails in an IMAP folder to existing objects",
"version": "16.0.1.1.0",
"author": "Therp BV,Odoo Community Association (OCA)",
+ "maintainers": ["NL66278"],
"website": "https://github.com/OCA/server-tools",
"license": "AGPL-3",
"category": "Tools",
diff --git a/fetchmail_from_imap_folder/readme/CONTRIBUTORS.md b/fetchmail_from_imap_folder/readme/CONTRIBUTORS.md
index 20ea12371..dcfe0c81f 100644
--- a/fetchmail_from_imap_folder/readme/CONTRIBUTORS.md
+++ b/fetchmail_from_imap_folder/readme/CONTRIBUTORS.md
@@ -1,2 +1,3 @@
- Holger Brunn
- Ronald Portier
+- Alexandre Fayolle
diff --git a/fetchmail_from_imap_folder/static/description/index.html b/fetchmail_from_imap_folder/static/description/index.html
index a040a917e..3c1707bd5 100644
--- a/fetchmail_from_imap_folder/static/description/index.html
+++ b/fetchmail_from_imap_folder/static/description/index.html
@@ -367,7 +367,7 @@
Email gateway - folders
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!! source digest: sha256:907101d997473fcc276317ee6d3bf95f2f005eab22b585dd59644a757959ca10
+!! source digest: sha256:c6afe0f3176202f575e0bfd827acadf557acced4a2dccdb2a55dafc0337abc87
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
Adds the possibility to attach emails from a certain IMAP folder to
@@ -463,6 +463,7 @@
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!! source digest: sha256:c6afe0f3176202f575e0bfd827acadf557acced4a2dccdb2a55dafc0337abc87
+!! source digest: sha256:c3af3dec7c2b9f46c88cd4355883c08deb3d7c03e21735f2f1b5ca4131aa7e69
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
Adds the possibility to attach emails from a certain IMAP folder to
@@ -469,7 +469,9 @@
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
diff --git a/fetchmail_from_imap_folder/tests/test_match_algorithms.py b/fetchmail_from_imap_folder/tests/test_match_algorithms.py
index 04018f42b..bdd406c37 100644
--- a/fetchmail_from_imap_folder/tests/test_match_algorithms.py
+++ b/fetchmail_from_imap_folder/tests/test_match_algorithms.py
@@ -56,7 +56,14 @@ def setUpClass(cls):
cls.partner_model = cls.env["res.partner"]
cls.test_partner = cls.partner_model.with_context(tracking_disable=True).create(
- {"name": "Reynaert de Vos", "email": TEST_EMAIL, "is_company": False}
+ {
+ "name": "Reynaert de Vos",
+ "email": TEST_EMAIL,
+ "is_company": False,
+ "category_id": [
+ (6, 0, []),
+ ],
+ }
)
cls.server_model = cls.env["fetchmail.server"]
cls.folder_model = cls.env["fetchmail.server.folder"]
@@ -81,6 +88,40 @@ def setUpClass(cls):
"mail_field": "from",
}
)
+ cls.partner_ir_model = cls.env["ir.model"].search(
+ [
+ ("model", "=", cls.partner_model._name),
+ ],
+ limit=1,
+ )
+ cls.partner_category = cls.env.ref("base.res_partner_category_12")
+ cls.server_action = cls.env["ir.actions.server"].create(
+ {
+ "name": "Action Set Active Partner",
+ "model_id": cls.partner_ir_model.id,
+ "state": "object_write",
+ "code": False,
+ "fields_lines": [
+ (
+ 0,
+ 0,
+ {
+ "col1": cls.env["ir.model.fields"]
+ .search(
+ [
+ ("name", "=", "category_id"),
+ ("model_id", "=", cls.partner_ir_model.id),
+ ],
+ limit=1,
+ )
+ .id,
+ "evaluation_type": "equation",
+ "value": str([cls.partner_category.id]),
+ },
+ ),
+ ],
+ }
+ )
def test_email_exact(self):
"""A message to ronald@acme.com should be linked to partner with that email."""
@@ -122,3 +163,15 @@ def test_retrieve_imap_folder_domain(self):
folder.match_algorithm = "email_domain"
connection = MockConnection()
folder.retrieve_imap_folder(connection)
+
+ def test_non_action(self):
+ connection = MockConnection()
+ self.folder.action_id = False
+ self.folder.apply_matching(connection, "1")
+ self.assertFalse(self.test_partner.category_id)
+
+ def test_action(self):
+ connection = MockConnection()
+ self.folder.action_id = self.server_action
+ self.folder.apply_matching(connection, "1")
+ self.assertEqual(self.partner_category, self.test_partner.category_id)
diff --git a/fetchmail_from_imap_folder/views/fetchmail_server.xml b/fetchmail_from_imap_folder/views/fetchmail_server.xml
index 4748da163..cd2baf067 100644
--- a/fetchmail_from_imap_folder/views/fetchmail_server.xml
+++ b/fetchmail_from_imap_folder/views/fetchmail_server.xml
@@ -26,6 +26,7 @@
+
@@ -63,6 +64,7 @@
+
Date: Wed, 24 Jul 2024 08:17:38 +0200
Subject: [PATCH 53/79] [IMP] Add option to read e-mails unseen
---
fetchmail_from_imap_folder/README.rst | 2 +-
fetchmail_from_imap_folder/__manifest__.py | 2 +-
fetchmail_from_imap_folder/i18n/de.po | 12 +
fetchmail_from_imap_folder/i18n/es.po | 12 +
.../i18n/fetchmail_attach_from_folder.pot | 12 +
fetchmail_from_imap_folder/i18n/fr.po | 12 +
fetchmail_from_imap_folder/i18n/fr_CA.po | 12 +
fetchmail_from_imap_folder/i18n/it.po | 209 +++++++++++-------
fetchmail_from_imap_folder/i18n/pt_BR.po | 12 +
fetchmail_from_imap_folder/i18n/ru.po | 12 +
fetchmail_from_imap_folder/i18n/sl.po | 12 +
.../models/fetchmail_server_folder.py | 9 +-
.../static/description/index.html | 2 +-
.../views/fetchmail_server.xml | 1 +
.../wizard/attach_mail_manually.py | 2 +-
15 files changed, 234 insertions(+), 89 deletions(-)
diff --git a/fetchmail_from_imap_folder/README.rst b/fetchmail_from_imap_folder/README.rst
index 2a61cdf35..4825e7213 100644
--- a/fetchmail_from_imap_folder/README.rst
+++ b/fetchmail_from_imap_folder/README.rst
@@ -7,7 +7,7 @@ Email gateway - folders
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !! source digest: sha256:c3af3dec7c2b9f46c88cd4355883c08deb3d7c03e21735f2f1b5ca4131aa7e69
+ !! source digest: sha256:b5ee1bcd71066b368da923b5aa94b37da6f960f51ffd129b199967db10b576d7
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
diff --git a/fetchmail_from_imap_folder/__manifest__.py b/fetchmail_from_imap_folder/__manifest__.py
index 2fbb4ca32..b6dcce88b 100644
--- a/fetchmail_from_imap_folder/__manifest__.py
+++ b/fetchmail_from_imap_folder/__manifest__.py
@@ -3,7 +3,7 @@
{
"name": "Email gateway - folders",
"summary": "Attach mails in an IMAP folder to existing objects",
- "version": "16.0.1.3.0",
+ "version": "16.0.1.4.0",
"author": "Therp BV,Odoo Community Association (OCA)",
"maintainers": ["NL66278"],
"website": "https://github.com/OCA/server-tools",
diff --git a/fetchmail_from_imap_folder/i18n/de.po b/fetchmail_from_imap_folder/i18n/de.po
index 422af7e49..da0d9713e 100644
--- a/fetchmail_from_imap_folder/i18n/de.po
+++ b/fetchmail_from_imap_folder/i18n/de.po
@@ -74,6 +74,13 @@ msgstr ""
msgid "Body"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid ""
+"By default all undeleted emails are searched. Checking this field adds the "
+"unread condition."
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_attach_mail_manually
msgid "Cancel"
@@ -232,6 +239,11 @@ msgstr ""
msgid "Exact mailadress"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid "Fetch Unseen Only"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Fetch folder now"
diff --git a/fetchmail_from_imap_folder/i18n/es.po b/fetchmail_from_imap_folder/i18n/es.po
index bf37dcbb8..17aa02352 100644
--- a/fetchmail_from_imap_folder/i18n/es.po
+++ b/fetchmail_from_imap_folder/i18n/es.po
@@ -74,6 +74,13 @@ msgstr ""
msgid "Body"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid ""
+"By default all undeleted emails are searched. Checking this field adds the "
+"unread condition."
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_attach_mail_manually
msgid "Cancel"
@@ -232,6 +239,11 @@ msgstr ""
msgid "Exact mailadress"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid "Fetch Unseen Only"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Fetch folder now"
diff --git a/fetchmail_from_imap_folder/i18n/fetchmail_attach_from_folder.pot b/fetchmail_from_imap_folder/i18n/fetchmail_attach_from_folder.pot
index 07c6838ec..eb4b378d3 100644
--- a/fetchmail_from_imap_folder/i18n/fetchmail_attach_from_folder.pot
+++ b/fetchmail_from_imap_folder/i18n/fetchmail_attach_from_folder.pot
@@ -69,6 +69,13 @@ msgstr ""
msgid "Body"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid ""
+"By default all undeleted emails are searched. Checking this field adds the "
+"unread condition."
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_attach_mail_manually
msgid "Cancel"
@@ -227,6 +234,11 @@ msgstr ""
msgid "Exact mailadress"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid "Fetch Unseen Only"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Fetch folder now"
diff --git a/fetchmail_from_imap_folder/i18n/fr.po b/fetchmail_from_imap_folder/i18n/fr.po
index 068eb2d2e..667b1a4fc 100644
--- a/fetchmail_from_imap_folder/i18n/fr.po
+++ b/fetchmail_from_imap_folder/i18n/fr.po
@@ -74,6 +74,13 @@ msgstr ""
msgid "Body"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid ""
+"By default all undeleted emails are searched. Checking this field adds the "
+"unread condition."
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_attach_mail_manually
msgid "Cancel"
@@ -232,6 +239,11 @@ msgstr ""
msgid "Exact mailadress"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid "Fetch Unseen Only"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Fetch folder now"
diff --git a/fetchmail_from_imap_folder/i18n/fr_CA.po b/fetchmail_from_imap_folder/i18n/fr_CA.po
index cb90909c7..bd4e60e9a 100644
--- a/fetchmail_from_imap_folder/i18n/fr_CA.po
+++ b/fetchmail_from_imap_folder/i18n/fr_CA.po
@@ -74,6 +74,13 @@ msgstr ""
msgid "Body"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid ""
+"By default all undeleted emails are searched. Checking this field adds the "
+"unread condition."
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_attach_mail_manually
msgid "Cancel"
@@ -232,6 +239,11 @@ msgstr ""
msgid "Exact mailadress"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid "Fetch Unseen Only"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Fetch folder now"
diff --git a/fetchmail_from_imap_folder/i18n/it.po b/fetchmail_from_imap_folder/i18n/it.po
index 0040ddded..a0cf84314 100644
--- a/fetchmail_from_imap_folder/i18n/it.po
+++ b/fetchmail_from_imap_folder/i18n/it.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: server-tools (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-09-29 11:14+0000\n"
-"PO-Revision-Date: 2023-11-30 16:34+0000\n"
+"PO-Revision-Date: 2024-09-06 15:06+0000\n"
"Last-Translator: mymage \n"
"Language-Team: Italian (http://www.transifex.com/oca/OCA-server-tools-8-0/"
"language/it/)\n"
@@ -17,22 +17,22 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.17\n"
+"X-Generator: Weblate 5.6.2\n"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__action_id
msgid "Action"
-msgstr ""
+msgstr "Azione"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__active
msgid "Active"
-msgstr ""
+msgstr "Attivo"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__archive_path
msgid "Archive Path"
-msgstr ""
+msgstr "Archivia percorso"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__assigned_attachment_ids
@@ -40,45 +40,54 @@ msgstr ""
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__assigned_attachment_ids
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__assigned_attachment_ids
msgid "Assigned Attachments"
-msgstr ""
+msgstr "Allegati assegnati"
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/wizard/attach_mail_manually.py:0
#, python-format
msgid "Attach emails manually"
-msgstr ""
+msgstr "Allega e-mail manualmente"
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_attach_mail_manually
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Attach mail manually"
-msgstr ""
+msgstr "Allega e-mail manualmente"
#. module: fetchmail_attach_from_folder
#: model:ir.model,name:fetchmail_attach_from_folder.model_fetchmail_attach_mail_manually
msgid "Attach mail to selected documents."
-msgstr ""
+msgstr "Allega e-mail ai documenti selezionati."
#. module: fetchmail_attach_from_folder
#: model:ir.model,name:fetchmail_attach_from_folder.model_fetchmail_attach_mail_manually_mail
msgid "Attach single mail to selected documents."
-msgstr ""
+msgstr "Allega e-mail singola ai documenti selezionati."
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__folders_available
msgid "Available folders"
-msgstr ""
+msgstr "Cartelle disponibili"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__body
msgid "Body"
+msgstr "Corpo"
+
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid ""
+"By default all undeleted emails are searched. Checking this field adds the "
+"unread condition."
msgstr ""
+"Vengono cercate in modo predefinito tutte le e-mail non cancellate. "
+"Selezionando questo campo aggiunge la condizione non lette."
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_attach_mail_manually
msgid "Cancel"
-msgstr ""
+msgstr "Annulla"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_change_ids
@@ -86,7 +95,7 @@ msgstr ""
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_change_ids
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_change_ids
msgid "Changeset Changes"
-msgstr ""
+msgstr "Modifiche dell'insieme di modifiche"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_ids
@@ -94,7 +103,7 @@ msgstr ""
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_ids
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_ids
msgid "Changesets"
-msgstr ""
+msgstr "Insiemi di modifiche"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__folders_only
@@ -102,25 +111,27 @@ msgid ""
"Check this field to leave imap inbox alone and only retrieve mail from "
"configured folders."
msgstr ""
+"Selezionare questo campo per lasciare da sola la cartella in ingresso IMAP e "
+"ricevere e-mail solo dalle cartelle configurate."
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
#, python-format
msgid "Confirm connection first."
-msgstr ""
+msgstr "Prima confermare la connessione."
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields.selection,name:fetchmail_attach_from_folder.selection__fetchmail_server_folder__state__done
msgid "Confirmed"
-msgstr ""
+msgstr "Confermata"
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
#, python-format
msgid "Could not create archive folder %(folder)s on server %(server)s"
-msgstr ""
+msgstr "Impossibile creare la cartella %(folder)s nel server %(server)s"
#. module: fetchmail_attach_from_folder
#. odoo-python
@@ -128,20 +139,22 @@ msgstr ""
#, python-format
msgid "Could not fetch %(msgid)s in folder %(folder)s on server %(server)s"
msgstr ""
+"Impossibile recuperare %(msgid)s nella cartella %(folder)s nel server "
+"%(server)s"
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
#, python-format
msgid "Could not open folder %(folder)s on server %(server)s"
-msgstr ""
+msgstr "Impossibile aprire la cartella %(folder)s nel server %(server)s"
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
#, python-format
msgid "Could not search folder %(folder)s on server %(server)s"
-msgstr ""
+msgstr "Impossibile cercare la cartella %(folder)s nel server %(server)s"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
@@ -149,7 +162,7 @@ msgstr ""
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
msgid "Count Changesets"
-msgstr ""
+msgstr "Conta insiemi di modifiche"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
@@ -157,7 +170,7 @@ msgstr ""
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
msgid "Count Pending Changeset Changes"
-msgstr ""
+msgstr "Conteggio modifiche dell'insieme di modifiche in attesa"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
@@ -165,53 +178,53 @@ msgstr ""
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
msgid "Count Pending Changesets"
-msgstr ""
+msgstr "Conteggio insieme di modifiche in attesa"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__object_id
msgid "Create a New Record"
-msgstr ""
+msgstr "Crea un nuovo record"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__create_uid
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__create_uid
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__create_uid
msgid "Created by"
-msgstr ""
+msgstr "Creato da"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__create_date
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__create_date
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__create_date
msgid "Created on"
-msgstr ""
+msgstr "Creato il"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__date
msgid "Date"
-msgstr ""
+msgstr "Data"
#. module: fetchmail_attach_from_folder
#: model:ir.model,name:fetchmail_attach_from_folder.model_fetchmail_server_folder
msgid "Define folders (IMAP mailboxes) from which to fetch mail."
-msgstr ""
+msgstr "Definire le cartelle (cassette posta IMAP) dalle quali ricevere e-mail."
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__delete_matching
msgid "Delete matched emails from server"
-msgstr ""
+msgstr "Elimina le email corrispondenti dal server"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__delete_matching
msgid "Delete matches"
-msgstr ""
+msgstr "Cancella corrispondenti"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__display_name
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__display_name
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__display_name
msgid "Display Name"
-msgstr ""
+msgstr "Nome visualizzato"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__domain
@@ -221,90 +234,99 @@ msgstr "Dominio"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields.selection,name:fetchmail_attach_from_folder.selection__fetchmail_server_folder__match_algorithm__email_domain
msgid "Domain of email address"
-msgstr ""
+msgstr "Dominio degli indirizzi e-mail"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__mail_ids
msgid "Emails"
-msgstr ""
+msgstr "E-mail"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields.selection,name:fetchmail_attach_from_folder.selection__fetchmail_server_folder__match_algorithm__email_exact
msgid "Exact mailadress"
-msgstr ""
+msgstr "Indirizzo e-mail esatto"
+
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid "Fetch Unseen Only"
+msgstr "Recupera solo non lette"
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Fetch folder now"
-msgstr ""
+msgstr "Recupera cartella adesso"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__mail_field
msgid "Field (email)"
-msgstr ""
+msgstr "Campo (email)"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__model_field
msgid "Field (model)"
-msgstr ""
+msgstr "Campo (modello)"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__model_order
msgid ""
"Field(s) to order by, this mostly useful in conjunction with 'Use 1st match'"
msgstr ""
+"Campo(i) di ordinamento, principalmente utilizzato insieme a 'Utilizza la "
+"prima corrispondenza'"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__domain
msgid "Fill in a search filter to narrow down objects to match"
msgstr ""
+"Compilare un filtro di ricerca per ridurre gli oggetti da far corrispondere"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__flag_nonmatching
msgid "Flag Nonmatching"
-msgstr ""
+msgstr "Selezionare non corrispondente"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__flag_nonmatching
msgid "Flag emails in the server that don't match any object in Odoo"
msgstr ""
+"Seleziona e-mail nel server che non corrispondono a nessun oggetto in Odoo"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__folder_id
msgid "Folder"
-msgstr ""
+msgstr "Cartella"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__folder_ids
msgid "Folders"
-msgstr ""
+msgstr "Cartelle"
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Folders available on server"
-msgstr ""
+msgstr "Cartelle disponibili nel server"
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Folders to monitor"
-msgstr ""
+msgstr "Cartelle da monitorare"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__email_from
msgid "From"
-msgstr ""
+msgstr "Dal"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__id
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__id
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__id
msgid "ID"
-msgstr ""
+msgstr "ID"
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "INBOX.subfolder1"
-msgstr ""
+msgstr "INBOX.subfolder1"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__match_first
@@ -312,54 +334,56 @@ msgid ""
"If there are multiple matches, use the first one. If not checked, multiple "
"matches count as no match at all"
msgstr ""
+"Se ci sono corrispondenze multiple, usare la prima. Se non selezionata, "
+"corrispondenze multiple non vengono considerate"
#. module: fetchmail_attach_from_folder
#: model:ir.model,name:fetchmail_attach_from_folder.model_fetchmail_server
msgid "Incoming Mail Server"
-msgstr ""
+msgstr "Server di posta in arrivo"
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
#, python-format
msgid "Invalid folder %s!"
-msgstr ""
+msgstr "Cartella non valida %s!"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually____last_update
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail____last_update
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder____last_update
msgid "Last Modified on"
-msgstr ""
+msgstr "Ultima modifica il"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__write_uid
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__write_uid
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__write_uid
msgid "Last Updated by"
-msgstr ""
+msgstr "Ultimo aggiornamento di"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__write_date
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__write_date
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__write_date
msgid "Last Updated on"
-msgstr ""
+msgstr "Ultimo aggiornamento il"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__match_algorithm
msgid "Match Algorithm"
-msgstr ""
+msgstr "Algoritmo di corrispondenza"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__msgid
msgid "Message id"
-msgstr ""
+msgstr "ID messaggio"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__msg_state
msgid "Message state"
-msgstr ""
+msgstr "Stato del messaggio"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__model_id
@@ -369,27 +393,27 @@ msgstr "Modello"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__name
msgid "Name"
-msgstr ""
+msgstr "Nome"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields.selection,name:fetchmail_attach_from_folder.selection__fetchmail_server_folder__state__draft
msgid "Not Confirmed"
-msgstr ""
+msgstr "Non confermato"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__object_id
msgid "Object"
-msgstr ""
+msgstr "Oggetto"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields.selection,name:fetchmail_attach_from_folder.selection__fetchmail_server_folder__match_algorithm__odoo_standard
msgid "Odoo standard"
-msgstr ""
+msgstr "Standard Odoo"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__folders_only
msgid "Only folders, not inbox"
-msgstr ""
+msgstr "Solo cartelle, non inbox"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__action_id
@@ -397,16 +421,18 @@ msgid ""
"Optional custom server action to trigger for each incoming mail, on the "
"record that was created or updated by this mail"
msgstr ""
+"Azione server personalizzata opzionale da attivare per ogni e-mail in "
+"arrivo, sul record che è stato creato o aggiornato da questa e-mail"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__model_order
msgid "Order (model)"
-msgstr ""
+msgstr "Ordine (modello)"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__path
msgid "Path"
-msgstr ""
+msgstr "Percorso"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__object_id
@@ -415,41 +441,45 @@ msgid ""
"document type. This will create new documents for new conversations, or "
"attach follow-up emails to the existing conversations (documents)."
msgstr ""
+"Elabora ogni e-mail in arrivo come parte di una conversazione corrispondente "
+"a questo tipo di documento. Questo creerĂ nuovi documenti per nuove "
+"conversazioni, o allegherĂ e-mail di aggiornamento alle conversazioni "
+"esistenti (documenti)."
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields.selection,name:fetchmail_attach_from_folder.selection__fetchmail_server_folder__msg_state__received
msgid "Received"
-msgstr ""
+msgstr "Ricevuto"
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Reset Confirmation"
-msgstr ""
+msgstr "Conferma reset"
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_attach_mail_manually
msgid "Save"
-msgstr ""
+msgstr "Salva"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields.selection,name:fetchmail_attach_from_folder.selection__fetchmail_server_folder__msg_state__sent
msgid "Sent"
-msgstr ""
+msgstr "Inviato"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__sequence
msgid "Sequence"
-msgstr ""
+msgstr "Sequenza"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__server_id
msgid "Server"
-msgstr ""
+msgstr "Server"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__server_type
msgid "Server Type"
-msgstr ""
+msgstr "Tipo server"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__smart_search
@@ -457,33 +487,36 @@ msgstr ""
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__smart_search
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__smart_search
msgid "Smart Search"
-msgstr ""
+msgstr "Ricerca intelligente"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__state
msgid "Status"
-msgstr ""
+msgstr "Stato"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__subject
msgid "Subject"
-msgstr ""
+msgstr "Soggetto"
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Test & Confirm"
-msgstr ""
+msgstr "Testa e conferma"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__match_algorithm
msgid "The algorithm used to determine which object an email matches."
msgstr ""
+"L'algoritmo utilizzato per determinare quale oggetto corrisponde all'email."
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__mail_field
msgid ""
"The field in the email used for matching. Typically this is 'to' or 'from'"
msgstr ""
+"Il campo nella e-mail utilizzato per la corrispondenza. Normalmente è 'a' o "
+"'da'"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__model_field
@@ -493,11 +526,15 @@ msgid ""
"'email' if your model is res.partner, or 'partner_id.email' if you're "
"matching sale orders"
msgstr ""
+"Il campo nel modello che contiene il campo per la corrispondenza.\n"
+"Esempi:\n"
+"'email' se il modello è res.partner, o 'partner_id.email' se la "
+"corrispondenza è con gli ordini di vendita"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__model_id
msgid "The model to attach emails to"
-msgstr ""
+msgstr "Modello a cui allegare l'email"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
@@ -505,7 +542,7 @@ msgstr ""
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
msgid "The number of pending changes of this record"
-msgstr ""
+msgstr "Numero di modifiche di questo record in attesa"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
@@ -513,7 +550,7 @@ msgstr ""
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
msgid "The number of pending changesets of this record"
-msgstr ""
+msgstr "Numero di insieme di modifiche di questo record in attesa"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
@@ -521,7 +558,7 @@ msgstr ""
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
msgid "The overall number of changesets of this record"
-msgstr ""
+msgstr "Numero totale di insiemi di modifiche di questo record"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__path
@@ -529,28 +566,32 @@ msgid ""
"The path to your mail folder. Typically would be something like 'INBOX."
"myfolder'"
msgstr ""
+"Percorso alla cartella e-mail. Normalmente è qualcosa del tipo 'INBOX."
+"miacartella'"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__archive_path
msgid "The path where successfully retrieved messages will be stored."
-msgstr ""
+msgstr "Il percorso dove vengono salvati i messaggi ricevuti correttamente."
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__msg_state
msgid "The state messages fetched from this folder should be assigned in Odoo"
msgstr ""
+"Lo stato dei messaggi estratti da questa cartella che deve essere assegnato "
+"in Odoo"
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
#, python-format
msgid "Unable to retrieve folders."
-msgstr ""
+msgstr "Impossibile ottenere le cartelle."
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__match_first
msgid "Use 1st match"
-msgstr ""
+msgstr "Utilizza la prima corrispondenza"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__user_can_see_changeset
@@ -558,34 +599,34 @@ msgstr ""
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__user_can_see_changeset
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__user_can_see_changeset
msgid "User Can See Changeset"
-msgstr ""
+msgstr "L'utente può vedere l'insieme delle modifiche"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__wizard_id
msgid "Wizard"
-msgstr ""
+msgstr "Procedura guidata"
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "[('state', '=', 'open')]"
-msgstr ""
+msgstr "[('state', '=', 'open')]"
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "email"
-msgstr ""
+msgstr "e-mail"
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "name asc"
-msgstr ""
+msgstr "nome ascendente"
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_attach_mail_manually
msgid "or"
-msgstr ""
+msgstr "o"
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "to,from"
-msgstr ""
+msgstr "a,da"
diff --git a/fetchmail_from_imap_folder/i18n/pt_BR.po b/fetchmail_from_imap_folder/i18n/pt_BR.po
index 421c24180..334d4326b 100644
--- a/fetchmail_from_imap_folder/i18n/pt_BR.po
+++ b/fetchmail_from_imap_folder/i18n/pt_BR.po
@@ -77,6 +77,13 @@ msgstr ""
msgid "Body"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid ""
+"By default all undeleted emails are searched. Checking this field adds the "
+"unread condition."
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_attach_mail_manually
msgid "Cancel"
@@ -235,6 +242,11 @@ msgstr "Emails"
msgid "Exact mailadress"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid "Fetch Unseen Only"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Fetch folder now"
diff --git a/fetchmail_from_imap_folder/i18n/ru.po b/fetchmail_from_imap_folder/i18n/ru.po
index de228435c..2474b5bd1 100644
--- a/fetchmail_from_imap_folder/i18n/ru.po
+++ b/fetchmail_from_imap_folder/i18n/ru.po
@@ -76,6 +76,13 @@ msgstr ""
msgid "Body"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid ""
+"By default all undeleted emails are searched. Checking this field adds the "
+"unread condition."
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_attach_mail_manually
msgid "Cancel"
@@ -234,6 +241,11 @@ msgstr ""
msgid "Exact mailadress"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid "Fetch Unseen Only"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Fetch folder now"
diff --git a/fetchmail_from_imap_folder/i18n/sl.po b/fetchmail_from_imap_folder/i18n/sl.po
index 380f62469..313221ced 100644
--- a/fetchmail_from_imap_folder/i18n/sl.po
+++ b/fetchmail_from_imap_folder/i18n/sl.po
@@ -76,6 +76,13 @@ msgstr ""
msgid "Body"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid ""
+"By default all undeleted emails are searched. Checking this field adds the "
+"unread condition."
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_attach_mail_manually
msgid "Cancel"
@@ -234,6 +241,11 @@ msgstr "E-poštna sporočila"
msgid "Exact mailadress"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__fetch_unseen_only
+msgid "Fetch Unseen Only"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "Fetch folder now"
diff --git a/fetchmail_from_imap_folder/models/fetchmail_server_folder.py b/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
index 3e351fb36..8105e0fe4 100644
--- a/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
+++ b/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
@@ -97,6 +97,10 @@ class FetchmailServerFolder(models.Model):
help="Optional custom server action to trigger for each incoming "
"mail, on the record that was created or updated by this mail",
)
+ fetch_unseen_only = fields.Boolean(
+ help="By default all undeleted emails are searched. Checking this "
+ "field adds the unread condition.",
+ )
def button_confirm_folder(self):
self.write({"state": "draft"})
@@ -170,10 +174,13 @@ def check_imap_archive_folder(self, connection):
% {"folder": self.archive_path, "server": server.name}
)
+ def get_criteria(self):
+ return "UNDELETED" if not self.fetch_unseen_only else "UNSEEN UNDELETED"
+
def retrieve_imap_folder(self, connection):
"""Retrieve all mails for one IMAP folder."""
self.ensure_one()
- msgids = self.get_msgids(connection, "UNDELETED")
+ msgids = self.get_msgids(connection, self.get_criteria())
for msgid in msgids[0].split():
# We will accept exceptions for single messages
try:
diff --git a/fetchmail_from_imap_folder/static/description/index.html b/fetchmail_from_imap_folder/static/description/index.html
index 7fcdda0ac..5d8583a5c 100644
--- a/fetchmail_from_imap_folder/static/description/index.html
+++ b/fetchmail_from_imap_folder/static/description/index.html
@@ -367,7 +367,7 @@
Email gateway - folders
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!! source digest: sha256:c3af3dec7c2b9f46c88cd4355883c08deb3d7c03e21735f2f1b5ca4131aa7e69
+!! source digest: sha256:b5ee1bcd71066b368da923b5aa94b37da6f960f51ffd129b199967db10b576d7
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
Adds the possibility to attach emails from a certain IMAP folder to
diff --git a/fetchmail_from_imap_folder/views/fetchmail_server.xml b/fetchmail_from_imap_folder/views/fetchmail_server.xml
index cd2baf067..0ae8cb86b 100644
--- a/fetchmail_from_imap_folder/views/fetchmail_server.xml
+++ b/fetchmail_from_imap_folder/views/fetchmail_server.xml
@@ -103,6 +103,7 @@
+
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
index bd75b208d..f547e71e6 100644
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.py
@@ -42,7 +42,7 @@ def default_get(self, fields_list):
folder = folder_model.browse([folder_id])
connection = folder.server_id.connect()
connection.select(folder.path)
- criteria = "FLAGGED" if folder.flag_nonmatching else "UNDELETED"
+ criteria = "FLAGGED" if folder.flag_nonmatching else folder.get_criteria()
msgids = folder.get_msgids(connection, criteria)
for msgid in msgids[0].split():
mail_message, message_org = folder.fetch_msg(connection, msgid)
From 7d4c19888f84123b1fe772f2b2dfaaaeadeca84b Mon Sep 17 00:00:00 2001
From: Jose Zambudio
Date: Mon, 14 Oct 2024 09:19:26 +0200
Subject: [PATCH 54/79] [MIG] fetchmail_attach_from_folder: Migration to 17.0
---
fetchmail_from_imap_folder/README.rst | 16 ++++-----
fetchmail_from_imap_folder/__manifest__.py | 2 +-
.../models/fetchmail_server.py | 3 +-
.../models/fetchmail_server_folder.py | 2 +-
fetchmail_from_imap_folder/pyproject.toml | 3 ++
.../static/description/index.html | 6 ++--
.../tests/test_match_algorithms.py | 31 ++++-------------
.../views/fetchmail_server.xml | 33 ++++++++-----------
.../wizard/attach_mail_manually.py | 6 ++--
.../wizard/attach_mail_manually.xml | 2 +-
10 files changed, 43 insertions(+), 61 deletions(-)
create mode 100644 fetchmail_from_imap_folder/pyproject.toml
diff --git a/fetchmail_from_imap_folder/README.rst b/fetchmail_from_imap_folder/README.rst
index 4825e7213..1e8cb6f85 100644
--- a/fetchmail_from_imap_folder/README.rst
+++ b/fetchmail_from_imap_folder/README.rst
@@ -17,13 +17,13 @@ Email gateway - folders
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github
- :target: https://github.com/OCA/server-tools/tree/16.0/fetchmail_attach_from_folder
+ :target: https://github.com/OCA/server-tools/tree/17.0/fetchmail_attach_from_folder
:alt: OCA/server-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/server-tools-16-0/server-tools-16-0-fetchmail_attach_from_folder
+ :target: https://translation.odoo-community.org/projects/server-tools-17-0/server-tools-17-0-fetchmail_attach_from_folder
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
- :target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=16.0
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=17.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -101,7 +101,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -116,9 +116,9 @@ Authors
Contributors
------------
-- Holger Brunn hbrunn@therp.nl
-- Ronald Portier ronald@therp.nl
-- Alexandre Fayolle alexandre.fayolle@camptocamp.com
+- Holger Brunn hbrunn@therp.nl
+- Ronald Portier ronald@therp.nl
+- Alexandre Fayolle alexandre.fayolle@camptocamp.com
Maintainers
-----------
@@ -141,6 +141,6 @@ Current `maintainer `__:
|maintainer-NL66278|
-This module is part of the `OCA/server-tools `_ project on GitHub.
+This module is part of the `OCA/server-tools `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/fetchmail_from_imap_folder/__manifest__.py b/fetchmail_from_imap_folder/__manifest__.py
index b6dcce88b..ffc3c3334 100644
--- a/fetchmail_from_imap_folder/__manifest__.py
+++ b/fetchmail_from_imap_folder/__manifest__.py
@@ -3,7 +3,7 @@
{
"name": "Email gateway - folders",
"summary": "Attach mails in an IMAP folder to existing objects",
- "version": "16.0.1.4.0",
+ "version": "17.0.1.0.0",
"author": "Therp BV,Odoo Community Association (OCA)",
"maintainers": ["NL66278"],
"website": "https://github.com/OCA/server-tools",
diff --git a/fetchmail_from_imap_folder/models/fetchmail_server.py b/fetchmail_from_imap_folder/models/fetchmail_server.py
index 7d344395a..7df4ba7a3 100644
--- a/fetchmail_from_imap_folder/models/fetchmail_server.py
+++ b/fetchmail_from_imap_folder/models/fetchmail_server.py
@@ -42,7 +42,8 @@ def parse_list_response(line):
connection.logout()
folders_available = fields.Text(
- string="Available folders", compute="_compute_folders_available", readonly=True
+ string="Available folders",
+ compute="_compute_folders_available",
)
folder_ids = fields.One2many(
comodel_name="fetchmail.server.folder",
diff --git a/fetchmail_from_imap_folder/models/fetchmail_server_folder.py b/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
index 8105e0fe4..072a70939 100644
--- a/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
+++ b/fetchmail_from_imap_folder/models/fetchmail_server_folder.py
@@ -393,7 +393,7 @@ def attach_mail(self, match_object, message_dict):
thread_model = self.env["mail.thread"]
attachments = message_dict["attachments"] or []
attachment_ids = []
- attachement_values = thread_model._message_post_process_attachments(
+ attachement_values = thread_model._process_attachments_for_post(
attachments, attachment_ids, msg_values
)
msg_values.update(attachement_values)
diff --git a/fetchmail_from_imap_folder/pyproject.toml b/fetchmail_from_imap_folder/pyproject.toml
new file mode 100644
index 000000000..4231d0ccc
--- /dev/null
+++ b/fetchmail_from_imap_folder/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["whool"]
+build-backend = "whool.buildapi"
diff --git a/fetchmail_from_imap_folder/static/description/index.html b/fetchmail_from_imap_folder/static/description/index.html
index 5d8583a5c..d4f235b29 100644
--- a/fetchmail_from_imap_folder/static/description/index.html
+++ b/fetchmail_from_imap_folder/static/description/index.html
@@ -369,7 +369,7 @@
Adds the possibility to attach emails from a certain IMAP folder to
objects, ie partners. Matching is done via several algorithms, ie email
address, email address’s domain or the original Odoo algorithm.
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
-feedback.
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!! source digest: sha256:b5ee1bcd71066b368da923b5aa94b37da6f960f51ffd129b199967db10b576d7
+!! source digest: sha256:2ef6e5c6392b55a996244e9880d1f1ee0a7fec6ecdf902ea72a800b8425caf89
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
Adds the possibility to attach emails from a certain IMAP folder to
From 5bbead91bd4f076b276000506b1f76552147f9c2 Mon Sep 17 00:00:00 2001
From: AlexGarS73
Date: Thu, 17 Jul 2025 08:20:45 +0200
Subject: [PATCH 57/79] [IMP] fetchmail_attach_from_folder: pre-commit auto
fixes
---
.../views/fetchmail_server.xml | 2 --
.../wizard/attach_mail_manually.xml | 12 +++++-------
2 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/fetchmail_from_imap_folder/views/fetchmail_server.xml b/fetchmail_from_imap_folder/views/fetchmail_server.xml
index ef04ab4b6..dafd36b64 100644
--- a/fetchmail_from_imap_folder/views/fetchmail_server.xml
+++ b/fetchmail_from_imap_folder/views/fetchmail_server.xml
@@ -1,6 +1,5 @@
-
fetchmail.server.formfetchmail.server
@@ -110,5 +109,4 @@
-
diff --git a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
index 15e8d2d1b..d1dd0b223 100644
--- a/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
+++ b/fetchmail_from_imap_folder/wizard/attach_mail_manually.xml
@@ -1,6 +1,5 @@
-
fetchmail.attach.mail.manuallyfetchmail.attach.mail.manually
@@ -28,16 +27,15 @@
-
From 5897593bd052578281846f9fb0c270347afca1e1 Mon Sep 17 00:00:00 2001
From: AlexGarS73
Date: Thu, 17 Jul 2025 09:58:50 +0200
Subject: [PATCH 58/79] [MIG] fetchmail_attach_from_folder: Migration to 18.0
---
fetchmail_from_imap_folder/README.rst | 10 +-
fetchmail_from_imap_folder/__manifest__.py | 2 +-
.../static/description/index.html | 6 +-
.../tests/test_match_algorithms.py | 215 +++++++++++++++++-
.../views/fetchmail_server.xml | 4 +-
.../wizard/attach_mail_manually.py | 4 +-
.../wizard/attach_mail_manually.xml | 4 +-
7 files changed, 228 insertions(+), 17 deletions(-)
diff --git a/fetchmail_from_imap_folder/README.rst b/fetchmail_from_imap_folder/README.rst
index a92799038..78c22ca17 100644
--- a/fetchmail_from_imap_folder/README.rst
+++ b/fetchmail_from_imap_folder/README.rst
@@ -17,13 +17,13 @@ Email gateway - folders
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github
- :target: https://github.com/OCA/server-tools/tree/17.0/fetchmail_attach_from_folder
+ :target: https://github.com/OCA/server-tools/tree/18.0/fetchmail_attach_from_folder
:alt: OCA/server-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/server-tools-17-0/server-tools-17-0-fetchmail_attach_from_folder
+ :target: https://translation.odoo-community.org/projects/server-tools-18-0/server-tools-18-0-fetchmail_attach_from_folder
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
- :target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=17.0
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=18.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -101,7 +101,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -141,6 +141,6 @@ Current `maintainer `__:
|maintainer-NL66278|
-This module is part of the `OCA/server-tools `_ project on GitHub.
+This module is part of the `OCA/server-tools `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/fetchmail_from_imap_folder/__manifest__.py b/fetchmail_from_imap_folder/__manifest__.py
index ffc3c3334..5ade469c5 100644
--- a/fetchmail_from_imap_folder/__manifest__.py
+++ b/fetchmail_from_imap_folder/__manifest__.py
@@ -3,7 +3,7 @@
{
"name": "Email gateway - folders",
"summary": "Attach mails in an IMAP folder to existing objects",
- "version": "17.0.1.0.0",
+ "version": "18.0.1.0.0",
"author": "Therp BV,Odoo Community Association (OCA)",
"maintainers": ["NL66278"],
"website": "https://github.com/OCA/server-tools",
diff --git a/fetchmail_from_imap_folder/static/description/index.html b/fetchmail_from_imap_folder/static/description/index.html
index 1deb2e754..1e6a0047c 100644
--- a/fetchmail_from_imap_folder/static/description/index.html
+++ b/fetchmail_from_imap_folder/static/description/index.html
@@ -369,7 +369,7 @@
Adds the possibility to attach emails from a certain IMAP folder to
objects, ie partners. Matching is done via several algorithms, ie email
address, email address’s domain or the original Odoo algorithm.
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
-feedback.
Adds the possibility to attach emails from a certain IMAP folder to
objects, ie partners. Matching is done via several algorithms, ie email
address, email address’s domain or the original Odoo algorithm.
In your fetchmail configuration, you’ll find a new list field
Folders to monitor. Add your folders here in IMAP notation (usually
something like INBOX.your_folder_name.your_subfolder_name), choose a
model to attach mails to and a matching algorithm to use.
Fill in a field to search for the email address in Field (model).
For partners, this would be email. Also fill in the header field
from the email to look at in Field (email). If you want to match
@@ -410,7 +415,7 @@
Match the domain of the email address(es) found in Field (email).
This would attach a mail to test1@example.com to a record with
Field (model) set to test2@example.com. Given that this is a
@@ -418,14 +423,14 @@
A widespread configuration is to have a shared mailbox with several
folders, i.e. one where users drop mails they want to attach to
partners. Let this folder be called From partners. Then create a
@@ -443,7 +448,7 @@
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
@@ -451,15 +456,15 @@
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!! source digest: sha256:e4c93058a6151bbc67ceadf75cf0fee376e22dbd28e548bc91887592979779de
+!! source digest: sha256:ab65e43855bfb568a640043322dc68354fa2d392958a160fb7b4b14d4c5ed9c0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
Adds the possibility to attach emails from a certain IMAP folder to
From c91205ce75271d99079806199cf60ced62368151 Mon Sep 17 00:00:00 2001
From: Weblate
Date: Wed, 28 Jan 2026 13:23:22 +0000
Subject: [PATCH 70/79] Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.
Translation: server-tools-18.0/server-tools-18.0-fetchmail_attach_from_folder
Translate-URL: https://translation.odoo-community.org/projects/server-tools-18-0/server-tools-18-0-fetchmail_attach_from_folder/
---
fetchmail_from_imap_folder/i18n/de.po | 106 +++-------------
fetchmail_from_imap_folder/i18n/es.po | 106 +++-------------
fetchmail_from_imap_folder/i18n/fr.po | 106 +++-------------
fetchmail_from_imap_folder/i18n/fr_CA.po | 101 ++--------------
fetchmail_from_imap_folder/i18n/it.po | 146 ++++++++---------------
fetchmail_from_imap_folder/i18n/pt_BR.po | 124 +++++--------------
fetchmail_from_imap_folder/i18n/ru.po | 101 ++--------------
fetchmail_from_imap_folder/i18n/sl.po | 107 +++--------------
8 files changed, 155 insertions(+), 742 deletions(-)
diff --git a/fetchmail_from_imap_folder/i18n/de.po b/fetchmail_from_imap_folder/i18n/de.po
index da0d9713e..a33fb1652 100644
--- a/fetchmail_from_imap_folder/i18n/de.po
+++ b/fetchmail_from_imap_folder/i18n/de.po
@@ -44,7 +44,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/wizard/attach_mail_manually.py:0
-#, python-format
msgid "Attach emails manually"
msgstr ""
@@ -86,22 +85,6 @@ msgstr ""
msgid "Cancel"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_change_ids
-msgid "Changeset Changes"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_ids
-msgid "Changesets"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__folders_only
msgid ""
@@ -112,7 +95,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Confirm connection first."
msgstr ""
@@ -124,55 +106,28 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not create archive folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
-msgid "Could not fetch %(msgid)s in folder %(folder)s on server %(server)s"
+msgid ""
+"Could not fetch %(message_uid)s in folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not open folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not search folder %(folder)s on server %(server)s"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "Count Changesets"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "Count Pending Changeset Changes"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "Count Pending Changesets"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__object_id
msgid "Create a New Record"
@@ -332,18 +287,9 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Invalid folder %s!"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder____last_update
-#, fuzzy
-msgid "Last Modified on"
-msgstr "Zuletzt aktualisiert am"
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__write_uid
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__write_uid
@@ -364,7 +310,7 @@ msgid "Match Algorithm"
msgstr ""
#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__msgid
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__message_uid
msgid "Message id"
msgstr ""
@@ -463,6 +409,11 @@ msgstr ""
msgid "Server Type"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__x_server_type_env_default
+msgid "Server Type Env Default"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__smart_search
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__smart_search
@@ -511,35 +462,11 @@ msgstr ""
msgid "The model to attach emails to"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "The number of pending changes of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "The number of pending changesets of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "The overall number of changesets of this record"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__path
msgid ""
-"The path to your mail folder. Typically would be something like 'INBOX."
-"myfolder'"
+"The path to your mail folder. Typically would be something like "
+"'INBOX.myfolder'"
msgstr ""
#. module: fetchmail_attach_from_folder
@@ -555,7 +482,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Unable to retrieve folders."
msgstr ""
@@ -564,14 +490,6 @@ msgstr ""
msgid "Use 1st match"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__user_can_see_changeset
-msgid "User Can See Changeset"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__wizard_id
msgid "Wizard"
@@ -601,3 +519,7 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "to,from"
msgstr ""
+
+#, fuzzy
+#~ msgid "Last Modified on"
+#~ msgstr "Zuletzt aktualisiert am"
diff --git a/fetchmail_from_imap_folder/i18n/es.po b/fetchmail_from_imap_folder/i18n/es.po
index 17aa02352..f73cd740e 100644
--- a/fetchmail_from_imap_folder/i18n/es.po
+++ b/fetchmail_from_imap_folder/i18n/es.po
@@ -44,7 +44,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/wizard/attach_mail_manually.py:0
-#, python-format
msgid "Attach emails manually"
msgstr ""
@@ -86,22 +85,6 @@ msgstr ""
msgid "Cancel"
msgstr "Cancelar"
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_change_ids
-msgid "Changeset Changes"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_ids
-msgid "Changesets"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__folders_only
msgid ""
@@ -112,7 +95,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Confirm connection first."
msgstr ""
@@ -124,55 +106,28 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not create archive folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
-msgid "Could not fetch %(msgid)s in folder %(folder)s on server %(server)s"
+msgid ""
+"Could not fetch %(message_uid)s in folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not open folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not search folder %(folder)s on server %(server)s"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "Count Changesets"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "Count Pending Changeset Changes"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "Count Pending Changesets"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__object_id
msgid "Create a New Record"
@@ -332,18 +287,9 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Invalid folder %s!"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder____last_update
-#, fuzzy
-msgid "Last Modified on"
-msgstr "Ăšltima actualizaciĂłn en"
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__write_uid
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__write_uid
@@ -364,7 +310,7 @@ msgid "Match Algorithm"
msgstr ""
#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__msgid
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__message_uid
msgid "Message id"
msgstr ""
@@ -463,6 +409,11 @@ msgstr ""
msgid "Server Type"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__x_server_type_env_default
+msgid "Server Type Env Default"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__smart_search
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__smart_search
@@ -511,35 +462,11 @@ msgstr ""
msgid "The model to attach emails to"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "The number of pending changes of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "The number of pending changesets of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "The overall number of changesets of this record"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__path
msgid ""
-"The path to your mail folder. Typically would be something like 'INBOX."
-"myfolder'"
+"The path to your mail folder. Typically would be something like "
+"'INBOX.myfolder'"
msgstr ""
#. module: fetchmail_attach_from_folder
@@ -555,7 +482,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Unable to retrieve folders."
msgstr ""
@@ -564,14 +490,6 @@ msgstr ""
msgid "Use 1st match"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__user_can_see_changeset
-msgid "User Can See Changeset"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__wizard_id
msgid "Wizard"
@@ -601,3 +519,7 @@ msgstr "o"
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "to,from"
msgstr ""
+
+#, fuzzy
+#~ msgid "Last Modified on"
+#~ msgstr "Ăšltima actualizaciĂłn en"
diff --git a/fetchmail_from_imap_folder/i18n/fr.po b/fetchmail_from_imap_folder/i18n/fr.po
index 667b1a4fc..2d926f5f9 100644
--- a/fetchmail_from_imap_folder/i18n/fr.po
+++ b/fetchmail_from_imap_folder/i18n/fr.po
@@ -44,7 +44,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/wizard/attach_mail_manually.py:0
-#, python-format
msgid "Attach emails manually"
msgstr ""
@@ -86,22 +85,6 @@ msgstr ""
msgid "Cancel"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_change_ids
-msgid "Changeset Changes"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_ids
-msgid "Changesets"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__folders_only
msgid ""
@@ -112,7 +95,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Confirm connection first."
msgstr ""
@@ -124,55 +106,28 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not create archive folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
-msgid "Could not fetch %(msgid)s in folder %(folder)s on server %(server)s"
+msgid ""
+"Could not fetch %(message_uid)s in folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not open folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not search folder %(folder)s on server %(server)s"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "Count Changesets"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "Count Pending Changeset Changes"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "Count Pending Changesets"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__object_id
msgid "Create a New Record"
@@ -332,18 +287,9 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Invalid folder %s!"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder____last_update
-#, fuzzy
-msgid "Last Modified on"
-msgstr "Dernière mise à jour le"
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__write_uid
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__write_uid
@@ -364,7 +310,7 @@ msgid "Match Algorithm"
msgstr ""
#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__msgid
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__message_uid
msgid "Message id"
msgstr ""
@@ -463,6 +409,11 @@ msgstr ""
msgid "Server Type"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__x_server_type_env_default
+msgid "Server Type Env Default"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__smart_search
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__smart_search
@@ -511,35 +462,11 @@ msgstr ""
msgid "The model to attach emails to"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "The number of pending changes of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "The number of pending changesets of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "The overall number of changesets of this record"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__path
msgid ""
-"The path to your mail folder. Typically would be something like 'INBOX."
-"myfolder'"
+"The path to your mail folder. Typically would be something like "
+"'INBOX.myfolder'"
msgstr ""
#. module: fetchmail_attach_from_folder
@@ -555,7 +482,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Unable to retrieve folders."
msgstr ""
@@ -564,14 +490,6 @@ msgstr ""
msgid "Use 1st match"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__user_can_see_changeset
-msgid "User Can See Changeset"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__wizard_id
msgid "Wizard"
@@ -601,3 +519,7 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "to,from"
msgstr ""
+
+#, fuzzy
+#~ msgid "Last Modified on"
+#~ msgstr "Dernière mise à jour le"
diff --git a/fetchmail_from_imap_folder/i18n/fr_CA.po b/fetchmail_from_imap_folder/i18n/fr_CA.po
index bd4e60e9a..3fea44e85 100644
--- a/fetchmail_from_imap_folder/i18n/fr_CA.po
+++ b/fetchmail_from_imap_folder/i18n/fr_CA.po
@@ -44,7 +44,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/wizard/attach_mail_manually.py:0
-#, python-format
msgid "Attach emails manually"
msgstr ""
@@ -86,22 +85,6 @@ msgstr ""
msgid "Cancel"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_change_ids
-msgid "Changeset Changes"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_ids
-msgid "Changesets"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__folders_only
msgid ""
@@ -112,7 +95,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Confirm connection first."
msgstr ""
@@ -124,55 +106,28 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not create archive folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
-msgid "Could not fetch %(msgid)s in folder %(folder)s on server %(server)s"
+msgid ""
+"Could not fetch %(message_uid)s in folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not open folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not search folder %(folder)s on server %(server)s"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "Count Changesets"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "Count Pending Changeset Changes"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "Count Pending Changesets"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__object_id
msgid "Create a New Record"
@@ -332,17 +287,9 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Invalid folder %s!"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder____last_update
-msgid "Last Modified on"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__write_uid
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__write_uid
@@ -363,7 +310,7 @@ msgid "Match Algorithm"
msgstr ""
#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__msgid
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__message_uid
msgid "Message id"
msgstr ""
@@ -462,6 +409,11 @@ msgstr ""
msgid "Server Type"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__x_server_type_env_default
+msgid "Server Type Env Default"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__smart_search
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__smart_search
@@ -510,35 +462,11 @@ msgstr ""
msgid "The model to attach emails to"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "The number of pending changes of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "The number of pending changesets of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "The overall number of changesets of this record"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__path
msgid ""
-"The path to your mail folder. Typically would be something like 'INBOX."
-"myfolder'"
+"The path to your mail folder. Typically would be something like "
+"'INBOX.myfolder'"
msgstr ""
#. module: fetchmail_attach_from_folder
@@ -554,7 +482,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Unable to retrieve folders."
msgstr ""
@@ -563,14 +490,6 @@ msgstr ""
msgid "Use 1st match"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__user_can_see_changeset
-msgid "User Can See Changeset"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__wizard_id
msgid "Wizard"
diff --git a/fetchmail_from_imap_folder/i18n/it.po b/fetchmail_from_imap_folder/i18n/it.po
index 8ef2d80b1..993eab6e6 100644
--- a/fetchmail_from_imap_folder/i18n/it.po
+++ b/fetchmail_from_imap_folder/i18n/it.po
@@ -45,7 +45,6 @@ msgstr "Allegati assegnati"
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/wizard/attach_mail_manually.py:0
-#, python-format
msgid "Attach emails manually"
msgstr "Allega e-mail manualmente"
@@ -89,22 +88,6 @@ msgstr ""
msgid "Cancel"
msgstr "Annulla"
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_change_ids
-msgid "Changeset Changes"
-msgstr "Modifiche dell'insieme di modifiche"
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_ids
-msgid "Changesets"
-msgstr "Insiemi di modifiche"
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__folders_only
msgid ""
@@ -117,7 +100,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Confirm connection first."
msgstr "Prima confermare la connessione."
@@ -129,57 +111,28 @@ msgstr "Confermata"
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not create archive folder %(folder)s on server %(server)s"
msgstr "Impossibile creare la cartella %(folder)s nel server %(server)s"
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
-msgid "Could not fetch %(msgid)s in folder %(folder)s on server %(server)s"
+msgid ""
+"Could not fetch %(message_uid)s in folder %(folder)s on server %(server)s"
msgstr ""
-"Impossibile recuperare %(msgid)s nella cartella %(folder)s nel server "
-"%(server)s"
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not open folder %(folder)s on server %(server)s"
msgstr "Impossibile aprire la cartella %(folder)s nel server %(server)s"
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not search folder %(folder)s on server %(server)s"
msgstr "Impossibile cercare la cartella %(folder)s nel server %(server)s"
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "Count Changesets"
-msgstr "Conta insiemi di modifiche"
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "Count Pending Changeset Changes"
-msgstr "Conteggio modifiche dell'insieme di modifiche in attesa"
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "Count Pending Changesets"
-msgstr "Conteggio insieme di modifiche in attesa"
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__object_id
msgid "Create a New Record"
@@ -207,7 +160,8 @@ msgstr "Data"
#. module: fetchmail_attach_from_folder
#: model:ir.model,name:fetchmail_attach_from_folder.model_fetchmail_server_folder
msgid "Define folders (IMAP mailboxes) from which to fetch mail."
-msgstr "Definire le cartelle (cassette posta IMAP) dalle quali ricevere e-mail."
+msgstr ""
+"Definire le cartelle (cassette posta IMAP) dalle quali ricevere e-mail."
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__delete_matching
@@ -345,17 +299,9 @@ msgstr "Server di posta in arrivo"
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Invalid folder %s!"
msgstr "Cartella non valida %s!"
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder____last_update
-msgid "Last Modified on"
-msgstr "Ultima modifica il"
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__write_uid
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__write_uid
@@ -376,7 +322,7 @@ msgid "Match Algorithm"
msgstr "Algoritmo di corrispondenza"
#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__msgid
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__message_uid
msgid "Message id"
msgstr "ID messaggio"
@@ -481,6 +427,11 @@ msgstr "Server"
msgid "Server Type"
msgstr "Tipo server"
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__x_server_type_env_default
+msgid "Server Type Env Default"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__smart_search
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__smart_search
@@ -536,38 +487,14 @@ msgstr ""
msgid "The model to attach emails to"
msgstr "Modello a cui allegare l'email"
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "The number of pending changes of this record"
-msgstr "Numero di modifiche di questo record in attesa"
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "The number of pending changesets of this record"
-msgstr "Numero di insiemi di modifiche in attesa di questo record"
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "The overall number of changesets of this record"
-msgstr "Numero totale di insiemi di modifiche di questo record"
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__path
msgid ""
-"The path to your mail folder. Typically would be something like 'INBOX."
-"myfolder'"
+"The path to your mail folder. Typically would be something like "
+"'INBOX.myfolder'"
msgstr ""
-"Percorso alla cartella e-mail. Normalmente è qualcosa del tipo 'INBOX."
-"miacartella'"
+"Percorso alla cartella e-mail. Normalmente è qualcosa del tipo "
+"'INBOX.miacartella'"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__archive_path
@@ -584,7 +511,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Unable to retrieve folders."
msgstr "Impossibile ottenere le cartelle."
@@ -593,14 +519,6 @@ msgstr "Impossibile ottenere le cartelle."
msgid "Use 1st match"
msgstr "Utilizza la prima corrispondenza"
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__user_can_see_changeset
-msgid "User Can See Changeset"
-msgstr "L'utente può vedere l'insieme delle modifiche"
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__wizard_id
msgid "Wizard"
@@ -630,3 +548,39 @@ msgstr "o"
#: model_terms:ir.ui.view,arch_db:fetchmail_attach_from_folder.view_email_server_form
msgid "to,from"
msgstr "a,da"
+
+#~ msgid "Changeset Changes"
+#~ msgstr "Modifiche dell'insieme di modifiche"
+
+#~ msgid "Changesets"
+#~ msgstr "Insiemi di modifiche"
+
+#, python-format
+#~ msgid "Could not fetch %(msgid)s in folder %(folder)s on server %(server)s"
+#~ msgstr ""
+#~ "Impossibile recuperare %(msgid)s nella cartella %(folder)s nel server "
+#~ "%(server)s"
+
+#~ msgid "Count Changesets"
+#~ msgstr "Conta insiemi di modifiche"
+
+#~ msgid "Count Pending Changeset Changes"
+#~ msgstr "Conteggio modifiche dell'insieme di modifiche in attesa"
+
+#~ msgid "Count Pending Changesets"
+#~ msgstr "Conteggio insieme di modifiche in attesa"
+
+#~ msgid "Last Modified on"
+#~ msgstr "Ultima modifica il"
+
+#~ msgid "The number of pending changes of this record"
+#~ msgstr "Numero di modifiche di questo record in attesa"
+
+#~ msgid "The number of pending changesets of this record"
+#~ msgstr "Numero di insiemi di modifiche in attesa di questo record"
+
+#~ msgid "The overall number of changesets of this record"
+#~ msgstr "Numero totale di insiemi di modifiche di questo record"
+
+#~ msgid "User Can See Changeset"
+#~ msgstr "L'utente può vedere l'insieme delle modifiche"
diff --git a/fetchmail_from_imap_folder/i18n/pt_BR.po b/fetchmail_from_imap_folder/i18n/pt_BR.po
index 334d4326b..93a846de7 100644
--- a/fetchmail_from_imap_folder/i18n/pt_BR.po
+++ b/fetchmail_from_imap_folder/i18n/pt_BR.po
@@ -10,8 +10,8 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-09-29 11:14+0000\n"
"PO-Revision-Date: 2024-05-29 16:35+0000\n"
-"Last-Translator: Rodrigo Macedo \n"
+"Last-Translator: Rodrigo Macedo "
+"\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/oca/OCA-server-"
"tools-8-0/language/pt_BR/)\n"
"Language: pt_BR\n"
@@ -47,7 +47,7 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/wizard/attach_mail_manually.py:0
-#, fuzzy, python-format
+#, fuzzy
msgid "Attach emails manually"
msgstr "Anexar mail manualmente"
@@ -89,22 +89,6 @@ msgstr ""
msgid "Cancel"
msgstr "Cancelar"
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_change_ids
-msgid "Changeset Changes"
-msgstr "Mudanças no conjunto de alterações"
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_ids
-msgid "Changesets"
-msgstr "Conjunto de alterações"
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__folders_only
msgid ""
@@ -115,7 +99,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Confirm connection first."
msgstr ""
@@ -127,55 +110,28 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not create archive folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
-msgid "Could not fetch %(msgid)s in folder %(folder)s on server %(server)s"
+msgid ""
+"Could not fetch %(message_uid)s in folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not open folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not search folder %(folder)s on server %(server)s"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "Count Changesets"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "Count Pending Changeset Changes"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "Count Pending Changesets"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__object_id
msgid "Create a New Record"
@@ -339,18 +295,9 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Invalid folder %s!"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder____last_update
-#, fuzzy
-msgid "Last Modified on"
-msgstr "Última atualização em"
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__write_uid
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__write_uid
@@ -371,7 +318,7 @@ msgid "Match Algorithm"
msgstr ""
#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__msgid
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__message_uid
msgid "Message id"
msgstr "Identificação da mensagem"
@@ -470,6 +417,11 @@ msgstr "Servidor"
msgid "Server Type"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__x_server_type_env_default
+msgid "Server Type Env Default"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__smart_search
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__smart_search
@@ -518,38 +470,14 @@ msgstr ""
msgid "The model to attach emails to"
msgstr "O modelo para anexar emails ao"
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "The number of pending changes of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "The number of pending changesets of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "The overall number of changesets of this record"
-msgstr "O número total de conjuntos de alterações deste registro"
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__path
msgid ""
-"The path to your mail folder. Typically would be something like 'INBOX."
-"myfolder'"
+"The path to your mail folder. Typically would be something like "
+"'INBOX.myfolder'"
msgstr ""
-"O caminho para sua pasta de mail. Tipicamente seria alguma coisa como 'INBOX."
-"myfolder'"
+"O caminho para sua pasta de mail. Tipicamente seria alguma coisa como "
+"'INBOX.myfolder'"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__archive_path
@@ -565,7 +493,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Unable to retrieve folders."
msgstr ""
@@ -574,14 +501,6 @@ msgstr ""
msgid "Use 1st match"
msgstr "Use a 1a combinação"
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__user_can_see_changeset
-msgid "User Can See Changeset"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__wizard_id
msgid "Wizard"
@@ -612,6 +531,19 @@ msgstr "ou"
msgid "to,from"
msgstr "para,de"
+#~ msgid "Changeset Changes"
+#~ msgstr "Mudanças no conjunto de alterações"
+
+#~ msgid "Changesets"
+#~ msgstr "Conjunto de alterações"
+
+#, fuzzy
+#~ msgid "Last Modified on"
+#~ msgstr "Última atualização em"
+
+#~ msgid "The overall number of changesets of this record"
+#~ msgstr "O número total de conjuntos de alterações deste registro"
+
#~ msgid "Flag nonmatching"
#~ msgstr "Sinal sem correspondente"
diff --git a/fetchmail_from_imap_folder/i18n/ru.po b/fetchmail_from_imap_folder/i18n/ru.po
index 2474b5bd1..2c31bbf67 100644
--- a/fetchmail_from_imap_folder/i18n/ru.po
+++ b/fetchmail_from_imap_folder/i18n/ru.po
@@ -46,7 +46,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/wizard/attach_mail_manually.py:0
-#, python-format
msgid "Attach emails manually"
msgstr ""
@@ -88,22 +87,6 @@ msgstr ""
msgid "Cancel"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_change_ids
-msgid "Changeset Changes"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_ids
-msgid "Changesets"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__folders_only
msgid ""
@@ -114,7 +97,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Confirm connection first."
msgstr ""
@@ -126,55 +108,28 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not create archive folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
-msgid "Could not fetch %(msgid)s in folder %(folder)s on server %(server)s"
+msgid ""
+"Could not fetch %(message_uid)s in folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not open folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not search folder %(folder)s on server %(server)s"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "Count Changesets"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "Count Pending Changeset Changes"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "Count Pending Changesets"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__object_id
msgid "Create a New Record"
@@ -334,17 +289,9 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Invalid folder %s!"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder____last_update
-msgid "Last Modified on"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__write_uid
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__write_uid
@@ -365,7 +312,7 @@ msgid "Match Algorithm"
msgstr ""
#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__msgid
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__message_uid
msgid "Message id"
msgstr ""
@@ -464,6 +411,11 @@ msgstr ""
msgid "Server Type"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__x_server_type_env_default
+msgid "Server Type Env Default"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__smart_search
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__smart_search
@@ -512,35 +464,11 @@ msgstr ""
msgid "The model to attach emails to"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "The number of pending changes of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "The number of pending changesets of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "The overall number of changesets of this record"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__path
msgid ""
-"The path to your mail folder. Typically would be something like 'INBOX."
-"myfolder'"
+"The path to your mail folder. Typically would be something like "
+"'INBOX.myfolder'"
msgstr ""
#. module: fetchmail_attach_from_folder
@@ -556,7 +484,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Unable to retrieve folders."
msgstr ""
@@ -565,14 +492,6 @@ msgstr ""
msgid "Use 1st match"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__user_can_see_changeset
-msgid "User Can See Changeset"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__wizard_id
msgid "Wizard"
diff --git a/fetchmail_from_imap_folder/i18n/sl.po b/fetchmail_from_imap_folder/i18n/sl.po
index 313221ced..31f78f426 100644
--- a/fetchmail_from_imap_folder/i18n/sl.po
+++ b/fetchmail_from_imap_folder/i18n/sl.po
@@ -46,7 +46,7 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/wizard/attach_mail_manually.py:0
-#, fuzzy, python-format
+#, fuzzy
msgid "Attach emails manually"
msgstr "Ročno pripenjanje e-pošte"
@@ -88,22 +88,6 @@ msgstr ""
msgid "Cancel"
msgstr "Preklic"
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_change_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_change_ids
-msgid "Changeset Changes"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__changeset_ids
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__changeset_ids
-msgid "Changesets"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__folders_only
msgid ""
@@ -114,7 +98,6 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Confirm connection first."
msgstr ""
@@ -126,55 +109,28 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not create archive folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
-msgid "Could not fetch %(msgid)s in folder %(folder)s on server %(server)s"
+msgid ""
+"Could not fetch %(message_uid)s in folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not open folder %(folder)s on server %(server)s"
msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Could not search folder %(folder)s on server %(server)s"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "Count Changesets"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "Count Pending Changeset Changes"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "Count Pending Changesets"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__object_id
msgid "Create a New Record"
@@ -340,18 +296,9 @@ msgstr ""
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server_folder.py:0
-#, python-format
msgid "Invalid folder %s!"
msgstr ""
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail____last_update
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder____last_update
-#, fuzzy
-msgid "Last Modified on"
-msgstr "ZadnjiÄŤ posodobljeno"
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__write_uid
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__write_uid
@@ -372,7 +319,7 @@ msgid "Match Algorithm"
msgstr ""
#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__msgid
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__message_uid
msgid "Message id"
msgstr "ID sporoÄŤila"
@@ -471,6 +418,11 @@ msgstr "StreĹľnik"
msgid "Server Type"
msgstr ""
+#. module: fetchmail_attach_from_folder
+#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__x_server_type_env_default
+msgid "Server Type Env Default"
+msgstr ""
+
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__smart_search
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__smart_search
@@ -526,35 +478,11 @@ msgstr ""
msgid "The model to attach emails to"
msgstr "Model, ki mu pripenjamo e-pošto"
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changeset_changes
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changeset_changes
-msgid "The number of pending changes of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_pending_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_pending_changesets
-msgid "The number of pending changesets of this record"
-msgstr ""
-
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server__count_changesets
-#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__count_changesets
-msgid "The overall number of changesets of this record"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,help:fetchmail_attach_from_folder.field_fetchmail_server_folder__path
msgid ""
-"The path to your mail folder. Typically would be something like 'INBOX."
-"myfolder'"
+"The path to your mail folder. Typically would be something like "
+"'INBOX.myfolder'"
msgstr "Pot do e-poštne mape. Običajno je to nekaj kot 'INBOX.mojamapa'"
#. module: fetchmail_attach_from_folder
@@ -570,7 +498,6 @@ msgstr "Stanje, ki se dodeli sporoÄŤilom prenesenim iz te mape."
#. module: fetchmail_attach_from_folder
#. odoo-python
#: code:addons/fetchmail_attach_from_folder/models/fetchmail_server.py:0
-#, python-format
msgid "Unable to retrieve folders."
msgstr ""
@@ -579,14 +506,6 @@ msgstr ""
msgid "Use 1st match"
msgstr "Uporabi 1. ujemanje"
-#. module: fetchmail_attach_from_folder
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__user_can_see_changeset
-#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__user_can_see_changeset
-msgid "User Can See Changeset"
-msgstr ""
-
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually_mail__wizard_id
msgid "Wizard"
@@ -617,6 +536,10 @@ msgstr "ali"
msgid "to,from"
msgstr "to,from"
+#, fuzzy
+#~ msgid "Last Modified on"
+#~ msgstr "ZadnjiÄŤ posodobljeno"
+
#~ msgid "Flag nonmatching"
#~ msgstr "OznaÄŤi ne ujemajoÄŤa"
From afe107451a389fb08b09e834e7c5c8182183c08c Mon Sep 17 00:00:00 2001
From: mymage
Date: Thu, 29 Jan 2026 09:28:44 +0000
Subject: [PATCH 71/79] Translated using Weblate (Italian)
Currently translated at 100.0% (91 of 91 strings)
Translation: server-tools-18.0/server-tools-18.0-fetchmail_attach_from_folder
Translate-URL: https://translation.odoo-community.org/projects/server-tools-18-0/server-tools-18-0-fetchmail_attach_from_folder/it/
---
fetchmail_from_imap_folder/i18n/it.po | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/fetchmail_from_imap_folder/i18n/it.po b/fetchmail_from_imap_folder/i18n/it.po
index 993eab6e6..696155086 100644
--- a/fetchmail_from_imap_folder/i18n/it.po
+++ b/fetchmail_from_imap_folder/i18n/it.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: server-tools (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-09-29 11:14+0000\n"
-"PO-Revision-Date: 2025-10-16 11:43+0000\n"
+"PO-Revision-Date: 2026-01-29 12:09+0000\n"
"Last-Translator: mymage \n"
"Language-Team: Italian (http://www.transifex.com/oca/OCA-server-tools-8-0/"
"language/it/)\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.10.4\n"
+"X-Generator: Weblate 5.15.2\n"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server_folder__action_id
@@ -120,6 +120,8 @@ msgstr "Impossibile creare la cartella %(folder)s nel server %(server)s"
msgid ""
"Could not fetch %(message_uid)s in folder %(folder)s on server %(server)s"
msgstr ""
+"Impossibile recuperare %(message_uid)s nella cartella %(folder)s nel server %"
+"(server)s"
#. module: fetchmail_attach_from_folder
#. odoo-python
@@ -430,7 +432,7 @@ msgstr "Tipo server"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_server__x_server_type_env_default
msgid "Server Type Env Default"
-msgstr ""
+msgstr "Tipo server ambiente predefinito"
#. module: fetchmail_attach_from_folder
#: model:ir.model.fields,field_description:fetchmail_attach_from_folder.field_fetchmail_attach_mail_manually__smart_search
From a10e004c1678666f294ba52d1b48a8ce39b4a237 Mon Sep 17 00:00:00 2001
From: adrip-s73
Date: Wed, 10 Dec 2025 13:53:53 +0100
Subject: [PATCH 72/79] [18.0][FIX] fetchmail_attach_from_folder: add missing
keyword argument
---
fetchmail_from_imap_folder/README.rst | 12 +++----
.../models/fetchmail_server.py | 4 +--
.../static/description/index.html | 34 ++++++++-----------
3 files changed, 20 insertions(+), 30 deletions(-)
diff --git a/fetchmail_from_imap_folder/README.rst b/fetchmail_from_imap_folder/README.rst
index efecb7f4e..c84f593ce 100644
--- a/fetchmail_from_imap_folder/README.rst
+++ b/fetchmail_from_imap_folder/README.rst
@@ -1,7 +1,3 @@
-.. image:: https://odoo-community.org/readme-banner-image
- :target: https://odoo-community.org/get-involved?utm_source=readme
- :alt: Odoo Community Association
-
=======================
Email gateway - folders
=======================
@@ -17,7 +13,7 @@ Email gateway - folders
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
-.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
+.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github
@@ -120,9 +116,9 @@ Authors
Contributors
------------
-- Holger Brunn hbrunn@therp.nl
-- Ronald Portier ronald@therp.nl
-- Alexandre Fayolle alexandre.fayolle@camptocamp.com
+- Holger Brunn hbrunn@therp.nl
+- Ronald Portier ronald@therp.nl
+- Alexandre Fayolle alexandre.fayolle@camptocamp.com
Maintainers
-----------
diff --git a/fetchmail_from_imap_folder/models/fetchmail_server.py b/fetchmail_from_imap_folder/models/fetchmail_server.py
index a42f8c356..cc43ba6a6 100644
--- a/fetchmail_from_imap_folder/models/fetchmail_server.py
+++ b/fetchmail_from_imap_folder/models/fetchmail_server.py
@@ -71,10 +71,10 @@ def onchange_server_type(self):
self.state = "draft"
return result
- def fetch_mail(self):
+ def fetch_mail(self, **kwargs):
result = True
for this in self:
if not this.folders_only:
- result = result and super(FetchmailServer, this).fetch_mail()
+ result = result and super(FetchmailServer, this).fetch_mail(**kwargs)
this.folder_ids.fetch_mail()
return result
diff --git a/fetchmail_from_imap_folder/static/description/index.html b/fetchmail_from_imap_folder/static/description/index.html
index 5066fe23a..3a77ca4ba 100644
--- a/fetchmail_from_imap_folder/static/description/index.html
+++ b/fetchmail_from_imap_folder/static/description/index.html
@@ -3,7 +3,7 @@
-README.rst
+Email gateway - folders
-
Adds the possibility to attach emails from a certain IMAP folder to
objects, ie partners. Matching is done via several algorithms, ie email
address, email address’s domain or the original Odoo algorithm.
In your fetchmail configuration, you’ll find a new list field
Folders to monitor. Add your folders here in IMAP notation (usually
something like INBOX.your_folder_name.your_subfolder_name), choose a
model to attach mails to and a matching algorithm to use.
Fill in a field to search for the email address in Field (model).
For partners, this would be email. Also fill in the header field
from the email to look at in Field (email). If you want to match
@@ -415,7 +410,7 @@
Match the domain of the email address(es) found in Field (email).
This would attach a mail to test1@example.com to a record with
Field (model) set to test2@example.com. Given that this is a
@@ -423,14 +418,14 @@
A widespread configuration is to have a shared mailbox with several
folders, i.e. one where users drop mails they want to attach to
partners. Let this folder be called From partners. Then create a
@@ -448,7 +443,7 @@
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
@@ -456,15 +451,15 @@
Adds the possibility to attach emails from a certain IMAP folder to
objects, ie partners. Matching is done via several algorithms, ie email
address, email address’s domain or the original Odoo algorithm.
In your fetchmail configuration, you’ll find a new list field
Folders to monitor. Add your folders here in IMAP notation (usually
something like INBOX.your_folder_name.your_subfolder_name), choose a
model to attach mails to and a matching algorithm to use.
Fill in a field to search for the email address in Field (model).
For partners, this would be email. Also fill in the header field
from the email to look at in Field (email). If you want to match
@@ -410,7 +415,7 @@
Match the domain of the email address(es) found in Field (email).
This would attach a mail to test1@example.com to a record with
Field (model) set to test2@example.com. Given that this is a
@@ -418,14 +423,14 @@
A widespread configuration is to have a shared mailbox with several
folders, i.e. one where users drop mails they want to attach to
partners. Let this folder be called From partners. Then create a
@@ -443,7 +448,7 @@
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
@@ -451,15 +456,15 @@