summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/DBInfoscreen.pm31
-rw-r--r--lib/DBInfoscreen/Controller/Stationboard.pm403
-rw-r--r--lib/DBInfoscreen/Controller/Wagenreihung.pm6
-rw-r--r--lib/DBInfoscreen/Helper/EFA.pm1
-rw-r--r--lib/DBInfoscreen/Helper/HAFAS.pm89
5 files changed, 443 insertions, 87 deletions
diff --git a/lib/DBInfoscreen.pm b/lib/DBInfoscreen.pm
index c33a703..1fd3674 100644
--- a/lib/DBInfoscreen.pm
+++ b/lib/DBInfoscreen.pm
@@ -187,9 +187,27 @@ sub startup {
my ( $self, $occupancy ) = @_;
my @symbols
- = (qw(help_outline person_outline people priority_high));
+ = (
+ qw(help_outline person_outline people priority_high not_interested)
+ );
my $text = 'Auslastung unbekannt';
+ if ( $occupancy eq 'MANY_SEATS' ) {
+ $occupancy = 1;
+ }
+ elsif ( $occupancy eq 'FEW_SEATS' ) {
+ $occupancy = 2;
+ }
+ elsif ( $occupancy eq 'STANDING_ONLY' ) {
+ $occupancy = 3;
+ }
+ elsif ( $occupancy eq 'FULL' ) {
+ $occupancy = 4;
+ }
+
+ if ( $occupancy > 3 ) {
+ $text = 'Voraussichtlich überfüllt';
+ }
if ( $occupancy > 2 ) {
$text = 'Sehr hohe Auslastung erwartet';
}
@@ -279,15 +297,18 @@ sub startup {
$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/Stationboard.pm b/lib/DBInfoscreen/Controller/Stationboard.pm
index 6006a15..93388fa 100644
--- a/lib/DBInfoscreen/Controller/Stationboard.pm
+++ b/lib/DBInfoscreen/Controller/Stationboard.pm
@@ -17,6 +17,7 @@ use Mojo::JSON qw(decode_json encode_json);
use Mojo::Promise;
use Mojo::UserAgent;
use Travel::Status::DE::DBWagenreihung;
+use Travel::Status::DE::EFA;
use Travel::Status::DE::HAFAS;
use Travel::Status::DE::IRIS;
use Travel::Status::DE::IRIS::Stations;
@@ -44,11 +45,20 @@ sub class_to_product {
}
sub handle_no_results {
- my ( $self, $station, $data, $hafas ) = @_;
+ my ( $self, $station, $data, $hafas, $efa ) = @_;
my $errstr = $data->{errstr};
- if ($hafas) {
+ if ($efa) {
+ $self->render(
+ 'landingpage',
+ error => ( $errstr // "Keine Abfahrten an '$station'" ),
+ hide_opts => 0,
+ status => $data->{status} // 404,
+ );
+ return;
+ }
+ elsif ($hafas) {
$self->render_later;
my $service = 'DB';
if ( $hafas ne '1' and Travel::Status::DE::HAFAS::get_service($hafas) )
@@ -343,6 +353,24 @@ sub get_results_p {
my ( $self, $station, %opt ) = @_;
my $data;
+ if ( $opt{efa} ) {
+ my $service = 'VRR';
+ if ( $opt{efa} ne '1'
+ and Travel::Status::DE::EFA::get_service( $opt{efa} ) )
+ {
+ $service = $opt{efa};
+ }
+ return Travel::Status::DE::EFA->new_p(
+ service => $service,
+ name => $station,
+ lwp_options => {
+ timeout => 10,
+ agent => 'dbf.finalrewind.org/2'
+ },
+ promise => 'Mojo::Promise',
+ user_agent => Mojo::UserAgent->new,
+ );
+ }
if ( $opt{hafas} ) {
my $service = 'DB';
if ( $opt{hafas} ne '1'
@@ -412,12 +440,14 @@ sub handle_request {
my $station = $self->stash('station');
my $template = $self->param('mode') // 'app';
+ my $efa = $self->param('efa');
my $hafas = $self->param('hafas');
my $with_related = !$self->param('no_related');
my %opt = (
cache_iris_main => $self->app->cache_iris_main,
cache_iris_rt => $self->app->cache_iris_rt,
lookahead => $self->config->{lookahead},
+ efa => $efa,
hafas => $hafas,
);
@@ -469,7 +499,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';
}
@@ -502,6 +537,10 @@ sub handle_request {
$self->get_results_p( $station, %opt )->then(
sub {
my ($status) = @_;
+ if ($efa) {
+ $self->handle_efa( $station, $status );
+ return;
+ }
my $data = {
results => [ $status->results ],
hafas => $hafas ? $status : undef,
@@ -518,12 +557,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;
@@ -554,7 +587,7 @@ sub handle_request {
errstr => $err,
status => ( $err =~ m{Ambiguous|LOCATION} ? 300 : 500 ),
},
- $hafas
+ $hafas, $efa
);
return;
}
@@ -750,8 +783,55 @@ sub render_train {
from_json => $wr_json );
$departure->{wr} = $wr;
$departure->{wr_text} = join( q{ • },
- map { $_->{short} }
- grep { $_->{short} } $wr->train_descriptions );
+ map { $_->desc_short }
+ grep { $_->desc_short } $wr->groups );
+ my $first = 0;
+ for my $group ( $wr->groups ) {
+ my $had_entry = 0;
+ for my $wagon ( $group->wagons ) {
+ if (
+ not( $wagon->is_locomotive
+ or $wagon->is_powercar )
+ )
+ {
+ my $class;
+ if ($first) {
+ push(
+ @{ $departure->{wr_preview} },
+ [ '•', 'meta' ]
+ );
+ $first = 0;
+ }
+ my $entry;
+ if ( $wagon->is_closed ) {
+ $entry = 'X';
+ $class = 'closed';
+ }
+ else {
+ $entry = $wagon->number
+ || (
+ $wagon->type =~ m{AB} ? '½'
+ : $wagon->type =~ m{A} ? '1.'
+ : $wagon->type =~ m{B} ? '2.'
+ : $wagon->type
+ );
+ }
+ if (
+ $group->train_no ne $departure->{train_no} )
+ {
+ $class = 'otherno';
+ }
+ push(
+ @{ $departure->{wr_preview} },
+ [ $entry, $class ]
+ );
+ $had_entry = 1;
+ }
+ }
+ if ($had_entry) {
+ $first = 1;
+ }
+ }
};
$departure->{wr_text} ||= 'Wagen';
return;
@@ -827,10 +907,11 @@ sub render_train {
}
if ($direction) {
- $departure->{direction} = $direction;
+ $departure->{wr_direction} = $direction;
+ $departure->{wr_direction_num} = $direction eq 'l' ? 0 : 100;
}
elsif ( $platform_info->{direction} ) {
- $departure->{direction} = 'a' . $platform_info->{direction};
+ $departure->{wr_direction} = 'a' . $platform_info->{direction};
}
return;
@@ -856,9 +937,9 @@ sub render_train {
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} = [];
@@ -874,6 +955,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;
}
}
@@ -933,27 +1024,36 @@ sub render_train {
# 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,
- 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;
@@ -969,6 +1069,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,
@@ -1044,6 +1148,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 => [
@@ -1074,11 +1180,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;
}
@@ -1097,8 +1212,6 @@ sub train_details {
delete $self->stash->{layout};
}
- my $api_version = $Travel::Status::DE::IRIS::VERSION;
-
$self->stash( departures => [] );
$self->stash( title => 'DBF' );
@@ -1128,7 +1241,10 @@ sub train_details {
}
my $service = 'DB';
- if ( $hafas ne '1' and Travel::Status::DE::HAFAS::get_service($hafas) ) {
+ if ( $hafas
+ and $hafas ne '1'
+ and Travel::Status::DE::HAFAS::get_service($hafas) )
+ {
$opt{service} = $hafas;
}
@@ -1164,19 +1280,26 @@ sub train_details {
$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';
}
else {
my $prod
- = $self->class_to_product($hafas_obj)->{ $journey->class }
+ = $self->class_to_product($hafas_obj)->{ $product->class }
// q{};
if ( $prod eq 'ice' or $prod eq 'ic_ec' ) {
$linetype = 'fern';
@@ -1197,7 +1320,7 @@ sub train_details {
$res->{origin} = $journey->route_start;
$res->{destination} = $journey->route_end;
- $res->{operator} = $journey->operator;
+ $res->{operators} = [ $journey->operators ];
$res->{route_post_diff} = $route;
@@ -1241,7 +1364,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};
}
@@ -1279,39 +1410,144 @@ sub train_details {
$res->{details} = [@him_details];
}
- $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,
- 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;
}
+sub handle_efa {
+ my ( $self, $station_name, $efa ) = @_;
+ my $template = $self->param('mode') // 'app';
+ my $hide_low_delay = $self->param('hidelowdelay') // 0;
+ my $hide_opts = $self->param('hide_opts') // 0;
+ my $show_realtime = $self->param('rt') // $self->param('show_realtime')
+ // 0;
+
+ my @departures;
+
+ if ( $self->param('ajax') ) {
+ delete $self->stash->{layout};
+ }
+
+ for my $result ( $efa->results ) {
+ my $time;
+
+ if ( $show_realtime and $result->rt_datetime ) {
+ $time = $result->rt_datetime->strftime('%H:%M');
+ }
+ else {
+ $time = $result->sched_datetime->strftime('%H:%M');
+ }
+
+ my $linetype = $result->mot_name // 'bahn';
+ if ( $linetype eq 's-bahn' ) {
+ $linetype = 'sbahn';
+ }
+ elsif ( $linetype eq 'u-bahn' ) {
+ $linetype = 'ubahn';
+ }
+ elsif ( $linetype =~ m{bus} ) {
+ $linetype = 'bus';
+ }
+ elsif ( $linetype eq 'zug' ) {
+ $linetype = 'bahn';
+ }
+ elsif ( $linetype eq 'sonstige' ) {
+ $linetype = 'ext';
+ }
+ push(
+ @departures,
+ {
+ time => $time,
+ sched_departure => $result->sched_datetime->strftime('%H:%M'),
+ departure => $result->rt_datetime
+ ? $result->rt_datetime->strftime('%H:%M')
+ : undef,
+ train => $result->line,
+ train_type => q{},
+ train_line => $result->line,
+ train_no => $result->train_no,
+ via => [],
+ destination => $result->destination,
+ platform => $result->platform,
+ is_cancelled => $result->is_cancelled,
+ linetype => $linetype,
+ delay => $result->delay,
+ occupancy => $result->occupancy,
+ replaced_by => [],
+ replacement_for => [],
+ route_pre => [],
+ route_post => [],
+ wr_link => undef,
+ }
+ );
+ }
+
+ $self->render(
+ $template,
+ description => "Abfahrtstafel $station_name",
+ departures => \@departures,
+ station => $station_name,
+ version => $self->config->{version},
+ title => $station_name,
+ refresh_interval => $template eq 'app' ? 0 : 120,
+ hide_opts => $hide_opts,
+ hide_low_delay => $hide_low_delay,
+ show_realtime => $show_realtime,
+ load_marquee => (
+ $template eq 'single'
+ or $template eq 'multi'
+ ),
+ force_mobile => ( $template eq 'app' ),
+ );
+}
+
sub handle_result {
my ( $self, $data ) = @_;
@@ -1641,6 +1877,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
@@ -1693,6 +1931,7 @@ sub handle_result {
origin => $result->route_end =~ s{,\Q$city\E}{}r,
platform => $result->platform,
scheduled_platform => $result->sched_platform,
+ load => $result->load // {},
info => $info,
is_cancelled => $result->is_cancelled,
linetype => $linetype,
@@ -1814,14 +2053,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 {
@@ -1842,6 +2090,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
@@ -1854,7 +2103,7 @@ sub stations_by_coordinates {
name => $_->name,
eva => $_->eva,
distance => $_->distance_m / 1000,
- hafas => 1
+ hafas => $service,
}
} $hafas->results;
if ( @hafas > 10 ) {
diff --git a/lib/DBInfoscreen/Controller/Wagenreihung.pm b/lib/DBInfoscreen/Controller/Wagenreihung.pm
index 1708285..03a607d 100644
--- a/lib/DBInfoscreen/Controller/Wagenreihung.pm
+++ b/lib/DBInfoscreen/Controller/Wagenreihung.pm
@@ -72,7 +72,7 @@ sub wagenreihung {
e => $exit_side ? substr( $exit_side, 0, 1 ) : '',
tt => $wr->train_type,
tn => $train,
- s => $wr->station_name,
+ s => $wr->station->{name},
p => $wr->platform
};
@@ -168,7 +168,7 @@ sub wagenreihung {
'wagenreihung',
description => sprintf(
'Ist-Wagenreihung %s in %s',
- $title, $wr->station_name
+ $title, $wr->station->{name}
),
wr_error => undef,
title => $title,
@@ -184,7 +184,7 @@ sub wagenreihung {
my ($err) = @_;
$self->handle_wagenreihung_error( $train,
- $err->{error}->{msg} // "Unbekannter Fehler" );
+ $err->{error}->{msg} // $err // "Unbekannter Fehler" );
return;
}
)->wait;
diff --git a/lib/DBInfoscreen/Helper/EFA.pm b/lib/DBInfoscreen/Helper/EFA.pm
index 2a7416e..4e81bc3 100644
--- a/lib/DBInfoscreen/Helper/EFA.pm
+++ b/lib/DBInfoscreen/Helper/EFA.pm
@@ -13,7 +13,6 @@ use Encode qw(decode encode);
use Mojo::JSON qw(decode_json);
use Mojo::Promise;
use Mojo::Util qw(url_escape);
-use XML::LibXML;
sub new {
my ( $class, %opt ) = @_;
diff --git a/lib/DBInfoscreen/Helper/HAFAS.pm b/lib/DBInfoscreen/Helper/HAFAS.pm
index 149bfc9..a55f03f 100644
--- a/lib/DBInfoscreen/Helper/HAFAS.pm
+++ b/lib/DBInfoscreen/Helper/HAFAS.pm
@@ -13,7 +13,6 @@ use Encode qw(decode encode);
use Travel::Status::DE::HAFAS;
use Mojo::JSON qw(decode_json);
use Mojo::Promise;
-use XML::LibXML;
sub new {
my ( $class, %opt ) = @_;
@@ -105,7 +104,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,
{
@@ -119,6 +178,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,
@@ -128,6 +188,7 @@ sub get_route_p {
and
( $stop->dep_cancelled or not $stop->sched_dep )
),
+ %annotation,
}
);
if (
@@ -142,6 +203,32 @@ 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, $hafas );