diff options
Diffstat (limited to 'lib/DBInfoscreen.pm')
-rw-r--r-- | lib/DBInfoscreen.pm | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/lib/DBInfoscreen.pm b/lib/DBInfoscreen.pm new file mode 100644 index 0000000..af952c2 --- /dev/null +++ b/lib/DBInfoscreen.pm @@ -0,0 +1,249 @@ +package DBInfoscreen; +use Mojo::Base 'Mojolicious'; + +# Copyright (C) 2011-2019 Daniel Friesel <derf+dbf@finalrewind.org> +# License: 2-Clause BSD + +use Travel::Status::DE::HAFAS; +use Travel::Status::DE::HAFAS::StopFinder; +use Travel::Status::DE::IRIS::Stations; + +use utf8; + +no if $] >= 5.018, warnings => 'experimental::smartmatch'; + +our $VERSION = qx{git describe --dirty} || '0.05'; + +my %default = ( + backend => 'iris', + mode => 'app', + admode => 'deparr', +); + +sub startup { + my ($self) = @_; + + $self->helper( + 'handle_no_results' => sub { + my ( $self, $backend, $station, $errstr ) = @_; + + if ( $backend eq 'ris' ) { + my $db_service = Travel::Status::DE::HAFAS::get_service('DB'); + my $sf = Travel::Status::DE::HAFAS::StopFinder->new( + url => $db_service->{stopfinder}, + input => $station, + ); + my @candidates + = map { [ $_->{name}, $_->{id} ] } $sf->results; + if ( @candidates > 1 + or ( @candidates == 1 and $candidates[0][1] ne $station ) ) + { + $self->render( + 'landingpage', + stationlist => \@candidates, + hide_opts => 0 + ); + return; + } + } + if ( $backend eq 'iris' ) { + my @candidates = map { [ $_->[1], $_->[0] ] } + Travel::Status::DE::IRIS::Stations::get_station($station); + if ( @candidates > 1 + or ( @candidates == 1 and $candidates[0][1] ne $station ) ) + { + $self->render( + 'landingpage', + stationlist => \@candidates, + hide_opts => 0 + ); + return; + } + } + $self->render( + 'landingpage', + error => ( $errstr // "Got no results for '$station'" ), + hide_opts => 0 + ); + return; + } + ); + + $self->helper( + 'handle_no_results_json' => sub { + my ( $self, $backend, $station, $errstr, $api_version, $callback ) + = @_; + + $self->res->headers->access_control_allow_origin(q{*}); + my $json; + if ($errstr) { + $json = $self->render_to_string( + json => { + api_version => $api_version, + version => $VERSION, + error => $errstr, + } + ); + } + else { + my @candidates = map { { code => $_->[0], name => $_->[1] } } + Travel::Status::DE::IRIS::Stations::get_station($station); + if ( @candidates > 1 + or + ( @candidates == 1 and $candidates[0]{code} ne $station ) ) + { + $json = $self->render_to_string( + json => { + api_version => $api_version, + version => $VERSION, + error => 'ambiguous station code/name', + candidates => \@candidates, + } + ); + } + else { + $json = $self->render_to_string( + json => { + api_version => $api_version, + version => $VERSION, + error => + ( $errstr // "Got no results for '$station'" ) + } + ); + } + } + if ($callback) { + $self->render( + data => "$callback($json);", + format => 'json' + ); + } + else { + $self->render( + data => $json, + format => 'json' + ); + } + return; + } + ); + + $self->helper( + 'is_important' => sub { + my ( $self, $stop ) = @_; + + # Centraal: dutch main station (Hbf in .nl) + # HB: swiss main station (Hbf in .ch) + # hl.n.: czech main station (Hbf in .cz) + if ( $stop =~ m{ HB $ | hl\.n\. $ | Hbf | Centraal | Flughafen }x ) + { + return 1; + } + return; + } + ); + + $self->helper( + 'json_route_diff' => sub { + my ( $self, $route, $sched_route ) = @_; + my @json_route; + my @route = @{$route}; + my @sched_route = @{$sched_route}; + + my $route_idx = 0; + my $sched_idx = 0; + + while ( $route_idx <= $#route and $sched_idx <= $#sched_route ) { + if ( $route[$route_idx] eq $sched_route[$sched_idx] ) { + push( @json_route, { name => $route[$route_idx] } ); + $route_idx++; + $sched_idx++; + } + + # this branch is inefficient, but won't be taken frequently + elsif ( not( $route[$route_idx] ~~ \@sched_route ) ) { + push( + @json_route, + { + name => $route[$route_idx], + isAdditional => 1 + } + ); + $route_idx++; + } + else { + push( + @json_route, + { + name => $sched_route[$sched_idx], + isCancelled => 1 + } + ); + $sched_idx++; + } + } + while ( $route_idx < $#route ) { + push( + @json_route, + { + name => $route[$route_idx], + isAdditional => 1, + isCancelled => 0 + } + ); + $route_idx++; + } + while ( $sched_idx < $#sched_route ) { + push( + @json_route, + { + name => $sched_route[$sched_idx], + isAdditional => 0, + isCancelled => 1 + } + ); + $sched_idx++; + } + return @json_route; + } + ); + + my $r = $self->routes; + + $r->get('/_redirect')->to('static#redirect'); + + $r->get('/_auto')->to('static#geolocation'); + + $r->get('/_datenschutz')->to('static#privacy'); + + $r->post('/_geolocation')->to('stationboard#stations_by_coordinates'); + + $r->get('/_impressum')->to('static#imprint'); + + $r->get('/_wr/:train/:departure')->to('wagenreihung#wagenreihung'); + + $self->defaults( layout => 'default' ); + $self->sessions->default_expiration( 3600 * 24 * 28 ); + + $r->get('/')->to('stationboard#handle_request'); + $r->get('/multi/*station')->to('stationboard#handle_request'); + $r->get('/*station')->to('stationboard#handle_request'); + + $self->config( + hypnotoad => { + accepts => $ENV{DBFAKEDISPLAY_ACCEPTS} // 100, + clients => $ENV{DBFAKEDISPLAY_CLIENTS} // 10, + listen => [ $ENV{DBFAKEDISPLAY_LISTEN} // 'http://*:8092' ], + pid_file => $ENV{DBFAKEDISPLAY_PID_FILE} + // '/tmp/db-fakedisplay.pid', + spare => $ENV{DBFAKEDISPLAY_SPARE} // 2, + workers => $ENV{DBFAKEDISPLAY_WORKERS} // 2, + }, + ); + + $self->types->type( json => 'application/json; charset=utf-8' ); + $self->plugin('browser_detect'); + +} + +1; |