import glob import re import os import matplotlib.pyplot as plt from matplotlib.lines import Line2D 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): games.append(to_game_entry(content, name)) return games 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("\"", "")) 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), "playdate": pry_out("date", datetime.now()), "release_date": pry_out("game_release_year", datetime.now()) } def montage(games_list, year): print(games_list) by_playdate = sorted(games_list, key=lambda game: game["playdate"].timestamp()) coverlist = list(map(lambda game: game["cover"], by_playdate)) file = "collage-" + str(year) + ".jpg" cmd = "montage " + " ".join(coverlist) + " -geometry +0+0 -tile 8x5 -resize 170x200! " + file os.system(cmd) 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 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))) 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(): 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) + ")") 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)) 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") 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") games_list = end_of_year(year) montage(games_list, year) print_stats(games_list) generate_chart(games_list)