summaryrefslogtreecommitdiff
path: root/lib/Travelynx/Helper/Traewelling.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Travelynx/Helper/Traewelling.pm')
-rw-r--r--lib/Travelynx/Helper/Traewelling.pm235
1 files changed, 109 insertions, 126 deletions
diff --git a/lib/Travelynx/Helper/Traewelling.pm b/lib/Travelynx/Helper/Traewelling.pm
index 88b91a0..d688004 100644
--- a/lib/Travelynx/Helper/Traewelling.pm
+++ b/lib/Travelynx/Helper/Traewelling.pm
@@ -1,12 +1,14 @@
package Travelynx::Helper::Traewelling;
-# Copyright (C) 2020 Daniel Friesel
+# Copyright (C) 2020-2023 Birte Kristina Friesel
+# Copyright (C) 2023 networkException <git@nwex.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
use strict;
use warnings;
use 5.020;
+use utf8;
use DateTime;
use DateTime::Format::Strptime;
@@ -74,54 +76,61 @@ sub get_status_p {
};
$self->{user_agent}->request_timeout(20)
- ->get_p( "https://traewelling.de/api/v0/user/${username}" => $header )
- ->then(
+ ->get_p(
+ "https://traewelling.de/api/v1/user/${username}/statuses?limit=1" =>
+ $header )->then(
sub {
my ($tx) = @_;
if ( my $err = $tx->error ) {
- my $err_msg = "HTTP $err->{code} $err->{message}";
- $promise->reject($err_msg);
+ my $err_msg
+ = "v1/user/${username}/statuses: HTTP $err->{code} $err->{message}";
+ $promise->reject( { http => $err->{code}, text => $err_msg } );
return;
}
else {
- if ( my $status = $tx->result->json->{statuses}{data}[0] ) {
+ if ( my $status = $tx->result->json->{data}[0] ) {
my $status_id = $status->{id};
my $message = $status->{body};
my $checkin_at
- = $self->parse_datetime( $status->{created_at} );
+ = $self->parse_datetime( $status->{createdAt} );
my $dep_dt = $self->parse_datetime(
- $status->{train_checkin}{departure} );
+ $status->{train}{origin}{departurePlanned} );
my $arr_dt = $self->parse_datetime(
- $status->{train_checkin}{arrival} );
+ $status->{train}{destination}{arrivalPlanned} );
my $dep_eva
- = $status->{train_checkin}{origin}{ibnr};
+ = $status->{train}{origin}{evaIdentifier};
my $arr_eva
- = $status->{train_checkin}{destination}{ibnr};
+ = $status->{train}{destination}{evaIdentifier};
+
+ my $dep_ds100
+ = $status->{train}{origin}{rilIdentifier};
+ my $arr_ds100
+ = $status->{train}{destination}{rilIdentifier};
my $dep_name
- = $status->{train_checkin}{origin}{name};
+ = $status->{train}{origin}{name};
my $arr_name
- = $status->{train_checkin}{destination}{name};
-
- my $category
- = $status->{train_checkin}{hafas_trip}{category};
- my $trip_id
- = $status->{train_checkin}{hafas_trip}{trip_id};
- my $linename
- = $status->{train_checkin}{hafas_trip}{linename};
+ = $status->{train}{destination}{name};
+
+ my $category = $status->{train}{category};
+ my $linename = $status->{train}{lineName};
+ my $trip_id = $status->{train}{hafasId};
my ( $train_type, $train_line ) = split( qr{ }, $linename );
$promise->resolve(
{
+ http => $tx->res->code,
status_id => $status_id,
message => $message,
checkin => $checkin_at,
dep_dt => $dep_dt,
dep_eva => $dep_eva,
+ dep_ds100 => $dep_ds100,
dep_name => $dep_name,
arr_dt => $arr_dt,
arr_eva => $arr_eva,
+ arr_ds100 => $arr_ds100,
arr_name => $arr_name,
trip_id => $trip_id,
train_type => $train_type,
@@ -133,7 +142,8 @@ sub get_status_p {
return;
}
else {
- $promise->reject("unknown error");
+ $promise->reject(
+ { text => "v1/${username}/statuses: unknown error" } );
return;
}
}
@@ -141,7 +151,7 @@ sub get_status_p {
)->catch(
sub {
my ($err) = @_;
- $promise->reject($err);
+ $promise->reject( { text => "v1/${username}/statuses: $err" } );
return;
}
)->wait;
@@ -160,21 +170,20 @@ sub get_user_p {
};
my $promise = Mojo::Promise->new;
- $ua->get_p( "https://traewelling.de/api/v0/getuser" => $header )->then(
+ $ua->get_p( "https://traewelling.de/api/v1/auth/user" => $header )->then(
sub {
my ($tx) = @_;
if ( my $err = $tx->error ) {
- my $err_msg
- = "HTTP $err->{code} $err->{message} bei Abfrage der Nutzerdaten";
+ my $err_msg = "v1/auth/user: HTTP $err->{code} $err->{message}";
$promise->reject($err_msg);
return;
}
else {
- my $user_data = $tx->result->json;
+ my $user_data = $tx->result->json->{data};
$self->{model}->set_user(
uid => $uid,
trwl_id => $user_data->{id},
- screen_name => $user_data->{name},
+ screen_name => $user_data->{displayName},
user_name => $user_data->{username},
);
$promise->resolve;
@@ -184,84 +193,7 @@ sub get_user_p {
)->catch(
sub {
my ($err) = @_;
- $promise->reject("$err bei Abfrage der Nutzerdaten");
- return;
- }
- )->wait;
-
- return $promise;
-}
-
-sub login_p {
- my ( $self, %opt ) = @_;
-
- my $uid = $opt{uid};
- my $email = $opt{email};
- my $password = $opt{password};
-
- my $ua = $self->{user_agent}->request_timeout(20);
-
- my $request = {
- email => $email,
- password => $password,
- };
-
- my $promise = Mojo::Promise->new;
- my $token;
-
- $ua->post_p(
- "https://traewelling.de/api/v0/auth/login" => $self->{header},
- json => $request
- )->then(
- sub {
- my ($tx) = @_;
- if ( my $err = $tx->error ) {
- my $err_msg = "HTTP $err->{code} $err->{message} bei Login";
- $promise->reject($err_msg);
- return;
- }
- else {
- my $res = $tx->result->json;
- $token = $res->{token};
- my $expiry_dt = $self->parse_datetime( $res->{expires_at} );
-
- # Fall back to one year expiry
- $expiry_dt //= DateTime->now( time_zone => 'Europe/Berlin' )
- ->add( years => 1 );
- $self->{model}->link(
- uid => $uid,
- email => $email,
- token => $token,
- expires => $expiry_dt
- );
- return $self->get_user_p( $uid, $token );
- }
- }
- )->then(
- sub {
- $promise->resolve;
- return;
- }
- )->catch(
- sub {
- my ($err) = @_;
- if ($token) {
-
- # We have a token, but couldn't complete the login. For now, we
- # solve this by logging out and invalidating the token.
- $self->logout_p(
- uid => $uid,
- token => $token
- )->finally(
- sub {
- $promise->reject($err);
- return;
- }
- );
- }
- else {
- $promise->reject($err);
- }
+ $promise->reject("v1/auth/user: $err");
return;
}
)->wait;
@@ -289,12 +221,13 @@ sub logout_p {
my $promise = Mojo::Promise->new;
$ua->post_p(
- "https://traewelling.de/api/v0/auth/logout" => $header => json =>
+ "https://traewelling.de/api/v1/auth/logout" => $header => json =>
$request )->then(
sub {
my ($tx) = @_;
if ( my $err = $tx->error ) {
- my $err_msg = "HTTP $err->{code} $err->{message}";
+ my $err_msg
+ = "v1/auth/logout: HTTP $err->{code} $err->{message}";
$promise->reject($err_msg);
return;
}
@@ -306,7 +239,7 @@ sub logout_p {
)->catch(
sub {
my ($err) = @_;
- $promise->reject($err);
+ $promise->reject("v1/auth/logout: $err");
return;
}
)->wait;
@@ -314,7 +247,34 @@ sub logout_p {
return $promise;
}
-sub checkin {
+sub convert_travelynx_to_traewelling_visibility {
+ my ($travelynx_visibility) = @_;
+
+ my %visibilities = (
+
+ # public => StatusVisibility::PUBLIC
+ 100 => 0,
+
+ # travelynx => StatusVisibility::AUTHENTICATED
+ # (only visible for logged in users)
+ 80 => 4,
+
+ # followers => StatusVisibility::FOLLOWERS
+ 60 => 2,
+
+ # unlisted => StatusVisibility::PRIVATE
+ # (there is no träwelling equivalent to unlisted, their
+ # StatusVisibility::UNLISTED shows the journey on the profile)
+ 30 => 3,
+
+ # private => StatusVisibility::PRIVATE
+ 10 => 3,
+ );
+
+ return $visibilities{$travelynx_visibility};
+}
+
+sub checkin_p {
my ( $self, %opt ) = @_;
my $header = {
@@ -334,47 +294,63 @@ sub checkin {
}
my $request = {
- tripID => $opt{trip_id},
+ tripId => $opt{trip_id},
lineName => $opt{train_type} . ' '
. ( $opt{train_line} // $opt{train_no} ),
+ ibnr => \1,
start => q{} . $opt{dep_eva},
destination => q{} . $opt{arr_eva},
departure => $departure_ts,
arrival => $arrival_ts,
- toot => $opt{data}{toot} ? \1 : \0,
+ toot => $opt{data}{toot} ? \1 : \0,
tweet => $opt{data}{tweet} ? \1 : \0,
+ visibility =>
+ convert_travelynx_to_traewelling_visibility( $opt{visibility} )
};
if ( $opt{user_data}{comment} ) {
$request->{body} = $opt{user_data}{comment};
}
+ my $debug_prefix
+ = "v1/trains/checkin('$request->{lineName}' $request->{tripId} $request->{start} -> $request->{destination})";
+
+ my $promise = Mojo::Promise->new;
+
$self->{user_agent}->request_timeout(20)
- ->post_p( "https://traewelling.de/api/v0/trains/checkin" =>
- $header => json => $request )->then(
+ ->post_p(
+ "https://traewelling.de/api/v1/trains/checkin" => $header => json =>
+ $request )->then(
sub {
my ($tx) = @_;
if ( my $err = $tx->error ) {
my $err_msg = "HTTP $err->{code} $err->{message}";
- if ( $err->{code} != 409 and $err->{code} != 406 ) {
- $self->{log}->warn("Traewelling checkin error: $err_msg");
- }
- else {
- $self->{log}->debug("Traewelling checkin error: $err_msg");
+ if ( $tx->res->body ) {
+ if ( $err->{code} == 409 ) {
+ my $j = $tx->res->json;
+ $err_msg .= sprintf(
+': Bereits in %s eingecheckt: https://traewelling.de/status/%d',
+ $j->{message}{lineName},
+ $j->{message}{status_id}
+ );
+ }
+ else {
+ $err_msg .= ' ' . $tx->res->body;
+ }
}
+ $self->{log}
+ ->debug("Traewelling $debug_prefix error: $err_msg");
$self->{model}->log(
- uid => $opt{uid},
+ uid => $opt{uid},
message =>
- "Fehler bei $opt{train_type} $opt{train_no}: $err_msg",
+"Konnte $opt{train_type} $opt{train_no} nicht übertragen: $debug_prefix returned $err_msg",
is_error => 1
);
+ $promise->reject( { http => $err->{code} } );
return;
}
$self->{log}->debug( "... success! " . $tx->res->body );
- # As of 2020-10-04, traewelling.de checkins do not yet return
- # "statusId". The patch is present on the develop branch and waiting
- # for a merge into master.
$self->{model}->log(
uid => $opt{uid},
message => "Eingecheckt in $opt{train_type} $opt{train_no}",
@@ -384,21 +360,28 @@ sub checkin {
uid => $opt{uid},
ts => $opt{checkin_ts}
);
+ $promise->resolve( { http => $tx->res->code } );
# TODO store status_id in in_transit object so that it can be shown
# on the user status page
+ return;
}
)->catch(
sub {
my ($err) = @_;
- $self->{log}->debug("... error: $err");
+ $self->{log}->debug("... $debug_prefix error: $err");
$self->{model}->log(
- uid => $opt{uid},
- message => "Fehler bei $opt{train_type} $opt{train_no}: $err",
+ uid => $opt{uid},
+ message =>
+"Konnte $opt{train_type} $opt{train_no} nicht übertragen: $debug_prefix returned $err",
is_error => 1
);
+ $promise->reject( { connection => $err } );
+ return;
}
)->wait;
+
+ return $promise;
}
1;