Commit 07e0f897 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

allow checking into traewelling

parent 590d3de5
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -259,6 +259,26 @@ sub run {
		)->wait;
	}

	for my $candidate ( $self->app->traewelling->get_pushable_accounts ) {
		$self->app->log->debug(
			"Pushing to Traewelling for UID $candidate->{uid}");
		my $trip_id = $candidate->{journey_data}{trip_id};
		if ( not $trip_id ) {
			$self->app->log->debug("... trip_id is missing");

			# TODO log traewelling error
			return;
		}
		if (    $candidate->{data}{latest_push_ts}
			and $candidate->{data}{latest_push_ts} == $candidate->{checkin_ts} )
		{
			$self->app->log->debug("... already handled");
			return;
		}
		$self->app->traewelling_api->checkin( %{$candidate},
			trip_id => $trip_id );
	}

	# Computing yearly stats may take a while, but we've got all time in the
	# world here. This means users won't have to wait when loading their
	# own by-year journey log.
+61 −55
Original line number Diff line number Diff line
@@ -267,41 +267,31 @@ sub logout_p {
}

sub checkin {
	my ( $self, $uid ) = @_;
	if ( my $token = $self->get_traewelling_push_token($uid) ) {
		my $user = $self->get_user_status;

# TODO delete previous traewelling status if the train's destination has been changed
# TODO delete traewelling status when undoing a travelynx checkin
		if ( $user->{checked_in} and $user->{extra_data}{trip_id} ) {
			my $traewelling = $self->{model}->get($uid);
			if ( $traewelling->{data}{trip_id} eq $user->{extra_data}{trip_id} )
			{
				return;
			}
	my ( $self, %opt ) = @_;

	my $header = {
				'User-Agent'    => 'travelynx/' . $self->{version},
				'Authorization' => "Bearer $token",
		'User-Agent'    => $self->{header}{'User-Agent'},
		'Authorization' => "Bearer $opt{token}",
	};

	my $request = {
				tripID      => $user->{extra_data}{trip_id},
				start       => q{} . $user->{dep_eva},
				destination => q{} . $user->{arr_eva},
		tripID      => $opt{trip_id},
		start       => q{} . $opt{dep_eva},
		destination => q{} . $opt{arr_eva},
	};
	my $trip_req = sprintf(
		"tripID=%s&lineName=%s%%20%s&start=%s",
				$user->{extra_data}{trip_id}, $user->{train_type},
				$user->{train_line} // $user->{train_no}, $user->{dep_eva}
		$opt{trip_id}, $opt{train_type}, $opt{train_line} // $opt{train_no},
		$opt{dep_eva}
	);

	$self->{user_agent}->request_timeout(20)
	  ->get_p(
				"https://traewelling.de/api/v0/trains/trip?$trip_req" =>
				  $header )->then(
		"https://traewelling.de/api/v0/trains/trip?$trip_req" => $header )
	  ->then(
		sub {
			return $self->{user_agent}->request_timeout(20)
					  ->post_p(
						"https://traewelling.de/api/v0/trains/checkin" =>
			  ->post_p( "https://traewelling.de/api/v0/trains/checkin" =>
				  $header => json => $request );
		}
	)->then(
@@ -309,24 +299,40 @@ sub checkin {
			my ($tx) = @_;
			if ( my $err = $tx->error ) {
				my $err_msg = "HTTP $err->{code} $err->{message}";
						$self->mark_trwl_checkin_error( $uid, $user, $err_msg );
				$self->{log}->debug("... error: $err_msg");
				$self->{model}->log(
					uid => $opt{uid},
					message =>
					  "Fehler bei $opt{train_type} $opt{train_no}: $err_msg",
					is_error => 1
				);
				return;
			}
					else {
  # TODO check for traewelling error ("error" key in response)
  # TODO store ID of resulting status (request /user/{name} and store status ID)
						$self->mark_trwl_checkin_success( $uid, $user );
			$self->{log}->debug("... success!");
			$self->{model}->log(
				uid       => $opt{uid},
				message   => "Eingecheckt in $opt{train_type} $opt{train_no}",
				status_id => $tx->res->json->{statusId}
			);
			$self->{model}->set_latest_push_ts(
				uid => $opt{uid},
				ts  => $opt{checkin_ts}
			);

                      # mark success: checked into (trip_id, start, destination)
					}
			# TODO store status_id in in_transit object so that it can be shown
			# on the user status page
		}
	)->catch(
		sub {
			my ($err) = @_;
					$self->mark_trwl_checkin_error( $uid, $user, $err );
			$self->{log}->debug("... error: $err");
			$self->{model}->log(
				uid      => $opt{uid},
				message  => "Fehler bei $opt{train_type} $opt{train_no}: $err",
				is_error => 1
			);
		}
	)->wait;
}
	}
}

1;
+22 −10
Original line number Diff line number Diff line
@@ -146,16 +146,16 @@ sub set_latest_pull_status_id {
	);
}

sub set_latest_push_status_id {
sub set_latest_push_ts {
	my ( $self, %opt ) = @_;
	my $uid = $opt{uid};
	my $status_id = $opt{status_id};
	my $ts  = $opt{ts};
	my $db  = $opt{db} // $self->{pg}->db;

	my $res_h
	  = $db->select( 'traewelling', 'data', { user_id => $uid } )->expand->hash;

	$res_h->{data}{latest_push_status_id} = $status_id;
	$res_h->{data}{latest_push_ts} = $ts;

	$db->update(
		'traewelling',
@@ -181,12 +181,24 @@ sub set_sync {
	);
}

sub get_push_accounts {
sub get_pushable_accounts {
	my ($self) = @_;
	my $res = $self->{pg}->db->select(
		'traewelling',
		[ 'user_id', 'token', 'data' ],
		{ push_sync => 1 }
	my $now    = $self->now->epoch;
	my $res    = $self->{pg}->db->query(
		qq{select t.user_id as uid, t.token as token, t.data as data,
			i.checkin_station_id as dep_eva, i.checkout_station_id as arr_eva,
			i.data as journey_data, i.train_type as train_type,
			i.train_line as train_line, i.train_no as train_no,
			extract(epoch from i.checkin_time) as checkin_ts
			from traewelling as t
			join in_transit as i on t.user_id = i.user_id
			where t.push_sync = True
			and i.checkout_station_id is not null
			and i.cancelled = False
			and (extract(epoch from i.sched_departure) > ?
				or extract(epoch from i.real_departure) > ?)
			and extract(epoch from i.sched_departure) < ?
		}, $now - 300, $now - 300, $now + 600
	);
	return $res->expand->hashes->each;
}
+1 −1
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@
			<div class="input-field col s12">
				<div>
					<label>
						%= radio_button sync_source => 'travelynx', disabled => undef
						%= radio_button sync_source => 'travelynx'
						<span>Checkin-Synchronisierung travelynx → Träwelling</span>
					</label>
				</div>