notze
6 years ago
committed by
notze-nb2
11 changed files with 392 additions and 0 deletions
-
78mail_store_outgoing/README.rst
-
1mail_store_outgoing/__init__.py
-
21mail_store_outgoing/__manifest__.py
-
123mail_store_outgoing/i18n/de.po
-
1mail_store_outgoing/models/__init__.py
-
113mail_store_outgoing/models/ir_mail_server.py
-
2mail_store_outgoing/security/ir.model.access.csv
-
BINmail_store_outgoing/static/description/icon.png
-
2mail_store_outgoing/tests/__init__.py
-
20mail_store_outgoing/tests/test_ir_mail.py
-
31mail_store_outgoing/views/ir_mail_server_view.xml
@ -0,0 +1,78 @@ |
|||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
|||
:target: https://www.gnu.org/licenses/agpl |
|||
:alt: License: AGPL-3 |
|||
|
|||
=================== |
|||
Mail Store Outgoing |
|||
=================== |
|||
|
|||
This Module enables Odoo to store outgoing Mails via IMAP into a selected folder. |
|||
|
|||
Installation |
|||
============ |
|||
|
|||
Just install the module via the module list. |
|||
|
|||
Configuration |
|||
============= |
|||
|
|||
To configure this module, you need to test the connection and then select your folder out of the provided list. |
|||
|
|||
Usage |
|||
===== |
|||
|
|||
If you sent and email, it will appear in your selected mailfolder. |
|||
|
|||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
|||
:alt: Try me on Runbot |
|||
:target: https://runbot.odoo-community.org/runbot/205/10.0 |
|||
|
|||
Known issues / Roadmap |
|||
====================== |
|||
|
|||
No known issues |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues |
|||
<https://github.com/OCA/social/issues>`_. In case of trouble, please |
|||
check there if your issue has already been reported. If you spotted it first, |
|||
help us smash it by providing detailed and welcomed feedback. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Images |
|||
------ |
|||
|
|||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Georg Notter, georg.notter@agenterp.com (Agent ERP GmbH) |
|||
|
|||
Do not contact contributors directly about support or help with technical issues. |
|||
|
|||
Funders |
|||
------- |
|||
|
|||
The development of this module has been financially supported by: |
|||
|
|||
* Agent ERP GmbH |
|||
|
|||
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. |
@ -0,0 +1 @@ |
|||
from . import models |
@ -0,0 +1,21 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2017 Georg Notter, Agent ERP GmbH |
|||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). |
|||
{ |
|||
"name": "Mail Store Outgoing", |
|||
"summary": "Store outgoing Mails via IMAP into a selected folder.", |
|||
"version": "12.0.1.0.0", |
|||
"category": "mail", |
|||
"website": "https://github.com/OCA/social", |
|||
"author": "Agent ERP GmbH, Odoo Community Association (OCA)", |
|||
"license": "AGPL-3", |
|||
"application": False, |
|||
"installable": True, |
|||
"depends": [ |
|||
"mail", |
|||
], |
|||
"data": [ |
|||
'views/ir_mail_server_view.xml', |
|||
'security/ir.model.access.csv', |
|||
], |
|||
} |
@ -0,0 +1,123 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * mail_store_outgoing |
|||
# |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 10.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2017-10-15 14:53+0000\n" |
|||
"PO-Revision-Date: 2017-10-15 16:57+0100\n" |
|||
"Last-Translator: <>\n" |
|||
"Language-Team: \n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: 8bit\n" |
|||
"Plural-Forms: \n" |
|||
"X-Generator: Poedit 1.5.4\n" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: code:addons/mail_store_outgoing/models/ir_mail_server.py:48 |
|||
#, python-format |
|||
msgid "Connection Test Failed!" |
|||
msgstr "Verbindung fehlgeschlagen!" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_create_uid |
|||
msgid "Created by" |
|||
msgstr "Erstellt von" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_create_date |
|||
msgid "Created on" |
|||
msgstr "Angelegt am" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_display_name |
|||
msgid "Display Name" |
|||
msgstr "Anzeigename" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_name |
|||
msgid "Foldername" |
|||
msgstr "Verzeichnisname" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: code:addons/mail_store_outgoing/models/ir_mail_server.py:48 |
|||
#, python-format |
|||
msgid "" |
|||
"Here is what we got instead:\n" |
|||
" %s" |
|||
msgstr "" |
|||
"Fehlermeldung:\n" |
|||
" %s" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_id |
|||
msgid "ID" |
|||
msgstr "ID" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_server_imap_mailbox_verified |
|||
msgid "IMAP Connection Verified" |
|||
msgstr "IMAP Verbindung verifiziert" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model,name:mail_store_outgoing.model_ir_mail_imap_folder |
|||
msgid "Imap Folder" |
|||
msgstr "Imap Verzeichnis" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_server_imap_mailbox_folder |
|||
msgid "Imap Folders" |
|||
msgstr "Imap Verzeichnisse" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder___last_update |
|||
msgid "Last Modified on" |
|||
msgstr "Zuletzt geändert am" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_write_uid |
|||
msgid "Last Updated by" |
|||
msgstr "Zuletzt aktualisiert durch" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_write_date |
|||
msgid "Last Updated on" |
|||
msgstr "Zuletzt aktualisiert am" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_imap_folder_server_id |
|||
msgid "Mail Server" |
|||
msgstr "Mailserver" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.ui.view,arch_db:mail_store_outgoing.ir_mail_server_form |
|||
msgid "Outgoing Mail Settings" |
|||
msgstr "Maileinstellungen" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_server_separate_imap_server |
|||
msgid "Separate Imap Server" |
|||
msgstr "Alternativer Imapserver" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_server_store_outgoing_mail |
|||
msgid "Store Outgoing Mail" |
|||
msgstr "Ausgehende Mails speichern" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.ui.view,arch_db:mail_store_outgoing.ir_mail_server_form |
|||
msgid "Test Imap Connection" |
|||
msgstr "Verbindung testen " |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model.fields,field_description:mail_store_outgoing.field_ir_mail_server_has_separate_imap_server |
|||
msgid "Use Separate Imap Server" |
|||
msgstr "Verwende alternativen IMAP Server" |
|||
|
|||
#. module: mail_store_outgoing |
|||
#: model:ir.model,name:mail_store_outgoing.model_ir_mail_server |
|||
msgid "ir.mail_server" |
|||
msgstr "ir.mail_server" |
@ -0,0 +1 @@ |
|||
from . import ir_mail_server |
@ -0,0 +1,113 @@ |
|||
# -*- coding: utf-8 -*- |
|||
import logging |
|||
import re |
|||
import imaplib |
|||
from odoo import tools |
|||
from odoo.exceptions import ValidationError |
|||
from odoo import fields |
|||
from odoo import models |
|||
from odoo import api |
|||
from odoo.tools.translate import _ |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
|
|||
class IrMailServer(models.Model): |
|||
_inherit = 'ir.mail_server' |
|||
|
|||
imap_mailbox_folder = fields.Many2one('ir.mail.imap.folder', |
|||
'Imap Folders',) |
|||
imap_mailbox_verified = fields.Boolean('IMAP Connection Verified', ) |
|||
store_outgoing_mail = fields.Boolean() |
|||
has_separate_imap_server = fields.Boolean('Use Separate Imap Server', ) |
|||
separate_imap_server = fields.Char() |
|||
active = fields.Boolean() |
|||
|
|||
@api.model |
|||
def parse_list_response(self, line): |
|||
line = line.decode('utf-8') |
|||
list_response_pattern = re.compile( |
|||
r'\((?P<flags>.*?)\) "(?P<delimiter>.*)" (?P<name>.*)' |
|||
) |
|||
flags, delimiter, mailbox_name = \ |
|||
list_response_pattern.match(line).groups() |
|||
mailbox_name = mailbox_name.strip('"') |
|||
return (flags, delimiter, mailbox_name) |
|||
|
|||
@api.multi |
|||
def test_imap_connection(self): |
|||
self.ensure_one() |
|||
imap_pool = self.env['ir.mail.imap.folder'] |
|||
if self.has_separate_imap_server: |
|||
smtp_server = self.separate_imap_server |
|||
else: |
|||
smtp_server = self.smtp_host |
|||
try: |
|||
maillib = imaplib.IMAP4_SSL(smtp_server) |
|||
maillib.login(self.smtp_user, self.smtp_pass) |
|||
typ, mBoxes = maillib.list() |
|||
folder_ids = imap_pool.search([('server_id', '=', self.id)]) |
|||
for folder in folder_ids: |
|||
folder.unlink() |
|||
for line in mBoxes: |
|||
flags, delimiter, mailbox_name = self.parse_list_response(line) |
|||
res = {'server_id': self.id, 'name': mailbox_name, } |
|||
imap_pool.create(res) |
|||
self.write({'imap_mailbox_verified': True}) |
|||
except Exception as e: |
|||
raise ValidationError( |
|||
_("Connection Test Failed! " |
|||
"Here is what we got instead:\n %s") % tools.ustr(e)) |
|||
finally: |
|||
maillib.logout() |
|||
|
|||
@api.model |
|||
def send_email(self, message, mail_server_id=None, |
|||
smtp_server=None, smtp_port=None, smtp_user=None, |
|||
smtp_password=None, smtp_encryption=None, smtp_debug=False, |
|||
smtp_session=None): |
|||
res = super(IrMailServer, self).send_email( |
|||
message, mail_server_id, smtp_server, smtp_port, |
|||
smtp_user, smtp_password, smtp_encryption, smtp_debug, |
|||
smtp_session) |
|||
self._save_sent_message_to_sentbox(message, mail_server_id) |
|||
return res |
|||
|
|||
@api.model |
|||
def _save_sent_message_to_sentbox(self, msg, mail_server_id): |
|||
mail_server = None |
|||
smtp_server = None |
|||
if mail_server_id: |
|||
mail_server = self.sudo().browse(mail_server_id) |
|||
else: |
|||
mail_server = self.sudo().search([], order='sequence', limit=1) |
|||
if mail_server: |
|||
if not mail_server.store_outgoing_mail: |
|||
return True |
|||
if mail_server.has_separate_imap_server: |
|||
smtp_server = mail_server.separate_imap_server |
|||
else: |
|||
smtp_server = mail_server.smtp_host |
|||
smtp_user = mail_server.smtp_user |
|||
smtp_password = mail_server.smtp_pass |
|||
try: |
|||
maillib = imaplib.IMAP4_SSL(smtp_server) |
|||
maillib.login(smtp_user, smtp_password) |
|||
folder = mail_server.imap_mailbox_folder.name.join('""') |
|||
maillib.append(str.encode(folder), r'\Seen', None, str(msg).encode()) |
|||
except Exception as ex: |
|||
_logger.error(_( |
|||
'Failed attaching mail via imap to server %s %s') |
|||
% (ex, msg)) |
|||
finally: |
|||
maillib.logout() |
|||
return True |
|||
|
|||
|
|||
class IrMailImapFolder(models.Model): |
|||
|
|||
_name = 'ir.mail.imap.folder' |
|||
_description = 'Imap Folder' |
|||
|
|||
server_id = fields.Many2one('ir.mail_server', 'Mail Server', ) |
|||
name = fields.Char('Foldername',) |
@ -0,0 +1,2 @@ |
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
|||
access_ir_mail_imap_folder,access_ir_mail_imap_folder,model_ir_mail_imap_folder,,1,0,1,0 |
After Width: 64 | Height: 64 | Size: 1005 B |
@ -0,0 +1,2 @@ |
|||
from . import test_ir_mail |
|||
|
@ -0,0 +1,20 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2018 AGENTERP GMBH |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from openerp.tests.common import TransactionCase |
|||
|
|||
|
|||
class TestIrMail(TransactionCase): |
|||
|
|||
def setUp(self): |
|||
super(TestIrMail, self).setUp() |
|||
|
|||
def test_parse_list_response(self): |
|||
imap_mailbox = \ |
|||
'(\\HasNoChildren \\UnMarked) "." "INBOX.Deleted Messages"' |
|||
flags, delimiter, mailbox_name = \ |
|||
self.env['ir.mail_server'].parse_list_response(imap_mailbox) |
|||
self.assertEqual(flags, '\\HasNoChildren \\UnMarked') |
|||
self.assertEqual(delimiter, '.') |
|||
self.assertEqual(mailbox_name, 'INBOX.Deleted Messages') |
@ -0,0 +1,31 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<record model="ir.ui.view" id="ir_mail_server_form_save_outgoing"> |
|||
<field name="model">ir.mail_server</field> |
|||
<field name="name">ir_mail_server_form_save_outgoing</field> |
|||
<field name="inherit_id" ref="base.ir_mail_server_form" /> |
|||
<field name="arch" type="xml"> |
|||
<field name="sequence" position="after"> |
|||
<field name="active"/> |
|||
</field> |
|||
<xpath expr="//form/sheet/group" position="after"> |
|||
<group string="Outgoing Mail Settings" colspan="4"> |
|||
<field name="store_outgoing_mail"/> |
|||
</group> |
|||
<group colspan="4" attrs="{'invisible': [('store_outgoing_mail','=', False)]}"> |
|||
<field name="has_separate_imap_server"/> |
|||
<field name="separate_imap_server" attrs="{'invisible': [('has_separate_imap_server','=', False)]}"/> |
|||
</group> |
|||
<group colspan="4" attrs="{'invisible': [('store_outgoing_mail','=', False)]}"> |
|||
<button name="test_imap_connection" type="object" string="Test Imap Connection" icon="gtk-network"/> |
|||
</group> |
|||
<group colspan="4" attrs="{'invisible': [('store_outgoing_mail','=', False)]}"> |
|||
<field name="imap_mailbox_verified" readonly="1"/> |
|||
</group> |
|||
<group colspan="4" attrs="{'invisible': [('store_outgoing_mail','=', False),('imap_mailbox_verified','=', False)]}"> |
|||
<field name="imap_mailbox_folder" attrs="{'required': [('imap_mailbox_verified','=', True),('store_outgoing_mail','=',True)]}"/> |
|||
</group> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue