From 5c369fbe203d0e7cd2af154662b33a370e3b2420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristi=C3=A1n=20Maureira-Fredes?= Date: Thu, 21 Aug 2025 00:20:39 +0200 Subject: [PATCH 1/4] Add initial visualization of the data --- .gitignore | 1 + public/css/style.css | 0 scripts/gen_web_views.py | 51 +++++++++++++++ scripts/requirements.txt | 1 + scripts/templates/base.html | 93 ++++++++++++++++++++++++++++ scripts/templates/base_sponsors.html | 46 ++++++++++++++ 6 files changed, 192 insertions(+) create mode 100644 .gitignore create mode 100644 public/css/style.css create mode 100644 scripts/gen_web_views.py create mode 100644 scripts/templates/base.html create mode 100644 scripts/templates/base_sponsors.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d5fd3aa --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +public/*html diff --git a/public/css/style.css b/public/css/style.css new file mode 100644 index 0000000..e69de29 diff --git a/scripts/gen_web_views.py b/scripts/gen_web_views.py new file mode 100644 index 0000000..d62f652 --- /dev/null +++ b/scripts/gen_web_views.py @@ -0,0 +1,51 @@ +import sys +import jinja2 +import json +import numpy as np +import pandas as pd +from jinja2 import Environment, FileSystemLoader +from pathlib import Path + +BASE = Path(__file__).parents[0] +DEST = BASE / ".." / "public" +DATA = BASE / ".." / "data" + +environment = Environment( + loader=FileSystemLoader(str(BASE)) +) + +out = DEST / "sponsors.html" +base_html = environment.get_template(str(Path("templates") / "base_sponsors.html")) + +# Read data +dfs = [] +sponsor_dir = DATA / "sponsors" +for datafile in sponsor_dir.glob("**/*.json"): + data = None + with open(datafile) as f: + try: + data = json.load(f) + except json.decoder.JSONDecodeError: + print("[ERROR] Failed to part", datafile) + sys.exit(1) + + df = pd.DataFrame(data["sponsors"]) + df["level"] = df["level"].apply(lambda x : data["levels"][x] if x in data["levels"] else np.nan) + df["conference"] = datafile.parents[0].stem + df["year"] = data["year"] + dfs.append(df) + +sponsors = pd.concat(dfs) +grouped = sponsors.drop(["conference", "year"], axis=1).groupby("name").sum().sort_values("level", ascending=False) + +# End read data + +context = { + "title": "Sponsors", + "description": "Historical data from European Conferences", + "sponsors": sponsors, + "grouped": grouped, +} + +with open(out, mode="w", encoding="utf-8") as f: + f.write(base_html.render(context)) diff --git a/scripts/requirements.txt b/scripts/requirements.txt index 8dee024..aa7e52f 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -1,2 +1,3 @@ requests types-requests +jinja2 diff --git a/scripts/templates/base.html b/scripts/templates/base.html new file mode 100644 index 0000000..dfe2fb0 --- /dev/null +++ b/scripts/templates/base.html @@ -0,0 +1,93 @@ + + + + + + + + + + + +
+ +
+ + +
+
+
+

+ {{ title }} +

+
+ +
+

{{ description }}

+
+ +
+ {% block content %} + {% endblock %} +
+ +
+
+ + + + diff --git a/scripts/templates/base_sponsors.html b/scripts/templates/base_sponsors.html new file mode 100644 index 0000000..41a0b81 --- /dev/null +++ b/scripts/templates/base_sponsors.html @@ -0,0 +1,46 @@ +{% extends "templates/base.html" %} +{% block content %} +

+ Ranking by amount +

+ + + + + + + + + {% for idx, sponsor in grouped.iterrows() %} + + + + + {% endfor %} + +
CompanyTotal amount (EUR)
{{ sponsor['name'] }}{{ sponsor['level'] }}
+ +

+ All data +

+ + + + + + + + + + + {% for idx, sponsor in sponsors.iterrows() %} + + + + + + + {% endfor %} + +
YearConferenceCompanyAmount (EUR)
{{ sponsor['year'] }}{{ sponsor['conference'] }}{{ sponsor['name'] }}{{ sponsor['level'] }}
+{% endblock %} From f6f86a8d464b8b9c22a87a4114ab18155c5b33f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristi=C3=A1n=20Maureira-Fredes?= Date: Thu, 21 Aug 2025 09:27:02 +0200 Subject: [PATCH 2/4] Typo on error message --- scripts/gen_web_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gen_web_views.py b/scripts/gen_web_views.py index d62f652..94133a9 100644 --- a/scripts/gen_web_views.py +++ b/scripts/gen_web_views.py @@ -26,7 +26,7 @@ try: data = json.load(f) except json.decoder.JSONDecodeError: - print("[ERROR] Failed to part", datafile) + print("[ERROR] Failed to parse", datafile) sys.exit(1) df = pd.DataFrame(data["sponsors"]) From 2bf37ac0d71545f065be79b8155ae7a1cd2033d3 Mon Sep 17 00:00:00 2001 From: Artur Czepiel Date: Thu, 21 Aug 2025 09:34:55 +0200 Subject: [PATCH 3/4] sync requirements and add some optional uv --- Makefile | 2 ++ scripts/gen_web_views.py | 8 ++++++++ scripts/requirements.txt | 2 ++ 3 files changed, 12 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..14964e5 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +html: + cd scripts && uv run gen_web_views.py diff --git a/scripts/gen_web_views.py b/scripts/gen_web_views.py index 94133a9..2e20504 100644 --- a/scripts/gen_web_views.py +++ b/scripts/gen_web_views.py @@ -1,3 +1,11 @@ +# /// script +# dependencies = [ +# "jinja2", +# "numpy", +# "pandas", +# ] +# /// + import sys import jinja2 import json diff --git a/scripts/requirements.txt b/scripts/requirements.txt index aa7e52f..8cd545d 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -1,3 +1,5 @@ requests types-requests jinja2 +numpy +pandas From 87f2d68f2aa51b981b089b3f224e8d75a8d96865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristi=C3=A1n=20Maureira-Fredes?= Date: Sat, 23 Aug 2025 13:55:47 +0200 Subject: [PATCH 4/4] Add sort option to each table column --- scripts/templates/base.html | 17 ++++++++++ scripts/templates/base_sponsors.html | 49 +++++++++++++--------------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/scripts/templates/base.html b/scripts/templates/base.html index dfe2fb0..e83e31b 100644 --- a/scripts/templates/base.html +++ b/scripts/templates/base.html @@ -72,6 +72,7 @@

+ + diff --git a/scripts/templates/base_sponsors.html b/scripts/templates/base_sponsors.html index 41a0b81..50cf38e 100644 --- a/scripts/templates/base_sponsors.html +++ b/scripts/templates/base_sponsors.html @@ -1,46 +1,43 @@ {% extends "templates/base.html" %} {% block content %} +{% set sort_icon = '' %}

Ranking by amount

- - - - - - - - +
CompanyTotal amount (EUR)
+ + + + {% for idx, sponsor in grouped.iterrows() %} + {% if sponsor['name'] and ( sponsors['level'] is defined )%} - - + + + {% endif %} {% endfor %} -
Company {{ sort_icon }}Total amount (EUR) {{ sort_icon }}
{{ sponsor['name'] }}{{ sponsor['level'] }}{{ sponsor['name'] }}{{ sponsor['level'] }}

All data

- - - - - - - - - - +
YearConferenceCompanyAmount (EUR)
+ + + + + + {% for idx, sponsor in sponsors.iterrows() %} + {% if sponsor['name'] and ( sponsors['level'] is defined )%} - - - - + + + + + {% endif %} {% endfor %} -
Year {{ sort_icon }}Conference {{ sort_icon }}Company {{ sort_icon }}Amount (EUR) {{ sort_icon }}
{{ sponsor['year'] }}{{ sponsor['conference'] }}{{ sponsor['name'] }}{{ sponsor['level'] }}{{ sponsor['year'] }}{{ sponsor['conference'] }}{{ sponsor['name'] }}{{ sponsor['level'] }}
{% endblock %}