diff options
| -rwxr-xr-x | lib/Travelynx.pm | 35 | ||||
| -rw-r--r-- | lib/Travelynx/Controller/Account.pm | 22 | ||||
| -rwxr-xr-x | lib/Travelynx/Controller/Traveling.pm | 38 | ||||
| -rw-r--r-- | templates/_public_status_card.html.ep | 87 | ||||
| -rw-r--r-- | templates/account.html.ep | 14 | ||||
| -rw-r--r-- | templates/privacy.html.ep | 42 | ||||
| -rw-r--r-- | templates/user_status.html.ep | 5 | 
7 files changed, 243 insertions, 0 deletions
| diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm index b04526a..8760135 100755 --- a/lib/Travelynx.pm +++ b/lib/Travelynx.pm @@ -775,6 +775,38 @@ sub startup {  	);  	$self->helper( +		'get_privacy_by_name' => sub { +			my ( $self, $name ) = @_; + +			my $res = $self->pg->db->select( +				'users', +				[ 'id', 'public_level' ], +				{ +					name   => $name, +					status => 1 +				} +			); + +			if ( my $user = $res->hash ) { +				return $user; +			} +			return; +		} +	); + +	$self->helper( +		'set_privacy' => sub { +			my ( $self, $uid, $public_level ) = @_; + +			$self->pg->db->update( +				'users', +				{ public_level => $public_level }, +				{ id           => $uid } +			); +		} +	); + +	$self->helper(  		'mark_for_password_reset' => sub {  			my ( $self, $db, $uid, $token ) = @_; @@ -1696,6 +1728,7 @@ sub startup {  	$r->get('/recover/:id/:token')->to('account#recover_password');  	$r->get('/register')->to('account#registration_form');  	$r->get('/reg/:id/:token')->to('account#verify'); +	$r->get('/status/:name')->to('traveling#user_status');  	$r->post('/action')->to('traveling#log_action');  	$r->post('/geolocation')->to('traveling#geolocation');  	$r->post('/list_departures')->to('traveling#redirect_to_station'); @@ -1715,6 +1748,7 @@ sub startup {  	);  	$authed_r->get('/account')->to('account#account'); +	$authed_r->get('/account/privacy')->to('account#privacy');  	$authed_r->get('/ajax/status_card.html')->to('traveling#status_card');  	$authed_r->get('/cancelled')->to('traveling#cancelled');  	$authed_r->get('/change_password')->to('account#password_form'); @@ -1728,6 +1762,7 @@ sub startup {  	$authed_r->get('/journey/:id')->to('traveling#journey_details');  	$authed_r->get('/s/*station')->to('traveling#station');  	$authed_r->get('/confirm_mail/:token')->to('account#confirm_mail'); +	$authed_r->post('/account/privacy')->to('account#privacy');  	$authed_r->post('/journey/add')->to('traveling#add_journey_form');  	$authed_r->post('/journey/edit')->to('traveling#edit_journey');  	$authed_r->post('/change_password')->to('account#change_password'); diff --git a/lib/Travelynx/Controller/Account.pm b/lib/Travelynx/Controller/Account.pm index e4b385c..44babfa 100644 --- a/lib/Travelynx/Controller/Account.pm +++ b/lib/Travelynx/Controller/Account.pm @@ -208,6 +208,28 @@ sub do_logout {  	$self->redirect_to('/login');  } +sub privacy { +	my ($self) = @_; + +	my $user         = $self->current_user; +	my $public_level = $user->{is_public}; + +	if ( $self->param('action') and $self->param('action') eq 'save' ) { +		if ( $self->param('public_status') ) { +			$public_level |= 0x02; +		} +		else { +			$public_level &= ~0x02; +		} +		$self->set_privacy( $user->{id}, $public_level ); +	} +	else { +		$self->param( public_status => $public_level & 0x02 ? 1 : 0 ); +	} + +	$self->render( 'privacy', name => $user->{name} ); +} +  sub change_mail {  	my ($self) = @_; diff --git a/lib/Travelynx/Controller/Traveling.pm b/lib/Travelynx/Controller/Traveling.pm index 81b3a70..cf704ec 100755 --- a/lib/Travelynx/Controller/Traveling.pm +++ b/lib/Travelynx/Controller/Traveling.pm @@ -25,6 +25,44 @@ sub homepage {  	}  } +sub user_status { +	my ($self) = @_; + +	my $name = $self->stash('name'); +	my $user = $self->get_privacy_by_name($name); + +	if ( $user and ( $user->{public_level} & 0x02 ) ) { +		my $status = $self->get_user_status( $user->{id} ); +		$self->render( +			'user_status', +			name    => $name, +			journey => $status +		); +	} +	else { +		$self->render('not_found'); +	} +} + +sub public_status_card { +	my ($self) = @_; + +	my $name = $self->stash('name'); +	my $user = $self->get_privacy_by_name($name); + +	if ( $user and ( $user->{public_level} & 0x02 ) ) { +		my $status = $self->get_user_status( $user->{id} ); +		$self->render( +			'_public_status_card', +			name    => $name, +			journey => $status +		); +	} +	else { +		$self->render('not_found'); +	} +} +  sub status_card {  	my ($self) = @_;  	my $status = $self->get_user_status; diff --git a/templates/_public_status_card.html.ep b/templates/_public_status_card.html.ep new file mode 100644 index 0000000..1b33c18 --- /dev/null +++ b/templates/_public_status_card.html.ep @@ -0,0 +1,87 @@ +% if ($journey->{checked_in}) { +	<div class="card green darken-4"> +		<div class="card-content white-text"> +			<span class="card-title"><%= $name %> ist unterwegs</span> +			<p> +				In <b><%= $journey->{train_type} %> <%= $journey->{train_no} %></b> +				% if ($journey->{arr_name}) { +					von <b><%= $journey->{dep_name} %></b> nach <b><%= $journey->{arr_name} %></b>. +				% } +				% else { +					ab <b><%= $journey->{dep_name} %></b>. +				% } +			</p> +			<p> +				<b><%= $journey->{real_departure}->strftime('%H:%M') %></b> +				% if ($journey->{real_departure}->epoch != $journey->{sched_departure}->epoch) { +					(<%= sprintf('%+d', ($journey->{real_departure}->epoch - $journey->{sched_departure}->epoch)/60) %>) +				% } +				→ +				% if ($journey->{real_arrival}->epoch) { +					<b><%= $journey->{real_arrival}->strftime('%H:%M') %></b> +					% if ($journey->{real_arrival}->epoch != $journey->{sched_arrival}->epoch) { +						(<%= sprintf('%+d', ($journey->{real_arrival}->epoch - $journey->{sched_arrival}->epoch)/60) %>) +					% } +				% } +				% elsif ($journey->{arr_name}) { +					noch nicht bekannt +				% } +				% else { +					unbekannt +				% } +			</p> +			<p> +				<div class="center"> +					% if ($journey->{departure_countdown} > 120) { +						Abfahrt in <%= sprintf('%.f', $journey->{departure_countdown} / 60) %> Minuten +					% } +					% elsif ($journey->{departure_countdown} > 60) { +						Abfahrt in einer Minute +					% } +					% elsif ($journey->{departure_countdown} > 0) { +						Abfahrt in weniger als einer Minute +					% } +					% elsif (defined $journey->{arrival_countdown}) { +						% if ($journey->{arrival_countdown} > 60) { +							Ankunft in <%= sprintf('%.f', $journey->{arrival_countdown} / 60) %> +							Minute<%= sprintf('%.f', $journey->{arrival_countdown} / 60) == 1 ? '' : 'n' %> +						% } +						% elsif ($journey->{arrival_countdown} > 0) { +							Ankunft in weniger als einer Minute +						% } +						% else { +							Ziel erreicht +						% } +					% } +					% elsif ($journey->{arr_name}) { +						Ankunft in mehr als zwei Stunden +					% } +				</div> +				<div class="progress green darken-3" style="height: 1ex;"> +					<div class="determinate white" style="width: <%= sprintf('%.2f', 100 * ($journey->{journey_completion} // 0)); %>%;"></div> +				</div> +			</p> +			% if (@{$journey->{messages} // []} > 0 and $journey->{messages}[0]) { +				<p style="margin-bottom: 2ex;"> +					<ul> +						% for my $message (reverse @{$journey->{messages} // []}) { +							% if ($journey->{sched_departure}->epoch - $message->[0]->epoch < 1800) { +								<li> <i class="material-icons tiny">warning</i> <%= $message->[0]->strftime('%H:%M') %>: <%= $message->[1] %></li> +							% } +						% } +					</ul> +				</p> +			% } +		</div> +	</div> +% } +% else { +	<div class="card grey darken-4"> +		<div class="card-content white-text"> +			<span class="card-title"><%= $name %> ist gerade nicht eingecheckt</span> +			<p> +				Zuletzt gesehen in <%= $journey->{arr_name} %>. +			</p> +		</div> +	</div> +% } diff --git a/templates/account.html.ep b/templates/account.html.ep index 92b61db..076adf1 100644 --- a/templates/account.html.ep +++ b/templates/account.html.ep @@ -37,6 +37,20 @@  				<td><a href="/change_password"><i class="material-icons">edit</i> ändern</a></td>  			</tr>  			<tr> +				<th scope="row">Privatsphäre</th> +				<td> +					% if ($acc->{is_public} == 0) { +						Keine öffentlichen Daten +					% } +					% else { +						Öffentliche Daten: +					% } +					% if ($acc->{is_public} & 0x02) { +						Status +					% } +					<a href="/account/privacy"><i class="material-icons">edit</i> ändern</a></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/privacy.html.ep b/templates/privacy.html.ep new file mode 100644 index 0000000..bf509ce --- /dev/null +++ b/templates/privacy.html.ep @@ -0,0 +1,42 @@ +<h1>Privatsphäre</h1> +<div class="row"> +	<div class="col s12"> +		Hier kannst du auswählen, welche Aspekte deines Accounts bzw. deiner +		Bahnfahrten öffentlich einsehbar sind. Öffentliche Daten sind +		grundsätzlich für <i>alle</i> einsehbar, die die (leicht erratbare) URL +		kennen. +	</div> +</div> +<h2>Öffentliche Daten:</h2> +%= form_for '/account/privacy' => (method => 'POST') => begin +	%= csrf_field +	<div class="row"> +		<div class="input-field col s12"> +			<label> +				%= check_box public_status => 1 +				<span class="black-text">Aktueller Status</span> +			</label> +		</div> +	</div> +	<div class="row"> +		<div class="col s12"> +			Wenn aktiv, ist dein aktueller Status unter <a href="/status/<%= $name +			%>">/status/<%= $name %></a> abrufbar. Wenn du eingecheckt bist, +			werden dort Zug, Start- und Zielstation, Abfahrts- und Ankunftszeit +			gezeigt; andernfalls lediglich der Zielbahnhof der letzten Reise. +			Wann die letzte Reise beendet wurde, wird bewusst nicht angegeben. +		</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 diff --git a/templates/user_status.html.ep b/templates/user_status.html.ep new file mode 100644 index 0000000..7691258 --- /dev/null +++ b/templates/user_status.html.ep @@ -0,0 +1,5 @@ +<div class="row"> +	<div class="col s12"> +		%= include '_public_status_card', name => $name, journey => $journey +	</div> +</div> | 
