From 33be560292ac02595f3fb386d5785d1f2b690dba Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Mon, 7 Sep 2020 20:49:45 +0200 Subject: working train intersection demo \o/ --- lib/DBInfoscreen.pm | 3 + lib/DBInfoscreen/Controller/Map.pm | 117 ++++++++++++++++++++++++++++++++++++- lib/DBInfoscreen/Helper/HAFAS.pm | 60 ++++++++++++------- 3 files changed, 155 insertions(+), 25 deletions(-) (limited to 'lib') diff --git a/lib/DBInfoscreen.pm b/lib/DBInfoscreen.pm index 72be819..3b3d5c1 100644 --- a/lib/DBInfoscreen.pm +++ b/lib/DBInfoscreen.pm @@ -351,6 +351,9 @@ sub startup { $r->get('/map/:tripid/:lineno')->to('map#route'); $r->get('/intersection/:trips')->to('map#intersection'); + $r->get('/map')->to('map#search_form'); + $r->get('/_trainsearch')->to('map#search'); + $self->defaults( layout => 'app' ); $r->get('/')->to('stationboard#handle_request'); diff --git a/lib/DBInfoscreen/Controller/Map.pm b/lib/DBInfoscreen/Controller/Map.pm index 73d8df5..8a84e16 100644 --- a/lib/DBInfoscreen/Controller/Map.pm +++ b/lib/DBInfoscreen/Controller/Map.pm @@ -274,7 +274,7 @@ sub estimate_train_positions2 { } } - if ( not $next_stop ) { + if ( @route and not $next_stop ) { @train_positions = ( [ $route[-1]{lat}, $route[-1]{lon} ] ); $next_stop = { type => 'present', @@ -313,13 +313,15 @@ sub estimate_train_intersection { my $arr2 = $route2[ $i2 + 1 ]{arr}; if ( not( $dep1 and $arr1 ) ) { - say "skip 1 $route1[$i1]{name}"; + + #say "skip 1 $route1[$i1]{name}"; $i1++; next; } if ( not( $dep2 and $arr2 ) ) { - say "skip 2 $route2[$i2]{name}"; + + #say "skip 2 $route2[$i2]{name}"; $i2++; next; } @@ -857,4 +859,113 @@ sub ajax_route { )->wait; } +sub search { + my ($self) = @_; + + my $t1 = $self->param('train1'); + my $t2 = $self->param('train2'); + + my $t1_data; + my $t2_data; + + my $now = DateTime->now( time_zone => 'Europe/Berlin' ); + my $date_yy = $now->strftime('%d.%m.%y'); + my $date_yyyy = $now->strftime('%d.%m.%Y'); + + # Doesn't seem to matter -- so far, HAFAS is happy as long as the date part + # starts with a number. HAFAS-internal tripIDs use this format (withouth + # leading zero for day of month < 10) though, so let's stick with it. + my $date_map = $now->strftime('%d%m%Y'); + + if ( $t1 and $t1 =~ m{^\S+\s+\d+$} ) { + $t1_data = $self->hafas->trainsearch( + train_no => $t1, + date_yy => $date_yy, + date_yyyy => $date_yyyy + ); + } + else { + $self->render( + 'trainsearch', + title => 'Fahrtverlauf', + hide_opts => 1, + error => $t1 + ? "Züge müssen im Format 'Zugtyp Nummer' angegeben werden, z.B. 'RE 1234'" + : undef, + ); + return; + } + + if ( $t2 and $t2 =~ m{^\S+\s+\d+$} ) { + $t2_data = $self->hafas->trainsearch( train_no => $t2 ); + } + elsif ($t2) { + $self->render( + 'trainsearch', + title => 'Fahrtverlauf', + hide_opts => 1, + error => +"Züge müssen im Format 'Zugtyp Nummer' angegeben werden, z.B. 'RE 1234'", + ); + return; + } + + if ( not $t1_data ) { + $self->render( + 'trainsearch', + title => 'Fahrtverlauf', + hide_opts => 1, + error => "Zug $t1 nicht gefunden" + ); + return; + } + + if ( $t2 and not $t2_data ) { + $self->render( + 'trainsearch', + title => 'Fahrtverlauf', + hide_opts => 1, + error => "Zug $t2 nicht gefunden" + ); + return; + } + + if ( $t1 and not $t2 ) { + $self->redirect_to( + sprintf( + "/map/1|%d|%d|%d|%s/0", + $t1_data->{id}, $t1_data->{cycle}, + $t1_data->{pool}, $date_map + ) + ); + } + elsif ( $t1 and $t2 ) { + $self->redirect_to( + sprintf( + "/intersection/1|%d|%d|%d|%s,0;1|%d|%d|%d|%s,0", + $t1_data->{id}, $t1_data->{cycle}, $t1_data->{pool}, + $date_map, $t2_data->{id}, $t2_data->{cycle}, + $t2_data->{pool}, $date_map + ) + ); + } + else { + $self->render( + 'trainsearch', + title => 'Fahrtverlauf', + hide_opts => 1, + ); + } +} + +sub search_form { + my ($self) = @_; + + $self->render( + 'trainsearch', + title => 'Fahrtverlauf', + hide_opts => 1, + ); +} + 1; diff --git a/lib/DBInfoscreen/Helper/HAFAS.pm b/lib/DBInfoscreen/Helper/HAFAS.pm index 8007ff4..f7df0f7 100644 --- a/lib/DBInfoscreen/Helper/HAFAS.pm +++ b/lib/DBInfoscreen/Helper/HAFAS.pm @@ -151,35 +151,27 @@ sub hafas_xml_req { return $ret; } -sub get_route_timestamps { +sub trainsearch { my ( $self, %opt ) = @_; my $base = 'https://reiseauskunft.bahn.de/bin/trainsearch.exe/dn?L=vs_json&start=yes&rt=1'; - my ( $date_yy, $date_yyyy, $train_no, $train_origin ); - if ( $opt{train} ) { - $date_yy = $opt{train}->start->strftime('%d.%m.%y'); - $date_yyyy = $opt{train}->start->strftime('%d.%m.%Y'); - $train_no = $opt{train}->type . ' ' . $opt{train}->train_no; - $train_origin = $opt{train}->origin; - } - else { + if ( not $opt{date_yy} ) { my $now = DateTime->now( time_zone => 'Europe/Berlin' ); - $date_yy = $now->strftime('%d.%m.%y'); - $date_yyyy = $now->strftime('%d.%m.%Y'); - $train_no = $opt{train_no}; + $opt{date_yy} = $now->strftime('%d.%m.%y'); + $opt{date_yyyy} = $now->strftime('%d.%m.%Y'); } my $trainsearch = $self->hafas_json_req( $self->{main_cache}, - "${base}&date=${date_yy}&trainname=${train_no}" ); + "${base}&date=$opt{date_yy}&trainname=$opt{train_no}" ); if ( not $trainsearch ) { return; } # Fallback: Take first result - my $trainlink = $trainsearch->{suggestions}[0]{trainLink}; + my $result = $trainsearch->{suggestions}[0]; # Try finding a result for the current date for my $suggestion ( @{ $trainsearch->{suggestions} // [] } ) { @@ -187,8 +179,8 @@ sub get_route_timestamps { # Drunken API, sail with care. Both date formats are used interchangeably if ( exists $suggestion->{depDate} - and ( $suggestion->{depDate} eq $date_yy - or $suggestion->{depDate} eq $date_yyyy ) + and ( $suggestion->{depDate} eq $opt{date_yy} + or $suggestion->{depDate} eq $opt{date_yyyy} ) ) { # Train numbers are not unique, e.g. IC 149 refers both to the @@ -197,28 +189,52 @@ sub get_route_timestamps { # requests with the stationFilter=80 parameter. Checking the origin # station seems to be the more generic solution, so we do that # instead. - if ( $train_origin and $suggestion->{dep} eq $train_origin ) { - $trainlink = $suggestion->{trainLink}; + if ( $opt{train_origin} + and $suggestion->{dep} eq $opt{train_origin} ) + { + $result = $suggestion; last; } } } - if ( not $trainlink ) { + return $result; +} + +sub get_route_timestamps { + my ( $self, %opt ) = @_; + + if ( $opt{train} ) { + $opt{date_yy} = $opt{train}->start->strftime('%d.%m.%y'); + $opt{date_yyyy} = $opt{train}->start->strftime('%d.%m.%Y'); + $opt{train_no} = $opt{train}->type . ' ' . $opt{train}->train_no; + $opt{train_origin} = $opt{train}->origin; + } + else { + my $now = DateTime->now( time_zone => 'Europe/Berlin' ); + $opt{date_yy} = $now->strftime('%d.%m.%y'); + $opt{date_yyyy} = $now->strftime('%d.%m.%Y'); + } + + my $trainsearch_result = $self->trainsearch(%opt); + + if ( not $trainsearch_result ) { return; } - $base = 'https://reiseauskunft.bahn.de/bin/traininfo.exe/dn'; + my $trainlink = $trainsearch_result->{trainLink}; + + my $base = 'https://reiseauskunft.bahn.de/bin/traininfo.exe/dn'; my $traininfo = $self->hafas_json_req( $self->{realtime_cache}, - "${base}/${trainlink}?rt=1&date=${date_yy}&L=vs_json" ); + "${base}/${trainlink}?rt=1&date=$opt{date_yy}&L=vs_json" ); if ( not $traininfo or $traininfo->{error} ) { return; } my $traindelay = $self->hafas_xml_req( $self->{realtime_cache}, - "${base}/${trainlink}?rt=1&date=${date_yy}&L=vs_java3" ); + "${base}/${trainlink}?rt=1&date=$opt{date_yy}&L=vs_java3" ); my $ret = {}; -- cgit v1.2.3