diff --git a/.travis.yml b/.travis.yml index e31ccc1cea7..e17ae79257a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,7 @@ virtualenv: system_site_packages: true install: + - git clone https://github.com/akretion/server-tools.git ${HOME}/server-tools-attachm -b 8-attachm-meta - git clone https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools - export PATH=${HOME}/maintainer-quality-tools/travis:${PATH} - travis_install_nightly diff --git a/file_email/README.rst b/file_email/README.rst new file mode 100644 index 00000000000..fb6ec5c39b3 --- /dev/null +++ b/file_email/README.rst @@ -0,0 +1,80 @@ + +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +========== +File Email +========== + +Abstract module for importing and processing the + attachment of an email. The attachment of the email will be imported + as an ir.attachment.metadata and then in your custom module + you can process it. + +An example of processing can be found in account_statement_email + + +Usage +===== + +Go the menu Settings > File Exchange > Configuration + +A implementation must define in your own module to test this module on a use case + + + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/149/8.0 + + +Known issues / Roadmap +====================== + +The purpose of this module is not to import the data of the file but only exchange files with external application. + + +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 +`_. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + + +Contributors +------------ + +* Valentin CHEMIERE +* Sebastien BEAU +* Joel Grand-Guillaume Camptocamp +* initOS + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://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 https://odoo-community.org. diff --git a/file_email/__init__.py b/file_email/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/file_email/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/file_email/__openerp__.py b/file_email/__openerp__.py new file mode 100644 index 00000000000..88baa95ac72 --- /dev/null +++ b/file_email/__openerp__.py @@ -0,0 +1,26 @@ +# coding: utf-8 +# @author Sébastien BEAU @ Akretion +# @author Florian DA COSTA @ Akretion +# @author Benoit GUILLOT @ Akretion +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + 'name': 'File Email', + 'version': '8.0.1.0.0', + 'author': 'Akretion,Odoo Community Association (OCA)', + 'category': 'Generic Modules', + 'license': 'AGPL-3', + 'website': 'http://www.akretion.com/', + 'depends': [ + 'attachment_metadata', + 'fetchmail' + ], + 'data': [ + 'security/ir.model.access.csv', + "views/fetchmail_view.xml", + "views/attachment_view.xml", + ], + 'demo': [], + 'installable': True, + 'images': [], +} diff --git a/file_email/models/__init__.py b/file_email/models/__init__.py new file mode 100644 index 00000000000..3d9d7edd669 --- /dev/null +++ b/file_email/models/__init__.py @@ -0,0 +1,2 @@ +from . import attachment +from . import fetchmail diff --git a/file_email/models/attachment.py b/file_email/models/attachment.py new file mode 100644 index 00000000000..5fb552e62fe --- /dev/null +++ b/file_email/models/attachment.py @@ -0,0 +1,109 @@ +# coding: utf-8 +# @author Sébastien BEAU @ Akretion +# @author Florian DA COSTA @ Akretion +# @author Benoit GUILLOT @ Akretion +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp import models, fields, api +import base64 + + +class IrAttachmentMetadata(models.Model): + _inherit = "ir.attachment.metadata" + + fetchmail_attachment_condition_id = fields.Many2one( + 'fetchmail.attachment.condition', + string='FetchMail condition', + help="The Fetchemail attachment condition used" + "to create this attachment") + fetchmail_server_id = fields.Many2one( + 'fetchmail.server', + string='Email Server', + related='fetchmail_attachment_condition_id.server_id', store=True, + readonly=True, + help="The email server used to create this attachment") + + def message_process(self, cr, uid, model, message, custom_values=None, + save_original=False, strip_attachments=False, + thread_id=None, + context=None): + if context is None: + context = {} + context['no_post'] = True + return True + + def message_post(self, cr, uid, thread_id, body='', subject=None, + type='notification', subtype=None, parent_id=False, + attachments=None, content_subtype='html', context=None, + **kwargs): + if context.get('no_post'): + return None + return True + + @api.model + def _get_attachment_metadata_data(self, condition, msg, att): + values = { + 'fetchmail_attachment_condition_id': condition.id, + 'file_type': condition.server_id.file_type, + 'name': msg['subject'], + 'direction': 'input', + 'date': msg['date'], + 'ext_id': msg['message_id'], + 'datas_fname': att[0], + 'datas': base64.b64encode(att[1]), + 'state': 'pending' + } + return values + + @api.model + def prepare_data_from_basic_condition(self, condition, msg): + vals = {} + if (condition.from_email in msg['from'] and + condition.mail_subject in msg['subject']): + for att in msg['attachments']: + if condition.file_extension in att[0]: + vals = self._get_attachment_metadata_data( + condition, msg, att) + break + return vals + + @api.model + def _prepare_data_for_attachment_metadata(self, msg): + """Method to prepare the data for creating a attachment metadata. + :param msg: a dictionnary with the email data + :type: dict + + :return: a list of dictionnary that containt + the attachment metadata data + :rtype: list + """ + res = [] + server_id = self._context.get('fetchmail_server_id', False) + file_condition_obj = self.env['fetchmail.attachment.condition'] + cond_ids = file_condition_obj.search([('server_id', '=', server_id)]) + if cond_ids: + for cond in cond_ids: + # this part of code raise an expetion if type != normal + # if cond.type == 'normal': + vals = self.prepare_data_from_basic_condition(cond, msg) + # else: + # vals = getattr(self, cond.type)(cond, msg) + if vals: + res.append(vals) + return res + + @api.model + def message_new(self, msg, custom_values): + created_ids = [] + res = self._prepare_data_for_attachment_metadata(msg) + if res: + for vals in res: + default = self._context.get('default_attachment_metadata_vals') + if default: + for key in default: + if key not in vals: + vals[key] = default[key] + created_ids.append(self.create(vals)) + self._cr.commit() + return created_ids[0] + return None diff --git a/file_email/models/fetchmail.py b/file_email/models/fetchmail.py new file mode 100644 index 00000000000..944a7c719dc --- /dev/null +++ b/file_email/models/fetchmail.py @@ -0,0 +1,72 @@ +# coding: utf-8 +# @author Sébastien BEAU @ Akretion +# @author Florian DA COSTA @ Akretion +# @author Benoit GUILLOT @ Akretion +# @author Mourad EL HADJ MIMOUNE +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp import models, fields, api + + +class FetchmailServer(models.Model): + _inherit = 'fetchmail.server' + + def company_default_get(self): + company_id = (self.env['res.company']. + _company_default_get('fetchmail.server')) + return self.env['res.company'].browse(company_id) + + file_type = fields.Selection( + selection='get_file_type', + help='The file type will show some special option') + company_id = fields.Many2one( + 'res.company', string='Company', + required=True, default=company_default_get) + attachment_metadata_condition_ids = fields.One2many( + 'fetchmail.attachment.condition', 'server_id', string='Attachment') + + @api.model + def get_file_type(self): + return [('basic_import', 'Basic import')] + + @api.one + def get_context_for_server(self): + if self._context is None: + ctx = {} + else: + ctx = self._context.copy() + ctx['default_attachment_metadata_vals'] = {} + ctx['default_company_id'] = self.company_id.id + ctx['default_fetchmail_server_id'] = self.id + return ctx + + @api.multi + def fetch_mail(self): + for server in self: + super(FetchmailServer, server).fetch_mail() + return True + + +class FetchmailAttachmentCondition(models.Model): + _name = 'fetchmail.attachment.condition' + _description = "Fetchmail Attachment Conditions" + + @api.model + def _get_attachment_metadata_condition_type(self): + return self.get_attachment_metadata_condition_type() + + def get_attachment_metadata_condition_type(self): + return [('normal', 'Normal')] + + name = fields.Char(string='Name', required=True,) + from_email = fields.Char(string='Email') + mail_subject = fields.Char() + type = fields.Selection( + selection='_get_attachment_metadata_condition_type', + required=True, default='normal', + help="Create your own type if the normal type " + "do not correspond to your need") + file_extension = fields.Char( + required=True, + help="File extension or file name") + server_id = fields.Many2one('fetchmail.server', string='Server Mail') diff --git a/file_email/security/ir.model.access.csv b/file_email/security/ir.model.access.csv new file mode 100644 index 00000000000..9fff725bf35 --- /dev/null +++ b/file_email/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_fetchmail_attachment_condition_manager,fetchmail.attachment.condition.user,model_fetchmail_attachment_condition,base.group_system,1,1,1,1 +access_fetchmail_attachment_condition_user,fetchmail.attachment.condition.user,model_fetchmail_attachment_condition,base.group_user,1,0,0,0 diff --git a/file_email/views/attachment_view.xml b/file_email/views/attachment_view.xml new file mode 100644 index 00000000000..f1f9e2b1913 --- /dev/null +++ b/file_email/views/attachment_view.xml @@ -0,0 +1,24 @@ + + + + + + + ir.attachment.metadata.search + ir.attachment.metadata + search + + + + + + + + + + + + + + diff --git a/file_email/views/fetchmail_view.xml b/file_email/views/fetchmail_view.xml new file mode 100644 index 00000000000..1ff41a969db --- /dev/null +++ b/file_email/views/fetchmail_view.xml @@ -0,0 +1,72 @@ + + + + + + fetchmail.server + + + + + + + + + + + + + + + + + view_fetchmail_attachment_condition_tree + fetchmail.attachment.condition + + + + + + + + + + + + + + view_fetchmail_attachment_condition_form + fetchmail.attachment.condition + +
+ +

+

+ + + + + + + +
+
+
+
+ + + +
+
diff --git a/oca_dependencies.txt b/oca_dependencies.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/oca_dependencies.txt @@ -0,0 +1 @@ + diff --git a/requirements.txt b/requirements.txt index c489fc0eb7f..249f8179d76 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ pysftp acme_tiny IPy + python-fs