Loading index.pl +191 −255 Original line number Diff line number Diff line Loading @@ -44,13 +44,10 @@ app->plugin( authentication => { autoload_user => 1, session_key => 'foodor', fail_render => { template => 'login' }, load_user => sub { my ( $self, $uid ) = @_; my $data = $self->get_user_data($uid); if ($data) { return { name => $data->{name} }; } return undef; return $self->get_user_data($uid); }, validate_user => sub { my ( $self, $username, $password, $extradata ) = @_; Loading @@ -68,6 +65,7 @@ app->plugin( }, } ); app->sessions->default_expiration( 60 * 60 * 24 * 180 ); app->defaults( layout => 'default' ); Loading Loading @@ -427,7 +425,7 @@ helper 'checkin' => sub { } my $success = $self->app->checkin_query->execute( $self->get_user_id, $self->current_user->{id}, $self->get_station_id( ds100 => $status->{station_ds100}, name => $status->{station_name} Loading Loading @@ -457,7 +455,7 @@ helper 'checkin' => sub { helper 'undo' => sub { my ($self) = @_; my $uid = $self->get_user_id; my $uid = $self->current_user->{id}; $self->app->get_last_actions_query->execute($uid); my $rows = $self->app->get_last_actions_query->fetchall_arrayref; Loading @@ -469,8 +467,8 @@ helper 'undo' => sub { return 'Repeated undo is not supported'; } my $success = $self->app->undo_query->execute( $self->get_user_id, my $success = $self->app->undo_query->execute( $self->current_user->{id}, DateTime->now( time_zone => 'Europe/Berlin' )->epoch, ); Loading Loading @@ -501,7 +499,7 @@ helper 'checkout' => sub { if ( not defined $train ) { if ($force) { my $success = $self->app->checkout_query->execute( $self->get_user_id, $self->current_user->{id}, $self->get_station_id( ds100 => $status->{station_ds100}, name => $status->{station_name} Loading @@ -523,7 +521,7 @@ helper 'checkout' => sub { } else { my $success = $self->app->checkout_query->execute( $self->get_user_id, $self->current_user->{id}, $self->get_station_id( ds100 => $status->{station_ds100}, name => $status->{station_name} Loading Loading @@ -580,7 +578,7 @@ helper 'get_user_token' => sub { helper 'get_user_data' => sub { my ( $self, $uid ) = @_; $uid //= $self->get_user_id; $uid //= $self->current_user->{id}; my $query = $self->app->get_user_query; $query->execute($uid); my $rows = $query->fetchall_arrayref; Loading @@ -603,7 +601,7 @@ helper 'get_user_data' => sub { deletion_requested => $row[7] }; } return; return undef; }; helper 'get_user_password' => sub { Loading @@ -623,80 +621,9 @@ helper 'get_user_password' => sub { return; }; helper 'get_user_name' => sub { my ($self) = @_; my $user = $self->req->headers->header('X-Remote-User') // 'dev'; return $user; }; helper 'get_user_id' => sub { helper 'add_user' => sub { my ( $self, $user_name, $email, $token, $password ) = @_; $user_name //= $self->get_user_name; if ( not -e $dbname ) { $self->app->dbh->begin_work; $self->app->dbh->do( qq{ create table schema_version ( version integer primary key ); } ); $self->app->dbh->do( qq{ create table users ( id integer primary key, name char(64) not null unique, status int not null, public_level bool not null, email char(256), token char(80), password text, registered_at datetime not null, last_login datetime not null, deletion_requested datetime ) } ); $self->app->dbh->do( qq{ create table stations ( id integer primary key, ds100 char(16) not null unique, name char(64) not null unique ) } ); $self->app->dbh->do( qq{ create table user_actions ( user_id int not null, action_id int not null, station_id int, action_time int not null, train_type char(16), train_line char(16), train_no char(16), train_id char(128), sched_time int, real_time int, route text, messages text, primary key (user_id, action_time) ) } ); $self->app->dbh->do( qq{ insert into schema_version (version) values (1); } ); $self->app->dbh->commit; } $self->app->get_userid_query->execute($user_name); my $rows = $self->app->get_userid_query->fetchall_arrayref; Loading Loading @@ -737,7 +664,7 @@ helper 'check_if_user_name_exists' => sub { helper 'get_user_travels' => sub { my ( $self, $limit ) = @_; my $uid = $self->get_user_id; my $uid = $self->current_user->{id}; my $query = $self->app->get_all_actions_query; if ($limit) { $query = $self->app->get_last_actions_query; Loading Loading @@ -800,7 +727,7 @@ helper 'get_user_travels' => sub { helper 'get_user_status' => sub { my ($self) = @_; my $uid = $self->get_user_id; my $uid = $self->current_user->{id}; $self->app->get_last_actions_query->execute($uid); my $rows = $self->app->get_last_actions_query->fetchall_arrayref; Loading Loading @@ -886,176 +813,33 @@ helper 'navbar_class' => sub { get '/' => sub { my ($self) = @_; if ( $self->is_user_authenticated ) { $self->render( 'landingpage', with_geolocation => 1 ); }; post '/action' => sub { my ($self) = @_; my $params = $self->req->json; if ( not exists $params->{action} ) { $params = $self->req->params->to_hash; } if ( not $params->{action} ) { $self->render( json => { success => 0, error => 'Missing action value', }, status => 400, ); return; } my $station = $params->{station}; if ( $params->{action} eq 'checkin' ) { my ( $train, $error ) = $self->checkin( $params->{station}, $params->{train}, ); if ($error) { $self->render( json => { success => 0, error => $error, }, ); } else { $self->render( json => { success => 1, }, ); } } elsif ( $params->{action} eq 'checkout' ) { my $error = $self->checkout( $params->{station}, $params->{force}, ); if ($error) { $self->render( json => { success => 0, error => $error, }, ); } else { $self->render( json => { success => 1, }, ); } $self->render( 'landingpage', intro => 1 ); } elsif ( $params->{action} eq 'undo' ) { my $error = $self->undo; if ($error) { $self->render( json => { success => 0, error => $error, }, ); } else { $self->render( json => { success => 1, }, ); } } else { $self->render( json => { success => 0, error => 'invalid action value', }, status => 400, ); } }; get '/a/account' => sub { my ($self) = @_; $self->render('account'); }; get '/a/export.json' => sub { my ($self) = @_; my $uid = $self->get_user_id; my $query = $self->app->get_all_actions_query; $query->execute($uid); my @entries; while ( my @row = $query->fetchrow_array ) { my ( $action, $raw_ts, $ds100, $name, $train_type, $train_line, $train_no, $train_id, $raw_sched_ts, $raw_real_ts, $raw_route, $raw_messages ) = @row; $name = decode( 'UTF-8', $name ); $raw_route = decode( 'UTF-8', $raw_route ); $raw_messages = decode( 'UTF-8', $raw_messages ); push( @entries, { action => $action_types[ $action - 1 ], action_ts => $raw_ts, station_ds100 => $ds100, station_name => $name, train_type => $train_type, train_line => $train_line, train_no => $train_no, train_id => $train_id, scheduled_ts => $raw_sched_ts, realtime_ts => $raw_real_ts, messages => $raw_messages ? [ map { [ split(qr{:}) ] } split( qr{[|]}, $raw_messages ) ] : undef, route => $raw_route ? [ split( qr{[|]}, $raw_route ) ] : undef, } ); } $self->render( json => [@entries], ); }; get '/a/history' => sub { my ($self) = @_; $self->render('history'); }; get '/x/about' => sub { get '/about' => sub { my ($self) = @_; $self->render( 'about', version => $VERSION ); }; get '/x/impressum' => sub { get '/impressum' => sub { my ($self) = @_; $self->render('imprint'); }; get '/x/imprint' => sub { get '/imprint' => sub { my ($self) = @_; $self->render('imprint'); }; post '/x/geolocation' => sub { post '/geolocation' => sub { my ($self) = @_; my $lon = $self->param('lon'); Loading Loading @@ -1085,12 +869,12 @@ post '/x/geolocation' => sub { }; get '/x/login' => sub { get '/login' => sub { my ($self) = @_; $self->render('login'); }; post '/x/login' => sub { post '/login' => sub { my ($self) = @_; my $user = $self->req->param('user'); my $password = $self->req->param('password'); Loading @@ -1114,18 +898,12 @@ post '/x/login' => sub { } }; get '/x/logout' => sub { my ($self) = @_; $self->logout; $self->redirect_to('/x/login'); }; get '/x/register' => sub { get '/register' => sub { my ($self) = @_; $self->render('register'); }; post '/x/register' => sub { post '/register' => sub { my ($self) = @_; my $user = $self->req->param('user'); my $email = $self->req->param('email'); Loading Loading @@ -1163,8 +941,7 @@ post '/x/register' => sub { return; } #if ( $self->check_if_user_name_exists($user) or $user eq 'dev' ) { if ( $user ne $self->get_user_name ) { if ( $self->check_if_user_name_exists($user) ) { $self->render( 'register', invalid => 'user_collision' ); return; } Loading @@ -1181,14 +958,14 @@ post '/x/register' => sub { my $token = make_token(); my $pw_hash = hash_password($password); my $user_id = $self->get_user_id( $user, $email, $token, $pw_hash ); my $user_id = $self->add_user( $user, $email, $token, $pw_hash ); my $body = "Hallo, ${user}!\n\n"; $body .= "Mit deiner E-Mail-Adresse (${email}) wurde ein Account auf\n"; $body .= "travelynx.finalrewind.org angelegt.\n\n"; $body .= "Falls die Registrierung von dir ausging, kannst du den Account unter\n"; $body .= "https://travelynx.finalrewind.org/x/reg/${user_id}/${token}\n"; $body .= "https://travelynx.finalrewind.org/reg/${user_id}/${token}\n"; $body .= "freischalten.\n\n"; $body .= "Falls nicht, ignoriere diese Mail bitte. Nach 48 Stunden wird deine\n"; Loading @@ -1200,7 +977,7 @@ post '/x/register' => sub { $body .= " * Datum: ${date}\n"; $body .= " * Verwendete IP: ${ip}\n"; $body .= " * Verwendeter Browser gemäß User Agent: ${ua}\n\n\n"; $body .= "Impressum: https://travelynx.finalrewind.org/x/impressum\n"; $body .= "Impressum: https://travelynx.finalrewind.org/impressum\n"; my $reg_mail = Email::Simple->create( header => [ Loading @@ -1221,7 +998,7 @@ post '/x/register' => sub { } }; get '/x/reg/:id/:token' => sub { get '/reg/:id/:token' => sub { my ($self) = @_; my $id = $self->stash('id'); Loading @@ -1244,7 +1021,166 @@ get '/x/reg/:id/:token' => sub { $self->render( 'login', from => 'verification' ); }; get '/*station' => sub { under sub { my ($self) = @_; return $self->is_user_authenticated; }; post '/action' => sub { my ($self) = @_; my $params = $self->req->json; if ( not exists $params->{action} ) { $params = $self->req->params->to_hash; } if ( not $params->{action} ) { $self->render( json => { success => 0, error => 'Missing action value', }, status => 400, ); return; } my $station = $params->{station}; if ( $params->{action} eq 'checkin' ) { my ( $train, $error ) = $self->checkin( $params->{station}, $params->{train}, ); if ($error) { $self->render( json => { success => 0, error => $error, }, ); } else { $self->render( json => { success => 1, }, ); } } elsif ( $params->{action} eq 'checkout' ) { my $error = $self->checkout( $params->{station}, $params->{force}, ); if ($error) { $self->render( json => { success => 0, error => $error, }, ); } else { $self->render( json => { success => 1, }, ); } } elsif ( $params->{action} eq 'undo' ) { my $error = $self->undo; if ($error) { $self->render( json => { success => 0, error => $error, }, ); } else { $self->render( json => { success => 1, }, ); } } else { $self->render( json => { success => 0, error => 'invalid action value', }, status => 400, ); } }; get '/account' => sub { my ($self) = @_; $self->render('account'); }; get '/history' => sub { my ($self) = @_; $self->render('history'); }; get '/export.json' => sub { my ($self) = @_; my $uid = $self->current_user->{id}; my $query = $self->app->get_all_actions_query; $query->execute($uid); my @entries; while ( my @row = $query->fetchrow_array ) { my ( $action, $raw_ts, $ds100, $name, $train_type, $train_line, $train_no, $train_id, $raw_sched_ts, $raw_real_ts, $raw_route, $raw_messages ) = @row; $name = decode( 'UTF-8', $name ); $raw_route = decode( 'UTF-8', $raw_route ); $raw_messages = decode( 'UTF-8', $raw_messages ); push( @entries, { action => $action_types[ $action - 1 ], action_ts => $raw_ts, station_ds100 => $ds100, station_name => $name, train_type => $train_type, train_line => $train_line, train_no => $train_no, train_id => $train_id, scheduled_ts => $raw_sched_ts, realtime_ts => $raw_real_ts, messages => $raw_messages ? [ map { [ split(qr{:}) ] } split( qr{[|]}, $raw_messages ) ] : undef, route => $raw_route ? [ split( qr{[|]}, $raw_route ) ] : undef, } ); } $self->render( json => [@entries], ); }; post '/logout' => sub { my ($self) = @_; $self->logout; $self->redirect_to('/login'); }; get '/s/*station' => sub { my ($self) = @_; my $station = $self->stash('station'); Loading public/static/js/geolocation.js +2 −2 Original line number Diff line number Diff line Loading @@ -25,14 +25,14 @@ $(document).ready(function() { stationlink.attr('href', ds100); stationlink.text(name); resultBody.append('<tr><td><a href="/' + ds100 + '">' + name + '</a></td></tr>'); resultBody.append('<tr><td><a href="/s/' + ds100 + '">' + name + '</a></td></tr>'); }); placeholder.replaceWith(resultTable); } }; var processLocation = function(loc) { $.post('/x/geolocation', {lon: loc.coords.longitude, lat: loc.coords.latitude}, processResult); $.post('/geolocation', {lon: loc.coords.longitude, lat: loc.coords.latitude}, processResult); }; var processError = function(error) { Loading public/static/js/geolocation.min.js +1 −1 Original line number Diff line number Diff line $(document).ready(function(){var e=$("p.geolocationhint"),t=$("div.geolocation div.progress"),o=function(o,a,n){e.remove(),t.remove()},a=function(e){e.error?o(0,e.error):0==e.candidates.length?o():(resultTable=$("<table><tbody></tbody></table>"),resultBody=resultTable.children(),$.each(e.candidates,function(e,t){var o=t.ds100,a=t.name,n=t.distance;n=n.toFixed(1);var r=$(document.createElement("a"));r.attr("href",o),r.text(a),resultBody.append('<tr><td><a href="/'+o+'">'+a+"</a></td></tr>")}),t.replaceWith(resultTable))},n=function(e){$.post("/x/geolocation",{lon:e.coords.longitude,lat:e.coords.latitude},a)},r=function(e){e.code==e.PERMISSION_DENIED?o():e.code==e.POSITION_UNAVAILABLE?o():(e.code,e.TIMEOUT,o())};navigator.geolocation?navigator.geolocation.getCurrentPosition(n,r):o()}); $(document).ready(function(){var a=$("p.geolocationhint"),n=$("div.geolocation div.progress"),t=function(e,t,o){a.remove(),n.remove()},o=function(e){e.error?t(0,e.error):0==e.candidates.length?t():(resultTable=$("<table><tbody></tbody></table>"),resultBody=resultTable.children(),$.each(e.candidates,function(e,t){var o=t.ds100,a=t.name,n=t.distance;n=n.toFixed(1);var r=$(document.createElement("a"));r.attr("href",o),r.text(a),resultBody.append('<tr><td><a href="/s/'+o+'">'+a+"</a></td></tr>")}),n.replaceWith(resultTable))};navigator.geolocation?navigator.geolocation.getCurrentPosition(function(e){$.post("/geolocation",{lon:e.coords.longitude,lat:e.coords.latitude},o)},function(e){e.code==e.PERMISSION_DENIED||e.code==e.POSITION_UNAVAILABLE||(e.code,e.TIMEOUT),t()}):t()}); public/static/js/travelynx-actions.js +1 −1 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ $(document).ready(function() { station: link.data('station'), force: link.data('force'), }; tvly_run(link, req, '/' + req.station, function() { tvly_run(link, req, '/s/' + req.station, function() { link.append(' – Ohne Echtzeitdaten auschecken?') link.data('force', true); }); Loading public/static/js/travelynx-actions.min.js +1 −1 Original line number Diff line number Diff line function tvly_run(n,t,i,a){var c='<i class="material-icons">error</i>',o=$('<div class="progress"><div class="indeterminate"></div></div>');n.hide(),n.after(o),$.post("/action",t,function(t){t.success?$(location).attr("href",i):(M.toast({html:c+" "+t.error}),o.remove(),a&&a(),n.append(" "+c),n.show())})}$(document).ready(function(){$(".action-checkin").click(function(){var t=$(this);tvly_run(t,{action:"checkin",station:t.data("station"),train:t.data("train")},"/")}),$(".action-checkout").click(function(){var t=$(this),n={action:"checkout",station:t.data("station"),force:t.data("force")};tvly_run(t,n,"/"+n.station,function(){t.append(" – Ohne Echtzeitdaten auschecken?"),t.data("force",!0)})}),$(".action-undo").click(function(){tvly_run($(this),{action:"undo"},window.location.href)})}); function tvly_run(n,t,i,a){var c='<i class="material-icons">error</i>',o=$('<div class="progress"><div class="indeterminate"></div></div>');n.hide(),n.after(o),$.post("/action",t,function(t){t.success?$(location).attr("href",i):(M.toast({html:c+" "+t.error}),o.remove(),a&&a(),n.append(" "+c),n.show())})}$(document).ready(function(){$(".action-checkin").click(function(){var t=$(this);tvly_run(t,{action:"checkin",station:t.data("station"),train:t.data("train")},"/")}),$(".action-checkout").click(function(){var t=$(this),n={action:"checkout",station:t.data("station"),force:t.data("force")};tvly_run(t,n,"/s/"+n.station,function(){t.append(" – Ohne Echtzeitdaten auschecken?"),t.data("force",!0)})}),$(".action-undo").click(function(){tvly_run($(this),{action:"undo"},window.location.href)})}); Loading
index.pl +191 −255 Original line number Diff line number Diff line Loading @@ -44,13 +44,10 @@ app->plugin( authentication => { autoload_user => 1, session_key => 'foodor', fail_render => { template => 'login' }, load_user => sub { my ( $self, $uid ) = @_; my $data = $self->get_user_data($uid); if ($data) { return { name => $data->{name} }; } return undef; return $self->get_user_data($uid); }, validate_user => sub { my ( $self, $username, $password, $extradata ) = @_; Loading @@ -68,6 +65,7 @@ app->plugin( }, } ); app->sessions->default_expiration( 60 * 60 * 24 * 180 ); app->defaults( layout => 'default' ); Loading Loading @@ -427,7 +425,7 @@ helper 'checkin' => sub { } my $success = $self->app->checkin_query->execute( $self->get_user_id, $self->current_user->{id}, $self->get_station_id( ds100 => $status->{station_ds100}, name => $status->{station_name} Loading Loading @@ -457,7 +455,7 @@ helper 'checkin' => sub { helper 'undo' => sub { my ($self) = @_; my $uid = $self->get_user_id; my $uid = $self->current_user->{id}; $self->app->get_last_actions_query->execute($uid); my $rows = $self->app->get_last_actions_query->fetchall_arrayref; Loading @@ -469,8 +467,8 @@ helper 'undo' => sub { return 'Repeated undo is not supported'; } my $success = $self->app->undo_query->execute( $self->get_user_id, my $success = $self->app->undo_query->execute( $self->current_user->{id}, DateTime->now( time_zone => 'Europe/Berlin' )->epoch, ); Loading Loading @@ -501,7 +499,7 @@ helper 'checkout' => sub { if ( not defined $train ) { if ($force) { my $success = $self->app->checkout_query->execute( $self->get_user_id, $self->current_user->{id}, $self->get_station_id( ds100 => $status->{station_ds100}, name => $status->{station_name} Loading @@ -523,7 +521,7 @@ helper 'checkout' => sub { } else { my $success = $self->app->checkout_query->execute( $self->get_user_id, $self->current_user->{id}, $self->get_station_id( ds100 => $status->{station_ds100}, name => $status->{station_name} Loading Loading @@ -580,7 +578,7 @@ helper 'get_user_token' => sub { helper 'get_user_data' => sub { my ( $self, $uid ) = @_; $uid //= $self->get_user_id; $uid //= $self->current_user->{id}; my $query = $self->app->get_user_query; $query->execute($uid); my $rows = $query->fetchall_arrayref; Loading @@ -603,7 +601,7 @@ helper 'get_user_data' => sub { deletion_requested => $row[7] }; } return; return undef; }; helper 'get_user_password' => sub { Loading @@ -623,80 +621,9 @@ helper 'get_user_password' => sub { return; }; helper 'get_user_name' => sub { my ($self) = @_; my $user = $self->req->headers->header('X-Remote-User') // 'dev'; return $user; }; helper 'get_user_id' => sub { helper 'add_user' => sub { my ( $self, $user_name, $email, $token, $password ) = @_; $user_name //= $self->get_user_name; if ( not -e $dbname ) { $self->app->dbh->begin_work; $self->app->dbh->do( qq{ create table schema_version ( version integer primary key ); } ); $self->app->dbh->do( qq{ create table users ( id integer primary key, name char(64) not null unique, status int not null, public_level bool not null, email char(256), token char(80), password text, registered_at datetime not null, last_login datetime not null, deletion_requested datetime ) } ); $self->app->dbh->do( qq{ create table stations ( id integer primary key, ds100 char(16) not null unique, name char(64) not null unique ) } ); $self->app->dbh->do( qq{ create table user_actions ( user_id int not null, action_id int not null, station_id int, action_time int not null, train_type char(16), train_line char(16), train_no char(16), train_id char(128), sched_time int, real_time int, route text, messages text, primary key (user_id, action_time) ) } ); $self->app->dbh->do( qq{ insert into schema_version (version) values (1); } ); $self->app->dbh->commit; } $self->app->get_userid_query->execute($user_name); my $rows = $self->app->get_userid_query->fetchall_arrayref; Loading Loading @@ -737,7 +664,7 @@ helper 'check_if_user_name_exists' => sub { helper 'get_user_travels' => sub { my ( $self, $limit ) = @_; my $uid = $self->get_user_id; my $uid = $self->current_user->{id}; my $query = $self->app->get_all_actions_query; if ($limit) { $query = $self->app->get_last_actions_query; Loading Loading @@ -800,7 +727,7 @@ helper 'get_user_travels' => sub { helper 'get_user_status' => sub { my ($self) = @_; my $uid = $self->get_user_id; my $uid = $self->current_user->{id}; $self->app->get_last_actions_query->execute($uid); my $rows = $self->app->get_last_actions_query->fetchall_arrayref; Loading Loading @@ -886,176 +813,33 @@ helper 'navbar_class' => sub { get '/' => sub { my ($self) = @_; if ( $self->is_user_authenticated ) { $self->render( 'landingpage', with_geolocation => 1 ); }; post '/action' => sub { my ($self) = @_; my $params = $self->req->json; if ( not exists $params->{action} ) { $params = $self->req->params->to_hash; } if ( not $params->{action} ) { $self->render( json => { success => 0, error => 'Missing action value', }, status => 400, ); return; } my $station = $params->{station}; if ( $params->{action} eq 'checkin' ) { my ( $train, $error ) = $self->checkin( $params->{station}, $params->{train}, ); if ($error) { $self->render( json => { success => 0, error => $error, }, ); } else { $self->render( json => { success => 1, }, ); } } elsif ( $params->{action} eq 'checkout' ) { my $error = $self->checkout( $params->{station}, $params->{force}, ); if ($error) { $self->render( json => { success => 0, error => $error, }, ); } else { $self->render( json => { success => 1, }, ); } $self->render( 'landingpage', intro => 1 ); } elsif ( $params->{action} eq 'undo' ) { my $error = $self->undo; if ($error) { $self->render( json => { success => 0, error => $error, }, ); } else { $self->render( json => { success => 1, }, ); } } else { $self->render( json => { success => 0, error => 'invalid action value', }, status => 400, ); } }; get '/a/account' => sub { my ($self) = @_; $self->render('account'); }; get '/a/export.json' => sub { my ($self) = @_; my $uid = $self->get_user_id; my $query = $self->app->get_all_actions_query; $query->execute($uid); my @entries; while ( my @row = $query->fetchrow_array ) { my ( $action, $raw_ts, $ds100, $name, $train_type, $train_line, $train_no, $train_id, $raw_sched_ts, $raw_real_ts, $raw_route, $raw_messages ) = @row; $name = decode( 'UTF-8', $name ); $raw_route = decode( 'UTF-8', $raw_route ); $raw_messages = decode( 'UTF-8', $raw_messages ); push( @entries, { action => $action_types[ $action - 1 ], action_ts => $raw_ts, station_ds100 => $ds100, station_name => $name, train_type => $train_type, train_line => $train_line, train_no => $train_no, train_id => $train_id, scheduled_ts => $raw_sched_ts, realtime_ts => $raw_real_ts, messages => $raw_messages ? [ map { [ split(qr{:}) ] } split( qr{[|]}, $raw_messages ) ] : undef, route => $raw_route ? [ split( qr{[|]}, $raw_route ) ] : undef, } ); } $self->render( json => [@entries], ); }; get '/a/history' => sub { my ($self) = @_; $self->render('history'); }; get '/x/about' => sub { get '/about' => sub { my ($self) = @_; $self->render( 'about', version => $VERSION ); }; get '/x/impressum' => sub { get '/impressum' => sub { my ($self) = @_; $self->render('imprint'); }; get '/x/imprint' => sub { get '/imprint' => sub { my ($self) = @_; $self->render('imprint'); }; post '/x/geolocation' => sub { post '/geolocation' => sub { my ($self) = @_; my $lon = $self->param('lon'); Loading Loading @@ -1085,12 +869,12 @@ post '/x/geolocation' => sub { }; get '/x/login' => sub { get '/login' => sub { my ($self) = @_; $self->render('login'); }; post '/x/login' => sub { post '/login' => sub { my ($self) = @_; my $user = $self->req->param('user'); my $password = $self->req->param('password'); Loading @@ -1114,18 +898,12 @@ post '/x/login' => sub { } }; get '/x/logout' => sub { my ($self) = @_; $self->logout; $self->redirect_to('/x/login'); }; get '/x/register' => sub { get '/register' => sub { my ($self) = @_; $self->render('register'); }; post '/x/register' => sub { post '/register' => sub { my ($self) = @_; my $user = $self->req->param('user'); my $email = $self->req->param('email'); Loading Loading @@ -1163,8 +941,7 @@ post '/x/register' => sub { return; } #if ( $self->check_if_user_name_exists($user) or $user eq 'dev' ) { if ( $user ne $self->get_user_name ) { if ( $self->check_if_user_name_exists($user) ) { $self->render( 'register', invalid => 'user_collision' ); return; } Loading @@ -1181,14 +958,14 @@ post '/x/register' => sub { my $token = make_token(); my $pw_hash = hash_password($password); my $user_id = $self->get_user_id( $user, $email, $token, $pw_hash ); my $user_id = $self->add_user( $user, $email, $token, $pw_hash ); my $body = "Hallo, ${user}!\n\n"; $body .= "Mit deiner E-Mail-Adresse (${email}) wurde ein Account auf\n"; $body .= "travelynx.finalrewind.org angelegt.\n\n"; $body .= "Falls die Registrierung von dir ausging, kannst du den Account unter\n"; $body .= "https://travelynx.finalrewind.org/x/reg/${user_id}/${token}\n"; $body .= "https://travelynx.finalrewind.org/reg/${user_id}/${token}\n"; $body .= "freischalten.\n\n"; $body .= "Falls nicht, ignoriere diese Mail bitte. Nach 48 Stunden wird deine\n"; Loading @@ -1200,7 +977,7 @@ post '/x/register' => sub { $body .= " * Datum: ${date}\n"; $body .= " * Verwendete IP: ${ip}\n"; $body .= " * Verwendeter Browser gemäß User Agent: ${ua}\n\n\n"; $body .= "Impressum: https://travelynx.finalrewind.org/x/impressum\n"; $body .= "Impressum: https://travelynx.finalrewind.org/impressum\n"; my $reg_mail = Email::Simple->create( header => [ Loading @@ -1221,7 +998,7 @@ post '/x/register' => sub { } }; get '/x/reg/:id/:token' => sub { get '/reg/:id/:token' => sub { my ($self) = @_; my $id = $self->stash('id'); Loading @@ -1244,7 +1021,166 @@ get '/x/reg/:id/:token' => sub { $self->render( 'login', from => 'verification' ); }; get '/*station' => sub { under sub { my ($self) = @_; return $self->is_user_authenticated; }; post '/action' => sub { my ($self) = @_; my $params = $self->req->json; if ( not exists $params->{action} ) { $params = $self->req->params->to_hash; } if ( not $params->{action} ) { $self->render( json => { success => 0, error => 'Missing action value', }, status => 400, ); return; } my $station = $params->{station}; if ( $params->{action} eq 'checkin' ) { my ( $train, $error ) = $self->checkin( $params->{station}, $params->{train}, ); if ($error) { $self->render( json => { success => 0, error => $error, }, ); } else { $self->render( json => { success => 1, }, ); } } elsif ( $params->{action} eq 'checkout' ) { my $error = $self->checkout( $params->{station}, $params->{force}, ); if ($error) { $self->render( json => { success => 0, error => $error, }, ); } else { $self->render( json => { success => 1, }, ); } } elsif ( $params->{action} eq 'undo' ) { my $error = $self->undo; if ($error) { $self->render( json => { success => 0, error => $error, }, ); } else { $self->render( json => { success => 1, }, ); } } else { $self->render( json => { success => 0, error => 'invalid action value', }, status => 400, ); } }; get '/account' => sub { my ($self) = @_; $self->render('account'); }; get '/history' => sub { my ($self) = @_; $self->render('history'); }; get '/export.json' => sub { my ($self) = @_; my $uid = $self->current_user->{id}; my $query = $self->app->get_all_actions_query; $query->execute($uid); my @entries; while ( my @row = $query->fetchrow_array ) { my ( $action, $raw_ts, $ds100, $name, $train_type, $train_line, $train_no, $train_id, $raw_sched_ts, $raw_real_ts, $raw_route, $raw_messages ) = @row; $name = decode( 'UTF-8', $name ); $raw_route = decode( 'UTF-8', $raw_route ); $raw_messages = decode( 'UTF-8', $raw_messages ); push( @entries, { action => $action_types[ $action - 1 ], action_ts => $raw_ts, station_ds100 => $ds100, station_name => $name, train_type => $train_type, train_line => $train_line, train_no => $train_no, train_id => $train_id, scheduled_ts => $raw_sched_ts, realtime_ts => $raw_real_ts, messages => $raw_messages ? [ map { [ split(qr{:}) ] } split( qr{[|]}, $raw_messages ) ] : undef, route => $raw_route ? [ split( qr{[|]}, $raw_route ) ] : undef, } ); } $self->render( json => [@entries], ); }; post '/logout' => sub { my ($self) = @_; $self->logout; $self->redirect_to('/login'); }; get '/s/*station' => sub { my ($self) = @_; my $station = $self->stash('station'); Loading
public/static/js/geolocation.js +2 −2 Original line number Diff line number Diff line Loading @@ -25,14 +25,14 @@ $(document).ready(function() { stationlink.attr('href', ds100); stationlink.text(name); resultBody.append('<tr><td><a href="/' + ds100 + '">' + name + '</a></td></tr>'); resultBody.append('<tr><td><a href="/s/' + ds100 + '">' + name + '</a></td></tr>'); }); placeholder.replaceWith(resultTable); } }; var processLocation = function(loc) { $.post('/x/geolocation', {lon: loc.coords.longitude, lat: loc.coords.latitude}, processResult); $.post('/geolocation', {lon: loc.coords.longitude, lat: loc.coords.latitude}, processResult); }; var processError = function(error) { Loading
public/static/js/geolocation.min.js +1 −1 Original line number Diff line number Diff line $(document).ready(function(){var e=$("p.geolocationhint"),t=$("div.geolocation div.progress"),o=function(o,a,n){e.remove(),t.remove()},a=function(e){e.error?o(0,e.error):0==e.candidates.length?o():(resultTable=$("<table><tbody></tbody></table>"),resultBody=resultTable.children(),$.each(e.candidates,function(e,t){var o=t.ds100,a=t.name,n=t.distance;n=n.toFixed(1);var r=$(document.createElement("a"));r.attr("href",o),r.text(a),resultBody.append('<tr><td><a href="/'+o+'">'+a+"</a></td></tr>")}),t.replaceWith(resultTable))},n=function(e){$.post("/x/geolocation",{lon:e.coords.longitude,lat:e.coords.latitude},a)},r=function(e){e.code==e.PERMISSION_DENIED?o():e.code==e.POSITION_UNAVAILABLE?o():(e.code,e.TIMEOUT,o())};navigator.geolocation?navigator.geolocation.getCurrentPosition(n,r):o()}); $(document).ready(function(){var a=$("p.geolocationhint"),n=$("div.geolocation div.progress"),t=function(e,t,o){a.remove(),n.remove()},o=function(e){e.error?t(0,e.error):0==e.candidates.length?t():(resultTable=$("<table><tbody></tbody></table>"),resultBody=resultTable.children(),$.each(e.candidates,function(e,t){var o=t.ds100,a=t.name,n=t.distance;n=n.toFixed(1);var r=$(document.createElement("a"));r.attr("href",o),r.text(a),resultBody.append('<tr><td><a href="/s/'+o+'">'+a+"</a></td></tr>")}),n.replaceWith(resultTable))};navigator.geolocation?navigator.geolocation.getCurrentPosition(function(e){$.post("/geolocation",{lon:e.coords.longitude,lat:e.coords.latitude},o)},function(e){e.code==e.PERMISSION_DENIED||e.code==e.POSITION_UNAVAILABLE||(e.code,e.TIMEOUT),t()}):t()});
public/static/js/travelynx-actions.js +1 −1 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ $(document).ready(function() { station: link.data('station'), force: link.data('force'), }; tvly_run(link, req, '/' + req.station, function() { tvly_run(link, req, '/s/' + req.station, function() { link.append(' – Ohne Echtzeitdaten auschecken?') link.data('force', true); }); Loading
public/static/js/travelynx-actions.min.js +1 −1 Original line number Diff line number Diff line function tvly_run(n,t,i,a){var c='<i class="material-icons">error</i>',o=$('<div class="progress"><div class="indeterminate"></div></div>');n.hide(),n.after(o),$.post("/action",t,function(t){t.success?$(location).attr("href",i):(M.toast({html:c+" "+t.error}),o.remove(),a&&a(),n.append(" "+c),n.show())})}$(document).ready(function(){$(".action-checkin").click(function(){var t=$(this);tvly_run(t,{action:"checkin",station:t.data("station"),train:t.data("train")},"/")}),$(".action-checkout").click(function(){var t=$(this),n={action:"checkout",station:t.data("station"),force:t.data("force")};tvly_run(t,n,"/"+n.station,function(){t.append(" – Ohne Echtzeitdaten auschecken?"),t.data("force",!0)})}),$(".action-undo").click(function(){tvly_run($(this),{action:"undo"},window.location.href)})}); function tvly_run(n,t,i,a){var c='<i class="material-icons">error</i>',o=$('<div class="progress"><div class="indeterminate"></div></div>');n.hide(),n.after(o),$.post("/action",t,function(t){t.success?$(location).attr("href",i):(M.toast({html:c+" "+t.error}),o.remove(),a&&a(),n.append(" "+c),n.show())})}$(document).ready(function(){$(".action-checkin").click(function(){var t=$(this);tvly_run(t,{action:"checkin",station:t.data("station"),train:t.data("train")},"/")}),$(".action-checkout").click(function(){var t=$(this),n={action:"checkout",station:t.data("station"),force:t.data("force")};tvly_run(t,n,"/s/"+n.station,function(){t.append(" – Ohne Echtzeitdaten auschecken?"),t.data("force",!0)})}),$(".action-undo").click(function(){tvly_run($(this),{action:"undo"},window.location.href)})});