#!/usr/bin/env perl use strict; use warnings; use 5.014; use utf8; no if $] >= 5.018, warnings => 'experimental::smartmatch'; our $VERSION = '1.05'; use Carp; use DateTime; use DateTime::Format::Strptime; use Encode qw(decode); use Getopt::Long qw(:config no_ignore_case bundling); use List::Util qw(first max); use List::MoreUtils qw(none); use Travel::Status::DE::IRIS; use Travel::Status::DE::IRIS::Stations; my ( $date, $time, $lookahead ); my $datetime = DateTime->now( time_zone => 'Europe/Berlin' ); my $developer_mode = 0; my $realtime = 0; my $with_related = 1; my $emma_url; my ( $filter_via, $track_via, $status_via ); my ( @grep_class, @grep_type, @grep_platform ); my ( %edata, @edata_pre ); my @output; binmode( STDOUT, ':encoding(utf-8)' ); @ARGV = map { decode( 'UTF-8', $_ ) } @ARGV; GetOptions( 'c|class=s@' => \@grep_class, 'd|date=s' => \$date, 'h|help' => sub { show_help(0) }, 'l|lookahead=i' => \$lookahead, 'o|output=s@' => \@edata_pre, 'p|platform=s@' => \@grep_platform, 'r|realtime' => \$realtime, 't|time=s' => \$time, 'T|type=s' => \@grep_type, 'v|via=s' => \$filter_via, 'V|track-via=s' => \$track_via, 'x|exact|no-related' => sub { $with_related = 0 }, 'devmode' => \$developer_mode, 'emma=s' => \$emma_url, 'version' => \&show_version, ) or show_help(1); if ( @ARGV != 1 ) { show_help(1); } # opt=foo,bar support @edata_pre = split( qr{,}, join( q{,}, @edata_pre ) ); @grep_class = split( qr{,}, join( q{,}, @grep_class ) ); @grep_platform = split( qr{,}, join( q{,}, @grep_platform ) ); @grep_type = split( qr{,}, join( q{,}, @grep_type ) ); my ($station) = @ARGV; $station = get_station($station); if ($track_via) { $track_via = get_station($track_via); } if ($date) { my ( $day, $month, $year ) = split( qr{ [.] }ox, $date ); $datetime->set( day => $day, month => $month, year => $year || $datetime->year, ); } if ($time) { my ( $hour, $minute, $second ) = split( qr{ : }ox, $time ); $datetime->set( hour => $hour, minute => $minute, second => $second || $datetime->second, ); } for my $efield (@edata_pre) { given ($efield) { when ('a') { $edata{additional} = 1 } when ('c') { $edata{canceled} = 1 } when ('d') { $edata{delay} = 1 } when ('D') { $edata{delays} = 1 } when ('f') { $edata{fullroute} = 1 } when ('m') { $edata{messages} = 1 } when ('M') { $edata{trackinfo} = 1 } when ('q') { $edata{qos} = 1 } when ('r') { $edata{route} = 1 } when ('R') { $edata{replacements} = 1 } when ('t') { $edata{times} = 1 } when ('!') { $edata{debug} = 1 } default { $edata{$efield} = 1 } } } my $status = Travel::Status::DE::IRIS->new( datetime => $datetime, developer_mode => $developer_mode, lookahead => $lookahead, station => $station, with_related => $with_related, emma_url => $emma_url, ); if ($track_via) { # lookahead should not be used here - the via stop is reached an unknown # amount of time later $status_via = Travel::Status::DE::IRIS->new( datetime => $datetime, station => $track_via, ); } sub get_arrival { my ( $result, $fmt ) = @_; my $dt_arrival = $realtime ? $result->arrival : $result->sched_arrival; if ($fmt) { return $dt_arrival ? $dt_arrival->strftime($fmt) : q{}; } return $dt_arrival; } sub get_departure { my ( $result, $fmt ) = @_; my $dt_dep = $realtime ? $result->departure : $result->sched_departure; if ($fmt) { return $dt_dep ? $dt_dep->strftime($fmt) : q{}; } return $dt_dep; } sub get_station { my ($input_name) = @_; if ( $input_name =~ m{ ^ [[:digit:]]+ $ }x ) { return $input_name; } my @stations = Travel::Status::DE::IRIS::Stations::get_station($input_name); if ( @stations == 0 ) { say STDERR "No station matches '$input_name'"; exit(1); } elsif ( @stations == 1 ) { return $stations[0][0]; } else { say STDERR "The input '$input_name' is ambiguous. Please choose one " . 'of the following:'; say STDERR join( "\n", map { $_->[1] . ' (' . $_->[0] . ')' } @stations ); exit(1); } } sub show_help { my ($code) = @_; print 'Usage: db-iris [-r] [-c ] [-d ] ' . '[-o ] [-p ] [-t