summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/DBInfoscreen/Controller/Stationboard.pm108
-rw-r--r--public/static/default.css12
-rw-r--r--templates/_train_details.html.ep84
3 files changed, 145 insertions, 59 deletions
diff --git a/lib/DBInfoscreen/Controller/Stationboard.pm b/lib/DBInfoscreen/Controller/Stationboard.pm
index 0d1cbb7..32ca5e9 100644
--- a/lib/DBInfoscreen/Controller/Stationboard.pm
+++ b/lib/DBInfoscreen/Controller/Stationboard.pm
@@ -6,9 +6,11 @@ use Mojo::Base 'Mojolicious::Controller';
use Cache::File;
use DateTime;
+use Encode qw(decode encode);
use File::Slurp qw(read_file write_file);
use List::Util qw(max);
use List::MoreUtils qw();
+use Mojo::JSON qw(decode_json);
use Travel::Status::DE::HAFAS;
use Travel::Status::DE::IRIS;
use Travel::Status::DE::IRIS::Stations;
@@ -99,6 +101,94 @@ sub log_api_access {
return;
}
+sub hafas_json_req {
+ my ( $ua, $cache, $url ) = @_;
+
+ if ( my $content = $cache->thaw($url) ) {
+ return decode_json( ${$content} );
+ }
+
+ my $res = $ua->get($url)->result;
+
+ if ( $res->is_error ) {
+ return;
+ }
+
+ my $body = encode( 'utf-8', decode( 'ISO-8859-15', $res->body ) );
+
+ $body =~ s{^TSLs[.]sls = }{};
+ $body =~ s{;$}{};
+ $body =~ s{(}{(}g;
+ $body =~ s{)}{)}g;
+
+ $cache->freeze( $url, \$body );
+
+ return decode_json($body);
+}
+
+# quick&dirty, will be cleaned up later
+sub get_route_timestamps {
+ my ( $ua, $train ) = @_;
+
+ my $cache_iris_main = Cache::File->new(
+ cache_root => $ENV{DBFAKEDISPLAY_IRIS_CACHE} // '/tmp/dbf-iris-main',
+ default_expires => '6 hours',
+ lock_level => Cache::File::LOCK_LOCAL(),
+ );
+
+ $ua->request_timeout(3);
+
+ my $base
+ = 'https://reiseauskunft.bahn.de/bin/trainsearch.exe/dn?L=vs_json.vs_hap&start=yes&rt=1';
+ my $date_yy = $train->start->strftime('%d.%m.%y');
+ my $date_yyyy = $train->start->strftime('%d.%m.%Y');
+ my $train_no = $train->type . ' ' . $train->train_no;
+
+ my $trainsearch = hafas_json_req( $ua, $cache_iris_main,
+ "${base}&date=&${date_yy}&trainname=${train_no}" );
+
+ if ( not $trainsearch ) {
+ return;
+ }
+
+ # Fallback: Take first result
+ my $trainlink = $trainsearch->{suggestions}[0]{trainLink};
+
+ # Try finding a result for the current date
+ for my $suggestion ( @{ $trainsearch->{suggestions} // [] } ) {
+
+ # Drunken API, sail with care. Both date formats are used interchangeably
+ if ( $suggestion->{depDate} eq $date_yy
+ or $suggestion->{depDate} eq $date_yyyy )
+ {
+ $trainlink = $suggestion->{trainLink};
+ last;
+ }
+ }
+
+ if ( not $trainlink ) {
+ return;
+ }
+
+ $base = 'https://reiseauskunft.bahn.de/bin/traininfo.exe/dn';
+
+ my $traininfo = hafas_json_req( $ua, $cache_iris_main,
+ "${base}/${trainlink}?rt=1&date=${date_yy}&L=vs_json.vs_hap" );
+
+ if ( not $traininfo or $traininfo->{error} ) {
+ return;
+ }
+
+ my $ret = {};
+
+ for my $station ( @{ $traininfo->{suggestions}[0]{locations} // [] } ) {
+ $ret->{ $station->{name} }
+ = [ $station->{arrTime}, $station->{depTime} ];
+ }
+
+ return $ret;
+}
+
sub get_results_for {
my ( $backend, $station, %opt ) = @_;
my $data;
@@ -735,9 +825,8 @@ sub handle_request {
}
);
if ( $self->param('train') ) {
- $departures[-1]{scheduled_route} = [ $result->sched_route ];
- $departures[-1]{route_pre} = [ $result->route_pre ];
- $departures[-1]{route_pre_diff} = [
+ $departures[-1]{route_pre} = [ $result->route_pre ];
+ $departures[-1]{route_pre_diff} = [
$self->json_route_diff(
[ $result->route_pre ],
[ $result->sched_route_pre ]
@@ -750,6 +839,19 @@ sub handle_request {
[ $result->sched_route_post ]
)
];
+ my $route_ts = get_route_timestamps( $self->ua, $result );
+ if ($route_ts) {
+ for my $elem (
+ @{ $departures[-1]{route_pre_diff} },
+ @{ $departures[-1]{route_post_diff} }
+ )
+ {
+ if ( exists $route_ts->{ $elem->{name} } ) {
+ $elem->{arr} = $route_ts->{ $elem->{name} }[0];
+ $elem->{dep} = $route_ts->{ $elem->{name} }[1];
+ }
+ }
+ }
}
}
else {
diff --git a/public/static/default.css b/public/static/default.css
index 0ca02b0..d67ce35 100644
--- a/public/static/default.css
+++ b/public/static/default.css
@@ -242,18 +242,6 @@ div.app .moreinfo .timeinfo {
margin-bottom: 0.6em;
}
-div.app .moreinfo .mroute {
- margin-bottom: 0.6em;
-}
-
-div.applight .moreinfo .mroute .separator {
- color: #999999;
-}
-
-div.appdark .moreinfo .mroute .separator {
- color: #999999;
-}
-
div.applight .moreinfo .mroute .important-stop {
color: #000000;
}
diff --git a/templates/_train_details.html.ep b/templates/_train_details.html.ep
index b1dfd13..cdadaa0 100644
--- a/templates/_train_details.html.ep
+++ b/templates/_train_details.html.ep
@@ -80,15 +80,40 @@
% }
% }
+% if ($departure->{moreinfo} and @{$departure->{moreinfo}}) {
+ Meldungen:
+ <ul>
+% for my $pair (@{$departure->{moreinfo}}) {
+ <li>
+% if ($pair->[0]->isa('DateTime')) {
+% if ($pair->[0]->day != $dt_now->day) {
+% $pair->[0]->set_locale('de_DE');
+%= $pair->[0]->strftime('%a %H:%M')
+% }
+% else {
+%= $pair->[0]->strftime('%H:%M')
+% }
+% }
+% else {
+%= $pair->[0]
+% }
+ :
+ <span class="reason">
+%= $pair->[1]
+ </span>
+ </li>
+% }
+% if ($departure->{route_info}) {
+ <li><%= $departure->{route_info} %></li>
+% }
+ </ul>
+% }
% if ($departure->{route_pre_diff} and $departure->{route_post_diff}) {
% if (@{$departure->{route_pre_diff}}) {
- <div class="mroute">
- Von:
-% my $first = 0;
+ Von:
+ <ul class="mroute">
% for my $stop (@{$departure->{route_pre_diff}}) {
-% if ($first++) {
- <span class="separator">–</span>
-% }
+ <li>
<a href="/<%= $stop->{name} %>#<%= $departure->{train_type} . $departure->{train_no} %>" class="
% if ($stop->{isAdditional}) {
additional-stop
@@ -102,18 +127,16 @@
% else {
generic-stop
% }
- "><%= $stop->{name} %></a>
+ "><%= $stop->{dep} // q{} %> <%= $stop->{name} %></a>
+ </li>
% }
- </div> <!-- mroute -->
+ </ul> <!-- mroute -->
% }
% if (@{$departure->{route_post_diff}}) {
- <div class="mroute">
- Nach:
-% my $first = 0;
+ Nach:
+ <ul class="mroute">
% for my $stop (@{$departure->{route_post_diff}}) {
-% if ($first++) {
- <span class="separator">–</span>
-% }
+ <li>
<a href="/<%= $stop->{name} %>#<%= $departure->{train_type} . $departure->{train_no} %>" class="
% if ($stop->{isAdditional}) {
additional-stop
@@ -127,37 +150,10 @@
% else {
generic-stop
% }
- "><%= $stop->{name} %></a>
+ "><%= $stop->{arr} // q{} %> <%= $stop->{name} %></a>
+ </li>
% }
- </div> <!-- mroute -->
+ </ul> <!-- mroute -->
% }
% }
-% if ($departure->{moreinfo} and @{$departure->{moreinfo}}) {
- Meldungen:
- <ul>
-% for my $pair (@{$departure->{moreinfo}}) {
- <li>
-% if ($pair->[0]->isa('DateTime')) {
-% if ($pair->[0]->day != $dt_now->day) {
-% $pair->[0]->set_locale('de_DE');
-%= $pair->[0]->strftime('%a %H:%M')
-% }
-% else {
-%= $pair->[0]->strftime('%H:%M')
-% }
-% }
-% else {
-%= $pair->[0]
-% }
- :
- <span class="reason">
-%= $pair->[1]
- </span>
- </li>
-% }
-% if ($departure->{route_info}) {
- <li><%= $departure->{route_info} %></li>
-% }
- </ul>
-% }
</div> <!-- mfooter -->