Loading lib/Travelynx.pm +29 −20 Original line number Diff line number Diff line Loading @@ -679,7 +679,7 @@ sub startup { @{ $journey->{route} } ) { $station_data = $station_data->[1]; $station_data = $station_data->[2]; if ( $station_data->{sched_arr} ) { my $sched_arr = epoch_to_dt( $station_data->{sched_arr} ); Loading Loading @@ -1040,10 +1040,19 @@ sub startup { my $eva = $1; if ( $route_data->{$eva} ) { $station->[0] = $route_data->{$eva}{name}; $station->[1] = $route_data->{$eva}{eva}; } } $station->[1] = $route_data->{ $station->[0] }; 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; } $station->[2] = $sd; } } my @messages; Loading Loading @@ -1338,13 +1347,13 @@ sub startup { for my $station ( @{ $journey->{route_after} } ) { my $station_desc = $station->[0]; if ( $station->[1]{rt_arr} ) { $station_desc .= $station->[1]{sched_arr}->strftime(';%s'); $station_desc .= $station->[1]{rt_arr}->strftime(';%s'); if ( $station->[1]{rt_dep} ) { if ( $station->[2]{rt_arr} ) { $station_desc .= $station->[2]{sched_arr}->strftime(';%s'); $station_desc .= $station->[2]{rt_arr}->strftime(';%s'); if ( $station->[2]{rt_dep} ) { $station_desc .= $station->[1]{sched_dep}->strftime(';%s'); $station_desc .= $station->[1]{rt_dep}->strftime(';%s'); .= $station->[2]{sched_dep}->strftime(';%s'); $station_desc .= $station->[2]{rt_dep}->strftime(';%s'); } else { $station_desc .= ';0;0'; Loading Loading @@ -1414,7 +1423,7 @@ sub startup { { $is_after = 1; if ( @{$station} > 1 and not $dep_info ) { $dep_info = $station->[1]; $dep_info = $station->[2]; } } } Loading Loading @@ -1499,11 +1508,11 @@ sub startup { for my $station (@route_after) { if ( @{$station} > 1 ) { # Note: $station->[1]{sched_arr} may already have been # Note: $station->[2]{sched_arr} may already have been # converted to a DateTime object. This can happen when a # station is present several times in a train's route, e.g. # for Frankfurt Flughafen in some nightly connections. my $times = $station->[1]; my $times = $station->[2] // {}; if ( $times->{sched_arr} and ref( $times->{sched_arr} ) ne 'DateTime' ) { Loading Loading @@ -1753,17 +1762,17 @@ sub startup { @{ $ret->{intermediateStops} }, { name => $stop->[0], scheduledArrival => $stop->[1]{sched_arr} ? $stop->[1]{sched_arr}->epoch scheduledArrival => $stop->[2]{sched_arr} ? $stop->[2]{sched_arr}->epoch : undef, realArrival => $stop->[1]{rt_arr} ? $stop->[1]{rt_arr}->epoch realArrival => $stop->[2]{rt_arr} ? $stop->[2]{rt_arr}->epoch : undef, scheduledDeparture => $stop->[1]{sched_dep} ? $stop->[1]{sched_dep}->epoch scheduledDeparture => $stop->[2]{sched_dep} ? $stop->[2]{sched_dep}->epoch : undef, realDeparture => $stop->[1]{rt_dep} ? $stop->[1]{rt_dep}->epoch realDeparture => $stop->[2]{rt_dep} ? $stop->[2]{rt_dep}->epoch : undef, } ); Loading lib/Travelynx/Command/database.pm +76 −0 Original line number Diff line number Diff line Loading @@ -1212,6 +1212,82 @@ my @migrations = ( } ); }, # v29 -> v30 # change layout of stops in in_transit and journeys "route" lists. # Old layout: A mixture of [name, {data}, undef/"additional"/"cancelled"], [name, timestamp, timestamp], and [name] # New layout: [name, eva, {data including isAdditional/isCancelled}] # Combined with a maintenance task that adds eva IDs to past stops, this will allow for more resilience against station name changes. # It will also help increase the performance of distance and map calculation sub { my ($db) = @_; my $json = JSON->new; say 'Adjusting route schema, this may take a while ...'; my $res = $db->select( 'in_transit_str', '*' ); while ( my $row = $res->expand->hash ) { my @new_route; for my $stop ( @{ $row->{route} } ) { push( @new_route, [ $stop->[0], undef, {} ] ); } $db->update( 'in_transit', { route => $json->encode( \@new_route ) }, { user_id => $row->{user_id} } ); } my $total = $db->select( 'journeys', 'count(*) as count' )->hash->{count}; my $count = 0; $res = $db->select( 'journeys_str', '*' ); while ( my $row = $res->expand->hash ) { my $id = $row->{journey_id}; my @new_route; for my $stop ( @{ $row->{route} } ) { if ( @{$stop} == 1 ) { push( @new_route, [ $stop->[0], undef, {} ] ); } elsif ( ( not defined $stop->[1] or $stop->[1] =~ m{ ^ \d+ $ }x ) and ( not defined $stop->[2] or $stop->[2] =~ m{ ^ \d+ $ }x ) ) { push( @new_route, [ $stop->[0], undef, {} ] ); } else { my $attr = $stop->[1] // {}; if ( $stop->[2] and $stop->[2] eq 'additional' ) { $attr->{isAdditional} = 1; } elsif ( $stop->[2] and $stop->[2] eq 'cancelled' ) { $attr->{isCancelled} = 1; } push( @new_route, [ $stop->[0], undef, $attr ] ); } } $db->update( 'journeys', { route => $json->encode( \@new_route ) }, { id => $row->{journey_id} } ); if ( $count++ % 10000 == 0 ) { printf( " %2.0f%% complete\n", $count * 100 / $total ); } } say ' done'; $db->query( qq{ update schema_version set version = 30; } ); }, ); sub sync_stations { Loading lib/Travelynx/Helper/HAFAS.pm +15 −15 Original line number Diff line number Diff line Loading @@ -134,13 +134,13 @@ sub get_route_timestamps_p { arr_delay => $stop->{arr_delay}, dep_delay => $stop->{dep_delay}, eva => $stop->{eva}, load => $stop->{load}, isCancelled => ( ( $stop->{arr_cancelled} or not $stop->{sched_arr} ) and ( $stop->{dep_cancelled} or not $stop->{sched_dep} ) ), load => $stop->{load} }; if ( ( $stop->{arr_cancelled} or not $stop->{sched_arr} ) and ( $stop->{dep_cancelled} or not $stop->{sched_dep} ) ) { $ret->{$name}{isCancelled} = 1; } if ( $station_is_past and not $ret->{$name}{isCancelled} Loading lib/Travelynx/Helper/IRIS.pm +13 −5 Original line number Diff line number Diff line Loading @@ -179,27 +179,35 @@ sub route_diff { while ( $route_idx <= $#route and $sched_idx <= $#sched_route ) { if ( $route[$route_idx] eq $sched_route[$sched_idx] ) { push( @json_route, [ $route[$route_idx], {}, undef ] ); push( @json_route, [ $route[$route_idx], undef, {} ] ); $route_idx++; $sched_idx++; } # this branch is inefficient, but won't be taken frequently elsif ( not( grep { $_ eq $route[$route_idx] } @sched_route ) ) { push( @json_route, [ $route[$route_idx], {}, 'additional' ], ); push( @json_route, [ $route[$route_idx], undef, { isAdditional => 1 } ], ); $route_idx++; } else { push( @json_route, [ $sched_route[$sched_idx], {}, 'cancelled' ], ); push( @json_route, [ $sched_route[$sched_idx], undef, { isCancelled => 1 } ], ); $sched_idx++; } } while ( $route_idx <= $#route ) { push( @json_route, [ $route[$route_idx], {}, 'additional' ], ); push( @json_route, [ $route[$route_idx], undef, { isAdditional => 1 } ], ); $route_idx++; } while ( $sched_idx <= $#sched_route ) { push( @json_route, [ $sched_route[$sched_idx], {}, 'cancelled' ], ); push( @json_route, [ $sched_route[$sched_idx], undef, { isCancelled => 1 } ], ); $sched_idx++; } return @json_route; Loading lib/Travelynx/Model/Journeys.pm +6 −5 Original line number Diff line number Diff line Loading @@ -162,7 +162,7 @@ sub add { my @route; if ( not $route_has_start ) { push( @route, [ $dep_station->{name}, {}, undef ] ); push( @route, [ $dep_station->{name}, $dep_station->{eva}, {} ] ); } if ( $opt{route} ) { Loading @@ -170,10 +170,11 @@ sub add { for my $station ( @{ $opt{route} } ) { my $station_info = $self->{stations}->search($station); if ($station_info) { push( @route, [ $station_info->{name}, {}, undef ] ); push( @route, [ $station_info->{name}, $station_info->{eva}, {} ] ); } else { push( @route, [ $station, {}, undef ] ); push( @route, [ $station, undef, {} ] ); push( @unknown_stations, $station ); } } Loading @@ -192,7 +193,7 @@ sub add { } if ( not $route_has_stop ) { push( @route, [ $arr_station->{name}, {}, undef ] ); push( @route, [ $arr_station->{name}, $arr_station->{eva}, {} ] ); } my $entry = { Loading Loading @@ -358,7 +359,7 @@ sub update { )->rows; } if ( exists $opt{route} ) { my @new_route = map { [ $_, {}, undef ] } @{ $opt{route} }; my @new_route = map { [ $_, undef, {} ] } @{ $opt{route} }; $rows = $db->update( 'journeys', { Loading Loading
lib/Travelynx.pm +29 −20 Original line number Diff line number Diff line Loading @@ -679,7 +679,7 @@ sub startup { @{ $journey->{route} } ) { $station_data = $station_data->[1]; $station_data = $station_data->[2]; if ( $station_data->{sched_arr} ) { my $sched_arr = epoch_to_dt( $station_data->{sched_arr} ); Loading Loading @@ -1040,10 +1040,19 @@ sub startup { my $eva = $1; if ( $route_data->{$eva} ) { $station->[0] = $route_data->{$eva}{name}; $station->[1] = $route_data->{$eva}{eva}; } } $station->[1] = $route_data->{ $station->[0] }; 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; } $station->[2] = $sd; } } my @messages; Loading Loading @@ -1338,13 +1347,13 @@ sub startup { for my $station ( @{ $journey->{route_after} } ) { my $station_desc = $station->[0]; if ( $station->[1]{rt_arr} ) { $station_desc .= $station->[1]{sched_arr}->strftime(';%s'); $station_desc .= $station->[1]{rt_arr}->strftime(';%s'); if ( $station->[1]{rt_dep} ) { if ( $station->[2]{rt_arr} ) { $station_desc .= $station->[2]{sched_arr}->strftime(';%s'); $station_desc .= $station->[2]{rt_arr}->strftime(';%s'); if ( $station->[2]{rt_dep} ) { $station_desc .= $station->[1]{sched_dep}->strftime(';%s'); $station_desc .= $station->[1]{rt_dep}->strftime(';%s'); .= $station->[2]{sched_dep}->strftime(';%s'); $station_desc .= $station->[2]{rt_dep}->strftime(';%s'); } else { $station_desc .= ';0;0'; Loading Loading @@ -1414,7 +1423,7 @@ sub startup { { $is_after = 1; if ( @{$station} > 1 and not $dep_info ) { $dep_info = $station->[1]; $dep_info = $station->[2]; } } } Loading Loading @@ -1499,11 +1508,11 @@ sub startup { for my $station (@route_after) { if ( @{$station} > 1 ) { # Note: $station->[1]{sched_arr} may already have been # Note: $station->[2]{sched_arr} may already have been # converted to a DateTime object. This can happen when a # station is present several times in a train's route, e.g. # for Frankfurt Flughafen in some nightly connections. my $times = $station->[1]; my $times = $station->[2] // {}; if ( $times->{sched_arr} and ref( $times->{sched_arr} ) ne 'DateTime' ) { Loading Loading @@ -1753,17 +1762,17 @@ sub startup { @{ $ret->{intermediateStops} }, { name => $stop->[0], scheduledArrival => $stop->[1]{sched_arr} ? $stop->[1]{sched_arr}->epoch scheduledArrival => $stop->[2]{sched_arr} ? $stop->[2]{sched_arr}->epoch : undef, realArrival => $stop->[1]{rt_arr} ? $stop->[1]{rt_arr}->epoch realArrival => $stop->[2]{rt_arr} ? $stop->[2]{rt_arr}->epoch : undef, scheduledDeparture => $stop->[1]{sched_dep} ? $stop->[1]{sched_dep}->epoch scheduledDeparture => $stop->[2]{sched_dep} ? $stop->[2]{sched_dep}->epoch : undef, realDeparture => $stop->[1]{rt_dep} ? $stop->[1]{rt_dep}->epoch realDeparture => $stop->[2]{rt_dep} ? $stop->[2]{rt_dep}->epoch : undef, } ); Loading
lib/Travelynx/Command/database.pm +76 −0 Original line number Diff line number Diff line Loading @@ -1212,6 +1212,82 @@ my @migrations = ( } ); }, # v29 -> v30 # change layout of stops in in_transit and journeys "route" lists. # Old layout: A mixture of [name, {data}, undef/"additional"/"cancelled"], [name, timestamp, timestamp], and [name] # New layout: [name, eva, {data including isAdditional/isCancelled}] # Combined with a maintenance task that adds eva IDs to past stops, this will allow for more resilience against station name changes. # It will also help increase the performance of distance and map calculation sub { my ($db) = @_; my $json = JSON->new; say 'Adjusting route schema, this may take a while ...'; my $res = $db->select( 'in_transit_str', '*' ); while ( my $row = $res->expand->hash ) { my @new_route; for my $stop ( @{ $row->{route} } ) { push( @new_route, [ $stop->[0], undef, {} ] ); } $db->update( 'in_transit', { route => $json->encode( \@new_route ) }, { user_id => $row->{user_id} } ); } my $total = $db->select( 'journeys', 'count(*) as count' )->hash->{count}; my $count = 0; $res = $db->select( 'journeys_str', '*' ); while ( my $row = $res->expand->hash ) { my $id = $row->{journey_id}; my @new_route; for my $stop ( @{ $row->{route} } ) { if ( @{$stop} == 1 ) { push( @new_route, [ $stop->[0], undef, {} ] ); } elsif ( ( not defined $stop->[1] or $stop->[1] =~ m{ ^ \d+ $ }x ) and ( not defined $stop->[2] or $stop->[2] =~ m{ ^ \d+ $ }x ) ) { push( @new_route, [ $stop->[0], undef, {} ] ); } else { my $attr = $stop->[1] // {}; if ( $stop->[2] and $stop->[2] eq 'additional' ) { $attr->{isAdditional} = 1; } elsif ( $stop->[2] and $stop->[2] eq 'cancelled' ) { $attr->{isCancelled} = 1; } push( @new_route, [ $stop->[0], undef, $attr ] ); } } $db->update( 'journeys', { route => $json->encode( \@new_route ) }, { id => $row->{journey_id} } ); if ( $count++ % 10000 == 0 ) { printf( " %2.0f%% complete\n", $count * 100 / $total ); } } say ' done'; $db->query( qq{ update schema_version set version = 30; } ); }, ); sub sync_stations { Loading
lib/Travelynx/Helper/HAFAS.pm +15 −15 Original line number Diff line number Diff line Loading @@ -134,13 +134,13 @@ sub get_route_timestamps_p { arr_delay => $stop->{arr_delay}, dep_delay => $stop->{dep_delay}, eva => $stop->{eva}, load => $stop->{load}, isCancelled => ( ( $stop->{arr_cancelled} or not $stop->{sched_arr} ) and ( $stop->{dep_cancelled} or not $stop->{sched_dep} ) ), load => $stop->{load} }; if ( ( $stop->{arr_cancelled} or not $stop->{sched_arr} ) and ( $stop->{dep_cancelled} or not $stop->{sched_dep} ) ) { $ret->{$name}{isCancelled} = 1; } if ( $station_is_past and not $ret->{$name}{isCancelled} Loading
lib/Travelynx/Helper/IRIS.pm +13 −5 Original line number Diff line number Diff line Loading @@ -179,27 +179,35 @@ sub route_diff { while ( $route_idx <= $#route and $sched_idx <= $#sched_route ) { if ( $route[$route_idx] eq $sched_route[$sched_idx] ) { push( @json_route, [ $route[$route_idx], {}, undef ] ); push( @json_route, [ $route[$route_idx], undef, {} ] ); $route_idx++; $sched_idx++; } # this branch is inefficient, but won't be taken frequently elsif ( not( grep { $_ eq $route[$route_idx] } @sched_route ) ) { push( @json_route, [ $route[$route_idx], {}, 'additional' ], ); push( @json_route, [ $route[$route_idx], undef, { isAdditional => 1 } ], ); $route_idx++; } else { push( @json_route, [ $sched_route[$sched_idx], {}, 'cancelled' ], ); push( @json_route, [ $sched_route[$sched_idx], undef, { isCancelled => 1 } ], ); $sched_idx++; } } while ( $route_idx <= $#route ) { push( @json_route, [ $route[$route_idx], {}, 'additional' ], ); push( @json_route, [ $route[$route_idx], undef, { isAdditional => 1 } ], ); $route_idx++; } while ( $sched_idx <= $#sched_route ) { push( @json_route, [ $sched_route[$sched_idx], {}, 'cancelled' ], ); push( @json_route, [ $sched_route[$sched_idx], undef, { isCancelled => 1 } ], ); $sched_idx++; } return @json_route; Loading
lib/Travelynx/Model/Journeys.pm +6 −5 Original line number Diff line number Diff line Loading @@ -162,7 +162,7 @@ sub add { my @route; if ( not $route_has_start ) { push( @route, [ $dep_station->{name}, {}, undef ] ); push( @route, [ $dep_station->{name}, $dep_station->{eva}, {} ] ); } if ( $opt{route} ) { Loading @@ -170,10 +170,11 @@ sub add { for my $station ( @{ $opt{route} } ) { my $station_info = $self->{stations}->search($station); if ($station_info) { push( @route, [ $station_info->{name}, {}, undef ] ); push( @route, [ $station_info->{name}, $station_info->{eva}, {} ] ); } else { push( @route, [ $station, {}, undef ] ); push( @route, [ $station, undef, {} ] ); push( @unknown_stations, $station ); } } Loading @@ -192,7 +193,7 @@ sub add { } if ( not $route_has_stop ) { push( @route, [ $arr_station->{name}, {}, undef ] ); push( @route, [ $arr_station->{name}, $arr_station->{eva}, {} ] ); } my $entry = { Loading Loading @@ -358,7 +359,7 @@ sub update { )->rows; } if ( exists $opt{route} ) { my @new_route = map { [ $_, {}, undef ] } @{ $opt{route} }; my @new_route = map { [ $_, undef, {} ] } @{ $opt{route} }; $rows = $db->update( 'journeys', { Loading