summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2019-04-23 21:30:31 +0200
committerDaniel Friesel <derf@finalrewind.org>2019-04-23 21:30:31 +0200
commitffaa0c44a78bb4bab632fcb76b668215da4c0a82 (patch)
treee4379158253dbdfbc0b6217e351da5a410ad1074 /lib
parent5af134ef1ec968597a8fb9feb44372657d178bb8 (diff)
Automatic checkout \o/
Diffstat (limited to 'lib')
-rwxr-xr-xlib/Travelynx.pm44
-rw-r--r--lib/Travelynx/Command/work.pm111
2 files changed, 145 insertions, 10 deletions
diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm
index da10a9a..c11f175 100755
--- a/lib/Travelynx.pm
+++ b/lib/Travelynx.pm
@@ -474,10 +474,10 @@ 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};
- $db //= $self->pg->db;
+ $uid //= $self->current_user->{id};
+ $db //= $self->pg->db;
$self->pg->db->delete(
'journey_stats',
@@ -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;
+ my $db = $self->pg->db;
+ my $status = $self->get_departures( $station, 120, 120 );
+ $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} ) {
@@ -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;
@@ -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,
@@ -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(
diff --git a/lib/Travelynx/Command/work.pm b/lib/Travelynx/Command/work.pm
new file mode 100644
index 0000000..b8f8e52
--- /dev/null
+++ b/lib/Travelynx/Command/work.pm
@@ -0,0 +1,111 @@
+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.