Loading lib/Travelynx.pm +191 −136 Original line number Diff line number Diff line Loading @@ -414,68 +414,87 @@ sub startup { ); $self->helper( 'checkin' => sub { 'checkin_p' => sub { my ( $self, %opt ) = @_; my $station = $opt{station}; my $train_id = $opt{train_id}; my $uid = $opt{uid} // $self->current_user->{id}; my $db = $opt{db} // $self->pg->db; my $hafas; my $status = $self->iris->get_departures( station => $station, lookbehind => 140, lookahead => 40 ); if ( $status->{errstr} ) { return ( undef, $status->{errstr} ); if ( $train_id =~ m{[|]} ) { $hafas = 1; } my ($train) = List::Util::first { $_->train_id eq $train_id } @{ $status->{results} }; if ( not defined $train ) { return ( undef, "Train ${train_id} not found" ); if ($hafas) { return Mojo::Promise->reject( 'HAFAS checkins are not supported yet, sorry'); } my $user = $self->get_user_status( $uid, $db ); if ( $user->{checked_in} or $user->{cancelled} ) { if ( $user->{train_id} eq $train_id and $user->{dep_eva} eq $status->{station_eva} ) { # checking in twice is harmless return ( $train, undef ); return Mojo::Promise->reject('You are already checked in'); } # Otherwise, someone forgot to check out first $self->checkout( my $promise = Mojo::Promise->new; $self->iris->get_departures_p( station => $station, force => 1, uid => $uid, db => $db ); lookbehind => 140, lookahead => 40 )->then( sub { my ($status) = @_; if ( $status->{errstr} ) { $promise->reject( $status->{errstr} ); return; } my $eva = $status->{station_eva}; my $train = List::Util::first { $_->train_id eq $train_id } @{ $status->{results} }; if ( not defined $train ) { $promise->reject("Train ${train_id} not found"); return; } eval { $self->in_transit->add( uid => $uid, db => $db, departure_eva => $status->{station_eva}, departure_eva => $eva, train => $train, route => [ $self->iris->route_diff($train) ], ); }; if ($@) { $self->app->log->error("Checkin($uid): INSERT failed: $@"); return ( undef, 'INSERT failed: ' . $@ ); $self->app->log->error( "Checkin($uid): INSERT failed: $@"); $promise->reject( 'INSERT failed: ' . $@ ); return; } if ( not $opt{in_transaction} ) { # mustn't be called during a transaction if ( not $opt{in_transaction} ) { $self->add_route_timestamps( $uid, $train, 1 ); $self->run_hook( $uid, 'checkin' ); } return ( $train, undef ); $promise->resolve($train); return; } )->catch( sub { my ($status) = @_; $promise->reject( $status->{errstr} ); return; } )->wait; return $promise; } ); Loading Loading @@ -1814,17 +1833,19 @@ sub startup { ); $self->helper( 'traewelling_to_travelynx' => sub { 'traewelling_to_travelynx_p' => sub { my ( $self, %opt ) = @_; my $traewelling = $opt{traewelling}; my $user_data = $opt{user_data}; my $uid = $user_data->{user_id}; my $promise = Mojo::Promise->new; if ( not $traewelling->{checkin} or $self->now->epoch - $traewelling->{checkin}->epoch > 900 ) { $self->log->debug("... not checked in"); return; return $promise->resolve; } if ( $traewelling->{status_id} and $user_data->{data}{latest_pull_status_id} Loading @@ -1832,7 +1853,7 @@ sub startup { == $user_data->{data}{latest_pull_status_id} ) { $self->log->debug("... already handled"); return; return $promise->resolve; } $self->log->debug( "... checked in : $traewelling->{dep_name} $traewelling->{dep_eva} -> $traewelling->{arr_name} $traewelling->{arr_eva}" Loading @@ -1841,7 +1862,7 @@ sub startup { if ( $user_status->{checked_in} ) { $self->log->debug( "... also checked in via travelynx. aborting."); return; return $promise->resolve; } if ( $traewelling->{category} Loading @@ -1859,14 +1880,18 @@ sub startup { uid => $uid, status_id => $traewelling->{status_id} ); return; return $promise->resolve; } my $dep = $self->iris->get_departures( $self->iris->get_departures_p( station => $traewelling->{dep_eva}, lookbehind => 60, lookahead => 40 ); )->then( sub { my ($dep) = @_; my ( $train_ref, $train_id ); if ( $dep->{errstr} ) { $self->traewelling->log( uid => $uid, Loading @@ -1875,9 +1900,10 @@ sub startup { status_id => $traewelling->{status_id}, is_error => 1, ); $promise->resolve; return; } my ( $train_ref, $train_id ); for my $train ( @{ $dep->{results} } ) { if ( $train->line ne $traewelling->{line} ) { next; Loading @@ -1889,7 +1915,8 @@ sub startup { next; } if ( not List::Util::first { $_ eq $traewelling->{arr_name} } not List::Util::first { $_ eq $traewelling->{arr_name} } $train->route_post ) { Loading @@ -1899,30 +1926,46 @@ sub startup { $train_ref = $train; last; } if ($train_id) { if ( not $train_id ) { $self->log->debug( "... train $traewelling->{line} not found"); $self->traewelling->log( uid => $uid, message => "Konnte $traewelling->{line} nach $traewelling->{arr_name} nicht übernehmen: Zug nicht gefunden", status_id => $traewelling->{status_id}, is_error => 1 ); return $promise->resolve; } $self->log->debug("... found train: $train_id"); my $db = $self->pg->db; my $tx = $db->begin; my ( undef, $err ) = $self->checkin( $self->checkin_p( station => $traewelling->{dep_eva}, train_id => $train_id, uid => $uid, in_transaction => 1, db => $db ); if ( not $err ) { ( undef, $err ) = $self->checkout( )->then( sub { $self->log->debug("... handled origin"); my ( undef, $err ) = $self->checkout( station => $traewelling->{arr_eva}, train_id => 0, uid => $uid, in_transaction => 1, db => $db ); if ( not $err ) { $self->log->debug("... success!"); if ($err) { $self->log->debug("... error: $err"); return Mojo::Promise->reject($err); } $self->log->debug("... handled destination"); if ( $traewelling->{message} ) { $self->in_transit->update_user_data( uid => $uid, Loading @@ -1945,9 +1988,12 @@ sub startup { ); $tx->commit; $promise->resolve; return; } } if ($err) { )->catch( sub { my ($err) = @_; $self->log->debug("... error: $err"); $self->traewelling->log( uid => $uid, Loading @@ -1956,18 +2002,27 @@ sub startup { status_id => $traewelling->{status_id}, is_error => 1 ); $promise->resolve; return; } )->wait; } else { $self->log->debug("... train $traewelling->{line} not found"); )->catch( sub { my ($dep) = @_; $self->traewelling->log( uid => $uid, message => "Konnte $traewelling->{line} nach $traewelling->{arr_name} nicht übernehmen: Zug nicht gefunden", "Konnte $traewelling->{line} nach $traewelling->{arr_name} nicht übernehmen: $dep->{errstr}", status_id => $traewelling->{status_id}, is_error => 1 is_error => 1, ); $promise->resolve; return; } )->wait; return $promise; } ); Loading lib/Travelynx/Command/traewelling.pm +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ sub pull_sync { sub { my ($traewelling) = @_; $pull_result{ $traewelling->{http} } += 1; $self->app->traewelling_to_travelynx( return $self->app->traewelling_to_travelynx_p( traewelling => $traewelling, user_data => $account_data ); Loading lib/Travelynx/Controller/Api.pm +42 −32 Original line number Diff line number Diff line Loading @@ -261,43 +261,53 @@ sub travel_v1 { $train_id = $train->train_id; } my ( $train, $error ) = $self->checkin( $self->render_later; $self->checkin_p( station => $from_station, train_id => $train_id, uid => $uid ); if ( $payload->{comment} and not $error ) { )->then( sub { my ($train) = @_; if ( $payload->{comment} ) { $self->in_transit->update_user_data( uid => $uid, user_data => { comment => sanitize( q{}, $payload->{comment} ) } user_data => { comment => sanitize( q{}, $payload->{comment} ) } ); } if ( $to_station and not $error ) { ( $train, $error ) = $self->checkout( if ($to_station) { my ( $train2, $error ) = $self->checkout( station => $to_station, force => 0, uid => $uid ); } if ($error) { return Mojo::Promise->reject($error); } } $self->render( json => { success => \0, success => \1, deprecated => \0, error => 'Checkin/Checkout error: ' . $error, status => $self->get_user_status_json_v1( uid => $uid ) } ); } else { )->catch( sub { my ($error) = @_; $self->render( json => { success => \1, success => \0, deprecated => \0, error => 'Checkin/Checkout error: ' . $error, status => $self->get_user_status_json_v1( uid => $uid ) } ); } )->wait; } elsif ( $payload->{action} eq 'checkout' ) { my $to_station = sanitize( q{}, $payload->{toStation} ); Loading lib/Travelynx/Controller/Traveling.pm +61 −53 Original line number Diff line number Diff line Loading @@ -615,29 +615,23 @@ sub travel_action { if ( $params->{action} eq 'checkin' ) { my ( $train, $error ) = $self->checkin( $self->render_later; $self->checkin_p( station => $params->{station}, train_id => $params->{train} ); )->then( sub { my $destination = $params->{dest}; if ($error) { $self->render( json => { success => 0, error => $error, }, ); } elsif ( not $destination ) { if ( not $destination ) { $self->render( json => { success => 1, redirect_to => '/', }, ); return; } else { # Silently ignore errors -- if they are permanent, the user will see # them when selecting the destination manually. my ( $still_checked_in, undef ) = $self->checkout( Loading @@ -652,6 +646,17 @@ sub travel_action { }, ); } )->catch( sub { my ($error) = @_; $self->render( json => { success => 0, error => $error, }, ); } )->wait; } elsif ( $params->{action} eq 'checkout' ) { my ( $still_checked_in, $error ) = $self->checkout( Loading Loading @@ -702,27 +707,30 @@ sub travel_action { } } elsif ( $params->{action} eq 'cancelled_from' ) { my ( undef, $error ) = $self->checkin( $self->render_later; $self->checkin_p( station => $params->{station}, train_id => $params->{train} ); if ($error) { )->then( sub { $self->render( json => { success => 0, error => $error, success => 1, redirect_to => '/', }, ); } else { )->catch( sub { my ($error) = @_; $self->render( json => { success => 1, redirect_to => '/', success => 0, error => $error, }, ); } )->wait; } elsif ( $params->{action} eq 'cancelled_to' ) { my ( undef, $error ) = $self->checkout( Loading Loading
lib/Travelynx.pm +191 −136 Original line number Diff line number Diff line Loading @@ -414,68 +414,87 @@ sub startup { ); $self->helper( 'checkin' => sub { 'checkin_p' => sub { my ( $self, %opt ) = @_; my $station = $opt{station}; my $train_id = $opt{train_id}; my $uid = $opt{uid} // $self->current_user->{id}; my $db = $opt{db} // $self->pg->db; my $hafas; my $status = $self->iris->get_departures( station => $station, lookbehind => 140, lookahead => 40 ); if ( $status->{errstr} ) { return ( undef, $status->{errstr} ); if ( $train_id =~ m{[|]} ) { $hafas = 1; } my ($train) = List::Util::first { $_->train_id eq $train_id } @{ $status->{results} }; if ( not defined $train ) { return ( undef, "Train ${train_id} not found" ); if ($hafas) { return Mojo::Promise->reject( 'HAFAS checkins are not supported yet, sorry'); } my $user = $self->get_user_status( $uid, $db ); if ( $user->{checked_in} or $user->{cancelled} ) { if ( $user->{train_id} eq $train_id and $user->{dep_eva} eq $status->{station_eva} ) { # checking in twice is harmless return ( $train, undef ); return Mojo::Promise->reject('You are already checked in'); } # Otherwise, someone forgot to check out first $self->checkout( my $promise = Mojo::Promise->new; $self->iris->get_departures_p( station => $station, force => 1, uid => $uid, db => $db ); lookbehind => 140, lookahead => 40 )->then( sub { my ($status) = @_; if ( $status->{errstr} ) { $promise->reject( $status->{errstr} ); return; } my $eva = $status->{station_eva}; my $train = List::Util::first { $_->train_id eq $train_id } @{ $status->{results} }; if ( not defined $train ) { $promise->reject("Train ${train_id} not found"); return; } eval { $self->in_transit->add( uid => $uid, db => $db, departure_eva => $status->{station_eva}, departure_eva => $eva, train => $train, route => [ $self->iris->route_diff($train) ], ); }; if ($@) { $self->app->log->error("Checkin($uid): INSERT failed: $@"); return ( undef, 'INSERT failed: ' . $@ ); $self->app->log->error( "Checkin($uid): INSERT failed: $@"); $promise->reject( 'INSERT failed: ' . $@ ); return; } if ( not $opt{in_transaction} ) { # mustn't be called during a transaction if ( not $opt{in_transaction} ) { $self->add_route_timestamps( $uid, $train, 1 ); $self->run_hook( $uid, 'checkin' ); } return ( $train, undef ); $promise->resolve($train); return; } )->catch( sub { my ($status) = @_; $promise->reject( $status->{errstr} ); return; } )->wait; return $promise; } ); Loading Loading @@ -1814,17 +1833,19 @@ sub startup { ); $self->helper( 'traewelling_to_travelynx' => sub { 'traewelling_to_travelynx_p' => sub { my ( $self, %opt ) = @_; my $traewelling = $opt{traewelling}; my $user_data = $opt{user_data}; my $uid = $user_data->{user_id}; my $promise = Mojo::Promise->new; if ( not $traewelling->{checkin} or $self->now->epoch - $traewelling->{checkin}->epoch > 900 ) { $self->log->debug("... not checked in"); return; return $promise->resolve; } if ( $traewelling->{status_id} and $user_data->{data}{latest_pull_status_id} Loading @@ -1832,7 +1853,7 @@ sub startup { == $user_data->{data}{latest_pull_status_id} ) { $self->log->debug("... already handled"); return; return $promise->resolve; } $self->log->debug( "... checked in : $traewelling->{dep_name} $traewelling->{dep_eva} -> $traewelling->{arr_name} $traewelling->{arr_eva}" Loading @@ -1841,7 +1862,7 @@ sub startup { if ( $user_status->{checked_in} ) { $self->log->debug( "... also checked in via travelynx. aborting."); return; return $promise->resolve; } if ( $traewelling->{category} Loading @@ -1859,14 +1880,18 @@ sub startup { uid => $uid, status_id => $traewelling->{status_id} ); return; return $promise->resolve; } my $dep = $self->iris->get_departures( $self->iris->get_departures_p( station => $traewelling->{dep_eva}, lookbehind => 60, lookahead => 40 ); )->then( sub { my ($dep) = @_; my ( $train_ref, $train_id ); if ( $dep->{errstr} ) { $self->traewelling->log( uid => $uid, Loading @@ -1875,9 +1900,10 @@ sub startup { status_id => $traewelling->{status_id}, is_error => 1, ); $promise->resolve; return; } my ( $train_ref, $train_id ); for my $train ( @{ $dep->{results} } ) { if ( $train->line ne $traewelling->{line} ) { next; Loading @@ -1889,7 +1915,8 @@ sub startup { next; } if ( not List::Util::first { $_ eq $traewelling->{arr_name} } not List::Util::first { $_ eq $traewelling->{arr_name} } $train->route_post ) { Loading @@ -1899,30 +1926,46 @@ sub startup { $train_ref = $train; last; } if ($train_id) { if ( not $train_id ) { $self->log->debug( "... train $traewelling->{line} not found"); $self->traewelling->log( uid => $uid, message => "Konnte $traewelling->{line} nach $traewelling->{arr_name} nicht übernehmen: Zug nicht gefunden", status_id => $traewelling->{status_id}, is_error => 1 ); return $promise->resolve; } $self->log->debug("... found train: $train_id"); my $db = $self->pg->db; my $tx = $db->begin; my ( undef, $err ) = $self->checkin( $self->checkin_p( station => $traewelling->{dep_eva}, train_id => $train_id, uid => $uid, in_transaction => 1, db => $db ); if ( not $err ) { ( undef, $err ) = $self->checkout( )->then( sub { $self->log->debug("... handled origin"); my ( undef, $err ) = $self->checkout( station => $traewelling->{arr_eva}, train_id => 0, uid => $uid, in_transaction => 1, db => $db ); if ( not $err ) { $self->log->debug("... success!"); if ($err) { $self->log->debug("... error: $err"); return Mojo::Promise->reject($err); } $self->log->debug("... handled destination"); if ( $traewelling->{message} ) { $self->in_transit->update_user_data( uid => $uid, Loading @@ -1945,9 +1988,12 @@ sub startup { ); $tx->commit; $promise->resolve; return; } } if ($err) { )->catch( sub { my ($err) = @_; $self->log->debug("... error: $err"); $self->traewelling->log( uid => $uid, Loading @@ -1956,18 +2002,27 @@ sub startup { status_id => $traewelling->{status_id}, is_error => 1 ); $promise->resolve; return; } )->wait; } else { $self->log->debug("... train $traewelling->{line} not found"); )->catch( sub { my ($dep) = @_; $self->traewelling->log( uid => $uid, message => "Konnte $traewelling->{line} nach $traewelling->{arr_name} nicht übernehmen: Zug nicht gefunden", "Konnte $traewelling->{line} nach $traewelling->{arr_name} nicht übernehmen: $dep->{errstr}", status_id => $traewelling->{status_id}, is_error => 1 is_error => 1, ); $promise->resolve; return; } )->wait; return $promise; } ); Loading
lib/Travelynx/Command/traewelling.pm +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ sub pull_sync { sub { my ($traewelling) = @_; $pull_result{ $traewelling->{http} } += 1; $self->app->traewelling_to_travelynx( return $self->app->traewelling_to_travelynx_p( traewelling => $traewelling, user_data => $account_data ); Loading
lib/Travelynx/Controller/Api.pm +42 −32 Original line number Diff line number Diff line Loading @@ -261,43 +261,53 @@ sub travel_v1 { $train_id = $train->train_id; } my ( $train, $error ) = $self->checkin( $self->render_later; $self->checkin_p( station => $from_station, train_id => $train_id, uid => $uid ); if ( $payload->{comment} and not $error ) { )->then( sub { my ($train) = @_; if ( $payload->{comment} ) { $self->in_transit->update_user_data( uid => $uid, user_data => { comment => sanitize( q{}, $payload->{comment} ) } user_data => { comment => sanitize( q{}, $payload->{comment} ) } ); } if ( $to_station and not $error ) { ( $train, $error ) = $self->checkout( if ($to_station) { my ( $train2, $error ) = $self->checkout( station => $to_station, force => 0, uid => $uid ); } if ($error) { return Mojo::Promise->reject($error); } } $self->render( json => { success => \0, success => \1, deprecated => \0, error => 'Checkin/Checkout error: ' . $error, status => $self->get_user_status_json_v1( uid => $uid ) } ); } else { )->catch( sub { my ($error) = @_; $self->render( json => { success => \1, success => \0, deprecated => \0, error => 'Checkin/Checkout error: ' . $error, status => $self->get_user_status_json_v1( uid => $uid ) } ); } )->wait; } elsif ( $payload->{action} eq 'checkout' ) { my $to_station = sanitize( q{}, $payload->{toStation} ); Loading
lib/Travelynx/Controller/Traveling.pm +61 −53 Original line number Diff line number Diff line Loading @@ -615,29 +615,23 @@ sub travel_action { if ( $params->{action} eq 'checkin' ) { my ( $train, $error ) = $self->checkin( $self->render_later; $self->checkin_p( station => $params->{station}, train_id => $params->{train} ); )->then( sub { my $destination = $params->{dest}; if ($error) { $self->render( json => { success => 0, error => $error, }, ); } elsif ( not $destination ) { if ( not $destination ) { $self->render( json => { success => 1, redirect_to => '/', }, ); return; } else { # Silently ignore errors -- if they are permanent, the user will see # them when selecting the destination manually. my ( $still_checked_in, undef ) = $self->checkout( Loading @@ -652,6 +646,17 @@ sub travel_action { }, ); } )->catch( sub { my ($error) = @_; $self->render( json => { success => 0, error => $error, }, ); } )->wait; } elsif ( $params->{action} eq 'checkout' ) { my ( $still_checked_in, $error ) = $self->checkout( Loading Loading @@ -702,27 +707,30 @@ sub travel_action { } } elsif ( $params->{action} eq 'cancelled_from' ) { my ( undef, $error ) = $self->checkin( $self->render_later; $self->checkin_p( station => $params->{station}, train_id => $params->{train} ); if ($error) { )->then( sub { $self->render( json => { success => 0, error => $error, success => 1, redirect_to => '/', }, ); } else { )->catch( sub { my ($error) = @_; $self->render( json => { success => 1, redirect_to => '/', success => 0, error => $error, }, ); } )->wait; } elsif ( $params->{action} eq 'cancelled_to' ) { my ( undef, $error ) = $self->checkout( Loading