Unverified Commit 83954508 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

move get_connecting_trains helper to Traveling controller

parent 17126940
Loading
Loading
Loading
Loading
+0 −175
Original line number Diff line number Diff line
@@ -1368,181 +1368,6 @@ sub startup {
		}
	);

	$self->helper(
		'get_connecting_trains' => sub {
			my ( $self, %opt ) = @_;

			my $uid         = $opt{uid} //= $self->current_user->{id};
			my $use_history = $self->users->use_history( uid => $uid );

			my ( $eva, $exclude_via, $exclude_train_id, $exclude_before );
			my $now = $self->now->epoch;
			my ( $stationinfo, $arr_epoch, $arr_platform );

			if ( $opt{eva} ) {
				if ( $use_history & 0x01 ) {
					$eva = $opt{eva};
				}
				elsif ( $opt{destination_name} ) {
					$eva = $opt{eva};
				}
			}
			else {
				if ( $use_history & 0x02 ) {
					my $status = $self->get_user_status;
					$eva              = $status->{arr_eva};
					$exclude_via      = $status->{dep_name};
					$exclude_train_id = $status->{train_id};
					$arr_platform     = $status->{arr_platform};
					$stationinfo      = $status->{extra_data}{stationinfo_arr};
					if ( $status->{real_arrival} ) {
						$exclude_before = $arr_epoch
						  = $status->{real_arrival}->epoch;
					}
				}
			}

			$exclude_before //= $now - 300;

			if ( not $eva ) {
				return;
			}

			my @destinations = $self->journeys->get_connection_targets(%opt);

			if ($exclude_via) {
				@destinations = grep { $_ ne $exclude_via } @destinations;
			}

			if ( not @destinations ) {
				return;
			}

			my $stationboard = $self->iris->get_departures(
				station      => $eva,
				lookbehind   => 10,
				lookahead    => 40,
				with_related => 1
			);
			if ( $stationboard->{errstr} ) {
				return;
			}
			@{ $stationboard->{results} } = map { $_->[0] }
			  sort { $a->[1] <=> $b->[1] }
			  map  { [ $_, $_->departure ? $_->departure->epoch : 0 ] }
			  @{ $stationboard->{results} };
			my @results;
			my @cancellations;
			my %via_count = map { $_ => 0 } @destinations;
			for my $train ( @{ $stationboard->{results} } ) {
				if ( not $train->departure ) {
					next;
				}
				if (    $exclude_before
					and $train->departure
					and $train->departure->epoch < $exclude_before )
				{
					next;
				}
				if (    $exclude_train_id
					and $train->train_id eq $exclude_train_id )
				{
					next;
				}

             # In general, this function is meant to return feasible
             # connections. However, cancelled connections may also be of
             # interest and are also useful for logging cancellations.
             # To satisfy both demands with (hopefully) little confusion and
             # UI clutter, this function returns two concatenated arrays:
             # actual connections (ordered by actual departure time) followed
             # by cancelled connections (ordered by scheduled departure time).
             # This is easiest to achieve in two separate loops.
             #
             # Note that a cancelled train may still have a matching destination
             # in its route_post, e.g. if it leaves out $eva due to
             # unscheduled route changes but continues on schedule afterwards
             # -- so it is only cancelled at $eva, not on the remainder of
             # the route. Also note that this specific case is not yet handled
             # properly by the cancellation logic etc.

				if ( $train->departure_is_cancelled ) {
					my @via
					  = ( $train->sched_route_post, $train->sched_route_end );
					for my $dest (@destinations) {
						if ( List::Util::any { $_ eq $dest } @via ) {
							push( @cancellations, [ $train, $dest ] );
							next;
						}
					}
				}
				else {
					my @via = ( $train->route_post, $train->route_end );
					for my $dest (@destinations) {
						if ( $via_count{$dest} < 2
							and List::Util::any { $_ eq $dest } @via )
						{
							push( @results, [ $train, $dest ] );

                 # Show all past and up to two future departures per destination
							if ( not $train->departure
								or $train->departure->epoch >= $now )
							{
								$via_count{$dest}++;
							}
							next;
						}
					}
				}
			}

			@results = map { $_->[0] }
			  sort { $a->[1] <=> $b->[1] }
			  map {
				[
					$_,
					$_->[0]->departure->epoch // $_->[0]->sched_departure->epoch
				]
			  } @results;
			@cancellations = map { $_->[0] }
			  sort { $a->[1] <=> $b->[1] }
			  map { [ $_, $_->[0]->sched_departure->epoch ] } @cancellations;

			for my $result (@results) {
				my $train = $result->[0];
				my @message_ids
				  = List::Util::uniq map { $_->[1] } $train->raw_messages;
				$train->{message_id} = { map { $_ => 1 } @message_ids };
				my $interchange_duration;
				if ( exists $stationinfo->{i} ) {
					$interchange_duration
					  = $stationinfo->{i}{$arr_platform}{ $train->platform };
					$interchange_duration //= $stationinfo->{i}{"*"};
				}
				if ( defined $interchange_duration ) {
					my $interchange_time
					  = ( $train->departure->epoch - $arr_epoch ) / 60;
					if ( $interchange_time < $interchange_duration ) {
						$train->{interchange_text} = 'Anschluss knapp';
						$train->{interchange_icon} = 'warning';
					}
					elsif ( $interchange_time == $interchange_duration ) {
						$train->{interchange_text}
						  = 'Anschluss könnte knapp werden';
						$train->{interchange_icon} = 'directions_run';
					}

       #else {
       #	$train->{interchange_text} = 'Anschluss wird voraussichtlich erreicht';
       #	$train->{interchange_icon} = 'check';
       #}
				}
			}

			return ( @results, @cancellations );
		}
	);

	$self->helper(
		'stationinfo_to_direction' => sub {
			my ( $self, $platform_info, $wagonorder, $prev_stop, $next_stop )
+166 −0
Original line number Diff line number Diff line
@@ -1476,4 +1476,170 @@ sub add_journey_form {
	}
}

sub get_connecting_trains {
	my ( $self, %opt ) = @_;

	my $uid         = $opt{uid} //= $self->current_user->{id};
	my $use_history = $self->users->use_history( uid => $uid );

	my ( $eva, $exclude_via, $exclude_train_id, $exclude_before );
	my $now = $self->now->epoch;
	my ( $stationinfo, $arr_epoch, $arr_platform );

	if ( $opt{eva} ) {
		if ( $use_history & 0x01 ) {
			$eva = $opt{eva};
		}
		elsif ( $opt{destination_name} ) {
			$eva = $opt{eva};
		}
	}
	else {
		if ( $use_history & 0x02 ) {
			my $status = $self->get_user_status;
			$eva              = $status->{arr_eva};
			$exclude_via      = $status->{dep_name};
			$exclude_train_id = $status->{train_id};
			$arr_platform     = $status->{arr_platform};
			$stationinfo      = $status->{extra_data}{stationinfo_arr};
			if ( $status->{real_arrival} ) {
				$exclude_before = $arr_epoch = $status->{real_arrival}->epoch;
			}
		}
	}

	$exclude_before //= $now - 300;

	if ( not $eva ) {
		return;
	}

	my @destinations = $self->journeys->get_connection_targets(%opt);

	if ($exclude_via) {
		@destinations = grep { $_ ne $exclude_via } @destinations;
	}

	if ( not @destinations ) {
		return;
	}

	my $stationboard = $self->iris->get_departures(
		station      => $eva,
		lookbehind   => 10,
		lookahead    => 40,
		with_related => 1
	);
	if ( $stationboard->{errstr} ) {
		return;
	}
	@{ $stationboard->{results} } = map { $_->[0] }
	  sort { $a->[1] <=> $b->[1] }
	  map  { [ $_, $_->departure ? $_->departure->epoch : 0 ] }
	  @{ $stationboard->{results} };
	my @results;
	my @cancellations;
	my %via_count = map { $_ => 0 } @destinations;
	for my $train ( @{ $stationboard->{results} } ) {
		if ( not $train->departure ) {
			next;
		}
		if (    $exclude_before
			and $train->departure
			and $train->departure->epoch < $exclude_before )
		{
			next;
		}
		if (    $exclude_train_id
			and $train->train_id eq $exclude_train_id )
		{
			next;
		}

		# In general, this function is meant to return feasible
		# connections. However, cancelled connections may also be of
		# interest and are also useful for logging cancellations.
		# To satisfy both demands with (hopefully) little confusion and
		# UI clutter, this function returns two concatenated arrays:
		# actual connections (ordered by actual departure time) followed
		# by cancelled connections (ordered by scheduled departure time).
		# This is easiest to achieve in two separate loops.
		#
		# Note that a cancelled train may still have a matching destination
		# in its route_post, e.g. if it leaves out $eva due to
		# unscheduled route changes but continues on schedule afterwards
		# -- so it is only cancelled at $eva, not on the remainder of
		# the route. Also note that this specific case is not yet handled
		# properly by the cancellation logic etc.

		if ( $train->departure_is_cancelled ) {
			my @via = ( $train->sched_route_post, $train->sched_route_end );
			for my $dest (@destinations) {
				if ( List::Util::any { $_ eq $dest } @via ) {
					push( @cancellations, [ $train, $dest ] );
					next;
				}
			}
		}
		else {
			my @via = ( $train->route_post, $train->route_end );
			for my $dest (@destinations) {
				if ( $via_count{$dest} < 2
					and List::Util::any { $_ eq $dest } @via )
				{
					push( @results, [ $train, $dest ] );

                 # Show all past and up to two future departures per destination
					if ( not $train->departure
						or $train->departure->epoch >= $now )
					{
						$via_count{$dest}++;
					}
					next;
				}
			}
		}
	}

	@results = map { $_->[0] }
	  sort { $a->[1] <=> $b->[1] }
	  map {
		[ $_, $_->[0]->departure->epoch // $_->[0]->sched_departure->epoch ]
	  } @results;
	@cancellations = map { $_->[0] }
	  sort { $a->[1] <=> $b->[1] }
	  map { [ $_, $_->[0]->sched_departure->epoch ] } @cancellations;

	for my $result (@results) {
		my $train       = $result->[0];
		my @message_ids = List::Util::uniq map { $_->[1] } $train->raw_messages;
		$train->{message_id} = { map { $_ => 1 } @message_ids };
		my $interchange_duration;
		if ( exists $stationinfo->{i} ) {
			$interchange_duration
			  = $stationinfo->{i}{$arr_platform}{ $train->platform };
			$interchange_duration //= $stationinfo->{i}{"*"};
		}
		if ( defined $interchange_duration ) {
			my $interchange_time
			  = ( $train->departure->epoch - $arr_epoch ) / 60;
			if ( $interchange_time < $interchange_duration ) {
				$train->{interchange_text} = 'Anschluss knapp';
				$train->{interchange_icon} = 'warning';
			}
			elsif ( $interchange_time == $interchange_duration ) {
				$train->{interchange_text} = 'Anschluss könnte knapp werden';
				$train->{interchange_icon} = 'directions_run';
			}

       #else {
       #	$train->{interchange_text} = 'Anschluss wird voraussichtlich erreicht';
       #	$train->{interchange_icon} = 'check';
       #}
		}
	}

	return ( @results, @cancellations );
}

1;