Skip to content

Commit

Permalink
[ADD] mail_attach_image: Allows you to attach an image in the email f…
Browse files Browse the repository at this point in the history
…rom base64 code
  • Loading branch information
ysantiago authored and moylop260 committed Jun 1, 2016
1 parent f72b722 commit ad71761
Show file tree
Hide file tree
Showing 9 changed files with 260 additions and 0 deletions.
48 changes: 48 additions & 0 deletions mail_attach_image/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License: AGPL-3

=========================
Attach Image Email
=========================

This application allows you to attach an image in the email from base64 code.

Requirements
------------

You need add in email template the image base64 code, as follow:

``<img src"data:image/png;base64,codeBase64"/>``

Result
------

An email with the image attach:

.. image:: ./static/description/email.png
:align: center


Contributors
------------
* Ivan Yelizariev <@yelizariev>
* Moises López <moylop260@vauxoo.com>
* Yennifer Santiago <yennifer@vauxoo.com>
* Vauxoo <info@vauxoo.com>

Maintainer
----------

.. image:: https://www.vauxoo.com/logo.png
:alt: Vauxoo
:target: https://vauxoo.com

This module is maintained by Vauxoo.

A latinamerican company that provides training, coaching,
development and implementation of enterprise management
sytems and bases its entire operation strategy in the use
of Open Source Software and its main product is odoo.

To contribute to this module, please visit http://www.vauxoo.com.

10 changes: 10 additions & 0 deletions mail_attach_image/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# coding: utf-8
# © 2016 Vauxoo - http://www.vauxoo.com
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# info Vauxoo (info@vauxoo.com)
# contributor: Ivan Yelizariev @yelizariev
# coded by: yennifer@vauxoo.com
# planned by: moylop260@vauxoo.com

from . import models
from . import tests
21 changes: 21 additions & 0 deletions mail_attach_image/__openerp__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# © 2016 Vauxoo - http://www.vauxoo.com
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# info Vauxoo (info@vauxoo.com)
# contributor: Ivan Yelizariev @yelizariev
# coded by: yennifer@vauxoo.com
# planned by: moylop260@vauxoo.com

{
'name': 'Attach image in email',
'version': '8.0.1.0.0',
'author': 'Vauxoo',
'category': 'Addons Vauxoo',
'website': 'https://www.vauxoo.com',
'license': 'AGPL-3',
'depends': [
'base',
],
'installable': True,
'auto_install': False,
}
9 changes: 9 additions & 0 deletions mail_attach_image/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# © 2016 Vauxoo - http://www.vauxoo.com
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# info Vauxoo (info@vauxoo.com)
# contributor: Ivan Yelizariev @yelizariev
# coded by: yennifer@vauxoo.com
# planned by: moylop260@vauxoo.com

from . import ir_mail_server
80 changes: 80 additions & 0 deletions mail_attach_image/models/ir_mail_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
# © 2016 Vauxoo - http://www.vauxoo.com
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# info Vauxoo (info@vauxoo.com)
# contributor: Ivan Yelizariev @yelizariev
# coded by: yennifer@vauxoo.com
# planned by: moylop260@vauxoo.com

from email.mime.base import MIMEBase
from email import Encoders
from openerp.addons.base.ir.ir_mail_server import encode_header_param
import base64
import re

from openerp import models


class IrMailServer(models.Model):
_inherit = 'ir.mail_server'

def get_images(self, body):
"""Extract of boby template the code base64 image.
:params string body: email body.
:returns string new_body: new email body with attach image.
:returns: list custom_attachments: list of image in code base64"""
ftemplate = '__image-%s__'
fcounter = 0
custom_attachments = []

pattern = re.compile(r'"data:image/png;base64,[^"]*"')
pos = 0
new_body = ''
while True:
match = pattern.search(body, pos)
if not match:
break
start = match.start()
end = match.end()
data = body[start + len('"data:image/png;base64,'):end-1]
new_body += body[pos:start]

fname = ftemplate % fcounter
fcounter += 1
custom_attachments.append((fname, base64.b64decode(data)))

new_body += '"cid:%s"' % fname
pos = end

new_body += body[pos:]
return new_body, custom_attachments

def image2attach(self, msg, image_attachments=None):
"""Attach the image in email
:params msg: email.mime.multipart.MIMEMultipart.
:params list image_attachments: list of image in code base64.
"""
if image_attachments is None:
image_attachments = []
for (fname, fcontent) in image_attachments:
filename_rfc2047 = encode_header_param(fname)
part = MIMEBase('application', "octet-stream")
part.add_header('Content-ID', '<%s>' % filename_rfc2047)
part.set_payload(fcontent)
Encoders.encode_base64(part)
msg.attach(part)

def build_email(self, email_from, email_to, subject, body, email_cc=None,
email_bcc=None, reply_to=False, attachments=None,
message_id=None, references=None, object_id=False,
subtype='plain', headers=None, body_alternative=None,
subtype_alternative='plain'):
new_body, image_attachments = self.get_images(body)
msg = super(IrMailServer, self).build_email(
email_from, email_to, subject, new_body, email_cc, email_bcc,
reply_to, attachments, message_id, references, object_id, subtype,
headers, body_alternative, subtype_alternative)
self.image2attach(msg, image_attachments)
return msg
Binary file added mail_attach_image/static/description/email.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions mail_attach_image/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# coding: utf-8
# © 2016 Vauxoo - http://www.vauxoo.com
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# info Vauxoo (info@vauxoo.com)
# contributor: Ivan Yelizariev @yelizariev
# coded by: yennifer@vauxoo.com
# planned by: moylop260@vauxoo.com

from . import test_attach_image
32 changes: 32 additions & 0 deletions mail_attach_image/tests/template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<table border="0" cellpadding="2" cellspacing="2" align="center" width="400">
<tbody>
<tr>
<td valign="top">
<div style="font-family: 'Lucida Grande', Ubuntu, Arial,
Verdana, sans-serif; font-size: 12px; color: rgb(34, 34,
34); background-color: rgb(255, 255, 255); ">
<div class="moz-text-html" lang="x-unicode">
<table border="0" cellpadding="2" cellspacing="2" width="100%">
<tbody>
<tr>
<td valign="top">
<img src="data:image/png;base64,{image_base64}"
height="100" width="250">
</td>
</tr>
</tbody>
</table>
<div style="font-family: &quot;Lucida
Grande&quot;,Ubuntu,Arial,Verdana,sans-serif;
font-size: 15px; color: #8F41A2;
background-color: rgb(255, 255, 255);" align="left"><strong style="color: #8F41A2; font-size: 16px">
<big><b>Hello, this is a test template</b></big></strong><br>
</div>
</div>
</div>
</td>
<td valign="top"><br>
</td>
</tr>
</tbody>
</table>
51 changes: 51 additions & 0 deletions mail_attach_image/tests/test_attach_image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
# © 2016 Vauxoo - http://www.vauxoo.com
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# info Vauxoo (info@vauxoo.com)
# contributor: Ivan Yelizariev @yelizariev
# coded by: yennifer@vauxoo.com
# planned by: moylop260@vauxoo.com

import base64
import os

from lxml import html

from openerp.tests import common


class TestAttachImageEmail(common.TransactionCase):
# Pseudo-constructor method of the setUp test.
def setUp(self):
# Define global variables to test methods.
super(TestAttachImageEmail, self).setUp()

self.mail_server = self.env['ir.mail_server'].create({
'name': 'Test',
'smtp_host': 'smtp.gmail.com',
})
self.logo_b64 = self.env.user.company_id.logo.strip('\n')
curr_dir = os.path.dirname(os.path.realpath(__file__))
self.template_html = open(
os.path.join(curr_dir, "template.html")).read()

# Test methods
def test_10_create_attach_image(self):
"""Test verifies that the image was attached properly by comparing
the last attachment in a message with the code of the image on the
html template.
"""
email_from = 'partner1@example.com'
email_to = 'partner2@example.com'
subject = 'Test attach image'
body = self.template_html.format(image_base64=self.logo_b64)
msg = self.mail_server.build_email(email_from, email_to, subject, body)

image_attach = msg._payload[-1]
self.assertEquals(
image_attach.get_payload().strip('\n'), self.logo_b64)

email_html_str = base64.decodestring(msg._payload[0].get_payload())
content = html.document_fromstring(email_html_str)
image = content.xpath('//table/tbody//img')[0]
self.assertEquals(image.attrib['src'], 'cid:__image-0__')

0 comments on commit ad71761

Please sign in to comment.