Switch to new carriage formation API

This commit is contained in:
Birte Kristina Friesel 2024-08-08 21:13:39 +02:00
parent 7fb0d48d80
commit 45dc2e4e2a
No known key found for this signature in database
GPG key ID: 19E6E524EBB177BA
6 changed files with 191 additions and 102 deletions

View file

@ -14,7 +14,7 @@ requires 'Mojolicious::Plugin::OAuth2';
requires 'Mojo::Pg';
requires 'Text::CSV';
requires 'Text::Markdown';
requires 'Travel::Status::DE::DBWagenreihung', '== 0.12';
requires 'Travel::Status::DE::DBWagenreihung', '== 0.16';
requires 'Travel::Status::DE::HAFAS', '>= 5.03';
requires 'Travel::Status::DE::IRIS';
requires 'UUID::Tiny';

View file

@ -497,8 +497,15 @@ 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_wagonorder(
uid => $uid,
train_id => $train->train_id,
is_departure => 1,
eva => $eva,
datetime => $train->sched_departure,
train_type => $train->type,
train_no => $train->train_no
);
$self->add_stationinfo( $uid, 1, $train->train_id,
$eva );
$self->run_hook( $uid, 'checkin' );
@ -628,8 +635,15 @@ sub startup {
if ( not $opt{in_transaction} ) {
$self->run_hook( $uid, 'checkin' );
if ( $opt{hafas} eq 'DB' and $journey->class <= 16 ) {
$self->add_wagonorder( $uid, 1, $journey->id,
$found->sched_dep, $journey->number );
$self->add_wagonorder(
uid => $uid,
train_id => $journey->id,
is_departure => 1,
eva => $found->loc->eva,
datetime => $found->sched_dep,
train_type => $journey->type,
train_no => $journey->number
);
$self->add_stationinfo( $uid, 1, $journey->id,
$found->loc->eva );
}
@ -995,8 +1009,15 @@ 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_wagonorder(
uid => $uid,
train_id => $train->train_id,
is_arrival => 1,
eva => $new_checkout_station_id,
datetime => $train->sched_departure,
train_type => $train->type,
train_no => $train->train_no
);
$self->add_stationinfo( $uid, 0, $train->train_id,
$dep_eva, $new_checkout_station_id );
}
@ -1227,21 +1248,23 @@ sub startup {
$self->helper(
'add_wagonorder' => sub {
my ( $self, $uid, $is_departure, $train_id, $sched_departure,
$train_no )
= @_;
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $train_id = $opt{train_id};
my $train_type = $opt{train_type};
my $train_no = $opt{train_no};
my $eva = $opt{eva};
my $datetime = $opt{datetime};
$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(
if ( $datetime and $train_no ) {
$self->dbdb->has_wagonorder_p(%opt)->then(
sub {
my ($api) = @_;
return $self->dbdb->get_wagonorder_p( $api,
$sched_departure, $train_no );
return $self->dbdb->get_wagonorder_p(%opt);
}
)->then(
sub {
@ -1250,46 +1273,39 @@ sub startup {
my $data = {};
my $user_data = {};
if ( $is_departure and not exists $wagonorder->{error} )
if ( $opt{is_departure}
and not exists $wagonorder->{error} )
{
$data->{wagonorder_dep} = $wagonorder;
$user_data->{wagongroups} = [];
for my $group (
@{
$wagonorder->{data}{istformation}
{allFahrzeuggruppe} // []
}
)
{
for my $group ( @{ $wagonorder->{groups} // [] } ) {
my @wagons;
for
my $wagon ( @{ $group->{allFahrzeug} // [] } )
for my $wagon ( @{ $group->{vehicles} // [] } )
{
push(
@wagons,
{
id => $wagon->{fahrzeugnummer},
number =>
$wagon->{wagenordnungsnummer},
type => $wagon->{fahrzeugtyp},
id => $wagon->{vehicleID},
number => $wagon
->{wagonIdentificationNumber},
type =>
$wagon->{type}{constructionType},
}
);
}
push(
@{ $user_data->{wagongroups} },
{
name =>
$group->{fahrzeuggruppebezeichnung},
from =>
$group->{startbetriebsstellename},
to => $group->{zielbetriebsstellename},
no => $group->{verkehrlichezugnummer},
name => $group->{name},
to => $group->{transport}{destination}
{name},
type => $group->{transport}{category},
no => $group->{transport}{number},
wagons => [@wagons],
}
);
if ( $group->{fahrzeuggruppebezeichnung}
and $group->{fahrzeuggruppebezeichnung} eq
'ICE0304' )
if ( $group->{name}
and $group->{name} eq 'ICE0304' )
{
$data->{wagonorder_pride} = 1;
}
@ -1307,7 +1323,7 @@ sub startup {
train_id => $train_id,
);
}
elsif ( not $is_departure
elsif ( $opt{is_arrival}
and not exists $wagonorder->{error} )
{
$data->{wagonorder_arr} = $wagonorder;
@ -1580,10 +1596,10 @@ sub startup {
from_json => $wagonorder );
};
if ( $wr
and $wr->sections
and $wr->sectors
and defined $wr->direction )
{
my $section_0 = ( $wr->sections )[0];
my $section_0 = ( $wr->sectors )[0];
my $direction = $wr->direction;
if ( $section_0->name eq 'A'
and $direction == 0 )
@ -1726,7 +1742,7 @@ sub startup {
from_json => $in_transit->{data}{wagonorder_dep} );
};
if ( $wr
and $wr->wagons
and $wr->carriages
and defined $wr->direction )
{
$ret->{wagonorder} = $wr;

View file

@ -84,8 +84,15 @@ sub run {
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_wagonorder(
uid => $uid,
train_id => $journey->id,
is_departure => 1,
eva => $dep,
datetime => $found_dep->sched_dep,
train_type => $journey->type,
train_no => $journey->number,
);
$self->app->add_stationinfo( $uid, 1, $journey->id,
$found_dep->loc->eva );
}
@ -102,8 +109,15 @@ sub run {
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_wagonorder(
uid => $uid,
train_id => $journey->id,
is_arrival => 1,
eva => $arr,
datetime => $found_arr->sched_dep,
train_type => $journey->type,
train_no => $journey->number,
);
$self->app->add_stationinfo( $uid, 0, $journey->id,
$found_dep->loc->eva, $found_arr->loc->eva );
}
@ -203,8 +217,15 @@ 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_wagonorder(
uid => $uid,
train_id => $train->train_id,
is_departure => 1,
eva => $dep,
datetime => $train->sched_departure,
train_type => $train->type,
train_no => $train->train_no
);
$self->app->add_stationinfo( $uid, 1, $train->train_id,
$dep, $arr );
}
@ -279,8 +300,15 @@ 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_wagonorder(
uid => $uid,
train_id => $train->train_id,
is_arrival => 1,
eva => $arr,
datetime => $train->sched_departure,
train_type => $train->type,
train_no => $train->train_no
);
$self->app->add_stationinfo( $uid, 0, $train->train_id,
$dep, $arr );
}

View file

@ -27,39 +27,53 @@ sub new {
}
sub has_wagonorder_p {
my ( $self, $ts, $train_no ) = @_;
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 ( $self, %opt ) = @_;
my $datetime = $opt{datetime}->clone->set_time_zone('UTC');
my %param = (
administrationId => 80,
category => $opt{train_type},
date => $datetime->strftime('%Y-%m-%d'),
evaNumber => $opt{eva},
number => $opt{train_no},
time => $datetime->rfc3339 =~ s{(?=Z)}{.000}r
);
my $url = sprintf( '%s?%s',
'https://www.bahn.de/web/api/reisebegleitung/wagenreihung/vehicle-sequence',
join( '&', map { $_ . '=' . $param{$_} } keys %param ) );
my $cache = $self->{realtime_cache};
my $promise = Mojo::Promise->new;
my $debug_prefix
= "has_wagonorder_p($opt{train_type} $opt{train_no} @ $opt{eva})";
if ( my $content = $cache->get("HEAD $url") ) {
if ( $content eq 'n' ) {
$self->{log}
->debug("has_wagonorder_p(${train_no}/${api_ts}): n (cached)");
$self->{log}->debug("${debug_prefix}: n (cached)");
return $promise->reject;
}
else {
$self->{log}
->debug("has_wagonorder_p(${train_no}/${api_ts}): y (cached)");
$self->{log}->debug("${debug_prefix}: y (cached)");
return $promise->resolve($content);
}
}
$self->{user_agent}->request_timeout(5)->head_p( $url => $self->{header} )
$self->{user_agent}->request_timeout(5)->get_p( $url => $self->{header} )
->then(
sub {
my ($tx) = @_;
if ( $tx->result->is_success ) {
$self->{log}
->debug("has_wagonorder_p(${train_no}/${api_ts}): a");
$self->{log}->debug("${debug_prefix}: a");
$cache->set( "HEAD $url", 'a' );
my $body = decode( 'utf-8', $tx->res->body );
my $json = JSON->new->decode($body);
$cache->freeze( $url, $json );
$promise->resolve('a');
}
else {
$self->{log}
->debug("has_wagonorder_p(${train_no}/${api_ts}): n");
my $code = $tx->code;
$self->{log}->debug("${debug_prefix}: n (HTTP $code)");
$cache->set( "HEAD $url", 'n' );
$promise->reject;
}
@ -67,7 +81,8 @@ sub has_wagonorder_p {
}
)->catch(
sub {
$self->{log}->debug("has_wagonorder_p(${train_no}/${api_ts}): n");
my ($err) = @_;
$self->{log}->debug("${debug_prefix}: n ($err)");
$cache->set( "HEAD $url", 'n' );
$promise->reject;
return;
@ -77,17 +92,29 @@ sub has_wagonorder_p {
}
sub get_wagonorder_p {
my ( $self, $api, $ts, $train_no ) = @_;
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 ( $self, %opt ) = @_;
my $datetime = $opt{datetime}->clone->set_time_zone('UTC');
my %param = (
administrationId => 80,
category => $opt{train_type},
date => $datetime->strftime('%Y-%m-%d'),
evaNumber => $opt{eva},
number => $opt{train_no},
time => $datetime->rfc3339 =~ s{(?=Z)}{.000}r
);
my $url = sprintf( '%s?%s',
'https://www.bahn.de/web/api/reisebegleitung/wagenreihung/vehicle-sequence',
join( '&', map { $_ . '=' . $param{$_} } keys %param ) );
my $debug_prefix
= "get_wagonorder_p($opt{train_type} $opt{train_no} @ $opt{eva})";
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)");
$self->{log}->debug("${debug_prefix}: (cached)");
$promise->resolve($content);
return $promise;
}
@ -100,15 +127,13 @@ 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");
$self->{log}->debug("${debug_prefix}: 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}");
$self->{log}->debug("${debug_prefix}: HTTP ${code}");
$promise->reject("HTTP ${code}");
}
return;
@ -116,8 +141,7 @@ sub get_wagonorder_p {
)->catch(
sub {
my ($err) = @_;
$self->{log}
->debug("get_wagonorder_p(${train_no}/${api_ts}): error ${err}");
$self->{log}->debug("${debug_prefix}: error ${err}");
$promise->reject($err);
return;
}

View file

@ -68,33 +68,48 @@
% }
% if (my $wr = $journey->{wagonorder}) {
<br/>
% my @wagons = $wr->wagons;
<!-- <a href="https://dbf.finalrewind.org/carriage-formation?<%= $journey->{train_no} %>/<%= $journey->{sched_departure}->strftime('%Y%m%d%H%M') %>?e=<%= $journey->{dep_direction} // q{} %>"> -->
% my $direction = $wr->direction == 100 ? '→' : '←';
% if ($journey->{dep_direction}) {
% $direction = $journey->{dep_direction} eq 'l' ? '◀' : '▶';
% if (($journey->{dep_direction} eq 'l' ? 0 : 100) != $wr->direction) {
% @wagons = reverse @wagons;
% }
% }
<a href="https://dbf.finalrewind.org/_wr/<%= $journey->{train_no} %>/<%= $journey->{sched_departure}->strftime('%Y%m%d%H%M') %>?e=<%= $journey->{dep_direction} // q{} %>">
%= $direction
% my $gi;
% for my $wagon (@wagons) {
% if (not ($wagon->is_locomotive or $wagon->is_powercar)) {
% if (defined $gi and $gi != $wagon->group_index) {
% my $had_entry = 0;
% for my $group ($wr->groups) {
% if ($had_entry) {
% $had_entry = 0;
% }
% for my $wagon ($group->carriages) {
% if (not ($wagon->is_locomotive or $wagon->is_powercar)) {
% $had_entry = 1;
% if ($wagon->is_closed) {
X
% }
% elsif ( $wagon->number) {
%= $wagon->number
% }
% else {
%= $wagon->number || ($wagon->type =~ m{AB} ? '½' : $wagon->type =~ m{A} ? '1.' : $wagon->type =~ m{B} ? '2.' : $wagon->type )
% if ( $wagon->has_first_class ) {
% if ( $wagon->has_second_class ) {
½
% }
% else {
1.
% }
% }
% elsif ( $wagon->has_second_class ) {
2.
% }
% else {
%= $wagon->type;
% }
% }
% }
% }
% $gi = $wagon->group_index;
% }
%= $direction
</a>
<!-- </a> -->
% }
</div>
<div class="progress" style="height: 1ex;">

View file

@ -4,10 +4,16 @@
% if ($wagon_number and my $group_name = app->ice_name->{$wagon_number}) {
„<%= $group_name %>“
% }
als <b><%= $journey->{type} %> <%= $wagongroup->{no} %></b>
von <b><%= $wagongroup->{from} %></b> nach <b><%= $wagongroup->{to} %></b><br/>
als <b><%= $wagongroup->{type} // $journey->{type} %> <%= $wagongroup->{no} %></b>
% if ($wagongroup->{from}) {
von <b><%= $wagongroup->{from} %></b>
% }
% if ($wagongroup->{to}) {
nach <b><%= $wagongroup->{to} %></b>
% }
<br/>
% for my $wagon (@{$wagongroup->{wagons}}) {
% if (length($wagon->{id}) == 12) {
% if (length($wagon->{id}) == 12 or length($wagon->{id}) == 14) {
<span><%= substr($wagon->{id}, 0, 2) %></span><span><%= substr($wagon->{id}, 2, 2) %></span><span><%= substr($wagon->{id}, 4, 1) %></span><span class="wagonclass"><%= substr($wagon->{id}, 5, 3) %></span><span class="wagonnum"><%= substr($wagon->{id}, 8, 3) %></span><span class="checksum"><%= substr($wagon->{id}, 11) %></span>
% }
% elsif ($wagon->{id}) {