diff options
| -rwxr-xr-x | lib/Travelynx.pm | 28 | ||||
| -rw-r--r-- | lib/Travelynx/Command/database.pm | 14 | ||||
| -rw-r--r-- | lib/Travelynx/Controller/Account.pm | 23 | ||||
| -rw-r--r-- | lib/Travelynx/Model/Users.pm | 43 | ||||
| -rw-r--r-- | templates/_checked_in.html.ep | 20 | ||||
| -rw-r--r-- | templates/account.html.ep | 15 | ||||
| -rw-r--r-- | templates/use_external_links.html.ep | 72 | 
7 files changed, 198 insertions, 17 deletions
| diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm index 73182ed..de5ea18 100755 --- a/lib/Travelynx.pm +++ b/lib/Travelynx.pm @@ -1379,6 +1379,16 @@ sub startup {  	);  	$self->helper( +		'resolve_sb_template' => sub { +			my ( $self, $template, %opt ) = @_; +			my $ret = $template; +			$ret =~ s{[{]eva[}]}{$opt{eva}}g; +			$ret =~ s{[{]name[}]}{$opt{name}}g; +			return $ret; +		} +	); + +	$self->helper(  		'get_connection_targets' => sub {  			my ( $self, %opt ) = @_; @@ -1957,16 +1967,20 @@ sub startup {  			);  			if ( $latest_cancellation and $latest_cancellation->{cancelled} ) { -				if ( my $station -					= $self->app->station_by_eva -					->{ $latest_cancellation->{dep_eva} } ) +				if ( +					my $station = $self->app->station_by_eva->{ +						$latest_cancellation->{dep_eva} +					} +				  )  				{  					$latest_cancellation->{dep_ds100} = $station->[0];  					$latest_cancellation->{dep_name}  = $station->[1];  				} -				if ( my $station -					= $self->app->station_by_eva -					->{ $latest_cancellation->{arr_eva} } ) +				if ( +					my $station = $self->app->station_by_eva->{ +						$latest_cancellation->{arr_eva} +					} +				  )  				{  					$latest_cancellation->{arr_ds100} = $station->[0];  					$latest_cancellation->{arr_name}  = $station->[1]; @@ -2554,6 +2568,7 @@ sub startup {  	$authed_r->get('/account/hooks')->to('account#webhook');  	$authed_r->get('/account/traewelling')->to('traewelling#settings');  	$authed_r->get('/account/insight')->to('account#insight'); +	$authed_r->get('/account/services')->to('account#services');  	$authed_r->get('/ajax/status_card.html')->to('traveling#status_card');  	$authed_r->get('/cancelled')->to('traveling#cancelled');  	$authed_r->get('/fgr')->to('passengerrights#list_candidates'); @@ -2577,6 +2592,7 @@ sub startup {  	$authed_r->post('/account/hooks')->to('account#webhook');  	$authed_r->post('/account/traewelling')->to('traewelling#settings');  	$authed_r->post('/account/insight')->to('account#insight'); +	$authed_r->post('/account/services')->to('account#services');  	$authed_r->post('/journey/add')->to('traveling#add_journey_form');  	$authed_r->post('/journey/comment')->to('traveling#comment_form');  	$authed_r->post('/journey/edit')->to('traveling#edit_journey'); diff --git a/lib/Travelynx/Command/database.pm b/lib/Travelynx/Command/database.pm index e84cf54..32522be 100644 --- a/lib/Travelynx/Command/database.pm +++ b/lib/Travelynx/Command/database.pm @@ -1069,6 +1069,20 @@ my @migrations = (  			}  		);  	}, + +	# v24 -> v25 +	# travelynx 1.23 adds optional links to external services, e.g. +	# DBF or marudor.de departure boards +	sub { +		my ($db) = @_; +		$db->query( +			qq{ +				alter table users add column external_services smallint; +				comment on column users.external_services is 'Which external service to use for stationboard or routing links'; +				update schema_version set version = 25; +			} +		); +	},  );  sub setup_db { diff --git a/lib/Travelynx/Controller/Account.pm b/lib/Travelynx/Controller/Account.pm index 97ea8ad..f4f05d9 100644 --- a/lib/Travelynx/Controller/Account.pm +++ b/lib/Travelynx/Controller/Account.pm @@ -375,6 +375,29 @@ sub insight {  } +sub services { +	my ($self) = @_; +	my $user = $self->current_user; + +	if ( $self->param('action') and $self->param('action') eq 'save' ) { +		my $sb    = $self->param('stationboard'); +		my $value = 0; +		if ( $sb =~ m{ ^ \d+ $ }x and $sb >= 0 and $sb <= 3 ) { +			$value = int($sb); +		} +		$self->users->use_external_services( +			uid => $user->{id}, +			set => $value +		); +		$self->flash( success => 'external' ); +		$self->redirect_to('account'); +	} + +	$self->param( stationboard => +		  $self->users->use_external_services( uid => $user->{id} ) ); +	$self->render('use_external_links'); +} +  sub webhook {  	my ($self) = @_; diff --git a/lib/Travelynx/Model/Users.pm b/lib/Travelynx/Model/Users.pm index 3d19831..061bb33 100644 --- a/lib/Travelynx/Model/Users.pm +++ b/lib/Travelynx/Model/Users.pm @@ -10,6 +10,13 @@ use 5.020;  use DateTime; +my @sb_templates = ( +	undef, +	[ 'DBF',        'https://dbf.finalrewind.org/{name}' ], +	[ 'marudor.de', 'https://marudor.de/{name}' ], +	[ 'NVM',        'https://nvm.finalrewind.org/board/{eva}' ], +); +  sub new {  	my ( $class, %opt ) = @_; @@ -286,7 +293,7 @@ sub get_data {  	my $user = $db->select(  		'users', -		'id, name, status, public_level, email, ' +		'id, name, status, public_level, email, external_services, '  		  . 'extract(epoch from registered_at) as registered_at_ts, '  		  . 'extract(epoch from last_seen) as last_seen_ts, '  		  . 'extract(epoch from deletion_requested) as deletion_requested_ts', @@ -294,11 +301,17 @@ sub get_data {  	)->hash;  	if ($user) {  		return { -			id            => $user->{id}, -			name          => $user->{name}, -			status        => $user->{status}, -			is_public     => $user->{public_level}, -			email         => $user->{email}, +			id        => $user->{id}, +			name      => $user->{name}, +			status    => $user->{status}, +			is_public => $user->{public_level}, +			email     => $user->{email}, +			sb_name   => $user->{external_services} +			? $sb_templates[ $user->{external_services} & 0x07 ][0] +			: undef, +			sb_template => $user->{external_services} +			? $sb_templates[ $user->{external_services} & 0x07 ][1] +			: undef,  			registered_at => DateTime->from_epoch(  				epoch     => $user->{registered_at_ts},  				time_zone => 'Europe/Berlin' @@ -478,6 +491,24 @@ sub use_history {  	}  } +sub use_external_services { +	my ( $self, %opt ) = @_; +	my $db    = $opt{db} // $self->{pg}->db; +	my $uid   = $opt{uid}; +	my $value = $opt{set}; + +	if ($value) { +		if ( $value < 0 or $value > 3 ) { +			$value = 0; +		} +		$db->update( 'users', { external_services => $value }, { id => $uid } ); +	} +	else { +		return $db->select( 'users', ['external_services'], { id => $uid } ) +		  ->hash->{external_services}; +	} +} +  sub get_webhook {  	my ( $self, %opt ) = @_;  	my $db  = $opt{db} // $self->{pg}->db; diff --git a/templates/_checked_in.html.ep b/templates/_checked_in.html.ep index d882501..2c37bbc 100644 --- a/templates/_checked_in.html.ep +++ b/templates/_checked_in.html.ep @@ -1,3 +1,4 @@ +% my $user = current_user();  <div class="autorefresh">  	<div class="card">  		<div class="card-content"> @@ -102,7 +103,12 @@  						% }  					</div>  					<div style="float: right; text-align: right;"> -						<b><%= $journey->{arr_name} %></b><br/> +						% if ($user->{sb_template}) { +							<b><a href="<%= resolve_sb_template($user->{sb_template}, name => $journey->{arr_name}, eva => $journey->{arr_eva}) %>" class="unmarked"><%= $journey->{arr_name} %></a></b><br/> +						% } +						% else { +							<b><%= $journey->{arr_name} %></b><br/> +						% }  						% if ($journey->{real_arrival}->epoch) {  							<b><%= $journey->{real_arrival}->strftime('%H:%M') %></b>  							% if ($journey->{real_arrival}->epoch != $journey->{sched_arrival}->epoch) { @@ -250,14 +256,14 @@  				% }  				<a class="action-share blue-text right"  					style="margin-right: 0;" -					% if (current_user()->{is_public} & 0x04 and $journey->{comment}) { +					% if ($user->{is_public} & 0x04 and $journey->{comment}) {  						data-text="<%= $journey->{comment} %> (@ <%= $journey->{train_type} %> <%= $journey->{train_no} %> → <%= $journey->{arr_name} %>) #travelynx"  					% }  					% else {  						data-text="Ich bin gerade <%= $attrib %> <%= $journey->{train_type} %> <%= $journey->{train_no} %> nach <%= $journey->{arr_name} %> #travelynx"  					% } -					% if (current_user()->{is_public} & 0x02) { -						data-url="<%= url_for('/status')->to_abs->scheme('https') %>/<%= current_user->{name} %>/<%= $journey->{sched_departure}->epoch %>" +					% if ($user->{is_public} & 0x02) { +						data-url="<%= url_for('/status')->to_abs->scheme('https') %>/<%= $user->{name} %>/<%= $journey->{sched_departure}->epoch %>"  					% }  					>  					<i class="material-icons left" aria-hidden="true">share</i> Teilen @@ -309,7 +315,11 @@  					<tbody>  						% for my $station (@{$journey->{route_after}}) {  							% my $is_dest = ($journey->{arr_name} and $station->[0] eq $journey->{arr_name}); -							<tr><td><a style="<%= $is_dest? 'font-weight: bold;' : '' %>" class="action-checkout" data-station="<%= $station->[0] %>"><%= $station->[0] %> +							<tr><td> +								% if ($user->{sb_template}) { +									<a href="<%= resolve_sb_template($user->{sb_template}, name => $station->[0], eva => $station->[1]{eva}) %>"><i class="material-icons tiny">info</i></a> +								% } +								<a style="<%= $is_dest? 'font-weight: bold;' : '' %>" class="action-checkout" data-station="<%= $station->[0] %>"><%= $station->[0] %>  								% if ($station->[2] and $station->[2] eq 'cancelled') {  									<span style="float: right;">entfällt</span>  								% } diff --git a/templates/account.html.ep b/templates/account.html.ep index bce4dcb..7658237 100644 --- a/templates/account.html.ep +++ b/templates/account.html.ep @@ -25,6 +25,9 @@  					% elsif ($success eq 'use_history') {  						<span class="card-title">Einstellungen zu vorgeschlagenen Verbindungen geändert</span>  					% } +					% elsif ($success eq 'external') { +						<span class="card-title">Einstellungen zu externen Diensten geändert</span> +					% }  					% elsif ($success eq 'webhook') {  						<span class="card-title">Web Hook aktualisiert</span>  					% } @@ -145,6 +148,18 @@  				</td>  			</tr>  			<tr> +				<th scope="row">Externe Dienste</th> +				<td> +					<a href="/account/services"><i class="material-icons">edit</i></a> +					% if ($acc->{sb_name}) { +						Abfahrtstafel: <%= $acc->{sb_name} %> +					% } +					% else { +						<span style="color: #999999;">Keine</span> +					% } +				</td> +			</tr> +			<tr>  				<th scope="row">Registriert am</th>  				<td><%= $acc->{registered_at}->strftime('%d.%m.%Y %H:%M') %></td>  			</tr> diff --git a/templates/use_external_links.html.ep b/templates/use_external_links.html.ep new file mode 100644 index 0000000..f1c8c81 --- /dev/null +++ b/templates/use_external_links.html.ep @@ -0,0 +1,72 @@ +<h1>Externe Dienste</h1> +<div class="row"> +	<div class="col s12"> +		<p> +			Travelynx kann an geeigneten Stellen Links zu externen Diensten +			(z.B. Abfahrstafeln oder Informationen zum gerade genutzten Zug) +			einbinden. Hier lässt sich konfigurieren, welcher Dienst für welche +			Art von Informationen genutzt wird. +		<p/> +	</div> +</div> +<h2>Abfahrtstafel</h2> +%= form_for '/account/services' => (method => 'POST') => begin +	%= csrf_field +	<div class="row"> +		<div class="col s12"> +			Angaben zu anderen an einer Station verkehrenden Verkehrsmitteln +		</div> +	</div> +	<div class="row"> +		<div class="input-field col s12"> +			<div> +				<label> +					%= radio_button stationboard => '0' +					<span>Keine</span> +				</label> +			</div> +		</div> +	</div> +	<div class="row"> +		<div class="input-field col s12"> +			<div> +				<label> +					%= radio_button stationboard => '1' +					<span><a href="https://dbf.finalrewind.org/">DBF</a></span> +				</label> +			</div> +		</div> +	</div> +	<div class="row"> +		<div class="input-field col s12"> +			<div> +				<label> +					%= radio_button stationboard => '2' +					<span><a href="https://marudor.de/">marudor.de</a></span> +				</label> +			</div> +		</div> +	</div> +	<div class="row"> +		<div class="input-field col s12"> +			<div> +				<label> +					%= radio_button stationboard => '3' +					<span><a href="https://nvm.finalrewind.org/">NVM</a></span> +				</label> +			</div> +		</div> +	</div> +	<div class="row"> +		<div class="col s3 m3 l3"> +		</div> +		<div class="col s6 m6 l6 center-align"> +			<button class="btn waves-effect waves-light" type="submit" name="action" value="save"> +				Speichern +				<i class="material-icons right">send</i> +			</button> +		</div> +		<div class="col s3 m3 l3"> +		</div> +	</div> +%= end | 
