summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rwxr-xr-xlib/Travelynx.pm8
-rwxr-xr-xlib/Travelynx/Controller/Api.pm167
2 files changed, 169 insertions, 6 deletions
diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm
index cc0f81d..3abe949 100755
--- a/lib/Travelynx.pm
+++ b/lib/Travelynx.pm
@@ -159,12 +159,13 @@ sub startup {
status => 1,
history => 2,
action => 3,
+ import => 4,
};
}
);
$self->attr(
token_types => sub {
- return [qw(status history action)];
+ return [qw(status history action import)];
}
);
@@ -330,7 +331,7 @@ sub startup {
my ( $self, %opt ) = @_;
my $db = $opt{db};
- my $uid = $self->current_user->{id};
+ my $uid = $opt{uid} // $self->current_user->{id};
my $now = DateTime->now( time_zone => 'Europe/Berlin' );
my $dep_station = get_station( $opt{dep_station} );
my $arr_station = get_station( $opt{arr_station} );
@@ -410,7 +411,7 @@ sub startup {
$journey_id
= $db->insert( 'journeys', $entry, { returning => 'id' } )
->hash->{id};
- $self->invalidate_stats_cache( $opt{rt_departure}, $db );
+ $self->invalidate_stats_cache( $opt{rt_departure}, $db, $uid );
};
if ($@) {
@@ -3232,6 +3233,7 @@ sub startup {
$r->get('/status/:name/:ts')->to('traveling#user_status');
$r->get('/ajax/status/:name')->to('traveling#public_status_card');
$r->get('/ajax/status/:name/:ts')->to('traveling#public_status_card');
+ $r->post('/api/v1/import')->to('api#import_v1');
$r->post('/action')->to('traveling#log_action');
$r->post('/geolocation')->to('traveling#geolocation');
$r->post('/list_departures')->to('traveling#redirect_to_station');
diff --git a/lib/Travelynx/Controller/Api.pm b/lib/Travelynx/Controller/Api.pm
index a442784..84e1507 100755
--- a/lib/Travelynx/Controller/Api.pm
+++ b/lib/Travelynx/Controller/Api.pm
@@ -1,6 +1,7 @@
package Travelynx::Controller::Api;
use Mojo::Base 'Mojolicious::Controller';
+use DateTime;
use Travel::Status::DE::IRIS::Stations;
use UUID::Tiny qw(:std);
@@ -8,6 +9,17 @@ sub make_token {
return create_uuid_as_string(UUID_V4);
}
+sub sanitize {
+ my ( $type, $value ) = @_;
+ if ( not defined $value ) {
+ return undef;
+ }
+ if ( $type eq '' ) {
+ return '' . $value;
+ }
+ return 0 + $value;
+}
+
sub documentation {
my ($self) = @_;
@@ -71,9 +83,9 @@ sub get_v0 {
or $status->{cancelled}
) ? \1 : \0,
station => {
- ds100 => $status->{arr_ds100} // $status->{dep_ds100},
- name => $status->{arr_name} // $status->{dep_name},
- uic => $station_eva,
+ ds100 => $status->{arr_ds100} // $status->{dep_ds100},
+ name => $status->{arr_name} // $status->{dep_name},
+ uic => $station_eva,
longitude => $station_lon,
latitude => $station_lat,
},
@@ -153,6 +165,155 @@ sub get_v1 {
}
}
+sub import_v1 {
+ my ($self) = @_;
+
+ my $payload = $self->req->json;
+ my $api_token = $payload->{token} // '';
+
+ if ( $api_token !~ qr{ ^ (?<id> \d+ ) - (?<token> .* ) $ }x ) {
+ $self->render(
+ json => {
+ success => \0,
+ error => 'Malformed JSON or malformed token',
+ },
+ );
+ return;
+ }
+ my $uid = $+{id};
+ $api_token = $+{token};
+
+ if ( $uid > 2147483647 ) {
+ $self->render(
+ json => {
+ success => \0,
+ error => 'Malformed token',
+ },
+ );
+ return;
+ }
+
+ my $token = $self->get_api_token($uid);
+ if ( $api_token ne $token->{'import'} ) {
+ $self->render(
+ json => {
+ success => \0,
+ error => 'Invalid token',
+ },
+ );
+ return;
+ }
+
+ if ( not exists $payload->{fromStation}
+ or not exists $payload->{toStation} )
+ {
+ $self->render(
+ json => {
+ success => \0,
+ error => 'missing fromStation or toStation',
+ },
+ );
+ return;
+ }
+
+ my %opt;
+
+ eval {
+ %opt = (
+ uid => $uid,
+ train_type => sanitize( q{}, $payload->{train}{type} ),
+ train_no => sanitize( q{}, $payload->{train}{no} ),
+ train_line => sanitize( q{}, $payload->{train}{line} ),
+ cancelled => $payload->{cancelled} ? 1 : 0,
+ dep_station => sanitize( q{}, $payload->{fromStation}{name} ),
+ arr_station => sanitize( q{}, $payload->{toStation}{name} ),
+ sched_departure =>
+ sanitize( 0, $payload->{fromStation}{scheduledTime} ),
+ rt_departure => sanitize(
+ 0,
+ $payload->{fromStation}{realTime}
+ // $payload->{fromStation}{scheduledTime}
+ ),
+ sched_arrival =>
+ sanitize( 0, $payload->{toStation}{scheduledTime} ),
+ rt_arrival => sanitize(
+ 0,
+ $payload->{toStation}{realTime}
+ // $payload->{toStation}{scheduledTime}
+ ),
+ comment => sanitize( q{}, $payload->{comment} ),
+ );
+
+ if ( $payload->{route} and ref( $payload->{route} ) eq 'ARRAY' ) {
+ $opt{route}
+ = [ map { sanitize( q{}, $_ ) } @{ $payload->{route} } ];
+ }
+
+ for my $key (qw(sched_departure rt_departure sched_arrival rt_arrival))
+ {
+ $opt{$key} = DateTime->from_epoch(
+ time_zone => 'Europe/Berlin',
+ epoch => $opt{$key}
+ );
+ }
+ };
+ if ($@) {
+ my ($first_line) = split( qr{\n}, $@ );
+ $self->render(
+ json => {
+ success => \0,
+ error => $first_line
+ }
+ );
+ return;
+ }
+
+ my $db = $self->pg->db;
+ my $tx = $db->begin;
+
+ $opt{db} = $db;
+ my ( $journey_id, $error ) = $self->add_journey(%opt);
+ my $journey;
+
+ if ( not $error ) {
+ $journey = $self->get_journey(
+ uid => $uid,
+ db => $db,
+ journey_id => $journey_id,
+ verbose => 1
+ );
+ $error = $self->journey_sanity_check($journey);
+ }
+
+ if ($error) {
+ $self->render(
+ json => {
+ success => \0,
+ error => $error
+ }
+ );
+ }
+ elsif ( $payload->{dryRun} ) {
+ $self->render(
+ json => {
+ success => \1,
+ id => $journey_id,
+ result => $journey
+ }
+ );
+ }
+ else {
+ $tx->commit;
+ $self->render(
+ json => {
+ success => \1,
+ id => $journey_id,
+ result => $journey
+ }
+ );
+ }
+}
+
sub set_token {
my ($self) = @_;
if ( $self->validation->csrf_protect->has_error('csrf_token') ) {