Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Same behaviour in py2 and py3
  • Loading branch information
ecarreras committed Jul 30, 2025
commit 8c6d76ff5beffb681cb22596f19c645e33b38617
35 changes: 17 additions & 18 deletions qreu/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,40 +363,39 @@ def add_attachment(self, input_buff, attname=False):
:return: True if Added, Exception if failed
:rtype: bool
"""
from os.path import basename
import base64
import mimetypes
from email.mime.application import MIMEApplication

try:
# Try to get name from input if not provided
filename = attname or input_buff.name
except AttributeError:
raise ValueError('Name of the attachment not provided')
from os.path import basename
import base64

# Read bytes from buffer
content = input_buff.getvalue() if isinstance(input_buff, (StringIO, BytesIO)) else input_buff.read()
if six.PY2:
attachment_str = base64.encodestring(content)
else:
# TODO Revisar
attachment_str = content.decode('utf-8')
if isinstance(content, six.text_type): # Python 2
content = content.encode('utf-8')

# Base64 encode
attachment_str = base64.b64encode(content).decode('ascii')

# Guess MIME type
filetype = mimetypes.guess_type(filename)[0]
subtype = 'octet-stream'
maintype, subtype = 'application', 'octet-stream'
if filetype:
splitedfiletype = filetype.split('/')[-1]
subtype = splitedfiletype
attachment = MIMEApplication('', _subtype=subtype)
maintype, subtype = filetype.split('/')

attachment.set_charset('utf-8')
# Create MIME part
attachment = MIMEApplication('', _subtype=subtype)
attachment.add_header(
'Content-Disposition',
'attachment; filename="%s"' % self.remove_accent(u'{}'.format(basename(filename)))
)
attachment.add_header('Content-Transfer-Encoding', 'base64')
attachment.set_payload(
attachment_str,
charset=attachment.get_charset()
)
attachment.set_payload(attachment_str)

self.email.attach(attachment)
return True

Expand Down Expand Up @@ -542,7 +541,7 @@ def attachments(self):
yield {
'type': part.get_content_type(),
'name': filename,
'content': part.get_payload()
'content': part.get_payload(decode=True)
}

@property
Expand Down
17 changes: 2 additions & 15 deletions spec/qreu_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,16 +288,9 @@ def call_wrongly_html():
expect(files).to(equal([f_name, f_name]))
for attachment in e.attachments:
filename = attachment['name']
filecontent = attachment['content']
filecontent = attachment['content'].decode('utf-8')
with open(f_path, 'rb') as f:
# attachment_str = base64.encodestring(f.read())
attachment_str = f.read().decode('utf-8')
# try:
# attachment_str = str(attachment_str, 'utf-8')
# except TypeError as e:
# print(e)
# # Python 2.7 compat
# attachment_str = unicode(attachment_str)
expect(filecontent).to(equal(attachment_str))

with it('must add an iostring as attachment to body'):
Expand All @@ -311,16 +304,10 @@ def call_wrongly_html():

input_iostr = BytesIO(f_data)
check_str = f_data.decode('utf-8')
# check_str = base64.encodestring(f_data)
# try:
# check_str = str(check_str, 'utf-8')
# except TypeError:
# # Python 2.7 compat
# check_str = unicode(check_str)
e.add_attachment(input_buff=input_iostr, attname=f_name)
for attachment in e.attachments:
filename = attachment['name']
filecontent = attachment['content']
filecontent = attachment['content'].decode('utf-8')
expect(filecontent).to(equal(check_str))

with it('must raise an exception adding an unexisting attachment'):
Expand Down