summaryrefslogtreecommitdiff
path: root/lib/DBInfoscreen.pm
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2019-03-24 10:13:30 +0100
committerDaniel Friesel <derf@finalrewind.org>2019-03-24 10:13:30 +0100
commit9792369c2b79e68cc7384bbd9b55eef30fe8c004 (patch)
treeced72989066592a9344109974480ed67e413f9ee /lib/DBInfoscreen.pm
parent542a1db1106aaafe16203ffdb3bbac792d17a96c (diff)
Transition from Mojolicious::Lite to full Mojolicious app
Diffstat (limited to 'lib/DBInfoscreen.pm')
-rw-r--r--lib/DBInfoscreen.pm249
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;