Loading .gitmodules 0 → 100644 +3 −0 Original line number Diff line number Diff line [submodule "ext/dbdb"] path = ext/dbdb url = https://github.com/derf/train-platform-directions.git dbdb @ eacf5450 Original line number Diff line number Diff line Subproject commit eacf5450dd79def235232e452ee8d9a1f700af9a lib/Travelynx.pm +25 −51 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ use List::Util; use List::UtilsBy qw(uniq_by); use List::MoreUtils qw(first_index); use Travel::Status::DE::DBRIS::Formation; use Travelynx::Helper::DBDB; use Travelynx::Helper::DBRIS; use Travelynx::Helper::EFA; use Travelynx::Helper::HAFAS; Loading Loading @@ -409,20 +408,6 @@ sub startup { } ); $self->helper( dbdb => sub { my ($self) = @_; state $dbdb = Travelynx::Helper::DBDB->new( 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}, ); } ); $self->helper( loc_handle => sub { my ($self) = @_; Loading Loading @@ -2157,10 +2142,10 @@ sub startup { my $db = $self->pg->db; if ($is_departure) { $self->dbdb->get_stationinfo_p($dep_eva)->then( sub { my ($station_info) = @_; my $data = { stationinfo_dep => $station_info }; if ( my $si = $self->stations->get_bahn_stationinfo( eva => $dep_eva ) ) { my $data = { stationinfo_dep => $si }; $self->in_transit->update_data( uid => $uid, Loading @@ -2170,19 +2155,14 @@ sub startup { ); return; } )->catch( sub { # no stationinfo? no problem. return; } )->wait; } 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 }; if ( my $si = $self->stations->get_bahn_stationinfo( eva => $arr_eva ) ) { my $data = { stationinfo_arr => $si }; $self->in_transit->update_data( uid => $uid, Loading @@ -2192,12 +2172,6 @@ sub startup { ); return; } )->catch( sub { # no stationinfo? no problem. return; } )->wait; } } ); Loading lib/Travelynx/Command/database.pm +88 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ package Travelynx::Command::database; use Mojo::Base 'Mojolicious::Command'; use DateTime; use File::Slurp qw(read_file); use File::Slurp qw(read_dir read_file); use List::Util qw(); use JSON; use Travel::Status::DE::EFA; Loading Loading @@ -3535,8 +3535,95 @@ qq{select distinct checkout_station_id from in_transit where backend_id = 0;} } ); }, # v68 -> v69 # Incorporate dbdb (entry/exit direction) data into travelynx # This avoids having to make web requests to lib.finalrewind.org/dbdb, # and allows for also showing the exit direction for intermediate stops. sub { my ($db) = @_; $db->query( qq{ alter table schema_version add column dbdb varchar(12); create table bahn_platform_directions ( eva integer primary key, data jsonb not null ); } ); sync_dbdb($db); $db->query( qq{ update schema_version set version = 69; update schema_version set dbdb = '2025-10-27'; } ); }, ); sub sync_dbdb { my ($db) = @_; my $json = JSON->new; for my $file ( read_dir( 'ext/dbdb/s', prefix => 1 ) ) { if ( $file !~ m{\.txt$} ) { next; } my %station; for my $line ( read_file( $file, { binmode => ':encoding(utf-8)' } ) ) { if ( $line =~ m{ ^ \s* (?<platform> \d+ ) \s+ (?<type> \S+ ) \s+ (?<direction> \S+ ) }x ) { $station{ $+{platform} } = { kopfgleis => $+{type} eq 'K' ? \1 : \0, direction => $+{direction}, }; } elsif ( $line =~ m{ ^ @ \s* (?<stations> [^:]+ ) : \s* (?<platforms> .+ ) $ }x ) { my $stations_raw = $+{stations}; my $platforms_raw = $+{platforms}; my @stations = split( qr{, }, $stations_raw ); my @platforms = split( qr{, }, $platforms_raw ); for my $platform (@platforms) { my ( $number, $direction ) = split( qr{ }, $platform ); for my $from_station (@stations) { $station{$number}{direction_from}{$from_station} = $direction; } } } } my ($station_name) = ( $file =~ m{ s / ([^.]*) . txt $ }x ); my ($station) = Travel::Status::DE::IRIS::Stations::get_station($station_name); if ( $station and $station->[0] eq $station_name ) { $db->insert( 'bahn_platform_directions', { eva => $station->[2], data => $json->encode( \%station ) }, { on_conflict => \'(eva) do update set data = EXCLUDED.data' } ); } elsif ( not $station ) { say STDERR "DBDB import: unknown station: $station_name"; } else { say STDERR "DBDB import: station mismatch: wanted to import $station_name, but got " . $station->[0]; } } } sub sync_stations { my ( $db, $iris_version ) = @_; Loading lib/Travelynx/Helper/DBDB.pmdeleted 100644 → 0 +0 −76 Original line number Diff line number Diff line package Travelynx::Helper::DBDB; # Copyright (C) 2020-2023 Birte Kristina Friesel # # SPDX-License-Identifier: AGPL-3.0-or-later use strict; use warnings; use 5.020; use Encode qw(decode); use Mojo::Promise; use Mojo::UserAgent; use JSON; 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_stationinfo_p { my ( $self, $eva ) = @_; my $url = "https://lib.finalrewind.org/dbdb/s/${eva}.json"; 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); } $self->{user_agent}->request_timeout(5) ->get_p( $url => $self->{header} ) ->then( sub { 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; } )->catch( sub { my ($err) = @_; $self->{log}->debug("get_stationinfo_p(${eva}): Error ${err}"); $cache->freeze( $url, {} ); $promise->reject($err); return; } )->wait; return $promise; } 1; Loading
.gitmodules 0 → 100644 +3 −0 Original line number Diff line number Diff line [submodule "ext/dbdb"] path = ext/dbdb url = https://github.com/derf/train-platform-directions.git
dbdb @ eacf5450 Original line number Diff line number Diff line Subproject commit eacf5450dd79def235232e452ee8d9a1f700af9a
lib/Travelynx.pm +25 −51 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ use List::Util; use List::UtilsBy qw(uniq_by); use List::MoreUtils qw(first_index); use Travel::Status::DE::DBRIS::Formation; use Travelynx::Helper::DBDB; use Travelynx::Helper::DBRIS; use Travelynx::Helper::EFA; use Travelynx::Helper::HAFAS; Loading Loading @@ -409,20 +408,6 @@ sub startup { } ); $self->helper( dbdb => sub { my ($self) = @_; state $dbdb = Travelynx::Helper::DBDB->new( 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}, ); } ); $self->helper( loc_handle => sub { my ($self) = @_; Loading Loading @@ -2157,10 +2142,10 @@ sub startup { my $db = $self->pg->db; if ($is_departure) { $self->dbdb->get_stationinfo_p($dep_eva)->then( sub { my ($station_info) = @_; my $data = { stationinfo_dep => $station_info }; if ( my $si = $self->stations->get_bahn_stationinfo( eva => $dep_eva ) ) { my $data = { stationinfo_dep => $si }; $self->in_transit->update_data( uid => $uid, Loading @@ -2170,19 +2155,14 @@ sub startup { ); return; } )->catch( sub { # no stationinfo? no problem. return; } )->wait; } 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 }; if ( my $si = $self->stations->get_bahn_stationinfo( eva => $arr_eva ) ) { my $data = { stationinfo_arr => $si }; $self->in_transit->update_data( uid => $uid, Loading @@ -2192,12 +2172,6 @@ sub startup { ); return; } )->catch( sub { # no stationinfo? no problem. return; } )->wait; } } ); Loading
lib/Travelynx/Command/database.pm +88 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ package Travelynx::Command::database; use Mojo::Base 'Mojolicious::Command'; use DateTime; use File::Slurp qw(read_file); use File::Slurp qw(read_dir read_file); use List::Util qw(); use JSON; use Travel::Status::DE::EFA; Loading Loading @@ -3535,8 +3535,95 @@ qq{select distinct checkout_station_id from in_transit where backend_id = 0;} } ); }, # v68 -> v69 # Incorporate dbdb (entry/exit direction) data into travelynx # This avoids having to make web requests to lib.finalrewind.org/dbdb, # and allows for also showing the exit direction for intermediate stops. sub { my ($db) = @_; $db->query( qq{ alter table schema_version add column dbdb varchar(12); create table bahn_platform_directions ( eva integer primary key, data jsonb not null ); } ); sync_dbdb($db); $db->query( qq{ update schema_version set version = 69; update schema_version set dbdb = '2025-10-27'; } ); }, ); sub sync_dbdb { my ($db) = @_; my $json = JSON->new; for my $file ( read_dir( 'ext/dbdb/s', prefix => 1 ) ) { if ( $file !~ m{\.txt$} ) { next; } my %station; for my $line ( read_file( $file, { binmode => ':encoding(utf-8)' } ) ) { if ( $line =~ m{ ^ \s* (?<platform> \d+ ) \s+ (?<type> \S+ ) \s+ (?<direction> \S+ ) }x ) { $station{ $+{platform} } = { kopfgleis => $+{type} eq 'K' ? \1 : \0, direction => $+{direction}, }; } elsif ( $line =~ m{ ^ @ \s* (?<stations> [^:]+ ) : \s* (?<platforms> .+ ) $ }x ) { my $stations_raw = $+{stations}; my $platforms_raw = $+{platforms}; my @stations = split( qr{, }, $stations_raw ); my @platforms = split( qr{, }, $platforms_raw ); for my $platform (@platforms) { my ( $number, $direction ) = split( qr{ }, $platform ); for my $from_station (@stations) { $station{$number}{direction_from}{$from_station} = $direction; } } } } my ($station_name) = ( $file =~ m{ s / ([^.]*) . txt $ }x ); my ($station) = Travel::Status::DE::IRIS::Stations::get_station($station_name); if ( $station and $station->[0] eq $station_name ) { $db->insert( 'bahn_platform_directions', { eva => $station->[2], data => $json->encode( \%station ) }, { on_conflict => \'(eva) do update set data = EXCLUDED.data' } ); } elsif ( not $station ) { say STDERR "DBDB import: unknown station: $station_name"; } else { say STDERR "DBDB import: station mismatch: wanted to import $station_name, but got " . $station->[0]; } } } sub sync_stations { my ( $db, $iris_version ) = @_; Loading
lib/Travelynx/Helper/DBDB.pmdeleted 100644 → 0 +0 −76 Original line number Diff line number Diff line package Travelynx::Helper::DBDB; # Copyright (C) 2020-2023 Birte Kristina Friesel # # SPDX-License-Identifier: AGPL-3.0-or-later use strict; use warnings; use 5.020; use Encode qw(decode); use Mojo::Promise; use Mojo::UserAgent; use JSON; 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_stationinfo_p { my ( $self, $eva ) = @_; my $url = "https://lib.finalrewind.org/dbdb/s/${eva}.json"; 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); } $self->{user_agent}->request_timeout(5) ->get_p( $url => $self->{header} ) ->then( sub { 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; } )->catch( sub { my ($err) = @_; $self->{log}->debug("get_stationinfo_p(${eva}): Error ${err}"); $cache->freeze( $url, {} ); $promise->reject($err); return; } )->wait; return $promise; } 1;