#!/usr/bin/env perl use strict; use warnings; use 5.010; no if $] >= 5.018, warnings => "experimental::smartmatch"; our $VERSION = '0.00'; binmode( STDOUT, ':encoding(utf-8)' ); use Getopt::Long qw(:config no_ignore_case); use List::Util qw(max); use Travel::Status::DE::ASEAG; my (@grep_lines); my $full_route = 0; my $hide_past = 1; my $relative_times = 0; my $via; GetOptions( 'a|route-after' => sub { $full_route = 'after' }, 'b|route-before' => sub { $full_route = 'before' }, 'h|help' => sub { show_help(0) }, 'f|full-route' => \$full_route, 'l|line=s@' => \@grep_lines, 'p|with-past' => sub { $hide_past = 0 }, 'r|relative' => \$relative_times, 'v|via=s' => \$via, 'V|version' => \&show_version, ) or show_help(1); if ( @ARGV != 1 ) { show_help(1); } # --line=foo,bar support @grep_lines = split( qr{,}, join( q{,}, @grep_lines ) ); my ($stop_name) = @ARGV; my $status = Travel::Status::DE::ASEAG->new; sub show_help { my ($code) = @_; print "Usage: B [ B<-l> I ] [B<-f>] I< \n" . "See also: man aseag-m\n"; exit $code; } sub show_version { say "aseag-m version ${VERSION}"; exit 0; } sub display_result { my (@lines) = @_; my @line_length; if ( not @lines ) { die("Nothing to show\n"); } for my $i ( 0 .. 2 ) { $line_length[$i] = max map { length( $_->[$i] ) } @lines; } for my $line (@lines) { printf( join( q{ }, ( map { "%-${_}s" } @line_length ) ) . "\n", @{$line}[ 0 .. 2 ] ); if ($full_route) { print "\n" . $line->[3] . "\n\n\n"; } } return; } sub show_results { my @output; for my $d ( $status->results( full_routes => $full_route, hide_past => $hide_past, stop => $stop_name, via => $via, ) ) { my $dtime = $d->time; if ( ( @grep_lines and not( $d->line ~~ \@grep_lines ) ) ) { next; } if ($relative_times) { push( @output, [ $d->line, $d->destination, sprintf( '%3d min', $d->countdown ), join( "\n", map { sprintf( '%-8s %s', @{$_} ) } @{ $d->route_timetable } ) ] ); } else { push( @output, [ $dtime, $d->line, $d->destination, join( "\n", map { sprintf( '%-8s %s', @{$_} ) } @{ $d->route_timetable } ) ] ); } } display_result(@output); return; } if ( my $err = $status->errstr ) { say STDERR "Request error: ${err}"; exit 2; } show_results(); __END__ =head1 NAME aseag-m - Unofficial interface to the ASEAG departure monitor =head1 SYNOPSIS B I =head1 VERSION version 0.00 =head1 DESCRIPTION B lists upcoming bus departures at the ASEAG stop I. =head1 OPTIONS =over =item B<-a>, B<--route-after> For each departure, show all of the line's stops after I as well. =item B<-b>, B<--route-before> For each departure, show all of the line's stops before I as well. =item B<-f>, B<--full-route> For each departure, show all other stops serviced by the respective line. =item B<-l>, B<--line> I Only show departures of I (comma-separatad list, option may be repeated) =item B<-p>, B<--with-past> Also show departures in the past. Also appleas to the route information of B<-a> / B<-b> / B<-f>. =item B<-r>, B<--relative> Use relative departure and route times. =item B<-v>, B<--via> I Only show lines which will also service I. With B<-b>, I must be in the schedule before I, with B<-f> it may be anywhere, with B<-a> (and by default) it must be after I. =item B<-V>, B<--version> Show version information. =back =head1 EXIT STATUS Zero. =head1 CONFIGURATION None. =head1 DEPENDENCIES =over =item * Class::Accessor(3pm) =item * DateTime(3pm) =item * LWP::UserAgent(3pm) =back =head1 BUGS AND LIMITATIONS Unknown. =head1 AUTHOR Copyright (C) 2013 by Daniel Friesel Ederf@finalrewind.orgE =head1 LICENSE This program is licensed under the same terms as Perl itself.