summaryrefslogtreecommitdiff
path: root/lib/Travelynx/Helper
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Travelynx/Helper')
-rw-r--r--lib/Travelynx/Helper/DBDB.pm21
-rw-r--r--lib/Travelynx/Helper/DBRIS.pm147
-rw-r--r--lib/Travelynx/Helper/HAFAS.pm104
-rw-r--r--lib/Travelynx/Helper/MOTIS.pm158
-rw-r--r--lib/Travelynx/Helper/Traewelling.pm18
5 files changed, 378 insertions, 70 deletions
diff --git a/lib/Travelynx/Helper/DBDB.pm b/lib/Travelynx/Helper/DBDB.pm
index 79e9c0b..a310aa3 100644
--- a/lib/Travelynx/Helper/DBDB.pm
+++ b/lib/Travelynx/Helper/DBDB.pm
@@ -61,7 +61,8 @@ sub has_wagonorder_p {
}
}
- $self->{user_agent}->request_timeout(5)->get_p( $url => $self->{header} )
+ $self->{user_agent}->request_timeout(5)
+ ->get_p( $url => $self->{header} )
->then(
sub {
my ($tx) = @_;
@@ -81,7 +82,7 @@ sub has_wagonorder_p {
}
return;
}
- )->catch(
+ )->catch(
sub {
my ($err) = @_;
$self->{log}->debug("${debug_prefix}: n ($err)");
@@ -89,7 +90,7 @@ sub has_wagonorder_p {
$promise->reject;
return;
}
- )->wait;
+ )->wait;
return $promise;
}
@@ -120,7 +121,8 @@ sub get_wagonorder_p {
return $promise;
}
- $self->{user_agent}->request_timeout(5)->get_p( $url => $self->{header} )
+ $self->{user_agent}->request_timeout(5)
+ ->get_p( $url => $self->{header} )
->then(
sub {
my ($tx) = @_;
@@ -139,14 +141,14 @@ sub get_wagonorder_p {
}
return;
}
- )->catch(
+ )->catch(
sub {
my ($err) = @_;
$self->{log}->debug("${debug_prefix}: error ${err}");
$promise->reject($err);
return;
}
- )->wait;
+ )->wait;
return $promise;
}
@@ -163,7 +165,8 @@ sub get_stationinfo_p {
return $promise->resolve($content);
}
- $self->{user_agent}->request_timeout(5)->get_p( $url => $self->{header} )
+ $self->{user_agent}->request_timeout(5)
+ ->get_p( $url => $self->{header} )
->then(
sub {
my ($tx) = @_;
@@ -183,7 +186,7 @@ sub get_stationinfo_p {
$promise->resolve($json);
return;
}
- )->catch(
+ )->catch(
sub {
my ($err) = @_;
$self->{log}->debug("get_stationinfo_p(${eva}): Error ${err}");
@@ -191,7 +194,7 @@ sub get_stationinfo_p {
$promise->reject($err);
return;
}
- )->wait;
+ )->wait;
return $promise;
}
diff --git a/lib/Travelynx/Helper/DBRIS.pm b/lib/Travelynx/Helper/DBRIS.pm
new file mode 100644
index 0000000..0a46758
--- /dev/null
+++ b/lib/Travelynx/Helper/DBRIS.pm
@@ -0,0 +1,147 @@
+package Travelynx::Helper::DBRIS;
+
+# Copyright (C) 2025 Birte Kristina Friesel
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+use strict;
+use warnings;
+use 5.020;
+use utf8;
+
+use DateTime;
+use Encode qw(decode);
+use JSON;
+use Mojo::Promise;
+use Mojo::UserAgent;
+use Travel::Status::DE::DBRIS;
+
+sub new {
+ my ( $class, %opt ) = @_;
+
+ my $version = $opt{version};
+
+ $opt{header}
+ = { 'User-Agent' =>
+"travelynx/${version} on $opt{root_url} +https://finalrewind.org/projects/travelynx"
+ };
+
+ return bless( \%opt, $class );
+}
+
+sub get_station_id_p {
+ my ( $self, $station_name ) = @_;
+ my $promise = Mojo::Promise->new;
+ Travel::Status::DE::DBRIS->new_p(
+ locationSearch => $station_name,
+ cache => $self->{cache},
+ lwp_options => {
+ timeout => 10,
+ agent => $self->{header}{'User-Agent'},
+ },
+ promise => 'Mojo::Promise',
+ user_agent => Mojo::UserAgent->new,
+ )->then(
+ sub {
+ my ($dbris) = @_;
+ my $found;
+ for my $result ( $dbris->results ) {
+ if ( defined $result->eva ) {
+ $promise->resolve($result);
+ return;
+ }
+ }
+ $promise->reject("Unable to find station '$station_name'");
+ return;
+ }
+ )->catch(
+ sub {
+ my ($err) = @_;
+ $promise->reject("'$err' while trying to look up '$station_name'");
+ return;
+ }
+ )->wait;
+ return $promise;
+}
+
+sub get_departures_p {
+ my ( $self, %opt ) = @_;
+
+ my $agent = $self->{user_agent};
+
+ if ( $opt{station} =~ m{ [@] L = (?<eva> \d+ ) [@] }x ) {
+ $opt{station} = {
+ eva => $+{eva},
+ id => $opt{station},
+ };
+ }
+
+ my $when = (
+ $opt{timestamp}
+ ? $opt{timestamp}->clone
+ : DateTime->now( time_zone => 'Europe/Berlin' )
+ )->subtract( minutes => $opt{lookbehind} );
+ return Travel::Status::DE::DBRIS->new_p(
+ station => $opt{station},
+ datetime => $when,
+ cache => $self->{cache},
+ promise => 'Mojo::Promise',
+ user_agent => $agent->request_timeout(10),
+ );
+}
+
+sub get_journey_p {
+ my ( $self, %opt ) = @_;
+
+ my $promise = Mojo::Promise->new;
+ my $now = DateTime->now( time_zone => 'Europe/Berlin' );
+
+ my $agent = $self->{user_agent};
+ my $proxy;
+ if ( my @proxies = @{ $self->{service_config}{'bahn.de'}{proxies} // [] } )
+ {
+ $proxy = $proxies[ int( rand( scalar @proxies ) ) ];
+ }
+ elsif ( my $p = $self->{service_config}{'bahn.de'}{proxy} ) {
+ $proxy = $p;
+ }
+
+ if ($proxy) {
+ $agent = Mojo::UserAgent->new;
+ $agent->proxy->http($proxy);
+ $agent->proxy->https($proxy);
+ }
+
+ Travel::Status::DE::DBRIS->new_p(
+ journey => $opt{trip_id},
+ with_polyline => $opt{with_polyline},
+ cache => $self->{realtime_cache},
+ promise => 'Mojo::Promise',
+ user_agent => $agent->request_timeout(10),
+ )->then(
+ sub {
+ my ($dbris) = @_;
+ my $journey = $dbris->result;
+
+ if ($journey) {
+ $self->{log}->debug("get_journey_p($opt{trip_id}): success");
+ $promise->resolve($journey);
+ return;
+ }
+ $self->{log}->debug("get_journey_p($opt{trip_id}): no journey");
+ $promise->reject('no journey');
+ return;
+ }
+ )->catch(
+ sub {
+ my ($err) = @_;
+ $self->{log}->debug("get_journey_p($opt{trip_id}): error $err");
+ $promise->reject($err);
+ return;
+ }
+ )->wait;
+
+ return $promise;
+}
+
+1;
diff --git a/lib/Travelynx/Helper/HAFAS.pm b/lib/Travelynx/Helper/HAFAS.pm
index 5b1ee81..c35dfdb 100644
--- a/lib/Travelynx/Helper/HAFAS.pm
+++ b/lib/Travelynx/Helper/HAFAS.pm
@@ -7,11 +7,13 @@ package Travelynx::Helper::HAFAS;
use strict;
use warnings;
use 5.020;
+use utf8;
use DateTime;
use Encode qw(decode);
use JSON;
use Mojo::Promise;
+use Mojo::UserAgent;
use Travel::Status::DE::HAFAS;
sub _epoch {
@@ -53,58 +55,18 @@ sub get_service {
return Travel::Status::DE::HAFAS::get_service($service);
}
-sub get_json_p {
- my ( $self, $url, %opt ) = @_;
-
- my $cache = $self->{main_cache};
- my $promise = Mojo::Promise->new;
+sub get_departures_p {
+ my ( $self, %opt ) = @_;
- if ( $opt{realtime} ) {
- $cache = $self->{realtime_cache};
- }
- $opt{encoding} //= 'ISO-8859-15';
+ $opt{service} //= 'ÖBB';
- if ( my $content = $cache->thaw($url) ) {
- return $promise->resolve($content);
+ my $agent = $self->{user_agent};
+ if ( my $proxy = $self->{service_config}{ $opt{service} }{proxy} ) {
+ $agent = Mojo::UserAgent->new;
+ $agent->proxy->http($proxy);
+ $agent->proxy->https($proxy);
}
- $self->{user_agent}->request_timeout(5)->get_p( $url => $self->{header} )
- ->then(
- sub {
- my ($tx) = @_;
-
- if ( my $err = $tx->error ) {
- $promise->reject(
-"hafas->get_json_p($url) returned HTTP $err->{code} $err->{message}"
- );
- return;
- }
-
- my $body = decode( $opt{encoding}, $tx->res->body );
-
- $body =~ s{^TSLs[.]sls = }{};
- $body =~ s{;$}{};
- $body =~ s{&#x0028;}{(}g;
- $body =~ s{&#x0029;}{)}g;
- my $json = JSON->new->decode($body);
- $cache->freeze( $url, $json );
- $promise->resolve($json);
- return;
- }
- )->catch(
- sub {
- my ($err) = @_;
- $self->{log}->info("hafas->get_json_p($url): $err");
- $promise->reject("hafas->get_json_p($url): $err");
- return;
- }
- )->wait;
- return $promise;
-}
-
-sub get_departures_p {
- my ( $self, %opt ) = @_;
-
my $when = (
$opt{timestamp}
? $opt{timestamp}->clone
@@ -118,19 +80,28 @@ sub get_departures_p {
results => 300,
cache => $self->{realtime_cache},
promise => 'Mojo::Promise',
- user_agent => $self->{user_agent}->request_timeout(5),
+ user_agent => $agent->request_timeout(5),
);
}
sub search_location_p {
my ( $self, %opt ) = @_;
+ $opt{service} //= 'ÖBB';
+
+ my $agent = $self->{user_agent};
+ if ( my $proxy = $self->{service_config}{ $opt{service} }{proxy} ) {
+ $agent = Mojo::UserAgent->new;
+ $agent->proxy->http($proxy);
+ $agent->proxy->https($proxy);
+ }
+
return Travel::Status::DE::HAFAS->new_p(
service => $opt{service},
locationSearch => $opt{query},
cache => $self->{realtime_cache},
promise => 'Mojo::Promise',
- user_agent => $self->{user_agent}->request_timeout(5),
+ user_agent => $agent->request_timeout(5),
);
}
@@ -143,13 +114,22 @@ sub get_tripid_p {
my $train_desc = $train->type . ' ' . $train->train_no;
$train_desc =~ s{^- }{};
+ $opt{service} //= 'ÖBB';
+
+ my $agent = $self->{user_agent};
+ if ( my $proxy = $self->{service_config}{ $opt{service} }{proxy} ) {
+ $agent = Mojo::UserAgent->new;
+ $agent->proxy->http($proxy);
+ $agent->proxy->https($proxy);
+ }
+
Travel::Status::DE::HAFAS->new_p(
service => $opt{service},
journeyMatch => $train_desc,
datetime => $train->start,
cache => $self->{realtime_cache},
promise => 'Mojo::Promise',
- user_agent => $self->{user_agent}->request_timeout(10),
+ user_agent => $agent->request_timeout(10),
)->then(
sub {
my ($hafas) = @_;
@@ -195,6 +175,15 @@ sub get_journey_p {
my $promise = Mojo::Promise->new;
my $now = DateTime->now( time_zone => 'Europe/Berlin' );
+ $opt{service} //= 'ÖBB';
+
+ my $agent = $self->{user_agent};
+ if ( my $proxy = $self->{service_config}{ $opt{service} }{proxy} ) {
+ $agent = Mojo::UserAgent->new;
+ $agent->proxy->http($proxy);
+ $agent->proxy->https($proxy);
+ }
+
Travel::Status::DE::HAFAS->new_p(
service => $opt{service},
journey => {
@@ -203,7 +192,7 @@ sub get_journey_p {
with_polyline => $opt{with_polyline},
cache => $self->{realtime_cache},
promise => 'Mojo::Promise',
- user_agent => $self->{user_agent}->request_timeout(10),
+ user_agent => $agent->request_timeout(10),
)->then(
sub {
my ($hafas) = @_;
@@ -236,6 +225,15 @@ sub get_route_p {
my $promise = Mojo::Promise->new;
my $now = DateTime->now( time_zone => 'Europe/Berlin' );
+ $opt{service} //= 'ÖBB';
+
+ my $agent = $self->{user_agent};
+ if ( my $proxy = $self->{service_config}{ $opt{service} }{proxy} ) {
+ $agent = Mojo::UserAgent->new;
+ $agent->proxy->http($proxy);
+ $agent->proxy->https($proxy);
+ }
+
Travel::Status::DE::HAFAS->new_p(
service => $opt{service},
journey => {
@@ -246,7 +244,7 @@ sub get_route_p {
with_polyline => $opt{with_polyline},
cache => $self->{realtime_cache},
promise => 'Mojo::Promise',
- user_agent => $self->{user_agent}->request_timeout(10),
+ user_agent => $agent->request_timeout(10),
)->then(
sub {
my ($hafas) = @_;
diff --git a/lib/Travelynx/Helper/MOTIS.pm b/lib/Travelynx/Helper/MOTIS.pm
new file mode 100644
index 0000000..d4e1777
--- /dev/null
+++ b/lib/Travelynx/Helper/MOTIS.pm
@@ -0,0 +1,158 @@
+package Travelynx::Helper::MOTIS;
+
+# Copyright (C) 2025 networkException <git@nwex.de>
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+use strict;
+use warnings;
+use 5.020;
+use utf8;
+
+use DateTime;
+use Encode qw(decode);
+use JSON;
+use Mojo::Promise;
+use Mojo::UserAgent;
+
+use Travel::Status::MOTIS;
+
+sub _epoch {
+ my ($dt) = @_;
+
+ return $dt ? $dt->epoch : 0;
+}
+
+sub new {
+ my ( $class, %opt ) = @_;
+
+ my $version = $opt{version};
+
+ $opt{header}
+ = { 'User-Agent' =>
+"travelynx/${version} on $opt{root_url} +https://finalrewind.org/projects/travelynx"
+ };
+
+ return bless( \%opt, $class );
+}
+
+sub get_service {
+ my ( $self, $service ) = @_;
+
+ return Travel::Status::MOTIS::get_service($service);
+}
+
+sub get_station_by_query_p {
+ my ( $self, %opt ) = @_;
+
+ $opt{service} //= 'transitous';
+
+ my $promise = Mojo::Promise->new;
+
+ Travel::Status::MOTIS->new_p(
+ cache => $self->{cache},
+ promise => 'Mojo::Promise',
+ user_agent => Mojo::UserAgent->new,
+ lwp_options => {
+ timeout => 10,
+ agent => $self->{header}{'User-Agent'},
+ },
+
+ service => $opt{service},
+ stops_by_query => $opt{query},
+ )->then(
+ sub {
+ my ($motis) = @_;
+ my $found;
+
+ for my $result ( $motis->results ) {
+ if ( defined $result->id ) {
+ $promise->resolve($result);
+ return;
+ }
+ }
+
+ $promise->reject("Unable to find station '$opt{query}'");
+ return;
+ }
+ )->catch(
+ sub {
+ my ($err) = @_;
+ $promise->reject("'$err' while trying to look up '$opt{query}'");
+ return;
+ }
+ )->wait;
+
+ return $promise;
+}
+
+sub get_departures_p {
+ my ( $self, %opt ) = @_;
+
+ $opt{service} //= 'transitous';
+
+ my $timestamp = (
+ $opt{timestamp}
+ ? $opt{timestamp}->clone
+ : DateTime->now
+ )->subtract( minutes => $opt{lookbehind} );
+
+ return Travel::Status::MOTIS->new_p(
+ cache => $self->{cache},
+ promise => 'Mojo::Promise',
+ user_agent => Mojo::UserAgent->new,
+ lwp_options => {
+ timeout => 10,
+ agent => $self->{header}{'User-Agent'},
+ },
+
+ service => $opt{service},
+ timestamp => $timestamp,
+ stop_id => $opt{station_id},
+ results => 60,
+ );
+}
+
+sub get_trip_p {
+ my ( $self, %opt ) = @_;
+
+ $opt{service} //= 'transitous';
+
+ my $promise = Mojo::Promise->new;
+
+ Travel::Status::MOTIS->new_p(
+ with_polyline => $opt{with_polyline},
+ cache => $self->{realtime_cache},
+ promise => 'Mojo::Promise',
+ user_agent => Mojo::UserAgent->new,
+
+ service => $opt{service},
+ trip_id => $opt{trip_id},
+ )->then(
+ sub {
+ my ($motis) = @_;
+ my $journey = $motis->result;
+
+ if ($journey) {
+ $self->{log}->debug("get_trip_p($opt{trip_id}): success");
+ $promise->resolve($journey);
+ return;
+ }
+
+ $self->{log}->debug("get_trip_p($opt{trip_id}): no journey");
+ $promise->reject('no journey');
+ return;
+ }
+ )->catch(
+ sub {
+ my ($err) = @_;
+ $self->{log}->debug("get_trip_p($opt{trip_id}): error $err");
+ $promise->reject($err);
+ return;
+ }
+ )->wait;
+
+ return $promise;
+}
+
+1;
diff --git a/lib/Travelynx/Helper/Traewelling.pm b/lib/Travelynx/Helper/Traewelling.pm
index 100a799..66f2a29 100644
--- a/lib/Travelynx/Helper/Traewelling.pm
+++ b/lib/Travelynx/Helper/Traewelling.pm
@@ -78,7 +78,8 @@ sub get_status_p {
$self->{user_agent}->request_timeout(20)
->get_p(
"https://traewelling.de/api/v1/user/${username}/statuses?limit=1" =>
- $header )->then(
+ $header )
+ ->then(
sub {
my ($tx) = @_;
if ( my $err = $tx->error ) {
@@ -150,13 +151,13 @@ sub get_status_p {
}
}
}
- )->catch(
+ )->catch(
sub {
my ($err) = @_;
$promise->reject( { text => "v1/${username}/statuses: $err" } );
return;
}
- )->wait;
+ )->wait;
return $promise;
}
@@ -238,13 +239,13 @@ sub logout_p {
return;
}
}
- )->catch(
+ )->catch(
sub {
my ($err) = @_;
$promise->reject("v1/auth/logout: $err");
return;
}
- )->wait;
+ )->wait;
return $promise;
}
@@ -322,7 +323,8 @@ sub checkin_p {
$self->{user_agent}->request_timeout(20)
->post_p(
"https://traewelling.de/api/v1/trains/checkin" => $header => json =>
- $request )->then(
+ $request )
+ ->then(
sub {
my ($tx) = @_;
if ( my $err = $tx->error ) {
@@ -368,7 +370,7 @@ sub checkin_p {
# on the user status page
return;
}
- )->catch(
+ )->catch(
sub {
my ($err) = @_;
$self->{log}->debug("... $debug_prefix error: $err");
@@ -381,7 +383,7 @@ sub checkin_p {
$promise->reject( { connection => $err } );
return;
}
- )->wait;
+ )->wait;
return $promise;
}