Unverified Commit 138dd87a authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

Incorporate dbdb into travelynx

parent ec60d908
Loading
Loading
Loading
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
Original line number Diff line number Diff line
Subproject commit eacf5450dd79def235232e452ee8d9a1f700af9a
+25 −51
Original line number Diff line number Diff line
@@ -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;
@@ -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) = @_;
@@ -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,
@@ -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,
@@ -2192,12 +2172,6 @@ sub startup {
					);
					return;
				}
				)->catch(
					sub {
						# no stationinfo? no problem.
						return;
					}
				)->wait;
			}
		}
	);
+88 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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 ) = @_;

lib/Travelynx/Helper/DBDB.pm

deleted100644 → 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