diff options
Diffstat (limited to 'lib')
-rwxr-xr-x | lib/Travelynx.pm | 360 | ||||
-rw-r--r-- | lib/Travelynx/Command/database.pm | 220 | ||||
-rw-r--r-- | lib/Travelynx/Command/dumpstops.pm | 2 | ||||
-rw-r--r-- | lib/Travelynx/Command/traewelling.pm | 34 | ||||
-rw-r--r-- | lib/Travelynx/Command/work.pm | 38 | ||||
-rw-r--r-- | lib/Travelynx/Controller/Account.pm | 23 | ||||
-rwxr-xr-x | lib/Travelynx/Controller/Profile.pm | 100 | ||||
-rwxr-xr-x | lib/Travelynx/Controller/Traveling.pm | 25 | ||||
-rw-r--r-- | lib/Travelynx/Helper/DBDB.pm | 29 | ||||
-rw-r--r-- | lib/Travelynx/Helper/HAFAS.pm | 22 | ||||
-rw-r--r-- | lib/Travelynx/Model/InTransit.pm | 128 | ||||
-rwxr-xr-x | lib/Travelynx/Model/Journeys.pm | 8 | ||||
-rw-r--r-- | lib/Travelynx/Model/Users.pm | 36 |
13 files changed, 713 insertions, 312 deletions
diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm index 4d04e9e..2f8396c 100755 --- a/lib/Travelynx.pm +++ b/lib/Travelynx.pm @@ -362,11 +362,12 @@ sub startup { dbdb => sub { my ($self) = @_; state $dbdb = Travelynx::Helper::DBDB->new( - log => $self->app->log, - cache => $self->app->cache_iris_main, - root_url => $self->base_url_for('/')->to_abs, - user_agent => $self->ua, - version => $self->app->config->{version}, + log => $self->app->log, + main_cache => $self->app->cache_iris_main, + realtime_cache => $self->app->cache_iris_rt, + root_url => $self->base_url_for('/')->to_abs, + user_agent => $self->ua, + version => $self->app->config->{version}, ); } ); @@ -506,6 +507,10 @@ sub startup { # mustn't be called during a transaction if ( not $opt{in_transaction} ) { $self->add_route_timestamps( $uid, $train, 1 ); + $self->add_wagonorder( $uid, 1, $train->train_id, + $train->sched_departure, $train->train_no ); + $self->add_stationinfo( $uid, 1, $train->train_id, + $eva ); $self->run_hook( $uid, 'checkin' ); } @@ -568,6 +573,7 @@ sub startup { db => $db, journey => $journey, stop => $found, + data => { trip_id => $journey->id } ); }; if ($@) { @@ -576,11 +582,6 @@ sub startup { $promise->reject( 'INSERT failed: ' . $@ ); return; } - $self->in_transit->update_data( - uid => $uid, - db => $db, - data => { trip_id => $journey->id } - ); my $polyline; if ( $journey->polyline ) { @@ -631,6 +632,12 @@ sub startup { # mustn't be called during a transaction if ( not $opt{in_transaction} ) { $self->run_hook( $uid, 'checkin' ); + if ( $journey->class <= 16 ) { + $self->app->add_wagonorder( $uid, 1, $journey->id, + $found->sched_dep, $journey->number ); + $self->add_stationinfo( $uid, 1, $journey->id, + $found->loc->eva ); + } } $promise->resolve($journey); @@ -992,6 +999,10 @@ sub startup { if ( not $opt{in_transaction} ) { $self->run_hook( $uid, 'update' ); $self->add_route_timestamps( $uid, $train, 0, 1 ); + $self->add_wagonorder( $uid, 0, $train->train_id, + $train->sched_departure, $train->train_no ); + $self->add_stationinfo( $uid, 0, $train->train_id, + $dep_eva, $new_checkout_station_id ); } $promise->resolve( 1, undef ); return; @@ -1065,7 +1076,7 @@ sub startup { last; } } - if ( not $found ) { + if ( not $found and not $force ) { return $promise->resolve( 1, 'station not found in route' ); } @@ -1218,6 +1229,111 @@ sub startup { } ); + $self->helper( + 'add_wagonorder' => sub { + my ( $self, $uid, $is_departure, $train_id, $sched_departure, + $train_no ) + = @_; + + $uid //= $self->current_user->{id}; + + my $db = $self->pg->db; + + if ( $sched_departure and $train_no ) { + $self->dbdb->has_wagonorder_p( $sched_departure, $train_no ) + ->then( + sub { + my ($api) = @_; + return $self->dbdb->get_wagonorder_p( $api, + $sched_departure, $train_no ); + } + )->then( + sub { + my ($wagonorder) = @_; + + my $data = {}; + my $user_data = {}; + + if ( $is_departure and not exists $wagonorder->{error} ) + { + $data->{wagonorder_dep} = $wagonorder; + $user_data->{wagongroups} = []; + for my $group ( + @{ + $wagonorder->{data}{istformation} + {allFahrzeuggruppe} // [] + } + ) + { + my @wagons; + for + my $wagon ( @{ $group->{allFahrzeug} // [] } ) + { + push( + @wagons, + { + id => $wagon->{fahrzeugnummer}, + number => + $wagon->{wagenordnungsnummer}, + type => $wagon->{fahrzeugtyp}, + } + ); + } + push( + @{ $user_data->{wagongroups} }, + { + name => + $group->{fahrzeuggruppebezeichnung}, + from => + $group->{startbetriebsstellename}, + to => $group->{zielbetriebsstellename}, + no => $group->{verkehrlichezugnummer}, + wagons => [@wagons], + } + ); + if ( $group->{fahrzeuggruppebezeichnung} + and $group->{fahrzeuggruppebezeichnung} eq + 'ICE0304' ) + { + $data->{wagonorder_pride} = 1; + } + } + $self->in_transit->update_data( + uid => $uid, + db => $db, + data => $data, + train_id => $train_id, + ); + $self->in_transit->update_user_data( + uid => $uid, + db => $db, + user_data => $user_data, + train_id => $train_id, + ); + } + elsif ( not $is_departure + and not exists $wagonorder->{error} ) + { + $data->{wagonorder_arr} = $wagonorder; + $self->in_transit->update_data( + uid => $uid, + db => $db, + data => $data, + train_id => $train_id, + ); + } + return; + } + )->catch( + sub { + # no wagonorder? no problem. + return; + } + )->wait; + } + } + ); + # This helper is only ever called from an IRIS context. # HAFAS already has all relevant information. $self->helper( @@ -1241,19 +1357,22 @@ sub startup { return; } - my $route = $in_transit->{route}; + my $route = $in_transit->{route}; + my $train_id = $train->train_id; + # TODO get_tripid_p is only needed on the first call, afterwards the tripid is known. $self->hafas->get_tripid_p( train => $train )->then( sub { my ($trip_id) = @_; $self->in_transit->update_data( - uid => $uid, - db => $db, - data => { trip_id => $trip_id } + uid => $uid, + db => $db, + data => { trip_id => $trip_id }, + train_id => $train_id, ); - return $self->hafas->get_route_timestamps_p( + return $self->hafas->get_route_p( train => $train, trip_id => $trip_id, with_polyline => ( @@ -1264,42 +1383,53 @@ sub startup { } )->then( sub { - my ( $route_data, $journey, $polyline ) = @_; - - for my $station ( @{$route} ) { - if ( $station->[0] - =~ m{^Betriebsstelle nicht bekannt (\d+)$} ) - { - my $eva = $1; - if ( $route_data->{$eva} ) { - $station->[0] = $route_data->{$eva}{name}; - $station->[1] = $route_data->{$eva}{eva}; - } - } - if ( my $sd = $route_data->{ $station->[0] } ) { - $station->[1] = $sd->{eva}; - if ( $station->[2]{isAdditional} ) { - $sd->{isAdditional} = 1; - } - if ( $station->[2]{isCancelled} ) { - $sd->{isCancelled} = 1; - } - - # keep rt_dep / rt_arr if they are no longer present - my %old; - for my $k (qw(rt_arr rt_dep arr_delay dep_delay)) { - $old{$k} = $station->[2]{$k}; - } - $station->[2] = $sd; - if ( not $station->[2]{rt_arr} ) { - $station->[2]{rt_arr} = $old{rt_arr}; - $station->[2]{arr_delay} = $old{arr_delay}; + my ( $new_route, $journey, $polyline ) = @_; + my $db_route; + + for my $i ( 0 .. $#{$new_route} ) { + my $old_name = $route->[$i][0]; + my $old_eva = $route->[$i][1]; + my $old_entry = $route->[$i][2]; + my $new_name = $new_route->[$i]->{name}; + my $new_eva = $new_route->[$i]->{eva}; + my $new_entry = $new_route->[$i]; + + if ( defined $old_name and $old_name eq $new_name ) { + if ( $old_entry->{rt_arr} + and not $new_entry->{rt_arr} ) + { + $new_entry->{rt_arr} = $old_entry->{rt_arr}; + $new_entry->{arr_delay} + = $old_entry->{arr_delay}; } - if ( not $station->[2]{rt_dep} ) { - $station->[2]{rt_dep} = $old{rt_dep}; - $station->[2]{dep_delay} = $old{dep_delay}; + if ( $old_entry->{rt_dep} + and not $new_entry->{rt_dep} ) + { + $new_entry->{rt_dep} = $old_entry->{rt_dep}; + $new_entry->{dep_delay} + = $old_entry->{dep_delay}; } } + + push( + @{$db_route}, + [ + $new_name, + $new_eva, + { + sched_arr => $new_entry->{sched_arr}, + rt_arr => $new_entry->{rt_arr}, + arr_delay => $new_entry->{arr_delay}, + sched_dep => $new_entry->{sched_dep}, + rt_dep => $new_entry->{rt_dep}, + dep_delay => $new_entry->{dep_delay}, + tz_offset => $new_entry->{tz_offset}, + isAdditional => $new_entry->{isAdditional}, + isCancelled => $new_entry->{isCancelled}, + load => $new_entry->{load}, + } + ] + ); } my @messages; @@ -1318,7 +1448,7 @@ sub startup { $self->in_transit->set_route_data( uid => $uid, db => $db, - route => $route, + route => $db_route, delay_messages => [ map { [ $_->[0]->epoch, $_->[1] ] } $train->delay_messages @@ -1328,6 +1458,7 @@ sub startup { $train->qos_messages ], him_messages => \@messages, + train_id => $train_id, ); if ($polyline) { @@ -1336,6 +1467,7 @@ sub startup { db => $db, polyline => $polyline, old_id => $in_transit->{polyline_id}, + train_id => $train_id, ); } @@ -1348,107 +1480,28 @@ sub startup { return; } )->wait; + } + ); - if ( $train->sched_departure ) { - $self->dbdb->has_wagonorder_p( $train->sched_departure, - $train->train_no )->then( - sub { - my ($api) = @_; - return $self->dbdb->get_wagonorder_p( $api, - $train->sched_departure, $train->train_no ); - } - )->then( - sub { - my ($wagonorder) = @_; - - my $data = {}; - my $user_data = {}; + $self->helper( + 'add_stationinfo' => sub { + my ( $self, $uid, $is_departure, $train_id, $dep_eva, $arr_eva ) + = @_; - if ( $is_departure and not exists $wagonorder->{error} ) - { - $data->{wagonorder_dep} = $wagonorder; - $user_data->{wagongroups} = []; - for my $group ( - @{ - $wagonorder->{data}{istformation} - {allFahrzeuggruppe} // [] - } - ) - { - my @wagons; - for - my $wagon ( @{ $group->{allFahrzeug} // [] } ) - { - push( - @wagons, - { - id => $wagon->{fahrzeugnummer}, - number => - $wagon->{wagenordnungsnummer}, - type => $wagon->{fahrzeugtyp}, - } - ); - } - push( - @{ $user_data->{wagongroups} }, - { - name => - $group->{fahrzeuggruppebezeichnung}, - from => - $group->{startbetriebsstellename}, - to => $group->{zielbetriebsstellename}, - no => $group->{verkehrlichezugnummer}, - wagons => [@wagons], - } - ); - if ( $group->{fahrzeuggruppebezeichnung} - and $group->{fahrzeuggruppebezeichnung} eq - 'ICE0304' ) - { - $data->{wagonorder_pride} = 1; - } - } - $self->in_transit->update_data( - uid => $uid, - db => $db, - data => $data - ); - $self->in_transit->update_user_data( - uid => $uid, - db => $db, - user_data => $user_data - ); - } - elsif ( not $is_departure - and not exists $wagonorder->{error} ) - { - $data->{wagonorder_arr} = $wagonorder; - $self->in_transit->update_data( - uid => $uid, - db => $db, - data => $data - ); - } - return; - } - )->catch( - sub { - # no wagonorder? no problem. - return; - } - )->wait; - } + $uid //= $self->current_user->{id}; + my $db = $self->pg->db; if ($is_departure) { - $self->dbdb->get_stationinfo_p( $in_transit->{dep_eva} )->then( + $self->dbdb->get_stationinfo_p($dep_eva)->then( sub { my ($station_info) = @_; my $data = { stationinfo_dep => $station_info }; $self->in_transit->update_data( - uid => $uid, - db => $db, - data => $data + uid => $uid, + db => $db, + data => $data, + train_id => $train_id, ); return; } @@ -1460,16 +1513,17 @@ sub startup { )->wait; } - if ( $in_transit->{arr_eva} and not $is_departure ) { - $self->dbdb->get_stationinfo_p( $in_transit->{arr_eva} )->then( + if ( $arr_eva and not $is_departure ) { + $self->dbdb->get_stationinfo_p($arr_eva)->then( sub { my ($station_info) = @_; my $data = { stationinfo_arr => $station_info }; $self->in_transit->update_data( - uid => $uid, - db => $db, - data => $data + uid => $uid, + db => $db, + data => $data, + train_id => $train_id, ); return; } @@ -1493,6 +1547,7 @@ sub startup { $ret =~ s{[{]tt[}]}{$opt{tt}}g; $ret =~ s{[{]tn[}]}{$opt{tn}}g; $ret =~ s{[{]id[}]}{$opt{id}}g; + $ret =~ s{[{]hafas[}]}{$opt{hafas}}g; return $ret; } ); @@ -2358,11 +2413,14 @@ sub startup { $r->get('/recover')->to('account#request_password_reset'); $r->get('/recover/:id/:token')->to('account#recover_password'); $r->get('/reg/:id/:token')->to('account#verify'); - $r->get('/status/:name')->to('profile#user_status'); - $r->get('/status/:name/:ts')->to('profile#user_status'); + $r->get( '/status/:name' => [ format => [ 'html', 'json' ] ] ) + ->to( 'profile#user_status', format => undef ); + $r->get( '/status/:name/:ts' => [ format => [ 'html', 'json' ] ] ) + ->to( 'profile#user_status', format => undef ); $r->get('/ajax/status/#name')->to('profile#status_card'); $r->get('/ajax/status/:name/:ts')->to('profile#status_card'); - $r->get('/p/:name')->to('profile#profile'); + $r->get( '/p/:name' => [ format => [ 'html', 'json' ] ] ) + ->to( 'profile#profile', format => undef ); $r->get( '/p/:name/j/:id' => 'public_journey' ) ->to('profile#journey_details'); $r->get('/.well-known/webfinger')->to('account#webfinger'); @@ -2408,7 +2466,6 @@ sub startup { $authed_r->get('/account/hooks')->to('account#webhook'); $authed_r->get('/account/traewelling')->to('traewelling#settings'); $authed_r->get('/account/insight')->to('account#insight'); - $authed_r->get('/account/services')->to('account#services'); $authed_r->get('/ajax/status_card.html')->to('traveling#status_card'); $authed_r->get('/cancelled')->to('traveling#cancelled'); $authed_r->get('/fgr')->to('passengerrights#list_candidates'); @@ -2436,7 +2493,6 @@ sub startup { $authed_r->post('/account/hooks')->to('account#webhook'); $authed_r->post('/account/traewelling')->to('traewelling#settings'); $authed_r->post('/account/insight')->to('account#insight'); - $authed_r->post('/account/services')->to('account#services'); $authed_r->post('/journey/add')->to('traveling#add_journey_form'); $authed_r->post('/journey/comment')->to('traveling#comment_form'); $authed_r->post('/journey/visibility')->to('traveling#visibility_form'); diff --git a/lib/Travelynx/Command/database.pm b/lib/Travelynx/Command/database.pm index d13b2a7..fb5ee80 100644 --- a/lib/Travelynx/Command/database.pm +++ b/lib/Travelynx/Command/database.pm @@ -1946,6 +1946,226 @@ my @migrations = ( } ); }, + + # v51 -> v52 + # Explicitly encode backend type; preparation for multiple hAFAS backends + sub { + my ($db) = @_; + $db->query( + qq{ + create table backends ( + id smallserial not null primary key, + iris bool not null, + hafas bool not null, + efa bool not null, + ris bool not null, + name varchar(32) not null, + unique (iris, hafas, efa, ris, name) + ); + insert into backends (id, iris, hafas, efa, ris, name) values (0, true, false, false, false, ''); + insert into backends (id, iris, hafas, efa, ris, name) values (1, false, true, false, false, 'DB'); + alter sequence backends_id_seq restart with 2; + alter table in_transit add column backend_id smallint references backends (id); + alter table journeys add column backend_id smallint references backends (id); + update in_transit set backend_id = 0 where train_id not like '%|%'; + update journeys set backend_id = 0 where train_id not like '%|%'; + update in_transit set backend_id = 1 where train_id like '%|%'; + update journeys set backend_id = 1 where train_id like '%|%'; + update journeys set backend_id = 1 where train_id = 'manual'; + alter table in_transit alter column backend_id set not null; + alter table journeys alter column backend_id set not null; + + drop view in_transit_str; + drop view journeys_str; + create view in_transit_str as select + user_id, + backend.iris as is_iris, backend.hafas as is_hafas, + backend.efa as is_efa, backend.ris as is_ris, + backend.name as backend_name, + train_type, train_line, train_no, train_id, + extract(epoch from checkin_time) as checkin_ts, + extract(epoch from sched_departure) as sched_dep_ts, + extract(epoch from real_departure) as real_dep_ts, + checkin_station_id as dep_eva, + dep_station.ds100 as dep_ds100, + dep_station.name as dep_name, + dep_station.lat as dep_lat, + dep_station.lon as dep_lon, + extract(epoch from checkout_time) as checkout_ts, + extract(epoch from sched_arrival) as sched_arr_ts, + extract(epoch from real_arrival) as real_arr_ts, + checkout_station_id as arr_eva, + arr_station.ds100 as arr_ds100, + arr_station.name as arr_name, + arr_station.lat as arr_lat, + arr_station.lon as arr_lon, + polyline_id, + polylines.polyline as polyline, + visibility, + coalesce(visibility, users.public_level & 127) as effective_visibility, + cancelled, route, messages, user_data, + dep_platform, arr_platform, data + from in_transit + left join polylines on polylines.id = polyline_id + left join users on users.id = user_id + left join stations as dep_station on checkin_station_id = dep_station.eva + left join stations as arr_station on checkout_station_id = arr_station.eva + left join backends as backend on backend_id = backend.id + ; + create view journeys_str as select + journeys.id as journey_id, user_id, + backend.iris as is_iris, backend.hafas as is_hafas, + backend.efa as is_efa, backend.ris as is_ris, + backend.name as backend_name, + train_type, train_line, train_no, train_id, + extract(epoch from checkin_time) as checkin_ts, + extract(epoch from sched_departure) as sched_dep_ts, + extract(epoch from real_departure) as real_dep_ts, + checkin_station_id as dep_eva, + dep_station.ds100 as dep_ds100, + dep_station.name as dep_name, + dep_station.lat as dep_lat, + dep_station.lon as dep_lon, + extract(epoch from checkout_time) as checkout_ts, + extract(epoch from sched_arrival) as sched_arr_ts, + extract(epoch from real_arrival) as real_arr_ts, + checkout_station_id as arr_eva, + arr_station.ds100 as arr_ds100, + arr_station.name as arr_name, + arr_station.lat as arr_lat, + arr_station.lon as arr_lon, + polylines.polyline as polyline, + visibility, + coalesce(visibility, users.public_level & 127) as effective_visibility, + cancelled, edited, route, messages, user_data, + dep_platform, arr_platform + from journeys + left join polylines on polylines.id = polyline_id + left join users on users.id = user_id + left join stations as dep_station on checkin_station_id = dep_station.eva + left join stations as arr_station on checkout_station_id = arr_station.eva + left join backends as backend on backend_id = backend.id + ; + update schema_version set version = 52; + } + ); + }, + sub { + my ($db) = @_; + $db->query( + qq{ + drop view in_transit_str; + drop view journeys_str; + drop view follows_in_transit; + alter table in_transit alter column train_id type varchar(384); + alter table journeys alter column train_id type varchar(384); + create view in_transit_str as select + user_id, + backend.iris as is_iris, backend.hafas as is_hafas, + backend.efa as is_efa, backend.ris as is_ris, + backend.name as backend_name, + train_type, train_line, train_no, train_id, + extract(epoch from checkin_time) as checkin_ts, + extract(epoch from sched_departure) as sched_dep_ts, + extract(epoch from real_departure) as real_dep_ts, + checkin_station_id as dep_eva, + dep_station.ds100 as dep_ds100, + dep_station.name as dep_name, + dep_station.lat as dep_lat, + dep_station.lon as dep_lon, + extract(epoch from checkout_time) as checkout_ts, + extract(epoch from sched_arrival) as sched_arr_ts, + extract(epoch from real_arrival) as real_arr_ts, + checkout_station_id as arr_eva, + arr_station.ds100 as arr_ds100, + arr_station.name as arr_name, + arr_station.lat as arr_lat, + arr_station.lon as arr_lon, + polyline_id, + polylines.polyline as polyline, + visibility, + coalesce(visibility, users.public_level & 127) as effective_visibility, + cancelled, route, messages, user_data, + dep_platform, arr_platform, data + from in_transit + left join polylines on polylines.id = polyline_id + left join users on users.id = user_id + left join stations as dep_station on checkin_station_id = dep_station.eva + left join stations as arr_station on checkout_station_id = arr_station.eva + left join backends as backend on backend_id = backend.id + ; + create view journeys_str as select + journeys.id as journey_id, user_id, + backend.iris as is_iris, backend.hafas as is_hafas, + backend.efa as is_efa, backend.ris as is_ris, + backend.name as backend_name, + train_type, train_line, train_no, train_id, + extract(epoch from checkin_time) as checkin_ts, + extract(epoch from sched_departure) as sched_dep_ts, + extract(epoch from real_departure) as real_dep_ts, + checkin_station_id as dep_eva, + dep_station.ds100 as dep_ds100, + dep_station.name as dep_name, + dep_station.lat as dep_lat, + dep_station.lon as dep_lon, + extract(epoch from checkout_time) as checkout_ts, + extract(epoch from sched_arrival) as sched_arr_ts, + extract(epoch from real_arrival) as real_arr_ts, + checkout_station_id as arr_eva, + arr_station.ds100 as arr_ds100, + arr_station.name as arr_name, + arr_station.lat as arr_lat, + arr_station.lon as arr_lon, + polylines.polyline as polyline, + visibility, + coalesce(visibility, users.public_level & 127) as effective_visibility, + cancelled, edited, route, messages, user_data, + dep_platform, arr_platform + from journeys + left join polylines on polylines.id = polyline_id + left join users on users.id = user_id + left join stations as dep_station on checkin_station_id = dep_station.eva + left join stations as arr_station on checkout_station_id = arr_station.eva + left join backends as backend on backend_id = backend.id + ; + create view follows_in_transit as select + r1.subject_id as follower_id, user_id as followee_id, + users.name as followee_name, + train_type, train_line, train_no, train_id, + extract(epoch from checkin_time) as checkin_ts, + extract(epoch from sched_departure) as sched_dep_ts, + extract(epoch from real_departure) as real_dep_ts, + checkin_station_id as dep_eva, + dep_station.ds100 as dep_ds100, + dep_station.name as dep_name, + dep_station.lat as dep_lat, + dep_station.lon as dep_lon, + extract(epoch from checkout_time) as checkout_ts, + extract(epoch from sched_arrival) as sched_arr_ts, + extract(epoch from real_arrival) as real_arr_ts, + checkout_station_id as arr_eva, + arr_station.ds100 as arr_ds100, + arr_station.name as arr_name, + arr_station.lat as arr_lat, + arr_station.lon as arr_lon, + polyline_id, + polylines.polyline as polyline, + visibility, + coalesce(visibility, users.public_level & 127) as effective_visibility, + cancelled, route, messages, user_data, + dep_platform, arr_platform, data + from in_transit + left join polylines on polylines.id = polyline_id + left join users on users.id = user_id + left join relations as r1 on r1.predicate = 1 and r1.object_id = user_id + left join stations as dep_station on checkin_station_id = dep_station.eva + left join stations as arr_station on checkout_station_id = arr_station.eva + order by checkin_time desc + ; + update schema_version set version = 53; + } + ); + }, ); sub sync_stations { diff --git a/lib/Travelynx/Command/dumpstops.pm b/lib/Travelynx/Command/dumpstops.pm index e6740ec..c8ecd7a 100644 --- a/lib/Travelynx/Command/dumpstops.pm +++ b/lib/Travelynx/Command/dumpstops.pm @@ -8,7 +8,7 @@ use Mojo::Base 'Mojolicious::Command'; use List::Util qw(); use Text::CSV; -has description => 'Export HAFAS/IRIS stops to CSV'; +has description => 'Export known stops to CSV'; has usage => sub { shift->extract_usage }; diff --git a/lib/Travelynx/Command/traewelling.pm b/lib/Travelynx/Command/traewelling.pm index 4c47e84..ed40371 100644 --- a/lib/Travelynx/Command/traewelling.pm +++ b/lib/Travelynx/Command/traewelling.pm @@ -20,6 +20,12 @@ sub pull_sync { my $request_count = 0; for my $account_data ( $self->app->traewelling->get_pull_accounts ) { + if ( -e 'maintenance' ) { + $self->app->log->debug( + 'treawelling: "maintenance" file found, aborting'); + return; + } + my $in_transit = $self->app->in_transit->get( uid => $account_data->{user_id}, ); @@ -30,6 +36,13 @@ sub pull_sync { next; } + if ( not defined $account_data->{data}{user_name} ) { + $self->app->log->debug( +"travelynx user $account_data->{user_id} has a Traewellig connection, but no username" + ); + next; + } + # $account_data->{user_id} is the travelynx uid # $account_data->{user_name} is the Träwelling username $request_count += 1; @@ -39,7 +52,7 @@ sub pull_sync { # In 'work', the event loop is not running, # so there's no need to multiply by $request_count at the moment - Mojo::Promise->timer(1)->then( + Mojo::Promise->timer(1.5)->then( sub { return $self->app->traewelling_api->get_status_p( username => $account_data->{data}{user_name}, @@ -77,6 +90,13 @@ sub push_sync { my %push_result; for my $candidate ( $self->app->traewelling->get_pushable_accounts ) { + + if ( -e 'maintenance' ) { + $self->app->log->debug( + 'treawelling: "maintenance" file found, aborting'); + return; + } + $self->app->log->debug( "Pushing to Traewelling for UID $candidate->{uid}"); my $trip_id = $candidate->{journey_data}{trip_id}; @@ -121,6 +141,12 @@ sub run { my $push_result; my $pull_result; + if ( -e 'maintenance' ) { + $self->app->log->debug( + 'treawelling: "maintenance" file found, aborting'); + return; + } + if ( not $direction or $direction eq 'push' ) { $push_result = $self->push_sync; } @@ -133,6 +159,12 @@ sub run { my $trwl_pull_finished_at = DateTime->now( time_zone => 'Europe/Berlin' ); + if ( -e 'maintenance' ) { + $self->app->log->debug( + 'treawelling: "maintenance" file found, aborting'); + return; + } + my $trwl_push_duration = $trwl_push_finished_at->epoch - $started_at->epoch; my $trwl_pull_duration = $trwl_pull_finished_at->epoch - $trwl_push_finished_at->epoch; diff --git a/lib/Travelynx/Command/work.pm b/lib/Travelynx/Command/work.pm index 10b1b69..65fddc3 100644 --- a/lib/Travelynx/Command/work.pm +++ b/lib/Travelynx/Command/work.pm @@ -21,6 +21,11 @@ sub run { my $checkin_deadline = $now->clone->subtract( hours => 48 ); my $json = JSON->new; + if ( -e 'maintenance' ) { + $self->app->log->debug('work: "maintenance" file found, aborting'); + return; + } + my $num_incomplete = $self->app->in_transit->delete_incomplete_checkins( earlier_than => $checkin_deadline ); @@ -32,6 +37,11 @@ sub run { for my $entry ( $self->app->in_transit->get_all_active ) { + if ( -e 'maintenance' ) { + $self->app->log->debug('work: "maintenance" file found, aborting'); + return; + } + my $uid = $entry->{user_id}; my $dep = $entry->{dep_eva}; my $arr = $entry->{arr_eva}; @@ -60,7 +70,7 @@ sub run { return; } - if ( $found_dep->{rt_dep} ) { + if ( $found_dep->rt_dep ) { $self->app->in_transit->update_departure_hafas( uid => $uid, journey => $journey, @@ -68,9 +78,17 @@ sub run { dep_eva => $dep, arr_eva => $arr ); + if ( $journey->class <= 16 + and $found_dep->rt_dep->epoch > $now->epoch ) + { + $self->app->add_wagonorder( $uid, 1, $train_id, + $found_dep->sched_dep, $journey->number ); + $self->app->add_stationinfo( $uid, 1, $journey->id, + $found_dep->loc->eva ); + } } - if ( $found_arr and $found_arr->{rt_arr} ) { + if ( $found_arr and $found_arr->rt_arr ) { $self->app->in_transit->update_arrival_hafas( uid => $uid, journey => $journey, @@ -78,6 +96,14 @@ sub run { dep_eva => $dep, arr_eva => $arr ); + if ( $journey->class <= 16 + and $found_arr->rt_arr->epoch - $now->epoch < 600 ) + { + $self->app->add_wagonorder( $uid, 0, $train_id, + $found_dep->sched_dep, $journey->number ); + $self->app->add_stationinfo( $uid, 0, $journey->id, + $found_dep->loc->eva, $found_arr->loc->eva ); + } } } )->catch( @@ -171,6 +197,10 @@ sub run { } else { $self->app->add_route_timestamps( $uid, $train, 1 ); + $self->app->add_wagonorder( $uid, 1, $train->train_id, + $train->sched_departure, $train->train_no ); + $self->app->add_stationinfo( $uid, 1, $train->train_id, + $dep, $arr ); } } }; @@ -243,6 +273,10 @@ sub run { and $now->epoch > $entry->{real_arr_ts} ) ? 1 : 0 ); + $self->app->add_wagonorder( $uid, 0, $train->train_id, + $train->sched_departure, $train->train_no ); + $self->app->add_stationinfo( $uid, 0, $train->train_id, + $dep, $arr ); } } elsif ( $entry->{real_arr_ts} ) { diff --git a/lib/Travelynx/Controller/Account.pm b/lib/Travelynx/Controller/Account.pm index f1dc43e..5c101b1 100644 --- a/lib/Travelynx/Controller/Account.pm +++ b/lib/Travelynx/Controller/Account.pm @@ -831,29 +831,6 @@ sub insight { } -sub services { - my ($self) = @_; - my $user = $self->current_user; - - if ( $self->param('action') and $self->param('action') eq 'save' ) { - my $sb = $self->param('stationboard'); - my $value = 0; - if ( $sb =~ m{ ^ \d+ $ }x and $sb >= 0 and $sb <= 4 ) { - $value = int($sb); - } - $self->users->use_external_services( - uid => $user->{id}, - set => $value - ); - $self->flash( success => 'external' ); - $self->redirect_to('account'); - } - - $self->param( stationboard => - $self->users->use_external_services( uid => $user->{id} ) ); - $self->render('use_external_links'); -} - sub webhook { my ($self) = @_; diff --git a/lib/Travelynx/Controller/Profile.pm b/lib/Travelynx/Controller/Profile.pm index a063c10..a5f394f 100755 --- a/lib/Travelynx/Controller/Profile.pm +++ b/lib/Travelynx/Controller/Profile.pm @@ -152,34 +152,45 @@ sub profile { @journeys = $self->journeys->get(%opt); } - $self->render( - 'profile', - title => "travelynx: $name", - name => $name, - uid => $user->{id}, - privacy => $user, - bio => $profile->{bio}{html}, - metadata => $profile->{metadata}, - is_self => $is_self, - following => ( $relation and $relation eq 'follows' ) ? 1 : 0, - follow_requested => ( $relation and $relation eq 'requests_follow' ) - ? 1 - : 0, - can_follow => ( $my_user and $user->{accept_follows} and not $relation ) - ? 1 - : 0, - can_request_follow => - ( $my_user and $user->{accept_follow_requests} and not $relation ) - ? 1 - : 0, - follows_me => ( $inverse_relation and $inverse_relation eq 'follows' ) - ? 1 - : 0, - follow_reqs_me => - ( $inverse_relation and $inverse_relation eq 'requests_follow' ) ? 1 - : 0, - journey => $status, - journeys => [@journeys], + $self->respond_to( + json => { + json => { + name => $name, + uid => $user->{id}, + bio => $profile->{bio}{html}, + metadata => $profile->{metadata}, + } + }, + any => { + template => 'profile', + title => "travelynx: $name", + name => $name, + uid => $user->{id}, + privacy => $user, + bio => $profile->{bio}{html}, + metadata => $profile->{metadata}, + is_self => $is_self, + following => ( $relation and $relation eq 'follows' ) ? 1 : 0, + follow_requested => ( $relation and $relation eq 'requests_follow' ) + ? 1 + : 0, + can_follow => + ( $my_user and $user->{accept_follows} and not $relation ) ? 1 + : 0, + can_request_follow => ( + $my_user and $user->{accept_follow_requests} and not $relation + ) ? 1 + : 0, + follows_me => + ( $inverse_relation and $inverse_relation eq 'follows' ) ? 1 + : 0, + follow_reqs_me => ( + $inverse_relation and $inverse_relation eq 'requests_follow' + ) ? 1 + : 0, + journey => $status, + journeys => [@journeys], + } ); } @@ -334,7 +345,16 @@ sub user_status { my $user = $self->users->get_privacy_by( name => $name ); if ( not $user ) { - $self->render( 'not_found', status => 404 ); + $self->respond_to( + json => { + json => { error => 'not found' }, + status => 404, + }, + any => { + template => 'not_found', + status => 404 + } + ); return; } @@ -389,11 +409,29 @@ sub user_status { "/p/${name}/j/$journey->{id}?token=${token}-${ts}"); } else { - $self->render( 'not_found', status => 404 ); + $self->respond_to( + json => { + json => { error => 'not found' }, + status => 404, + }, + any => { + template => 'not_found', + status => 404 + } + ); } return; } - $self->render( 'not_found', status => 404 ); + $self->respond_to( + json => { + json => { error => 'not found' }, + status => 404, + }, + any => { + template => 'not_found', + status => 404 + } + ); return; } diff --git a/lib/Travelynx/Controller/Traveling.pm b/lib/Travelynx/Controller/Traveling.pm index 89385e1..f9bc2d5 100755 --- a/lib/Travelynx/Controller/Traveling.pm +++ b/lib/Travelynx/Controller/Traveling.pm @@ -604,7 +604,7 @@ sub geolocation { name => $_->name, eva => $_->eva, distance => $_->distance_m / 1000, - hafas => 1 + hafas => 'DB' } } $hafas->results; if ( @hafas > 10 ) { @@ -714,7 +714,7 @@ sub travel_action { if ( my $destination = $params->{dest} ) { my $station_link = '/s/' . $destination; if ( $status->{train_id} =~ m{[|]} ) { - $station_link .= '?hafas=1'; + $station_link .= '?hafas=DB'; } $self->render( json => { @@ -750,7 +750,7 @@ sub travel_action { my ( $still_checked_in, $error ) = @_; my $station_link = '/s/' . $params->{station}; if ( $status->{train_id} =~ m{[|]} ) { - $station_link .= '?hafas=1'; + $station_link .= '?hafas=DB'; } if ($error) { @@ -801,7 +801,7 @@ sub travel_action { my $redir = '/'; if ( $status->{checked_in} or $status->{cancelled} ) { if ( $status->{train_id} =~ m{[|]} ) { - $redir = '/s/' . $status->{dep_eva} . '?hafas=1'; + $redir = '/s/' . $status->{dep_eva} . '?hafas=DB'; } else { $redir = '/s/' . $status->{dep_ds100}; @@ -999,7 +999,7 @@ sub station { } else { - $api_link = '/s/' . $status->{station_eva} . '?hafas=1'; + $api_link = '/s/' . $status->{station_eva} . '?hafas=DB'; # You can't check into a train which terminates here @results = grep { $_->departure } @{ $status->{results} }; @@ -1128,7 +1128,7 @@ sub station { my @suggestions = $hafas2->results; if ( @suggestions == 1 ) { $self->redirect_to( - '/s/' . $suggestions[0]->eva . '?hafas=1' ); + '/s/' . $suggestions[0]->eva . '?hafas=DB' ); } else { $self->render( @@ -1171,14 +1171,14 @@ sub redirect_to_station { if ( my $s = $self->app->stations->search($station) ) { if ( $s->{source} == 1 ) { - $self->redirect_to("/s/${station}?hafas=1"); + $self->redirect_to("/s/${station}?hafas=DB"); } else { $self->redirect_to("/s/${station}"); } } else { - $self->redirect_to("/s/${station}?hafas=1"); + $self->redirect_to("/s/${station}?hafas=DB"); } } @@ -1510,7 +1510,7 @@ sub year_in_review { if ( not @journeys ) { $self->render( 'not_found', - message => 'Keine Zugfahrten im angefragten Jahr gefunden.', + message => 'Keine Fahrten im angefragten Jahr gefunden.', status => 404 ); return; @@ -1583,7 +1583,7 @@ sub yearly_history { $self->render( 'not_found', status => 404, - message => 'Keine Zugfahrten im angefragten Jahr gefunden.' + message => 'Keine Fahrten im angefragten Jahr gefunden.' ); return; } @@ -1660,7 +1660,7 @@ sub monthly_history { if ( not @journeys ) { $self->render( 'not_found', - message => 'Keine Zugfahrten im angefragten Monat gefunden.', + message => 'Keine Fahrten im angefragten Monat gefunden.', status => 404 ); return; @@ -2112,6 +2112,7 @@ sub add_journey_form { $self->render( 'add_journey', with_autocomplete => 1, + status => 400, error => 'Zug muss als „Typ Nummer“ oder „Typ Linie Nummer“ eingegeben werden.' ); @@ -2126,6 +2127,7 @@ sub add_journey_form { $self->render( 'add_journey', with_autocomplete => 1, + status => 400, error => "${key}: Ungültiges Datums-/Zeitformat" ); return; @@ -2167,6 +2169,7 @@ sub add_journey_form { $self->render( 'add_journey', with_autocomplete => 1, + status => 400, error => $error, ); } diff --git a/lib/Travelynx/Helper/DBDB.pm b/lib/Travelynx/Helper/DBDB.pm index b98a372..da3bfb1 100644 --- a/lib/Travelynx/Helper/DBDB.pm +++ b/lib/Travelynx/Helper/DBDB.pm @@ -31,14 +31,18 @@ sub has_wagonorder_p { my $api_ts = $ts->strftime('%Y%m%d%H%M'); my $url = "https://ist-wr.noncd.db.de/wagenreihung/1.0/${train_no}/${api_ts}"; - my $cache = $self->{cache}; + my $cache = $self->{realtime_cache}; my $promise = Mojo::Promise->new; if ( my $content = $cache->get("HEAD $url") ) { if ( $content eq 'n' ) { + $self->{log} + ->debug("has_wagonorder_p(${train_no}/${api_ts}): n (cached)"); return $promise->reject; } else { + $self->{log} + ->debug("has_wagonorder_p(${train_no}/${api_ts}): y (cached)"); return $promise->resolve($content); } } @@ -48,10 +52,14 @@ sub has_wagonorder_p { sub { my ($tx) = @_; if ( $tx->result->is_success ) { + $self->{log} + ->debug("has_wagonorder_p(${train_no}/${api_ts}): a"); $cache->set( "HEAD $url", 'a' ); $promise->resolve('a'); } else { + $self->{log} + ->debug("has_wagonorder_p(${train_no}/${api_ts}): n"); $cache->set( "HEAD $url", 'n' ); $promise->reject; } @@ -59,6 +67,7 @@ sub has_wagonorder_p { } )->catch( sub { + $self->{log}->debug("has_wagonorder_p(${train_no}/${api_ts}): n"); $cache->set( "HEAD $url", 'n' ); $promise->reject; return; @@ -73,10 +82,12 @@ sub get_wagonorder_p { my $url = "https://ist-wr.noncd.db.de/wagenreihung/1.0/${train_no}/${api_ts}"; - my $cache = $self->{cache}; + my $cache = $self->{realtime_cache}; my $promise = Mojo::Promise->new; if ( my $content = $cache->thaw($url) ) { + $self->{log} + ->debug("get_wagonorder_p(${train_no}/${api_ts}): (cached)"); $promise->resolve($content); return $promise; } @@ -89,11 +100,15 @@ sub get_wagonorder_p { if ( $tx->result->is_success ) { my $body = decode( 'utf-8', $tx->res->body ); my $json = JSON->new->decode($body); + $self->{log} + ->debug("get_wagonorder_p(${train_no}/${api_ts}): success"); $cache->freeze( $url, $json ); $promise->resolve($json); } else { my $code = $tx->code; + $self->{log}->debug( + "get_wagonorder_p(${train_no}/${api_ts}): HTTP ${code}"); $promise->reject("HTTP ${code}"); } return; @@ -101,6 +116,8 @@ sub get_wagonorder_p { )->catch( sub { my ($err) = @_; + $self->{log} + ->debug("get_wagonorder_p(${train_no}/${api_ts}): error ${err}"); $promise->reject($err); return; } @@ -113,10 +130,11 @@ sub get_stationinfo_p { my $url = "https://lib.finalrewind.org/dbdb/s/${eva}.json"; - my $cache = $self->{cache}; + my $cache = $self->{main_cache}; my $promise = Mojo::Promise->new; if ( my $content = $cache->thaw($url) ) { + $self->{log}->debug("get_stationinfo_p(${eva}): (cached)"); return $promise->resolve($content); } @@ -126,12 +144,16 @@ sub get_stationinfo_p { my ($tx) = @_; if ( my $err = $tx->error ) { + $self->{log}->debug( +"get_stationinfo_p(${eva}): HTTP $err->{code} $err->{message}" + ); $cache->freeze( $url, {} ); $promise->reject("HTTP $err->{code} $err->{message}"); return; } my $json = $tx->result->json; + $self->{log}->debug("get_stationinfo_p(${eva}): success"); $cache->freeze( $url, $json ); $promise->resolve($json); return; @@ -139,6 +161,7 @@ sub get_stationinfo_p { )->catch( sub { my ($err) = @_; + $self->{log}->debug("get_stationinfo_p(${eva}): Error ${err}"); $cache->freeze( $url, {} ); $promise->reject($err); return; diff --git a/lib/Travelynx/Helper/HAFAS.pm b/lib/Travelynx/Helper/HAFAS.pm index 7671d78..538c8ea 100644 --- a/lib/Travelynx/Helper/HAFAS.pm +++ b/lib/Travelynx/Helper/HAFAS.pm @@ -199,7 +199,7 @@ sub get_journey_p { return $promise; } -sub get_route_timestamps_p { +sub get_route_p { my ( $self, %opt ) = @_; my $promise = Mojo::Promise->new; @@ -219,13 +219,12 @@ sub get_route_timestamps_p { sub { my ($hafas) = @_; my $journey = $hafas->result; - my $ret = {}; + my $ret = []; my $polyline; my $station_is_past = 1; for my $stop ( $journey->route ) { - my $name = $stop->loc->name; - $ret->{$name} = $ret->{ $stop->loc->eva } = { + my $entry = { name => $stop->loc->name, eva => $stop->loc->eva, sched_arr => _epoch( $stop->sched_arr ), @@ -237,26 +236,27 @@ sub get_route_timestamps_p { load => $stop->load }; if ( $stop->tz_offset ) { - $ret->{$name}{tz_offset} = $stop->tz_offset; + $entry->{tz_offset} = $stop->tz_offset; } if ( ( $stop->arr_cancelled or not $stop->sched_arr ) and ( $stop->dep_cancelled or not $stop->sched_dep ) ) { - $ret->{$name}{isCancelled} = 1; + $entry->{isCancelled} = 1; } if ( $station_is_past - and not $ret->{$name}{isCancelled} + and not $entry->{isCancelled} and $now->epoch < ( - $ret->{$name}{rt_arr} // $ret->{$name}{rt_dep} - // $ret->{$name}{sched_arr} - // $ret->{$name}{sched_dep} // $now->epoch + $entry->{rt_arr} // $entry->{rt_dep} + // $entry->{sched_arr} // $entry->{sched_dep} + // $now->epoch ) ) { $station_is_past = 0; } - $ret->{$name}{isPast} = $station_is_past; + $entry->{isPast} = $station_is_past; + push( @{$ret}, $entry ); } if ( $journey->polyline ) { diff --git a/lib/Travelynx/Model/InTransit.pm b/lib/Travelynx/Model/InTransit.pm index 69026ac..6bafd93 100644 --- a/lib/Travelynx/Model/InTransit.pm +++ b/lib/Travelynx/Model/InTransit.pm @@ -47,6 +47,16 @@ sub epoch_to_dt { ); } +sub epoch_or_dt_to_dt { + my ($input) = @_; + + if ( ref($input) eq 'DateTime' ) { + return $input; + } + + return epoch_to_dt($input); +} + sub new { my ( $class, %opt ) = @_; @@ -88,10 +98,13 @@ sub add { my $stop = $opt{stop}; my $checkin_station_id = $opt{departure_eva}; my $route = $opt{route}; + my $data = $opt{data}; my $json = JSON->new; if ($train) { + my $backend_id + = $db->select( 'backends', ['id'], { iris => 1 } )->hash->{id}; $db->insert( 'in_transit', { @@ -114,13 +127,23 @@ sub add { data => JSON->new->encode( { rt => $train->departure_has_realtime ? 1 - : 0 + : 0, + %{ $data // {} } } ), + backend_id => $backend_id, } ); } elsif ( $journey and $stop ) { + my $backend_id = $db->select( + 'backends', + ['id'], + { + hafas => 1, + name => 'DB' + } + )->hash->{id}; my @route; my $product = $journey->product_at( $stop->loc->eva ) // $journey->product; @@ -162,7 +185,13 @@ sub add { sched_departure => $stop->{sched_dep}, real_departure => $stop->{rt_dep} // $stop->{sched_dep}, route => $json->encode( \@route ), - data => JSON->new->encode( { rt => $stop->{rt_dep} ? 1 : 0 } ), + data => JSON->new->encode( + { + rt => $stop->{rt_dep} ? 1 : 0, + %{ $data // {} } + } + ), + backend_id => $backend_id, } ); } @@ -211,8 +240,15 @@ sub postprocess { if ($is_after) { push( @route_after, $station ); } - if ( $ret->{dep_name} - and $station->[0] eq $ret->{dep_name} ) + + # Note that the departure stop may be present more than once in @route, + # e.g. when traveling along ring lines such as S41 / S42 in Berlin. + if ( + $ret->{dep_name} + and $station->[0] eq $ret->{dep_name} + and not($station->[2]{sched_dep} + and $station->[2]{sched_dep} < $ret->{sched_dep_ts} ) + ) { $is_after = 1; if ( @{$station} > 1 and not $dep_info ) { @@ -273,31 +309,25 @@ sub postprocess { # station is present several times in a train's route, e.g. # for Frankfurt Flughafen in some nightly connections. my $times = $station->[2] // {}; - if ( $times->{sched_arr} - and ref( $times->{sched_arr} ) ne 'DateTime' ) - { - $times->{sched_arr} - = epoch_to_dt( $times->{sched_arr} ); - if ( $times->{rt_arr} ) { - $times->{rt_arr} - = epoch_to_dt( $times->{rt_arr} ); - $times->{arr_delay} - = $times->{rt_arr}->epoch - $times->{sched_arr}->epoch; + for my $key (qw(sched_arr rt_arr sched_dep rt_dep)) { + if ( $times->{$key} ) { + $times->{$key} + = epoch_or_dt_to_dt( $times->{$key} ); } + } + if ( $times->{sched_arr} and $times->{rt_arr} ) { + $times->{arr_delay} + = $times->{rt_arr}->epoch - $times->{sched_arr}->epoch; + } + if ( $times->{sched_arr} or $times->{rt_arr} ) { $times->{arr} = $times->{rt_arr} || $times->{sched_arr}; $times->{arr_countdown} = $times->{arr}->epoch - $epoch; } - if ( $times->{sched_dep} - and ref( $times->{sched_dep} ) ne 'DateTime' ) - { - $times->{sched_dep} - = epoch_to_dt( $times->{sched_dep} ); - if ( $times->{rt_dep} ) { - $times->{rt_dep} - = epoch_to_dt( $times->{rt_dep} ); - $times->{dep_delay} - = $times->{rt_dep}->epoch - $times->{sched_dep}->epoch; - } + if ( $times->{sched_dep} and $times->{rt_dep} ) { + $times->{dep_delay} + = $times->{rt_dep}->epoch - $times->{sched_dep}->epoch; + } + if ( $times->{sched_dep} or $times->{rt_dep} ) { $times->{dep} = $times->{rt_dep} || $times->{sched_dep}; $times->{dep_countdown} = $times->{dep}->epoch - $epoch; } @@ -566,7 +596,8 @@ sub set_polyline { $self->set_polyline_id( uid => $uid, db => $db, - polyline_id => $polyline_id + polyline_id => $polyline_id, + train_id => $opt{train_id}, ); } @@ -579,11 +610,13 @@ sub set_polyline_id { my $db = $opt{db} // $self->{pg}->db; my $polyline_id = $opt{polyline_id}; - $db->update( - 'in_transit', - { polyline_id => $polyline_id }, - { user_id => $uid } - ); + my %where = ( user_id => $uid ); + + if ( $opt{train_id} ) { + $where{train_id} = $opt{train_id}; + } + + $db->update( 'in_transit', { polyline_id => $polyline_id }, \%where ); } sub set_route_data { @@ -596,6 +629,12 @@ sub set_route_data { my $qos_msg = $opt{qos_messages}; my $him_msg = $opt{him_messages}; + my %where = ( user_id => $uid ); + + if ( $opt{train_id} ) { + $where{train_id} = $opt{train_id}; + } + my $res_h = $db->select( 'in_transit', ['data'], { user_id => $uid } ) ->expand->hash; @@ -612,7 +651,7 @@ sub set_route_data { route => JSON->new->encode($route), data => JSON->new->encode($data) }, - { user_id => $uid } + \%where ); } @@ -839,6 +878,12 @@ sub update_data { my $db = $opt{db} // $self->{pg}->db; my $new_data = $opt{data} // {}; + my %where = ( user_id => $uid ); + + if ( $opt{train_id} ) { + $where{train_id} = $opt{train_id}; + } + my $res_h = $db->select( 'in_transit', ['data'], { user_id => $uid } ) ->expand->hash; @@ -848,11 +893,7 @@ sub update_data { $data->{$k} = $v; } - $db->update( - 'in_transit', - { data => JSON->new->encode($data) }, - { user_id => $uid } - ); + $db->update( 'in_transit', { data => JSON->new->encode($data) }, \%where ); } sub update_user_data { @@ -862,6 +903,12 @@ sub update_user_data { my $db = $opt{db} // $self->{pg}->db; my $new_data = $opt{user_data} // {}; + my %where = ( user_id => $uid ); + + if ( $opt{train_id} ) { + $where{train_id} = $opt{train_id}; + } + my $res_h = $db->select( 'in_transit', ['user_data'], { user_id => $uid } ) ->expand->hash; @@ -871,11 +918,8 @@ sub update_user_data { $data->{$k} = $v; } - $db->update( - 'in_transit', - { user_data => JSON->new->encode($data) }, - { user_id => $uid } - ); + $db->update( 'in_transit', + { user_data => JSON->new->encode($data) }, \%where ); } sub update_visibility { diff --git a/lib/Travelynx/Model/Journeys.pm b/lib/Travelynx/Model/Journeys.pm index 97c4681..424430c 100755 --- a/lib/Travelynx/Model/Journeys.pm +++ b/lib/Travelynx/Model/Journeys.pm @@ -218,6 +218,7 @@ sub add { edited => 0x3fff, cancelled => $opt{cancelled} ? 1 : 0, route => JSON->new->encode( \@route ), + backend_id => 1, }; if ( $opt{comment} ) { @@ -515,7 +516,7 @@ sub get { my @select = ( - qw(journey_id train_type train_line train_no checkin_ts sched_dep_ts real_dep_ts dep_eva dep_ds100 dep_name dep_lat dep_lon checkout_ts sched_arr_ts real_arr_ts arr_eva arr_ds100 arr_name arr_lat arr_lon cancelled edited route messages user_data visibility effective_visibility) + qw(journey_id is_iris is_hafas backend_name train_type train_line train_no checkin_ts sched_dep_ts real_dep_ts dep_eva dep_ds100 dep_name dep_lat dep_lon checkout_ts sched_arr_ts real_arr_ts arr_eva arr_ds100 arr_name arr_lat arr_lon cancelled edited route messages user_data visibility effective_visibility) ); my %where = ( user_id => $uid, @@ -573,6 +574,9 @@ sub get { my $ref = { id => $entry->{journey_id}, + is_iris => $entry->{is_iris}, + is_hafas => $entry->{is_hafas}, + backend_name => $entry->{backend_name}, type => $entry->{train_type}, line => $entry->{train_line}, no => $entry->{train_no}, @@ -823,7 +827,7 @@ sub get_latest_checkout_stations { { name => $row->{arr_name}, eva => $row->{arr_eva}, - hafas => ( $row->{train_id} =~ m{[|]} ? 1 : 0 ), + hafas => ( $row->{train_id} =~ m{[|]} ? 'DB' : 0 ), } ); } diff --git a/lib/Travelynx/Model/Users.pm b/lib/Travelynx/Model/Users.pm index 4602fa2..4d90d92 100644 --- a/lib/Travelynx/Model/Users.pm +++ b/lib/Travelynx/Model/Users.pm @@ -40,14 +40,6 @@ my %predicate_atoi = ( is_blocked_by => 3, ); -my @sb_templates = ( - undef, - [ 'DBF', 'https://dbf.finalrewind.org/{name}?rt=1#{tt}{tn}' ], - [ 'bahn.expert', 'https://bahn.expert/{name}#{id}' ], - [ 'DBF HAFAS', 'https://dbf.finalrewind.org/{name}?rt=1&hafas=1#{tt}{tn}' ], - [ 'bahn.expert/regional', 'https://bahn.expert/regional/{name}#{id}' ], -); - my %token_id = ( status => 1, history => 2, @@ -411,7 +403,7 @@ sub get { my $user = $db->select( 'users', 'id, name, status, public_level, email, ' - . 'external_services, accept_follows, notifications, ' + . 'accept_follows, notifications, ' . 'extract(epoch from registered_at) as registered_at_ts, ' . 'extract(epoch from last_seen) as last_seen_ts, ' . 'extract(epoch from deletion_requested) as deletion_requested_ts', @@ -435,12 +427,8 @@ sub get { past_status => $user->{public_level} & 0x08000 ? 1 : 0, past_all => $user->{public_level} & 0x10000 ? 1 : 0, email => $user->{email}, - sb_name => $user->{external_services} - ? $sb_templates[ $user->{external_services} & 0x07 ][0] - : undef, - sb_template => $user->{external_services} - ? $sb_templates[ $user->{external_services} & 0x07 ][1] - : undef, + sb_template => + 'https://dbf.finalrewind.org/{name}?rt=1&hafas={hafas}#{tt}{tn}', registered_at => DateTime->from_epoch( epoch => $user->{registered_at_ts}, time_zone => 'Europe/Berlin' @@ -659,24 +647,6 @@ sub use_history { } } -sub use_external_services { - my ( $self, %opt ) = @_; - my $db = $opt{db} // $self->{pg}->db; - my $uid = $opt{uid}; - my $value = $opt{set}; - - if ( defined $value ) { - if ( $value < 0 or $value > 4 ) { - $value = 0; - } - $db->update( 'users', { external_services => $value }, { id => $uid } ); - } - else { - return $db->select( 'users', ['external_services'], { id => $uid } ) - ->hash->{external_services}; - } -} - sub get_webhook { my ( $self, %opt ) = @_; my $db = $opt{db} // $self->{pg}->db; |