-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathTextUtils.py
148 lines (122 loc) · 5.33 KB
/
TextUtils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
"""This module provides static methods to create ascii, csv, and html attachment and send email to specified group of people. """
import time
import sys
import datetime
from io import StringIO
import smtplib
from email.message import EmailMessage
import tabulate
import pandas as pd
from email.utils import formataddr
from . import NiceNum
##########################################
# This code is partially taken from #
# AccountingReports.py #
##########################################
class TextUtils:
"""Formats the text to create ascii, csv, and html attachment and send email to specified group of people. """
def __init__(self, table_header):
"""Args:
table_header(list of str) - the header row for the output table
"""
self.table_header = table_header
def getWidth(self, l):
"""Returns max length of string in the list - needed for text formating of the table
l(list of str)
"""
return max(len(repr(s)) for s in l)
def getLength(self, text):
"""Returns number of rows in the table
Args:
text(list)
"""
return len(text[self.table_header[0]])
def printAsTextTable(self, format_type, text, template=False):
""""Prepares input text to send as attachment
Args:
format_type(str) - text, csv, html
text (dict of lists) - {column_name:[values],column_name:[values]} where column_name corresponds to header name
or pandas dataframe
"""
if not isinstance(text, pd.DataFrame):
# Convert list of dicts to pandas data frame
df = pd.DataFrame.from_dict(text, orient='index').transpose()
# Order the columns according to the header
df = df[self.table_header]
else:
df = text
# TODO: Remove this alignment code when python-tabulate recognizes
# numbers with comma separators.
alignment_list = ["left"] * (len(self.table_header) - 1)
alignment_list.append("right")
# the order is defined by header list
if format_type == "text":
return tabulate.tabulate(df, tablefmt="grid", headers=self.table_header,
showindex=False, floatfmt=',.0f', colalign=alignment_list)
elif format_type == "html":
return tabulate.tabulate(df, tablefmt="html", headers=self.table_header,
showindex=False, floatfmt=',.0f', colalign=alignment_list)
elif format_type == "csv":
return df.to_csv(index=False)
def sendEmail(toList, subject, content, fromEmail=None, smtpServerHost=None, html_template=False):
"""
This turns the "report" into an email attachment and sends it to the EmailTarget(s).
Args:
toList(list of str) - list of emails addresses
content(str) - email content
fromEmail (str) - from email address
smtpServerHost(str) - smtpHost
"""
#Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8')
if toList[1] is None:
print("Cannot send mail (no To: specified)!", file=sys.stderr)
sys.exit(1)
msg = EmailMessage()
msg["Subject"] = subject
msg["From"] = formataddr(fromEmail)
msg["To"] = _toStr(toList)
# new code
if "text" in content:
msg.set_content(content["text"], 'plain')
msg.add_alternative("<pre>" + content["text"] + "</pre>", subtype="html")
elif "html" in content and "text" not in content:
msg.add_alternative(content["html"], subtype="html")
if html_template:
attachment_html = content["html"]
else:
attachment_html = "<html><head><title>%s</title></head><body>%s</body>" \
"</html>" % (subject, content["html"])
msg.add_attachment(attachment_html, filename="report_{}.html".format(datetime.datetime.now().strftime('%Y_%m_%d')))
if "csv" in content:
msg.add_attachment(content["csv"], filename="report_{}.csv".format(datetime.datetime.now().strftime('%Y_%m_%d')))
msg = msg.as_string()
if len(toList[1]) != 0:
server = smtplib.SMTP(smtpServerHost)
server.sendmail(fromEmail[1], toList[1], msg)
server.quit()
else:
# The email list isn't valid, so we write it to stderr and hope
# it reaches somebody who cares.
print("Problem in sending email to: ", toList, file=sys.stderr)
def _toStr(toList):
"""Formats outgoing address list
Args:
toList(list of str) - email addresses
"""
names = [formataddr(i) for i in zip(*toList)]
return ', '.join(names)
if __name__ == "__main__":
text = {}
title = ["Time", "Hours", "AAAAAAAAAAAAAAA"]
a = TextUtils(title)
content = {"Time": ["aaa", "ccc", "bbb", "Total"],
"Hours": [10000, 30, 300000, "", ],
"AAAAAAAAAAAAAAA": ["", "", "", 10000000000]}
text["text"] = a.printAsTextTable("text", content)
text["csv"] = a.printAsTextTable("csv", content)
text["html"] = a.printAsTextTable("html", content)
text[
"html"] = "<html><body><h2>%s</h2><table border=1>%s</table></body></html>" % (
"aaaaa", a.printAsTextTable("html", content),)
sendEmail((["Tanya Levshina", ], ["[email protected]", ]), "balalala",
text, ("Gratia Operation", "[email protected]"), "smtp.fnal.gov")