Mathias Markl 7 years ago
parent
commit
07c53588db
  1. 5
      muk_web_preview_mail/README.md
  2. 2
      muk_web_preview_mail/__init__.py
  3. 18
      muk_web_preview_mail/__manifest__.py
  4. 2
      muk_web_preview_mail/controllers/__init__.py
  5. 87
      muk_web_preview_mail/controllers/main.py
  6. 28
      muk_web_preview_mail/demo/demo.xml
  7. 13
      muk_web_preview_mail/demo/preview_mail_demo.xml
  8. 6
      muk_web_preview_mail/doc/changelog.rst
  9. 49
      muk_web_preview_mail/doc/index.rst
  10. 38
      muk_web_preview_mail/static/description/index.html
  11. 5
      muk_web_preview_mail/static/src/js/preview_handler.js
  12. 3
      muk_web_preview_mail/tests/__init__.py
  13. 12
      muk_web_preview_mail/tests/test_mail_parse.py

5
muk_web_preview_mail/README.md

@ -1,5 +0,0 @@
# MuK Preview Mail
Extendes the Preview Dialog to support mails. Currently the following mail extensions are supported:
* Microsoft Outlook Express Mail Message (*.eml, message/rfc822)

2
muk_web_preview_mail/__init__.py

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
################################################################################### ###################################################################################
# #
# Copyright (C) 2017 MuK IT GmbH # Copyright (C) 2017 MuK IT GmbH

18
muk_web_preview_mail/__manifest__.py

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
################################################################################### ###################################################################################
# #
# Copyright (C) 2017 MuK IT GmbH # Copyright (C) 2017 MuK IT GmbH
@ -22,28 +20,25 @@
{ {
"name": "MuK Preview Mail", "name": "MuK Preview Mail",
"summary": """Mail Preview""", "summary": """Mail Preview""",
"description": """
Extendes the Extendes the Preview Dialog to support mails.
Currently the following mail extensions are supported:
- Microsoft Outlook Express Mail Message (*.eml, message/rfc822)
""",
"version": "11.0.1.1.0",
"version": "11.0.2.0.0",
"category": "Extra Tools", "category": "Extra Tools",
"license": "AGPL-3", "license": "AGPL-3",
"website": "http://www.mukit.at", "website": "http://www.mukit.at",
"live_test_url": "https://demo.mukit.at/web/login",
"author": "MuK IT", "author": "MuK IT",
"contributors": [ "contributors": [
"Mathias Markl <mathias.markl@mukit.at>", "Mathias Markl <mathias.markl@mukit.at>",
], ],
"depends": [ "depends": [
"mail", "mail",
"muk_utils",
"muk_web_preview", "muk_web_preview",
], ],
"data": [ "data": [
"template/assets.xml", "template/assets.xml",
], ],
"demo": [ "demo": [
"demo/preview_mail_demo.xml",
"demo/demo.xml",
], ],
"qweb": [ "qweb": [
"static/src/xml/*.xml", "static/src/xml/*.xml",
@ -52,10 +47,7 @@
'static/description/banner.png' 'static/description/banner.png'
], ],
"external_dependencies": { "external_dependencies": {
"python": [
'requests',
'cachetools'
],
"python": [],
"bin": [], "bin": [],
}, },
"application": False, "application": False,

2
muk_web_preview_mail/controllers/__init__.py

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
################################################################################### ###################################################################################
# #
# Copyright (C) 2017 MuK IT GmbH # Copyright (C) 2017 MuK IT GmbH

87
muk_web_preview_mail/controllers/main.py

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
################################################################################### ###################################################################################
# #
# Copyright (C) 2017 MuK IT GmbH # Copyright (C) 2017 MuK IT GmbH
@ -21,88 +19,43 @@
import os import os
import json import json
import email
import base64
import urllib import urllib
import logging import logging
import mimetypes import mimetypes
import collections import collections
import werkzeug.exceptions
from urllib import parse
from odoo import _
from odoo import tools
from odoo import http
from odoo.http import request
from odoo.http import Response
import werkzeug
_logger = logging.getLogger(__name__)
from odoo import _, http
from odoo.http import request, Response
try:
import requests
except ImportError:
_logger.warn('Cannot `import requests`.')
from odoo.addons.muk_utils.http import get_response
from odoo.addons.muk_utils.http import make_error_response
try:
from cachetools import TTLCache
mail_cache = TTLCache(maxsize=50, ttl=600)
except ImportError:
_logger.warn('Cannot `import cachetools`.')
_logger = logging.getLogger(__name__)
class MailParserController(http.Controller): class MailParserController(http.Controller):
_Attachment = collections.namedtuple('Attachment', 'name mimetype extension url info') _Attachment = collections.namedtuple('Attachment', 'name mimetype extension url info')
@http.route('/web/preview/converter/mail', auth="user", type='http')
def parse_mail(self, url, attachment=None, force_compute=False, **kw):
try:
message = mail_cache[url] if not force_compute else None
except KeyError:
message = None
if not message:
if not bool(parse.urlparse(url).netloc):
url_parts = url.split('?')
path = url_parts[0]
query_string = url_parts[1] if len(url_parts) > 1 else None
router = request.httprequest.app.get_db_router(request.db).bind('')
match = router.match(path, query_args=query_string)
method = router.match(path, query_args=query_string)[0]
params = dict(parse.parse_qsl(query_string))
if len(match) > 1:
params.update(match[1])
response = method(**params)
if not response.status_code == 200:
return self._make_error_response(response.status_code,response.description if hasattr(response, 'description') else _("Unknown Error"))
else:
if response.headers['content-type'] == 'message/rfc822':
message = request.env['mail.thread'].message_parse(response.data, False)
else:
return werkzeug.exceptions.UnsupportedMediaType(_("Unparsable message! The file has to be of type: message/rfc822"))
else:
try:
response = requests.get(url)
if response.headers['content-type'] == 'message/rfc822':
message = request.env['mail.thread'].message_parse(response.content, False)
else:
return werkzeug.exceptions.UnsupportedMediaType(_("Unparsable message! The file has to be of type: message/rfc822"))
except requests.exceptions.RequestException as exception:
return self._make_error_response(exception.response.status_code, exception.response.reason or _("Unknown Error"))
mail_cache[url] = message
return self._make_parse_response(request.httprequest.url, message.copy(), attachment)
@http.route('/web/preview/mail', auth="user", type='http')
def preview_mail(self, url, attachment=None, **kw):
status, headers, content = get_response(url)
if status != 200:
return make_error_response(status, content or _("Unknown Error"))
elif headers['content-type'] != 'message/rfc822':
return werkzeug.exceptions.UnsupportedMediaType(
_("Unparsable message! The file has to be of type: message/rfc822"))
else:
message = request.env['mail.thread'].message_parse(content, False)
return self._make_parse_response(request.httprequest.url, message, attachment)
def _set_query_parameter(self, url, param_name, param_value): def _set_query_parameter(self, url, param_name, param_value):
scheme, netloc, path, query_string, fragment = parse.urlsplit(url)
query_params = parse.parse_qs(query_string)
scheme, netloc, path, query_string, fragment = urllib.parse.urlsplit(url)
query_params = urllib.parse.parse_qs(query_string)
query_params[param_name] = [param_value] query_params[param_name] = [param_value]
new_query_string = urllib.parse.urlencode(query_params, doseq=True) new_query_string = urllib.parse.urlencode(query_params, doseq=True)
return parse.urlunsplit((scheme, netloc, path, new_query_string, fragment))
def _make_error_response(self, status, message):
exception = werkzeug.exceptions.HTTPException()
exception.code = status
exception.description = message
return exception
return urllib.parse.urlunsplit((scheme, netloc, path, new_query_string, fragment))
def _make_attachment_response(self, file, filename): def _make_attachment_response(self, file, filename):
headers = [('Content-Type', mimetypes.guess_type(urllib.request.pathname2url(filename))[0]), headers = [('Content-Type', mimetypes.guess_type(urllib.request.pathname2url(filename))[0]),

28
muk_web_preview_mail/demo/demo.xml

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017 MuK IT GmbH
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<odoo noupdate="1">
<record id="mail_attachment_demo" model="ir.attachment">
<field name="name">sample.eml</field>
<field name="datas_fname">sample.eml</field>
<field name="datas" type="base64" file="muk_web_preview_mail/demo/data/sample.eml"/>
</record>
</odoo>

13
muk_web_preview_mail/demo/preview_mail_demo.xml

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="mail_attachment_demo" model="ir.attachment">
<field name="name">sample.eml</field>
<field name="datas_fname">sample.eml</field>
<field name="datas" type="base64" file="muk_web_preview_mail/demo/data/sample.eml"/>
</record>
</data>
</odoo>

6
muk_web_preview_mail/doc/changelog.rst

@ -1,9 +1,13 @@
`2.0.0`
-------
- Migrated to Python 3
`1.1.0` `1.1.0`
------- -------
- Lazy load javascript - Lazy load javascript
`1.0.0` `1.0.0`
------- -------

49
muk_web_preview_mail/doc/index.rst

@ -0,0 +1,49 @@
================
MuK Preview Mail
================
Extendes the Preview Dialog to support mails. Currently the following
mail extensions are supported:
* Microsoft Outlook Express Mail Message (\*.eml, message/rfc822)
Installation
============
To install this module, you need to:
Download the module and add it to your Odoo addons folder. Afterward, log on to
your Odoo server and go to the Apps menu. Trigger the debug modus and update the
list by clicking on the "Update Apps List" link. Now install the module by
clicking on the install button.
Configuration
=============
No additional configuration is needed to use this module.
Usage
=============
Go to a binary that contains a mail and open the preview dialog to view
the preview.
Credits
=======
Contributors
------------
* Mathias Markl <mathias.markl@mukit.at>
Author & Maintainer
-------------------
This module is maintained by the `MuK IT GmbH <https://www.mukit.at/>`_.
MuK IT is an Austrian company specialized in customizing and extending Odoo.
We develop custom solutions for your individual needs to help you focus on
your strength and expertise to grow your business.
If you want to get in touch please contact us via mail
(sale@mukit.at) or visit our website (https://mukit.at).

38
muk_web_preview_mail/static/description/index.html

@ -4,15 +4,15 @@
<h3 class="oe_slogan">Preview your mails directly in Odoo.</h3> <h3 class="oe_slogan">Preview your mails directly in Odoo.</h3>
<h4 class="oe_slogan" style="font-size: 23px;">MuK IT GmbH - <h4 class="oe_slogan" style="font-size: 23px;">MuK IT GmbH -
www.mukit.at</h4> www.mukit.at</h4>
<div class="oe_demo oe_screenshot">
<div class="oe_demo oe_screenshot" style="max-width: 84%; margin: 16px 8%;">
<img src="screenshot.png"> <img src="screenshot.png">
</div> </div>
</div> </div>
</section> </section>
<section class="oe_container" style="padding-top: 25px;">
<section class="oe_container">
<div class="oe_row oe_spaced"> <div class="oe_row oe_spaced">
<div class="oe_picture">
<div style="max-width: 84%; margin: 16px 8%;">
<h3 class="oe_slogan">Overview</h3> <h3 class="oe_slogan">Overview</h3>
<p class="oe_mt32">Extendes the Preview Dialog to support mails. <p class="oe_mt32">Extendes the Preview Dialog to support mails.
Currently the following mail extensions are supported:</p> Currently the following mail extensions are supported:</p>
@ -24,14 +24,46 @@
</div> </div>
</section> </section>
<section class="oe_container oe_dark"
style="margin-bottom: 20px; border-top: 5px solid #797979; border-bottom: 5px solid #797979;">
<h3 class="oe_slogan" style="margin-bottom: 10px;">Demo</h3>
<div class="row" style="margin: auto; max-width: 200px;">
<div class="col-xs-6">
<h5 class="oe_slogan" style="font-size: 20px; margin: 2px;">User:</h5>
</div>
<div class="col-xs-6">
<h5 class="oe_slogan" style="font-size: 20px; margin: 2px;">apps</h5>
</div>
<div class="col-xs-6">
<h5 class="oe_slogan" style="font-size: 20px; margin: 2px;">Password:</h5>
</div>
<div class="col-xs-6">
<h5 class="oe_slogan" style="font-size: 20px; margin: 2px;">demo</h5>
</div>
</div>
<div class="oe_slogan" style="margin-top: 5px;">
<a class="btn btn-primary btn-lg mt8"
href="https://demo.mukit.at/web/login"
style="position: relative; overflow: hidden;"><span
class="o_ripple"
style="height: 138px; width: 138px; top: -35.2969px; left: -8.17188px;"></span>
<i class="fa fa-video-camera"></i> Live Preview </a>
</div>
</section>
<section class="oe_container oe_dark"> <section class="oe_container oe_dark">
<h3 class="oe_slogan">Help and Support</h3> <h3 class="oe_slogan">Help and Support</h3>
<h5 class="oe_slogan" style="font-size: 20px;">Feel free to
contact us, if you need any help with your Odoo integration or
addiontal features.</h5>
<div class="oe_slogan"> <div class="oe_slogan">
<a class="btn btn-primary btn-lg mt8" href="mailto:sale@mukit.at"> <a class="btn btn-primary btn-lg mt8" href="mailto:sale@mukit.at">
<i class="fa fa-envelope"></i> Email <i class="fa fa-envelope"></i> Email
</a> <a class="btn btn-primary btn-lg mt8" </a> <a class="btn btn-primary btn-lg mt8"
href="https://mukit.at/page/contactus"> <i class="fa fa-phone"></i> href="https://mukit.at/page/contactus"> <i class="fa fa-phone"></i>
Contact Contact
</a> <a class="btn btn-primary btn-lg mt8" href="mailto:support@mukit.at">
<i class="fa fa-life-ring"></i> Support
</a> </a>
</div> </div>
<img src="logo.png" style="width: 200px; margin-bottom: 20px;" <img src="logo.png" style="width: 200px; margin-bottom: 20px;"

5
muk_web_preview_mail/static/src/js/preview_handler.js

@ -41,7 +41,7 @@ var MailHandler = PreviewHandler.BaseHandler.extend({
var result = $.Deferred(); var result = $.Deferred();
var $content = $(QWeb.render('MailHTMLContent')); var $content = $(QWeb.render('MailHTMLContent'));
$.ajax({ $.ajax({
url: '/web/preview/converter/mail',
url: '/web/preview/mail',
dataType: "json", dataType: "json",
data: { data: {
url: url, url: url,
@ -61,6 +61,7 @@ var MailHandler = PreviewHandler.BaseHandler.extend({
}, },
}); });
}); });
$content.find('.reply').toggle(!!self.widget.do_action);
$content.find('#subject').text(mail.subject); $content.find('#subject').text(mail.subject);
$content.find('#meta-to').text(mail.to); $content.find('#meta-to').text(mail.to);
$content.find('#meta-cc').text(mail.cc); $content.find('#meta-cc').text(mail.cc);
@ -127,6 +128,6 @@ var MailHandler = PreviewHandler.BaseHandler.extend({
return { return {
MailHandler: MailHandler, MailHandler: MailHandler,
}
};
}); });

3
muk_web_preview_mail/tests/__init__.py

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
################################################################################### ###################################################################################
# #
# Copyright (C) 2017 MuK IT GmbH # Copyright (C) 2017 MuK IT GmbH
@ -20,4 +18,3 @@
################################################################################### ###################################################################################
from . import test_mail_parse from . import test_mail_parse

12
muk_web_preview_mail/tests/test_mail_parse.py

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
################################################################################### ###################################################################################
# #
# Copyright (C) 2017 MuK IT GmbH # Copyright (C) 2017 MuK IT GmbH
@ -20,21 +18,15 @@
################################################################################### ###################################################################################
import os import os
import base64
import logging import logging
import unittest
from urllib.parse import urlunparse from urllib.parse import urlunparse
from urllib.parse import urlparse from urllib.parse import urlparse
from urllib.parse import parse_qsl from urllib.parse import parse_qsl
from urllib.parse import urlencode from urllib.parse import urlencode
from contextlib import closing
from odoo import _
from odoo.tests import common from odoo.tests import common
from odoo.addons.muk_web_preview_mail.controllers import main
_path = os.path.dirname(os.path.dirname(__file__)) _path = os.path.dirname(os.path.dirname(__file__))
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -53,9 +45,7 @@ class MailParseTestCase(common.HttpCase):
def test_parse_mail(self): def test_parse_mail(self):
self.authenticate('admin', 'admin') self.authenticate('admin', 'admin')
url = "/web/preview/converter/mail" url = "/web/preview/converter/mail"
params = {'url': "/web/content?id={}".format(
self.sample_mail_attachment.id
)}
params = {'url': "/web/content?id={}".format(self.sample_mail_attachment.id)}
url_parts = list(urlparse(url)) url_parts = list(urlparse(url))
query = dict(parse_qsl(url_parts[4])) query = dict(parse_qsl(url_parts[4]))
query.update(params) query.update(params)

Loading…
Cancel
Save