mirror of
https://github.com/derf/travelynx
synced 2024-12-12 22:12:32 +00:00
Work in progress: show connections when arriving soon
At the moment, the heuristic used to determine connection targets is quite simple: $station is a target iff there were at least two trips in the past 6 weeks with checkin at the current destination station and checkout at $station. Todo / enhanhement options: * Consider current origin station as well, i.e.: $station is a target iff there were at least two trips in the past 6 weeks which are preceded by a trip from the current origin station and (same as above) * Make connection links clickable once the current journey has ended. Connections need to be added to _checked_out as well for this to work.
This commit is contained in:
parent
7486920a6a
commit
7960114f71
2 changed files with 145 additions and 1 deletions
111
lib/Travelynx.pm
111
lib/Travelynx.pm
|
@ -1482,6 +1482,117 @@ sub startup {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$self->helper(
|
||||||
|
'get_connection_targets' => sub {
|
||||||
|
my ( $self, %opt ) = @_;
|
||||||
|
|
||||||
|
my $uid = $opt{uid} // $self->current_user->{id};
|
||||||
|
my $threshold = $opt{threshold}
|
||||||
|
// DateTime->now( time_zone => 'Europe/Berlin' )
|
||||||
|
->subtract( weeks => 60 );
|
||||||
|
my $db = $opt{db} // $self->pg->db;
|
||||||
|
|
||||||
|
my $journey = $db->select( 'in_transit', ['checkout_station_id'],
|
||||||
|
{ user_id => $uid } )->hash;
|
||||||
|
if ( not $journey ) {
|
||||||
|
$journey = $db->select(
|
||||||
|
'journeys',
|
||||||
|
['checkout_station_id'],
|
||||||
|
{
|
||||||
|
user_id => $uid,
|
||||||
|
cancelled => 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
limit => 1,
|
||||||
|
order_by => { -desc => 'real_dep_ts' }
|
||||||
|
}
|
||||||
|
)->hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( not $journey ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $res = $db->query(
|
||||||
|
qq{
|
||||||
|
select
|
||||||
|
count(stations.name) as count,
|
||||||
|
stations.name as dest
|
||||||
|
from journeys
|
||||||
|
left outer join stations on checkout_station_id = stations.id
|
||||||
|
where user_id = ?
|
||||||
|
and checkin_station_id = ?
|
||||||
|
and real_departure > ?
|
||||||
|
group by stations.name
|
||||||
|
order by count desc;
|
||||||
|
},
|
||||||
|
$uid,
|
||||||
|
$journey->{checkout_station_id},
|
||||||
|
$threshold
|
||||||
|
);
|
||||||
|
my @destinations = $res->hashes->grep( sub { shift->{count} > 2 } )
|
||||||
|
->map( sub { shift->{dest} } )->each;
|
||||||
|
return @destinations;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$self->helper(
|
||||||
|
'get_connecting_trains' => sub {
|
||||||
|
my ( $self, %opt ) = @_;
|
||||||
|
|
||||||
|
my $status = $self->get_user_status;
|
||||||
|
|
||||||
|
if ( not $status->{arr_ds100} ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
my @destinations = $self->get_connection_targets(%opt);
|
||||||
|
my $stationboard
|
||||||
|
= $self->get_departures( $status->{arr_ds100}, 0, 60 );
|
||||||
|
|
||||||
|
@destinations = grep { $_ ne $status->{dep_name} } @destinations;
|
||||||
|
|
||||||
|
if ( $stationboard->{errstr} ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
my @results;
|
||||||
|
my %via_count = map { $_ => 0 } @destinations;
|
||||||
|
for my $train ( @{ $stationboard->{results} } ) {
|
||||||
|
if ( not $train->departure ) {
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
if ( $train->departure->epoch < $status->{real_arrival}->epoch )
|
||||||
|
{
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
if ( $train->train_id eq $status->{train_id} ) {
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
my @via = ( $train->route_post, $train->route_end );
|
||||||
|
for my $dest (@destinations) {
|
||||||
|
if ( $via_count{$dest} < 3
|
||||||
|
and List::Util::any { $_ eq $dest } @via )
|
||||||
|
{
|
||||||
|
push( @results, [ $train, $dest ] );
|
||||||
|
$via_count{$dest}++;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@results = map { $_->[0] }
|
||||||
|
sort { $a->[1] <=> $b->[1] }
|
||||||
|
map {
|
||||||
|
[
|
||||||
|
$_,
|
||||||
|
$_->[0]->departure->epoch // $_->[0]->sched_departur->epoch
|
||||||
|
]
|
||||||
|
} @results;
|
||||||
|
|
||||||
|
return @results;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
$self->helper(
|
$self->helper(
|
||||||
'get_user_travels' => sub {
|
'get_user_travels' => sub {
|
||||||
my ( $self, %opt ) = @_;
|
my ( $self, %opt ) = @_;
|
||||||
|
|
|
@ -77,8 +77,41 @@
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
</p>
|
||||||
% }
|
% }
|
||||||
|
% if (defined $journey->{arrival_countdown} and $journey->{arrival_countdown} < (20*60)) {
|
||||||
|
% if (my @connections = get_connecting_trains()) {
|
||||||
|
<span class="card-title" style="margin-top: 2ex;">Verbindungen</span>
|
||||||
|
<div class="hide-on-med-and-up"><table><tbody>
|
||||||
|
% for my $res (@connections) {
|
||||||
|
% my ($train, $via) = @{$res};
|
||||||
|
<tr>
|
||||||
|
<td><%= $train->line %></td>
|
||||||
|
<td><%= $via %></td>
|
||||||
|
<td><%= $train->departure->strftime('%H:%M') %>
|
||||||
|
% if ($train->departure_delay) {
|
||||||
|
%= sprintf('(%+d)', $train->departure_delay)
|
||||||
|
% }
|
||||||
|
<br/>Gleis <%= $train->platform %></td>
|
||||||
|
</tr>
|
||||||
|
% }
|
||||||
|
</tbody></table></div>
|
||||||
|
<div class="hide-on-small-only"><table><tbody>
|
||||||
|
% for my $res (@connections) {
|
||||||
|
% my ($train, $via) = @{$res};
|
||||||
|
<tr>
|
||||||
|
<td><%= $train->line %></td>
|
||||||
|
<td><%= $via %></td>
|
||||||
|
<td><%= $train->departure->strftime('%H:%M') %>
|
||||||
|
% if ($train->departure_delay) {
|
||||||
|
%= sprintf('(%+d)', $train->departure_delay)
|
||||||
|
% }
|
||||||
|
</td><td>Gleis <%= $train->platform %></td>
|
||||||
|
</tr>
|
||||||
|
% }
|
||||||
|
</tbody></table></div>
|
||||||
|
% }
|
||||||
|
% }
|
||||||
% if (defined $journey->{arrival_countdown} and $journey->{arrival_countdown} <= 0) {
|
% if (defined $journey->{arrival_countdown} and $journey->{arrival_countdown} <= 0) {
|
||||||
<p>
|
<p style="margin-top: 2ex;">
|
||||||
Der automatische Checkout erfolgt in wenigen Minuten. Zum Umsteigen:
|
Der automatische Checkout erfolgt in wenigen Minuten. Zum Umsteigen:
|
||||||
Aktuelle Station erneut in der Liste auswählen. Zum Weiterfahren im
|
Aktuelle Station erneut in der Liste auswählen. Zum Weiterfahren im
|
||||||
aktuellen Zug: Neues Ziel wählen.
|
aktuellen Zug: Neues Ziel wählen.
|
||||||
|
|
Loading…
Reference in a new issue