Improvements to trip list pages
This commit is contained in:
parent
7d376b38f3
commit
455528125c
|
@ -6,6 +6,7 @@ import typing
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
|
import emoji
|
||||||
from pycountry.db import Country
|
from pycountry.db import Country
|
||||||
|
|
||||||
import agenda
|
import agenda
|
||||||
|
@ -42,6 +43,18 @@ class TripElement:
|
||||||
element_type: str
|
element_type: str
|
||||||
detail: StrDict
|
detail: StrDict
|
||||||
|
|
||||||
|
def get_emoji(self) -> str | None:
|
||||||
|
"""Emjoji for trip element."""
|
||||||
|
if self.element_type in ("check-in", "check-out"):
|
||||||
|
return emoji.emojize(":hotel:", language="alias")
|
||||||
|
if self.element_type == "train":
|
||||||
|
return emoji.emojize(":train:", language="alias")
|
||||||
|
if self.element_type == "flight":
|
||||||
|
return emoji.emojize(":airplane:", language="alias")
|
||||||
|
if self.element_type == "ferry":
|
||||||
|
return emoji.emojize(":ferry:", language="alias")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def airport_label(airport: StrDict) -> str:
|
def airport_label(airport: StrDict) -> str:
|
||||||
"""Airport label: name and iata."""
|
"""Airport label: name and iata."""
|
||||||
|
@ -259,6 +272,16 @@ class Trip:
|
||||||
day = as_date(element.when)
|
day = as_date(element.when)
|
||||||
grouped_elements[day].append(element)
|
grouped_elements[day].append(element)
|
||||||
|
|
||||||
|
# Sort elements within each day
|
||||||
|
for day in grouped_elements:
|
||||||
|
grouped_elements[day].sort(
|
||||||
|
key=lambda e: (
|
||||||
|
e.element_type == "check-in", # check-out elements last
|
||||||
|
e.element_type != "check-out", # check-in elements first
|
||||||
|
as_datetime(e.when), # then sort by time
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Convert the dictionary to a sorted list of tuples
|
# Convert the dictionary to a sorted list of tuples
|
||||||
grouped_elements_list = sorted(grouped_elements.items())
|
grouped_elements_list = sorted(grouped_elements.items())
|
||||||
|
|
||||||
|
|
|
@ -9,3 +9,4 @@ dateutil
|
||||||
ephem
|
ephem
|
||||||
flask
|
flask
|
||||||
requests
|
requests
|
||||||
|
emoji
|
||||||
|
|
|
@ -82,13 +82,21 @@
|
||||||
<div class="heading"><h2>{{ heading }}</h2></div>
|
<div class="heading"><h2>{{ heading }}</h2></div>
|
||||||
<p>{{ items | count }} trips</p>
|
<p>{{ items | count }} trips</p>
|
||||||
{% for trip in items %}
|
{% for trip in items %}
|
||||||
|
{% set distances_by_transport_type = trip.distances_by_transport_type() %}
|
||||||
{% set total_distance = trip.total_distance() %}
|
{% set total_distance = trip.total_distance() %}
|
||||||
{% set end = trip.end %}
|
{% set end = trip.end %}
|
||||||
<div class="border border-2 rounded mb-2 p-2">
|
<div class="border border-2 rounded mb-2 p-2">
|
||||||
<h3>
|
<h3>
|
||||||
{{ trip_link(trip) }}
|
{{ trip_link(trip) }}
|
||||||
<small class="text-muted">({{ display_date(trip.start) }})</small></h3>
|
<small class="text-muted">({{ display_date(trip.start) }})</small></h3>
|
||||||
<div>Countries: {{ trip.countries_str }}</div>
|
<ul class="list-unstyled">
|
||||||
|
{% for c in trip.countries %}
|
||||||
|
<li>
|
||||||
|
{{ c.name }}
|
||||||
|
{{ c.flag }}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
{% if end %}
|
{% if end %}
|
||||||
<div>Dates: {{ display_date_no_year(trip.start) }} to {{ display_date_no_year(end) }}</div>
|
<div>Dates: {{ display_date_no_year(trip.start) }} to {{ display_date_no_year(end) }}</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -100,60 +108,63 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{#
|
{% if distances_by_transport_type %}
|
||||||
{% for day in trip.days() %}
|
{% for transport_type, distance in distances_by_transport_type %}
|
||||||
<h4>{{ display_date_no_year(day) }}</h4>
|
<div>{{ transport_type | title }} distance:
|
||||||
|
{{ "{:,.0f} km / {:,.0f} miles".format(distance, distance / 1.60934) }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for item in trip.conferences %}
|
||||||
|
{% set country = get_country(item.country) if item.country else None %}
|
||||||
|
<div class="card my-1">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">
|
||||||
|
<a href="{{ item.url }}">{{ item.name }}</a>
|
||||||
|
<small class="text-muted">
|
||||||
|
{{ display_date_no_year(item.start) }} to {{ display_date_no_year(item.end) }}
|
||||||
|
</small>
|
||||||
|
</h5>
|
||||||
|
<p class="card-text">
|
||||||
|
Topic: {{ item.topic }}
|
||||||
|
| Venue: {{ item.venue }}
|
||||||
|
| Location: {{ item.location }}
|
||||||
|
{% if country %}
|
||||||
|
{{ country.flag }}
|
||||||
|
{% elif item.online %}
|
||||||
|
💻 Online
|
||||||
|
{% else %}
|
||||||
|
<span class="text-bg-danger p-2">
|
||||||
|
country code <strong>{{ item.country }}</strong> not found
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
{% if item.free %}
|
||||||
|
| <span class="badge bg-success text-nowrap">free to attend</span>
|
||||||
|
{% elif item.price and item.currency %}
|
||||||
|
| <span class="badge bg-info text-nowrap">price: {{ item.price }} {{ item.currency }}</span>
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
#}
|
|
||||||
|
|
||||||
{% for item in trip.conferences %}
|
|
||||||
{% set country = get_country(item.country) if item.country else None %}
|
|
||||||
<div class="card my-1">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">
|
|
||||||
<a href="{{ item.url }}">{{ item.name }}</a>
|
|
||||||
<small class="text-muted">
|
|
||||||
{{ display_date_no_year(item.start) }} to {{ display_date_no_year(item.end) }}
|
|
||||||
</small>
|
|
||||||
</h5>
|
|
||||||
<p class="card-text">
|
|
||||||
Topic: {{ item.topic }}
|
|
||||||
| Venue: {{ item.venue }}
|
|
||||||
| Location: {{ item.location }}
|
|
||||||
{% if country %}
|
|
||||||
{{ country.flag }}
|
|
||||||
{% elif item.online %}
|
|
||||||
💻 Online
|
|
||||||
{% else %}
|
|
||||||
<span class="text-bg-danger p-2">
|
|
||||||
country code <strong>{{ item.country }}</strong> not found
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
{% if item.free %}
|
|
||||||
| <span class="badge bg-success text-nowrap">free to attend</span>
|
|
||||||
{% elif item.price and item.currency %}
|
|
||||||
| <span class="badge bg-info text-nowrap">price: {{ item.price }} {{ item.currency }}</span>
|
|
||||||
{% endif %}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% set date_heading = None %}
|
{% set date_heading = None %}
|
||||||
{% for day, elements in trip.elements_grouped_by_day() %}
|
{% for day, elements in trip.elements_grouped_by_day() %}
|
||||||
<h4>{{ display_date_no_year(day) }}</h4>
|
<h4>{{ display_date_no_year(day) }}</h4>
|
||||||
{% for e in elements %}
|
{% for e in elements %}
|
||||||
<div>
|
{% if e.element_type == "check-out" %}
|
||||||
|
<div>{{ e.get_emoji() }} {{ e.title }} (check-out)</div>
|
||||||
|
{% elif e.element_type == "check-in" %}
|
||||||
|
<div>{{ e.get_emoji() }} {{ e.title }} (check-in)</div>
|
||||||
|
{% else %}
|
||||||
<div>
|
<div>
|
||||||
|
{{ e.get_emoji() }}
|
||||||
{{ display_time(e.when) }}
|
{{ display_time(e.when) }}
|
||||||
—
|
—
|
||||||
{{ e.element_type }}
|
|
||||||
—
|
|
||||||
{{ e.title }}
|
{{ e.title }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue