#!perl use strict; use warnings; use 5.014; our $VERSION = '0.06'; use utf8; use DateTime; use Encode qw(decode); use JSON; use Getopt::Long qw(:config no_ignore_case bundling); use List::MoreUtils qw(uniq); use List::Util qw(first max); use Travel::Routing::DE::HAFAS; use Travel::Status::DE::HAFAS; my ( $date, $time, $arrival, $language ); my $types = q{}; my $developer_mode; my ( $json_output, $raw_json_output ); my $show_full_route; my $exclude_infeasible; my ( $list_services, $service ); my ( @excluded_mots, @exclusive_mots ); my $max_change = undef; my $min_change_time = undef; my $verbosity = 0; my @output; my %min_verbosity = ( A => 3, C => 0, G => 2, H => 1, L => 0, M => 1, P => 0, ); binmode( STDOUT, ':encoding(utf-8)' ); for my $arg (@ARGV) { $arg = decode( 'UTF-8', $arg ); } my $output_bold = -t STDOUT ? "\033[1m" : q{}; my $output_reset = -t STDOUT ? "\033[0m" : q{}; GetOptions( 'a|arrive=s' => sub { $arrival = 1; $time = $_[1] }, 'c|max-change=s' => \$max_change, 'C|change-time=s' => \$min_change_time, 'd|date=s' => \$date, 'h|help' => sub { show_help(0) }, 'f|full-route' => \$show_full_route, 'l|language=s' => \$language, 'm|mot=s' => \$types, 's|service=s' => \$service, 't|time|depart=s' => \$time, 'x|exclude-infeasible' => \$exclude_infeasible, 'v|verbose+' => \$verbosity, 'V|version' => \&show_version, 'devmode' => \$developer_mode, 'json' => \$json_output, 'raw-json' => \$raw_json_output, 'list' => \$list_services, ) or show_help(1); if ($list_services) { printf( "%-40s %-14s %s\n\n", 'operator', 'abbr. (-s)', 'languages (-l)' ); for my $service ( Travel::Routing::DE::HAFAS::get_services() ) { printf( "%-40s %-14s %s\n", @{$service}{qw(name shortname)}, join( q{ }, @{ $service->{languages} // [] } ) ); } exit 0; } parse_mot_options(); my ( $from_stop, @via_stops ) = @ARGV; my $to_stop = pop @via_stops; if ( not( $from_stop and $to_stop ) ) { show_help(1); } my %opt = ( service => $service, from_stop => $from_stop, via_stops => \@via_stops, to_stop => $to_stop, excluded_mots => \@excluded_mots, exclusive_mots => \@exclusive_mots, max_change => $max_change, min_change_time => $min_change_time, developer_mode => $developer_mode, arrival => $arrival, language => $language, ); if ( $date or $time ) { my $dt = DateTime->now( time_zone => 'Europe/Berlin' ); if ($date) { if ( $date =~ m{ ^ (? \d{1,2} ) [.] (? \d{1,2} ) [.] (? \d{4})? $ }x ) { $dt->set( day => $+{day}, month => $+{month} ); if ( $+{year} ) { $dt->set( year => $+{year} ); } } else { say "--date must be specified as DD.MM.[YYYY]"; exit 1; } } if ($time) { if ( $time =~ m{ ^ (? \d{1,2} ) : (? \d{1,2} ) $ }x ) { $dt->set( hour => $+{hour}, minute => $+{minute}, second => 0, ); } else { say "--time must be specified as HH:MM"; exit 1; } } $opt{datetime} = $dt; } my $hafas = Travel::Routing::DE::HAFAS->new(%opt); sub show_help { my ($code) = @_; print 'Usage: hafas [-d ] [-m ] [-t