convert checkout to promises (checkout_p)
This commit is contained in:
parent
c0754f9e87
commit
38ad42b42c
3 changed files with 347 additions and 256 deletions
415
lib/Travelynx.pm
415
lib/Travelynx.pm
|
@ -588,7 +588,7 @@ sub startup {
|
||||||
);
|
);
|
||||||
|
|
||||||
$self->helper(
|
$self->helper(
|
||||||
'checkout' => sub {
|
'checkout_p' => sub {
|
||||||
my ( $self, %opt ) = @_;
|
my ( $self, %opt ) = @_;
|
||||||
|
|
||||||
my $station = $opt{station};
|
my $station = $opt{station};
|
||||||
|
@ -596,34 +596,29 @@ sub startup {
|
||||||
my $arr_eva = $opt{arr_eva};
|
my $arr_eva = $opt{arr_eva};
|
||||||
my $with_related = $opt{with_related} // 0;
|
my $with_related = $opt{with_related} // 0;
|
||||||
my $force = $opt{force};
|
my $force = $opt{force};
|
||||||
my $uid = $opt{uid};
|
my $uid = $opt{uid} // $self->current_user->{id};
|
||||||
my $db = $opt{db} // $self->pg->db;
|
my $db = $opt{db} // $self->pg->db;
|
||||||
my $status = $self->iris->get_departures(
|
my $user = $self->get_user_status( $uid, $db );
|
||||||
station => $station,
|
my $train_id = $user->{train_id};
|
||||||
lookbehind => 120,
|
|
||||||
lookahead => 180,
|
my $promise = Mojo::Promise->new;
|
||||||
with_related => $with_related,
|
|
||||||
);
|
|
||||||
$uid //= $self->current_user->{id};
|
|
||||||
my $user = $self->get_user_status( $uid, $db );
|
|
||||||
my $train_id = $user->{train_id};
|
|
||||||
|
|
||||||
if ( not $station ) {
|
if ( not $station ) {
|
||||||
$self->app->log->error("Checkout($uid): station is empty");
|
$self->app->log->error("Checkout($uid): station is empty");
|
||||||
return ( 1, 'BUG: Checkout station is empty.' );
|
return $promise->resolve( 1,
|
||||||
|
'BUG: Checkout station is empty.' );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( not $user->{checked_in} and not $user->{cancelled} ) {
|
if ( not $user->{checked_in} and not $user->{cancelled} ) {
|
||||||
return ( 0, 'You are not checked into any train' );
|
return $promise->resolve( 0,
|
||||||
}
|
'You are not checked into any train' );
|
||||||
if ( $status->{errstr} and not $force ) {
|
|
||||||
return ( 1, $status->{errstr} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $dep_eva and $dep_eva != $user->{dep_eva} ) {
|
if ( $dep_eva and $dep_eva != $user->{dep_eva} ) {
|
||||||
return ( 0, 'race condition' );
|
return $promise->resolve( 0, 'race condition' );
|
||||||
}
|
}
|
||||||
if ( $arr_eva and $arr_eva != $user->{arr_eva} ) {
|
if ( $arr_eva and $arr_eva != $user->{arr_eva} ) {
|
||||||
return ( 0, 'race condition' );
|
return $promise->resolve( 0, 'race condition' );
|
||||||
}
|
}
|
||||||
|
|
||||||
my $now = DateTime->now( time_zone => 'Europe/Berlin' );
|
my $now = DateTime->now( time_zone => 'Europe/Berlin' );
|
||||||
|
@ -632,196 +627,232 @@ sub startup {
|
||||||
with_data => 1
|
with_data => 1
|
||||||
);
|
);
|
||||||
|
|
||||||
# Note that a train may pass the same station several times.
|
$self->iris->get_departures_p(
|
||||||
# Notable example: S41 / S42 ("Ringbahn") both starts and
|
station => $station,
|
||||||
# terminates at Berlin Südkreuz
|
lookbehind => 120,
|
||||||
my ($train) = List::Util::first {
|
lookahead => 180,
|
||||||
$_->train_id eq $train_id
|
with_related => $with_related,
|
||||||
and $_->sched_arrival
|
)->then(
|
||||||
and $_->sched_arrival->epoch > $user->{sched_departure}->epoch
|
sub {
|
||||||
}
|
my ($status) = @_;
|
||||||
@{ $status->{results} };
|
|
||||||
|
|
||||||
$train //= List::Util::first { $_->train_id eq $train_id }
|
my $new_checkout_station_id = $status->{station_eva};
|
||||||
@{ $status->{results} };
|
|
||||||
|
|
||||||
my $new_checkout_station_id = $status->{station_eva};
|
# Store the intended checkout station regardless of this operation's
|
||||||
|
# success.
|
||||||
|
# TODO for with_related == 1, the correct EVA may be different
|
||||||
|
# and should be fetched from $train later on
|
||||||
|
$self->in_transit->set_arrival_eva(
|
||||||
|
uid => $uid,
|
||||||
|
db => $db,
|
||||||
|
arrival_eva => $new_checkout_station_id
|
||||||
|
);
|
||||||
|
|
||||||
# Store the intended checkout station regardless of this operation's
|
# If in_transit already contains arrival data for another estimated
|
||||||
# success.
|
# destination, we must invalidate it.
|
||||||
$self->in_transit->set_arrival_eva(
|
if ( defined $journey->{checkout_station_id}
|
||||||
uid => $uid,
|
and $journey->{checkout_station_id}
|
||||||
db => $db,
|
!= $new_checkout_station_id )
|
||||||
arrival_eva => $new_checkout_station_id
|
{
|
||||||
);
|
$self->in_transit->unset_arrival_data(
|
||||||
|
uid => $uid,
|
||||||
|
db => $db
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
# If in_transit already contains arrival data for another estimated
|
# Note that a train may pass the same station several times.
|
||||||
# destination, we must invalidate it.
|
# Notable example: S41 / S42 ("Ringbahn") both starts and
|
||||||
if ( defined $journey->{checkout_station_id}
|
# terminates at Berlin Südkreuz
|
||||||
and $journey->{checkout_station_id}
|
my $train = List::Util::first {
|
||||||
!= $new_checkout_station_id )
|
$_->train_id eq $train_id
|
||||||
{
|
and $_->sched_arrival
|
||||||
$self->in_transit->unset_arrival_data(
|
and $_->sched_arrival->epoch
|
||||||
uid => $uid,
|
> $user->{sched_departure}->epoch
|
||||||
db => $db
|
}
|
||||||
);
|
@{ $status->{results} };
|
||||||
}
|
|
||||||
|
|
||||||
if ( not defined $train ) {
|
$train //= List::Util::first { $_->train_id eq $train_id }
|
||||||
|
@{ $status->{results} };
|
||||||
|
|
||||||
# Arrival time via IRIS is unknown, so the train probably has not
|
if ( not defined $train ) {
|
||||||
# arrived yet. Fall back to HAFAS.
|
|
||||||
# TODO support cases where $station is EVA or DS100 code
|
# Arrival time via IRIS is unknown, so the train probably
|
||||||
if (
|
# has not arrived yet. Fall back to HAFAS.
|
||||||
my $station_data
|
# TODO support cases where $station is EVA or DS100 code
|
||||||
= List::Util::first { $_->[0] eq $station }
|
if (
|
||||||
@{ $journey->{route} }
|
my $station_data
|
||||||
)
|
= List::Util::first { $_->[0] eq $station }
|
||||||
{
|
@{ $journey->{route} }
|
||||||
$station_data = $station_data->[2];
|
)
|
||||||
if ( $station_data->{sched_arr} ) {
|
{
|
||||||
my $sched_arr
|
$station_data = $station_data->[2];
|
||||||
= epoch_to_dt( $station_data->{sched_arr} );
|
if ( $station_data->{sched_arr} ) {
|
||||||
my $rt_arr = epoch_to_dt( $station_data->{rt_arr} );
|
my $sched_arr
|
||||||
if ( $rt_arr->epoch == 0 ) {
|
= epoch_to_dt( $station_data->{sched_arr} );
|
||||||
$rt_arr = $sched_arr->clone;
|
my $rt_arr
|
||||||
if ( $station_data->{arr_delay}
|
= epoch_to_dt( $station_data->{rt_arr} );
|
||||||
and $station_data->{arr_delay} =~ m{^\d+$} )
|
if ( $rt_arr->epoch == 0 ) {
|
||||||
{
|
$rt_arr = $sched_arr->clone;
|
||||||
$rt_arr->add(
|
if ( $station_data->{arr_delay}
|
||||||
minutes => $station_data->{arr_delay} );
|
and $station_data->{arr_delay}
|
||||||
|
=~ m{^\d+$} )
|
||||||
|
{
|
||||||
|
$rt_arr->add( minutes =>
|
||||||
|
$station_data->{arr_delay} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$self->in_transit->set_arrival_times(
|
||||||
|
uid => $uid,
|
||||||
|
db => $db,
|
||||||
|
sched_arrival => $sched_arr,
|
||||||
|
rt_arrival => $rt_arr
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$self->in_transit->set_arrival_times(
|
if ( not $force ) {
|
||||||
uid => $uid,
|
|
||||||
db => $db,
|
|
||||||
sched_arrival => $sched_arr,
|
|
||||||
rt_arrival => $rt_arr
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( not $force ) {
|
|
||||||
|
|
||||||
# mustn't be called during a transaction
|
# mustn't be called during a transaction
|
||||||
if ( not $opt{in_transaction} ) {
|
if ( not $opt{in_transaction} ) {
|
||||||
$self->run_hook( $uid, 'update' );
|
$self->run_hook( $uid, 'update' );
|
||||||
}
|
}
|
||||||
return ( 1, undef );
|
$promise->resolve( 1, undef );
|
||||||
}
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
my $has_arrived = 0;
|
|
||||||
|
|
||||||
eval {
|
|
||||||
|
|
||||||
my $tx;
|
|
||||||
if ( not $opt{in_transaction} ) {
|
|
||||||
$tx = $db->begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( defined $train and not $train->arrival and not $force ) {
|
|
||||||
my $train_no = $train->train_no;
|
|
||||||
die("Train ${train_no} has no arrival timestamp\n");
|
|
||||||
}
|
|
||||||
elsif ( defined $train and $train->arrival ) {
|
|
||||||
$self->in_transit->set_arrival(
|
|
||||||
uid => $uid,
|
|
||||||
db => $db,
|
|
||||||
train => $train,
|
|
||||||
route => [ $self->iris->route_diff($train) ]
|
|
||||||
);
|
|
||||||
|
|
||||||
$has_arrived = $train->arrival->epoch < $now->epoch ? 1 : 0;
|
|
||||||
if ($has_arrived) {
|
|
||||||
my @unknown_stations
|
|
||||||
= $self->stations->grep_unknown( $train->route );
|
|
||||||
if (@unknown_stations) {
|
|
||||||
$self->app->log->warn(
|
|
||||||
sprintf(
|
|
||||||
'Route of %s %s (%s -> %s) contains unknown stations: %s',
|
|
||||||
$train->type,
|
|
||||||
$train->train_no,
|
|
||||||
$train->origin,
|
|
||||||
$train->destination,
|
|
||||||
join( ', ', @unknown_stations )
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
my $has_arrived = 0;
|
||||||
|
|
||||||
$journey = $self->in_transit->get(
|
eval {
|
||||||
uid => $uid,
|
|
||||||
db => $db
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( $has_arrived or $force ) {
|
my $tx;
|
||||||
$self->journeys->add_from_in_transit(
|
if ( not $opt{in_transaction} ) {
|
||||||
db => $db,
|
$tx = $db->begin;
|
||||||
journey => $journey
|
}
|
||||||
);
|
|
||||||
$self->in_transit->delete(
|
|
||||||
uid => $uid,
|
|
||||||
db => $db
|
|
||||||
);
|
|
||||||
|
|
||||||
my $cache_ts = $now->clone;
|
if ( defined $train
|
||||||
if ( $journey->{real_departure}
|
and not $train->arrival
|
||||||
=~ m{ ^ (?<year> \d{4} ) - (?<month> \d{2} ) }x )
|
and not $force )
|
||||||
{
|
{
|
||||||
$cache_ts->set(
|
my $train_no = $train->train_no;
|
||||||
year => $+{year},
|
die("Train ${train_no} has no arrival timestamp\n");
|
||||||
month => $+{month}
|
}
|
||||||
|
elsif ( defined $train and $train->arrival ) {
|
||||||
|
$self->in_transit->set_arrival(
|
||||||
|
uid => $uid,
|
||||||
|
db => $db,
|
||||||
|
train => $train,
|
||||||
|
route => [ $self->iris->route_diff($train) ]
|
||||||
|
);
|
||||||
|
|
||||||
|
$has_arrived
|
||||||
|
= $train->arrival->epoch < $now->epoch ? 1 : 0;
|
||||||
|
if ($has_arrived) {
|
||||||
|
my @unknown_stations
|
||||||
|
= $self->stations->grep_unknown(
|
||||||
|
$train->route );
|
||||||
|
if (@unknown_stations) {
|
||||||
|
$self->app->log->warn(
|
||||||
|
sprintf(
|
||||||
|
'Route of %s %s (%s -> %s) contains unknown stations: %s',
|
||||||
|
$train->type,
|
||||||
|
$train->train_no,
|
||||||
|
$train->origin,
|
||||||
|
$train->destination,
|
||||||
|
join( ', ', @unknown_stations )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$journey = $self->in_transit->get(
|
||||||
|
uid => $uid,
|
||||||
|
db => $db
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ( $has_arrived or $force ) {
|
||||||
|
$self->journeys->add_from_in_transit(
|
||||||
|
db => $db,
|
||||||
|
journey => $journey
|
||||||
|
);
|
||||||
|
$self->in_transit->delete(
|
||||||
|
uid => $uid,
|
||||||
|
db => $db
|
||||||
|
);
|
||||||
|
|
||||||
|
my $cache_ts = $now->clone;
|
||||||
|
if ( $journey->{real_departure}
|
||||||
|
=~ m{ ^ (?<year> \d{4} ) - (?<month> \d{2} ) }x
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$cache_ts->set(
|
||||||
|
year => $+{year},
|
||||||
|
month => $+{month}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$self->journey_stats_cache->invalidate(
|
||||||
|
ts => $cache_ts,
|
||||||
|
db => $db,
|
||||||
|
uid => $uid
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elsif ( defined $train
|
||||||
|
and $train->arrival_is_cancelled )
|
||||||
|
{
|
||||||
|
|
||||||
|
# This branch is only taken if the deparure was not cancelled,
|
||||||
|
# i.e., if the train was supposed to go here but got
|
||||||
|
# redirected or cancelled on the way and not from the start on.
|
||||||
|
# If the departure itself was cancelled, the user route is
|
||||||
|
# cancelled_from action -> 'cancelled journey' panel on main page
|
||||||
|
# -> cancelled_to action -> force checkout (causing the
|
||||||
|
# previous branch to be taken due to $force)
|
||||||
|
$journey->{cancelled} = 1;
|
||||||
|
$self->journeys->add_from_in_transit(
|
||||||
|
db => $db,
|
||||||
|
journey => $journey
|
||||||
|
);
|
||||||
|
$self->in_transit->set_cancelled_destination(
|
||||||
|
uid => $uid,
|
||||||
|
db => $db,
|
||||||
|
cancelled_destination => $train->station,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( not $opt{in_transaction} ) {
|
||||||
|
$tx->commit;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($@) {
|
||||||
|
$self->app->log->error("Checkout($uid): $@");
|
||||||
|
$promise->resolve( 1, 'Checkout error: ' . $@ );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
$self->journey_stats_cache->invalidate(
|
|
||||||
ts => $cache_ts,
|
|
||||||
db => $db,
|
|
||||||
uid => $uid
|
|
||||||
);
|
|
||||||
}
|
|
||||||
elsif ( defined $train and $train->arrival_is_cancelled ) {
|
|
||||||
|
|
||||||
# This branch is only taken if the deparure was not cancelled,
|
if ( $has_arrived or $force ) {
|
||||||
# i.e., if the train was supposed to go here but got
|
if ( not $opt{in_transaction} ) {
|
||||||
# redirected or cancelled on the way and not from the start on.
|
$self->run_hook( $uid, 'checkout' );
|
||||||
# If the departure itself was cancelled, the user route is
|
}
|
||||||
# cancelled_from action -> 'cancelled journey' panel on main page
|
$promise->resolve( 0, undef );
|
||||||
# -> cancelled_to action -> force checkout (causing the
|
return;
|
||||||
# previous branch to be taken due to $force)
|
}
|
||||||
$journey->{cancelled} = 1;
|
if ( not $opt{in_transaction} ) {
|
||||||
$self->journeys->add_from_in_transit(
|
$self->run_hook( $uid, 'update' );
|
||||||
db => $db,
|
$self->add_route_timestamps( $uid, $train, 0, 1 );
|
||||||
journey => $journey
|
}
|
||||||
);
|
$promise->resolve( 1, undef );
|
||||||
$self->in_transit->set_cancelled_destination(
|
return;
|
||||||
uid => $uid,
|
|
||||||
db => $db,
|
|
||||||
cancelled_destination => $train->station,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( not $opt{in_transaction} ) {
|
|
||||||
$tx->commit;
|
|
||||||
}
|
}
|
||||||
};
|
)->catch(
|
||||||
|
sub {
|
||||||
if ($@) {
|
my ($err) = @_;
|
||||||
$self->app->log->error("Checkout($uid): $@");
|
$promise->resolve( 1, $err );
|
||||||
return ( 1, 'Checkout error: ' . $@ );
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if ( $has_arrived or $force ) {
|
|
||||||
if ( not $opt{in_transaction} ) {
|
|
||||||
$self->run_hook( $uid, 'checkout' );
|
|
||||||
}
|
}
|
||||||
return ( 0, undef );
|
)->wait;
|
||||||
}
|
|
||||||
if ( not $opt{in_transaction} ) {
|
return $promise;
|
||||||
$self->run_hook( $uid, 'update' );
|
|
||||||
$self->add_route_timestamps( $uid, $train, 0, 1 );
|
|
||||||
}
|
|
||||||
return ( 1, undef );
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1788,13 +1819,17 @@ sub startup {
|
||||||
)->then(
|
)->then(
|
||||||
sub {
|
sub {
|
||||||
$self->log->debug("... handled origin");
|
$self->log->debug("... handled origin");
|
||||||
my ( undef, $err ) = $self->checkout(
|
return $self->checkout_p(
|
||||||
station => $traewelling->{arr_eva},
|
station => $traewelling->{arr_eva},
|
||||||
train_id => 0,
|
train_id => 0,
|
||||||
uid => $uid,
|
uid => $uid,
|
||||||
in_transaction => 1,
|
in_transaction => 1,
|
||||||
db => $db
|
db => $db
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
)->then(
|
||||||
|
sub {
|
||||||
|
my ( undef, $err ) = @_;
|
||||||
if ($err) {
|
if ($err) {
|
||||||
$self->log->debug("... error: $err");
|
$self->log->debug("... error: $err");
|
||||||
return Mojo::Promise->reject($err);
|
return Mojo::Promise->reject($err);
|
||||||
|
|
|
@ -86,15 +86,15 @@ sub run {
|
||||||
# train.
|
# train.
|
||||||
if ($checked_in) {
|
if ($checked_in) {
|
||||||
|
|
||||||
# check out (adds a cancelled journey and resets journey state
|
# check out (adds a cancelled journey and resets journey state
|
||||||
# to checkin
|
# to checkin
|
||||||
$self->app->checkout(
|
$self->app->checkout_p(
|
||||||
station => $arr,
|
station => $arr,
|
||||||
force => 1,
|
force => 2,
|
||||||
dep_eva => $dep,
|
dep_eva => $dep,
|
||||||
arr_eva => $arr,
|
arr_eva => $arr,
|
||||||
uid => $uid
|
uid => $uid
|
||||||
);
|
)->wait;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -153,15 +153,15 @@ sub run {
|
||||||
|
|
||||||
if ( $checked_in and $train->arrival_is_cancelled ) {
|
if ( $checked_in and $train->arrival_is_cancelled ) {
|
||||||
|
|
||||||
# check out (adds a cancelled journey and resets journey state
|
# check out (adds a cancelled journey and resets journey state
|
||||||
# to destination selection)
|
# to destination selection)
|
||||||
$self->app->checkout(
|
$self->app->checkout_p(
|
||||||
station => $arr,
|
station => $arr,
|
||||||
force => 0,
|
force => 0,
|
||||||
dep_eva => $dep,
|
dep_eva => $dep,
|
||||||
arr_eva => $arr,
|
arr_eva => $arr,
|
||||||
uid => $uid
|
uid => $uid
|
||||||
);
|
)->wait;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$self->app->add_route_timestamps(
|
$self->app->add_route_timestamps(
|
||||||
|
@ -174,21 +174,24 @@ sub run {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ( $entry->{real_arr_ts} ) {
|
elsif ( $entry->{real_arr_ts} ) {
|
||||||
my ( undef, $error ) = $self->app->checkout(
|
my ( undef, $error ) = $self->app->checkout_p(
|
||||||
station => $arr,
|
station => $arr,
|
||||||
force => 1,
|
force => 2,
|
||||||
dep_eva => $dep,
|
dep_eva => $dep,
|
||||||
arr_eva => $arr,
|
arr_eva => $arr,
|
||||||
uid => $uid
|
uid => $uid
|
||||||
);
|
)->catch(
|
||||||
if ($error) {
|
sub {
|
||||||
die("${error}\n");
|
my ($error) = @_;
|
||||||
}
|
$self->app->log->error("work($uid)/arrival: $@");
|
||||||
|
$errors += 1;
|
||||||
|
}
|
||||||
|
)->wait;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if ($@) {
|
if ($@) {
|
||||||
$errors += 1;
|
|
||||||
$self->app->log->error("work($uid)/arrival: $@");
|
$self->app->log->error("work($uid)/arrival: $@");
|
||||||
|
$errors += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
eval { }
|
eval { }
|
||||||
|
|
|
@ -622,17 +622,26 @@ sub travel_action {
|
||||||
if ( $params->{action} eq 'checkin' ) {
|
if ( $params->{action} eq 'checkin' ) {
|
||||||
|
|
||||||
my $status = $self->get_user_status;
|
my $status = $self->get_user_status;
|
||||||
|
my $promise;
|
||||||
|
|
||||||
if ( $status->{checked_in}
|
if ( $status->{checked_in}
|
||||||
and $status->{arr_eva}
|
and $status->{arr_eva}
|
||||||
and $status->{arrival_countdown} <= 0 )
|
and $status->{arrival_countdown} <= 0 )
|
||||||
{
|
{
|
||||||
$self->checkout( station => $status->{arr_eva} );
|
$promise = $self->checkout_p( station => $status->{arr_eva} );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$promise = Mojo::Promise->resolve;
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->render_later;
|
$self->render_later;
|
||||||
$self->checkin_p(
|
$promise->then(
|
||||||
station => $params->{station},
|
sub {
|
||||||
train_id => $params->{train}
|
return $self->checkin_p(
|
||||||
|
station => $params->{station},
|
||||||
|
train_id => $params->{train}
|
||||||
|
);
|
||||||
|
}
|
||||||
)->then(
|
)->then(
|
||||||
sub {
|
sub {
|
||||||
my $destination = $params->{dest};
|
my $destination = $params->{dest};
|
||||||
|
@ -648,17 +657,26 @@ sub travel_action {
|
||||||
|
|
||||||
# Silently ignore errors -- if they are permanent, the user will see
|
# Silently ignore errors -- if they are permanent, the user will see
|
||||||
# them when selecting the destination manually.
|
# them when selecting the destination manually.
|
||||||
my ( $still_checked_in, undef ) = $self->checkout(
|
return $self->checkout_p(
|
||||||
station => $destination,
|
station => $destination,
|
||||||
force => 0
|
force => 0
|
||||||
);
|
);
|
||||||
my $station_link = '/s/' . $destination;
|
}
|
||||||
$self->render(
|
)->then(
|
||||||
json => {
|
sub {
|
||||||
success => 1,
|
my ( $still_checked_in, undef ) = @_;
|
||||||
redirect_to => $still_checked_in ? '/' : $station_link,
|
if ( my $destination = $params->{dest} ) {
|
||||||
},
|
my $station_link = '/s/' . $destination;
|
||||||
);
|
$self->render(
|
||||||
|
json => {
|
||||||
|
success => 1,
|
||||||
|
redirect_to => $still_checked_in
|
||||||
|
? '/'
|
||||||
|
: $station_link,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
)->catch(
|
)->catch(
|
||||||
sub {
|
sub {
|
||||||
|
@ -673,28 +691,47 @@ sub travel_action {
|
||||||
)->wait;
|
)->wait;
|
||||||
}
|
}
|
||||||
elsif ( $params->{action} eq 'checkout' ) {
|
elsif ( $params->{action} eq 'checkout' ) {
|
||||||
my ( $still_checked_in, $error ) = $self->checkout(
|
$self->render_later;
|
||||||
|
$self->checkout_p(
|
||||||
station => $params->{station},
|
station => $params->{station},
|
||||||
force => $params->{force}
|
force => $params->{force}
|
||||||
);
|
)->then(
|
||||||
my $station_link = '/s/' . $params->{station};
|
sub {
|
||||||
|
my ( $still_checked_in, $error ) = @_;
|
||||||
|
my $station_link = '/s/' . $params->{station};
|
||||||
|
|
||||||
if ($error) {
|
if ($error) {
|
||||||
$self->render(
|
$self->render(
|
||||||
json => {
|
json => {
|
||||||
success => 0,
|
success => 0,
|
||||||
error => $error,
|
error => $error,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$self->render(
|
$self->render(
|
||||||
json => {
|
json => {
|
||||||
success => 1,
|
success => 1,
|
||||||
redirect_to => $still_checked_in ? '/' : $station_link,
|
redirect_to => $still_checked_in
|
||||||
},
|
? '/'
|
||||||
);
|
: $station_link,
|
||||||
}
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
)->catch(
|
||||||
|
sub {
|
||||||
|
my ($error) = @_;
|
||||||
|
$self->render(
|
||||||
|
json => {
|
||||||
|
success => 0,
|
||||||
|
error => $error,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
)->wait;
|
||||||
}
|
}
|
||||||
elsif ( $params->{action} eq 'undo' ) {
|
elsif ( $params->{action} eq 'undo' ) {
|
||||||
my $status = $self->get_user_status;
|
my $status = $self->get_user_status;
|
||||||
|
@ -747,27 +784,43 @@ sub travel_action {
|
||||||
)->wait;
|
)->wait;
|
||||||
}
|
}
|
||||||
elsif ( $params->{action} eq 'cancelled_to' ) {
|
elsif ( $params->{action} eq 'cancelled_to' ) {
|
||||||
my ( undef, $error ) = $self->checkout(
|
$self->render_later;
|
||||||
|
$self->checkout_p(
|
||||||
station => $params->{station},
|
station => $params->{station},
|
||||||
force => 1
|
force => 1
|
||||||
);
|
)->then(
|
||||||
|
sub {
|
||||||
if ($error) {
|
my ( undef, $error ) = @_;
|
||||||
$self->render(
|
if ($error) {
|
||||||
json => {
|
$self->render(
|
||||||
success => 0,
|
json => {
|
||||||
error => $error,
|
success => 0,
|
||||||
},
|
error => $error,
|
||||||
);
|
},
|
||||||
}
|
);
|
||||||
else {
|
}
|
||||||
$self->render(
|
else {
|
||||||
json => {
|
$self->render(
|
||||||
success => 1,
|
json => {
|
||||||
redirect_to => '/',
|
success => 1,
|
||||||
},
|
redirect_to => '/',
|
||||||
);
|
},
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
)->catch(
|
||||||
|
sub {
|
||||||
|
my ($error) = @_;
|
||||||
|
$self->render(
|
||||||
|
json => {
|
||||||
|
success => 0,
|
||||||
|
error => $error,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
)->wait;
|
||||||
}
|
}
|
||||||
elsif ( $params->{action} eq 'delete' ) {
|
elsif ( $params->{action} eq 'delete' ) {
|
||||||
my $error = $self->journeys->delete(
|
my $error = $self->journeys->delete(
|
||||||
|
|
Loading…
Reference in a new issue