diff options
-rw-r--r-- | lib/DBInfoscreen/Controller/Stationboard.pm | 108 | ||||
-rw-r--r-- | public/static/default.css | 12 | ||||
-rw-r--r-- | templates/_train_details.html.ep | 84 |
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 --> |