From aafcd2dd8ef4efa238ce1d0df2b829b098a303c4 Mon Sep 17 00:00:00 2001
From: Daniel Friesel <derf@finalrewind.org>
Date: Sun, 16 Oct 2022 13:47:42 +0200
Subject: parse arr/dep times in journey route

---
 bin/hafas-m                           | 32 +++++++++++++
 lib/Travel/Status/DE/HAFAS/Journey.pm | 86 ++++++++++++++++++++++++-----------
 2 files changed, 91 insertions(+), 27 deletions(-)

diff --git a/bin/hafas-m b/bin/hafas-m
index a33c5dc..dfb5d71 100755
--- a/bin/hafas-m
+++ b/bin/hafas-m
@@ -5,6 +5,7 @@ use 5.014;
 
 our $VERSION = '3.01';
 
+use utf8;
 use DateTime;
 use Encode          qw(decode);
 use Getopt::Long    qw(:config no_ignore_case);
@@ -60,6 +61,11 @@ my %opt = (
 	url            => $hafas_url,
 );
 
+if ( $opt{station} =~ m{[|]} ) {
+	$opt{journey} = { id => $opt{station} };
+	delete $opt{station};
+}
+
 if ( $date or $time ) {
 	my $dt = DateTime->now( time_zone => 'Europe/Berlin' );
 	if ($date) {
@@ -216,6 +222,32 @@ if ( my $err = $status->errstr ) {
 	exit 2;
 }
 
+if ( $opt{journey} ) {
+	my $result = $status->result;
+
+	printf( "%s → %s\n", $result->line, $result->destination );
+
+	for my $stop ( $result->route ) {
+		printf(
+			"%5s %s %5s %5s %s\n",
+			$stop->{arr} ? $stop->{arr}->strftime('%H:%M')      : q{},
+			( $stop->{arr} and $stop->{dep} ) ? '→'             : q{ },
+			$stop->{dep}   ? $stop->{dep}->strftime('%H:%M')    : q{},
+			$stop->{delay} ? sprintf( '(%+d)', $stop->{delay} ) : q{},
+			$stop->{name}
+		);
+	}
+
+	for my $msg ( $result->messages ) {
+		say '';
+		if ( $msg->short ) {
+			printf( "%s\n", $msg->short );
+		}
+		printf( "%s\n", $msg->text );
+	}
+	exit 0;
+}
+
 my $message_id = 1;
 for my $m ( $status->messages ) {
 	if ( $m->ref_count > 1 ) {
diff --git a/lib/Travel/Status/DE/HAFAS/Journey.pm b/lib/Travel/Status/DE/HAFAS/Journey.pm
index 6ef6901..c14a53e 100644
--- a/lib/Travel/Status/DE/HAFAS/Journey.pm
+++ b/lib/Travel/Status/DE/HAFAS/Journey.pm
@@ -12,7 +12,7 @@ our $VERSION = '3.01';
 
 Travel::Status::DE::HAFAS::Journey->mk_ro_accessors(
 	qw(sched_date date sched_datetime datetime info is_cancelled operator delay
-	  sched_time time train route route_end)
+	  sched_time time train route route_end origin destination)
 );
 
 sub new {
@@ -61,35 +61,63 @@ sub new {
 
 	my @stops;
 	for my $stop ( @{ $journey->{stopL} // [] } ) {
-		my $loc = $locL[ $stop->{locX} ];
-		my $arr = $stop->{aTimeS};
-		my $arr_dt;
-		if ($arr) {
-			if ( length($arr) == 8 ) {
+		my $loc       = $locL[ $stop->{locX} ];
+		my $sched_arr = $stop->{aTimeS};
+		my $rt_arr    = $stop->{aTimeR};
+		my $sched_dep = $stop->{dTimeS};
+		my $rt_dep    = $stop->{dTimeR};
+
+		for my $timestr ( $sched_arr, $rt_arr, $sched_dep, $rt_dep ) {
+			if ( not defined $timestr ) {
+				next;
+			}
+			if ( length($timestr) == 8 ) {
 
 				# arrival time includes a day offset
 				my $offset_date = $hafas->{now}->clone;
-				$offset_date->add( days => substr( $arr, 0, 2, q{} ) );
+				$offset_date->add( days => substr( $timestr, 0, 2, q{} ) );
 				$offset_date = $offset_date->strftime('%Y%m%d');
-				$arr_dt      = $hafas->{strptime_obj}
-				  ->parse_datetime("${offset_date}T${arr}");
+				$timestr     = $hafas->{strptime_obj}
+				  ->parse_datetime("${offset_date}T${timestr}");
 			}
 			else {
-				$arr_dt
-				  = $hafas->{strptime_obj}->parse_datetime("${date}T${arr}");
+				$timestr
+				  = $hafas->{strptime_obj}
+				  ->parse_datetime("${date}T${timestr}");
 			}
 		}
+
+		my $arr_delay
+		  = ( $sched_arr and $rt_arr )
+		  ? ( $rt_arr->epoch - $sched_arr->epoch ) / 60
+		  : undef;
+
+		my $dep_delay
+		  = ( $sched_dep and $rt_dep )
+		  ? ( $rt_dep->epoch - $sched_dep->epoch ) / 60
+		  : undef;
+
 		push(
 			@stops,
 			{
-				name    => $loc->{name},
-				eva     => $loc->{extId} + 0,
-				arrival => $arr_dt,
+				name      => $loc->{name},
+				eva       => $loc->{extId} + 0,
+				sched_arr => $sched_arr,
+				rt_arr    => $rt_arr,
+				sched_dep => $sched_dep,
+				rt_dep    => $rt_dep,
+				arr       => $rt_arr // $sched_arr,
+				arr_delay => $arr_delay,
+				dep       => $rt_dep // $sched_dep,
+				dep_delay => $dep_delay,
+				delay     => $dep_delay // $arr_delay
 			}
 		);
 	}
 
-	shift @stops;
+	if ( $journey->{stbStop} ) {
+		shift @stops;
+	}
 
 	my $ref = {
 		datetime_now => $hafas->{now},
@@ -101,6 +129,13 @@ sub new {
 		route        => \@stops,
 	};
 
+	if ( $hafas->{arrivals} ) {
+		$ref->{origin} = $ref->{route_end};
+	}
+	else {
+		$ref->{destination} = $ref->{route_end};
+	}
+
 	bless( $ref, $obj );
 
 	if ( $journey->{stbStop} ) {
@@ -168,12 +203,6 @@ sub countdown_sec {
 	return $self->{countdown_sec};
 }
 
-sub destination {
-	my ($self) = @_;
-
-	return $self->{route_end};
-}
-
 sub line {
 	my ($self) = @_;
 
@@ -205,12 +234,6 @@ sub messages {
 	return;
 }
 
-sub origin {
-	my ($self) = @_;
-
-	return $self->{route_end};
-}
-
 sub platform {
 	my ($self) = @_;
 
@@ -226,6 +249,15 @@ sub polyline {
 	return;
 }
 
+sub route {
+	my ($self) = @_;
+
+	if ( $self->{route} ) {
+		return @{ $self->{route} };
+	}
+	return;
+}
+
 sub TO_JSON {
 	my ($self) = @_;
 
-- 
cgit v1.2.3