diff options
Diffstat (limited to 'bin/efa-m')
-rwxr-xr-x | bin/efa-m | 103 |
1 files changed, 68 insertions, 35 deletions
@@ -4,7 +4,7 @@ use warnings; use 5.010; use utf8; -our $VERSION = '3.03'; +our $VERSION = '3.13'; binmode( STDOUT, ':encoding(utf-8)' ); @@ -19,7 +19,7 @@ my $efa_url; my $efa_encoding; my $use_cache = 1; my $cache; -my $json_output; +my ( $json_output, $raw_json_output ); my ( $date, $time, $input_type, $list_lines, $offset, $relative_times ); my ( $full_routes, $filter_via, $show_jid ); my ( $timeout, $developer_mode ); @@ -60,6 +60,7 @@ GetOptions( 'V|track-via=s' => \$filter_via, 'cache!' => \$use_cache, 'json' => \$json_output, + 'raw-json' => \$raw_json_output, 'devmode' => \$developer_mode, 'version' => \&show_version, @@ -98,12 +99,15 @@ if ($use_cache) { my ( $place, $input, $coord, $stopseq, $stopfinder ); if ( @ARGV == 1 ) { - if ( $ARGV[0] =~ m{ ^ ([^@]*) @ ([^@]*) [(] ([^)]*) [)] (.*) $ }x ) { + if ( $ARGV[0] + =~ m{ ^ ([^@]*) @ ([^@]*) [(] ([^T]*) T ([^)]*) [)] (.*) $ }x ) + { $stopseq = { stateless => $1, stop_id => $2, date => $3, - key => $4 + time => $4, + key => $5 }; } elsif ( $ARGV[0] =~ m{ ^ [?] (?<name> .*) $ }x ) { @@ -185,7 +189,7 @@ sub new_efa { sub show_help { my ($code) = @_; - print "Usage: efa-m [-d <dd.mm.yyyy>] [-t <hh:mm>] [place] <station>\n" + print "Usage: efa-m [-d <dd.mm.yyyy>] [-t <hh:mm>] <stop>\n" . "See also: man efa-m\n"; exit $code; @@ -232,7 +236,13 @@ sub format_route { if ( $stop->delay ) { $delay = sprintf( '(%+3d)', $stop->delay ); } - if ( defined $stop->arr and defined $stop->dep ) { + if ( $stop->is_cancelled ) { + $output .= sprintf( + " --:-- %s %s %35s %s\n", + $delay, $occupancy, $stop->full_name, $stop->platform // q{}, + ); + } + elsif ( defined $stop->arr and defined $stop->dep ) { if ( $stop->arr->epoch == $stop->dep->epoch ) { $output .= sprintf( " %5s %s %s %35s %s\n", @@ -321,7 +331,7 @@ sub show_coord { printf( "%5.1f km %-${max_len}s %s\n", $stop->distance_m * 1e-3, - $stop->full_name, $stop->id + $stop->full_name, $stop->id_code ); } } @@ -329,7 +339,8 @@ sub show_coord { sub show_stopfinder { my $max_len = max map { length( $_->full_name ) } $efa->results; for my $stop ( $efa->results ) { - printf( "%-${max_len}s %s\n", $stop->full_name, $stop->id ); + printf( "%-${max_len}s %s %s\n", + $stop->full_name, $stop->id_num, $stop->id_code ); } } @@ -340,11 +351,12 @@ sub show_stopseq { printf( "Fahrt %s am %s\n", - $trip->number || $stopseq, + $trip->number || $stopseq->{stateless}, ( $trip->route )[0]->sched_dep->strftime('%d.%m.%Y'), ); say q{}; + my $occupancy_len = 0; my $delay_len = 0; my $inner_delay_len = 0; my $max_delay = max map { abs( $_->delay // 0 ) } $trip->route; @@ -352,16 +364,28 @@ sub show_stopseq { $inner_delay_len = length($max_delay) + 1; $delay_len = length( sprintf( '(%+d)', $max_delay ) ) + 1; } + if ( first { $_->occupancy } $trip->route ) { + $occupancy_len = 2; + } + + if ( first { $_->is_cancelled } $trip->route and $delay_len < 3 ) { + $delay_len = 3; + } for my $stop ( $trip->route ) { printf( - "%s → %s%${delay_len}s %s (%s) %s\n", + "%s → %s%${delay_len}s %-${occupancy_len}s%s (%s) %s\n", $stop->arr ? $stop->arr->strftime('%H:%M') : q{ }, $stop->dep ? $stop->dep->strftime('%H:%M') : q{ }, - $stop->delay ? sprintf( " (%+${inner_delay_len}d)", $stop->delay ) - : q{}, + $stop->is_cancelled ? 'XX' + : ( + $stop->delay + ? sprintf( " (%+${inner_delay_len}d)", $stop->delay ) + : q{} + ), + $stop->occupancy ? format_occupancy( $stop->occupancy ) : q{}, $stop->full_name, $stop->niveau, $stop->platform @@ -482,11 +506,7 @@ sub show_results { @output_line = ( $dtime, $platform, $line, q{}, $d->destination, $d ); if ($show_jid) { - $output_line[2] .= sprintf( ' %s@%d(%s)%d', - $d->stateless =~ s{ }{}gr, - scalar $d->route_pre ? ( $d->route_pre )[0]->id : $d->stop_id, - $d->sched_datetime->strftime('%Y%m%d'), - $d->key ); + $output_line[2] .= ' ' . $d->id; } if ( $edata{route} ) { @@ -557,11 +577,15 @@ if ( my $err = $efa->errstr ) { if ( $efa->place_candidates ) { say 'You might want to try one of the following places:'; - say join( "\n", $efa->place_candidates ); + for my $candidate ( $efa->place_candidates ) { + printf( "%d %s\n", $candidate->id_num, $candidate->name ); + } } elsif ( $efa->name_candidates ) { say 'You might want to try one of the following names:'; - say join( "\n", $efa->name_candidates ); + for my $candidate ( $efa->name_candidates ) { + printf( "%d %s\n", $candidate->id_num, $candidate->name ); + } } exit 2; @@ -575,6 +599,9 @@ if ($json_output) { say JSON->new->convert_blessed->encode( [ $efa->results ] ); } } +elsif ($raw_json_output) { + say JSON->new->convert_blessed->encode( $efa->{response} ); +} elsif ($coord) { show_coord(); } @@ -609,7 +636,7 @@ B<efa-m> [B<-s> I<service>] I<tripid> =head1 VERSION -version 3.03 +version 3.13 =head1 DESCRIPTION @@ -621,8 +648,8 @@ The operating mode depends on the contents of its mandatory argument. =head2 Departure Monitor (I<name>) -Shows departures it I<name> or I<city> I<name>. For each departure, -B<efa-m> shows +Shows departures at I<name> or I<city> I<name>; I<name> may also be a stop ID +number or code. For each departure, B<efa-m> shows =over @@ -640,10 +667,10 @@ B<efa-m> shows =back -If I<city> is specified, I<name> refers to a location within I<city>. Otherwise, -I<name> must be self-contained. I.e., both C<< efa Essen Hbf >> and -C<< efa "Essen Hbf" >> are valid. Note, however, than C<< efa E Hbf >> works, -but C<< efa "E Hbf" >> does not. +If I<city> is specified, I<name> refers to a location within I<city>. +Otherwise, I<name> must be self-contained. I.e., both C<< efa-m Essen Hbf >> +and C<< efa-m "Essen Hbf" >> are valid. Note, however, than C<< efa-m E Hbf >> +works, but C<< efa-m "E Hbf" >> does not. By default, I<name> refers to a stop, this can be changed by specifying I<type>. Supported types are B<address> and B<poi> (point of interest). @@ -651,11 +678,13 @@ I<type>. Supported types are B<address> and B<poi> (point of interest). =head2 Location Search (B<?>I<query>|I<lat>B<:>I<lon>) List stops that match I<query> or that are located in the vicinity of -I<lat>B<:>I<lon> geocoordinates. +I<lat>B<:>I<lon> geocoordinates. In addition to stop names, the output also +includes stop ID codes (both modes) and numbers (only available in I<query> +mode). =head2 Trip Details (I<JourneyID>) -List trip information as well as arrival and departure time, name, and platform +List trip information including arrival and departure time, name, and platform of each stop on the trip's route. =head1 OPTIONS @@ -663,13 +692,12 @@ of each stop on the trip's route. Values in brackets indicate options that only apply to the corresponding operating mode(s). - =over =item B<-A>, B<--auto-url>, B<--discover-and-print> (monitor) -Probe all known EFA entry points for the specified stop. Print the first -result which was not an error. +Probe all known EFA services for the specified stop. Print the first result +which was not an error. Note that this may take a while and will not necessarily return the best result. Also, using thi option by default is not recommended, as it puts EFA @@ -682,8 +710,8 @@ May also be specified as I<dd.mm.> =item B<-D>, B<--discover> (monitor) -Probe all known EFA entry points for the specified stop. Print the URLs and -names of all entry points which did not return an error. +Probe all known EFA services for the specified stop. Print the URLs and names +of all services which did not return an error. =item B<-j>, B<--with-jid> (monitor) @@ -778,6 +806,11 @@ availability, delay reasons, and more. Only show departures at I<platforms> (comma-separated list, option may be repeated). Note that the C<< Bstg. >> / C<< Gleis >> prefix must be omitted. +=item B<--raw-json> + +Print unprocessed EFA response as JSON and exit. +Useful for debugging and development purposes. + =item B<-r>, B<--relative> (monitor) Show relative departure times in minutes (i.e. the time difference between @@ -786,7 +819,7 @@ already included. =item B<-s>, B<--service> I<name> -Short name of the EFA entry point. See Travel::Status::DE::EFA(3pm) and the +Short name of the EFA service. See Travel::Status::DE::EFA(3pm) and the B<--list> option for a list of services. =item B<-t>, B<--time> I<hh:mm> (monitor) @@ -851,7 +884,7 @@ departure and departure delay =head1 AUTHOR -Copyright (C) 2011-2023 by Birte Kristina Friesel E<lt>derf@finalrewind.orgE<gt> +Copyright (C) 2011-2023 Birte Kristina Friesel E<lt>derf@finalrewind.orgE<gt> =head1 LICENSE |