I am using this script to create pdf file and append images with statistics:
import MySQLdb
from plotly import graph_objs as go
import numpy as np
import os
from plotly.subplots import make_subplots
from PyPDF2 import PdfFileMerger
from datetime import datetime, timedelta
import smtplib
from email.message import EmailMessage
import imghdr
# Database connect
db = MySQLdb.connect(host="localhost",
user="root",
passwd="****",
db="ofasorgu_10_168_1_71")
today = datetime.today().strftime('%Y-%m-%d')
one_week = (datetime.today() - timedelta(days=7)).strftime('%Y-%m-%d')
two_week = (datetime.today() - timedelta(days=14)).strftime('%Y-%m-%d')
three_week = (datetime.today() - timedelta(days=21)).strftime('%Y-%m-%d')
four_week = (datetime.today() - timedelta(days=28)).strftime('%Y-%m-%d')
# Functions
def load_post_views(table, today, one_week, two_week, three_week, four_week):
product_views_dict = dict()
cursor = db.cursor()
cursor.execute(
"SELECT client_id, product_id, referrer, `date`" +
" FROM " + table +
" WHERE `date`>='"+four_week+"'")
for x in range(0, cursor.rowcount):
row = cursor.fetchone()
network = ""
period = ""
client_id = row[0]
product_id = row[1]
referrer = row[2]
date = str(row[3])
email_cursor = db.cursor()
email_cursor.execute("SELECT address FROM c8ty_connections_email WHERE entry_id=" + str(client_id))
email = email_cursor.fetchone()
product_cursor = db.cursor()
product_cursor.execute("SELECT post_title FROM c8ty_posts WHERE id=" + str(product_id))
product_name = product_cursor.fetchone()
# Add client ID key
if client_id not in product_views_dict:
product_views_dict[client_id] = dict()
# Add product ID key to client ID parent key
if product_id not in product_views_dict[client_id]:
product_views_dict[client_id][product_id] = {
today + " - " + one_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
},
one_week + " - " + two_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
},
two_week + " - " + three_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
},
three_week + " - " + four_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
}
}
# Find referrer
if "facebook" in referrer:
network = "facebook"
elif "twitter" in referrer:
network = "twitter"
elif "instagram" in referrer:
network = "instagram"
elif "linkedin" in referrer:
network = "linkedin"
elif "pinterest" in referrer:
network = "pinterest"
else:
network = "website"
# Check view period
if date <= today and date > one_week:
period = today + " - " + one_week
if date <= one_week and date > two_week:
period = one_week + " - " + two_week
if date <= two_week and date > three_week:
period = two_week + " - " + three_week
if date <= three_week and date > four_week:
period = three_week + " - " + four_week
product_views_dict[client_id][product_id][period][network] += 1
product_views_dict[client_id]["email"] = email[0]
product_views_dict[client_id][product_id]["product"] = product_name[0]
return product_views_dict
def draw_statistic(data_dict):
for clinetID, product_info in data_dict.items():
client_email = product_info["email"]
for productID, product_data in product_info.items():
if type(product_data) is dict:
product_name = product_data['product']
table_data = [
[
today + " - " + one_week,
one_week + " - " + two_week,
two_week + " - " + three_week,
three_week + " - " + four_week,
today + " - " + four_week
]
]
total_one = []
total_two = []
total_three = []
total_four = []
overall_traces = []
networks_and_positions = [
{"network": "website","row": 2,"col": 1},
{"network": "linkedin","row": 2,"col": 2},
{"network": "facebook","row": 3,"col": 1},
{"network": "twitter","row": 3,"col": 2},
{"network": "instagram","row": 4,"col": 1},
{"network": "pinterest","row": 4,"col": 2}
]
fig = make_subplots(rows=5, cols=2)
merge_fig = make_subplots(rows=1, cols=1)
count = 2
for dictionary in networks_and_positions:
network = dictionary['network']
row = dictionary['row']
col = dictionary['col']
total_one.append(product_data[today + " - " + one_week][network])
total_two.append(product_data[one_week + " - " + two_week][network])
total_three.append(product_data[two_week + " - " + three_week][network])
total_four.append(product_data[three_week + " - " + four_week][network])
table_data.append([
product_data[today + " - " + one_week][network],
product_data[one_week + " - " + two_week][network],
product_data[two_week + " - " + three_week][network],
product_data[three_week + " - " + four_week][network],
sum([
product_data[today + " - " + one_week][network],
product_data[one_week + " - " + two_week][network],
product_data[two_week + " - " + three_week][network],
product_data[three_week + " - " + four_week][network]
])
])
xaxis = [
today + " - " + one_week,
one_week + " - " + two_week,
two_week + " - " + three_week,
three_week + " - " + four_week,
]
yaxis = [
product_data[today + " - " + one_week][network],
product_data[one_week + " - " + two_week][network],
product_data[two_week + " - " + three_week][network],
product_data[three_week + " - " + four_week][network]
]
chart_name = network.capitalize() + " statistic"
# Create bar chart
if (count == 2):
social_fig = go.Bar(
x=xaxis,
y=yaxis,
name=chart_name
)
else:
social_fig = go.Bar(
x=xaxis,
y=yaxis,
name=chart_name,
yaxis="y"+str(count)
)
# Add chart to fig
fig.add_trace(
social_fig,
row=row,
col=col
)
count += 1
trace_name = network.capitalize() + " views"
overall_traces.append(
go.Scatter(
x=xaxis,
y=yaxis,
name=trace_name
)
)
total_column_values_array = [sum(total_one), sum(total_two), sum(total_three), sum(total_four),]
total_column_values_array.append(
sum(total_one)+sum(total_two)+sum(total_three)+sum(total_four)
)
table_data.append(total_column_values_array)
# Create product table
fig.add_trace(
go.Table(
header=dict(values=["Period", "Website", "Facebook", "Twitter", "Instagram", "LinkedIn", "Pinterest", "Total"]),
cells=dict(values=table_data)
)
)
merge_fig.add_traces(overall_traces)
# Craete folder if doesn't exist
if not os.path.exists("files"):
os.mkdir("files")
statistic_file = "files/statistic_"+product_name+".pdf"
overall_file = "files/overall_"+product_name+".pdf"
out_file = "files/"+product_name+"_statistic.pdf"
# Create charts file
fig.update_layout(height=1500, width=1000, title_text="<b>Greetings</b><br />This is statistic from <a href='https://www.cfasuk.co.uk/'>CFAS UK</a> for your product <b>"+product_name+"</b>")
fig.update_layout(
yaxis3=dict(title="Website views", titlefont=dict(color="#636efa")),
yaxis4=dict(title="LinkedIn views", titlefont=dict(color="#ef553b")),
yaxis5=dict(title="Facebook views", titlefont=dict(color="#00cc96")),
yaxis6=dict(title="Twitter views", titlefont=dict(color="#b780f9")),
yaxis7=dict(title="Instagram views", titlefont=dict(color="#ffa15a")),
yaxis8=dict(title="Pinterest views", titlefont=dict(color="#19d3f3")),
)
fig.write_image(statistic_file)
# Create overall file
merge_fig.update_layout(height=700, width=1000, title_text="Overall <b>"+product_name+"</b> statistic")
merge_fig.write_image(overall_file)
merge = PdfFileMerger(strict=False)
# Append charts file to merger
merge.append(statistic_file)
# Append overall file to merger
merge.append(overall_file)
# Create end statistic file with both charts and overall
merge.write(out_file)
merge.close()
# Delete statistic file
os.remove(statistic_file)
# Delete overall file
os.remove(overall_file)
# Send email with file
send_mail(
"tomaivanovtomov@gmail.com",
"tomaivanovtomov@gmail.com",
"CFAS UK, "+product_name+" statistic",
"This is automated email. Please, do not reply!<br/>"+
"If you find some problem with the statistic or the product is not yours, please contact CFAS UK team.<br/>"+
"Best regards!",
out_file
)
def send_mail(send_from, send_to, subject, text, file=None):
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login("tomaivanovtomov@gmail.com", "zmjquvphuvigqdai")
msg = EmailMessage()
msg['Subject'] = subject
msg['From'] = send_from
msg['To'] = send_to
msg.set_content(text)
with open(file, "rb") as f:
file_data = f.read()
file_name = f.name
msg.add_attachment(file_data, maintype='application/pdf', subtype='pdf', filename=file_name)
smtp.send_message(msg)
# Init
product_views_dict = load_post_views("an_product_view", today, one_week, two_week, three_week, four_week)
brochure_views_dict = load_post_views("an_brochure_view", today, one_week, two_week, three_week, four_week)
draw_statistic(product_views_dict)
draw_statistic(brochure_views_dict)
db.close()
exit()
It works fine when I test it on my local server. But I need to upload it to shared account on a Centos server. On my hosting provider. There I can't install anaconda
which I need to install orca
for static images. Is there an alternative to create images and then add it to pdf file? Thank you in advance!
Yes (you do not need to use any tool backend dependency in your code), there's a very easy alternative library example as shown below.
you can use matplotlib integration for this.
you can import these modules as shown below
from plotly.offline import init_notebook_mode, plot_mpl
import matplotlib.pyplot as plt
and you can use them as below:
init_notebook_mode()
fig = plt.figure()
# you can configure you plot here use below to save it as image
plot_mpl(fig)
plot_mpl(fig, image='png')
OR if you want to still stick to only plotly and find alternative, you can see beow
you can use a offline module of plotly to generate static images on the server and use it to generate a PDF. you can import it using from plotly.offline import plot
. Once you've imported then you use the plot function as below
fig = go.Figure( data=data, layout=layout )
plot( fig, filename='your-file-name' , image = 'png')