diff --git a/src/lanpartydb_website/blueprints/base/templates/layout/base.html b/src/lanpartydb_website/blueprints/base/templates/layout/base.html
index ce6814f9..15952a07 100644
--- a/src/lanpartydb_website/blueprints/base/templates/layout/base.html
+++ b/src/lanpartydb_website/blueprints/base/templates/layout/base.html
@@ -22,6 +22,7 @@
0
diff --git a/src/lanpartydb_website/blueprints/party/templates/party/index_by_country.html b/src/lanpartydb_website/blueprints/party/templates/party/index_by_country.html
new file mode 100644
index 00000000..6053baee
--- /dev/null
+++ b/src/lanpartydb_website/blueprints/party/templates/party/index_by_country.html
@@ -0,0 +1,22 @@
+{% extends 'layout/base.html' %}
+
+{% block body %}
+
+
+
{{ country.flag }} {{ country.name }} {{ pagination.total }}
+
+
+{{ pagination.links }}
+
+
+{% include 'party/_list.html' %}
+
+
+{{ pagination.info }}
+
+
+
+{{ pagination.links }}
+
+
+{%- endblock %}
diff --git a/src/lanpartydb_website/blueprints/party/templates/party/index_countries.html b/src/lanpartydb_website/blueprints/party/templates/party/index_countries.html
new file mode 100644
index 00000000..f1c4464e
--- /dev/null
+++ b/src/lanpartydb_website/blueprints/party/templates/party/index_countries.html
@@ -0,0 +1,25 @@
+{% extends 'layout/base.html' %}
+
+{% block body %}
+
+
{{ _('Countries') }} {{ countries_with_party_count|length }}
+
+
+
+
+ {{ _('Country') }} |
+ {{ _('Parties') }} |
+
+
+
+ {%- for country, party_count in countries_with_party_count|sort(attribute='0.name') %}
+
+ {{ country.flag }} |
+ {{ country.name }} |
+ {{ party_count }} |
+
+ {%- endfor %}
+
+
+
+{%- endblock %}
diff --git a/src/lanpartydb_website/blueprints/party/views.py b/src/lanpartydb_website/blueprints/party/views.py
index 4b1e0e1e..cfbb3db7 100644
--- a/src/lanpartydb_website/blueprints/party/views.py
+++ b/src/lanpartydb_website/blueprints/party/views.py
@@ -6,6 +6,8 @@
:License: MIT
"""
+from collections import Counter
+
from flask import abort, current_app, request
from flask_paginate import Pagination
from lanpartydb.models import Party
@@ -26,7 +28,7 @@ def index(page: int):
per_page = request.args.get('per_page', type=int, default=50)
offset = (page - 1) * per_page
- parties = list(current_app.parties_by_slug.values())
+ parties = _get_parties()
parties.sort(key=lambda party: party.start_on, reverse=True)
pagination = Pagination(page=page, per_page=per_page, total=len(parties))
@@ -40,6 +42,54 @@ def index(page: int):
}
+@blueprint.get('/-/by-country/')
+@templated
+def index_countries():
+ counter = Counter()
+ for party in _get_parties():
+ if party.location:
+ counter[party.location.country_code] += 1
+
+ country_codes_with_party_count = list(counter.items())
+
+ countries_with_party_count = [
+ (_find_country(country_code), party_count)
+ for country_code, party_count in country_codes_with_party_count
+ ]
+
+ return {
+ 'countries_with_party_count': countries_with_party_count,
+ }
+
+
+@blueprint.get('/-/by-country/
/', defaults={'page': 1})
+@blueprint.get('/-/by-country//pages//')
+@templated
+def index_by_country(country_code: str, page: int):
+ country = _find_country(country_code)
+
+ per_page = request.args.get('per_page', type=int, default=50)
+ offset = (page - 1) * per_page
+
+ parties = _get_parties()
+ parties = filter(
+ lambda party: _find_party_country_code(party) == country.alpha_2.lower(),
+ parties,
+ )
+ parties = list(sorted(parties, key=lambda party: party.start_on, reverse=True))
+
+ pagination = Pagination(page=page, per_page=per_page, total=len(parties))
+
+ parties_slice = parties[offset : offset + per_page]
+
+ return {
+ 'country': country,
+ 'parties': parties_slice,
+ 'pagination': pagination,
+ 'countries': countries,
+ }
+
+
@blueprint.get('//')
@templated
def view(slug: str):
@@ -49,7 +99,7 @@ def view(slug: str):
series = current_app.series_by_slug.get(party.series_slug)
- country = _get_country(party)
+ country = _find_party_country(party)
return {
'party': party,
@@ -58,8 +108,24 @@ def view(slug: str):
}
-def _get_country(party: Party) -> Country | None:
+def _get_parties() -> list[Party]:
+ return list(current_app.parties_by_slug.values())
+
+
+def _find_party_country_code(party: Party) -> str | None:
if not party.location:
return None
- return countries.get(alpha_2=party.location.country_code)
+ return party.location.country_code
+
+
+def _find_party_country(party: Party) -> Country | None:
+ country_code = _find_party_country_code(party)
+ if not country_code:
+ return None
+
+ return _find_country(country_code)
+
+
+def _find_country(country_code: str) -> Country | None:
+ return countries.get(alpha_2=country_code)