optionally link to external departure boards where sensible (WiP)
This commit is contained in:
parent
4deb0bde0b
commit
5eab0c14f4
7 changed files with 198 additions and 17 deletions
|
@ -1378,6 +1378,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(
|
$self->helper(
|
||||||
'get_connection_targets' => sub {
|
'get_connection_targets' => sub {
|
||||||
my ( $self, %opt ) = @_;
|
my ( $self, %opt ) = @_;
|
||||||
|
@ -1957,16 +1967,20 @@ sub startup {
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( $latest_cancellation and $latest_cancellation->{cancelled} ) {
|
if ( $latest_cancellation and $latest_cancellation->{cancelled} ) {
|
||||||
if ( my $station
|
if (
|
||||||
= $self->app->station_by_eva
|
my $station = $self->app->station_by_eva->{
|
||||||
->{ $latest_cancellation->{dep_eva} } )
|
$latest_cancellation->{dep_eva}
|
||||||
|
}
|
||||||
|
)
|
||||||
{
|
{
|
||||||
$latest_cancellation->{dep_ds100} = $station->[0];
|
$latest_cancellation->{dep_ds100} = $station->[0];
|
||||||
$latest_cancellation->{dep_name} = $station->[1];
|
$latest_cancellation->{dep_name} = $station->[1];
|
||||||
}
|
}
|
||||||
if ( my $station
|
if (
|
||||||
= $self->app->station_by_eva
|
my $station = $self->app->station_by_eva->{
|
||||||
->{ $latest_cancellation->{arr_eva} } )
|
$latest_cancellation->{arr_eva}
|
||||||
|
}
|
||||||
|
)
|
||||||
{
|
{
|
||||||
$latest_cancellation->{arr_ds100} = $station->[0];
|
$latest_cancellation->{arr_ds100} = $station->[0];
|
||||||
$latest_cancellation->{arr_name} = $station->[1];
|
$latest_cancellation->{arr_name} = $station->[1];
|
||||||
|
@ -2554,6 +2568,7 @@ sub startup {
|
||||||
$authed_r->get('/account/hooks')->to('account#webhook');
|
$authed_r->get('/account/hooks')->to('account#webhook');
|
||||||
$authed_r->get('/account/traewelling')->to('traewelling#settings');
|
$authed_r->get('/account/traewelling')->to('traewelling#settings');
|
||||||
$authed_r->get('/account/insight')->to('account#insight');
|
$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('/ajax/status_card.html')->to('traveling#status_card');
|
||||||
$authed_r->get('/cancelled')->to('traveling#cancelled');
|
$authed_r->get('/cancelled')->to('traveling#cancelled');
|
||||||
$authed_r->get('/fgr')->to('passengerrights#list_candidates');
|
$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/hooks')->to('account#webhook');
|
||||||
$authed_r->post('/account/traewelling')->to('traewelling#settings');
|
$authed_r->post('/account/traewelling')->to('traewelling#settings');
|
||||||
$authed_r->post('/account/insight')->to('account#insight');
|
$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/add')->to('traveling#add_journey_form');
|
||||||
$authed_r->post('/journey/comment')->to('traveling#comment_form');
|
$authed_r->post('/journey/comment')->to('traveling#comment_form');
|
||||||
$authed_r->post('/journey/edit')->to('traveling#edit_journey');
|
$authed_r->post('/journey/edit')->to('traveling#edit_journey');
|
||||||
|
|
|
@ -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 {
|
sub setup_db {
|
||||||
|
|
|
@ -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 {
|
sub webhook {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,13 @@ use 5.020;
|
||||||
|
|
||||||
use DateTime;
|
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 {
|
sub new {
|
||||||
my ( $class, %opt ) = @_;
|
my ( $class, %opt ) = @_;
|
||||||
|
|
||||||
|
@ -286,7 +293,7 @@ sub get_data {
|
||||||
|
|
||||||
my $user = $db->select(
|
my $user = $db->select(
|
||||||
'users',
|
'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 registered_at) as registered_at_ts, '
|
||||||
. 'extract(epoch from last_seen) as last_seen_ts, '
|
. 'extract(epoch from last_seen) as last_seen_ts, '
|
||||||
. 'extract(epoch from deletion_requested) as deletion_requested_ts',
|
. 'extract(epoch from deletion_requested) as deletion_requested_ts',
|
||||||
|
@ -294,11 +301,17 @@ sub get_data {
|
||||||
)->hash;
|
)->hash;
|
||||||
if ($user) {
|
if ($user) {
|
||||||
return {
|
return {
|
||||||
id => $user->{id},
|
id => $user->{id},
|
||||||
name => $user->{name},
|
name => $user->{name},
|
||||||
status => $user->{status},
|
status => $user->{status},
|
||||||
is_public => $user->{public_level},
|
is_public => $user->{public_level},
|
||||||
email => $user->{email},
|
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(
|
registered_at => DateTime->from_epoch(
|
||||||
epoch => $user->{registered_at_ts},
|
epoch => $user->{registered_at_ts},
|
||||||
time_zone => 'Europe/Berlin'
|
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 {
|
sub get_webhook {
|
||||||
my ( $self, %opt ) = @_;
|
my ( $self, %opt ) = @_;
|
||||||
my $db = $opt{db} // $self->{pg}->db;
|
my $db = $opt{db} // $self->{pg}->db;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
% my $user = current_user();
|
||||||
<div class="autorefresh">
|
<div class="autorefresh">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
|
@ -102,7 +103,12 @@
|
||||||
% }
|
% }
|
||||||
</div>
|
</div>
|
||||||
<div style="float: right; text-align: right;">
|
<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) {
|
% if ($journey->{real_arrival}->epoch) {
|
||||||
<b><%= $journey->{real_arrival}->strftime('%H:%M') %></b>
|
<b><%= $journey->{real_arrival}->strftime('%H:%M') %></b>
|
||||||
% if ($journey->{real_arrival}->epoch != $journey->{sched_arrival}->epoch) {
|
% if ($journey->{real_arrival}->epoch != $journey->{sched_arrival}->epoch) {
|
||||||
|
@ -250,14 +256,14 @@
|
||||||
% }
|
% }
|
||||||
<a class="action-share blue-text right"
|
<a class="action-share blue-text right"
|
||||||
style="margin-right: 0;"
|
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"
|
data-text="<%= $journey->{comment} %> (@ <%= $journey->{train_type} %> <%= $journey->{train_no} %> → <%= $journey->{arr_name} %>) #travelynx"
|
||||||
% }
|
% }
|
||||||
% else {
|
% else {
|
||||||
data-text="Ich bin gerade <%= $attrib %> <%= $journey->{train_type} %> <%= $journey->{train_no} %> nach <%= $journey->{arr_name} %> #travelynx"
|
data-text="Ich bin gerade <%= $attrib %> <%= $journey->{train_type} %> <%= $journey->{train_no} %> nach <%= $journey->{arr_name} %> #travelynx"
|
||||||
% }
|
% }
|
||||||
% if (current_user()->{is_public} & 0x02) {
|
% if ($user->{is_public} & 0x02) {
|
||||||
data-url="<%= url_for('/status')->to_abs->scheme('https') %>/<%= current_user->{name} %>/<%= $journey->{sched_departure}->epoch %>"
|
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
|
<i class="material-icons left" aria-hidden="true">share</i> Teilen
|
||||||
|
@ -309,7 +315,11 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
% for my $station (@{$journey->{route_after}}) {
|
% for my $station (@{$journey->{route_after}}) {
|
||||||
% my $is_dest = ($journey->{arr_name} and $station->[0] eq $journey->{arr_name});
|
% 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') {
|
% if ($station->[2] and $station->[2] eq 'cancelled') {
|
||||||
<span style="float: right;">entfällt</span>
|
<span style="float: right;">entfällt</span>
|
||||||
% }
|
% }
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
% elsif ($success eq 'use_history') {
|
% elsif ($success eq 'use_history') {
|
||||||
<span class="card-title">Einstellungen zu vorgeschlagenen Verbindungen geändert</span>
|
<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') {
|
% elsif ($success eq 'webhook') {
|
||||||
<span class="card-title">Web Hook aktualisiert</span>
|
<span class="card-title">Web Hook aktualisiert</span>
|
||||||
% }
|
% }
|
||||||
|
@ -144,6 +147,18 @@
|
||||||
% }
|
% }
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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>
|
<tr>
|
||||||
<th scope="row">Registriert am</th>
|
<th scope="row">Registriert am</th>
|
||||||
<td><%= $acc->{registered_at}->strftime('%d.%m.%Y %H:%M') %></td>
|
<td><%= $acc->{registered_at}->strftime('%d.%m.%Y %H:%M') %></td>
|
||||||
|
|
72
templates/use_external_links.html.ep
Normal file
72
templates/use_external_links.html.ep
Normal file
|
@ -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
|
Loading…
Reference in a new issue