jefklakscodex/extras/end-of-year-poster.py

159 lines
4.7 KiB
Python
Raw Permalink Normal View History

import glob
import re
import os
2022-12-23 16:47:20 +01:00
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
2022-12-23 16:47:20 +01:00
import sys
from dateutil import parser
from datetime import datetime
def is_in_year(year, content):
return re.search(r"date:\s?\"?" + str(year) + "-", content) is not None
def end_of_year(year):
games = []
for name in glob.glob('../content/games/**/*.md'):
if not '/_index.md' in name:
with open(name) as file:
content = file.read()
if is_in_year(year, content):
2022-12-23 16:47:20 +01:00
games.append(to_game_entry(content, name))
return games
2022-12-23 16:47:20 +01:00
def to_game_entry(content, name):
parts = name.split('/')
game_name = parts[-1].replace(".md", "")
game_platform = parts[-2]
cover = "../static/games/" + game_platform + "/" + game_name + "/" + "cover.jpg"
def pry_out(key, defval):
val = re.search(key + r":\s?(.*)", content)
if val is None:
return defval
if type(defval) is float:
return float(val.group(1))
if type(defval) is int:
return int(val.group(1))
if type(defval) is datetime:
return parser.parse(val.group(1).replace("\"", ""))
2022-12-23 16:47:20 +01:00
return val.group(1).replace("\"", "")
return {
"cover": cover,
"hltb": pry_out("howlongtobeat_hrs", 0.0),
"name": pry_out("game_name", ""),
"platform": game_platform,
"score": pry_out("score", 0),
2023-12-31 11:50:42 +01:00
"playdate": pry_out("date", datetime.now()),
"release_date": pry_out("game_release_year", datetime.now())
}
2022-12-23 16:47:20 +01:00
def montage(games_list, year):
2023-12-31 11:50:42 +01:00
print(games_list)
by_playdate = sorted(games_list, key=lambda game: game["playdate"].timestamp())
coverlist = list(map(lambda game: game["cover"], by_playdate))
2022-12-23 16:47:20 +01:00
file = "collage-" + str(year) + ".jpg"
cmd = "montage " + " ".join(coverlist) + " -geometry +0+0 -tile 8x5 -resize 170x200! " + file
os.system(cmd)
2022-12-23 16:47:20 +01:00
os.system("open " + file)
def group_per_platform(games_list):
per_platform = {}
for game in games_list:
if game["platform"] not in per_platform:
per_platform[game["platform"]] = [game]
else:
per_platform[game["platform"]].append(game)
return per_platform
2022-12-23 16:47:20 +01:00
def print_stats(games_list):
games_list = sorted(games_list, key=lambda game: game["hltb"])
total_hours = sum(list(map(lambda game: game["hltb"], games_list)))
print(" -- total #games: " + str(len(games_list)))
2022-12-23 16:47:20 +01:00
print(" -- total hours: " + str(total_hours))
print(" -- average hours: " + str(round(total_hours / len(games_list), 2)))
print(" -- average a day: " + str(round(total_hours / 355, 2)))
print()
print(" -- longest game: " + str(games_list[-1]["hltb"]) + " hours; " + games_list[-1]["name"])
print(" -- shortest game: " + str(games_list[0]["hltb"]) + " hours; " + games_list[0]["name"])
print()
for k, v in group_per_platform(games_list).items():
2022-12-23 16:47:20 +01:00
print(" -- Platform: " + k + " (" + str(len(v)) + "/" + str(len(games_list)) + ")")
recent_years = 2
print()
print("The **Recent GOTY** list:")
recent = list(filter(lambda g: datetime.now().year - g["release_date"].year <= recent_years, filter(lambda g: g["score"] >= 4, games_list)))
for game in recent:
print("- 💖 " + game["name"] + " (" + game["platform"] + "; " + str(game["release_date"].year) + ")")
print()
print("The **Vintage GOTY** list:")
vintage = list(filter(lambda g: datetime.now().year - g["release_date"].year, filter(lambda g: g["score"] >= 4, games_list)))
for game in vintage:
print("- 💖 " + game["name"] + " (" + game["platform"] + "; " + str(game["release_date"].year) + ")")
2022-12-23 16:47:20 +01:00
def generate_chart(games_list):
games_list = sorted(games_list, key=lambda game: game["score"])
mean_list_x = []
mean_list_y = []
legend_keys = []
legend_lines = []
legend_colors = {
'3ds': 'mediumaquamarine',
'ds': 'mediumturquoise',
'gameboy': 'olivedrab',
'gameboycolor': 'yellowgreen',
'gamecube': 'darkviolet',
'gba': 'slateblue',
'megadrive': 'royalblue',
'nes': 'firebrick',
'pc': 'dimgray',
'snes': 'orange',
'switch': 'red',
'wii': 'lightgrey'
}
for k, games in group_per_platform(games_list).items():
x = list(map(lambda g: g["name"], games))
y = list(map(lambda g: g["score"], games))
plt.bar(x, y, color=legend_colors[k])
legend_lines.append(Line2D([0], [0], color=legend_colors[k], lw=4))
legend_keys.append(k)
mean_list_x.append(x[len(x)//2])
mean_list_y.append(sum(list(map(lambda g: g["score"], games))) / len(games))
2022-12-23 16:47:20 +01:00
plt.xticks(rotation = 90)
plt.plot(mean_list_x, mean_list_y, color='black')
plt.scatter(mean_list_x, mean_list_y, color='black')
for i, x in enumerate(mean_list_x):
y = mean_list_y[i]
plt.text(x, y + .2, round(y, 2))
plt.legend(legend_lines, legend_keys, loc="upper left")
2022-12-23 16:47:20 +01:00
plt.show()
if len(sys.argv) <= 1:
print("Please provide a year [e.g. end-of-year-poster.py 2022].")
exit(-1)
year = int(sys.argv[1])
os.system("rm -rf *.jpg")
2022-12-23 16:47:20 +01:00
games_list = end_of_year(year)
montage(games_list, year)
print_stats(games_list)
generate_chart(games_list)