Unverified Commit 1074f248 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

use promises for checkin and traewelling_to_travelynx

parent f7e3bb49
Loading
Loading
Loading
Loading
+191 −136
Original line number Diff line number Diff line
@@ -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;
		}
	);

@@ -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}
@@ -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}"
@@ -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}
@@ -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,
@@ -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;
@@ -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
						  )
						{
@@ -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,
@@ -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,
@@ -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;
		}
	);

+1 −1
Original line number Diff line number Diff line
@@ -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
				);
+42 −32
Original line number Diff line number Diff line
@@ -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} );
+61 −53
Original line number Diff line number Diff line
@@ -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(
@@ -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(
@@ -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(