Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

stdout format changing when sending a file using smtplib - python2.7

Python2.7 output format not getting as expected if body of email read from a file. user_info.txt is a file generated by another job which contains all the details of users. The output format of user_info.txt is nice. Where as sending that file as an email, output format changes completely. does am I doing something wrong when reading from the file? Can some body help me on this please?

script:

#!/usr/bin/env python
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

msg = MIMEMultipart('alternative')
msg['Subject'] = "User Info"

"""Create the body of the message"""
open_file = open('/tmp/user_info.txt')
user_info = MIMEText(open_file.read().encode("utf-8"), 'plain', 'utf-8')
msg.attach(user_info)
open_file.close()

"""Send the message via gmail SMTP server."""
server = smtplib.SMTP('smtp-relay.gmail.com', 587)
server.sendmail("admin", "[email protected]", msg.as_string())
server.quit()

sample user_info.txt

user_name  Department_no ID          detail1     detail2 


aaaa          4         13           25088       32.000000

bbbbbbb       5         17           33280       42.000000

ccccccccccc   3          9           16896       22.000000

dddddd        5         17           33280       42.000000

eeeeeeeee     5         14           27136       36.000000

Email output:

user_name Department_no ID detail1 detail2

aaaa 4 13 25088 32.000000

bbbbbbb 5 17 33280 42.000000

ccccccccccc 3 9 16896 22.000000

dddddd 5 17 33280 42.000000

eeeeeeeee 5 14 27136 36.000000

Please check the email screenshot:

email

like image 625
user6136315 Avatar asked Apr 27 '17 23:04

user6136315


2 Answers

When sending email in MIMEText(... 'plain') format you don't have control over exactly how it is displayed by the reciever's mail client. Some will use variable width fonts, collapse whitespace, wrap lines in odd places - generally make your pretty fixed width table ugly.

One option is to send an html message body with the plain text as fallback.

...
msg = MIMEMultipart('alternative')
...
with open('/tmp/user_info.txt') as f:
    raw_text = f.read()

msg.attach(MIMEText(raw_text, 'plain'))
msg.attach(MIMEText(convert_to_html(raw_text), 'html'))

That leaves the question of how to implement that convert_to_html() function. I can see two reasonable options:

  • Just wrap in the basic <html>/<body> tags and a <pre>.
  • Actually parse back your plain text table into cells and make an html table.

If you have the data from before creating the text file, you might find it easier to make the table straight from that.

Either way, basic mail clients should fall back to the plain text version and fancy ones that insist on messing with layout will get the html version that specifies you want your message in table form.

like image 149
gz. Avatar answered Sep 29 '22 12:09

gz.


Question ... output format changes completely. does am I doing something wrong when reading from the file

Tested with Python:3.4.2 and 2.7.9, your code and given user_info.txt format with no failure.
Could receive user_info.txt in the same format.
So, you are doing nothing wrong.


Try the following, without sending your eMail, to verify your used email.mime module work as expected. The output should be OK.

result = user_info.get_payload(decode=True).decode('utf-8','ignore')
print(result)

In general there is no guarantee that a receiver of a eMail uses the same font, size or the same environment.

If you want to be sure, data layout looks the same use a Portabel Document Format.

like image 26
stovfl Avatar answered Sep 29 '22 13:09

stovfl