Loading lib/DBInfoscreen.pm +3 −0 Original line number Diff line number Diff line Loading @@ -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'); Loading lib/DBInfoscreen/Controller/Map.pm +114 −3 Original line number Diff line number Diff line Loading @@ -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', Loading Loading @@ -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; } Loading Loading @@ -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; lib/DBInfoscreen/Helper/HAFAS.pm +38 −22 Original line number Diff line number Diff line Loading @@ -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} // [] } ) { Loading @@ -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 Loading @@ -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 = {}; Loading templates/layouts/app.html.ep +1 −1 Original line number Diff line number Diff line Loading @@ -90,7 +90,7 @@ <div class="container"> % if (my $error = stash 'error') { <div class="error"><strong>Backend-Fehler:</strong> <div class="error"><strong>Fehler:</strong> <pre> %= $error </pre> Loading templates/route_map.html.ep +4 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,10 @@ Die eingezeichnete Route stammt aus dem HAFAS und ist im Detail oft fehlerbehaftet.<br/> Die Zugposition auf der Karte ist eine DBF-eigene Schätzung und kann erheblich von den tatsächlichen Gegebenheiten abweichen. % if (stash('intersection')) { <br/>In dieser Ansicht sind Live-Updates der Zug- und Begegnungspositionen noch nicht implementiert. % } </div> % if (my $op = stash('operator')) { Loading Loading
lib/DBInfoscreen.pm +3 −0 Original line number Diff line number Diff line Loading @@ -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'); Loading
lib/DBInfoscreen/Controller/Map.pm +114 −3 Original line number Diff line number Diff line Loading @@ -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', Loading Loading @@ -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; } Loading Loading @@ -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;
lib/DBInfoscreen/Helper/HAFAS.pm +38 −22 Original line number Diff line number Diff line Loading @@ -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} // [] } ) { Loading @@ -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 Loading @@ -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 = {}; Loading
templates/layouts/app.html.ep +1 −1 Original line number Diff line number Diff line Loading @@ -90,7 +90,7 @@ <div class="container"> % if (my $error = stash 'error') { <div class="error"><strong>Backend-Fehler:</strong> <div class="error"><strong>Fehler:</strong> <pre> %= $error </pre> Loading
templates/route_map.html.ep +4 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,10 @@ Die eingezeichnete Route stammt aus dem HAFAS und ist im Detail oft fehlerbehaftet.<br/> Die Zugposition auf der Karte ist eine DBF-eigene Schätzung und kann erheblich von den tatsächlichen Gegebenheiten abweichen. % if (stash('intersection')) { <br/>In dieser Ansicht sind Live-Updates der Zug- und Begegnungspositionen noch nicht implementiert. % } </div> % if (my $op = stash('operator')) { Loading