diff options
| author | Birte Kristina Friesel <derf@finalrewind.org> | 2023-07-15 13:28:54 +0200 | 
|---|---|---|
| committer | Birte Kristina Friesel <derf@finalrewind.org> | 2023-07-15 13:28:54 +0200 | 
| commit | b446b68e673e433cd7d964defcb5f6f6e96584a4 (patch) | |
| tree | 43afade7b50bcea1f784d414c4c521ecba1e0369 | |
| parent | d43c44e81c16ee7a4a2d178a507daa81c35e622a (diff) | |
Move InTransit post-processing to InTransit module
| -rwxr-xr-x | lib/Travelynx.pm | 188 | ||||
| -rw-r--r-- | lib/Travelynx/Model/InTransit.pm | 168 | 
2 files changed, 170 insertions, 186 deletions
| diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm index 9958b7e..42e1cd8 100755 --- a/lib/Travelynx.pm +++ b/lib/Travelynx.pm @@ -1415,78 +1415,11 @@ sub startup {  				with_data       => 1,  				with_timestamps => 1,  				with_visibility => 1, +				postprocess     => 1,  			);  			if ($in_transit) { - -				my @route = @{ $in_transit->{route} // [] }; -				my @route_after; -				my $dep_info; -				my $stop_before_dest; -				my $is_after = 0; -				for my $station (@route) { - -					if (    $in_transit->{arr_name} -						and @route_after -						and $station->[0] eq $in_transit->{arr_name} ) -					{ -						$stop_before_dest = $route_after[-1][0]; -					} -					if ($is_after) { -						push( @route_after, $station ); -					} -					if (    $in_transit->{dep_name} -						and $station->[0] eq $in_transit->{dep_name} ) -					{ -						$is_after = 1; -						if ( @{$station} > 1 and not $dep_info ) { -							$dep_info = $station->[2]; -						} -					} -				} -				my $stop_after_dep = @route_after ? $route_after[0][0] : undef; - -				my $ts = $in_transit->{checkout_ts} -				  // $in_transit->{checkin_ts}; -				my $action_time = epoch_to_dt($ts); - -				my $ret = { -					checked_in         => !$in_transit->{cancelled}, -					cancelled          => $in_transit->{cancelled}, -					timestamp          => $action_time, -					timestamp_delta    => $now->epoch - $action_time->epoch, -					train_type         => $in_transit->{train_type}, -					train_line         => $in_transit->{train_line}, -					train_no           => $in_transit->{train_no}, -					train_id           => $in_transit->{train_id}, -					boarding_countdown => -1, -					sched_departure    => -					  epoch_to_dt( $in_transit->{sched_dep_ts} ), -					real_departure => epoch_to_dt( $in_transit->{real_dep_ts} ), -					dep_ds100      => $in_transit->{dep_ds100}, -					dep_eva        => $in_transit->{dep_eva}, -					dep_name       => $in_transit->{dep_name}, -					dep_lat        => $in_transit->{dep_lat}, -					dep_lon        => $in_transit->{dep_lon}, -					dep_platform   => $in_transit->{dep_platform}, -					sched_arrival => epoch_to_dt( $in_transit->{sched_arr_ts} ), -					real_arrival  => epoch_to_dt( $in_transit->{real_arr_ts} ), -					arr_ds100     => $in_transit->{arr_ds100}, -					arr_eva       => $in_transit->{arr_eva}, -					arr_name      => $in_transit->{arr_name}, -					arr_lat       => $in_transit->{arr_lat}, -					arr_lon       => $in_transit->{arr_lon}, -					arr_platform  => $in_transit->{arr_platform}, -					route_after   => \@route_after, -					messages      => $in_transit->{messages}, -					extra_data    => $in_transit->{data}, -					comment       => $in_transit->{user_data}{comment}, -					visibility    => $in_transit->{visibility}, -					visibility_str       => $in_transit->{visibility_str}, -					effective_visibility => $in_transit->{effective_visibility}, -					effective_visibility_str => -					  $in_transit->{effective_visibility_str}, -				}; +				my $ret = $in_transit;  				my $traewelling = $self->traewelling->get(  					uid => $uid, @@ -1509,66 +1442,6 @@ sub startup {  					}  				} -				my @parsed_messages; -				for my $message ( @{ $ret->{messages} // [] } ) { -					my ( $ts, $msg ) = @{$message}; -					push( @parsed_messages, [ epoch_to_dt($ts), $msg ] ); -				} -				$ret->{messages} = [ reverse @parsed_messages ]; - -				@parsed_messages = (); -				for my $message ( @{ $ret->{extra_data}{qos_msg} // [] } ) { -					my ( $ts, $msg ) = @{$message}; -					push( @parsed_messages, [ epoch_to_dt($ts), $msg ] ); -				} -				$ret->{extra_data}{qos_msg} = [@parsed_messages]; - -				if ( $dep_info and $dep_info->{sched_arr} ) { -					$dep_info->{sched_arr} -					  = epoch_to_dt( $dep_info->{sched_arr} ); -					$dep_info->{rt_arr} = epoch_to_dt( $dep_info->{rt_arr} ); -					$dep_info->{rt_arr_countdown} = $ret->{boarding_countdown} -					  = $dep_info->{rt_arr}->epoch - $epoch; -				} - -				for my $station (@route_after) { -					if ( @{$station} > 1 ) { - -                     # Note: $station->[2]{sched_arr} may already have been -                     # converted to a DateTime object. This can happen when a -                     # station is present several times in a train's route, e.g. -                     # for Frankfurt Flughafen in some nightly connections. -						my $times = $station->[2] // {}; -						if ( $times->{sched_arr} -							and ref( $times->{sched_arr} ) ne 'DateTime' ) -						{ -							$times->{sched_arr} -							  = epoch_to_dt( $times->{sched_arr} ); -							if ( $times->{rt_arr} ) { -								$times->{rt_arr} -								  = epoch_to_dt( $times->{rt_arr} ); -								$times->{rt_arr_countdown} -								  = $times->{rt_arr}->epoch - $epoch; -							} -						} -						if ( $times->{sched_dep} -							and ref( $times->{sched_dep} ) ne 'DateTime' ) -						{ -							$times->{sched_dep} -							  = epoch_to_dt( $times->{sched_dep} ); -							if ( $times->{rt_dep} ) { -								$times->{rt_dep} -								  = epoch_to_dt( $times->{rt_dep} ); -								$times->{rt_dep_countdown} -								  = $times->{rt_dep}->epoch - $epoch; -							} -						} -					} -				} - -				$ret->{departure_countdown} -				  = $ret->{real_departure}->epoch - $now->epoch; -  				if (    $ret->{departure_countdown} > 0  					and $in_transit->{data}{wagonorder_dep} )  				{ @@ -1586,63 +1459,6 @@ sub startup {  					}  				} -				if ( $in_transit->{real_arr_ts} ) { -					$ret->{arrival_countdown} -					  = $ret->{real_arrival}->epoch - $now->epoch; -					$ret->{journey_duration} -					  = $ret->{real_arrival}->epoch -					  - $ret->{real_departure}->epoch; -					$ret->{journey_completion} -					  = $ret->{journey_duration} -					  ? 1 -					  - ( $ret->{arrival_countdown} / $ret->{journey_duration} ) -					  : 1; -					if ( $ret->{journey_completion} > 1 ) { -						$ret->{journey_completion} = 1; -					} -					elsif ( $ret->{journey_completion} < 0 ) { -						$ret->{journey_completion} = 0; -					} - -					my ($dep_platform_number) -					  = ( ( $ret->{dep_platform} // 0 ) =~ m{(\d+)} ); -					if ( $dep_platform_number -						and exists $in_transit->{data}{stationinfo_dep} -						{$dep_platform_number} ) -					{ -						$ret->{dep_direction} -						  = $self->stationinfo_to_direction( -							$in_transit->{data}{stationinfo_dep} -							  {$dep_platform_number}, -							$in_transit->{data}{wagonorder_dep}, -							undef, -							$stop_after_dep -						  ); -					} - -					my ($arr_platform_number) -					  = ( ( $ret->{arr_platform} // 0 ) =~ m{(\d+)} ); -					if ( $arr_platform_number -						and exists $in_transit->{data}{stationinfo_arr} -						{$arr_platform_number} ) -					{ -						$ret->{arr_direction} -						  = $self->stationinfo_to_direction( -							$in_transit->{data}{stationinfo_arr} -							  {$arr_platform_number}, -							$in_transit->{data}{wagonorder_arr}, -							$stop_before_dest, -							undef -						  ); -					} - -				} -				else { -					$ret->{arrival_countdown}  = undef; -					$ret->{journey_duration}   = undef; -					$ret->{journey_completion} = undef; -				} -  				return $ret;  			} diff --git a/lib/Travelynx/Model/InTransit.pm b/lib/Travelynx/Model/InTransit.pm index 81d4a24..072c7f4 100644 --- a/lib/Travelynx/Model/InTransit.pm +++ b/lib/Travelynx/Model/InTransit.pm @@ -27,6 +27,20 @@ my %visibility_atoi = (  	private   => 10,  ); +sub epoch_to_dt { +	my ($epoch) = @_; + +	# Bugs (and user errors) may lead to undefined timestamps. Set them to +	# 1970-01-01 to avoid crashing and show obviously wrong data instead. +	$epoch //= 0; + +	return DateTime->from_epoch( +		epoch     => $epoch, +		time_zone => 'Europe/Berlin', +		locale    => 'de-DE', +	); +} +  sub new {  	my ( $class, %opt ) = @_; @@ -151,6 +165,160 @@ sub get {  		  = $visibility_itoa{ $ret->{effective_visibility} };  	} +	if ( $opt{postprocess} and $ret ) { +		my $now   = DateTime->now( time_zone => 'Europe/Berlin' ); +		my $epoch = $now->epoch; +		my @route = @{ $ret->{route} // [] }; +		my @route_after; +		my $dep_info; +		my $stop_before_dest; +		my $is_after = 0; +		for my $station (@route) { + +			if (    $ret->{arr_name} +				and @route_after +				and $station->[0] eq $ret->{arr_name} ) +			{ +				$stop_before_dest = $route_after[-1][0]; +			} +			if ($is_after) { +				push( @route_after, $station ); +			} +			if (    $ret->{dep_name} +				and $station->[0] eq $ret->{dep_name} ) +			{ +				$is_after = 1; +				if ( @{$station} > 1 and not $dep_info ) { +					$dep_info = $station->[2]; +				} +			} +		} +		my $stop_after_dep = @route_after ? $route_after[0][0] : undef; + +		my $ts          = $ret->{checkout_ts} // $ret->{checkin_ts}; +		my $action_time = epoch_to_dt($ts); + +		$ret->{checked_in}         = !$ret->{cancelled}; +		$ret->{timestamp}          = $action_time; +		$ret->{timestamp_delta}    = $now->epoch - $action_time->epoch; +		$ret->{boarding_countdown} = -1; +		$ret->{sched_departure}    = epoch_to_dt( $ret->{sched_dep_ts} ); +		$ret->{real_departure}     = epoch_to_dt( $ret->{real_dep_ts} ); +		$ret->{sched_arrival}      = epoch_to_dt( $ret->{sched_arr_ts} ); +		$ret->{real_arrival}       = epoch_to_dt( $ret->{real_arr_ts} ); +		$ret->{route_after}        = \@route_after; +		$ret->{extra_data}         = $ret->{data}; +		$ret->{comment}            = $ret->{user_data}{comment}; + +		my @parsed_messages; +		for my $message ( @{ $ret->{messages} // [] } ) { +			my ( $ts, $msg ) = @{$message}; +			push( @parsed_messages, [ epoch_to_dt($ts), $msg ] ); +		} +		$ret->{messages} = [ reverse @parsed_messages ]; + +		@parsed_messages = (); +		for my $message ( @{ $ret->{extra_data}{qos_msg} // [] } ) { +			my ( $ts, $msg ) = @{$message}; +			push( @parsed_messages, [ epoch_to_dt($ts), $msg ] ); +		} +		$ret->{extra_data}{qos_msg} = [@parsed_messages]; + +		if ( $dep_info and $dep_info->{sched_arr} ) { +			$dep_info->{sched_arr} +			  = epoch_to_dt( $dep_info->{sched_arr} ); +			$dep_info->{rt_arr}           = epoch_to_dt( $dep_info->{rt_arr} ); +			$dep_info->{rt_arr_countdown} = $ret->{boarding_countdown} +			  = $dep_info->{rt_arr}->epoch - $epoch; +		} + +		for my $station (@route_after) { +			if ( @{$station} > 1 ) { + +				# Note: $station->[2]{sched_arr} may already have been +				# converted to a DateTime object. This can happen when a +				# station is present several times in a train's route, e.g. +				# for Frankfurt Flughafen in some nightly connections. +				my $times = $station->[2] // {}; +				if ( $times->{sched_arr} +					and ref( $times->{sched_arr} ) ne 'DateTime' ) +				{ +					$times->{sched_arr} +					  = epoch_to_dt( $times->{sched_arr} ); +					if ( $times->{rt_arr} ) { +						$times->{rt_arr} +						  = epoch_to_dt( $times->{rt_arr} ); +						$times->{rt_arr_countdown} +						  = $times->{rt_arr}->epoch - $epoch; +					} +				} +				if ( $times->{sched_dep} +					and ref( $times->{sched_dep} ) ne 'DateTime' ) +				{ +					$times->{sched_dep} +					  = epoch_to_dt( $times->{sched_dep} ); +					if ( $times->{rt_dep} ) { +						$times->{rt_dep} +						  = epoch_to_dt( $times->{rt_dep} ); +						$times->{rt_dep_countdown} +						  = $times->{rt_dep}->epoch - $epoch; +					} +				} +			} +		} + +		$ret->{departure_countdown} +		  = $ret->{real_departure}->epoch - $now->epoch; + +		if ( $ret->{real_arr_ts} ) { +			$ret->{arrival_countdown} +			  = $ret->{real_arrival}->epoch - $now->epoch; +			$ret->{journey_duration} +			  = $ret->{real_arrival}->epoch - $ret->{real_departure}->epoch; +			$ret->{journey_completion} +			  = $ret->{journey_duration} +			  ? 1 - ( $ret->{arrival_countdown} / $ret->{journey_duration} ) +			  : 1; +			if ( $ret->{journey_completion} > 1 ) { +				$ret->{journey_completion} = 1; +			} +			elsif ( $ret->{journey_completion} < 0 ) { +				$ret->{journey_completion} = 0; +			} + +			my ($dep_platform_number) +			  = ( ( $ret->{dep_platform} // 0 ) =~ m{(\d+)} ); +			if ( $dep_platform_number +				and exists $ret->{data}{stationinfo_dep}{$dep_platform_number} ) +			{ +				$ret->{dep_direction} = $self->stationinfo_to_direction( +					$ret->{data}{stationinfo_dep}{$dep_platform_number}, +					$ret->{data}{wagonorder_dep}, +					undef, $stop_after_dep +				); +			} + +			my ($arr_platform_number) +			  = ( ( $ret->{arr_platform} // 0 ) =~ m{(\d+)} ); +			if ( $arr_platform_number +				and exists $ret->{data}{stationinfo_arr}{$arr_platform_number} ) +			{ +				$ret->{arr_direction} = $self->stationinfo_to_direction( +					$ret->{data}{stationinfo_arr}{$arr_platform_number}, +					$ret->{data}{wagonorder_arr}, +					$stop_before_dest, undef +				); +			} + +		} +		else { +			$ret->{arrival_countdown}  = undef; +			$ret->{journey_duration}   = undef; +			$ret->{journey_completion} = undef; +		} + +	} +  	return $ret;  } | 
