From 60fda1c957b1eabab4874c885b1f9e5d1aae05d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20K=C3=B3nya?= Date: Sat, 26 Nov 2022 22:02:18 +0100 Subject: [PATCH] first finalized images --- chatanalyzer/__main__.py | 4 ++- chatanalyzer/analyzing.py | 27 +++++++++------- chatanalyzer/make_final.py | 63 +++++++++++++++++++++++++++++++++++++ chatanalyzer/participant.py | 4 ++- 4 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 chatanalyzer/make_final.py diff --git a/chatanalyzer/__main__.py b/chatanalyzer/__main__.py index 46e4466..5456c57 100644 --- a/chatanalyzer/__main__.py +++ b/chatanalyzer/__main__.py @@ -6,6 +6,7 @@ from datetime import datetime from participant import Participant import ftfy import analyzing +import make_final def read_json(filename): @@ -22,7 +23,7 @@ def main(): participant_count = len(chat_data["participants"]) for i in range(participant_count): - participants.append(Participant(chat_data["participants"][i]["name"])) + participants.append(Participant(chat_data["participants"][i]["name"], chat_data["title"], chat_data["thread_type"])) for f in file_list: chat_data = read_json(f) @@ -46,6 +47,7 @@ def main(): analyzing.make_wordcloud(WORDS_IN_CHAT) analyzing.make_timeline(participants) + make_final.assemble_image(participants) if __name__ == "__main__": diff --git a/chatanalyzer/analyzing.py b/chatanalyzer/analyzing.py index 144ffff..845ee33 100644 --- a/chatanalyzer/analyzing.py +++ b/chatanalyzer/analyzing.py @@ -8,6 +8,10 @@ import pandas as pd import plotly.express as px +# For some reason PIL doesn't work with relative path so I have to use absolute paths +RESOURCE_LOCATION = f"{path.abspath('Resources')}" + + def incidents_of_words(words): word_set = set(words) @@ -51,11 +55,9 @@ def create_dataframe(participants): def make_wordcloud(WORDS_IN_CHAT): - # For some reason PIL doesn't work with relative path so I have to use absolute paths - resource_location = f"{path.abspath('Resources')}" - img_mask = np.array(Image.open(f"{resource_location}/mask.png")) + img_mask = np.array(Image.open(f"{RESOURCE_LOCATION}/mask.png")) wordcloud = WordCloud(width = 2000, height = 2000, - background_color = "white", + background_color = None, mode="RGBA", prefer_horizontal=1, mask = img_mask, @@ -72,24 +74,27 @@ def make_wordcloud(WORDS_IN_CHAT): plt.axis("off") plt.tight_layout(pad = 0) - wordcloud.to_file(f"{resource_location}/wordcloud.png") + wordcloud.to_file(f"{RESOURCE_LOCATION}/wordcloud.png") def make_timeline(participants): df = create_dataframe(participants) fig = px.line(df, x="month", y="counts", color="sender") - fig.update_layout({ "showlegend": True, + fig.update_layout({ "showlegend": False, "title": {"text": "Timeline of Messages", "xanchor": "center", - "x": 0.5}, + "x": 0.5, + "font": {"color": "white"}}, "xaxis": {"showgrid": False, - "title": ""}, - "yaxis": {"gridcolor": "white", + "title": "", + "color": "white"}, + "yaxis": {"color": "white", "nticks": 2, - "title": ""}, + "title": "", + "color": "white"}, "paper_bgcolor": 'rgba(0,0,0,0)', "plot_bgcolor": 'rgba(0,0,0,0)' }) - fig.write_image("by-month.png",format="png", width=1500, height=600, scale=3) + fig.write_image(f"{RESOURCE_LOCATION}/timeline.png",format="png", width=1500, height=600, scale=3) diff --git a/chatanalyzer/make_final.py b/chatanalyzer/make_final.py new file mode 100644 index 0000000..1c11164 --- /dev/null +++ b/chatanalyzer/make_final.py @@ -0,0 +1,63 @@ +from PIL import Image, ImageDraw, ImageFont +from os import path + + +RESOURCE_LOCATION = f"{path.abspath('Resources')}" + + +def generate_images_from_text(x, y, txt): + fontsize = 1 # starting font size + img = Image.new('RGBA', (x, y), (0, 0, 0, 0)) + + # portion of image width you want text width to be + img_fraction = 0.80 + fnt = ImageFont.truetype('/home/koma52/.fonts/Ubuntu.ttf', fontsize) + + while fnt.getbbox(str(txt))[2] - fnt.getbbox(str(txt))[0] < img_fraction*img.size[0]: + # iterate until the text size is just larger than the criteria + fontsize += 1 + fnt = ImageFont.truetype("/home/koma52/.fonts/Ubuntu.ttf", fontsize) + + # optionally de-increment to be sure it is less than criteria + fontsize -= 1 + fnt = ImageFont.truetype("/home/koma52/.fonts/Ubuntu.ttf", fontsize) + + d = ImageDraw.Draw(img) + d.text((x/2,y/2), str(txt), font=fnt, fill=(255,255,255), anchor="mm") + # img.save(f'{RESOURCE_LOCATION}/name.png') + return img + + +def assemble_image(participants, wordcloudimg="wordcloud.png", timelineimg="timeline.png"): + if participants[0].chat_type == "Regular": + names = [] + for p in participants: + names.append(p.name) + name_txt = ' & '.join(names) + else: + name_txt = participants[0].title + + names = generate_images_from_text(5000, 600, name_txt) + # names.save(f'{RESOURCE_LOCATION}/name.png') + + number_of_messages = 0 + for p in participants: + number_of_messages += len(p.messages) + + n_o_m = generate_images_from_text(750, 350, str(number_of_messages)) + # n_o_m.save(f'{RESOURCE_LOCATION}/number_of_messages.png') + n_o_m_text = generate_images_from_text(750, 400, "TOTAL NUMBER OF MESSAGES") + # n_o_m_text.save(f'{RESOURCE_LOCATION}/number_of_messages_text.png') + + final = Image.new('RGB', (5000, 8000), (0, 0, 0)) + final.paste(names, (0, 0)) + final.paste(n_o_m_text, (3250, 4400)) + final.paste(n_o_m, (3250, 4750)) + wordcloud = Image.open(f"{RESOURCE_LOCATION}/{wordcloudimg}") + final.paste(wordcloud, (1500, 600)) + timeline = Image.open(f"{RESOURCE_LOCATION}/{timelineimg}") + final.paste(timeline, (250, 2600)) + + + final.save(f"{RESOURCE_LOCATION}/final.png") + diff --git a/chatanalyzer/participant.py b/chatanalyzer/participant.py index 020b36c..9c0abeb 100644 --- a/chatanalyzer/participant.py +++ b/chatanalyzer/participant.py @@ -8,9 +8,11 @@ def remove_punctuations(s): class Participant: - def __init__(self, name): + def __init__(self, name, title, chat_type): self.name = ftfy.ftfy(name) self.messages = {} + self.title = ftfy.ftfy(title) + self.chat_type = chat_type def add_message(self, timestamp, message): self.messages[str(datetime.fromtimestamp(timestamp/1000))] = ftfy.ftfy(message)