diff options
Diffstat (limited to 'templates')
| -rw-r--r-- | templates/_map_infobox.html.ep | 8 | ||||
| -rw-r--r-- | templates/_train_details.html.ep | 77 | ||||
| -rw-r--r-- | templates/_wagon.html.ep | 46 | ||||
| -rw-r--r-- | templates/about.html.ep | 42 | ||||
| -rw-r--r-- | templates/app.html.ep | 47 | ||||
| -rw-r--r-- | templates/coverage_map.html.ep | 22 | ||||
| -rw-r--r-- | templates/exception.html.ep | 2 | ||||
| -rw-r--r-- | templates/landingpage.html.ep | 9 | ||||
| -rw-r--r-- | templates/layouts/app.html.ep | 82 | ||||
| -rw-r--r-- | templates/layouts/legacy.html.ep | 166 | ||||
| -rw-r--r-- | templates/route_map.html.ep | 14 | ||||
| -rw-r--r-- | templates/select_backend.html.ep | 46 | ||||
| -rw-r--r-- | templates/wagenreihung.html.ep | 72 | 
13 files changed, 279 insertions, 354 deletions
diff --git a/templates/_map_infobox.html.ep b/templates/_map_infobox.html.ep index 7372802..16625f5 100644 --- a/templates/_map_infobox.html.ep +++ b/templates/_map_infobox.html.ep @@ -14,7 +14,7 @@ data-poly="<%= stash('ajax_polyline') %>"  % if (my $next = stash('next_stop')) {  	<div class="nextstop">  	% if ($next->{type} eq 'present' and $next->{station}{dep} and $next->{station}{arr}) { -		Aufenthalt in <strong><%= $next->{station}->loc->name %></strong> +		Aufenthalt in <strong><%= $next->{station}{name} %></strong>  		% if ($next->{station}{platform}) {  			an Gleis <strong><%= $next->{station}{platform} %></strong>  		% } @@ -24,7 +24,7 @@ data-poly="<%= stash('ajax_polyline') %>"  		% }  	% }  	% elsif ($next->{type} eq 'present' and $next->{station}{dep}) { -		Abfahrt in <strong><%= $next->{station}->loc->name %></strong> +		Abfahrt in <strong><%= $next->{station}{name} %></strong>  		% if ($next->{station}{platform}) {  			von Gleis <strong><%= $next->{station}{platform} %></strong>  		% } @@ -52,7 +52,7 @@ data-poly="<%= stash('ajax_polyline') %>"  	% }  	% elsif ($next->{type} eq 'next' and $next->{station}{arr}) {  		Nächster Halt: -		<strong><%= $next->{station}->loc->name %></strong> +		<strong><%= $next->{station}{name} %></strong>  		um <strong><%= $next->{station}{arr}->strftime('%H:%M') %></strong>  		% if ($next->{station}{arr_delay}) {  			%= sprintf('(%+d)', $next->{station}{arr_delay}) @@ -63,7 +63,7 @@ data-poly="<%= stash('ajax_polyline') %>"  	% }  	% elsif ($next->{type} eq 'next') {  		Nächster Halt: -		<strong><%= $next->{station}->loc->name %></strong> +		<strong><%= $next->{station}{name} %></strong>  		% if ($next->{station}{platform}) {  			auf Gleis <strong><%= $next->{station}{platform} %></strong>  		% } diff --git a/templates/_train_details.html.ep b/templates/_train_details.html.ep index 709a1ac..2c18da2 100644 --- a/templates/_train_details.html.ep +++ b/templates/_train_details.html.ep @@ -2,8 +2,8 @@      <div>  %   if ($departure->{train_no} or $departure->{train_line}) {        <span class="train-line <%= $linetype %>"><%= $departure->{train_type} %> - -      <%= $departure->{train_line} // $departure->{train_no} %></span> +        %= $departure->{train_line} // $departure->{train_no} +      </span>        <span class="train-no"><%= $departure->{train_line} ? $departure->{train_no} : q{} %></span>  %   }      </div> @@ -68,10 +68,10 @@  %   else {  %     my $left = '';  %     my $right = ''; -%     if ($departure->{direction} and $departure->{direction} eq 'l') { +%     if ($departure->{wr_direction} and $departure->{wr_direction} =~ m{l}) {  %       $left = '◀ ';  %     } -%     elsif ($departure->{direction} and $departure->{direction} eq 'r') { +%     elsif ($departure->{wr_direction} and $departure->{wr_direction} =~ m{r}) {  %       $right = ' ▶';  %     }  %     if ($departure->{scheduled_platform} and $departure->{platform} @@ -118,49 +118,46 @@      </div> <!-- dataline -->  %   if (my $wr = $departure->{wr}) {        <div class="wagonorder-preview"> -%     my @wagons = $wr->wagons; -%     my $direction = $wr->direction ? $wr->direction == 100 ? '→' : '←' : q{}; -%     if ($departure->{direction}) { -%       $direction = $departure->{direction} eq 'l' ? '◀' : '▶'; -%       if (($departure->{direction} eq 'l' ? 0 : 100) != $wr->direction) { -%         @wagons = reverse @wagons; -%       } +%     my $left = defined $wr->direction ? $wr->direction == 100 ? q{} : '←' : q{}; +%     my $right = defined $wr->direction ? $wr->direction == 100 ? '→' : q{} : q{}; +%     if ($departure->{wr_direction} and $departure->{wr_direction} =~ m{l}) { +%       $left = '◀'; +%       $right = q{};  %     } -      <a href="/_wr/<%= $departure->{train_no} %>/<%= $departure->{wr_link} %>?e=<%= $departure->{direction} // '' %>"> -      %= $direction -%     my $gi; -%     for my $wagon (@wagons) { -%       if (not ($wagon->is_locomotive or $wagon->is_powercar)) { -%         if (defined $gi and $gi != $wagon->group_index) { -            • -%         } -%         if ($wagon->is_closed) { -            X -%         } -%         else { -%=          $wagon->number || ($wagon->type =~ m{AB} ? '½' : $wagon->type =~ m{A} ? '1.' : $wagon->type =~ m{B} ? '2.' : $wagon->type ) -%         } -%       } -%       $gi = $wagon->group_index; +%     elsif ($departure->{wr_direction} and $departure->{wr_direction} =~ m{r}) { +%       $left = q{}; +%       $right = '▶';  %     } -      %= $direction +      <a href="/carriage-formation?<%= $departure->{wr_link} %>&e=<%= $departure->{wr_direction} // '' %>"> +      %= $left +      % for my $entry ((defined $departure->{wr_direction_num} and $departure->{wr_direction_num} != $wr->direction) ? reverse @{$departure->{wr_preview} // []} : @{$departure->{wr_preview} // []}) { +        % if ($entry->[1]) { +          <span class="<%= $entry->[1] %>"><%= $entry->[0] %></span> +        % } +        % else { +          %= $entry->[0] +        % } +      % } +      %= $right        </a>        </div>  %   }      <div class="verbose">  %     if ($departure->{trip_id}) {  %       if (stash('station_name')) { -          <a class="smallbutton" href="/map/<%= $departure->{trip_id} =~ s{#}{%23}gr %>/<%= $departure->{train_line} || 0 %>?from=<%= stash('station_name') %>&hafas=<%= param('hafas') // q{} %>"><i class="material-icons" aria-hidden="true">map</i> Karte</a> +          <a class="smallbutton" href="/map/<%= $departure->{trip_id} =~ s{#}{%23}gr %>/<%= $departure->{train_line} || 0 %>?from=<%= stash('station_name') %>&dbris=<%= param('dbris') %>&efa=<%= param('efa') // q{} %>&hafas=<%= param('hafas') // q{} %>"><i class="material-icons" aria-hidden="true">map</i> Karte</a>  %       }  %       else { -          <a class="smallbutton" href="/map/<%= $departure->{trip_id} =~ s{#}{%23}gr %>/<%= $departure->{train_line} || 0 %>?hafas=<%= param('hafas') // q{} %>"><i class="material-icons" aria-hidden="true">map</i> Karte</a> +          <a class="smallbutton" href="/map/<%= $departure->{trip_id} =~ s{#}{%23}gr %>/<%= $departure->{train_line} || 0 %>?dbris=<%= param('dbris') %>&efa=<%= param('efa') // q{} %>&hafas=<%= param('hafas') // q{} %>"><i class="material-icons" aria-hidden="true">map</i> Karte</a>  %       }  %     }  %     if ($departure->{wr_link}) { -        <a class="smallbutton" href="/_wr/<%= $departure->{train_no} %>/<%= $departure->{wr_link} %>?e=<%= $departure->{direction} // '' %>"><i class="material-icons" aria-hidden="true">train</i> <%= $departure->{wr_text} || 'Wagen' %> +        <a class="smallbutton" href="/carriage-formation?<%= $departure->{wr_link} %>&e=<%= $departure->{wr_direction} // '' %>"><i class="material-icons" aria-hidden="true">train</i> <%= $departure->{wr_text} || 'Wagen' %>          </a>  %     } -%     if ($departure->{train_type} and $departure->{train_no}) { +%     if ($departure->{trip_id} and param('dbris') and param('dbris') eq 'bahn.de') { +        <a class="smallbutton" href="https://bahn.expert/details/x/h/<%= Mojo::Util::url_escape( $departure->{trip_id} ) %>"><img src="/static/icons/bahn-expert.svg">Details</a> +%     } elsif ($departure->{train_type} and $departure->{train_no} and (not param('hafas') or param('hafas') eq 'DB')) {          <a class="smallbutton" href="https://bahn.expert/details/<%= $departure->{train_type} %>%20<%= $departure->{train_no} %>/<%= ($departure->{date} // DateTime->now(time_zone => 'Europe/Berlin'))->iso8601 %>?evaNumberAlongRoute=<%= $departure->{eva} %>"><img src="/static/icons/bahn-expert.svg">Details</a>  %     }  %     for my $link (@{$departure->{links}}) { @@ -257,7 +254,7 @@              </li>  %         }            <li class="<%= $stop->{isPast} ? 'past-stop' : 'future-stop' %>"> -          <a href="<%= url_for('station', station => $stop->{eva} // $stop->{name})->query({detailed => param('detailed'), past => param('past'), rt => param('rt'), hafas => param('hafas')}) %>#<%= ($departure->{train_type} // q{x}) . ($departure->{train_no} // q{x}) %>" class=" +          <a href="<%= url_for('station', station => $stop->{eva} // $stop->{name})->query({detailed => param('detailed'), past => param('past'), rt => param('rt'), dbris => param('dbris'), efa => param('efa'), hafas => param('hafas')}) %>#<%= ((param('dbris') or param('hafas')) and $departure->{trip_id}) ? ($departure->{trip_id} =~ s{[ #|]}{x}gr) : (($departure->{train_type} // q{x}) . ($departure->{train_no} // q{x})) %>" class="  %         if ($stop->{isAdditional}) {              additional-stop  %         } @@ -285,7 +282,9 @@            <%= $stop->{name} %></a>  %         if ($stop->{load}{FIRST} or $stop->{load}{SECOND}) {  %           my ($text, $icon1, $icon2) = utilization_icon([$stop->{load}{FIRST}, $stop->{load}{SECOND}]); -            <i class="material-icons" aria-hidden="true"><%= $icon1 %></i> +            % if ($icon1 ne 'help_outline') { +              <i class="material-icons" aria-hidden="true"><%= $icon1 %></i> +            % }              <i class="material-icons" aria-hidden="true"><%= $icon2 %></i>  %         }            </li> @@ -328,7 +327,9 @@              <strong><%= stash('station_name') %></strong>  %           if (my $u = $departure->{utilization}) {  %             my ($text, $icon1, $icon2) = utilization_icon($u); -              <i class="material-icons" aria-hidden="true"><%= $icon1 %></i> +            % if ($icon1 ne 'help_outline') { +                <i class="material-icons" aria-hidden="true"><%= $icon1 %></i> +            % }                <i class="material-icons" aria-hidden="true"><%= $icon2 %></i>  %           }            </li> @@ -348,7 +349,7 @@              </li>  %         }            <li class="<%= $stop->{isPast} ? 'past-stop' : 'future-stop' %>"> -          <a href="<%= url_for('station', station => $stop->{eva} // $stop->{name})->query({detailed => param('detailed'), past => param('past'), rt => param('rt'), hafas => param('hafas')}) %>#<%= ($departure->{train_type} // q{x}) . ($departure->{train_no} // q{x}) %>" class=" +          <a href="<%= url_for('station', station => $stop->{eva} // $stop->{name})->query({detailed => param('detailed'), past => param('past'), rt => param('rt'), dbris => param('dbris'), efa => param('efa'), hafas => param('hafas')}) %>#<%= ((param('dbris') or param('hafas')) and $departure->{trip_id}) ? ($departure->{trip_id} =~ s{[ #|]}{x}gr) : (($departure->{train_type} // q{x}) . ($departure->{train_no} // q{x})) %>" class="  %         if ($stop->{isAdditional}) {              additional-stop  %         } @@ -376,7 +377,9 @@            <%= $stop->{name} %></a>  %         if ($stop->{load}{FIRST} or $stop->{load}{SECOND}) {  %           my ($text, $icon1, $icon2) = utilization_icon([$stop->{load}{FIRST}, $stop->{load}{SECOND}]); -            <i class="material-icons" aria-hidden="true"><%= $icon1 %></i> +            % if ($icon1 ne 'help_outline') { +              <i class="material-icons" aria-hidden="true"><%= $icon1 %></i> +            % }              <i class="material-icons" aria-hidden="true"><%= $icon2 %></i>  %         }            </li> diff --git a/templates/_wagon.html.ep b/templates/_wagon.html.ep index 2f5a0df..dccecc0 100644 --- a/templates/_wagon.html.ep +++ b/templates/_wagon.html.ep @@ -1,6 +1,6 @@  % my $bg = '';  % my $extra_class = ''; -% if ($wagon->is_first_class) { +% if ($wagon->has_first_class) {  %   $extra_class .= ' firstclass';  % }  % if ($wagon->is_locomotive or $wagon->is_powercar) { @@ -9,34 +9,28 @@  % if ($wagon->is_closed) {  %   $extra_class .= ' closed';  % } -% if ($wagon->train_no ne $train_no) { +% if ($group->train_no ne $train_no) {  %   $extra_class .= ' nondestwagon';  % }    <div class="wagon <%= $extra_class %>" style=" -  top: <%= $wagon->{position}{start_percent} %>%; bottom: <%= 100 - $wagon->{position}{end_percent} %>%; <%= $bg %>"> +  top: <%= $wagon->start_percent %>%; bottom: <%= 100 - $wagon->end_percent %>%; <%= $bg %>">  %   if ($wagon->is_locomotive or $wagon->is_powercar) {  %   }  %   elsif ($wagon->is_closed) {        X  %   }  %   else { -%=    $wagon->number // '?' -%     if ($wagon->has_accessibility) { +%=    $wagon->number // q{} +%     if ($wagon->has_wheelchair_space) {          <i class="material-icons" style="font-size: 20px;">accessible</i>  %     }  %     if ($wagon->has_bistro) {          <i class="material-icons">restaurant</i>  %     } -%     if ($wagon->has_compartments) { -        <!--<i class="material-icons">folder</i>--> -%     } -%     if ($wagon->has_quiet_area) { +%     if ($wagon->has_quiet_zone) {          <i class="tiny material-icons">volume_off</i>  %     } -%     if ($wagon->has_phone_area) { -        <i class="material-icons">smartphone</i> -%     } -%     if ($wagon->has_family_area) { +%     if ($wagon->has_family_zone) {          <i class="material-icons">people</i>  %     }  %     if ($wagon->has_bahn_comfort) { @@ -44,9 +38,9 @@  %     }  %   }    <div class="direction"> -%   if (not defined $direction) { +%   if (not defined $wr->direction) {  %   } -%   elsif ($direction == 100) { +%   elsif ($wr->direction == 100) {        <i class="material-icons">arrow_downward</i>  %   }  %   else { @@ -55,9 +49,9 @@    </div>    </div>    <div class="details" style=" -  top: <%= $wagon->{position}{start_percent} %>%; bottom: <%= 100 - $wagon->{position}{end_percent} %>%;"> +  top: <%= $wagon->start_percent %>%; bottom: <%= 100 - $wagon->end_percent %>%;">  %   if ($exit_dir ne 'right') { -%     if (my $img = wagon_image($wagon->train_subtype // $type // '?', $wagon->type, $wagon->uic_id)) { +%     if (my $img = wagon_image($wr->train_type // '?', $wagon->type, $wagon->uic_id)) {          <a class="type" href="/w/<%= $img %>?n=<%= $wagon->number // '' %>&s=<%= $wagon->section %>&r=<%= $wref %>"><%= $wagon->type %></a>  %     }  %     else { @@ -67,7 +61,7 @@  %     }  %   }  %   my $uic_id = $wagon->uic_id; -%   if (length($uic_id) != 12) { +%   if (length($uic_id) != 12 and length($uic_id) != 14) {        <span class="uicunknown"><%= $uic_id %></span>  %   }  %   elsif (substr($uic_id, 0, 2) >= 90) { @@ -77,7 +71,7 @@        <span class="uicexchange"><%= substr($uic_id, 0, 2) %></span><span class="uiccountry"><%= substr($uic_id, 2, 2) %></span><span class="uic56"><%= substr($uic_id, 4, 2) %></span><span class="uic78"><%= substr($uic_id, 6, 2) %></span><span class="uicno"><%= substr($uic_id, 8, 3) %></span><span class="uiccheck"><%= substr($uic_id, 11) %></span>  %   }  %   if ($exit_dir eq 'right') { -%     if (my $img = wagon_image($wagon->train_subtype // $type // '?', $wagon->type, $wagon->uic_id)) { +%     if (my $img = wagon_image($wr->train_type // '?', $wagon->type, $wagon->uic_id)) {          <a class="type" href="/w/<%= $img %>?n=<%= $wagon->number // '' %>&s=<%= $wagon->section %>&r=<%= $wref %>"><%= $wagon->type %></a>  %     }  %     else { @@ -86,4 +80,18 @@          </span>  %     }  %   } +%   if ($multi and $first) { +      <br/> +      <span class="groupno"> +%       if (scalar $wr->train_numbers > 1) { +          <%= $group->train_type %> <%= $group->train_no %> +%       } +%       if (scalar $wr->destinations > 1) { +          → <%= $group->destination %> +%       } +      </span> +      % if ($multi and $group->desc_short) { +        <span class="grouptype"><%= $group->desc_short %></span> +%     } +%   }    </div> diff --git a/templates/about.html.ep b/templates/about.html.ep index b5af92b..3bf8295 100644 --- a/templates/about.html.ep +++ b/templates/about.html.ep @@ -1,7 +1,8 @@  <div class="container">  	<p> -		DBF ist ein inoffizieller Abfahrtsmonitor für den Regional- und Fernverkehr mit dem Ziel, Daten aus verschiedenen Quellen übersichtlich zusammenzutragen. -		Der Fokus liegt auf Zügen im Netz der Deutschen Bahn; eingeschränkte Unterstützung für Nahverkehr und Züge in anderen Netzen lässt sich optional zuschalten. +		DBF ist ein inoffizieller Abfahrtsmonitor für Nah-, Regional- und Fernverkehr in Deutschland und Umgebung. +		Die Fahrten in der Übersicht verlinken je eine Detailseite mit Unterwegshalten, Meldungen und Kartendarstellung. +		Bei HAFAS-Backends ist zusätzlich die Suche nach spezifischen Fahrten möglich.  	</p>  	<p>  		Der <a href="<%= app->config->{'source_url'} %>">Quelltext</a> steht unter der <a href="https://git.finalrewind.org/db-fakedisplay/tree/COPYING">GNU AGPL v3</a> als Open Source zur Verfügung. © 2011 – 2024 <a href="https://finalrewind.org">derf</a>. @@ -9,37 +10,28 @@  			Fehlermeldungen bitte via  			<a href="<%= $issue_url %>">Issue Tracker</a>.  		% } -	</p> -	<p> -		Das Projekt begann als „db-fakedisplay“ (kurz dbf) zur <a href="/Dortmund -		Hbf?mode=multi">Nachahmung von Bahnhofs-Abfahrtstafeln</a>. Inzwischen -		liegt der Fokus auf dem <a href="/Dortmund Hbf">App/Infoscreen-Modus</a> -		und die Bezeichnung DBF wurde zum Eigennamen ohne weitere Bedeutung. +		Alle von DBF referenzierten Informationen können auch direkt per CLI im Text- oder JSON-Format abgerufen werden – die unten verlinkten Backends beinhalten entsprechende Anwendungen.  	</p>  	<p>  		Diese Installation nutzt  		<strong>DBF v<%= stash('version') // '???' %></strong> mit folgenden Backends:  		<ul> -		<li> Innerdeutscher Regional- und Fernverkehr: DB IRIS via <a href="https://finalrewind.org/projects/Travel-Status-DE-IRIS/">Travel::Status::DE::IRIS</a> +		<li>Innerdeutscher Regional- und Fernverkehr: DB IRIS via <a href="https://finalrewind.org/projects/Travel-Status-DE-IRIS/">Travel::Status::DE::IRIS</a>  		<strong>v<%= $Travel::Status::DE::IRIS::VERSION %></strong></li> -		<li> Außerdeutsche Fahrten, Nahverkehr, Details, Karten: HAFAS via <a href="https://finalrewind.org/projects/Travel-Status-DE-DeutscheBahn/">Travel::Status::DE::HAFAS</a> +		<li>Nah-, Regional- und Fernverkehr im In- und Ausland: bahn.de via <a href="https://finalrewind.org/projects/Travel-Status-DE-DBRIS/">Travel::Status::DE::DBRIS</a> +		<strong>v<%= $Travel::Status::DE::DBRIS::VERSION %></strong></li> +		<li>Nah-, Regional- und Fernverkehr im In- und Ausland: EFA via <a href="https://finalrewind.org/projects/Travel-Status-DE-VRR/">Travel::Status::DE::EFA</a> +		<strong>v<%= $Travel::Status::DE::EFA::VERSION %></strong></li> +		<li>Nah-, Regional- und Fernverkehr im In- und Ausland: HAFAS via <a href="https://finalrewind.org/projects/Travel-Status-DE-DeutscheBahn/">Travel::Status::DE::HAFAS</a>  		<strong>v<%= $Travel::Status::DE::HAFAS::VERSION %></strong></li> -		<li>Wagenreihung: <a href="https://finalrewind.org/projects/Travel-Status-DE-DBWagenreihung/">Travel::Status::DE::DBWagenreihung</a> -		<strong>v<%= $Travel::Status::DE::DBWagenreihung::VERSION %></strong></li> -		<li>Zugauslastung Regionalverkehr: VRR EFA via <a href="https://github.com/derf/eva-to-efa-gw">eva-to-efa-gw</a></li> +		<li>Nah-, Regional- und Fernverkehr im In- und Ausland: MOTIS via <a href="https://finalrewind.org/projects/Travel-Status-MOTIS/">Travel::Status::MOTIS</a> +		<strong>v<%= $Travel::Status::MOTIS::VERSION %></strong></li>  		</ul>  	</p>  	<p> -		Unterstützte HAFAS-Instanzen („hafas=…“): -		<ul> -		% for my $service (Travel::Status::DE::HAFAS::get_services()) { -			<li><%= $service->{shortname} %> (<%= $service->{name} %>)</li> -		% } -		</ul> -	</p> -	<p> -		Verwendete Open Data-Ressourcen: +		Verwendete Ressourcen:  		<ul> +		<li><a href="/_backend">HAFAS-Backends</a> via <a href="https://github.com/public-transport/transport-apis">transport-apis</a>, CC0</li>  		<li><a href="https://data.deutschebahn.com/dataset/zugbildungsplanzugbildungsplan-zpar">Zugbildungsplan</a> © DB Fernverkehr AG, lizensiert unter CC-BY 4.0</li>  		<li><a href="http://data.deutschebahn.com/dataset/data-haltestellen">Haltestellenliste</a>  		© DB Station&Service AG, @@ -49,6 +41,12 @@  		© DB Fernverkehr AG, lizensiert unter CC-BY 4.0; Abbildungen © Seemanngrafik d.i.p. im Auftrag der Deutschen Bahn AG, lizensiert unter CC-BY-SA 4.0</li>  		</ul>  	</p> +	<p> +		Trivia: Das Projekt begann als „db-fakedisplay“ (kurz dbf) zur +		Nachahmung von Bahnhofs-Abfahrtstafeln. Inzwischen liegt der Fokus auf +		der Bereitstellung von Informationen für mobile und Desktop-Anwendungen +		und die Bezeichnung DBF wurde zum Eigennamen ohne weitere Bedeutung. +	</p>  </div>  % if (-e 'templates/imprint.html.ep') { diff --git a/templates/app.html.ep b/templates/app.html.ep index 50f8a5a..8b52c61 100644 --- a/templates/app.html.ep +++ b/templates/app.html.ep @@ -30,7 +30,7 @@  %     $route_str .= $stop . ($via_cur < $via_max ? ' - ' : q{});  %   }      <li -% if (param('hafas')) { +% if (param('dbris') or param('hafas') or param('efa')) {        data-jid="<%= $departure->{journey_id} =~ s{#}{%23}gr %>"  % }        data-train="<%= ($departure->{train_type} // q{}) %> <%= ($departure->{train_no} // $departure->{train} // q{}) %>" @@ -53,12 +53,23 @@        >  %   }  %   if (param('hafas')) { -      <a href="/z/<%= Mojo::Util::url_escape($departure->{journey_id}) . '?hafas=1&highlight=' .  Mojo::Util::url_escape($departure->{station} // $station) %>"> +      <a href="/z/<%= Mojo::Util::url_escape($departure->{journey_id}) . '?hafas=' . Mojo::Util::url_escape(param('hafas')) . '&highlight=' .  Mojo::Util::url_escape($departure->{station} // $station) %>"> +%   } +%   elsif (param('efa')) { +      <a href="/z/<%= Mojo::Util::url_escape($departure->{journey_id}) . '?efa=' . Mojo::Util::url_escape(param('efa')) . '&highlight=' .  Mojo::Util::url_escape($departure->{station} // $station) %>"> +%   } +%   elsif (param('dbris')) { +      <a href="/z/<%= Mojo::Util::url_escape($departure->{journey_id}) . '?dbris=' . Mojo::Util::url_escape(param('dbris')) . '&highlight=' .  Mojo::Util::url_escape($departure->{station} // $station) %>">  %   }  %   else {        <a href="/z/<%= Mojo::Util::url_escape(($departure->{train_type} // q{}) . ' ' . ($departure->{train_no} // $departure->{train} // q{})) . '/' .  Mojo::Util::url_escape($departure->{station} // $station) %>">  %   } -    <div class="anchor" id="<%= ($departure->{train_type} // q{x}) . ($departure->{train_no} // q{x}) %>"></div> +%   if (param('dbris') or param('hafas')) { +      <div class="anchor" id="<%= $departure->{journey_id} =~ s{[ #|]}{x}gr %>"></div> +%   } +%   else { +      <div class="anchor" id="<%= ($departure->{train_type} // q{x}) . ($departure->{train_no} // q{x}) %>"></div> +%   }      <div class="line <%= $departure->{linetype} %>">      % if ($departure->{train_type} and $departure->{train_no}) {  %=    $departure->{train_type} @@ -100,15 +111,14 @@  %=      $departure->{origin}        </span>  %   } -    <span class="time <%= ($show_realtime and $departure->{delay} and not -      $departure->{is_cancelled}) ? 'delayed' : q{} %>"> -%     if ($departure->{delay} and not $departure->{is_cancelled}) { -%       if ($show_realtime) { +    <span class="time <%= $show_realtime ? get_rt_time_class($departure) : q{} %>"> +%     if ($departure->{delay} and not $departure->{is_cancelled} and not $departure->{departure_is_cancelled}) { +%       if ($show_realtime and ($departure->{sched_arrival} or $departure->{sched_departure})) {  %         if ($departure->{delay} > ($hide_low_delay ? 4 : 0)) { -            <span class="delaynorm" aria-hidden="true">+<%= $departure->{delay} %> ⇒</span> +            <span class="delaynorm" aria-hidden="true"><%= $departure->{sched_departure} // $departure->{sched_arrival} %> ⇒</span>  %         }  %         elsif ($departure->{delay} < 0) { -            <span class="undelaynorm" aria-hidden="true"><%= $departure->{delay} %> ⇒</span> +            <span class="undelaynorm" aria-hidden="true"><%= $departure->{sched_departure} // $departure->{sched_arrival} %> ⇒</span>  %         }  %       }  %       else { @@ -140,7 +150,12 @@  %       }  %     }  %     else { -%=      $departure->{time} +%       if ($departure->{is_cancelled} or $departure->{departure_is_cancelled}) { +%=        $departure->{sched_departure} // $departure->{sched_arrival} // $departure->{time} +%       } +%       else { +%=        $departure->{time} +%       }  %     }      </span>  %   if (($departure->{scheduled_platform} and $departure->{platform} and @@ -151,6 +166,18 @@  %   else {        <span class="platform">  %   } +%   if ($departure->{load}{FIRST} or $departure->{load}{SECOND}) { +%     my ($text, $icon1, $icon2) = utilization_icon([$departure->{load}{FIRST}, $departure->{load}{SECOND}]); +      <span class="load"> +        <i class="material-icons" style="vertical-align: bottom;" aria-hidden="true"><%= $icon2 %></i> +      </span> +%   } +%   elsif (my $o = $departure->{occupancy}) { +      <span class="load"> +%       my ($text, $icon) = occupancy_icon($o); +        <i class="material-icons" style="vertical-align: bottom;" aria-hidden="true"><%= $icon %></i> +      </span> +%   }      <span class="visually-hidden">Gleis</span>  %=  $departure->{platform}      </span> diff --git a/templates/coverage_map.html.ep b/templates/coverage_map.html.ep new file mode 100644 index 0000000..bd3d94c --- /dev/null +++ b/templates/coverage_map.html.ep @@ -0,0 +1,22 @@ +<div class="container"> +	Das <%= $backend %>-Backend „<%= $service %>“ liefert ungefähr innerhalb +	der folgenden grob umrissenen Region voraussichtlich nützliche Echtzeitdaten. +</div> + +<div class="container"> +	<div id="map" style="height: 70vh;"> +	</div> +</div> + +<script> +const map = L.map('map').setView([51.306, 9.712], 6); + +L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { +  attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' +}).addTo(map); + +const coverage = L.geoJSON(<%== $coverage %>); + +coverage.addTo(map); +map.fitBounds(coverage.getBounds()); +</script> diff --git a/templates/exception.html.ep b/templates/exception.html.ep index 65ec7ff..7654c0b 100644 --- a/templates/exception.html.ep +++ b/templates/exception.html.ep @@ -5,7 +5,7 @@ Beim Bearbeiten der Anfrage ist ein Fehler aufgetreten.<br/>  <pre>  ----------[Debug start]----------  % if ($exception) { -%= $exception->message +%= ref($exception) ? $exception->message : $exception  Stash:  %= dumper $snapshot  % } diff --git a/templates/landingpage.html.ep b/templates/landingpage.html.ep index 17bb2bb..80fd34f 100644 --- a/templates/landingpage.html.ep +++ b/templates/landingpage.html.ep @@ -12,8 +12,9 @@  % }  % else {    <p> -    DBF ist ein inoffizieller Abfahrtsmonitor für den Regional- und Fernverkehr mit dem Ziel, Daten aus verschiedenen Quellen übersichtlich zusammenzutragen. -    Der Fokus liegt auf Zügen im Netz der Deutschen Bahn; eingeschränkte Unterstützung für Nahverkehr und Züge in anderen Netzen lässt sich optional zuschalten. +    DBF ist ein inoffizieller Abfahrtsmonitor für Nah-, Regional- und Fernverkehr in Deutschland und Umgebung mit dem Ziel, Daten aus verschiedenen Quellen zusammenzutragen. +    Es unterstützt neben Fahrten im Netz der DB InfraGO diverse Nah- und Fernverkehrsunternehmen mit EFA- und HAFAS-Backends. +    Die Fahrten in der Übersicht verlinken je eine Detailseite mit Unterwegshalten, Meldungen und Kartendarstellung.    </p>    <p>      Diese Seite ist ein kostenfreies, privat betriebenes Projekt ohne Verfügbarkeitsgarantie. @@ -21,10 +22,10 @@    </p>  % }  <p class="geolink"> -<a class="button" href="<%= url_for('_autostop')->to_abs->scheme('https')->query({hafas => param('hafas')}) %>">Stationen in der Umgebung suchen</a> +<a class="button" href="<%= url_for('_autostop')->to_abs->scheme('https')->query({efa => param('efa'), hafas => param('hafas')}) %>">Stationen in der Umgebung suchen</a>  </p>  <p> -Oder hier angeben: +Oder hier eine Station angeben:  </p>  </div>  % } diff --git a/templates/layouts/app.html.ep b/templates/layouts/app.html.ep index 1578298..c557bee 100644 --- a/templates/layouts/app.html.ep +++ b/templates/layouts/app.html.ep @@ -4,8 +4,8 @@  	<title><%= stash('title') // 'DBF' %></title>  	<meta charset="utf-8">  	<meta name="viewport" content="width=device-width, initial-scale=1.0"> -	<meta name="keywords" content="Abfahrtsmonitor, Bahnhofstafel, Abfahrten, Abfahrtstafel, ICE, IC, RE, RB, S-Bahn"> -	<meta name="description" content="<%= stash('description') // 'Inoffizieller Abfahrtsmonitor für innerdeutsche Zugfahrten' %>"> +	<meta name="keywords" content="Abfahrtsmonitor, Bahnhofstafel, Abfahrten, Abfahrtstafel, Nahverkehr, Regionalverkehr, Fernverkehr, ICE, IC, RE, RB, S-Bahn"> +	<meta name="description" content="<%= stash('description') // 'Inoffizieller Abfahrtsmonitor für Nah-, Reginol- und Fernverkehr' %>">  	<meta name="theme-color" content="#00838f">  	<link rel="icon" type="image/png" href="/static/icons/icon-16x16.png" sizes="16x16">  	<link rel="icon" type="image/png" href="/static/icons/icon-32x32.png" sizes="32x32"> @@ -18,7 +18,7 @@  	<meta http-equiv="refresh" content="<%= $self->stash('refresh_interval') %>"/>  % } -	% my $av = 'v96'; # asset version +	% my $av = 'v110'; # asset version  	% if (session('theme') and session('theme') eq 'dark' or param('dark')) {  		%= stylesheet "/static/${av}/css/dark.min.css", id => 'theme'  	% } @@ -117,43 +117,36 @@ Bitte eine Station aus der Liste auswählen</div>  %= form_for _redirect => begin +%= hidden_field efa => param('efa')  %= hidden_field hafas => param('hafas')  <div>    <div class="field"> -    <div class="desc">Zug / Station</div> -    <div> -% if (stash('stationlist')) { +%   if (stash('stationlist')) {        %= select_field input => stash('stationlist') -% } -% elsif (stash('input')) { -      %= text_field 'input', class => 'station', placeholder => 'Zug, Stationsname oder Ril100-Kürzel', id => 'stationinput' -% } -% else { -      %= text_field 'input', class => 'station', placeholder => 'Zug, Stationsname oder Ril100-Kürzel', id => 'stationinput', autofocus => 'autofocus' -% } -    </div> +%   } +%   elsif (stash('input')) { +      %= text_field 'input', class => 'station', placeholder => 'Stationsname oder Fahrtnummer', id => 'stationinput' +%   } +%   else { +      %= text_field 'input', class => 'station', placeholder => 'Stationsname oder Fahrtnummer', id => 'stationinput', autofocus => 'autofocus' +%   }    </div>    <div class="field">      %= submit_button 'Abfahrtstafel'    </div>    % if (stash('input')) {      <div class="geolink"> -      <a class="button" href="<%= url_for('_autostop')->to_abs->scheme('https')->query({hafas => param('hafas')}) %>">Stationen in der Umgebung suchen</a> +      <a class="button" href="<%= url_for('_autostop')->to_abs->scheme('https')->query({efa => param('efa'), hafas => param('hafas')}) %>">Stationen in der Umgebung suchen</a>      </div>    % } +  <div class="backendlink"> +    <a class="button button-light" href="<%= url_for('_backend')->query({efa => param('efa'), hafas => param('hafas')}) %>">Backend: <%= param('efa') ? param('efa') . ' (EFA)' : param('hafas') ? param('hafas') . ' (HAFAS)' : 'DB (IRIS-TTS)' %></a> +  </div>    <div class="break"></div>    <div class="moresettings-header moresettings-header-collapsed button button-light">Weitere Einstellungen</div>    <div class="moresettings moresettings-collapsed">      <div class="field">        <div class="desc"> -        %= check_box 'rt' => 1, id => 'id_show_realtime' -        <label for="id_show_realtime"> -          Zeiten inkl. Verspätung angeben -        </label> -      </div> -    </div> -    <div class="field"> -      <div class="desc">          %= check_box 'hidelowdelay' => 1, id => 'id_hidelowdelay'          <label for="id_hidelowdelay">            Verspätungen erst ab 5 Minuten anzeigen @@ -170,17 +163,9 @@ Bitte eine Station aus der Liste auswählen</div>      </div>      <div class="field">        <div class="desc"> -        %= check_box 'no_related' => 1, id => 'id_no_related' -        <label for="id_no_related"> -          Betriebliche Bahnhofstrennungen berücksichtigen (z.B. "Hbf (Fern+Regio)" vs. "Hbf (S)") -        </label> -      </div> -    </div> -    <div class="field"> -      <div class="desc">          %= check_box 'past' => 1, id => 'past'          <label for="past"> -          Bereits abgefahrene Züge anzeigen +          Fahrten der vergangenen 60 Minuten zeigen          </label>        </div>      </div> @@ -194,7 +179,7 @@ Bitte eine Station aus der Liste auswählen</div>      </div>      <div class="field">        <div class="desc"> -        Nur Züge über +        Nur Fahrten über        </div>        <div>          %= text_field 'via', placeholder => 'Bahnhof 1, Bhf2, ... (oder regulärer Ausdruck)', class => 'station' @@ -270,21 +255,22 @@ Bitte eine Station aus der Liste auswählen</div>            (z.B. als alleinstehender Infoscreen) gibt es den "Infoscreen"-Modus.</li>          <li>Die Abfahrtstafel unterstützt Namen, EVA-IDs, und (im IRIS-Backend)            DS100/Ril100-Codes zur Identifikation von Stationen.</li> -        <li>Zugdetails können optional für spezifische Abfahrtsdaten im +        <li>Abfahrten werden mit Echtzeitdaten bzw. Prognosen angegeben und +          danach sortiert. Mit dem Parameter +          <span style="font-family: monospace;">rt=0</span> wwerden stattdessen +          Plandaten angegeben und zur Sortierung genutzt.</li> +        <li>Bei HAFAS-Backends können optional Details für spezifische Fahrten im            DD.MM.[YYYY]-Format abgefragt werden, z.B. "ICE 921 (1.1.)" oder            "ICE 921 @ 1.1.". Das Datum bezieht sich auf die geplante -          Abfahrtszeit am Startbahnhof der Zugfahrt.</li> -        <li>Die Parameter <span style="font-family: monospace;">mode=json&version=3</span> -          (alternativ <span style="font-family: -          monospace;">https://dbf.finalrewind.org/Bahnhofsname.json?version=3</span>) -          bieten ein JSON-IRIS-Interface. Die route-Elemente können zusätzlich -          die Felder "isAdditional" oder "isCancelled" enthalten, der Rest sollte -          selbsterklärend sein. Im Fehlerfall fehlt das "departures"-Element, -          stattdessen wird ein "error"-Element mit Fehlermeldung zurückgegeben. -          Bitte maximal 30 Anfragen pro Minute und insbesondere nur eine Anfrage +          Abfahrtszeit am Startbahnhof der Fahrt.</li> +        <li>Viele Seiten sind auch als JSON verfügbar, wahlweise mittels +          <span style="font-family: monospace;">Accept: application/json</span> oder +          durch <span style="font-family: monospace;">.json</span> in der URL. +          HAFAS- und IRIS-Abfahrtstafeln liefern mit dem GET-Parameter <span style="font-family: monospace;">version=3</span> eine stabile JSON-API. +          Alle anderen Endpunkte (sowie Abfahrtstafeln mit <span style="font-family: monospace;">version=raw</span>) erlauben direkten Zugriff auf die serialisierten Travel::Status::DE::{EFA,HAFAS,IRIS}-Objekte ohne stabile API.</li> +        <li>Bitte maximal 30 Anfragen pro Minute und insbesondere nur eine Anfrage            pro Station und Minute – eine höhere Auflösung haben die Backenddaten            ohnehin nicht.</li> -        <li>Ein JSON-Interface für Zugdetails ist in Arbeit.</li>          <li>Mit <span style="font-family: monospace;">limit</span> kann die Anzahl der            angezeigten / im JSON enthaltenen Abfahrten eingeschränkt werden, z.B.            <span style="font-family: monospace;">limit=10</span> für die ersten zehn.</li> @@ -302,7 +288,7 @@ Bitte eine Station aus der Liste auswählen</div>  <div class="container">  <div class="config">  Farbschema: -<a onClick="javascript:setTheme('light')">light</a> +<a onClick="javascript:setTheme('light')">hell</a>  ·  <a onClick="javascript:setTheme('dark')">dunkel</a>  · @@ -315,7 +301,11 @@ Farbschema:  ·  <a onClick="javascript:setLang('default')">system language</a>  --> -</div> +</div> <!-- config --> +</div> <!-- container --> +% } +% if (not stash('hide_footer')) { +<div class="container">  <div class="about">  <a href="_about">DBF</a> v<%= stash('version') // '???' %>  · diff --git a/templates/layouts/legacy.html.ep b/templates/layouts/legacy.html.ep index 43a3cc5..e7e59ec 100644 --- a/templates/layouts/legacy.html.ep +++ b/templates/layouts/legacy.html.ep @@ -17,7 +17,7 @@  	<meta http-equiv="refresh" content="<%= $self->stash('refresh_interval') %>"/>  % } -	% my $av = 'v96'; # asset version +	% my $av = 'v110'; # asset version  	%= stylesheet "/static/${av}/css/legacy.css"  	%= stylesheet "/static/${av}/css/material-icons.css"  	%= stylesheet "/static/${av}/css/jquery-ui.min.css" @@ -62,169 +62,5 @@ Bitte eine Station aus der Liste auswählen</div>  %= content  </div> -% if (not stash('hide_opts')) { -<div class="container"> -<div class="input-field"> - - -%= form_for _redirect => begin -<div> -  <div class="field"> -    <div class="desc">Bahnhof / Haltestelle</div> -    <div> -% if (stash('stationlist')) { -      %= select_field input => stash('stationlist') -% } -% elsif (stash('input')) { -      %= text_field 'input', class => 'station', placeholder => 'Name oder Ril100-Kürzel' -% } -% else { -      %= text_field 'input', class => 'station', placeholder => 'Name oder Ril100-Kürzel', autofocus => 'autofocus' -% } -    </div> -  </div> -  <div class="field"> -    %= submit_button 'Abfahrtsmonitor' -  </div> -  % if (not stash('show_intro')) { -    <div class="break"></div> -    <div class="field"> -      <a class="button" href="<%= url_for('_autostop')->to_abs->scheme('https') %>">Bahnhöfe im Umfeld suchen</a> -    </div> -  % } -  <div class="break"></div> -  <div class="moresettings-header moresettings-header-collapsed button button-light">Weitere Einstellungen</div> -  <div class="moresettings moresettings-collapsed"> -    <div class="field"> -      <div class="desc"> -        Frontend -      </div> -      <div> -        %= select_field mode => [ ['App' => 'app'], ['Infoscreen' => 'infoscreen'], ['Bahnhofstafel' => 'multi'], ['Gleisanzeiger' => 'single'] ] -      </div> -    </div> -    <div class="field"> -      <div class="desc"> -        Nur Züge über -      </div> -      <div> -        %= text_field 'via', placeholder => 'Bahnhof 1, Bhf2, ... (oder regulärer Ausdruck)', class => 'station' -      </div> -    </div> -    <div class="field"> -      <div class="desc"> -        Gleise -      </div> -      <div> -        %= text_field 'platforms', placeholder => '1, 2, 5, ...' -      </div> -    </div> -    <div class="field"> -      <div class="desc"> -        %= check_box 'hidelowdelay' => 1, id => 'id_hidelowdelay' -        <label for="id_hidelowdelay"> -          Nur Verspätungen >5 Min. anzeigen -        </label> -      </div> -    </div> -    <div class="field"> -      <div class="desc"> -        %= check_box 'dark' => 1, id => 'id_dark' -        <label for="id_dark"> -          Dunkles Layout (experimentell) -        </label> -      </div> -    </div> -    <div class="field"> -      <div class="desc"> -        %= check_box 'hide_opts' => 1, id => 'id_hide_opts' -        <label for="id_hide_opts"> -          Formular verstecken (für Infoscreens) -        </label> -      </div> -    </div> -    <div class="field"> -      <div class="desc"> -        Ankunfts- oder Abfahrtszeit anzeigen? -      </div> -      <div> -        %= select_field admode => [['Abfahrt bevorzugen' => 'deparr'], ['Nur Abfahrt' => 'dep'], ['Nur Ankunft' => 'arr']] -      </div> -    </div> -    <div class="field"> -      <div class="desc"> -        %= check_box 'detailed' => 1, id => 'id_detailed' -        <label for="id_detailed"> -          Mehr Details (Zugnummern und Ankunftszeiten) anzeigen -        </label> -      </div> -    </div> -    <div class="field"> -      <div class="desc"> -        %= check_box 'rt' => 1, id => 'id_show_realtime' -        <label for="id_show_realtime"> -          Echtzeitangaben statt Fahrplandaten anzeigen -        </label> -      </div> -    </div> -    <div class="field"> -      <div class="desc"> -        %= check_box 'no_related' => 1, id => 'id_no_related' -        <label for="id_no_related"> -        Betriebliche Bahnhofstrennungen berücksichtigen (z.B. "Hbf (Fern+Regio)" vs. "Hbf (S)") -        </label> -      </div> -    </div> -    <div class="field"> -      %= submit_button 'Anzeigen' -    </div> -  </div> <!-- moresettings --> -</div> -% end - -</div> <!-- input-field --> - -<div class="notes"> -  <div class="developers-header developers-header-collapsed button button-light">API- und Entwickler-Hinweise</div> -  <div class="developers developers-collapsed"> -    <ul> -      <li>Diese Seite kann gerne als iframe in eigene Infoscreens o.ä. eingebunden werden. -	Für eine kleine Ansicht (z.B. iframe in einer normalen Website) bitte das -	"App"-Frontend verwenden. Für eine große Ansicht -	(z.B. als alleinstehender Infoscreen) gibt es das "Infoscreen"-Frontend.</li> -      <li>Die Parameter <span style="font-family: monospace;">mode=json&version=3</span> -	(alternativ auch <span style="font-family: -	monospace;">https://dbf.finalrewind.org/Bahnhofsname.json?version=3</span>) -	bieten ein JSON-IRIS-Interface. Die route-Elemente können zusätzlich -	die Felder "isAdditional" oder "isCancelled" enthalten, der Rest sollte -	selbsterklärend sein. Im Fehlerfall fehlt das "departures"-Element, -	stattdessen wird ein "error"-Element mit Fehlermeldung zurückgegeben. -	Bitte nur eine Anfrage pro Station und Minute -	– eine höhere Auflösung haben die Backenddaten ohnehin nicht.</li> -      <li>Mit <span style="font-family: monospace;">limit</span> kann die Anzahl der -	angezeigten / im JSON enthaltenen Abfahrten eingeschränkt werden, z.B. -	<span style="font-family: monospace;">limit=10</span> für die ersten zehn.</li> -      <li>Dieser Dienst ist Open Source-Software (Links siehe unten) und kann auch -	auf eigenen Servern installiert werden. Automatisierte Crawler, die mehrere -	Dutzend Stationen pro Minute abfragen, bitte nur auf eigenen Instanzen -	betreiben.</li> -    </ul> -  </div> <!-- developers --> -</div> <!-- notes --> - -</div> <!-- container --> - -<div class="container"> -<div class="about"> -<a href="_about">Über DBF</a> -· -<a href="_datenschutz" rel="nofollow">Datenschutz</a> -· -<a href="_impressum" rel="nofollow">Impressum</a><br/> -Version <%= stash('version') // '???' %> -</div> <!-- about --> -</div> <!-- container --> -% } -  </body>  </html> diff --git a/templates/route_map.html.ep b/templates/route_map.html.ep index 447960a..e1c4642 100644 --- a/templates/route_map.html.ep +++ b/templates/route_map.html.ep @@ -3,7 +3,7 @@  % }  <div class="container"> -		<div id="map" style="height: 500px;"> +		<div id="map" style="height: 70vh;">  		</div>  	</div> @@ -79,18 +79,20 @@ var marker;  </script>  <div class="container" style="margin-top: 1ex; margin-bottom: 1ex; color: #555;"> -Die eingezeichnete Route stammt aus dem HAFAS und ist im Detail oft -fehlerbehaftet.<br/> -Die Zugposition auf der Karte ist eine DBF-eigene Schätzung und kann erheblich -von den tatsächlichen Gegebenheiten abweichen. +<p> +Die eingezeichnete Route stammt aus dem angefragten Backend und stimmt nicht +notwendigerweise mit der Realität überein. +Die Fahrzeugposition auf der Karte ist eine DBF-eigene Schätzung und kann +erheblich von den tatsächlichen Gegebenheiten abweichen.  % if (stash('intersection')) {  <br/>In dieser Ansicht sind Live-Updates der Zug- und Begegnungspositionen noch  nicht implementiert.  % } +</p>  </div>  % if (my $op = stash('operator')) {  <div class="container" style="margin-top: 1ex; margin-bottom: 1ex; color: #555;"> -Betrieb: <%= $op %> +<p>Betrieb: <%= $op %></p>  </div>  % } diff --git a/templates/select_backend.html.ep b/templates/select_backend.html.ep new file mode 100644 index 0000000..c6d2a4c --- /dev/null +++ b/templates/select_backend.html.ep @@ -0,0 +1,46 @@ +<div class="container"> +	<p> +		Das Backend bestimmt die Datenquelle für Stations- und Zuginformationen. +		Innerhalb Deutschlands ist <strong>Deutsche Bahn</strong> via IRIS-TTS eine gute Wahl für Schienenverkehr im Bahnnetz. +		Die anderen Backends bieten sich für Fahrten im zugehörigen Verkehrsverbund (inklusive Nahverkehr) sowie im Ausland an. +		Sofern bekannt sind unterhalb der Backend-Namen Karten verlinkt, die die ungefähre Abdeckung aufzeigen. +		Ein Backend, welches Nah- und Fernverkehr in ganz Deutschland abdeckt, ist aktuell leider nicht verfügbar. +	</p> +	<p> +		% my $prev_type = 'IRIS-TTS'; +		% for my $backend (@{$backends}) { +			<p> +			% if ($backend->{type} ne $prev_type) { +				% $prev_type = $backend->{type}; +				<%= $prev_type %>:<br/> +			% } +			% my $class = 'button'; +			% if (param('efa')) { +				% if ($backend->{efa} and $backend->{shortname} eq param('efa')) { +					% $class .= ' button-active'; +				% } +			% } +			% elsif (param('hafas')) { +				% if ($backend->{hafas} and $backend->{shortname} eq param('hafas')) { +					% $class .= ' button-active'; +				% } +			% } +			% else { +				% if (not ($backend->{efa} or $backend->{hafas})) { +					% $class .= ' button-active'; +				% } +			% } +			<a class="<%= $class %>" href="<%= url_for(q{/})->query({ efa => $backend->{efa} ? $backend->{shortname} : q{}, hafas => $backend->{hafas} ? $backend->{shortname} : q{} }) %>"><%= $backend->{shortname} // 'IRIS-TTS' %> – <%= $backend->{name} %></a> +			% if ($backend->{has_area}) { +				<a href="/coverage/<%= $backend->{type} %>/<%= $backend->{shortname} %>"><%= join(q{, }, @{$backend->{regions}}) || '[Karte]' %></a> +			% } +			% else { +				%= join(q{, }, @{$backend->{regions} // []}) +			% } +			% if ($backend->{homepage}) { +				(<a href="<%= $backend->{homepage} %>"><%= $backend->{homepage} =~ s{ ^ http s? :// (?: www[.] )? (.*?) (?: / )? $ }{$1}xr %></a>) +			% } +			</p> +		% } +	</p> +</div> diff --git a/templates/wagenreihung.html.ep b/templates/wagenreihung.html.ep index 493d9c6..19c49ab 100644 --- a/templates/wagenreihung.html.ep +++ b/templates/wagenreihung.html.ep @@ -1,64 +1,56 @@ -% if (not $wr or $wr->errstr) { +% if (not $wr or $wr_error) {    <div class="container">      <div class="error">        <strong>Fehler bei der Abfrage der Wagenreihung:</strong> -      <%= $wr ? $wr->errstr : $wr_error %> +      <%= $wr_error // 'Unbekannter Fehler' %>      </div>    </div>  % }  % else { -  % my $has_multi_dest = 0; -  % my $has_multi_desc = 0; -  % if (scalar $wr->destinations > 1) { -    % $has_multi_dest = 1; -  % } -  % if (scalar $wr->train_descriptions > 1) { -    % $has_multi_desc = 1; -  % }    <div class="container">      <div style="text-align: center;"> -%=    join( ' / ', $wr->origins ) -      → -%=    join( ' / ', map { $_->{name} } $wr->destinations ) +      Gleis <%= $wr->platform %><br/>      </div> -    % if ($has_multi_dest) { -      <div style="text-align: center;"> -        % for my $destination ($wr->destinations) { -          Nach <%= $destination->{name} %> in Abschnitt <%= join(q{}, sort @{$destination->{sections} // []}) %><br/> -       % } -      </div> -    % } -    <%= $wr->station_name %> Gleis <%= $wr->platform %><br/> -    % for my $desc ($wr->train_descriptions) { -      % if ($desc->{text}) { -        %= $desc->{text} -        % if ($has_multi_desc and length(join(q{}, sort @{$desc->{sections}}))) { -          in Abschnitt <%= join(q{}, sort @{$desc->{sections}}) %> -        % } -        <br/> -      % } -    % }    </div>    <div class="container">      <div class="wagonorder exit-<%= stash('exit_dir') // 'unknown'%>"> -%     if (not $wr->has_bad_wagons) { -%       for my $section ($wr->sections) { -          <div class="section" style=" -          top: <%= $section->{start_percent} %>%; bottom: <%= 100 - $section->{end_percent} %>%;"> -%=          $section->{name} -          </div> -%       } +%     for my $sector ($wr->sectors) { +        <div class="section" style=" +        top: <%= $sector->start_percent %>%; bottom: <%= 100 - $sector->end_percent %>%;"> +%=        $sector->name +        </div>  %     } -%     for my $wagon ($wr->wagons) { -%=      include '_wagon', direction => $wr->direction, wagon => $wagon, type => $wr->train_type, wref => $wref, exit_dir => stash('exit_dir'); +%     for my $group ($wr->groups) { +%       my $first = 1; +%       for my $wagon ($group->carriages) { +%=        include '_wagon', wr => $wr, group => $group, wagon => $wagon, first => $first, multi => (scalar $wr->destinations) - 1 + (scalar $wr->train_numbers) - 1, wref => $wref, exit_dir => stash('exit_dir'), train_no => param('number'); +%         $first = 0; +%       }  %     }        </div> +    % for my $group ($wr->groups) { +      % if ($group->description) { +        <div style="text-align: center;"> +          %= $group->description +          % if ($group->designation) { +            „<%= $group->designation %>“ +          % } +          % if (scalar $wr->groups > 1 and $group->has_sectors) { +            in Abschnitt <%= join(q{}, sort $group->sectors) %> +          % } +        </div> +      % } +    % } +      <div style="text-align: center;"> +        nach +%=      join( ' / ', map { $_->{name} } $wr->destinations ) +      </div>  <!--  <div>        Legende: ♿ Behindertengerechte Ausstattung / 🍴 Bistro/Restaurant / 🚪 Abteile vorhanden      </div>  -->      <p class="copyright"> -      Quelle: DB Wagenreihungs-API. Angaben ohne Gewähr. +      Quelle: DB Wagenreihungs-API (<%= stash('ts') // q{} %>). Angaben ohne Gewähr.      </p>    </div>  | 
