diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/DBInfoscreen.pm | 60 | ||||
-rw-r--r-- | lib/DBInfoscreen/Controller/Map.pm | 30 | ||||
-rw-r--r-- | lib/DBInfoscreen/Controller/Stationboard.pm | 358 | ||||
-rw-r--r-- | lib/DBInfoscreen/Controller/Wagenreihung.pm | 126 | ||||
-rw-r--r-- | lib/DBInfoscreen/Helper/HAFAS.pm | 97 |
5 files changed, 353 insertions, 318 deletions
diff --git a/lib/DBInfoscreen.pm b/lib/DBInfoscreen.pm index 9dcc2d0..c784e96 100644 --- a/lib/DBInfoscreen.pm +++ b/lib/DBInfoscreen.pm @@ -38,12 +38,6 @@ sub startup { chomp $self->config->{version}; $self->defaults( version => $self->config->{version} // 'UNKNOWN' ); - $self->plugin( - I18N => { - default => 'de', - }, - ); - # Generally, the reverse proxy handles compression. # Also, Mojolicious compression breaks legacy callback-based JSON endpoints # for some clients. @@ -62,18 +56,6 @@ sub startup { if ( $cookie->name eq 'theme' ) { $self->session( theme => $cookie->value ); } - elsif ( $cookie->name eq 'lang' ) { - my $l = $cookie->value; - if ( $l eq 'de' or $l eq 'en' ) { - $self->languages($l); - } - } - } - - if ( my $l = $self->param('lang') ) { - if ( $l eq 'de' or $l eq 'en' ) { - $self->languages($l); - } } } ); @@ -103,36 +85,6 @@ sub startup { ); $self->attr( - ice_type_map => sub { - if ( -r 'share/zugbildungsplan.json' ) { - my $ice_type_map = JSON->new->utf8->decode( - scalar read_file('share/zugbildungsplan.json') ); - my $ret = {}; - while ( my ( $k, $v ) = each %{ $ice_type_map->{train} } ) { - if ( $v->{type} ) { - $ret->{$k} = [ - $v->{type}, $v->{shortType}, - exists $v->{wagons} ? 1 : 0 - ]; - } - } - return $ret; - } - return {}; - } - ); - - $self->attr( - train_details_db => sub { - if ( -r 'share/zugbildungsplan.json' ) { - return JSON->new->utf8->decode( - scalar read_file('share/zugbildungsplan.json') )->{train}; - } - return {}; - } - ); - - $self->attr( dbdb_wagon => sub { return JSON->new->utf8->decode( scalar read_file('share/dbdb_wagen.json') ); @@ -323,20 +275,22 @@ sub startup { $r->get('/dyn/:av/autocomplete.js')->to('stationboard#autocomplete'); $r->get('/_wr/:train/:departure')->to('wagenreihung#wagenreihung'); - $r->get('/wr/:train')->to('wagenreihung#zugbildung_db'); $r->get('/w/*wagon')->to('wagenreihung#wagen'); $r->get('/_ajax_mapinfo/:tripid/:lineno')->to('map#ajax_route'); $r->get('/map/:tripid/:lineno')->to('map#route'); - $r->get( '/z/:train/*station' => 'train_at_station' ) - ->to('stationboard#station_train_details'); - $r->get( '/z/:train' => 'train' )->to('stationboard#train_details'); + $r->get( '/z/:train/*station' => [ format => [ 'html', 'json' ] ] ) + ->to( 'stationboard#station_train_details', format => undef ) + ->name('train_at_station'); + $r->get( '/z/:train' => [ format => [ 'html', 'json' ] ] ) + ->to( 'stationboard#train_details', format => undef )->name('train'); $self->defaults( layout => 'app' ); $r->get('/')->to('stationboard#handle_request'); $r->get('/multi/*station')->to('stationboard#handle_request'); - $r->get('/*station')->to('stationboard#handle_request'); + $r->get( '/*station' => [ format => [ 'html', 'json' ] ] ) + ->to( 'stationboard#handle_request', format => undef ); $self->types->type( json => 'application/json; charset=utf-8' ); diff --git a/lib/DBInfoscreen/Controller/Map.pm b/lib/DBInfoscreen/Controller/Map.pm index e552a18..bced612 100644 --- a/lib/DBInfoscreen/Controller/Map.pm +++ b/lib/DBInfoscreen/Controller/Map.pm @@ -314,13 +314,26 @@ sub route { my ($self) = @_; my $trip_id = $self->stash('tripid'); my $line_no = $self->stash('lineno'); + my $hafas = $self->param('hafas'); my $from_name = $self->param('from'); my $to_name = $self->param('to'); $self->render_later; - $self->hafas->get_polyline_p( $trip_id, $line_no )->then( + my $service = 'DB'; + if ( $hafas + and $hafas ne '1' + and Travel::Status::DE::HAFAS::get_service($hafas) ) + { + $service = $hafas; + } + + $self->hafas->get_polyline_p( + id => $trip_id, + line => $line_no, + service => $service + )->then( sub { my ($journey) = @_; @@ -458,12 +471,25 @@ sub ajax_route { my ($self) = @_; my $trip_id = $self->stash('tripid'); my $line_no = $self->stash('lineno'); + my $hafas = $self->param('hafas'); delete $self->stash->{layout}; $self->render_later; - $self->hafas->get_polyline_p( $trip_id, $line_no )->then( + my $service = 'DB'; + if ( $hafas + and $hafas ne '1' + and Travel::Status::DE::HAFAS::get_service($hafas) ) + { + $service = $hafas; + } + + $self->hafas->get_polyline_p( + id => $trip_id, + line => $line_no, + service => $service + )->then( sub { my ($journey) = @_; diff --git a/lib/DBInfoscreen/Controller/Stationboard.pm b/lib/DBInfoscreen/Controller/Stationboard.pm index e2e5bb5..84fac61 100644 --- a/lib/DBInfoscreen/Controller/Stationboard.pm +++ b/lib/DBInfoscreen/Controller/Stationboard.pm @@ -29,6 +29,20 @@ my %default = ( admode => 'deparr', ); +sub class_to_product { + my ( $self, $hafas ) = @_; + + my $bits = $hafas->get_active_service->{productbits}; + my $ret; + + for my $i ( 0 .. $#{$bits} ) { + $ret->{ 2**$i } + = ref( $bits->[$i] ) eq 'ARRAY' ? $bits->[$i][0] : $bits->[$i]; + } + + return $ret; +} + sub handle_no_results { my ( $self, $station, $data, $hafas ) = @_; @@ -455,7 +469,12 @@ sub handle_request { # (or used by) marudor.de, it was renamed to 'json'. Many clients won't # notice this for year to come, so we make sure mode=marudor still works as # intended. - if ( $template eq 'marudor' ) { + if ( + $template eq 'marudor' + or ( $self->req->headers->accept + and $self->req->headers->accept eq 'application/json' ) + ) + { $template = 'json'; } @@ -490,6 +509,7 @@ sub handle_request { my ($status) = @_; my $data = { results => [ $status->results ], + hafas => $hafas ? $status : undef, station_ds100 => ( $status->station ? $status->station->{ds100} : undef ), station_eva => ( @@ -503,12 +523,6 @@ sub handle_request { ( $status->station ? $status->station->{name} : $station ), }; - if ( $status->station and $status->station->{names} ) { - $data->{station_name} - = List::Util::reduce { length($a) < length($b) ? $a : $b } - @{ $status->station->{names} }; - } - if ( not @{ $data->{results} } and $template eq 'json' ) { $self->handle_no_results_json( $station, $data, $api_version ); return; @@ -833,17 +847,17 @@ sub render_train { my %opt = ( train => $result ); - if ( $self->languages =~ m{^en} ) { - $opt{language} = 'en'; - } + #if ( $self->languages =~ m{^en} ) { + # $opt{language} = 'en'; + #} $self->hafas->get_route_p(%opt)->then( sub { my ( $route, $journey ) = @_; - $departure->{trip_id} = $journey->id; - $departure->{operator} = $journey->operator; - $departure->{date} = $route->[0]{sched_dep} // $route->[0]{dep}; + $departure->{trip_id} = $journey->id; + $departure->{operators} = [ $journey->operators ]; + $departure->{date} = $route->[0]{sched_dep} // $route->[0]{dep}; # Use HAFAS route as source of truth; ignore IRIS data $departure->{route_pre_diff} = []; @@ -859,6 +873,16 @@ sub render_train { = [ $load->{FIRST}, $load->{SECOND} ]; } } + $departure->{tz_offset} = $route->[$i]{tz_offset}; + $departure->{local_dt_da} = $route->[$i]{local_dt_da}; + $departure->{local_sched_arr} + = $route->[$i]{local_sched_arr}; + $departure->{local_sched_dep} + = $route->[$i]{local_sched_dep}; + $departure->{is_annotated} = $route->[$i]{is_annotated}; + $departure->{prod_name} = $route->[$i]{prod_name}; + $departure->{direction} = $route->[$i]{direction}; + $departure->{operator} = $route->[$i]{operator}; last; } } @@ -915,58 +939,39 @@ sub render_train { } )->wait; - $departure->{composition} - = $self->app->train_details_db->{ $departure->{train_no} }; - if ( not $departure->{arrival} - and $departure->{composition}{prepTime} - and $departure->{composition}{prepAt} eq $station_name ) - { - $departure->{prep_time} = $departure->{composition}{prepTime}; - $departure->{arrival_hidden} = 1; - } - if ( $self->param('detailed') ) { - my @cycle_from; - my @cycle_to; - for my $pred ( @{ $departure->{composition}{predecessors} // [] } ) { - push( @cycle_from, $pred->[1] ); - } - for my $succ ( @{ $departure->{composition}{successors} // [] } ) { - push( @cycle_to, $succ->[1] ); - } - $departure->{cycle_from} - = [ map { [ $_, $self->app->train_details_db->{$_} ] } @cycle_from ]; - $departure->{cycle_to} - = [ map { [ $_, $self->app->train_details_db->{$_} ] } @cycle_to ]; - } - # Defer rendering until all requests have completed Mojo::Promise->all(@requests)->then( sub { - $self->render( - $template // '_train_details', - description => sprintf( - '%s %s%s%s nach %s', - $departure->{train_type}, - $departure->{train_line} // $departure->{train_no}, - $departure->{origin} ? ' von ' : q{}, - $departure->{origin} // q{}, - $departure->{destination} // 'unbekannt' - ), - departure => $departure, - linetype => $linetype, - icetype => $self->app->ice_type_map->{ $departure->{train_no} }, - details => $self->param('detailed') - ? $departure->{composition} // {} - : {}, - dt_now => DateTime->now( time_zone => 'Europe/Berlin' ), - station_name => $station_name, - nav_link => - $self->url_for( 'station', station => $station_name )->query( - { - detailed => $self->param('detailed'), - hafas => $self->param('hafas') - } - ), + $self->respond_to( + json => { + json => { + departure => $departure, + station_name => $station_name, + }, + }, + any => { + template => $template // '_train_details', + description => sprintf( + '%s %s%s%s nach %s', + $departure->{train_type}, + $departure->{train_line} // $departure->{train_no}, + $departure->{origin} ? ' von ' : q{}, + $departure->{origin} // q{}, + $departure->{destination} // 'unbekannt' + ), + departure => $departure, + linetype => $linetype, + dt_now => DateTime->now( time_zone => 'Europe/Berlin' ), + station_name => $station_name, + nav_link => + $self->url_for( 'station', station => $station_name ) + ->query( + { + detailed => $self->param('detailed'), + hafas => $self->param('hafas') + } + ), + }, ); } )->wait; @@ -982,6 +987,10 @@ sub station_train_details { delete $self->stash->{layout}; } + if ( $station =~ s{ [.] json $ }{}x ) { + $self->stash( format => 'json' ); + } + my %opt = ( cache_iris_main => $self->app->cache_iris_main, cache_iris_rt => $self->app->cache_iris_rt, @@ -1057,6 +1066,8 @@ sub station_train_details { arrival_is_cancelled => $result->arrival_is_cancelled, moreinfo => $moreinfo, delay => $result->delay, + arrival_delay => $result->arrival_delay, + departure_delay => $result->departure_delay, route_pre => [ $result->route_pre ], route_post => [ $result->route_post ], replaced_by => [ @@ -1087,11 +1098,20 @@ sub station_train_details { )->catch( sub { my ($errstr) = @_; - $self->render( - 'landingpage', - error => - "Keine Abfahrt von $train_no in $station gefunden: $errstr", - status => 404, + $self->respond_to( + json => { + json => { + error => +"Keine Abfahrt von $train_no in $station gefunden: $errstr", + }, + status => 404, + }, + any => { + template => 'landingpage', + error => +"Keine Abfahrt von $train_no in $station gefunden: $errstr", + status => 404, + }, ); return; } @@ -1101,7 +1121,8 @@ sub station_train_details { # /z/:train sub train_details { my ($self) = @_; - my $train = $self->stash('train'); + my $train = $self->stash('train'); + my $hafas = $self->param('hafas'); # TODO error handling @@ -1139,10 +1160,18 @@ sub train_details { $opt{train_no} = $train_no; } - if ( $self->languages =~ m{^en} ) { - $opt{language} = 'en'; + my $service = 'DB'; + if ( $hafas + and $hafas ne '1' + and Travel::Status::DE::HAFAS::get_service($hafas) ) + { + $opt{service} = $hafas; } + #if ( $self->languages =~ m{^en} ) { + # $opt{language} = 'en'; + #} + if ( my $date = $self->param('date') ) { if ( $date =~ m{ ^ (?<day> \d{1,2} ) [.] (?<month> \d{1,2} ) [.] (?<year> \d{4})? $ }x @@ -1166,43 +1195,52 @@ sub train_details { $self->hafas->get_route_p(%opt)->then( sub { - my ( $route, $journey ) = @_; + my ( $route, $journey, $hafas_obj ) = @_; $res->{trip_id} = $journey->id; $res->{date} = $route->[0]{sched_dep} // $route->[0]{dep}; - if ( not $res->{train_type} ) { - my $train_type = $res->{train_type} = $journey->type // q{}; - my $train_no = $res->{train_no} = $journey->number // q{}; - $res->{train_line} = $journey->line_no // q{}; - $self->stash( title => "${train_type} ${train_no}" ); + my $product = $journey->product; + + if ( my $req_name = $self->param('highlight') ) { + if ( my $p = $journey->product_at($req_name) ) { + $product = $p; + } } - if ( not defined $journey->class ) { + my $train_type = $res->{train_type} = $product->type // q{}; + my $train_no = $res->{train_no} = $product->number // q{}; + $res->{train_line} = $product->line_no // q{}; + $self->stash( title => $train_type . ' ' + . ( $train_no || $res->{train_line} ) ); + + if ( not defined $product->class ) { $linetype = 'ext'; } - elsif ( $journey->class <= 2 ) { - $linetype = 'fern'; - } - elsif ( $journey->class <= 8 ) { - $linetype = 'bahn'; - } - elsif ( $journey->class <= 16 ) { - $linetype = 'sbahn'; - } - elsif ( $journey->class == 32 ) { - $linetype = 'bus'; - } - elsif ( $journey->class == 128 ) { - $linetype = 'ubahn'; - } - elsif ( $journey->class == 256 ) { - $linetype = 'tram'; + else { + my $prod + = $self->class_to_product($hafas_obj)->{ $product->class } + // q{}; + if ( $prod eq 'ice' or $prod eq 'ic_ec' ) { + $linetype = 'fern'; + } + elsif ( $prod eq 's' ) { + $linetype = 'sbahn'; + } + elsif ( $prod eq 'bus' ) { + $linetype = 'bus'; + } + elsif ( $prod eq 'u' ) { + $linetype = 'ubahn'; + } + elsif ( $prod eq 'tram' ) { + $linetype = 'tram'; + } } $res->{origin} = $journey->route_start; $res->{destination} = $journey->route_end; - $res->{operator} = $journey->operator; + $res->{operators} = [ $journey->operators ]; $res->{route_post_diff} = $route; @@ -1246,7 +1284,15 @@ sub train_details { = $station_info->{dep_cancelled}; $res->{is_cancelled} = $res->{arrival_is_cancelled} || $res->{arrival_is_cancelled}; - $res->{platform} = $station_info->{platform}; + $res->{tz_offset} = $station_info->{tz_offset}; + $res->{local_dt_da} = $station_info->{local_dt_da}; + $res->{local_sched_arr} = $station_info->{local_sched_arr}; + $res->{local_sched_dep} = $station_info->{local_sched_dep}; + $res->{is_annotated} = $station_info->{is_annotated}; + $res->{prod_name} = $station_info->{prod_name}; + $res->{direction} = $station_info->{direction}; + $res->{operator} = $station_info->{operator}; + $res->{platform} = $station_info->{platform}; $res->{scheduled_platform} = $station_info->{sched_platform}; } @@ -1284,55 +1330,52 @@ sub train_details { $res->{details} = [@him_details]; } - if ( $self->param('detailed') ) { - $res->{composition} - = $self->app->train_details_db->{ $res->{train_no} }; - my @cycle_from; - my @cycle_to; - for my $pred ( @{ $res->{composition}{predecessors} // [] } ) { - push( @cycle_from, $pred->[1] ); - } - for my $succ ( @{ $res->{composition}{successors} // [] } ) { - push( @cycle_to, $succ->[1] ); - } - $res->{cycle_from} - = [ map { [ $_, $self->app->train_details_db->{$_} ] } - @cycle_from ]; - $res->{cycle_to} - = [ map { [ $_, $self->app->train_details_db->{$_} ] } - @cycle_to ]; - } - - $self->render( - $self->param('ajax') ? '_train_details' : 'train_details', - description => sprintf( - '%s %s%s%s nach %s', - $res->{train_type}, - $res->{train_line} // $res->{train_no}, - $res->{origin} ? ' von ' : q{}, - $res->{origin} // q{}, - $res->{destination} // 'unbekannt' - ), - departure => $res, - linetype => $linetype, - icetype => $self->app->ice_type_map->{ $res->{train_no} }, - details => {}, #$departure->{composition} // {}, - dt_now => DateTime->now( time_zone => 'Europe/Berlin' ), + $self->respond_to( + json => { + json => { + journey => $journey, + }, + }, + any => { + template => $self->param('ajax') + ? '_train_details' + : 'train_details', + description => sprintf( + '%s %s%s%s nach %s', + $res->{train_type}, + $res->{train_line} // $res->{train_no}, + $res->{origin} ? ' von ' : q{}, + $res->{origin} // q{}, + $res->{destination} // 'unbekannt' + ), + departure => $res, + linetype => $linetype, + dt_now => DateTime->now( time_zone => 'Europe/Berlin' ), + }, ); } )->catch( sub { my ($e) = @_; if ($e) { - $self->render( - 'exception', - message => $e, - exception => undef, - snapshot => {} + $self->respond_to( + json => { + json => { + error => $e, + }, + status => 500, + }, + any => { + template => 'exception', + message => $e, + exception => undef, + snapshot => {}, + status => 500, + }, ); } else { - $self->render('not_found'); + $self->render( 'not_found', status => 404 ); } } )->wait; @@ -1356,6 +1399,7 @@ sub handle_result { my $callback = $self->param('callback'); my $via = $self->param('via'); my $hafas = $self->param('hafas'); + my $hafas_obj = $data->{hafas}; my $now = DateTime->now( time_zone => 'Europe/Berlin' ); @@ -1403,6 +1447,9 @@ sub handle_result { } } + my $class_to_product + = $hafas_obj ? $self->class_to_product($hafas_obj) : {}; + @results = $self->filter_results(@results); for my $result (@results) { @@ -1442,19 +1489,20 @@ sub handle_result { } } elsif ( $result->can('class') ) { - if ( $result->class <= 2 ) { + my $prod = $class_to_product->{ $result->class } // q{}; + if ( $prod eq 'ice' or $prod eq 'ic_ec' ) { $linetype = 'fern'; } - elsif ( $result->class == 16 ) { + elsif ( $prod eq 's' ) { $linetype = 'sbahn'; } - elsif ( $result->class == 32 ) { + elsif ( $prod eq 'bus' ) { $linetype = 'bus'; } - elsif ( $result->class == 128 ) { + elsif ( $prod eq 'u' ) { $linetype = 'ubahn'; } - elsif ( $result->class == 256 ) { + elsif ( $prod eq 'tram' ) { $linetype = 'tram'; } } @@ -1662,6 +1710,8 @@ sub handle_result { station => $result->station, moreinfo => $moreinfo, delay => $delay, + arrival_delay => $result->arrival_delay, + departure_delay => $result->departure_delay, missing_realtime => ( not $result->has_realtime and $result->start < $now ? 1 : 0 @@ -1782,6 +1832,11 @@ sub handle_result { my $params = $self->req->params->clone; $params->param( hafas => not $params->param('hafas') ); if ( $params->param('hafas') ) { + if ( $data->{station_eva} >= 8100000 + and $data->{station_eva} < 8200000 ) + { + $params->param( hafas => 'ÖBB' ); + } $api_link = '/' . $data->{station_eva} . '?' . $params->to_string; $api_text = 'Auf Nahverkehr wechseln'; $api_icon = 'train'; @@ -1803,7 +1858,6 @@ sub handle_result { api_text => $api_text, api_icon => $api_icon, departures => \@departures, - ice_type => $self->app->ice_type_map, station => $station_name, version => $self->config->{version}, title => $via ? "$station_name → $via" : $station_name, @@ -1831,14 +1885,23 @@ sub handle_result { sub stations_by_coordinates { my $self = shift; - my $lon = $self->param('lon'); - my $lat = $self->param('lat'); + my $lon = $self->param('lon'); + my $lat = $self->param('lat'); + my $hafas = $self->param('hafas'); if ( not $lon or not $lat ) { $self->render( json => { error => 'Invalid lon/lat received' } ); return; } + my $service = 'DB'; + if ( $hafas + and $hafas ne '1' + and Travel::Status::DE::HAFAS::get_service($hafas) ) + { + $service = $hafas; + } + $self->render_later; my @iris = map { @@ -1859,6 +1922,7 @@ sub stations_by_coordinates { Travel::Status::DE::HAFAS->new_p( promise => 'Mojo::Promise', user_agent => $self->ua, + service => $service, geoSearch => { lat => $lat, lon => $lon @@ -1871,7 +1935,7 @@ sub stations_by_coordinates { name => $_->name, eva => $_->eva, distance => $_->distance_m / 1000, - hafas => 1 + hafas => $service, } } $hafas->results; if ( @hafas > 10 ) { @@ -1947,6 +2011,10 @@ sub redirect_to_station { $params = $params->to_string; $self->redirect_to("/z/${input}?${params}"); } + elsif ( $params->param('hafas') and $params->param('hafas') ne '1' ) { + $params = $params->to_string; + $self->redirect_to("/${input}?${params}"); + } else { my @candidates = Travel::Status::DE::IRIS::Stations::get_station($input); diff --git a/lib/DBInfoscreen/Controller/Wagenreihung.pm b/lib/DBInfoscreen/Controller/Wagenreihung.pm index 5e5f653..1708285 100644 --- a/lib/DBInfoscreen/Controller/Wagenreihung.pm +++ b/lib/DBInfoscreen/Controller/Wagenreihung.pm @@ -13,126 +13,20 @@ use utf8; use Travel::Status::DE::DBWagenreihung; use Travel::Status::DE::DBWagenreihung::Wagon; -sub get_zugbildung_db { - my ( $self, $train_no ) = @_; - - my $details = $self->app->train_details_db->{$train_no}; - - if ( not $details ) { - return; - } - - my @wagons; - - for my $wagon ( @{ $details->{wagons} } ) { - my $wagon_type = $wagon->{type}; - my $wagon_number = $wagon->{number}; - my %wagon = ( - fahrzeugnummer => "", - fahrzeugtyp => $wagon_type, - kategorie => $wagon_type =~ m{^[0-9.]+$} ? 'LOK' : '', - train_no => $train_no, - wagenordnungsnummer => $wagon_number, - positionamhalt => { - startprozent => 0, - endeprozent => 0, - startmeter => 0, - endemeter => 0, - } - ); - my $wagon = Travel::Status::DE::DBWagenreihung::Wagon->new(%wagon); - - if ( $details->{type} ) { - $wagon->set_traintype( $details->{type} ); - } - push( @wagons, $wagon ); - } - - my $pos = 0; - for my $wagon (@wagons) { - $wagon->{position}{start_percent} = $pos; - $wagon->{position}{end_percent} = $pos + 5; - $pos += 5; - } - - my $train_type = $details->{rawType}; - $train_type =~ s{ - .* }{}x; - - my $route_start = $details->{route}{start} // $details->{route}{preStart}; - my $route_end = $details->{route}{end} // $details->{route}{postEnd}; - my $route = "${route_start} → ${route_end}"; - - return { - route => $route, - train_type => $train_type, - wagons => [@wagons] - }; -} - -sub zugbildung_db { - my ($self) = @_; - - my $train_no = $self->param('train'); - - my $details = $self->get_zugbildung_db($train_no); - - if ( not $details ) { - $self->render( 'not_found', - message => "Keine Daten zu Zug ${train_no} bekannt" ); - return; - } +sub handle_wagenreihung_error { + my ( $self, $train_no, $err ) = @_; $self->render( - 'zugbildung_db', - description => sprintf( - 'Soll-Wagenreihung %s %s', - $details->{train_type} // 'Zug', $train_no - ), - wr_error => undef, - title => $details->{train_type} . ' ' . $train_no, - route => $details->{route}, - zb => $details, + 'wagenreihung', + title => "Zug $train_no", + wr_error => $err, train_no => $train_no, - wagons => $details->{wagons}, + wr => undef, + wref => undef, hide_opts => 1, ); } -sub handle_wagenreihung_error { - my ( $self, $train_no, $err ) = @_; - - my $details = $self->get_zugbildung_db($train_no); - if ( $details and @{ $details->{wagons} } ) { - my $wr_error - = "${err}. Ersatzweise werden die Solldaten laut Fahrplan angezeigt."; - $self->render( - 'zugbildung_db', - description => sprintf( - 'Soll-Wagenreihung %s %s', - $details->{train_type} // 'Zug', $train_no - ), - wr_error => $wr_error, - title => $details->{train_type} . ' ' . $train_no, - route => $details->{route}, - zb => $details, - train_no => $train_no, - wagons => $details->{wagons}, - hide_opts => 1, - ); - } - else { - $self->render( - 'wagenreihung', - title => "Zug $train_no", - wr_error => $err, - train_no => $train_no, - wr => undef, - wref => undef, - hide_opts => 1, - ); - } -} - sub wagenreihung { my ($self) = @_; my $train = $self->stash('train'); @@ -331,15 +225,15 @@ sub wagen { ); } - my $title = $self->l('Wagen ') . $wagon_id; + my $title = 'Wagen ' . $wagon_id; if ( $wref->{tt} and $wref->{tn} ) { $title = sprintf( '%s %s', $wref->{tt}, $wref->{tn} ); if ($wagon_no) { - $title .= ' ' . $self->l('Wagen ') . $wagon_no; + $title .= ' Wagen ' . $wagon_no; } else { - $title .= ' ' . $self->l('Wagen ') . $wagon_id; + $title .= ' Wagen ' . $wagon_id; } } diff --git a/lib/DBInfoscreen/Helper/HAFAS.pm b/lib/DBInfoscreen/Helper/HAFAS.pm index ad21c58..cdb84f0 100644 --- a/lib/DBInfoscreen/Helper/HAFAS.pm +++ b/lib/DBInfoscreen/Helper/HAFAS.pm @@ -39,6 +39,7 @@ sub get_route_p { if ( $opt{trip_id} ) { $hafas_promise = Travel::Status::DE::HAFAS->new_p( + service => $opt{service}, journey => { id => $opt{trip_id}, }, @@ -104,7 +105,67 @@ sub get_route_p { my $journey = $hafas->result; my @ret; my $station_is_past = 1; + + my $num_names = 0; + my $prev_name = q{}; + my $num_directions = 0; + my $prev_direction = q{}; + my $num_operators = 0; + my $prev_operator = q{}; + + for my $stop ( $journey->route ) { + my $prod = $stop->prod_dep // $stop->prod_arr; + if ( $prod and $prod->name and $prod->name ne $prev_name ) { + $num_names++; + $prev_name = $prod->name; + } + if ( $prod + and $prod->operator + and $prod->operator ne $prev_operator ) + { + $num_operators++; + $prev_operator = $prod->operator; + } + if ( $stop->direction and $stop->direction ne $prev_direction ) + { + $num_directions++; + $prev_direction = $stop->direction; + } + } + + $prev_name = q{}; + $prev_direction = q{}; + $prev_operator = q{}; + for my $stop ( $journey->route ) { + + my $prod = $stop->prod_dep // $stop->prod_arr; + my %annotation; + if ( $num_names > 1 + and $prod + and $prod->name + and $prod->name ne $prev_name ) + { + $prev_name = $annotation{prod_name} = $prod->name; + } + if ( $num_operators > 1 + and $prod + and $prod->operator + and $prod->operator ne $prev_operator ) + { + $prev_operator = $annotation{operator} = $prod->operator; + } + if ( $num_directions > 1 + and $stop->direction + and $stop->direction ne $prev_direction ) + { + $prev_direction = $annotation{direction} = $stop->direction; + } + + if (%annotation) { + $annotation{is_annotated} = 1; + } + push( @ret, { @@ -118,6 +179,7 @@ sub get_route_p { dep_delay => $stop->dep_delay, arr_cancelled => $stop->arr_cancelled, dep_cancelled => $stop->dep_cancelled, + tz_offset => $stop->tz_offset, platform => $stop->platform, sched_platform => $stop->sched_platform, load => $stop->load, @@ -127,6 +189,7 @@ sub get_route_p { and ( $stop->dep_cancelled or not $stop->sched_dep ) ), + %annotation, } ); if ( @@ -141,9 +204,35 @@ sub get_route_p { $station_is_past = 0; } $ret[-1]{isPast} = $station_is_past; + if ( $stop->tz_offset ) { + if ( $stop->sched_arr ) { + $ret[-1]{local_sched_arr} + = $stop->sched_arr->clone->add( + minutes => $stop->tz_offset ); + } + if ( $stop->sched_dep ) { + $ret[-1]{local_sched_dep} + = $stop->sched_dep->clone->add( + minutes => $stop->tz_offset ); + } + if ( $stop->rt_arr ) { + $ret[-1]{local_rt_arr} = $stop->rt_arr->clone->add( + minutes => $stop->tz_offset ); + } + if ( $stop->rt_dep ) { + $ret[-1]{local_rt_dep} = $stop->rt_dep->clone->add( + minutes => $stop->tz_offset ); + } + $ret[-1]{local_dt_ad} = $ret[-1]{local_rt_arr} + // $ret[-1]{local_sched_arr} // $ret[-1]{local_rt_dep} + // $ret[-1]{local_sched_dep}; + $ret[-1]{local_dt_da} = $ret[-1]{local_rt_dep} + // $ret[-1]{local_sched_dep} // $ret[-1]{local_rt_arr} + // $ret[-1]{local_sched_arr}; + } } - $promise->resolve( \@ret, $journey ); + $promise->resolve( \@ret, $journey, $hafas ); return; } )->catch( @@ -160,11 +249,15 @@ sub get_route_p { # Input: (HAFAS TripID, line number) # Output: Promise returning a Travel::Status::DE::HAFAS::Journey instance on success sub get_polyline_p { - my ( $self, $trip_id, $line ) = @_; + my ( $self, %opt ) = @_; + my $trip_id = $opt{id}; + my $line = $opt{line}; + my $service = $opt{service}; my $promise = Mojo::Promise->new; Travel::Status::DE::HAFAS->new_p( + service => $service, journey => { id => $trip_id, name => $line, |