Loading lib/Travelynx.pm +34 −10 Original line number Diff line number Diff line Loading @@ -474,9 +474,9 @@ sub startup { # called twice: once with the old and once with the new value. $self->helper( 'invalidate_stats_cache' => sub { my ( $self, $ts, $db ) = @_; my ( $self, $ts, $db, $uid ) = @_; my $uid = $self->current_user->{id}; $uid //= $self->current_user->{id}; $db //= $self->pg->db; $self->pg->db->delete( Loading @@ -500,12 +500,12 @@ sub startup { $self->helper( 'checkout' => sub { my ( $self, $station, $force ) = @_; my ( $self, $station, $force, $uid ) = @_; my $db = $self->pg->db; my $uid = $self->current_user->{id}; my $status = $self->get_departures( $station, 120, 120 ); my $user = $self->get_user_status; $uid //= $self->current_user->{id}; my $user = $self->get_user_status($uid); my $train_id = $user->{train_id}; if ( not $user->{checked_in} and not $user->{cancelled} ) { Loading Loading @@ -602,7 +602,7 @@ sub startup { month => $+{month} ); } $self->invalidate_stats_cache( $cache_ts, $db ); $self->invalidate_stats_cache( $cache_ts, $db, $uid ); } $tx->commit; Loading Loading @@ -1268,7 +1268,7 @@ sub startup { // $in_transit->{checkin_ts}; my $action_time = epoch_to_dt($ts); return { my $ret = { checked_in => !$in_transit->{cancelled}, cancelled => $in_transit->{cancelled}, timestamp => $action_time, Loading @@ -1288,6 +1288,30 @@ sub startup { arr_name => $in_transit->{arr_name}, route_after => \@route_after, }; $ret->{departure_countdown} = $ret->{real_departure}->epoch - $now->epoch; if ( $in_transit->{real_arr_ts} ) { $ret->{arrival_countdown} = $ret->{real_arrival}->epoch - $now->epoch; $ret->{journey_duration} = $ret->{real_arrival}->epoch - $ret->{real_departure}->epoch; $ret->{journey_completion} = 1 - ( $ret->{arrival_countdown} / $ret->{journey_duration} ); if ( $ret->{journey_completion} > 1 ) { $ret->{journey_completion} = 1; } elsif ( $ret->{journey_completion} < 0 ) { $ret->{journey_completion} = 0; } } else { $ret->{arrival_countdown} = undef; $ret->{journey_duration} = undef; $ret->{journey_completion} = undef; } return $ret; } my $latest = $db->select( Loading lib/Travelynx/Command/work.pm 0 → 100644 +111 −0 Original line number Diff line number Diff line package Travelynx::Command::work; use Mojo::Base 'Mojolicious::Command'; use DateTime; use List::Util qw(first); has description => 'Perform automatic checkout when users arrive at their destination'; has usage => sub { shift->extract_usage }; sub run { my ($self) = @_; my $now = DateTime->now( time_zone => 'Europe/Berlin' ); my $db = $self->app->pg->db; for my $entry ( $db->select( 'in_transit_str', '*', { cancelled => 0 } )->hashes->each ) { my $uid = $entry->{user_id}; my $dep = $entry->{dep_ds100}; my $arr = $entry->{arr_ds100}; my $train = $entry->{train_id}; $self->app->log->debug("Processing $uid"); eval { if ( $now->epoch - $entry->{real_dep_ts} < 300 ) { $self->app->log->debug(" - updating departure"); my $status = $self->app->get_departures( $dep, 30, 30 ); if ( $status->{errstr} ) { die("get_departures($dep): $status->{errstr}\n"); } my ($train) = first { $_->train_id eq $train } @{ $status->{results} }; if ( not $train ) { die("could not find train $train at $dep\n"); } $db->update( 'in_transit', { real_departure => $train->departure }, { user_id => $uid } ); } }; if ($@) { $self->app->log->error("work($uid)/departure: $@"); } eval { if ( $entry->{arr_name} and ( not $entry->{real_arr_ts} or $now->epoch - $entry->{real_arr_ts} < 60 ) ) { $self->app->log->debug(" - updating arrival"); my $status = $self->app->get_departures( $arr, 20, 220 ); if ( $status->{errstr} ) { die("get_departures($arr): $status->{errstr}\n"); } my ($train) = first { $_->train_id eq $train } @{ $status->{results} }; if ( not $train ) { die("could not find train $train at $arr\n"); } $db->update( 'in_transit', { sched_arrival => $train->sched_arrival, real_arrival => $train->arrival, }, { user_id => $uid } ); } elsif ( $entry->{real_arr_ts} ) { $self->app->log->debug(" - checking out"); my ( undef, $error ) = $self->app->checkout( $arr, 1, $uid ); if ($error) { die("${error}\n"); } } }; if ($@) { $self->app->log->error("work($uid)/arrival: $@"); } eval { } } } 1; __END__ =head1 SYNOPSIS Usage: index.pl work Work Work Work. Should be called from a cronjob every three minutes or so. templates/landingpage.html.ep +26 −20 Original line number Diff line number Diff line Loading @@ -14,12 +14,6 @@ <div class="row"> <div class="col s12"> % my $status = get_user_status(); % my $now = DateTime->now(time_zone => 'Europe/Berlin'); % my $dep_wait = ($status->{real_departure}->epoch - $now->epoch)/60; % my $arr_wait = undef; % if ($status->{real_arrival}->epoch) { % $arr_wait = ($status->{real_arrival}->epoch - $now->epoch)/60; % } % if ($status->{checked_in}) { <div class="card green darken-4"> <div class="card-content white-text"> Loading @@ -34,30 +28,42 @@ % } </p> <p> Abfahrt % if ($dep_wait > 0) { in <%= int(($status->{real_departure}->epoch - $now->epoch)/60) %> Minute<%= $dep_wait == 1 ? '' : 'n' %> % } um <b><%= $status->{real_departure}->strftime('%H:%M') %></b> <b><%= $status->{real_departure}->strftime('%H:%M') %></b> % if ($status->{real_departure}->epoch != $status->{sched_departure}->epoch) { (+<%= int(($status->{real_departure}->epoch - $status->{sched_departure}->epoch)/60) %>) (<%= sprintf('%+d', ($status->{real_departure}->epoch - $status->{sched_departure}->epoch)/60) %>) % } </p> <p> → % if ($status->{real_arrival}->epoch) { Voraussichtliche Ankunft um <b><%= $status->{real_arrival}->strftime('%H:%M') %></b> <b><%= $status->{real_arrival}->strftime('%H:%M') %></b> % if ($status->{real_arrival}->epoch != $status->{sched_arrival}->epoch) { (+<%= int(($status->{real_arrival}->epoch - $status->{sched_arrival}->epoch)/60) %>) (<%= sprintf('%+d', ($status->{real_arrival}->epoch - $status->{sched_arrival}->epoch)/60) %>) % } % } % else { Ankunft: noch nicht bekannt unbekannt % } </p> <p> <b>Achtung:</b> Automatischer Checkout ist noch nicht implementiert. Bitte spätestens eine Stunde nach Ankunft am Ziel manuell auschecken. <div class="center"> % if ($status->{departure_countdown} > 120) { Abfahrt in <%= int($status->{departure_countdown} / 60) %> Minuten % } % elsif ($status->{arrival_countdown}) { % if ($status->{arrival_countdown} > 0) { Ankunft in <%= int($status->{arrival_countdown} / 60) %> Minute<%= int($status->{arrival_countdown} / 60) == 1 ? '' : 'n' %> % } % else { Ziel erreicht % } % } % elsif ($status->{arr_name}) { Ankunft in mehr als zwei Stunden % } </div> <div class="progress green darken-3" style="height: 1ex;"> <div class="determinate white" style="width: <%= sprintf('%.2f', 100 * $status->{journey_completion}); %>%;"></div> </div> </p> % if ($status->{arr_name}) { <p>Zielstation ändern?</p> Loading Loading
lib/Travelynx.pm +34 −10 Original line number Diff line number Diff line Loading @@ -474,9 +474,9 @@ sub startup { # called twice: once with the old and once with the new value. $self->helper( 'invalidate_stats_cache' => sub { my ( $self, $ts, $db ) = @_; my ( $self, $ts, $db, $uid ) = @_; my $uid = $self->current_user->{id}; $uid //= $self->current_user->{id}; $db //= $self->pg->db; $self->pg->db->delete( Loading @@ -500,12 +500,12 @@ sub startup { $self->helper( 'checkout' => sub { my ( $self, $station, $force ) = @_; my ( $self, $station, $force, $uid ) = @_; my $db = $self->pg->db; my $uid = $self->current_user->{id}; my $status = $self->get_departures( $station, 120, 120 ); my $user = $self->get_user_status; $uid //= $self->current_user->{id}; my $user = $self->get_user_status($uid); my $train_id = $user->{train_id}; if ( not $user->{checked_in} and not $user->{cancelled} ) { Loading Loading @@ -602,7 +602,7 @@ sub startup { month => $+{month} ); } $self->invalidate_stats_cache( $cache_ts, $db ); $self->invalidate_stats_cache( $cache_ts, $db, $uid ); } $tx->commit; Loading Loading @@ -1268,7 +1268,7 @@ sub startup { // $in_transit->{checkin_ts}; my $action_time = epoch_to_dt($ts); return { my $ret = { checked_in => !$in_transit->{cancelled}, cancelled => $in_transit->{cancelled}, timestamp => $action_time, Loading @@ -1288,6 +1288,30 @@ sub startup { arr_name => $in_transit->{arr_name}, route_after => \@route_after, }; $ret->{departure_countdown} = $ret->{real_departure}->epoch - $now->epoch; if ( $in_transit->{real_arr_ts} ) { $ret->{arrival_countdown} = $ret->{real_arrival}->epoch - $now->epoch; $ret->{journey_duration} = $ret->{real_arrival}->epoch - $ret->{real_departure}->epoch; $ret->{journey_completion} = 1 - ( $ret->{arrival_countdown} / $ret->{journey_duration} ); if ( $ret->{journey_completion} > 1 ) { $ret->{journey_completion} = 1; } elsif ( $ret->{journey_completion} < 0 ) { $ret->{journey_completion} = 0; } } else { $ret->{arrival_countdown} = undef; $ret->{journey_duration} = undef; $ret->{journey_completion} = undef; } return $ret; } my $latest = $db->select( Loading
lib/Travelynx/Command/work.pm 0 → 100644 +111 −0 Original line number Diff line number Diff line package Travelynx::Command::work; use Mojo::Base 'Mojolicious::Command'; use DateTime; use List::Util qw(first); has description => 'Perform automatic checkout when users arrive at their destination'; has usage => sub { shift->extract_usage }; sub run { my ($self) = @_; my $now = DateTime->now( time_zone => 'Europe/Berlin' ); my $db = $self->app->pg->db; for my $entry ( $db->select( 'in_transit_str', '*', { cancelled => 0 } )->hashes->each ) { my $uid = $entry->{user_id}; my $dep = $entry->{dep_ds100}; my $arr = $entry->{arr_ds100}; my $train = $entry->{train_id}; $self->app->log->debug("Processing $uid"); eval { if ( $now->epoch - $entry->{real_dep_ts} < 300 ) { $self->app->log->debug(" - updating departure"); my $status = $self->app->get_departures( $dep, 30, 30 ); if ( $status->{errstr} ) { die("get_departures($dep): $status->{errstr}\n"); } my ($train) = first { $_->train_id eq $train } @{ $status->{results} }; if ( not $train ) { die("could not find train $train at $dep\n"); } $db->update( 'in_transit', { real_departure => $train->departure }, { user_id => $uid } ); } }; if ($@) { $self->app->log->error("work($uid)/departure: $@"); } eval { if ( $entry->{arr_name} and ( not $entry->{real_arr_ts} or $now->epoch - $entry->{real_arr_ts} < 60 ) ) { $self->app->log->debug(" - updating arrival"); my $status = $self->app->get_departures( $arr, 20, 220 ); if ( $status->{errstr} ) { die("get_departures($arr): $status->{errstr}\n"); } my ($train) = first { $_->train_id eq $train } @{ $status->{results} }; if ( not $train ) { die("could not find train $train at $arr\n"); } $db->update( 'in_transit', { sched_arrival => $train->sched_arrival, real_arrival => $train->arrival, }, { user_id => $uid } ); } elsif ( $entry->{real_arr_ts} ) { $self->app->log->debug(" - checking out"); my ( undef, $error ) = $self->app->checkout( $arr, 1, $uid ); if ($error) { die("${error}\n"); } } }; if ($@) { $self->app->log->error("work($uid)/arrival: $@"); } eval { } } } 1; __END__ =head1 SYNOPSIS Usage: index.pl work Work Work Work. Should be called from a cronjob every three minutes or so.
templates/landingpage.html.ep +26 −20 Original line number Diff line number Diff line Loading @@ -14,12 +14,6 @@ <div class="row"> <div class="col s12"> % my $status = get_user_status(); % my $now = DateTime->now(time_zone => 'Europe/Berlin'); % my $dep_wait = ($status->{real_departure}->epoch - $now->epoch)/60; % my $arr_wait = undef; % if ($status->{real_arrival}->epoch) { % $arr_wait = ($status->{real_arrival}->epoch - $now->epoch)/60; % } % if ($status->{checked_in}) { <div class="card green darken-4"> <div class="card-content white-text"> Loading @@ -34,30 +28,42 @@ % } </p> <p> Abfahrt % if ($dep_wait > 0) { in <%= int(($status->{real_departure}->epoch - $now->epoch)/60) %> Minute<%= $dep_wait == 1 ? '' : 'n' %> % } um <b><%= $status->{real_departure}->strftime('%H:%M') %></b> <b><%= $status->{real_departure}->strftime('%H:%M') %></b> % if ($status->{real_departure}->epoch != $status->{sched_departure}->epoch) { (+<%= int(($status->{real_departure}->epoch - $status->{sched_departure}->epoch)/60) %>) (<%= sprintf('%+d', ($status->{real_departure}->epoch - $status->{sched_departure}->epoch)/60) %>) % } </p> <p> → % if ($status->{real_arrival}->epoch) { Voraussichtliche Ankunft um <b><%= $status->{real_arrival}->strftime('%H:%M') %></b> <b><%= $status->{real_arrival}->strftime('%H:%M') %></b> % if ($status->{real_arrival}->epoch != $status->{sched_arrival}->epoch) { (+<%= int(($status->{real_arrival}->epoch - $status->{sched_arrival}->epoch)/60) %>) (<%= sprintf('%+d', ($status->{real_arrival}->epoch - $status->{sched_arrival}->epoch)/60) %>) % } % } % else { Ankunft: noch nicht bekannt unbekannt % } </p> <p> <b>Achtung:</b> Automatischer Checkout ist noch nicht implementiert. Bitte spätestens eine Stunde nach Ankunft am Ziel manuell auschecken. <div class="center"> % if ($status->{departure_countdown} > 120) { Abfahrt in <%= int($status->{departure_countdown} / 60) %> Minuten % } % elsif ($status->{arrival_countdown}) { % if ($status->{arrival_countdown} > 0) { Ankunft in <%= int($status->{arrival_countdown} / 60) %> Minute<%= int($status->{arrival_countdown} / 60) == 1 ? '' : 'n' %> % } % else { Ziel erreicht % } % } % elsif ($status->{arr_name}) { Ankunft in mehr als zwei Stunden % } </div> <div class="progress green darken-3" style="height: 1ex;"> <div class="determinate white" style="width: <%= sprintf('%.2f', 100 * $status->{journey_completion}); %>%;"></div> </div> </p> % if ($status->{arr_name}) { <p>Zielstation ändern?</p> Loading