diff options
| -rwxr-xr-x | lib/Travelynx.pm | 6 | ||||
| -rw-r--r-- | lib/Travelynx/Command/work.pm | 151 | ||||
| -rwxr-xr-x | lib/Travelynx/Controller/Traveling.pm | 681 | ||||
| -rw-r--r-- | lib/Travelynx/Helper/DBRIS.pm | 94 | ||||
| -rw-r--r-- | lib/Travelynx/Helper/EFA.pm | 80 | ||||
| -rw-r--r-- | lib/Travelynx/Helper/IRIS.pm | 80 | ||||
| -rwxr-xr-x | lib/Travelynx/Model/Journeys.pm | 4 | ||||
| -rw-r--r-- | share/locales/de_DE.po | 6 | ||||
| -rw-r--r-- | share/locales/en_GB.po | 5 | ||||
| -rw-r--r-- | templates/_cancelled_departure.html.ep | 4 | ||||
| -rw-r--r-- | templates/_checked_in.html.ep | 19 | ||||
| -rw-r--r-- | templates/_checked_out.html.ep | 10 | ||||
| -rw-r--r-- | templates/_connections.html.ep | 76 | ||||
| -rw-r--r-- | templates/_connections_dbris.html.ep (renamed from templates/_suggestions_dbris.html.ep) | 30 | ||||
| -rw-r--r-- | templates/_connections_efa.html.ep (renamed from templates/_suggestions_efa.html.ep) | 30 | ||||
| -rw-r--r-- | templates/_connections_hafas.html.ep | 57 | ||||
| -rw-r--r-- | templates/_connections_iris.html.ep | 44 | ||||
| -rw-r--r-- | templates/changelog.html.ep | 16 | ||||
| -rw-r--r-- | templates/departures.html.ep | 19 | ||||
| -rw-r--r-- | templates/use_history.html.ep | 2 |
20 files changed, 617 insertions, 797 deletions
diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm index 39899c7..7b5cf99 100755 --- a/lib/Travelynx.pm +++ b/lib/Travelynx.pm @@ -2026,10 +2026,10 @@ sub startup { for my $stop ( $journey->route ) { $self->stations->add_or_update( - stop => $stop, - db => $db, + stop => $stop, + db => $db, keep_name => 1, - iris => 1, + iris => 1, ); } diff --git a/lib/Travelynx/Command/work.pm b/lib/Travelynx/Command/work.pm index dc58a48..41325d2 100644 --- a/lib/Travelynx/Command/work.pm +++ b/lib/Travelynx/Command/work.pm @@ -53,6 +53,9 @@ sub run { my $arr = $entry->{arr_eva}; my $train_id = $entry->{train_id}; + my $use_history = $self->app->users->use_history( uid => $uid ); + my $suggestions_enabled = $use_history & 0x02; + if ( $train_id eq 'manual' ) { if ( $arr and $entry->{real_arr_ts} @@ -190,16 +193,54 @@ sub run { )->wait; if ( $arr - and $entry->{real_arr_ts} - and $now->epoch - $entry->{real_arr_ts} > 900 ) + and $entry->{real_arr_ts} ) { - $self->app->checkout_p( - station => $arr, - force => 2, - dep_eva => $dep, - arr_eva => $arr, - uid => $uid - )->wait; + if ( $now->epoch - $entry->{real_arr_ts} > 900 ) { + $self->app->checkout_p( + station => $arr, + force => 2, + dep_eva => $dep, + arr_eva => $arr, + uid => $uid + )->wait; + } + elsif ( $suggestions_enabled + and $entry->{real_arr_ts} - $now->epoch < 900 ) + { + my @destinations + = $self->app->journeys->get_connection_targets( + uid => $uid, + backend_id => $entry->{backend_id}, + eva => $arr, + exclude => $dep, + ); + $self->app->dbris->get_connections_p( + station => $arr, + timestamp => $entry->{real_arr}, + destinations => \@destinations + )->then( + sub { + my ($suggestions) = @_; + $self->app->in_transit->update_data( + uid => $uid, + train_id => $train_id, + data => { + connection_suggestions_dbris => + $suggestions + }, + ); + return; + } + )->catch( + sub { + my ($err) = @_; + $self->app->log->debug( +"work($uid) @ DBRIS $entry->{backend_name}: get_departures_p($arr): $err" + ); + return; + } + )->wait; + } } }; if ($@) { @@ -285,16 +326,55 @@ sub run { )->wait; if ( $arr - and $entry->{real_arr_ts} - and $now->epoch - $entry->{real_arr_ts} > 900 ) + and $entry->{real_arr_ts} ) { - $self->app->checkout_p( - station => $arr, - force => 2, - dep_eva => $dep, - arr_eva => $arr, - uid => $uid - )->wait; + if ( $now->epoch - $entry->{real_arr_ts} > 900 ) { + $self->app->checkout_p( + station => $arr, + force => 2, + dep_eva => $dep, + arr_eva => $arr, + uid => $uid + )->wait; + } + elsif ( $suggestions_enabled + and $entry->{real_arr_ts} - $now->epoch < 900 ) + { + my @destinations + = $self->app->journeys->get_connection_targets( + uid => $uid, + backend_id => $entry->{backend_id}, + eva => $arr, + exclude => $dep, + ); + $self->app->efa->get_connections_p( + service => $entry->{backend_name}, + name => $arr, + timestamp => $entry->{real_arr}, + destinations => \@destinations + )->then( + sub { + my ($suggestions) = @_; + $self->app->in_transit->update_data( + uid => $uid, + train_id => $train_id, + data => { + connection_suggestions_efa => + $suggestions + }, + ); + return; + } + )->catch( + sub { + my ($err) = @_; + $self->app->log->debug( +"work($uid) @ EFA $entry->{backend_name}: get_departures_p($arr): $err" + ); + return; + } + )->wait; + } } }; if ($@) { @@ -702,6 +782,41 @@ sub run { $self->app->add_stationinfo( $uid, 0, $train->train_id, $dep, $arr ); } + if ( $now->epoch - $entry->{real_arr_ts} < 900 ) { + my @destinations + = $self->app->journeys->get_connection_targets( + uid => $uid, + backend_id => $entry->{backend_id}, + eva => $arr, + exclude => $dep, + ); + $self->app->iris->get_connections_p( + station => $arr, + timestamp => $entry->{real_arr}, + destinations => \@destinations + )->then( + sub { + my ($suggestions) = @_; + $self->app->in_transit->update_data( + uid => $uid, + train_id => $train_id, + data => { + connection_suggestions_iris => + $suggestions + }, + ); + return; + } + )->catch( + sub { + my ($err) = @_; + $self->app->log->debug( +"work($uid) @ DBRIS $entry->{backend_name}: get_departures_p($arr): $err" + ); + return; + } + )->wait; + } } elsif ( $entry->{real_arr_ts} ) { my ( undef, $error ) = $self->app->checkout_p( diff --git a/lib/Travelynx/Controller/Traveling.pm b/lib/Travelynx/Controller/Traveling.pm index 30c579e..28d7bfd 100755 --- a/lib/Travelynx/Controller/Traveling.pm +++ b/lib/Travelynx/Controller/Traveling.pm @@ -28,324 +28,6 @@ sub has_str_in_list { return; } -# when called with "eva" provided: look up connections from eva, either -# for provided backend_id / hafas or (if not provided) for user backend id. -# When calld without "eva": look up connections from current/latest arrival -# eva, using the checkin's backend id. -sub get_connecting_trains_p { - my ( $self, %opt ) = @_; - - my $user = $self->current_user; - my $uid = $opt{uid} //= $user->{id}; - my $use_history = $self->users->use_history( uid => $uid ); - - my ( $eva, $exclude_via, $exclude_train_id, $exclude_before ); - my $now = $self->now->epoch; - my ( $stationinfo, $arr_epoch, $arr_platform, $arr_countdown ); - - my $promise = Mojo::Promise->new; - - if ( $user->{backend_dbris} ) { - - # We do get a little bit of via information, so this might work in some - # cases. But not reliably. Probably best to leave it out entirely then. - return $promise->reject; - } - if ( $user->{backend_efa} ) { - - # TODO - return $promise->reject; - } - if ( $user->{backend_motis} ) { - - # FIXME: The following code can't handle external_ids currently - return $promise->reject; - } - - if ( $opt{eva} ) { - if ( $use_history & 0x01 ) { - $eva = $opt{eva}; - } - elsif ( $opt{destination_name} ) { - $eva = $opt{eva}; - } - if ( not defined $opt{backend_id} ) { - if ( $opt{hafas} ) { - $opt{backend_id} - = $self->stations->get_backend_id( hafas => $opt{hafas} ); - } - else { - $opt{backend_id} = $user->{backend_id}; - } - } - } - else { - if ( $use_history & 0x02 ) { - my $status = $self->get_user_status; - $opt{backend_id} = $status->{backend_id}; - $eva = $status->{arr_eva}; - $exclude_via = $status->{dep_name}; - $exclude_train_id = $status->{train_id}; - $arr_platform = $status->{arr_platform}; - $stationinfo = $status->{extra_data}{stationinfo_arr}; - if ( $status->{real_arrival} ) { - $exclude_before = $arr_epoch = $status->{real_arrival}->epoch; - $arr_countdown = $status->{arrival_countdown}; - } - } - } - - $exclude_before //= $now - 300; - - if ( not $eva ) { - return $promise->reject; - } - - $self->log->debug( - "get_connecting_trains_p(backend_id => $opt{backend_id}, eva => $eva)"); - - my @destinations = $self->journeys->get_connection_targets(%opt); - - @destinations = uniq_by { $_->{name} } @destinations; - - if ($exclude_via) { - @destinations = grep { $_->{name} ne $exclude_via } @destinations; - } - - if ( not @destinations ) { - return $promise->reject; - } - - $self->log->debug( 'get_connection_targets returned ' - . join( q{, }, map { $_->{name} } @destinations ) ); - - my $can_check_in = not $arr_epoch || ( $arr_countdown // 1 ) < 0; - my $lookahead - = $can_check_in ? 40 : ( ( ${arr_countdown} // 0 ) / 60 + 40 ); - - my $iris_promise = Mojo::Promise->new; - my %via_count = map { $_->{name} => 0 } @destinations; - - my $backend - = $self->stations->get_backend( backend_id => $opt{backend_id} ); - if ( $opt{backend_id} == 0 ) { - $self->iris->get_departures_p( - station => $eva, - lookbehind => 10, - lookahead => $lookahead, - with_related => 1 - )->then( - sub { - my ($stationboard) = @_; - if ( $stationboard->{errstr} ) { - $promise->resolve( [], [] ); - return; - } - - @{ $stationboard->{results} } = map { $_->[0] } - sort { $a->[1] <=> $b->[1] } - map { [ $_, $_->departure ? $_->departure->epoch : 0 ] } - @{ $stationboard->{results} }; - my @results; - my @cancellations; - my $excluded_train; - for my $train ( @{ $stationboard->{results} } ) { - if ( not $train->departure ) { - next; - } - if ( $exclude_before - and $train->departure - and $train->departure->epoch < $exclude_before ) - { - next; - } - if ( $exclude_train_id - and $train->train_id eq $exclude_train_id ) - { - $excluded_train = $train; - next; - } - - # In general, this function is meant to return feasible - # connections. However, cancelled connections may also be of - # interest and are also useful for logging cancellations. - # To satisfy both demands with (hopefully) little confusion and - # UI clutter, this function returns two concatenated arrays: - # actual connections (ordered by actual departure time) followed - # by cancelled connections (ordered by scheduled departure time). - # This is easiest to achieve in two separate loops. - # - # Note that a cancelled train may still have a matching destination - # in its route_post, e.g. if it leaves out $eva due to - # unscheduled route changes but continues on schedule afterwards - # -- so it is only cancelled at $eva, not on the remainder of - # the route. Also note that this specific case is not yet handled - # properly by the cancellation logic etc. - - if ( $train->departure_is_cancelled ) { - my @via = ( - $train->sched_route_post, $train->sched_route_end - ); - for my $dest (@destinations) { - if ( has_str_in_list( $dest->{name}, @via ) ) { - push( @cancellations, [ $train, $dest ] ); - next; - } - } - } - else { - my @via = ( $train->route_post, $train->route_end ); - for my $dest (@destinations) { - if ( $via_count{ $dest->{name} } < 2 - and has_str_in_list( $dest->{name}, @via ) ) - { - push( @results, [ $train, $dest ] ); - - # Show all past and up to two future departures per destination - if ( not $train->departure - or $train->departure->epoch >= $now ) - { - $via_count{ $dest->{name} }++; - } - next; - } - } - } - } - - @results = map { $_->[0] } - sort { $a->[1] <=> $b->[1] } - map { - [ - $_, - $_->[0]->departure->epoch - // $_->[0]->sched_departure->epoch - ] - } @results; - @cancellations = map { $_->[0] } - sort { $a->[1] <=> $b->[1] } - map { [ $_, $_->[0]->sched_departure->epoch ] } - @cancellations; - - # remove trains whose route matches the excluded one's - if ($excluded_train) { - my $route_pre - = join( '|', reverse $excluded_train->route_pre ); - @results - = grep { join( '|', $_->[0]->route_post ) ne $route_pre } - @results; - my $route_post = join( '|', $excluded_train->route_post ); - @results - = grep { join( '|', $_->[0]->route_post ) ne $route_post } - @results; - } - - # add message IDs and 'transfer short' hints - for my $result (@results) { - my $train = $result->[0]; - my @message_ids - = List::Util::uniq map { $_->[1] } $train->raw_messages; - $train->{message_id} = { map { $_ => 1 } @message_ids }; - my $interchange_duration; - if ( exists $stationinfo->{i} ) { - if ( defined $arr_platform - and defined $train->platform ) - { - $interchange_duration - = $stationinfo->{i}{$arr_platform} - { $train->platform }; - } - $interchange_duration //= $stationinfo->{i}{"*"}; - } - if ( defined $interchange_duration ) { - my $interchange_time - = ( $train->departure->epoch - $arr_epoch ) / 60; - if ( $interchange_time < $interchange_duration ) { - $train->{interchange_text} = 'Anschluss knapp'; - $train->{interchange_icon} = 'directions_run'; - } - elsif ( $interchange_time == $interchange_duration ) { - $train->{interchange_text} - = 'Anschluss könnte knapp werden'; - $train->{interchange_icon} = 'directions_run'; - } - } - } - - $promise->resolve( [ @results, @cancellations ], [] ); - return; - } - )->catch( - sub { - $promise->resolve( [], [] ); - return; - } - )->wait; - } - elsif ( $backend->{dbris} ) { - return $promise->reject; - } - elsif ( $backend->{efa} ) { - return $promise->reject; - } - elsif ( $backend->{hafas} ) { - my $hafas_service = $backend->{name}; - $self->hafas->get_departures_p( - service => $hafas_service, - eva => $eva, - lookbehind => 10, - lookahead => $lookahead - )->then( - sub { - my ($status) = @_; - my @hafas_trains; - my @all_hafas_trains = $status->results; - for my $hafas_train (@all_hafas_trains) { - for my $stop ( $hafas_train->route ) { - for my $dest (@destinations) { - if ( $stop->loc->name - and $stop->loc->name eq $dest->{name} - and $via_count{ $dest->{name} } < 2 - and $hafas_train->datetime ) - { - my $departure = $hafas_train->datetime; - my $arrival = $stop->arr; - my $delay = $hafas_train->delay; - if ( $delay - and $stop->arr == $stop->sched_arr ) - { - $arrival->add( minutes => $delay ); - } - if ( $departure->epoch >= $exclude_before ) { - $via_count{ $dest->{name} }++; - push( - @hafas_trains, - [ - $hafas_train, $dest, - $arrival, $hafas_service - ] - ); - } - } - } - } - } - $promise->resolve( [], \@hafas_trains ); - return; - } - )->catch( - sub { - my ($err) = @_; - $self->log->debug("get_connection_trains: hafas: $err"); - $promise->resolve( [], [] ); - return; - } - )->wait; - } - - return $promise; -} - sub compute_effective_visibility { my ( $self, $default_visibility, $journey_visibility ) = @_; if ( $journey_visibility eq 'default' ) { @@ -381,52 +63,16 @@ sub homepage { = $self->compute_effective_visibility( $user->{default_visibility_str}, $status->{visibility_str} ); - if ( defined $status->{arrival_countdown} - and $status->{arrival_countdown} < ( 40 * 60 ) ) - { - $self->render_later; - $self->get_connecting_trains_p->then( - sub { - my ( $connections_iris, $connections_hafas ) = @_; - $self->render( - 'landingpage', - user => $user, - user_status => $status, - journey_visibility => $journey_visibility, - connections_iris => $connections_iris, - connections_hafas => $connections_hafas, - with_map => 1, - %{$map_data}, - ); - $self->users->mark_seen( uid => $uid ); - } - )->catch( - sub { - $self->render( - 'landingpage', - user => $user, - user_status => $status, - journey_visibility => $journey_visibility, - with_map => 1, - %{$map_data}, - ); - $self->users->mark_seen( uid => $uid ); - } - )->wait; - return; - } - else { - $self->render( - 'landingpage', - user => $user, - user_status => $status, - journey_visibility => $journey_visibility, - with_map => 1, - %{$map_data}, - ); - $self->users->mark_seen( uid => $uid ); - return; - } + $self->render( + 'landingpage', + user => $user, + user_status => $status, + journey_visibility => $journey_visibility, + with_map => 1, + %{$map_data}, + ); + $self->users->mark_seen( uid => $uid ); + return; } else { @recent_targets = uniq_by { $_->{external_id_or_eva} } @@ -450,12 +96,14 @@ sub homepage { sub status_card { my ($self) = @_; + my $user = $self->current_user; my $status = $self->get_user_status; + my $uid = $user->{id}; delete $self->stash->{layout}; my @timeline = $self->in_transit->get_timeline( - uid => $self->current_user->{id}, + uid => $uid, short => 1 ); $self->stash( timeline => [@timeline] ); @@ -471,36 +119,8 @@ sub status_card { } my $journey_visibility = $self->compute_effective_visibility( - $self->current_user->{default_visibility_str}, + $user->{default_visibility_str}, $status->{visibility_str} ); - if ( defined $status->{arrival_countdown} - and $status->{arrival_countdown} < ( 40 * 60 ) ) - { - $self->render_later; - $self->get_connecting_trains_p->then( - sub { - my ( $connections_iris, $connections_hafas ) = @_; - $self->render( - '_checked_in', - journey => $status, - journey_visibility => $journey_visibility, - connections_iris => $connections_iris, - connections_hafas => $connections_hafas, - %{$map_data}, - ); - } - )->catch( - sub { - $self->render( - '_checked_in', - journey => $status, - journey_visibility => $journey_visibility, - %{$map_data}, - ); - } - )->wait; - return; - } $self->render( '_checked_in', journey => $status, @@ -509,50 +129,10 @@ sub status_card { ); } elsif ( $status->{cancellation} ) { - $self->render_later; - $self->get_connecting_trains_p( - backend_id => $status->{backend_id}, - eva => $status->{cancellation}{dep_eva}, - destination_name => $status->{cancellation}{arr_name} - )->then( - sub { - my ($connecting_trains) = @_; - $self->render( - '_cancelled_departure', - journey => $status->{cancellation}, - connections_iris => $connecting_trains - ); - } - )->catch( - sub { - $self->render( '_cancelled_departure', - journey => $status->{cancellation} ); - } - )->wait; - return; + $self->render( '_cancelled_departure', + journey => $status->{cancellation} ); } else { - my @connecting_trains; - my $now = DateTime->now( time_zone => 'Europe/Berlin' ); - if ( $now->epoch - $status->{timestamp}->epoch < ( 30 * 60 ) ) { - $self->render_later; - $self->get_connecting_trains_p->then( - sub { - my ( $connections_iris, $connections_hafas ) = @_; - $self->render( - '_checked_out', - journey => $status, - connections_iris => $connections_iris, - connections_hafas => $connections_hafas, - ); - } - )->catch( - sub { - $self->render( '_checked_out', journey => $status ); - } - )->wait; - return; - } $self->render( '_checked_out', journey => $status ); } } @@ -1204,6 +784,8 @@ sub station { } my @suggestions; + my $use_history = $self->users->use_history( uid => $uid ); + my $suggestions_enabled = $use_history & 0x01; my $promise; if ($dbris_service) { @@ -1298,6 +880,28 @@ sub station { sort { $b->[1] <=> $a->[1] } map { [ $_, $_->dep->epoch ] } $status->results; + if ($suggestions_enabled) { + my ($eva) = ( $station =~ m{ [@] L = (\d+) }x ); + my $backend_id + = $self->stations->get_backend_id( + dbris => $dbris_service ); + + my @destinations = $self->journeys->get_connection_targets( + uid => $uid, + backend_id => $backend_id, + eva => $eva + ); + + @suggestions = $self->dbris->grep_suggestions( + status => $status, + destinations => \@destinations + ); + + @suggestions + = sort { $a->[0]{sort_ts} <=> $b->[0]{sort_ts} } + grep { $_->[0]{sort_ts} >= $now - 300 } @suggestions; + } + $status = { station_eva => $station, related_stations => [], @@ -1306,37 +910,6 @@ sub station { if ( $station =~ m{ [@] O = (?<name> [^@]+ ) [@] }x ) { $status->{station_name} = $+{name}; } - - my ($eva) = ( $station =~ m{ [@] L = (\d+) }x ); - my $backend_id - = $self->stations->get_backend_id( dbris => $dbris_service ); - my @destinations = $self->journeys->get_connection_targets( - uid => $uid, - backend_id => $backend_id, - eva => $eva - ); - - for my $dep (@results) { - destination: for my $dest (@destinations) { - if ( $dep->destination - and $dep->destination eq $dest->{name} ) - { - push( @suggestions, [ $dep, $dest ] ); - next destination; - } - for my $via_name ( $dep->via ) { - if ( $via_name eq $dest->{name} ) { - push( @suggestions, [ $dep, $dest ] ); - next destination; - } - } - } - } - - @suggestions = map { $_->[0] } - sort { $a->[1] <=> $b->[1] } - grep { $_->[1] >= $now - 300 } - map { [ $_, $_->[0]->dep->epoch ] } @suggestions; } elsif ($hafas_service) { @@ -1363,34 +936,35 @@ sub station { @results = map { $_->[0] } sort { $b->[1] <=> $a->[1] } map { [ $_, $_->datetime->epoch ] } $status->results; + + if ($suggestions_enabled) { + my $backend_id + = $self->stations->get_backend_id( efa => $efa_service ); + + my @destinations = $self->journeys->get_connection_targets( + uid => $uid, + backend_id => $backend_id, + eva => $status->stop->id_num, + ); + + @suggestions = $self->efa->grep_suggestions( + status => $status, + destinations => \@destinations + ); + + @suggestions + = sort { $a->[0]{sort_ts} <=> $b->[0]{sort_ts} } + grep { + $_->[0]{sort_ts} >= $now - 300 + and $_->[0]{sort_ts} <= $now + 1800 + } @suggestions; + } + $status = { station_eva => $status->stop->id_num, station_name => $status->stop->full_name, related_stations => [], }; - my $backend_id - = $self->stations->get_backend_id( efa => $efa_service ); - my @destinations = $self->journeys->get_connection_targets( - uid => $uid, - backend_id => $backend_id, - eva => $status->{station_eva}, - ); - for my $dep (@results) { - destination: for my $dest (@destinations) { - for my $stop ( $dep->route_post ) { - if ( $stop->full_name eq $dest->{name} ) { - push( @suggestions, - [ $dep, $dest, $stop->arr ] ); - next destination; - } - } - } - } - - @suggestions = map { $_->[0] } - sort { $a->[1] <=> $b->[1] } - grep { $_->[1] >= $now - 300 and $_->[1] <= $now + 1800 } - map { [ $_, $_->[0]->datetime->epoch ] } @suggestions; } elsif ($motis_service) { @results = map { $_->[0] } @@ -1415,6 +989,24 @@ sub station { map { [ $_, $_->departure->epoch // $_->sched_departure->epoch ] } @results; + + if ($suggestions_enabled) { + my @destinations = $self->journeys->get_connection_targets( + uid => $uid, + backend_id => 0, + eva => $status->{station_eva}, + ); + @suggestions = $self->iris->grep_suggestions( + results => \@results, + destinations => \@destinations + ); + @suggestions + = sort { $a->[0]{sort_ts} <=> $b->[0]{sort_ts} } + grep { + $_->[0]{sort_ts} >= $now - 300 + and $_->[0]{sort_ts} <= $now + 1800 + } @suggestions; + } } my $user_status = $self->get_user_status; @@ -1436,7 +1028,6 @@ sub station { } } - my $connections_p; if ( $trip_id and ( $dbris_service or $hafas_service ) ) { @results = grep { $_->id eq $trip_id } @results; } @@ -1444,95 +1035,25 @@ sub station { @results = grep { $_->type . ' ' . $_->train_no eq $train } @results; } - else { - if ( $user_status->{cancellation} - and $status->{station_eva} eq - $user_status->{cancellation}{dep_eva} ) - { - $connections_p = $self->get_connecting_trains_p( - eva => $user_status->{cancellation}{dep_eva}, - destination_name => - $user_status->{cancellation}{arr_name}, - efa => $efa_service, - hafas => $hafas_service, - ); - } - else { - $connections_p = $self->get_connecting_trains_p( - eva => $status->{station_eva}, - efa => $efa_service, - hafas => $hafas_service - ); - } - } - if ($connections_p) { - $connections_p->then( - sub { - my ( $connections_iris, $connections_hafas ) = @_; - $self->render( - 'departures', - user => $user, - dbris => $dbris_service, - efa => $efa_service, - hafas => $hafas_service, - motis => $motis_service, - eva => $status->{station_eva}, - datetime => $timestamp, - now_in_range => $now_within_range, - results => \@results, - station => $status->{station_name}, - related_stations => $status->{related_stations}, - user_status => $user_status, - can_check_out => $can_check_out, - connections_iris => $connections_iris, - connections_hafas => $connections_hafas, - title => "travelynx: $status->{station_name}", - ); - } - )->catch( - sub { - $self->render( - 'departures', - user => $user, - dbris => $dbris_service, - efa => $efa_service, - hafas => $hafas_service, - motis => $motis_service, - eva => $status->{station_eva}, - datetime => $timestamp, - now_in_range => $now_within_range, - results => \@results, - station => $status->{station_name}, - related_stations => $status->{related_stations}, - user_status => $user_status, - can_check_out => $can_check_out, - suggestions => \@suggestions, - title => "travelynx: $status->{station_name}", - ); - } - )->wait; - } - else { - $self->render( - 'departures', - user => $user, - dbris => $dbris_service, - efa => $efa_service, - hafas => $hafas_service, - motis => $motis_service, - eva => $status->{station_eva}, - datetime => $timestamp, - now_in_range => $now_within_range, - results => \@results, - station => $status->{station_name}, - related_stations => $status->{related_stations}, - user_status => $user_status, - can_check_out => $can_check_out, - suggestions => \@suggestions, - title => "travelynx: $status->{station_name}", - ); - } + $self->render( + 'departures', + user => $user, + dbris => $dbris_service, + efa => $efa_service, + hafas => $hafas_service, + motis => $motis_service, + eva => $status->{station_eva}, + datetime => $timestamp, + now_in_range => $now_within_range, + results => \@results, + station => $status->{station_name}, + related_stations => $status->{related_stations}, + user_status => $user_status, + can_check_out => $can_check_out, + suggestions => \@suggestions, + title => "travelynx: $status->{station_name}", + ); } )->catch( sub { @@ -2762,8 +2283,6 @@ sub set_polyline { my $context = XML::LibXML::XPathContext->new($root); $context->registerNs( 'gpx', 'http://www.topografix.com/GPX/1/1' ); - use Data::Dumper; - my @polyline; for my $point ( $context->findnodes('/gpx:gpx/gpx:trk/gpx:trkseg/gpx:trkpt') ) diff --git a/lib/Travelynx/Helper/DBRIS.pm b/lib/Travelynx/Helper/DBRIS.pm index deeed65..edf8812 100644 --- a/lib/Travelynx/Helper/DBRIS.pm +++ b/lib/Travelynx/Helper/DBRIS.pm @@ -127,6 +127,39 @@ sub get_departures_p { ); } +sub get_connections_p { + my ( $self, %opt ) = @_; + my $promise = Mojo::Promise->new; + my $destinations = $opt{destinations}; + + $self->get_departures_p( + station => '@L=' . $opt{station}, + timestamp => $opt{timestamp}, + lookbehind => 0, + lookahead => 60, + )->then( + sub { + my ($status) = @_; + my @suggestions = $self->grep_suggestions( + status => $status, + destinations => $destinations, + max_per_dest => 2 + ); + @suggestions + = sort { $a->[0]{sort_ts} <=> $b->[0]{sort_ts} } @suggestions; + $promise->resolve( \@suggestions ); + return; + } + )->catch( + sub { + my ($err) = @_; + $promise->reject("get_departures_p($opt{station}): $err"); + return; + } + )->wait; + return $promise; +} + sub get_journey_p { my ( $self, %opt ) = @_; @@ -186,4 +219,65 @@ sub get_wagonorder_p { ); } +sub grep_suggestions { + my ( $self, %opt ) = @_; + my $status = $opt{status}; + my $destinations = $opt{destinations}; + my $max_per_dest = $opt{max_per_dest}; + + my @suggestions; + my %via_count; + + for my $dep ( $status->results ) { + my $dep_json = { + id => $dep->id, + ts => ( $dep->sched_dep // $dep->dep )->epoch, + sort_ts => $dep->dep->epoch, + is_cancelled => $dep->is_cancelled, + stop_eva => $dep->stop_eva, + maybe_line_no => $dep->maybe_line_no, + sched_hhmm => $dep->sched_dep->strftime('%H:%M'), + rt_hhmm => $dep->dep->strftime('%H:%M'), + delay => $dep->delay, + platform => $dep->platform, + type => $dep->type, + line => $dep->line, + }; + destination: for my $dest ( @{$destinations} ) { + if ( $dep->destination + and $dep->destination eq $dest->{name} ) + { + if ( not $dep->is_cancelled ) { + $via_count{ $dest->{name} } += 1; + } + if ( $max_per_dest + and $via_count{ $dest->{name} } + and $via_count{ $dest->{name} } > $max_per_dest ) + { + next destination; + } + push( @suggestions, [ $dep_json, $dest ] ); + next destination; + } + for my $via_name ( $dep->via ) { + if ( $via_name eq $dest->{name} ) { + if ( not $dep->is_cancelled ) { + $via_count{ $dest->{name} } += 1; + } + if ( $max_per_dest + and $via_count{ $dest->{name} } + and $via_count{ $dest->{name} } > $max_per_dest ) + { + next destination; + } + push( @suggestions, [ $dep_json, $dest ] ); + next destination; + } + } + } + } + + return @suggestions; +} + 1; diff --git a/lib/Travelynx/Helper/EFA.pm b/lib/Travelynx/Helper/EFA.pm index 5cae51b..70894df 100644 --- a/lib/Travelynx/Helper/EFA.pm +++ b/lib/Travelynx/Helper/EFA.pm @@ -48,6 +48,86 @@ sub get_departures_p { ); } +sub grep_suggestions { + my ( $self, %opt ) = @_; + my $status = $opt{status}; + my $destinations = $opt{destinations}; + my $max_per_dest = $opt{max_per_dest}; + + my @suggestions; + my %via_count; + + for my $dep ( $status->results ) { + destination: for my $dest ( @{$destinations} ) { + for my $stop ( $dep->route_post ) { + if ( $stop->full_name eq $dest->{name} ) { + if ( not $dep->is_cancelled ) { + $via_count{ $dest->{name} } += 1; + } + if ( $max_per_dest + and $via_count{ $dest->{name} } + and $via_count{ $dest->{name} } > $max_per_dest ) + { + next destination; + } + my $dep_json = { + id => $dep->id, + ts => ( $dep->sched_datetime // $dep->datetime )->epoch, + sort_ts => $dep->datetime->epoch, + is_cancelled => $dep->is_cancelled, + stop_id_num => $dep->stop_id_num, + sched_hhmm => $dep->sched_datetime->strftime('%H:%M'), + rt_hhmm => $dep->datetime->strftime('%H:%M'), + delay => $dep->delay, + platform => $dep->platform, + type => $dep->type, + line => $dep->line, + }; + push( @suggestions, + [ $dep_json, $dest, $stop->arr->strftime('%H:%M') ] ); + next destination; + } + } + } + } + return @suggestions; +} + +sub get_connections_p { + my ( $self, %opt ) = @_; + my $promise = Mojo::Promise->new; + my $destinations = $opt{destinations}; + + $self->get_departures_p( + service => $opt{service}, + name => $opt{name}, + timestamp => $opt{timestamp}, + lookbehind => 0, + lookahead => 60, + )->then( + sub { + my ($status) = @_; + my @suggestions = $self->grep_suggestions( + status => $status, + destinations => $destinations, + max_per_dest => 2 + ); + @suggestions + = sort { $a->[0]{sort_ts} <=> $b->[0]{sort_ts} } @suggestions; + $promise->resolve( \@suggestions ); + return; + } + )->catch( + sub { + my ($err) = @_; + $promise->reject( + "get_departures_p($opt{service}, $opt{name}): $err"); + return; + } + )->wait; + return $promise; +} + sub get_journey_p { my ( $self, %opt ) = @_; diff --git a/lib/Travelynx/Helper/IRIS.pm b/lib/Travelynx/Helper/IRIS.pm index 34739eb..9a5aa87 100644 --- a/lib/Travelynx/Helper/IRIS.pm +++ b/lib/Travelynx/Helper/IRIS.pm @@ -201,6 +201,86 @@ sub get_departures_p { } } +sub get_connections_p { + my ( $self, %opt ) = @_; + my $promise = Mojo::Promise->new; + my $destinations = $opt{destinations}; + + $self->get_departures_p( + station => $opt{station}, + timestamp => $opt{timestamp}, + lookbehind => 0, + lookahead => 60, + with_related => 1, + )->then( + sub { + my ($res) = @_; + my @suggestions = $self->grep_suggestions( + results => $res->{results}, + destinations => $destinations, + max_per_dest => 2 + ); + @suggestions + = sort { $a->[0]{sort_ts} <=> $b->[0]{sort_ts} } @suggestions; + $promise->resolve( \@suggestions ); + return; + } + )->catch( + sub { + my ($err) = @_; + $promise->reject("get_departures_p($opt{station}): $err"); + return; + } + )->wait; + return $promise; +} + +sub grep_suggestions { + my ( $self, %opt ) = @_; + my $results = $opt{results}; + my $destinations = $opt{destinations}; + my $max_per_dest = $opt{max_per_dest}; + + my @suggestions; + my %via_count; + + for my $dep ( @{$results} ) { + destination: for my $dest ( @{$destinations} ) { + for my $via_name ( $dep->route_post ) { + if ( $via_name eq $dest->{name} ) { + if ( not $dep->departure_is_cancelled ) { + $via_count{ $dest->{name} } += 1; + } + if ( $max_per_dest + and $via_count{ $dest->{name} } + and $via_count{ $dest->{name} } > $max_per_dest ) + { + next destination; + } + my $dep_json = { + id => $dep->train_id, + ts => + ( $dep->sched_departure // $dep->departure )->epoch, + sort_ts => $dep->departure->epoch, + station_uic => $dep->station_uic, + departure_is_cancelled => $dep->departure_is_cancelled, + sched_hhmm => $dep->sched_departure->strftime('%H:%M'), + rt_hhmm => $dep->departure->strftime('%H:%M'), + departure_delay => $dep->departure_delay, + platform => $dep->platform, + type => $dep->type, + line => $dep->line, + }; + push( @suggestions, [ $dep_json, $dest ] ); + next destination; + } + } + } + } + + return @suggestions; +} + sub route_diff { my ( $self, $train ) = @_; my @json_route; diff --git a/lib/Travelynx/Model/Journeys.pm b/lib/Travelynx/Model/Journeys.pm index f532b8b..744e7ae 100755 --- a/lib/Travelynx/Model/Journeys.pm +++ b/lib/Travelynx/Model/Journeys.pm @@ -2108,6 +2108,7 @@ sub get_connection_targets { my $min_count = $opt{min_count} // 3; my $backend_id = $opt{backend_id}; my $dest_id = $opt{eva}; + my $exclude_id = $opt{exclude}; $self->{log}->debug( "get_connection_targets(uid => $uid, backend_id => $backend_id, dest_id => $dest_id)" @@ -2163,6 +2164,9 @@ sub get_connection_targets { backend_id => $opt{backend_id}, evas => [@destinations] ); + if ( defined $exclude_id ) { + @destinations = grep { $_->{eva} != $exclude_id } @destinations; + } return @destinations; } diff --git a/share/locales/de_DE.po b/share/locales/de_DE.po index 5b67c83..96ad1a9 100644 --- a/share/locales/de_DE.po +++ b/share/locales/de_DE.po @@ -223,6 +223,12 @@ msgstr "Korrekte Berechnung und Visualisierung der Wegstrecke bei Fahrten mit Ri msgid "changelog.2-17.1" msgstr "Kartendaten („Polylines“) zu einzelnen Fahrten können nun als GPX ex- und importiert werden. Somit können Kartendaten nachträglich korrigiert oder nachgepflegt werden. Das GPX-Datenformat ist mit BRouter-Web kompatibel." +msgid "changelog.2-18.1" +msgstr "Checkin- und Verbindungsvorschläge sind für DBRIS-, EFA- und IRIS-Backends wieder verfügbar. Bei HAFAS-Backends fehlen die dazu notwendigen Daten in der Abfahrtstafel. Bei MOTIS-Backends fehlen die Daten möglicherweise ebenfalls." + +msgid "changelog.2-18.2" +msgstr "Bei der Reisestreckenberechnung für vergangene Fahrten werden nun auch Fahrten mit ungenügender Datenlage (d.h. bei denen ausschließlich die Entfernung nach Luftlinie verfügbar ist) berücksichtigt. Bislang wurden diese für monatliche und jährliche Statistiken ignoriert." + # history.html.ep msgid "history.review" diff --git a/share/locales/en_GB.po b/share/locales/en_GB.po index 073b3ab..9f53ac3 100644 --- a/share/locales/en_GB.po +++ b/share/locales/en_GB.po @@ -223,6 +223,11 @@ msgstr "Fix distance calculation and visualization of ring line trips. Trips sho msgid "changelog.2-17.1" msgstr "Map data (“polylines”) for individual trips can now be exported and imported in the GPX format. This allows map data to be corrected or augmented after the fact. The GPX import/export is compatible with BRouter-Web." +msgid "changelog.2-18.1" +msgstr "Checkin and connection suggestions are now available again for DBRIS, EFA, and IRIS backends. HAFAS backends lack the required station board data. MOTIS backends may lack the required data as well." + +msgid "changelog.2-18.2" +msgstr "Total distance calculation in the history now includes trips that lack appropriate route data (i.e., where only beeline distance / distance as the crow flies is available). Before this release, such trips were ignored when computing monthly and yearly statistics." # history.html.ep msgid "history.review" diff --git a/templates/_cancelled_departure.html.ep b/templates/_cancelled_departure.html.ep index db6cc5c..d47385a 100644 --- a/templates/_cancelled_departure.html.ep +++ b/templates/_cancelled_departure.html.ep @@ -5,9 +5,5 @@ in <a href="/s/<%= $journey->{dep_eva} %>"><%= $journey->{dep_name} %></a> entfällt. Der Ausfall der Fahrt nach <%= $journey->{arr_name} %> wurde bereits dokumentiert. </p> - % if (my @connections = @{stash('connections_iris') // []}) { - <p>Alternative Reisemöglichkeiten:</p> - %= include '_connections', connections => \@connections, checkin_from => $journey->{dep_eva}; - % } </div> </div> diff --git a/templates/_checked_in.html.ep b/templates/_checked_in.html.ep index 69754e3..659abff 100644 --- a/templates/_checked_in.html.ep +++ b/templates/_checked_in.html.ep @@ -221,17 +221,26 @@ </ul> </p> % } - % if (@{stash('connections_iris') // [] } or @{stash('connections_hafas') // []}) { + % if (my @suggestions = @{$journey->{extra_data}{connection_suggestions_dbris} // []}) { <span class="card-title" style="margin-top: 2ex;">Verbindungen</span> % if ($journey->{arrival_countdown} < 0) { <p>Fahrt auswählen zum Einchecken mit Zielwahl.</p> % } - % if (@{stash('connections_iris') // [] }) { - %= include '_connections', connections => stash('connections_iris'), checkin_from => $journey->{arrival_countdown} < 0 ? $journey->{arr_eva} : undef; + %= include '_connections_dbris', dbris => $journey->{backend_name}, suggestions => \@suggestions, checkin_from => $journey->{arrival_countdown} < 0 ? $journey->{arr_eva} : undef + % } + % if (my @suggestions = @{$journey->{extra_data}{connection_suggestions_efa} // []}) { + <span class="card-title" style="margin-top: 2ex;">Verbindungen</span> + % if ($journey->{arrival_countdown} < 0) { + <p>Fahrt auswählen zum Einchecken mit Zielwahl.</p> % } - % if (@{stash('connections_hafas') // [] }) { - %= include '_connections_hafas', connections => stash('connections_hafas'), checkin_from => $journey->{arrival_countdown} < 0 ? $journey->{arr_eva} : undef; + %= include '_connections_efa', efa => $journey->{backend_name}, suggestions => \@suggestions, checkin_from => $journey->{arrival_countdown} < 0 ? $journey->{arr_eva} : undef + % } + % if (my @suggestions = @{$journey->{extra_data}{connection_suggestions_iris} // []}) { + <span class="card-title" style="margin-top: 2ex;">Verbindungen</span> + % if ($journey->{arrival_countdown} < 0) { + <p>Fahrt auswählen zum Einchecken mit Zielwahl.</p> % } + %= include '_connections_iris', suggestions => \@suggestions, checkin_from => $journey->{arrival_countdown} < 0 ? $journey->{arr_eva} : undef % } % if (defined $journey->{arrival_countdown} and $journey->{arrival_countdown} <= 0) { <p style="margin-top: 2ex;"> diff --git a/templates/_checked_out.html.ep b/templates/_checked_out.html.ep index 21db335..fcac6f8 100644 --- a/templates/_checked_out.html.ep +++ b/templates/_checked_out.html.ep @@ -4,16 +4,6 @@ <p>Aus %= include '_format_train', journey => $journey bis <a href="/s/<%= $journey->{arr_eva} %>?hafas=<%= $journey->{is_hafas} ? $journey->{backend_name} : q{} %>"><%= $journey->{arr_name} %></a></p> - % if (@{stash('connections_iris') // [] } or @{stash('connections_hafas') // []}) { - <span class="card-title" style="margin-top: 2ex;">Verbindungen</span> - <p>Fahrt auswählen zum Einchecken mit Zielwahl.</p> - % if (@{stash('connections_iris') // [] }) { - %= include '_connections', connections => stash('connections_iris'), checkin_from => $journey->{arr_eva}; - % } - % if (@{stash('connections_hafas') // [] }) { - %= include '_connections_hafas', connections => stash('connections_hafas'), checkin_from => $journey->{arr_eva}; - % } - % } </div> <div class="card-action"> <a class="action-undo" data-id="<%= $journey->{journey_id} %>"> diff --git a/templates/_connections.html.ep b/templates/_connections.html.ep deleted file mode 100644 index 1dd2718..0000000 --- a/templates/_connections.html.ep +++ /dev/null @@ -1,76 +0,0 @@ -<ul class="collection departures connections"> - % for my $res (@{$connections}) { - % my ($train, $via, $via_arr, $load) = @{$res}; - % $via_arr = $via_arr ? $via_arr->strftime('%H:%M') : q{}; - % my $row_class = ''; - % my $link_class = 'action-checkin'; - % if ($train->is_cancelled) { - % $row_class = 'cancelled'; - % $link_class = 'action-cancelled-from'; - % } - % if ($checkin_from) { - <li class="collection-item <%= $row_class %> <%= $link_class %>" - data-station="<%= $train->station_uic %>" - data-train="<%= $train->train_id %>" - data-ts="<%= ($train->sched_departure // $train->departure)->epoch %>" - data-dest="<%= $via->{name} %>"> - % } - % else { - <li class="collection-item <%= $row_class %>"> - % } - <a class="dep-time" href="#"> - % if ($train->departure_is_cancelled) { - %= $train->sched_departure->strftime('%H:%M') - % } - % else { - %= $train->departure->strftime('%H:%M') - % } - % if ($via_arr) { - → <%= $via_arr %> - % } - % if ($train->departure_delay) { - %= sprintf('(%+d)', $train->departure_delay) - % } - </a> - <span class="connect-platform-wrapper"> - % if ($train->platform) { - <span>Gleis <%= $train->platform %></span> - % } - <span class="dep-line <%= $train->type // q{} %>"> - %= $train->line - </span> - </span> - <span class="dep-dest"> - % if ($train->is_cancelled) { - Fahrt nach <%= $via->{name} %> entfällt - % } - % else { - %= $via->{name} - % } - <br/> - % if ($load) { - % my ($first, $second) = load_icon($load); - <i class="material-icons tiny" aria-hidden="true"><%= $first %></i> <i class="material-icons tiny" aria-hidden="true"><%= $second %></i> - % } - % if ($train->{interchange_icon}) { - <i class="material-icons tiny" aria-label="<%= $train->{interchange_text} %>"><%= $train->{interchange_icon} %></i> - % } - % if ($train->{message_id}{96} or $train->{message_id}{97}) { - <i class="material-icons tiny" aria-label="Zug ist überbesetzt">warning</i> - % } - % if ($train->{message_id}{82} or $train->{message_id}{85}) { - <i class="material-icons tiny" aria-label="Fehlende Wagen">remove</i> - % } - % if (($train->{message_id}{73} or $train->{message_id}{74} or $train->{message_id}{75} or $train->{message_id}{76} or $train->{message_id}{80}) and not $train->{message_id}{84}) { - <i class="material-icons tiny" aria-label="Abweichende Wagenreihung">compare_arrows</i> - % } - % if ($train->{message_id}{83} or $train->{message_id}{93} or $train->{message_id}{95}) { - <i class="material-icons tiny" aria-label="Eingeschränkte Barrierefreiheit">info_outline</i> - % } - % if ($train->{message_id}{70} or $train->{message_id}{71}) { - <i class="material-icons tiny" aria-label="Ohne WLAN">portable_wifi_off</i> - % } - </span> - </li> - % } -</ul> diff --git a/templates/_suggestions_dbris.html.ep b/templates/_connections_dbris.html.ep index 175a57b..8fedf84 100644 --- a/templates/_suggestions_dbris.html.ep +++ b/templates/_connections_dbris.html.ep @@ -3,47 +3,47 @@ % my ($dep, $dest) = @{$res}; % my $row_class = ''; % my $link_class = 'action-checkin'; - % if ($dep->is_cancelled) { + % if ($dep->{is_cancelled}) { % $row_class = 'cancelled'; % $link_class = 'action-cancelled-from'; % } % if ($checkin_from) { <li class="collection-item <%= $row_class %> <%= $link_class %>" data-dbris="<%= $dbris %>" - data-station="<%= $dep->stop_eva %>" - data-train="<%= $dep->id %>" - data-suffix="<%= $dep->maybe_line_no %>" - data-ts="<%= ($dep->sched_dep // $dep->dep)->epoch %>" + data-station="<%= $dep->{stop_eva} %>" + data-train="<%= $dep->{id} %>" + data-suffix="<%= $dep->{maybe_line_no} %>" + data-ts="<%= $dep->{ts} %>" data-dest="<%= $dest->{name} %>"> % } % else { <li class="collection-item <%= $row_class %>"> % } <a class="dep-time" href="#"> - % if ($dep->is_cancelled) { - %= $dep->sched_dep->strftime('%H:%M') + % if ($dep->{is_cancelled}) { + %= $dep->{sched_hhmm} % } % else { - %= $dep->dep->strftime('%H:%M') + %= $dep->{rt_hhmm} % } - % if ($dep->delay) { - %= sprintf('(%+d)', $dep->delay) + % if ($dep->{delay}) { + %= sprintf('(%+d)', $dep->{delay}) % } </a> <span class="connect-platform-wrapper"> - % if ($dep->platform) { + % if ($dep->{platform}) { <span> - % if (($dep->type // q{}) =~ m{ ast | bus | ruf }ix) { + % if (($dep->{type} // q{}) =~ m{ ast | bus | ruf }ix) { Steig % } % else { Gleis % } - %= $dep->platform + %= $dep->{platform} </span> % } - <span class="dep-line <%= $dep->type // q{} %>"> - %= $dep->line + <span class="dep-line <%= $dep->{type} // q{} %>"> + %= $dep->{line} </span> </span> <span class="dep-dest"> diff --git a/templates/_suggestions_efa.html.ep b/templates/_connections_efa.html.ep index bca5d74..4800adb 100644 --- a/templates/_suggestions_efa.html.ep +++ b/templates/_connections_efa.html.ep @@ -3,49 +3,49 @@ % my ($dep, $dest, $via_arr) = @{$res}; % my $row_class = ''; % my $link_class = 'action-checkin'; - % if ($dep->is_cancelled) { + % if ($dep->{is_cancelled}) { % $row_class = 'cancelled'; % $link_class = 'action-cancelled-from'; % } % if ($checkin_from) { <li class="collection-item <%= $row_class %> <%= $link_class %>" data-efa="<%= $efa %>" - data-station="<%= $dep->stop_id_num %>" - data-train="<%= $dep->id %>" - data-ts="<%= ($dep->sched_datetime // $dep->datetime)->epoch %>" + data-station="<%= $dep->{stop_id_num} %>" + data-train="<%= $dep->{id} %>" + data-ts="<%= $dep->{ts} %>" data-dest="<%= $dest->{name} %>"> % } % else { <li class="collection-item <%= $row_class %>"> % } <a class="dep-time" href="#"> - % if ($dep->is_cancelled) { - %= $dep->sched_datetime->strftime('%H:%M') + % if ($dep->{is_cancelled}) { + %= $dep->{sched_hhmm} % } % else { - %= $dep->datetime->strftime('%H:%M') + %= $dep->{rt_hhmm} % } % if ($via_arr) { - → <%= $via_arr->strftime('%H:%M') %> + → <%= $via_arr %> % } - % if ($dep->delay) { - %= sprintf('(%+d)', $dep->delay) + % if ($dep->{delay}) { + %= sprintf('(%+d)', $dep->{delay}) % } </a> <span class="connect-platform-wrapper"> - % if ($dep->platform) { + % if ($dep->{platform}) { <span> - % if (($dep->type // q{}) =~ m{ ast | bus | ruf }ix) { + % if (($dep->{type} // q{}) =~ m{ ast | bus | ruf }ix) { Steig % } % else { Gleis % } - %= $dep->platform + %= $dep->{platform} </span> % } - <span class="dep-line <%= ($dep->type // q{}) =~ tr{a-zA-Z_-}{}cdr %>"> - %= $dep->line + <span class="dep-line <%= ($dep->{type} // q{}) =~ tr{a-zA-Z_-}{}cdr %>"> + %= $dep->{line} </span> </span> <span class="dep-dest"> diff --git a/templates/_connections_hafas.html.ep b/templates/_connections_hafas.html.ep deleted file mode 100644 index 3b995b5..0000000 --- a/templates/_connections_hafas.html.ep +++ /dev/null @@ -1,57 +0,0 @@ -<ul class="collection departures connections"> - % for my $res (@{$connections}) { - % my ($train, $via, $via_arr, $hafas_service) = @{$res}; - % $via_arr = $via_arr ? $via_arr->strftime('%H:%M') : q{}; - % my $row_class = ''; - % my $link_class = 'action-checkin'; - % if ($train->is_cancelled) { - % $row_class = 'cancelled'; - % $link_class = 'action-cancelled-from'; - % } - % if ($checkin_from) { - <li class="collection-item <%= $row_class %> <%= $link_class %>" - data-hafas="<%= $hafas_service %>" - data-station="<%= $train->station_eva %>" - data-train="<%= $train->id %>" - data-ts="<%= ($train->sched_datetime // $train->datetime)->epoch %>" - data-dest="<%= $via->{name} %>"> - % } - % else { - <li class="collection-item <%= $row_class %>"> - % } - <a class="dep-time" href="#"> - % if ($train->is_cancelled) { - %= $train->sched_datetime->strftime('%H:%M') - % } - % else { - %= $train->datetime->strftime('%H:%M') - % } - % if ($via_arr) { - → <%= $via_arr %> - % } - % if ($train->delay) { - %= sprintf('(%+d)', $train->delay) - % } - </a> - <span class="connect-platform-wrapper"> - % if ($train->platform) { - <span> - % if (($train->type // q{}) =~ m{ ast | bus | ruf }ix) { - Steig - % } - % else { - Gleis - % } - %= $train->platform - </span> - % } - <span class="dep-line <%= $train->type // q{} %>"> - %= $train->line - </span> - </span> - <span class="dep-dest"> - %= $via->{name} - </span> - </li> - % } -</ul> diff --git a/templates/_connections_iris.html.ep b/templates/_connections_iris.html.ep new file mode 100644 index 0000000..8ddc634 --- /dev/null +++ b/templates/_connections_iris.html.ep @@ -0,0 +1,44 @@ +<ul class="collection departures connections"> + % for my $res (@{$suggestions}) { + % my ($train, $dest) = @{$res}; + % my $row_class = ''; + % my $link_class = 'action-checkin'; + % if ($train->{departure_is_cancelled}) { + % $row_class = 'cancelled'; + % $link_class = 'action-cancelled-from'; + % } + % if ($checkin_from) { + <li class="collection-item <%= $row_class %> <%= $link_class %>" + data-station="<%= $train->{station_uic} %>" + data-train="<%= $train->{id} %>" + data-ts="<%= $train->{ts} %>" + data-dest="<%= $dest->{name} %>"> + % } + % else { + <li class="collection-item <%= $row_class %>"> + % } + <a class="dep-time" href="#"> + % if ($train->{departure_is_cancelled}) { + %= $train->{sched_hhmm} + % } + % else { + %= $train->{rt_hhmm} + % } + % if ($train->{departure_delay}) { + %= sprintf('(%+d)', $train->{departure_delay}) + % } + </a> + <span class="connect-platform-wrapper"> + % if ($train->{platform}) { + <span>Gleis <%= $train->{platform} %></span> + % } + <span class="dep-line <%= $train->{type} // q{} %>"> + %= $train->{line} + </span> + </span> + <span class="dep-dest"> + %= $dest->{name} + </span> + </li> + % } +</ul> diff --git a/templates/changelog.html.ep b/templates/changelog.html.ep index 042a46e..f6564cb 100644 --- a/templates/changelog.html.ep +++ b/templates/changelog.html.ep @@ -2,6 +2,22 @@ <div class="row"> <div class="col s12 m1 l1"> + 2.18 + </div> + <div class="col s12 m11 l11"> + <p> + <i class="material-icons left" aria-label="<%= L('changelog.added') %>">add</i> + %= L('changelog.2-18.1') + </p> + <p> + <i class="material-icons left" aria-label="<%= L('changelog.bugfix') %>">build</i> + %= L('changelog.2-18.2') + </p> + </div> +</div> + +<div class="row"> + <div class="col s12 m1 l1"> 2.17 </div> <div class="col s12 m11 l11"> diff --git a/templates/departures.html.ep b/templates/departures.html.ep index 0d57039..782b7c0 100644 --- a/templates/departures.html.ep +++ b/templates/departures.html.ep @@ -81,24 +81,19 @@ </div> </div> % } -% elsif (not param('train') and (@{stash('connections_iris') // []} or @{stash('connections_hafas') // []} or @{stash('suggestions') // []}) ) { +% elsif (not param('train') and @{stash('suggestions') // []} ) { % $have_connections = 1; <div class="row"> <div class="col s12"> <p>Häufig genutzte Verbindungen – Fahrt auswählen zum Einchecken mit Zielwahl</p> - % if (@{stash('connections_iris') // []}) { - %= include '_connections', connections => stash('connections_iris'), checkin_from => $eva; + % if ($dbris) { + %= include '_connections_dbris', suggestions => stash('suggestions'), checkin_from => $eva; % } - % if (@{stash('connections_hafas') // []}) { - %= include '_connections_hafas', connections => stash('connections_hafas'), checkin_from => $eva; + % elsif ($efa) { + %= include '_connections_efa', suggestions => stash('suggestions'), checkin_from => $eva; % } - % if (@{stash('suggestions') // []}) { - % if ($dbris) { - %= include '_suggestions_dbris', suggestions => stash('suggestions'), checkin_from => $eva; - % } - % elsif ($efa) { - %= include '_suggestions_efa', suggestions => stash('suggestions'), checkin_from => $eva; - % } + % else { + %= include '_connections_iris', suggestions => stash('suggestions'), checkin_from => $eva; % } </div> </div> diff --git a/templates/use_history.html.ep b/templates/use_history.html.ep index b02df18..2211603 100644 --- a/templates/use_history.html.ep +++ b/templates/use_history.html.ep @@ -2,7 +2,7 @@ <div class="row"> <div class="col s12"> <p> - Travelynx kann bei DBRIS- und EFA-Backends anhand deiner + Travelynx kann bei DBRIS-, EFA- und IRIS-Backends anhand deiner vergangenen Fahrten Verbindungen zum Einchecken vorschlagen. Fährst zu z.B regelmäßig von Dortmund Hbf nach Essen Hbf, werden dir in Dortmund bevorzugt Fahrten angezeigt, die Essen passieren. Bei |
