Loading lib/Travelynx.pm +55 −78 Original line number Diff line number Diff line Loading @@ -994,82 +994,6 @@ sub startup { return; } if ( $journey->{data}{trip_id} and not $journey->{polyline} ) { my ( $origin_eva, $destination_eva, $polyline_str ); $self->hafas->get_polyline_p( $train, $journey->{data}{trip_id} )->then( sub { my ($ret) = @_; my $polyline = $ret->{polyline}; $origin_eva = 0 + $ret->{raw}{origin}{id}; $destination_eva = 0 + $ret->{raw}{destination}{id}; # work around Cache::File turning floats into strings for my $coord ( @{$polyline} ) { @{$coord} = map { 0 + $_ } @{$coord}; } $polyline_str = JSON->new->encode($polyline); my $pl_res = $db->select( 'polylines', ['id'], { origin_eva => $origin_eva, destination_eva => $destination_eva, polyline => $polyline_str }, { limit => 1 } ); my $polyline_id; if ( my $h = $pl_res->hash ) { $polyline_id = $h->{id}; } else { eval { $polyline_id = $db->insert( 'polylines', { origin_eva => $origin_eva, destination_eva => $destination_eva, polyline => $polyline_str }, { returning => 'id' } )->hash->{id}; }; if ($@) { $self->app->log->warn( "add_route_timestamps: insert polyline: $@" ); } } if ($polyline_id) { $self->in_transit->set_polyline_id( uid => $uid, db => $db, polyline_id => $polyline_id ); } return; } )->catch( sub { my ($err) = @_; if ( $err =~ m{extra content at the end}i ) { $self->app->log->debug( "add_route_timestamps: $err"); } else { $self->app->log->warn("add_route_timestamps: $err"); } return; } )->wait; } my ($platform) = ( ( $train->platform // 0 ) =~ m{(\d+)} ); my $route = $journey->{route}; Loading Loading @@ -1136,11 +1060,14 @@ sub startup { ); return $self->hafas->get_route_timestamps_p( trip_id => $trip_id ); train => $train, trip_id => $trip_id, with_polyline => not $journey->{polyline} ); } )->then( sub { my ( $route_data, $journey ) = @_; my ( $route_data, $journey, $polyline ) = @_; for my $station ( @{$route} ) { $station->[1] Loading Loading @@ -1172,6 +1099,56 @@ sub startup { ], him_messages => \@messages, ); if ($polyline) { my $coords = $polyline->{coords}; my $from_eva = $polyline->{from_eva}; my $to_eva = $polyline->{to_eva}; my $polyline_str = JSON->new->encode($coords); my $pl_res = $db->select( 'polylines', ['id'], { origin_eva => $from_eva, destination_eva => $to_eva, polyline => $polyline_str }, { limit => 1 } ); my $polyline_id; if ( my $h = $pl_res->hash ) { $polyline_id = $h->{id}; } else { eval { $polyline_id = $db->insert( 'polylines', { origin_eva => $from_eva, destination_eva => $to_eva, polyline => $polyline_str }, { returning => 'id' } )->hash->{id}; }; if ($@) { $self->app->log->warn( "add_route_timestamps: insert polyline: $@" ); } } if ($polyline_id) { $self->in_transit->set_polyline_id( uid => $uid, db => $db, polyline_id => $polyline_id ); } } return; } )->catch( Loading lib/Travelynx/Helper/HAFAS.pm +40 −95 Original line number Diff line number Diff line Loading @@ -34,97 +34,6 @@ sub new { return bless( \%opt, $class ); } sub get_polyline_p { my ( $self, $train, $trip_id ) = @_; my $line = $train->line // 0; my $backend = $self->{hafas_rest_api}; my $url = "${backend}/trips/${trip_id}?lineName=${line}&polyline=true"; my $cache = $self->{main_cache}; my $promise = Mojo::Promise->new; my $version = $self->{version}; if ( my $content = $cache->thaw($url) ) { return $promise->resolve($content); } my $log_url = $url; $log_url =~ s{://\K[^:]+:[^@]+\@}{***@}; $self->{user_agent}->request_timeout(5)->get_p( $url => $self->{header} ) ->then( sub { my ($tx) = @_; if ( my $err = $tx->error ) { $promise->reject( "hafas->get_polyline_p($log_url) returned HTTP $err->{code} $err->{message}" ); return; } my $body = decode( 'utf-8', $tx->res->body ); my $json = JSON->new->decode($body); my @station_list; my @coordinate_list; for my $feature ( @{ $json->{polyline}{features} } ) { if ( exists $feature->{geometry}{coordinates} ) { my $coord = $feature->{geometry}{coordinates}; if ( exists $feature->{properties}{type} and $feature->{properties}{type} eq 'stop' ) { push( @{$coord}, $feature->{properties}{id} ); push( @station_list, $feature->{properties}{name} ); } push( @coordinate_list, $coord ); } } my $ret = { name => $json->{line}{name} // '?', polyline => [@coordinate_list], raw => $json, }; $cache->freeze( $url, $ret ); # borders (Gr" as in "Grenze") are only returned by HAFAS. # They are not stations. my $iris_stations = join( '|', $train->route ); my $hafas_stations = join( '|', grep { $_ !~ m{(\(Gr\)|\)Gr)$} } @station_list ); # Do not return polyline if it belongs to an entirely different # train. Trains with longer routes (e.g. due to train number # changes, which are handled by HAFAS but left out in IRIS) # are okay though. if ( $iris_stations ne $hafas_stations and index( $hafas_stations, $iris_stations ) == -1 ) { $self->{log}->info( 'Ignoring polyline for ' . $train->line . ": IRIS route does not agree with HAFAS route: $iris_stations != $hafas_stations" ); $promise->reject( "hafas->get_polyline_p($log_url): polyline route mismatch"); } else { $promise->resolve($ret); } return; } )->catch( sub { my ($err) = @_; $promise->reject("hafas->get_polyline_p($log_url): $err"); return; } )->wait; return $promise; } sub get_json_p { my ( $self, $url, %opt ) = @_; Loading Loading @@ -186,14 +95,16 @@ sub get_route_timestamps_p { # name => $opt{train_no}, }, with_polyline => $opt{with_polyline}, cache => $self->{realtime_cache}, promise => 'Mojo::Promise', user_agent => $self->{user_agent}->request_timeout(10) user_agent => $self->{user_agent}->request_timeout(10), )->then( sub { my ($hafas) = @_; my $journey = $hafas->result; my $ret = {}; my $polyline; my $station_is_past = 1; for my $stop ( $journey->route ) { Loading Loading @@ -228,7 +139,41 @@ sub get_route_timestamps_p { $ret->{$name}{isPast} = $station_is_past; } $promise->resolve( $ret, $journey ); if ( $journey->polyline ) { my @station_list; my @coordinate_list; for my $coord ( $journey->polyline ) { if ( $coord->{name} ) { push( @coordinate_list, [ $coord->{lon}, $coord->{lat}, $coord->{eva} ] ); push( @station_list, $coord->{name} ); } else { push( @coordinate_list, [ $coord->{lon}, $coord->{lat} ] ); } } my $iris_stations = join( '|', $opt{train}->route ); my $hafas_stations = join( '|', @station_list ); if ( $iris_stations eq $hafas_stations or index( $hafas_stations, $iris_stations ) != -1 ) { $polyline = { from_eva => ( $journey->route )[0]{eva}, to_eva => ( $journey->route )[-1]{eva}, coords => \@coordinate_list, }; } else { $self->{log}->info( 'Ignoring polyline for ' . $opt{train}->line . ": IRIS route does not agree with HAFAS route: $iris_stations != $hafas_stations" ); } } $promise->resolve( $ret, $journey, $polyline ); return; } )->catch( Loading Loading
lib/Travelynx.pm +55 −78 Original line number Diff line number Diff line Loading @@ -994,82 +994,6 @@ sub startup { return; } if ( $journey->{data}{trip_id} and not $journey->{polyline} ) { my ( $origin_eva, $destination_eva, $polyline_str ); $self->hafas->get_polyline_p( $train, $journey->{data}{trip_id} )->then( sub { my ($ret) = @_; my $polyline = $ret->{polyline}; $origin_eva = 0 + $ret->{raw}{origin}{id}; $destination_eva = 0 + $ret->{raw}{destination}{id}; # work around Cache::File turning floats into strings for my $coord ( @{$polyline} ) { @{$coord} = map { 0 + $_ } @{$coord}; } $polyline_str = JSON->new->encode($polyline); my $pl_res = $db->select( 'polylines', ['id'], { origin_eva => $origin_eva, destination_eva => $destination_eva, polyline => $polyline_str }, { limit => 1 } ); my $polyline_id; if ( my $h = $pl_res->hash ) { $polyline_id = $h->{id}; } else { eval { $polyline_id = $db->insert( 'polylines', { origin_eva => $origin_eva, destination_eva => $destination_eva, polyline => $polyline_str }, { returning => 'id' } )->hash->{id}; }; if ($@) { $self->app->log->warn( "add_route_timestamps: insert polyline: $@" ); } } if ($polyline_id) { $self->in_transit->set_polyline_id( uid => $uid, db => $db, polyline_id => $polyline_id ); } return; } )->catch( sub { my ($err) = @_; if ( $err =~ m{extra content at the end}i ) { $self->app->log->debug( "add_route_timestamps: $err"); } else { $self->app->log->warn("add_route_timestamps: $err"); } return; } )->wait; } my ($platform) = ( ( $train->platform // 0 ) =~ m{(\d+)} ); my $route = $journey->{route}; Loading Loading @@ -1136,11 +1060,14 @@ sub startup { ); return $self->hafas->get_route_timestamps_p( trip_id => $trip_id ); train => $train, trip_id => $trip_id, with_polyline => not $journey->{polyline} ); } )->then( sub { my ( $route_data, $journey ) = @_; my ( $route_data, $journey, $polyline ) = @_; for my $station ( @{$route} ) { $station->[1] Loading Loading @@ -1172,6 +1099,56 @@ sub startup { ], him_messages => \@messages, ); if ($polyline) { my $coords = $polyline->{coords}; my $from_eva = $polyline->{from_eva}; my $to_eva = $polyline->{to_eva}; my $polyline_str = JSON->new->encode($coords); my $pl_res = $db->select( 'polylines', ['id'], { origin_eva => $from_eva, destination_eva => $to_eva, polyline => $polyline_str }, { limit => 1 } ); my $polyline_id; if ( my $h = $pl_res->hash ) { $polyline_id = $h->{id}; } else { eval { $polyline_id = $db->insert( 'polylines', { origin_eva => $from_eva, destination_eva => $to_eva, polyline => $polyline_str }, { returning => 'id' } )->hash->{id}; }; if ($@) { $self->app->log->warn( "add_route_timestamps: insert polyline: $@" ); } } if ($polyline_id) { $self->in_transit->set_polyline_id( uid => $uid, db => $db, polyline_id => $polyline_id ); } } return; } )->catch( Loading
lib/Travelynx/Helper/HAFAS.pm +40 −95 Original line number Diff line number Diff line Loading @@ -34,97 +34,6 @@ sub new { return bless( \%opt, $class ); } sub get_polyline_p { my ( $self, $train, $trip_id ) = @_; my $line = $train->line // 0; my $backend = $self->{hafas_rest_api}; my $url = "${backend}/trips/${trip_id}?lineName=${line}&polyline=true"; my $cache = $self->{main_cache}; my $promise = Mojo::Promise->new; my $version = $self->{version}; if ( my $content = $cache->thaw($url) ) { return $promise->resolve($content); } my $log_url = $url; $log_url =~ s{://\K[^:]+:[^@]+\@}{***@}; $self->{user_agent}->request_timeout(5)->get_p( $url => $self->{header} ) ->then( sub { my ($tx) = @_; if ( my $err = $tx->error ) { $promise->reject( "hafas->get_polyline_p($log_url) returned HTTP $err->{code} $err->{message}" ); return; } my $body = decode( 'utf-8', $tx->res->body ); my $json = JSON->new->decode($body); my @station_list; my @coordinate_list; for my $feature ( @{ $json->{polyline}{features} } ) { if ( exists $feature->{geometry}{coordinates} ) { my $coord = $feature->{geometry}{coordinates}; if ( exists $feature->{properties}{type} and $feature->{properties}{type} eq 'stop' ) { push( @{$coord}, $feature->{properties}{id} ); push( @station_list, $feature->{properties}{name} ); } push( @coordinate_list, $coord ); } } my $ret = { name => $json->{line}{name} // '?', polyline => [@coordinate_list], raw => $json, }; $cache->freeze( $url, $ret ); # borders (Gr" as in "Grenze") are only returned by HAFAS. # They are not stations. my $iris_stations = join( '|', $train->route ); my $hafas_stations = join( '|', grep { $_ !~ m{(\(Gr\)|\)Gr)$} } @station_list ); # Do not return polyline if it belongs to an entirely different # train. Trains with longer routes (e.g. due to train number # changes, which are handled by HAFAS but left out in IRIS) # are okay though. if ( $iris_stations ne $hafas_stations and index( $hafas_stations, $iris_stations ) == -1 ) { $self->{log}->info( 'Ignoring polyline for ' . $train->line . ": IRIS route does not agree with HAFAS route: $iris_stations != $hafas_stations" ); $promise->reject( "hafas->get_polyline_p($log_url): polyline route mismatch"); } else { $promise->resolve($ret); } return; } )->catch( sub { my ($err) = @_; $promise->reject("hafas->get_polyline_p($log_url): $err"); return; } )->wait; return $promise; } sub get_json_p { my ( $self, $url, %opt ) = @_; Loading Loading @@ -186,14 +95,16 @@ sub get_route_timestamps_p { # name => $opt{train_no}, }, with_polyline => $opt{with_polyline}, cache => $self->{realtime_cache}, promise => 'Mojo::Promise', user_agent => $self->{user_agent}->request_timeout(10) user_agent => $self->{user_agent}->request_timeout(10), )->then( sub { my ($hafas) = @_; my $journey = $hafas->result; my $ret = {}; my $polyline; my $station_is_past = 1; for my $stop ( $journey->route ) { Loading Loading @@ -228,7 +139,41 @@ sub get_route_timestamps_p { $ret->{$name}{isPast} = $station_is_past; } $promise->resolve( $ret, $journey ); if ( $journey->polyline ) { my @station_list; my @coordinate_list; for my $coord ( $journey->polyline ) { if ( $coord->{name} ) { push( @coordinate_list, [ $coord->{lon}, $coord->{lat}, $coord->{eva} ] ); push( @station_list, $coord->{name} ); } else { push( @coordinate_list, [ $coord->{lon}, $coord->{lat} ] ); } } my $iris_stations = join( '|', $opt{train}->route ); my $hafas_stations = join( '|', @station_list ); if ( $iris_stations eq $hafas_stations or index( $hafas_stations, $iris_stations ) != -1 ) { $polyline = { from_eva => ( $journey->route )[0]{eva}, to_eva => ( $journey->route )[-1]{eva}, coords => \@coordinate_list, }; } else { $self->{log}->info( 'Ignoring polyline for ' . $opt{train}->line . ": IRIS route does not agree with HAFAS route: $iris_stations != $hafas_stations" ); } } $promise->resolve( $ret, $journey, $polyline ); return; } )->catch( Loading