From 07e0f8970681422a48fec9da5d14ad2a2b3735bd Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Thu, 1 Oct 2020 19:36:35 +0200 Subject: allow checking into traewelling --- lib/Travelynx/Command/work.pm | 20 +++++++ lib/Travelynx/Helper/Traewelling.pm | 116 +++++++++++++++++++----------------- lib/Travelynx/Model/Traewelling.pm | 32 ++++++---- 3 files changed, 103 insertions(+), 65 deletions(-) (limited to 'lib/Travelynx') diff --git a/lib/Travelynx/Command/work.pm b/lib/Travelynx/Command/work.pm index 593735f..5a79b10 100644 --- a/lib/Travelynx/Command/work.pm +++ b/lib/Travelynx/Command/work.pm @@ -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. diff --git a/lib/Travelynx/Helper/Traewelling.pm b/lib/Travelynx/Helper/Traewelling.pm index 3c7bec2..d2ffadc 100644 --- a/lib/Travelynx/Helper/Traewelling.pm +++ b/lib/Travelynx/Helper/Traewelling.pm @@ -267,66 +267,72 @@ 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} ) - { + my ( $self, %opt ) = @_; + + my $header = { + 'User-Agent' => $self->{header}{'User-Agent'}, + 'Authorization' => "Bearer $opt{token}", + }; + + my $request = { + 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", + $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( + sub { + return $self->{user_agent}->request_timeout(20) + ->post_p( "https://traewelling.de/api/v0/trains/checkin" => + $header => json => $request ); + } + )->then( + sub { + my ($tx) = @_; + if ( my $err = $tx->error ) { + my $err_msg = "HTTP $err->{code} $err->{message}"; + $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; } - my $header = { - 'User-Agent' => 'travelynx/' . $self->{version}, - 'Authorization' => "Bearer $token", - }; - - my $request = { - tripID => $user->{extra_data}{trip_id}, - start => q{} . $user->{dep_eva}, - destination => q{} . $user->{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} + $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} ); - $self->{user_agent}->request_timeout(20) - ->get_p( - "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" => - $header => json => $request ); - } - )->then( - sub { - my ($tx) = @_; - if ( my $err = $tx->error ) { - my $err_msg = "HTTP $err->{code} $err->{message}"; - $self->mark_trwl_checkin_error( $uid, $user, $err_msg ); - } - 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 ); - # mark success: checked into (trip_id, start, destination) - } - } - )->catch( - sub { - my ($err) = @_; - $self->mark_trwl_checkin_error( $uid, $user, $err ); - } - )->wait; + # TODO store status_id in in_transit object so that it can be shown + # on the user status page } - } + )->catch( + sub { + my ($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; diff --git a/lib/Travelynx/Model/Traewelling.pm b/lib/Travelynx/Model/Traewelling.pm index 7f08b0d..eb7201f 100644 --- a/lib/Travelynx/Model/Traewelling.pm +++ b/lib/Travelynx/Model/Traewelling.pm @@ -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 $db = $opt{db} // $self->{pg}->db; + my $uid = $opt{uid}; + 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; } -- cgit v1.2.3