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

add hafas (bus, ubahn, tram) support

parent a3210970
Loading
Loading
Loading
Loading
+287 −108
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ use List::MoreUtils qw();
use Mojo::JSON      qw(decode_json);
use Mojo::Promise;
use Mojo::UserAgent;
use Travel::Status::DE::HAFAS;
use Travel::Status::DE::IRIS;
use Travel::Status::DE::IRIS::Stations;
use XML::LibXML;
@@ -186,11 +187,15 @@ sub result_has_via {
}

sub log_api_access {
	my ($suffix) = @_;
	$suffix //= q{};

	my $file    = "$ENV{DBFAKEDISPLAY_STATS}${suffix}";
	my $counter = 1;
	if ( -r $ENV{DBFAKEDISPLAY_STATS} ) {
		$counter = read_file( $ENV{DBFAKEDISPLAY_STATS} ) + 1;
	if ( -r $file ) {
		$counter = read_file($file) + 1;
	}
	write_file( $ENV{DBFAKEDISPLAY_STATS}, $counter );
	write_file( $file, $counter );
	return;
}

@@ -261,6 +266,19 @@ sub get_results_p {
	my ( $station, %opt ) = @_;
	my $data;

	if ( $opt{hafas} ) {
		return Travel::Status::DE::HAFAS->new_p(
			station     => $station,
			cache       => $opt{cache_iris_rt},
			lwp_options => {
				timeout => 10,
				agent   => 'dbf.finalrewind.org/2'
			},
			promise    => 'Mojo::Promise',
			user_agent => Mojo::UserAgent->new,
		);
	}

	if ( $ENV{DBFAKEDISPLAY_STATS} ) {
		log_api_access();
	}
@@ -309,11 +327,13 @@ sub handle_request {
	my $station = $self->stash('station');

	my $template     = $self->param('mode') // 'app';
	my $hafas        = !!$self->param('hafas');
	my $with_related = !$self->param('no_related');
	my %opt          = (
		cache_iris_main => $self->app->cache_iris_main,
		cache_iris_rt   => $self->app->cache_iris_rt,
		lookahead       => $self->config->{lookahead}
		lookahead       => $self->config->{lookahead},
		hafas           => $hafas,
	);

	if ( $self->param('past') ) {
@@ -531,6 +551,7 @@ sub render_train {
	my ( $self, $result, $departure, $station_name, $template ) = @_;

	$departure->{links} = [];
	if ( $result->can('route_pre') ) {
		$departure->{route_pre_diff} = [
			$self->json_route_diff(
				[ $result->route_pre ],
@@ -543,6 +564,7 @@ sub render_train {
				[ $result->sched_route_post ]
			)
		];
	}

	if ( not $result->has_realtime ) {
		my $now = DateTime->now( time_zone => 'Europe/Berlin' );
@@ -555,6 +577,8 @@ sub render_train {
	}

	my $linetype = 'bahn';

	if ( $result->can('classes') ) {
		my @classes = $result->classes;
		if ( @classes == 0 ) {
			$linetype = 'ext';
@@ -565,6 +589,24 @@ sub render_train {
		elsif ( grep { $_ eq 'F' } @classes ) {
			$linetype = 'fern';
		}
	}
	elsif ( $result->can('class') ) {
		if ( $result->class <= 2 ) {
			$linetype = 'fern';
		}
		elsif ( $result->class == 16 ) {
			$linetype = 'sbahn';
		}
		elsif ( $result->class == 32 ) {
			$linetype = 'bus';
		}
		elsif ( $result->class == 128 ) {
			$linetype = 'ubahn';
		}
		elsif ( $result->class == 256 ) {
			$linetype = 'tram';
		}
	}

	$self->render_later;

@@ -965,8 +1007,6 @@ sub train_details {
	my ($self) = @_;
	my $train = $self->stash('train');

	my ( $train_type, $train_no ) = ( $train =~ m{ ^ (\S+) \s+ (.*) $ }x );

	# TODO error handling

	if ( $self->param('ajax') ) {
@@ -980,9 +1020,9 @@ sub train_details {
	$self->stash( version    => $self->config->{version} );

	my $res = {
		train_type      => $train_type,
		train_type      => undef,
		train_line      => undef,
		train_no        => $train_no,
		train_no        => undef,
		route_pre_diff  => [],
		route_post_diff => [],
		moreinfo        => [],
@@ -990,22 +1030,38 @@ sub train_details {
		replacement_for => [],
	};

	my %opt;

	if ( $train =~ m{[|]} ) {
		$opt{trip_id} = $train;
	}
	else {
		my ( $train_type, $train_no ) = ( $train =~ m{ ^ (\S+) \s+ (.*) $ }x );
		$res->{train_type} = $train_type;
		$res->{train_no}   = $train_no;
		$self->stash( title => "${train_type} ${train_no}" );
	$self->stash( hide_opts => 1 );
		$opt{train_type} = $train_type;
		$opt{train_no}   = $train_no;
	}

	$self->stash( hide_opts => 1 );
	$self->render_later;

	my $linetype = 'bahn';

	$self->hafas->get_route_timestamps_p(
		train_type => $train_type,
		train_no   => $train_no
	)->then(
	$self->hafas->get_route_timestamps_p(%opt)->then(
		sub {
			my ( $route_ts, $journey ) = @_;

			$res->{trip_id} = $journey->id;

			if ( not $res->{train_type} ) {
				my $train_type = $res->{train_type} = $journey->type   // q{};
				my $train_no   = $res->{train_no}   = $journey->number // q{};
				$res->{train_line} = $journey->line_no // q{};
				$self->stash( title => "${train_type} ${train_no}" );
			}

			if ( not defined $journey->class ) {
				$linetype = 'ext';
			}
@@ -1018,6 +1074,15 @@ sub train_details {
			elsif ( $journey->class <= 16 ) {
				$linetype = 'sbahn';
			}
			elsif ( $journey->class == 32 ) {
				$linetype = 'bus';
			}
			elsif ( $journey->class == 128 ) {
				$linetype = 'ubahn';
			}
			elsif ( $journey->class == 256 ) {
				$linetype = 'tram';
			}

			$res->{origin}      = $journey->route_start;
			$res->{destination} = $journey->route_end;
@@ -1031,6 +1096,45 @@ sub train_details {
				}
			}

			if ( my $req_name = $self->param('highlight') ) {
				my $split;
				for my $i ( 0 .. $#{ $res->{route_post_diff} } ) {
					if ( $res->{route_post_diff}[$i]{name} eq $req_name ) {
						$split = $i;
					}
				}
				if ( defined $split ) {
					$self->stash( station_name => $req_name );
					for my $i ( 0 .. $split - 1 ) {
						push(
							@{ $res->{route_pre_diff} },
							shift( @{ $res->{route_post_diff} } )
						);
					}
					my $station_info = shift( @{ $res->{route_post_diff} } );
					if ( $station_info->{sched_arr} ) {
						$res->{sched_arrival}
						  = $station_info->{sched_arr}->strftime('%H:%M');
					}
					if ( $station_info->{rt_arr} ) {
						$res->{arrival}
						  = $station_info->{rt_arr}->strftime('%H:%M');
					}
					if ( $station_info->{sched_dep} ) {
						$res->{sched_departure}
						  = $station_info->{sched_dep}->strftime('%H:%M');
					}
					if ( $station_info->{rt_dep} ) {
						$res->{departure}
						  = $station_info->{rt_dep}->strftime('%H:%M');
					}
					$res->{arrival_is_cancelled}
					  = $station_info->{arr_cancelled};
					$res->{departure_is_cancelled}
					  = $station_info->{dep_cancelled};
				}
			}

			my @him_messages;
			my @him_details;
			for my $message ( $journey->messages ) {
@@ -1184,12 +1288,19 @@ sub handle_result {
		{
			next;
		}
		my ( $info, $moreinfo )
		my ( $info, $moreinfo );
		if ( $result->can('replacement_for') ) {
			( $info, $moreinfo )
			  = $self->format_iris_result_info( $template, $result );
		}

		my $time     = $result->time;
		my $time
		  = $result->can('time')
		  ? $result->time
		  : $result->sched_datetime->strftime('%H:%M');
		my $linetype = 'bahn';

		if ( $result->can('classes') ) {
			my @classes = $result->classes;
			if ( @classes == 0 ) {
				$linetype = 'ext';
@@ -1200,6 +1311,24 @@ sub handle_result {
			elsif ( grep { $_ eq 'F' } @classes ) {
				$linetype = 'fern';
			}
		}
		elsif ( $result->can('class') ) {
			if ( $result->class <= 2 ) {
				$linetype = 'fern';
			}
			elsif ( $result->class == 16 ) {
				$linetype = 'sbahn';
			}
			elsif ( $result->class == 32 ) {
				$linetype = 'bus';
			}
			elsif ( $result->class == 128 ) {
				$linetype = 'ubahn';
			}
			elsif ( $result->class == 256 ) {
				$linetype = 'tram';
			}
		}

		# ->time defaults to dep, so we only need to overwrite $time
		# if we want arrival times
@@ -1319,6 +1448,7 @@ sub handle_result {
			);
		}
		else {
			if ( $result->can('replacement_for') ) {
				push(
					@departures,
					{
@@ -1346,17 +1476,26 @@ sub handle_result {
						scheduled_platform => $result->sched_platform,
						info               => $info,
						is_cancelled       => $result->is_cancelled,
					departure_is_cancelled => $result->departure_is_cancelled,
						departure_is_cancelled =>
						  $result->departure_is_cancelled,
						arrival_is_cancelled => $result->arrival_is_cancelled,
						linetype             => $linetype,
						messages             => {
							delay => [
							map { { timestamp => $_->[0], text => $_->[1] } }
							  $result->delay_messages
								map {
									{
										timestamp => $_->[0],
										text      => $_->[1]
									}
								} $result->delay_messages
							],
							qos => [
							map { { timestamp => $_->[0], text => $_->[1] } }
							  $result->qos_messages
								map {
									{
										timestamp => $_->[0],
										text      => $_->[1]
									}
								} $result->qos_messages
							],
						},
						station          => $result->station,
@@ -1383,6 +1522,46 @@ sub handle_result {
						: undef,
					}
				);
			}
			else {
				push(
					@departures,
					{
						time            => $time,
						sched_departure => $result->sched_datetime
						? $result->sched_datetime->strftime('%H:%M')
						: undef,
						departure => $result->rt_datetime
						? $result->rt_datetime->strftime('%H:%M')
						: undef,
						train      => $result->name,
						train_type => q{},
						train_line => $result->line,
						train_no   => $result->number,
						journey_id => $result->id,
						via        =>
						  [ map { $_->{name} } $result->route_interesting(3) ],
						destination        => $result->destination,
						origin             => $result->origin,
						platform           => $result->platform,
						scheduled_platform => $result->sched_platform,
						info               => $info,
						is_cancelled       => $result->is_cancelled
						  || $result->is_partially_cancelled,
						linetype        => $linetype,
						station         => $result->station,
						moreinfo        => $moreinfo,
						delay           => $delay,
						replaced_by     => [],
						replacement_for => [],
						route_pre       => [],
						route_post => [ map { $_->{name} } $result->route ],
						wr_link    => $result->sched_datetime
						? $result->sched_datetime->strftime('%Y%m%d%H%M')
						: undef,
					}
				);
			}
			if ( $self->param('train') ) {
				$self->render_train( $result, $departures[-1],
					$data->{station_name} // $self->stash('station') );
+17 −3
Original line number Diff line number Diff line
@@ -181,7 +181,19 @@ sub get_route_timestamps_p {
	my $promise = Mojo::Promise->new;
	my $now     = DateTime->now( time_zone => 'Europe/Berlin' );

	if ( $opt{train} ) {
	my $hafas_promise;

	if ( $opt{trip_id} ) {
		$hafas_promise = Travel::Status::DE::HAFAS->new_p(
			journey => {
				id => $opt{trip_id},
			},
			cache      => $self->{realtime_cache},
			promise    => 'Mojo::Promise',
			user_agent => $self->{user_agent}->request_timeout(10)
		);
	}
	elsif ( $opt{train} ) {
		$opt{date_yy}      = $opt{train}->start->strftime('%d.%m.%y');
		$opt{date_yyyy}    = $opt{train}->start->strftime('%d.%m.%Y');
		$opt{train_req}    = $opt{train}->type . ' ' . $opt{train}->train_no;
@@ -193,7 +205,7 @@ sub get_route_timestamps_p {
		$opt{date_yyyy} = $now->strftime('%d.%m.%Y');
	}

	$self->trainsearch_p(%opt)->then(
	$hafas_promise //= $self->trainsearch_p(%opt)->then(
		sub {
			my ($trainsearch_result) = @_;
			my $trip_id = $trainsearch_result->{trip_id};
@@ -208,7 +220,9 @@ sub get_route_timestamps_p {
				user_agent => $self->{user_agent}->request_timeout(10)
			);
		}
	)->then(
	);

	$hafas_promise->then(
		sub {
			my ($hafas) = @_;
			my $journey = $hafas->result;
+10 −3
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ function dbf_show_moreinfo(trainElem, keep_old) {
	$('.moreinfo').each(function() {
		const infoElem = $(this);
		if (!keep_old) {
			$('.moreinfo .train-line').removeClass('bahn sbahn fern ext').addClass(trainElem.data('linetype'));
			$('.moreinfo .train-line').removeClass('sbahn fern ext ubahn bus tram').addClass(trainElem.data('linetype'));
			$('.moreinfo .train-line').text(trainElem.data('line'));
			$('.moreinfo .train-no').text(trainElem.data('no'));
			$('.moreinfo .train-origin').text(trainElem.data('from'));
@@ -80,7 +80,7 @@ function dbf_show_moreinfo(trainElem, keep_old) {
			}
			$('.moreinfo .mfooter').append('Fahrtverlauf: <ul class="mroute">' + routebuf + '</ul>');
		}
		$.get(window.location.href, {train: trainElem.data('train'), ajax: 1}, function(data) {
		$.get(window.location.href, {train: trainElem.data('train'), jid: trainElem.data('jid'), ajax: 1}, function(data) {
			$('.moreinfo').html(data);
		}).fail(function() {
			$('.moreinfo .mfooter').append('Der Zug ist abgefahren (Zug nicht gefunden)');
@@ -99,13 +99,20 @@ function dbf_reg_handlers() {
		if (window.location.href.includes('detailed=1')) {
			suffix += '&detailed=1';
		}
		if (window.location.href.includes('hafas=1')) {
			suffix += '&hafas=1&highlight=' + trainElem.data('station');
		}
		if (window.location.href.includes('past=1')) {
			suffix += '&past=1';
		}
		if (window.location.href.includes('rt=1') || window.location.href.includes('show_realtime=1')) {
			suffix += '&rt=1';
		}
		if (window.location.href.includes('hafas=1')) {
			history.pushState({'page':'traindetail','jid':trainElem.data('jid')}, 'test', '/z/' + trainElem.data('jid') + suffix);
		} else {
			history.pushState({'page':'traindetail','station':station,'train':trainElem.data('no')}, 'test', '/z/' + trainElem.data('train') + '/' + trainElem.data('station') + suffix);
		}
		dbf_show_moreinfo(trainElem, false);
	});
	const trainid = $(location).attr('hash').substr(1);
+4 −4
Original line number Diff line number Diff line
@@ -210,7 +210,7 @@
      <ul class="mroute">
%       for my $stop (@{$departure->{route_pre_diff}}) {
          <li class="<%= $stop->{isPast} ? 'past-stop' : 'future-stop' %>">
          <a href="<%= url_for('station', station => $stop->{eva} // $stop->{name})->query({detailed => param('detailed'), past => param('past'), rt => param('rt')}) %>#<%= ($departure->{train_type} // q{x}) . ($departure->{train_no} // q{x}) %>" class="
          <a href="<%= url_for('station', station => $stop->{eva} // $stop->{name})->query({detailed => param('detailed'), past => param('past'), rt => param('rt'), hafas => param('hafas')}) %>#<%= ($departure->{train_type} // q{x}) . ($departure->{train_no} // q{x}) %>" class="
%         if ($stop->{isAdditional}) {
            additional-stop
%         }
@@ -265,7 +265,7 @@
%       }
%       for my $stop (@{$departure->{route_post_diff}}) {
          <li class="<%= $stop->{isPast} ? 'past-stop' : 'future-stop' %>">
          <a href="<%= url_for('station', station => $stop->{eva} // $stop->{name})->query({detailed => param('detailed'), past => param('past'), rt => param('rt')}) %>#<%= ($departure->{train_type} // q{x}) . ($departure->{train_no} // q{x}) %>" class="
          <a href="<%= url_for('station', station => $stop->{eva} // $stop->{name})->query({detailed => param('detailed'), past => param('past'), rt => param('rt'), hafas => param('hafas')}) %>#<%= ($departure->{train_type} // q{x}) . ($departure->{train_no} // q{x}) %>" class="
%         if ($stop->{isAdditional}) {
            additional-stop
%         }
@@ -352,7 +352,7 @@
%           my $tt = $train->{type} // $train->{rawType} // 'Zug';
%           $tt =~ s{ .*|[0-9]}{};
%           if ($tt ne 'Zug') {
            <li><a href="<%= url_for('train', train => "$tt $train_no")->query({detailed => param('detailed'), past => param('past'), rt => param('rt')}) %>"><%= $tt %> <%= $train_no %></a>
            <li><a href="<%= url_for('train', train => "$tt $train_no")->query({detailed => param('detailed'), past => param('past'), rt => param('rt'), hafas => param('hafas')}) %>"><%= $tt %> <%= $train_no %></a>
%           }
%           else {
            <li><%= $tt %> <%= $train_no %>
@@ -377,7 +377,7 @@
%           my $tt = $train->{type} // $train->{rawType} // 'Zug';
%           $tt =~ s{ .*|[0-9]}{};
%           if ($tt ne 'Zug') {
            <li><a href="<%= url_for('train', train => "$tt $train_no")->query({detailed => param('detailed'), past => param('past'), rt => param('rt')}) %>"><%= $tt %> <%= $train_no %></a>
            <li><a href="<%= url_for('train', train => "$tt $train_no")->query({detailed => param('detailed'), past => param('past'), rt => param('rt'), hafas => param('hafas')}) %>"><%= $tt %> <%= $train_no %></a>
%           }
%           else {
            <li><%= $tt %> <%= $train_no %>
+9 −1
Original line number Diff line number Diff line
@@ -30,6 +30,9 @@
%     $route_str .= $stop . ($via_cur < $via_max ? ' - ' : q{});
%   }
    <li
% if (param('hafas')) {
      data-jid="<%= $departure->{journey_id} %>"
% }
      data-train="<%= ($departure->{train_type} // q{}) %> <%= ($departure->{train_no} // $departure->{train} // q{}) %>"
      data-line="<%= $departure->{train_type} %> <%= $departure->{train_line} // $departure->{train_no} %>"
      data-no="<%= $departure->{train_line} ? $departure->{train_no} : q{} %>"
@@ -49,7 +52,12 @@
%   else {
      >
%   }
    <a href="/z/<%= Mojo::Util::url_escape(($departure->{train_type} // q{}) . ' ' . ($departure->{train_no} // $departure->{train} // q{}) . '/' .  ($departure->{station} // $station)) %>">
%   if (param('hafas')) {
      <a href="/z/<%= Mojo::Util::url_escape($departure->{journey_id}) . '?hafas=1&highlight=' .  Mojo::Util::url_escape($departure->{station} // $station) %>">
%   }
%   else {
      <a href="/z/<%= Mojo::Util::url_escape(($departure->{train_type} // q{}) . ' ' . ($departure->{train_no} // $departure->{train} // q{})) . '/' .  Mojo::Util::url_escape($departure->{station} // $station) %>">
%   }
    <div class="anchor" id="<%= ($departure->{train_type} // q{x}) . ($departure->{train_no} // q{x}) %>"></div>
    <div class="line <%= $departure->{linetype} %>">
    % if ($departure->{train_type} and $departure->{train_no}) {
Loading