summaryrefslogtreecommitdiff
path: root/bin/efa
diff options
context:
space:
mode:
Diffstat (limited to 'bin/efa')
-rwxr-xr-xbin/efa163
1 files changed, 117 insertions, 46 deletions
diff --git a/bin/efa b/bin/efa
index 5840068..6768902 100755
--- a/bin/efa
+++ b/bin/efa
@@ -4,20 +4,18 @@ use warnings;
use 5.010;
use utf8;
-no if $] >= 5.018, warnings => 'experimental::smartmatch';
-
use utf8;
use Encode qw(decode);
use Travel::Routing::DE::EFA;
use Exception::Class;
use Getopt::Long qw/:config no_ignore_case/;
-use List::Util qw(first);
+use List::Util qw(first max);
-our $VERSION = '2.19';
+our $VERSION = '2.24';
my $ignore_info;
my $efa;
-my $efa_url = 'http://efa.vrr.de/vrr/XSLT_TRIP_REQUEST2';
+my $efa_url = 'https://app.vrr.de/vrrstd/XML_TRIP_REQUEST2';
my ( @from, @to, @via, $from_type, $to_type, $via_type );
my $opt = {
'efa-url' => \$efa_url,
@@ -32,6 +30,9 @@ my $opt = {
binmode( STDOUT, ':encoding(utf-8)' );
binmode( STDERR, ':encoding(utf-8)' );
+my $output_bold = -t STDOUT ? "\033[1m" : q{};
+my $output_reset = -t STDOUT ? "\033[0m" : q{};
+
sub show_help {
my ($exit_status) = @_;
@@ -49,7 +50,7 @@ sub new_efa_by_url {
origin => [ @from, $from_type ],
destination => [ @to, $to_type ],
- via => ( @via ? [ @via, $via_type ] : undef ),
+ via => ( @via ? [ @via, $via_type ] : undef ),
arrival_time => $opt->{arrive},
departure_time => $opt->{depart},
@@ -172,6 +173,22 @@ sub format_footpath {
return $str;
}
+sub format_delay_incl {
+ my ( $delay, $len ) = @_;
+ if ( $delay and $len ) {
+ return sprintf( "(%+${len}d)", $delay );
+ }
+ return q{};
+}
+
+sub format_delay_excl {
+ my ( $delay, $len ) = @_;
+ if ( $delay and $len ) {
+ return sprintf( " %+${len}d ", $delay );
+ }
+ return q{};
+}
+
sub display_routes {
my (@routes) = @_;
@@ -191,8 +208,19 @@ sub display_routes {
}
}
+ my $delay_len = 0;
for my $c ( $route->parts ) {
- display_connection($c);
+ if ( $c->departure_delay ) {
+ $delay_len
+ = max( $delay_len, length( $c->departure_delay ) + 1 );
+ }
+ if ( $c->arrival_delay ) {
+ $delay_len = max( $delay_len, length( $c->arrival_delay ) + 1 );
+ }
+ }
+
+ for my $c ( $route->parts ) {
+ display_connection( $c, $delay_len );
}
# last one needs to be shown separately
@@ -211,29 +239,25 @@ sub display_routes {
}
sub display_connection {
- my ($c) = @_;
+ my ( $c, $delay_len ) = @_;
+
+ my $delay_fmt = $delay_len ? $delay_len + 2 : 0;
if ( $c->is_cancelled ) {
say '# FAHRT FÄLLT AUS';
}
- elsif ( $c->delay ) {
- printf( "# +%d, Plan: %s -> %s\n",
- $c->delay, $c->departure_stime, $c->arrival_stime );
- }
- for my $note ( $c->regular_notes ) {
- my $text = $note->summary;
- if ( not( length $ignore_info and $text =~ /$ignore_info/i ) ) {
- say "# $text";
- }
- }
+ my $occupancy = q{};
- for my $notice ( $c->current_notes ) {
- if ( $notice->subtitle ne $notice->subject ) {
- printf( "# %s - %s\n", $notice->subtitle, $notice->subject );
+ if ( $c->occupancy ) {
+ if ( $c->occupancy == 1 ) {
+ $occupancy = '[ ]';
}
- else {
- printf( "# %s\n", $notice->subtitle );
+ elsif ( $c->occupancy == 2 ) {
+ $occupancy = '[* ]';
+ }
+ elsif ( $c->occupancy == 3 ) {
+ $occupancy = '[!!]';
}
}
@@ -244,21 +268,52 @@ sub display_connection {
}
printf(
- "%-5s ab %-30s %-20s %s\n",
+ "${output_bold}%s${output_reset} %s %s\n",
+ $c->train_line || $c->train_product,
+ $c->train_destination ? q{→} : q{ },
+ $c->train_destination
+ );
+
+ printf(
+ "%-5s %-${delay_fmt}s ab %-30s\n",
$c->departure_time,
+ format_delay_incl( $c->departure_delay, $delay_len ),
$c->departure_stop_and_platform,
- $c->train_line || $c->train_product,
- $c->train_destination,
);
if ( $opt->{'full-route'} ) {
for my $via_stop ( $c->via ) {
- printf( "%-5s %-30s %s\n",
- $via_stop->[1], $via_stop->[2], $via_stop->[3] );
+ printf(
+ "%-5s %-${delay_fmt}s %-30s %s\n",
+ $via_stop->[1], format_delay_excl( $via_stop->[4], $delay_len ),
+ $via_stop->[2], $via_stop->[3]
+ );
+ }
+ }
+
+ printf(
+ "%-5s %-${delay_fmt}s an %-30s %s\n",
+ $c->arrival_time,
+ format_delay_incl( $c->arrival_delay, $delay_len ),
+ $c->arrival_stop_and_platform, $occupancy
+ );
+
+ for my $notice ( $c->current_notes ) {
+ if ( $notice->subtitle ne $notice->subject ) {
+ printf( "# %s - %s\n", $notice->subtitle, $notice->subject );
+ }
+ else {
+ printf( "# %s\n", $notice->subtitle );
+ }
+ }
+
+ for my $note ( $c->regular_notes ) {
+ my $text = $note->summary;
+ if ( not( length $ignore_info and $text =~ /$ignore_info/i ) ) {
+ say "# $text";
}
}
- printf( "%-5s an %s\n", $c->arrival_time, $c->arrival_stop_and_platform, );
print "\n";
if ( $opt->{'extended-info'}
@@ -325,14 +380,23 @@ if ( $opt->{exclude} ) {
@{ $opt->{exclude} } = split( qr{,}, join( q{,}, @{ $opt->{exclude} } ) );
}
+my %accessibility_map = (
+ s => 'without_solid_stairs',
+ 'no-stairs' => 'without_solid_stairs',
+ e => 'without_escalators',
+ 'no-escalators' => 'without_escalators',
+ E => 'without_elevators',
+ 'no-elevators' => 'without_elevators',
+ l => 'with_low_platform',
+ nf => 'with_low_platform',
+ 'low-platform' => 'with_low_platform',
+ w => 'with_wheelchair',
+ wheelchair => 'with_wheelchair',
+);
+
for my $field ( @{ $opt->{accessibility} } ) {
- given ($field) {
- when ( [qw[s no-stairs]] ) { $opt->{without_solid_stairs} = 1 }
- when ( [qw[e no-escalators]] ) { $opt->{without_escalators} = 1 }
- when ( [qw[E no-elevators]] ) { $opt->{without_elevators} = 1 }
- when ( [qw[l nf low-platform]] ) { $opt->{with_low_platform} = 1 }
- when ( [qw[w wheelchair]] ) { $opt->{with_wheelchair} = 1 }
- when ( [qw[i info]] ) { } # used for ignore_info default
+ if ( $accessibility_map{$field} ) {
+ $opt->{ $accessibility_map{$field} } = 1;
}
}
@@ -390,16 +454,18 @@ for my $pair ( [ \@from, \$from_type ], [ \@via, \$via_type ],
{$+{target}}x
)
{
- given ( $+{type} ) {
- when ('addr') { ${ $pair->[1] } = 'address' }
- default { ${ $pair->[1] } = $+{type} }
+ if ( $+{type} eq 'addr' ) {
+ ${ $pair->[1] } = 'address';
+ }
+ else {
+ ${ $pair->[1] } = $+{type};
}
}
}
if ( $opt->{service} ) {
my $service = first { lc( $_->{shortname} ) eq lc( $opt->{service} ) }
- Travel::Routing::DE::EFA::get_efa_urls();
+ Travel::Routing::DE::EFA::get_efa_urls();
if ( not $service ) {
printf STDERR (
"Error: Unknown service '%s'. See 'efa -l' for a "
@@ -457,7 +523,7 @@ efa - Command line client for EFA-based public transit routing services
=head1 VERSION
-version 2.19
+version 2.24
=head1 DESCRIPTION
@@ -472,6 +538,11 @@ instance can be selected using B<-s> I<service> or B<-u> I<url>. It is also
possible to probe all known EFA services for a specific connection using the
B<-A> and B<-D> options.
+If available, B<efa> shows the expected occupancy of each route part.
+It ranges from C<< [ ] >> (low occupancy) to C<< [!!] >> (very high
+occupancy). Occupation data appears to be limited to certain VRR trains
+at the moment.
+
=head1 OPTIONS
=over
@@ -531,7 +602,7 @@ entry points which did not return an error.
=item B<-u>|B<--efa-url> I<url>
URL to the EFA entry point, defaults to
-L<http://efa.vrr.de/vrr/XSLT_TRIP_REQUEST2>. Depending on your location, some
+L<https://app.vrr.de/vrrstd/XML_TRIP_REQUEST2>. Depending on your location, some
I<url>s may contain more specific data than others. See
Travel::Routing::DE::EFA(3pm) and the B<-l> option for alternatives.
@@ -708,9 +779,9 @@ All vehicles must be wheelchair accessible.
0 Everything went well
1 Invalid arguments, see error message
2 Network error, unable to send request
- 3 efa.vrr.de did not return any parsable data
- 4 efa.vrr.de error: ambiguous input
- 5 efa.vrr.de error: no connections found
+ 3 EFA did not return any parsable data
+ 4 EFA error: ambiguous input
+ 5 EFA error: no connections found
10 Unknown Travel::Routing::DE::EFA error
255 Other internal error
@@ -769,7 +840,7 @@ to to request via -> to.
=head1 AUTHOR
-Copyright (C) 2009-2020 by Daniel Friesel E<lt>derf@finalrewind.orgE<gt>
+Copyright (C) 2009-2023 by Birte Kristina Friesel E<lt>derf@finalrewind.orgE<gt>
=head1 LICENSE