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

Add preliminary EFA support

parent d8ffb516
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ use DateTime;
use DateTime::Format::Strptime;
use GIS::Distance;
use List::Util qw();
use Travel::Status::DE::EFA;

my $strp = DateTime::Format::Strptime->new(
	pattern   => '%Y-%m-%dT%H:%M:%S%z',
@@ -537,12 +538,15 @@ sub ajax_route {

sub coverage {
	my ($self)  = @_;
	my $backend = $self->stash('backend');
	my $backend = lc( $self->stash('backend') );
	my $service = $self->stash('service');

	my $coverage = {};

	if ( $backend eq 'HAFAS' ) {
	if ( $backend eq 'efa' ) {
		$coverage = $self->efa->get_coverage($service);
	}
	elsif ( $backend eq 'hafas' ) {
		$coverage = $self->hafas->get_coverage($service);
	}

+259 −1
Original line number Diff line number Diff line
@@ -1220,11 +1220,202 @@ sub station_train_details {
	)->wait;
}

sub train_details_efa {
	my ($self) = @_;
	my $trip_id = $self->stash('train');

	my $stopseq;
	if ( $trip_id =~ m{ ^ ([^@]*) @ ([^@]*) [(] ([^)]*) [)] (.*)  $ }x ) {
		$stopseq = {
			stateless => $1,
			stop_id   => $2,
			date      => $3,
			key       => $4
		};
	}
	else {
		$self->render( 'not_found', status => 404 );
		return;
	}

	$self->render_later;

	Travel::Status::DE::EFA->new_p(
		service     => $self->param('efa'),
		stopseq     => $stopseq,
		cache       => $self->app->cache_iris_rt,
		lwp_options => {
			timeout => 10,
			agent   => 'dbf.finalrewind.org/2'
		},
		promise    => 'Mojo::Promise',
		user_agent => Mojo::UserAgent->new,
	)->then(
		sub {
			my ($efa) = @_;
			my $trip = $efa->result;

			my $now = DateTime->now( time_zone => 'Europe/Berlin' );
			my $res = {
				trip_id         => $trip_id,
				train_type      => $trip->type,
				train_line      => $trip->line,
				train_no        => $trip->number,
				origin          => ( $trip->route )[0]->full_name,
				destination     => ( $trip->route )[-1]->full_name,
				operators       => [ $trip->operator ],
				linetype        => lc( $trip->product ) =~ tr{a-z}{}cdr,
				route_pre_diff  => [],
				route_post_diff => [],
				moreinfo        => [],
				replaced_by     => [],
				replacement_for => [],
			};

			if ( $res->{linetype} =~ m{strab|stra.?enbahn} ) {
				$res->{linetype} = 'tram';
			}
			elsif ( $res->{linetype} =~ m{bus} ) {
				$res->{linetype} = 'bus';
			}

			my $station_is_past = 1;
			for my $stop ( $trip->route ) {

				push(
					@{ $res->{route_post_diff} },
					{
						name      => $stop->full_name,
						id        => $stop->stop_id,
						sched_arr => $stop->sched_arr,
						sched_dep => $stop->sched_dep,
						rt_arr    => $stop->rt_arr,
						rt_dep    => $stop->rt_dep,
						platform  => $stop->platform,
					}
				);
				if (
					$station_is_past
					and $now->epoch < (
						$res->{route_post_diff}[-1]{rt_arr}
						  // $res->{route_post_diff}[-1]{rt_dep}
						  // $res->{route_post_diff}[-1]{sched_arr}
						  // $res->{route_post_diff}[-1]{sched_dep} // $now
					)->epoch
				  )
				{
					$station_is_past = 0;
				}
				$res->{route_post_diff}[-1]{isPast} = $station_is_past;
			}

			if ( my $req_id = $self->param('highlight') ) {
				my $split;
				for my $i ( 0 .. $#{ $res->{route_post_diff} } ) {
					if ( $res->{route_post_diff}[$i]{id} eq $req_id ) {
						$split = $i;
						last;
					}
				}
				if ( defined $split ) {
					$self->stash(
						station_name => $res->{route_post_diff}[$split]{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} } );
					$res->{eva} = $station_info->{eva};
					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};
					$res->{is_cancelled} = $res->{arrival_is_cancelled}
					  || $res->{arrival_is_cancelled};
					$res->{tz_offset}       = $station_info->{tz_offset};
					$res->{local_dt_da}     = $station_info->{local_dt_da};
					$res->{local_sched_arr} = $station_info->{local_sched_arr};
					$res->{local_sched_dep} = $station_info->{local_sched_dep};
					$res->{is_annotated}    = $station_info->{is_annotated};
					$res->{prod_name}       = $station_info->{prod_name};
					$res->{direction}       = $station_info->{direction};
					$res->{operator}        = $station_info->{operator};
					$res->{platform}        = $station_info->{platform};
					$res->{scheduled_platform}
					  = $station_info->{sched_platform};
				}
			}

			$self->respond_to(
				json => {
					json => {
						journey => $trip,
					},
				},
				any => {
					template => $self->param('ajax')
					? '_train_details'
					: 'train_details',
					description => sprintf(
						'%s %s%s%s nach %s',
						$res->{train_type},
						$res->{train_line} // $res->{train_no},
						$res->{origin} ? ' von ' : q{},
						$res->{origin}      // q{},
						$res->{destination} // 'unbekannt'
					),
					departure => $res,
					linetype  => $res->{linetype},
					dt_now    => DateTime->now( time_zone => 'Europe/Berlin' ),
				},
			);
		}
	)->catch(
		sub {
			my ($e) = @_;
			$self->respond_to(
				json => {
					json => {
						error => $e,
					},
					status => 500,
				},
				any => {
					template  => 'exception',
					message   => $e,
					exception => undef,
					snapshot  => {},
					status    => 500,
				},
			);
		}
	)->wait;
}

# /z/:train
sub train_details {
	my ($self) = @_;
	my $train  = $self->stash('train');
	my $hafas  = $self->param('hafas');
	my $efa    = $self->param('efa');

	# TODO error handling

@@ -1235,6 +1426,10 @@ sub train_details {
	$self->stash( departures => [] );
	$self->stash( title      => 'DBF' );

	if ($efa) {
		return $self->train_details_efa;
	}

	my $res = {
		train_type      => undef,
		train_line      => undef,
@@ -1570,7 +1765,7 @@ sub handle_efa {
		$template,
		description      => "Abfahrtstafel $station_name",
		departures       => \@departures,
		station          => $efa->stop->name,,
		station          => $efa->stop->name,
		version          => $self->config->{version},
		title            => $efa->stop->name // $station_name,
		refresh_interval => $template eq 'app' ? 0 : 120,
@@ -2103,6 +2298,7 @@ sub stations_by_coordinates {

	my $lon   = $self->param('lon');
	my $lat   = $self->param('lat');
	my $efa   = $self->param('efa');
	my $hafas = $self->param('hafas');

	if ( not $lon or not $lat ) {
@@ -2120,6 +2316,46 @@ sub stations_by_coordinates {

	$self->render_later;

	if ($efa) {
		Travel::Status::DE::EFA->new_p(
			promise    => 'Mojo::Promise',
			user_agent => $self->ua,
			service    => $efa,
			coord      => {
				lat => $lat,
				lon => $lon
			}
		)->then(
			sub {
				my ($efa) = @_;
				my @efa = map {
					{
						name     => $_->full_name,
						eva      => $_->id,
						distance => $_->distance_m / 1000,
						efa      => $efa,
					}
				} $efa->results;
				$self->render(
					json => {
						candidates => [@efa],
					}
				);
			}
		)->catch(
			sub {
				my ($err) = @_;
				$self->render(
					json => {
						candidates => [],
						warning    => $err,
					}
				);
			}
		)->wait;
		return;
	}

	my @iris = map {
		{
			ds100    => $_->[0][0],
@@ -2219,6 +2455,24 @@ sub backend_list {
		}
	);

	for my $backend ( Travel::Status::DE::EFA::get_services() ) {
		push(
			@backends,
			{
				name      => $backend->{name},
				shortname => $backend->{shortname},
				homepage  => $backend->{homepage},
				regions   => [
					map { $place_map{$_} // $_ }
					  @{ $backend->{coverage}{regions} }
				],
				has_area => $backend->{coverage}{area} ? 1 : 0,
				type     => 'EFA',
				efa      => 1,
			}
		);
	}

	for my $backend ( Travel::Status::DE::HAFAS::get_services() ) {
		push(
			@backends,
@@ -2292,6 +2546,10 @@ sub redirect_to_station {
		$params = $params->to_string;
		$self->redirect_to("/z/${input}?${params}");
	}
	elsif ( $params->param('efa') ) {
		$params = $params->to_string;
		$self->redirect_to("/${input}?${params}");
	}
	elsif ( $params->param('hafas') and $params->param('hafas') ne '1' ) {
		$params = $params->to_string;
		$self->redirect_to("/${input}?${params}");
+13 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ use Encode qw(decode encode);
use Mojo::JSON qw(decode_json);
use Mojo::Promise;
use Mojo::Util qw(url_escape);
use Travel::Status::DE::EFA;

sub new {
	my ( $class, %opt ) = @_;
@@ -28,6 +29,18 @@ sub new {

}

sub get_coverage {
	my ( $self, $service ) = @_;

	my $service_definition = Travel::Status::DE::EFA::get_service($service);

	if ( not $service_definition ) {
		return {};
	}

	return $service_definition->{coverage}{area} // {};
}

sub get_json_p {
	my ( $self, $cache, $url ) = @_;

+6 −3
Original line number Diff line number Diff line
@@ -39,10 +39,13 @@ $(function() {
				const eva = candidate.eva,
					name = candidate.name,
					distance = candidate.distance.toFixed(1),
					efa = candidate.efa,
					hafas = candidate.hafas;

				const stationlink = $(document.createElement('a'));
				if (hafas) {
				if (efa) {
					stationlink.attr('href', eva + '?efa=' + efa);
				} else if (hafas) {
					stationlink.attr('href', eva + '?hafas=' + hafas);
				} else {
					stationlink.attr('href', eva);
@@ -55,7 +58,7 @@ $(function() {

				const icon = $(document.createElement('i'));
				icon.attr('class', 'material-icons');
				icon.text(hafas ? 'directions' : 'train');
				icon.text((hafas || efa) ? 'directions' : 'train');

				stationlink.append(icon);
				stationlink.append(distancenode);
@@ -66,7 +69,7 @@ $(function() {

	const processLocation = function(loc) {
		const param = new URLSearchParams(window.location.search);
		$.post('/_geolocation', {lon: loc.coords.longitude, lat: loc.coords.latitude, hafas: param.get('hafas')}, processResult).fail(function(jqXHR, textStatus, errorThrown) {
		$.post('/_geolocation', {lon: loc.coords.longitude, lat: loc.coords.latitude, efa: param.get('efa'), hafas: param.get('hafas')}, processResult).fail(function(jqXHR, textStatus, errorThrown) {
			removeStatus();
			showError("Netzwerkfehler: ", textStatus, errorThrown);
		});
+1 −1
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ function dbf_anim_fine() {

function dbf_map_reload() {
	const param = new URLSearchParams(window.location.search);
	$.get('/_ajax_mapinfo/' + j_reqid + '?hafas=' + param.get('hafas'), function(data) {
	$.get('/_ajax_mapinfo/' + j_reqid + '?efa=' + param.get('efa') + '&amp;hafas=' + param.get('hafas'), function(data) {
		$('#infobox').html(data);
		dbf_map_parse();
		setTimeout(dbf_map_reload, 61000);
Loading