Show exploration days before/after each conference on trip page
For each conference, calculate the number of free days available before and after, relative to the trip boundary or adjacent conference. Multi-conference trips show the gap between conferences as "after" the first and "before" the second. Closes #189 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3ba18f9019
commit
54e898bc11
3 changed files with 44 additions and 0 deletions
|
|
@ -456,6 +456,39 @@ def coordinate_dict(item: StrDict, coord_type: str) -> StrDict:
|
|||
}
|
||||
|
||||
|
||||
def conference_free_days(trip: Trip) -> dict[str, tuple[int, int]]:
|
||||
"""Return (days_before, days_after) exploration days for each conference.
|
||||
|
||||
Keyed by the conference start date as an ISO string. Days are relative to
|
||||
the trip boundary or the adjacent conference's end/start for multi-conference
|
||||
trips.
|
||||
"""
|
||||
if not trip.conferences or not trip.end:
|
||||
return {}
|
||||
|
||||
def conf_attend_start(c: StrDict) -> date:
|
||||
return as_date(c.get("attend_start") or c["start"])
|
||||
|
||||
def conf_attend_end(c: StrDict) -> date:
|
||||
return as_date(c.get("attend_end") or c["end"])
|
||||
|
||||
sorted_confs = sorted(trip.conferences, key=conf_attend_start)
|
||||
result: dict[str, tuple[int, int]] = {}
|
||||
|
||||
for i, conf in enumerate(sorted_confs):
|
||||
before_boundary = conf_attend_end(sorted_confs[i - 1]) if i > 0 else trip.start
|
||||
after_boundary = (
|
||||
conf_attend_start(sorted_confs[i + 1])
|
||||
if i < len(sorted_confs) - 1
|
||||
else trip.end
|
||||
)
|
||||
days_before = (conf_attend_start(conf) - before_boundary).days
|
||||
days_after = (after_boundary - conf_attend_end(conf)).days
|
||||
result[str(conf["start"])] = (days_before, days_after)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def collect_trip_coordinates(trip: Trip) -> list[StrDict]:
|
||||
"""Extract and de-duplicate travel location coordinates from trip."""
|
||||
coords = []
|
||||
|
|
|
|||
|
|
@ -239,6 +239,16 @@
|
|||
{% elif item.price and item.currency %}
|
||||
<span class="badge bg-info text-nowrap">price: {{ item.price }} {{ item.currency }}</span>
|
||||
{% endif %}
|
||||
{% set free_days = conference_free_days.get(item.start | string) %}
|
||||
{% if free_days %}
|
||||
{% set days_before, days_after = free_days %}
|
||||
{% if days_before > 0 %}
|
||||
<span class="badge bg-secondary text-nowrap">{{ days_before }} day{{ 's' if days_before != 1 }} to explore before</span>
|
||||
{% endif %}
|
||||
{% if days_after > 0 %}
|
||||
<span class="badge bg-secondary text-nowrap">{{ days_after }} day{{ 's' if days_after != 1 }} to explore after</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1144,6 +1144,7 @@ def trip_page(start: str) -> str:
|
|||
destination_times=get_destination_timezones(trip),
|
||||
human_readable_delta=agenda.utils.human_readable_delta,
|
||||
trip_weather=trip_weather,
|
||||
conference_free_days=agenda.trip.conference_free_days(trip),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue