docker_project / app.py
Codingacademey
Add Flask app with Dockerfile
b0ae909
Raw
History Blame Contribute Delete
5.07 kB
from flask import Flask, render_template, request, redirect, url_for, send_file, flash
import io
import base64
import matplotlib.pyplot as plt
import preprocessor, helper
import pandas as pd
app = Flask(__name__)
app.secret_key = "change-this-secret"
def figure_to_png_base64(fig):
buf = io.BytesIO()
fig.savefig(buf, format='png', bbox_inches='tight')
plt.close(fig)
buf.seek(0)
return base64.b64encode(buf.read()).decode('utf-8')
@app.route('/', methods=['GET'])
def index():
return render_template('index.html')
@app.route('/analyze', methods=['POST'])
def analyze():
file = request.files.get('chat_file')
if not file or file.filename == '':
flash('Please upload a WhatsApp chat .txt file')
return redirect(url_for('index'))
try:
data = file.read().decode('utf-8')
except Exception:
file.stream.seek(0)
data = file.read().decode('latin-1', errors='ignore')
df = preprocessor.preprocess(data)
users = df['user'].unique().tolist()
if 'group_notification' in users:
users.remove('group_notification')
users.sort()
users.insert(0, 'overall')
selected_user = request.form.get('user') or 'overall'
if selected_user not in users:
selected_user = 'overall'
num_messages, num_words, num_media_messages = helper.fetch_stats(selected_user, df)
charts = {}
if selected_user == 'overall':
x, new_df = helper.most_busy_user(df)
fig, ax = plt.subplots()
ax.bar(x.index, x.values, color=['#ef4444','#10b981','#3b82f6','#f59e0b','#8b5cf6'])
plt.xticks(rotation=45, ha='right')
charts['busy_users'] = figure_to_png_base64(fig)
busy_table = new_df.to_html(classes='table table-striped table-sm', index=False)
else:
busy_table = None
wc_image = helper.create_wordcloud(selected_user, df)
wc_b64 = None
if wc_image is not None:
fig_wc, ax_wc = plt.subplots(figsize=(10, 5))
ax_wc.imshow(wc_image, interpolation='bilinear')
ax_wc.axis('off')
wc_b64 = figure_to_png_base64(fig_wc)
most_common_df = helper.most_common_words(selected_user, df)
common_b64 = None
if not most_common_df.empty:
fig_mc, ax_mc = plt.subplots()
ax_mc.barh(most_common_df[0], most_common_df[1])
plt.xticks(rotation=45)
common_b64 = figure_to_png_base64(fig_mc)
emojis_df = helper.emoji_helper(selected_user, df)
emoji_table = emojis_df.to_html(classes='table table-striped table-sm', index=False)
emoji_pie_b64 = None
if not emojis_df.empty:
top_emojis = emojis_df.head(4)
fig_em, ax_em = plt.subplots()
ax_em.pie(top_emojis[1], labels=top_emojis[0], autopct='%0.2f%%')
emoji_pie_b64 = figure_to_png_base64(fig_em)
timeline = helper.monthly_timeline(selected_user, df)
timeline_b64 = None
if not timeline.empty:
fig_tl, ax_tl = plt.subplots()
ax_tl.plot(timeline['time'], timeline['message'], color='#10b981')
plt.xticks(rotation=45, ha='right')
timeline_b64 = figure_to_png_base64(fig_tl)
deltas, rstats = helper.response_time_stats(selected_user, df)
resp_hist_b64 = None
if rstats['count'] > 0:
fig_rt, ax_rt = plt.subplots()
ax_rt.hist(deltas, bins=30, color='#93c5fd', edgecolor='#1f2937')
ax_rt.set_xlabel('Reply time (minutes)')
ax_rt.set_ylabel('Frequency')
ax_rt.set_title('Reply Time Distribution')
resp_hist_b64 = figure_to_png_base64(fig_rt)
request.environ['analysis_df'] = df
request.environ['analysis_selected_user'] = selected_user
return render_template(
'results.html',
users=users,
selected_user=selected_user,
stats={
'messages': num_messages,
'words': num_words,
'media': num_media_messages
},
busy_chart=charts.get('busy_users'),
busy_table=busy_table,
wc_b64=wc_b64,
common_b64=common_b64,
emoji_table=emoji_table,
emoji_pie_b64=emoji_pie_b64,
timeline_b64=timeline_b64,
resp_hist_b64=resp_hist_b64
)
@app.route('/download', methods=['POST'])
def download():
file = request.files.get('chat_file')
selected_user = request.form.get('user') or 'overall'
if not file or file.filename == '':
flash('Please upload a chat file to generate report')
return redirect(url_for('index'))
try:
data = file.read().decode('utf-8')
except Exception:
file.stream.seek(0)
data = file.read().decode('latin-1', errors='ignore')
df = preprocessor.preprocess(data)
pdf_buffer = helper.generate_pdf_report(selected_user, df)
return send_file(
pdf_buffer,
as_attachment=True,
download_name=f"whatsapp_analysis_{'overall' if selected_user=='overall' else selected_user}.pdf",
mimetype='application/pdf'
)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860, debug=False)