diff --git a/AGENTS.md b/AGENTS.md index 87c46c9..dba80ce 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -33,3 +33,7 @@ This is a personal agenda web application built with Flask that tracks various e ## Notes - Trip stats new-country badges come from `agenda.stats.calculate_yearly_stats` via `year_stats.new_countries` (first-visit year, excluding `PREVIOUSLY_VISITED`). +- Trip stats are calculated in `agenda/stats.py`: + - `travel_legs()` extracts airlines, airports, and stations from individual trip travel legs + - `calculate_yearly_stats()` aggregates stats per year including flight/train counts, airlines, airports, stations + - `calculate_overall_stats()` aggregates yearly stats into overall totals for the summary section diff --git a/agenda/stats.py b/agenda/stats.py index f9002a1..2e4dc67 100644 --- a/agenda/stats.py +++ b/agenda/stats.py @@ -61,6 +61,29 @@ def conferences(trip: Trip, yearly_stats: Mapping[int, StrDict]) -> None: yearly_stats[c["start"].year]["conferences"] += 1 +def calculate_overall_stats(yearly_stats: dict[int, StrDict]) -> StrDict: + """Aggregate yearly stats into overall stats for airlines, airports, stations.""" + overall: StrDict = { + "airlines": Counter(), + "airports": Counter(), + "stations": Counter(), + "flight_count": 0, + "train_count": 0, + } + + for year_stats in yearly_stats.values(): + if "airlines" in year_stats: + overall["airlines"] += year_stats["airlines"] + if "airports" in year_stats: + overall["airports"] += year_stats["airports"] + if "stations" in year_stats: + overall["stations"] += year_stats["stations"] + overall["flight_count"] += year_stats.get("flight_count", 0) + overall["train_count"] += year_stats.get("train_count", 0) + + return overall + + def calculate_yearly_stats( trips: list[Trip], previously_visited: set[str] | None = None ) -> dict[int, StrDict]: diff --git a/templates/trip/stats.html b/templates/trip/stats.html index e7eb51e..f912177 100644 --- a/templates/trip/stats.html +++ b/templates/trip/stats.html @@ -20,6 +20,36 @@ {% endfor %} +
+ Flight segments: {{ overall_stats.flight_count }} + {% if overall_stats.airlines %} + ({{ overall_stats.airlines | count }} airlines) + [ by airline: + {% for airline, count in overall_stats.airlines.most_common() %} + {{ airline }}: {{ count }}{% if not loop.last %},{% endif %} + {% endfor %} ] + {% endif %} +
+ {% if overall_stats.airports %} +
+ Airports used: {{ overall_stats.airports | count }} + [ by airport: + {% for airport, count in overall_stats.airports.most_common() %} + {{ airport }}: {{ count }}{% if not loop.last %},{% endif %} + {% endfor %} ] +
+ {% endif %} +
Train segments: {{ overall_stats.train_count }}
+ {% if overall_stats.stations %} +
+ Stations used: {{ overall_stats.stations | count }} + [ by station: + {% for station, count in overall_stats.stations.most_common() %} + {{ station }}: {{ count }}{% if not loop.last %},{% endif %} + {% endfor %} ] +
+ {% endif %} + {% for year, year_stats in yearly_stats | dictsort(reverse=True) %} {% set countries = year_stats.countries | default([]) | sort(attribute="name") %} {% set new_countries = year_stats.new_countries | default([]) %} diff --git a/web_view.py b/web_view.py index a61e257..b9c5de6 100755 --- a/web_view.py +++ b/web_view.py @@ -811,6 +811,7 @@ def trip_stats() -> str: yearly_stats = agenda.stats.calculate_yearly_stats( trip_list, app.config.get("PREVIOUSLY_VISITED") ) + overall_stats = agenda.stats.calculate_overall_stats(yearly_stats) return flask.render_template( "trip/stats.html", @@ -818,6 +819,7 @@ def trip_stats() -> str: total_distance=calc_total_distance(trip_list), distances_by_transport_type=sum_distances_by_transport_type(trip_list), yearly_stats=yearly_stats, + overall_stats=overall_stats, conferences=conferences, previously_visited=app.config.get("PREVIOUSLY_VISITED", set), )