400 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			400 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
{% macro display_datetime(dt) %}{{ dt.strftime("%a, %d, %b %Y %H:%M %z") }}{% endmacro %}
 | 
						|
{% macro display_time(dt) %}
 | 
						|
  {% if dt %}{{ dt.strftime("%H:%M %z") }}{% endif %}
 | 
						|
{% endmacro %}
 | 
						|
{% macro display_date(dt) %}{{ dt.strftime("%a %-d %b %Y") }}{% endmacro %}
 | 
						|
{% macro display_date_no_year(dt) %}{{ dt.strftime("%a %-d %b") }}{% endmacro %}
 | 
						|
 | 
						|
{% macro format_distance(distance) %}
 | 
						|
  {{ "{:,.0f} km / {:,.0f} miles".format(distance, distance / 1.60934) }}
 | 
						|
{% endmacro %}
 | 
						|
 | 
						|
{% macro trip_link(trip) %}
 | 
						|
    <a href="{{ url_for("trip_page", start=trip.start.isoformat()) }}">{{ trip.title }}</a>
 | 
						|
{% endmacro %}
 | 
						|
 | 
						|
{% macro conference_row(item, badge, show_flags=True) %}
 | 
						|
  {% set country = get_country(item.country) if item.country else None %}
 | 
						|
  <div class="grid-item text-end">{{ item.start.strftime("%a, %d %b %Y") }}</div>
 | 
						|
  <div class="grid-item text-end">{{ item.end.strftime("%a, %d %b") }}</div>
 | 
						|
  <div class="grid-item">
 | 
						|
    {% if item.url %}
 | 
						|
      <a href="{{ item.url }}">{{ item.name }}</a>
 | 
						|
    {% else %}
 | 
						|
      {{ item.name }}
 | 
						|
    {% endif %}
 | 
						|
    {% if item.going and not (item.accommodation_booked or item.travel_booked) %}
 | 
						|
      <span class="badge text-bg-primary">
 | 
						|
        {{ badge }}
 | 
						|
      </span>
 | 
						|
    {% endif %}
 | 
						|
    {% if item.accommodation_booked %}
 | 
						|
      <span class="badge text-bg-success">accommodation</span>
 | 
						|
    {% endif %}
 | 
						|
    {% if item.transport_booked %}
 | 
						|
      <span class="badge text-bg-success">transport</span>
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
  <div class="grid-item text-end">
 | 
						|
    {% if item.price and item.currency %}
 | 
						|
      <span class="badge bg-info text-nowrap">{{ "{:,d}".format(item.price | int) }} {{ item.currency }}</span>
 | 
						|
      {% if item.currency != "GBP" and item.currency in fx_rate %}
 | 
						|
        <span class="badge bg-info text-nowrap">{{ "{:,.2f}".format(item.price / fx_rate[item.currency]) }} GBP</span>
 | 
						|
      {% endif %}
 | 
						|
    {% elif item.free %}
 | 
						|
      <span class="badge bg-success text-nowrap">free to attend</span>
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
  <div class="grid-item">{{ item.topic }}</div>
 | 
						|
  <div class="grid-item">{{ item.location }}</div>
 | 
						|
  <div class="grid-item text-end">{{ display_date(item.cfp_end) if item.cfp_end else "" }}</div>
 | 
						|
  <div class="grid-item">
 | 
						|
    {% if country %}
 | 
						|
      {% if show_flags %}{{ country.flag }}{% endif %} {{ country.name }}
 | 
						|
    {% elif item.online %}
 | 
						|
      💻 Online
 | 
						|
    {% else %}
 | 
						|
      <span class="text-bg-danger p-2">
 | 
						|
        country code <strong>{{ item.country }}</strong> not found
 | 
						|
      </span>
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
{% endmacro %}
 | 
						|
 | 
						|
{% macro accommodation_row(item, badge, show_flags=True) %}
 | 
						|
  {% set country = get_country(item.country) %}
 | 
						|
 | 
						|
  {% set nights = (item.to.date() - item.from.date()).days %}
 | 
						|
  <div class="grid-item text-end">{{ item.from.strftime("%a, %d %b %Y") }}</div>
 | 
						|
  <div class="grid-item text-end">{{ item.to.strftime("%a, %d %b") }}</div>
 | 
						|
  <div class="grid-item text-end">{% if nights == 1 %}1 night{% else %}{{ nights }} nights{% endif %}</div>
 | 
						|
  <div class="grid-item">{{ item.operator }}</div>
 | 
						|
  <div class="grid-item">{{ item.location }}</div>
 | 
						|
  <div class="grid-item">
 | 
						|
    {% if country %}
 | 
						|
      {% if show_flags %}{{ country.flag }}{% endif %} {{ country.name }}
 | 
						|
    {% else %}
 | 
						|
      <span class="text-bg-danger p-2">
 | 
						|
        country code <strong>{{ item.country }}</strong> not found
 | 
						|
      </span>
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
  <div class="grid-item">
 | 
						|
    {% if g.user.is_authenticated and item.url %}
 | 
						|
      <a href="{{ item.url }}">{{ item.name }}</a>
 | 
						|
    {% else %}
 | 
						|
      {{ item.name }}
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
  <div class="grid-item text-end">
 | 
						|
    {% if g.user.is_authenticated and item.price and item.currency %}
 | 
						|
      <span class="badge bg-info text-nowrap">{{ "{:,f}".format(item.price) }} {{ item.currency }}</span>
 | 
						|
      {% if item.currency != "GBP" %}
 | 
						|
        <span class="badge bg-info text-nowrap">{{ "{:,.2f}".format(item.price / fx_rate[item.currency]) }} GBP</span>
 | 
						|
      {% endif %}
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
{% endmacro %}
 | 
						|
 | 
						|
{% macro flight_booking_row(booking, show_flags=True) %}
 | 
						|
  <div class="grid-item">
 | 
						|
    {% if g.user.is_authenticated %}
 | 
						|
      {{ booking.booking_reference or "reference missing" }}
 | 
						|
    {% else %}
 | 
						|
      <em>redacted</em>
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
 | 
						|
  <div class="grid-item text-end">
 | 
						|
    {% if g.user.is_authenticated and booking.price and booking.currency %}
 | 
						|
      <span class="badge bg-info text-nowrap">{{ "{:,f}".format(booking.price) }} {{ booking.currency }}</span>
 | 
						|
      {% if booking.currency != "GBP" %}
 | 
						|
        <span class="badge bg-info text-nowrap">{{ "{:,.2f}".format(booking.price / fx_rate[booking.currency]) }} GBP</span>
 | 
						|
      {% endif %}
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
  {% for i in range(8) %}
 | 
						|
    <div class="grid-item"></div>
 | 
						|
  {% endfor %}
 | 
						|
 | 
						|
  {% for item in booking.flights %}
 | 
						|
    {% set full_flight_number = item.airline + item.flight_number %}
 | 
						|
    {% set radarbox_url = "https://www.radarbox.com/data/flights/" + full_flight_number %}
 | 
						|
    <div class="grid-item"></div>
 | 
						|
    <div class="grid-item"></div>
 | 
						|
    <div class="grid-item text-end">{{ item.depart.strftime("%a, %d %b %Y") }}</div>
 | 
						|
    <div class="grid-item">{{ item.from }} → {{ item.to }}</div>
 | 
						|
    <div class="grid-item">{{ item.depart.strftime("%H:%M") }}</div>
 | 
						|
    <div class="grid-item">
 | 
						|
      {% if item.arrive %}
 | 
						|
        {{ item.arrive.strftime("%H:%M") }}
 | 
						|
        {% if item.arrive.date() != item.depart.date() %}+1 day{% endif %}
 | 
						|
      {% endif %}
 | 
						|
    </div>
 | 
						|
    <div class="grid-item">{{ item.duration }}</div>
 | 
						|
    <div class="grid-item">{{ full_flight_number }}</div>
 | 
						|
    <div class="grid-item">
 | 
						|
      <a href="https://www.flightradar24.com/data/flights/{{ full_flight_number | lower }}">flightradar24</a>
 | 
						|
      | <a href="https://uk.flightaware.com/live/flight/{{ full_flight_number | replace("U2", "EZY") }}">FlightAware</a>
 | 
						|
      | <a href="{{ radarbox_url }}">radarbox</a>
 | 
						|
    </div>
 | 
						|
    <div class="grid-item text-end">
 | 
						|
      {% if item.distance %}
 | 
						|
        {{ "{:,.0f} km / {:,.0f} miles".format(item.distance, item.distance / 1.60934) }}
 | 
						|
      {% endif %}
 | 
						|
    </div>
 | 
						|
  {% endfor %}
 | 
						|
{% endmacro %}
 | 
						|
 | 
						|
{% macro flight_row(item) %}
 | 
						|
  {% set full_flight_number = item.airline + item.flight_number %}
 | 
						|
  {% set radarbox_url = "https://www.radarbox.com/data/flights/" + full_flight_number %}
 | 
						|
  <div class="grid-item text-end">{{ item.depart.strftime("%a, %d %b %Y") }}</div>
 | 
						|
  <div class="grid-item">{{ item.from }} → {{ item.to }}</div>
 | 
						|
  <div class="grid-item">{{ item.depart.strftime("%H:%M") }}</div>
 | 
						|
  <div class="grid-item">
 | 
						|
    {% if item.arrive %}
 | 
						|
      {{ item.arrive.strftime("%H:%M") }}
 | 
						|
      {% if item.arrive.date() != item.depart.date() %}+1 day{% endif %}
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
  <div class="grid-item">{{ item.duration }}</div>
 | 
						|
  <div class="grid-item">{{ full_flight_number }}</div>
 | 
						|
  <div class="grid-item">
 | 
						|
    {% if g.user.is_authenticated %}
 | 
						|
      {{ item.booking_reference }}
 | 
						|
    {% else %}
 | 
						|
      <em>redacted</em>
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
  <div class="grid-item">
 | 
						|
    <a href="https://www.flightradar24.com/data/flights/{{ full_flight_number | lower }}">flightradar24</a>
 | 
						|
    | <a href="https://uk.flightaware.com/live/flight/{{ full_flight_number | replace("U2", "EZY") }}">FlightAware</a>
 | 
						|
    | <a href="{{ radarbox_url }}">radarbox</a>
 | 
						|
  </div>
 | 
						|
  <div class="grid-item text-end">
 | 
						|
    {% if item.distance %}
 | 
						|
      {{ "{:,.0f} km / {:,.0f} miles".format(item.distance, item.distance / 1.60934) }}
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
  <div class="grid-item text-end">
 | 
						|
    {% if g.user.is_authenticated and item.price and item.currency %}
 | 
						|
      <span class="badge bg-info text-nowrap">{{ "{:,f}".format(item.price) }} {{ item.currency }}</span>
 | 
						|
      {% if item.currency != "GBP" %}
 | 
						|
        <span class="badge bg-info text-nowrap">{{ "{:,.2f}".format(item.price / fx_rate[item.currency]) }} GBP</span>
 | 
						|
      {% endif %}
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
{% endmacro %}
 | 
						|
 | 
						|
{% macro train_row(item) %}
 | 
						|
  {% set url = item.url %}
 | 
						|
  <div class="grid-item text-end">{{ item.depart.strftime("%a, %d %b %Y") }}</div>
 | 
						|
  <div class="grid-item">
 | 
						|
    {% if g.user.is_authenticated and item.url %}<a href="{{ url }}">{% endif %}
 | 
						|
      {{ item.from }} → {{ item.to }}
 | 
						|
    {% if g.user.is_authenticated and item.url %}</a>{% endif %}
 | 
						|
  </div>
 | 
						|
  <div class="grid-item">{{ item.depart.strftime("%H:%M") }}</div>
 | 
						|
  <div class="grid-item">
 | 
						|
    {% if item.arrive %}
 | 
						|
      {{ item.arrive.strftime("%H:%M") }}
 | 
						|
      {% if item.depart != item.arrive and item.arrive.date() != item.depart.date() %}+1 day{% endif %}
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
  <div class="grid-item">{{ ((item.arrive - item.depart).total_seconds() // 60) | int }} mins</div>
 | 
						|
  <div class="grid-item">{{ item.operator }}</div>
 | 
						|
  <div class="grid-item">
 | 
						|
    {% if g.user.is_authenticated %}
 | 
						|
      {{ item.booking_reference }}
 | 
						|
    {% else %}
 | 
						|
      <em>redacted</em>
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
  <div class="grid-item">
 | 
						|
    {% for leg in item.legs %}
 | 
						|
      {% if leg.url %}
 | 
						|
        <a href="{{ leg.url }}">[{{ loop.index }}]</a>
 | 
						|
      {% endif %}
 | 
						|
    {% endfor %}
 | 
						|
  </div>
 | 
						|
  <div class="grid-item text-end">
 | 
						|
    {% if item.distance %}
 | 
						|
      {{ "{:,.0f} km / {:,.0f} miles".format(item.distance, item.distance / 1.60934) }}
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
  <div class="grid-item text-end">
 | 
						|
    {% if g.user.is_authenticated and item.price and item.currency %}
 | 
						|
      <span class="badge bg-info text-nowrap">{{ "{:,f}".format(item.price) }} {{ item.currency }}</span>
 | 
						|
      {% if item.currency != "GBP" and item.currency in fx_rate %}
 | 
						|
        <span class="badge bg-info text-nowrap">{{ "{:,.2f}".format(item.price / fx_rate[item.currency]) }} GBP</span>
 | 
						|
      {% endif %}
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
{% endmacro %}
 | 
						|
 | 
						|
{% macro ferry_row(item) %}
 | 
						|
  <div class="grid-item text-end">{{ item.depart.strftime("%a, %d %b %Y") }}</div>
 | 
						|
  <div class="grid-item">
 | 
						|
      {{ item.from }} → {{ item.to }}
 | 
						|
  </div>
 | 
						|
 | 
						|
  <div class="grid-item">{{ item.depart.strftime("%H:%M") }}</div>
 | 
						|
  <div class="grid-item">
 | 
						|
    {% if item.arrive %}
 | 
						|
      {{ item.arrive.strftime("%H:%M") }}
 | 
						|
      {% if item.depart != item.arrive and item.arrive.date() != item.depart.date() %}+1 day{% endif %}
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
 | 
						|
  <div class="grid-item"></div>
 | 
						|
  <div class="grid-item">{{ item.operator }}</div>
 | 
						|
  <div class="grid-item"></div>
 | 
						|
  <div class="grid-item"></div>
 | 
						|
  <div class="grid-item"></div>
 | 
						|
 | 
						|
  <div class="grid-item text-end">
 | 
						|
    {% if g.user.is_authenticated and item.price and item.currency %}
 | 
						|
      <span class="badge bg-info text-nowrap">{{ "{:,f}".format(item.price) }} {{ item.currency }}</span>
 | 
						|
      {% if item.currency != "GBP" %}
 | 
						|
        <span class="badge bg-info text-nowrap">{{ "{:,.2f}".format(item.price / fx_rate[item.currency]) }} GBP</span>
 | 
						|
      {% endif %}
 | 
						|
    {% endif %}
 | 
						|
  </div>
 | 
						|
 | 
						|
 | 
						|
  {# <div class="grid-item">{{ item | pprint }}</div> #}
 | 
						|
{% endmacro %}
 | 
						|
 | 
						|
{% macro flag(trip, flag) %}{% if trip.show_flags %}{{ flag }}{% endif %}{% endmacro %}
 | 
						|
 | 
						|
{% macro conference_list(trip) %}
 | 
						|
  {% 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 %}
 | 
						|
            {{ flag(trip, 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 %}
 | 
						|
{% endmacro %}
 | 
						|
 | 
						|
{% macro trip_item(trip) %}
 | 
						|
  {% set distances_by_transport_type = trip.distances_by_transport_type() %}
 | 
						|
  {% set total_distance = trip.total_distance() %}
 | 
						|
  {% set end = trip.end %}
 | 
						|
  <div class="border border-2 rounded mb-2 p-2">
 | 
						|
    <h3>
 | 
						|
    {{ trip_link(trip) }}
 | 
						|
    <small class="text-muted">({{ display_date(trip.start) }})</small></h3>
 | 
						|
    <ul class="list-unstyled">
 | 
						|
    {% for c in trip.countries %}
 | 
						|
      <li>
 | 
						|
        {{ c.name }}
 | 
						|
        {{ c.flag }}
 | 
						|
      </li>
 | 
						|
    {% endfor %}
 | 
						|
    </ul>
 | 
						|
    {% if end %}
 | 
						|
      <div>Dates: {{ display_date_no_year(trip.start) }} to {{ display_date_no_year(end) }}
 | 
						|
      {% if g.user.is_authenticated and trip.start <= today %}
 | 
						|
        <a href="https://photos.4angle.com/search?query=%7B%22takenAfter%22%3A%22{{trip.start}}T00%3A00%3A00.000Z%22%2C%22takenBefore%22%3A%22{{end}}T23%3A59%3A59.999Z%22%7D">photos</a>
 | 
						|
      {% endif %}
 | 
						|
      </div>
 | 
						|
    {% else %}
 | 
						|
      <div>Start: {{ display_date_no_year(trip.start) }} (end date missing)</div>
 | 
						|
    {% endif %}
 | 
						|
    {% if total_distance %}
 | 
						|
      <div>
 | 
						|
        Total distance:
 | 
						|
        {{ format_distance(total_distance) }}
 | 
						|
      </div>
 | 
						|
    {% endif %}
 | 
						|
 | 
						|
    {% if distances_by_transport_type %}
 | 
						|
      {% for transport_type, distance in distances_by_transport_type %}
 | 
						|
        <div>
 | 
						|
          {{ transport_type | title }}
 | 
						|
          distance: {{format_distance(distance) }}
 | 
						|
        </div>
 | 
						|
      {% endfor %}
 | 
						|
    {% endif %}
 | 
						|
 | 
						|
    {{ conference_list(trip) }}
 | 
						|
 | 
						|
    {% for day, elements in trip.elements_grouped_by_day() %}
 | 
						|
      <h4>{{ display_date_no_year(day) }}
 | 
						|
        {% if g.user.is_authenticated and day <= today %}
 | 
						|
          <span class="lead">
 | 
						|
            <a href="https://photos.4angle.com/search?query=%7B%22takenAfter%22%3A%22{{day}}T00%3A00%3A00.000Z%22%2C%22takenBefore%22%3A%22{{day}}T23%3A59%3A59.999Z%22%7D">photos</a>
 | 
						|
          </span>
 | 
						|
        {% endif %}
 | 
						|
      </h4>
 | 
						|
        {% set accommodation_label = {"check-in": "check-in from", "check-out": "check-out by"} %}
 | 
						|
        {% for e in elements %}
 | 
						|
          {% if e.element_type in accommodation_label %}
 | 
						|
            {% set c = get_country(e.detail.country) %}
 | 
						|
            <div>
 | 
						|
              {{ e.get_emoji() }} {{ e.title }} {{ flag(trip, c.flag) }}
 | 
						|
              ({{ accommodation_label[e.element_type] }} {{ display_time(e.start_time) }})
 | 
						|
            </div>
 | 
						|
          {% else %}
 | 
						|
            <div>
 | 
						|
              {{ e.get_emoji() }}
 | 
						|
              {{ display_time(e.start_time) }}
 | 
						|
              –
 | 
						|
              {{ e.start_loc }} {{ flag(trip, e.start_country.flag) }}
 | 
						|
              →
 | 
						|
              {{ display_time(e.end_time) }}
 | 
						|
              –
 | 
						|
              {{ e.end_loc }} {{ flag(trip, e.end_country.flag) }}
 | 
						|
              {% if e.element_type == "flight" %}
 | 
						|
                {% set full_flight_number = e.detail.airline + e.detail.flight_number %}
 | 
						|
                {% set radarbox_url = "https://www.radarbox.com/data/flights/" + full_flight_number %}
 | 
						|
                <span class="text-nowrap"><strong>airline:</strong> {{ e.detail.airline_name }}</span>
 | 
						|
                <span class="text-nowrap"><strong>flight number:</strong> {{ e.detail.airline }}{{ e.detail.flight_number }}</span>
 | 
						|
                {% if e.detail.duration %}
 | 
						|
                  <span class="text-nowrap"><strong>duration:</strong> {{ e.detail.duration }}</span>
 | 
						|
                {% endif %}
 | 
						|
                {# <pre>{{ e.detail | pprint }}</pre> #}
 | 
						|
              {% endif %}
 | 
						|
              {% if e.detail.distance %}
 | 
						|
                <span class="text-nowrap"><strong>distance:</strong> {{ format_distance(e.detail.distance) }}</span>
 | 
						|
              {% endif %}
 | 
						|
              {% if e.element_type == "flight" %}
 | 
						|
                <a href="https://www.flightradar24.com/data/flights/{{ full_flight_number | lower }}">flightradar24</a>
 | 
						|
                | <a href="https://uk.flightaware.com/live/flight/{{ full_flight_number | replace("U2", "EZY") }}">FlightAware</a>
 | 
						|
                | <a href="{{ radarbox_url }}">radarbox</a>
 | 
						|
              {% endif %}
 | 
						|
            </div>
 | 
						|
        {% endif %}
 | 
						|
        {% endfor %}
 | 
						|
    {% endfor %}
 | 
						|
 | 
						|
  </div>
 | 
						|
{% endmacro %}
 |