diff options
Diffstat (limited to 'lib')
| -rwxr-xr-x | lib/Travelynx.pm | 44 | ||||
| -rw-r--r-- | lib/Travelynx/Command/work.pm | 111 | 
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. | 
