diff options
-rw-r--r-- | cpanfile | 2 | ||||
-rwxr-xr-x | lib/Travelynx.pm | 82 | ||||
-rw-r--r-- | lib/Travelynx/Helper/HAFAS.pm | 22 | ||||
-rw-r--r-- | lib/Travelynx/Model/InTransit.pm | 57 |
4 files changed, 93 insertions, 70 deletions
@@ -14,7 +14,7 @@ requires 'Mojolicious::Plugin::OAuth2'; requires 'Mojo::Pg'; requires 'Text::CSV'; requires 'Text::Markdown'; -requires 'Travel::Status::DE::DBWagenreihung', '0.12'; +requires 'Travel::Status::DE::DBWagenreihung', '== 0.12'; requires 'Travel::Status::DE::HAFAS', '>= 5.03'; requires 'Travel::Status::DE::IRIS'; requires 'UUID::Tiny'; diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm index 4749d65..85eed6d 100755 --- a/lib/Travelynx.pm +++ b/lib/Travelynx.pm @@ -1243,6 +1243,7 @@ sub startup { my $route = $in_transit->{route}; + # TODO get_tripid_p is only needed on the first call, afterwards the tripid is known. $self->hafas->get_tripid_p( train => $train )->then( sub { my ($trip_id) = @_; @@ -1253,7 +1254,7 @@ sub startup { data => { trip_id => $trip_id } ); - return $self->hafas->get_route_timestamps_p( + return $self->hafas->get_route_p( train => $train, trip_id => $trip_id, with_polyline => ( @@ -1264,42 +1265,53 @@ sub startup { } )->then( sub { - my ( $route_data, $journey, $polyline ) = @_; - - for my $station ( @{$route} ) { - if ( $station->[0] - =~ m{^Betriebsstelle nicht bekannt (\d+)$} ) - { - my $eva = $1; - if ( $route_data->{$eva} ) { - $station->[0] = $route_data->{$eva}{name}; - $station->[1] = $route_data->{$eva}{eva}; - } - } - if ( my $sd = $route_data->{ $station->[0] } ) { - $station->[1] = $sd->{eva}; - if ( $station->[2]{isAdditional} ) { - $sd->{isAdditional} = 1; - } - if ( $station->[2]{isCancelled} ) { - $sd->{isCancelled} = 1; - } - - # keep rt_dep / rt_arr if they are no longer present - my %old; - for my $k (qw(rt_arr rt_dep arr_delay dep_delay)) { - $old{$k} = $station->[2]{$k}; - } - $station->[2] = $sd; - if ( not $station->[2]{rt_arr} ) { - $station->[2]{rt_arr} = $old{rt_arr}; - $station->[2]{arr_delay} = $old{arr_delay}; + my ( $new_route, $journey, $polyline ) = @_; + my $db_route; + + for my $i ( 0 .. $#{$new_route} ) { + my $old_name = $route->[$i][0]; + my $old_eva = $route->[$i][1]; + my $old_entry = $route->[$i][2]; + my $new_name = $new_route->[$i]->{name}; + my $new_eva = $new_route->[$i]->{eva}; + my $new_entry = $new_route->[$i]; + + if ( defined $old_name and $old_name eq $new_name ) { + if ( $old_entry->{rt_arr} + and not $new_entry->{rt_arr} ) + { + $new_entry->{rt_arr} = $old_entry->{rt_arr}; + $new_entry->{arr_delay} + = $old_entry->{arr_delay}; } - if ( not $station->[2]{rt_dep} ) { - $station->[2]{rt_dep} = $old{rt_dep}; - $station->[2]{dep_delay} = $old{dep_delay}; + if ( $old_entry->{rt_dep} + and not $new_entry->{rt_dep} ) + { + $new_entry->{rt_dep} = $old_entry->{rt_dep}; + $new_entry->{dep_delay} + = $old_entry->{dep_delay}; } } + + push( + @{$db_route}, + [ + $new_name, + $new_eva, + { + sched_arr => $new_entry->{sched_arr}, + rt_arr => $new_entry->{rt_arr}, + arr_delay => $new_entry->{arr_delay}, + sched_dep => $new_entry->{sched_dep}, + rt_dep => $new_entry->{rt_dep}, + dep_delay => $new_entry->{dep_delay}, + tz_offset => $new_entry->{tz_offset}, + isAdditional => $new_entry->{isAdditional}, + isCancelled => $new_entry->{isCancelled}, + load => $new_entry->{load}, + } + ] + ); } my @messages; @@ -1318,7 +1330,7 @@ sub startup { $self->in_transit->set_route_data( uid => $uid, db => $db, - route => $route, + route => $db_route, delay_messages => [ map { [ $_->[0]->epoch, $_->[1] ] } $train->delay_messages diff --git a/lib/Travelynx/Helper/HAFAS.pm b/lib/Travelynx/Helper/HAFAS.pm index 7671d78..538c8ea 100644 --- a/lib/Travelynx/Helper/HAFAS.pm +++ b/lib/Travelynx/Helper/HAFAS.pm @@ -199,7 +199,7 @@ sub get_journey_p { return $promise; } -sub get_route_timestamps_p { +sub get_route_p { my ( $self, %opt ) = @_; my $promise = Mojo::Promise->new; @@ -219,13 +219,12 @@ sub get_route_timestamps_p { sub { my ($hafas) = @_; my $journey = $hafas->result; - my $ret = {}; + my $ret = []; my $polyline; my $station_is_past = 1; for my $stop ( $journey->route ) { - my $name = $stop->loc->name; - $ret->{$name} = $ret->{ $stop->loc->eva } = { + my $entry = { name => $stop->loc->name, eva => $stop->loc->eva, sched_arr => _epoch( $stop->sched_arr ), @@ -237,26 +236,27 @@ sub get_route_timestamps_p { load => $stop->load }; if ( $stop->tz_offset ) { - $ret->{$name}{tz_offset} = $stop->tz_offset; + $entry->{tz_offset} = $stop->tz_offset; } if ( ( $stop->arr_cancelled or not $stop->sched_arr ) and ( $stop->dep_cancelled or not $stop->sched_dep ) ) { - $ret->{$name}{isCancelled} = 1; + $entry->{isCancelled} = 1; } if ( $station_is_past - and not $ret->{$name}{isCancelled} + and not $entry->{isCancelled} and $now->epoch < ( - $ret->{$name}{rt_arr} // $ret->{$name}{rt_dep} - // $ret->{$name}{sched_arr} - // $ret->{$name}{sched_dep} // $now->epoch + $entry->{rt_arr} // $entry->{rt_dep} + // $entry->{sched_arr} // $entry->{sched_dep} + // $now->epoch ) ) { $station_is_past = 0; } - $ret->{$name}{isPast} = $station_is_past; + $entry->{isPast} = $station_is_past; + push( @{$ret}, $entry ); } if ( $journey->polyline ) { diff --git a/lib/Travelynx/Model/InTransit.pm b/lib/Travelynx/Model/InTransit.pm index 69026ac..d825826 100644 --- a/lib/Travelynx/Model/InTransit.pm +++ b/lib/Travelynx/Model/InTransit.pm @@ -47,6 +47,16 @@ sub epoch_to_dt { ); } +sub epoch_or_dt_to_dt { + my ($input) = @_; + + if ( ref($input) eq 'DateTime' ) { + return $input; + } + + return epoch_to_dt($input); +} + sub new { my ( $class, %opt ) = @_; @@ -211,8 +221,15 @@ sub postprocess { if ($is_after) { push( @route_after, $station ); } - if ( $ret->{dep_name} - and $station->[0] eq $ret->{dep_name} ) + + # Note that the departure stop may be present more than once in @route, + # e.g. when traveling along ring lines such as S41 / S42 in Berlin. + if ( + $ret->{dep_name} + and $station->[0] eq $ret->{dep_name} + and not($station->[2]{sched_dep} + and $station->[2]{sched_dep} < $ret->{sched_dep_ts} ) + ) { $is_after = 1; if ( @{$station} > 1 and not $dep_info ) { @@ -273,31 +290,25 @@ sub postprocess { # station is present several times in a train's route, e.g. # for Frankfurt Flughafen in some nightly connections. my $times = $station->[2] // {}; - if ( $times->{sched_arr} - and ref( $times->{sched_arr} ) ne 'DateTime' ) - { - $times->{sched_arr} - = epoch_to_dt( $times->{sched_arr} ); - if ( $times->{rt_arr} ) { - $times->{rt_arr} - = epoch_to_dt( $times->{rt_arr} ); - $times->{arr_delay} - = $times->{rt_arr}->epoch - $times->{sched_arr}->epoch; + for my $key (qw(sched_arr rt_arr sched_dep rt_dep)) { + if ( $times->{$key} ) { + $times->{$key} + = epoch_or_dt_to_dt( $times->{$key} ); } + } + if ( $times->{sched_arr} and $times->{rt_arr} ) { + $times->{arr_delay} + = $times->{rt_arr}->epoch - $times->{sched_arr}->epoch; + } + if ( $times->{sched_arr} or $times->{rt_arr} ) { $times->{arr} = $times->{rt_arr} || $times->{sched_arr}; $times->{arr_countdown} = $times->{arr}->epoch - $epoch; } - if ( $times->{sched_dep} - and ref( $times->{sched_dep} ) ne 'DateTime' ) - { - $times->{sched_dep} - = epoch_to_dt( $times->{sched_dep} ); - if ( $times->{rt_dep} ) { - $times->{rt_dep} - = epoch_to_dt( $times->{rt_dep} ); - $times->{dep_delay} - = $times->{rt_dep}->epoch - $times->{sched_dep}->epoch; - } + if ( $times->{sched_dep} and $times->{rt_dep} ) { + $times->{dep_delay} + = $times->{rt_dep}->epoch - $times->{sched_dep}->epoch; + } + if ( $times->{sched_dep} or $times->{rt_dep} ) { $times->{dep} = $times->{rt_dep} || $times->{sched_dep}; $times->{dep_countdown} = $times->{dep}->epoch - $epoch; } |