diff --git a/index.pl b/index.pl index 7fb6681..21fcc07 100755 --- a/index.pl +++ b/index.pl @@ -241,6 +241,26 @@ app->attr( ); } ); +app->attr( + get_journey_actions_query => sub { + my ($self) = @_; + + return $self->app->dbh->prepare( + qq{ + select action_id, action_time, stations.ds100, stations.name, + train_type, train_line, train_no, train_id, + sched_time, real_time, + route, messages + from user_actions + left outer join stations on station_id = stations.id + where user_id = ? + and (action_time = ? or action_time = ?) + order by action_time desc + limit 2 + } + ); + } +); app->attr( get_userid_query => sub { my ($self) = @_; @@ -775,14 +795,21 @@ helper 'check_if_mail_is_blacklisted' => sub { }; helper 'get_user_travels' => sub { - my ( $self, $limit ) = @_; + my ( $self, %opt ) = @_; my $uid = $self->current_user->{id}; my $query = $self->app->get_all_actions_query; - if ($limit) { + if ( $opt{limit} ) { $query = $self->app->get_last_actions_query; } - $query->execute($uid); + + if ( $opt{uid} and $opt{checkin_epoch} and $opt{checkout_epoch} ) { + $query = $self->app->get_journey_actions_query; + $query->execute( $opt{uid}, $opt{checkin_epoch}, $opt{checkout_epoch} ); + } + else { + $query->execute($uid); + } my @travels; my $prev_action = 0; @@ -805,6 +832,7 @@ helper 'get_user_travels' => sub { to_name => $name, sched_arrival => epoch_to_dt($raw_sched_ts), rt_arrival => epoch_to_dt($raw_real_ts), + checkout => epoch_to_dt($raw_ts), type => $train_type, line => $train_line, no => $train_no, @@ -823,13 +851,23 @@ helper 'get_user_travels' => sub { my $ref = $travels[-1]; $ref->{from_name} = $name; $ref->{completed} = 1; - $ref->{sched_departure} = epoch_to_dt($raw_sched_ts), - $ref->{rt_departure} = epoch_to_dt($raw_real_ts), - $ref->{type} //= $train_type; + $ref->{sched_departure} = epoch_to_dt($raw_sched_ts); + $ref->{rt_departure} = epoch_to_dt($raw_real_ts); + $ref->{checkin} = epoch_to_dt($raw_ts); + $ref->{type} //= $train_type; $ref->{line} //= $train_line; $ref->{no} //= $train_no; $ref->{messages} //= [ split( qr{[|]}, $raw_messages ) ]; $ref->{route} //= [ split( qr{[|]}, $raw_route ) ]; + + if ( $opt{verbose} ) { + my @parsed_messages; + for my $message ( @{ $ref->{messages} // [] } ) { + my ( $ts, $msg ) = split( qr{:}, $message ); + push( @parsed_messages, [ epoch_to_dt($ts), $msg ] ); + } + $ref->{messages} = [@parsed_messages]; + } } $prev_action = $action; } @@ -1340,7 +1378,7 @@ get '/history' => sub { my ($self) = @_; $self->respond_to( - json => { json => [ $self->get_user_travels(0) ] }, + json => { json => [ $self->get_user_travels ] }, any => { template => 'history' } ); }; @@ -1348,7 +1386,42 @@ get '/history' => sub { get '/history.json' => sub { my ($self) = @_; - $self->render( json => [ $self->get_user_travels(0) ] ); + $self->render( json => [ $self->get_user_travels ] ); +}; + +get '/journey/:id' => sub { + my ($self) = @_; + my ( $uid, $checkin_ts, $checkout_ts ) = split( qr{-}, $self->stash('id') ); + + if ( $uid != $self->current_user->{id} ) { + $self->render( + 'journey', + error => 'notfound', + journey => {} + ); + return; + } + + my @journeys = $self->get_user_travels( + uid => $uid, + checkin_epoch => $checkin_ts, + checkout_epoch => $checkout_ts, + verbose => 1, + ); + if ( @journeys == 0 ) { + $self->render( + 'journey', + error => 'notfound', + journey => {} + ); + return; + } + + $self->render( + 'journey', + error => undef, + journey => $journeys[0] + ); }; get '/export.json' => sub { diff --git a/templates/history.html.ep b/templates/history.html.ep index cf81765..d79b515 100644 --- a/templates/history.html.ep +++ b/templates/history.html.ep @@ -19,12 +19,13 @@ - % for my $travel (get_user_travels(0)) { + % for my $travel (get_user_travels()) { % if ($travel->{completed}) { + % my $detail_link = '/journey/' . current_user()->{id} . '-' . $travel->{checkin}->epoch . '-' . $travel->{checkout}->epoch; <%= $travel->{sched_departure}->strftime('%d.%m.%Y') %> - <%= $travel->{type} %> <%= $travel->{line} // '' %> <%= $travel->{no} %> - <%= $travel->{from_name} %> → <%= $travel->{to_name} %> + <%= $travel->{type} %> <%= $travel->{line} // '' %> <%= $travel->{no} %> + <%= $travel->{from_name} %> → <%= $travel->{to_name} %> <%= $travel->{rt_departure}->strftime('%H:%M') %> % if ($travel->{sched_departure} != $travel->{rt_departure}) { (+<%= ($travel->{rt_departure}->epoch - $travel->{sched_departure}->epoch) / 60 %>) diff --git a/templates/journey.html.ep b/templates/journey.html.ep new file mode 100644 index 0000000..520b2ef --- /dev/null +++ b/templates/journey.html.ep @@ -0,0 +1,101 @@ +% if ($error) { +
+
+
+
+ Fehler +

Zugfahrt nicht gefunden.

+

+
+
+
+% } +% else { +
+
+

+ Fahrt von + <%= $journey->{from_name} %> + nach + <%= $journey->{to_name} %> + am + <%= $journey->{sched_departure}->strftime('%d.%m.%Y') %> +

+ + + + + + + + + + + + + + + + + + + + + +
Zug + <%= $journey->{type} %> <%= $journey->{no} %> + % if ($journey->{line}) { + (Linie <%= $journey->{type} %> <%= $journey->{line} %>) + % } +
Abfahrt + % if ($journey->{rt_departure} != $journey->{sched_departure}) { + %= $journey->{rt_departure}->strftime('%H:%M'); + (+<%= ($journey->{rt_departure}->epoch - $journey->{sched_departure}->epoch) / 60 %>, + Plan: <%= $journey->{sched_departure}->strftime('%H:%M'); %>) + % } + % else { + %= $journey->{sched_departure}->strftime('%H:%M'); + % } +
Ankunft + % if ($journey->{rt_arrival}->epoch == 0 and $journey->{sched_arrival}->epoch == 0) { + timer_off + % } + % elsif ($journey->{rt_arrival} != $journey->{sched_arrival}) { + %= $journey->{rt_arrival}->strftime('%H:%M'); + (+<%= ($journey->{rt_arrival}->epoch - $journey->{sched_arrival}->epoch) / 60 %>, + Plan: <%= $journey->{sched_arrival}->strftime('%H:%M'); %>) + % } + % else { + %= $journey->{sched_arrival}->strftime('%H:%M'); + % } +
Meldungen + % for my $message (@{$journey->{messages} // []}) { + % my ($ts, $msg) = @{$message}; + <%= $ts->strftime('%d.%m.%Y %H:%M') %> : <%= $msg %> + % } +
+
Route + % my $within = 0; + % my $at_startstop = 0; + % for my $station (@{$journey->{route}}) { + % if ($station eq $journey->{from_name}) { + % $within = 1; $at_startstop = 1; + % } + % elsif ($station eq $journey->{to_name}) { + % $within = 0; $at_startstop = 1; + % } + % else { + % $at_startstop = 0; + % } + % if ($at_startstop or $within) { + <%= $station %> + % } + % else { + <%= $station %> + % } +
+ % } +
+
+
+% } diff --git a/templates/landingpage.html.ep b/templates/landingpage.html.ep index c672dd2..dcc0083 100644 --- a/templates/landingpage.html.ep +++ b/templates/landingpage.html.ep @@ -75,12 +75,13 @@ - % for my $travel (get_user_travels(1)) { + % for my $travel (get_user_travels(limit => 1)) { % if ($travel->{completed}) { + % my $detail_link = '/journey/' . current_user()->{id} . '-' . $travel->{checkin}->epoch . '-' . $travel->{checkout}->epoch; <%= $travel->{sched_departure}->strftime('%d.%m.%Y') %> - <%= $travel->{type} %> <%= $travel->{line} // $travel->{no} %> - <%= $travel->{from_name} %> → <%= $travel->{to_name} %> + <%= $travel->{type} %> <%= $travel->{line} // $travel->{no} %> + <%= $travel->{from_name} %> → <%= $travel->{to_name} %> % if ($travel->{rt_arrival}->epoch and $travel->{rt_departure}->epoch) { <%= ($travel->{rt_arrival}->epoch - $travel->{rt_departure}->epoch) / 60 %> min