Unverified Commit 6d261197 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

set visibility per journey (wip)

some odds and ends left to polish, but ready for testing
parent fb387866
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -420,6 +420,25 @@ sub startup {
		}
	);

	$self->helper(
		'visibility_icon' => sub {
			my ( $self, $visibility ) = @_;
			if ( $visibility eq 'public' ) {
				return 'language';
			}
			if ( $visibility eq 'travelynx' ) {
				return 'lock_open';
			}
			if ( $visibility eq 'unlisted' ) {
				return 'lock_outline';
			}
			if ( $visibility eq 'private' ) {
				return 'lock';
			}
			return 'help_outline';
		}
	);

	$self->helper(
		'checkin' => sub {
			my ( $self, %opt ) = @_;
@@ -1348,7 +1367,8 @@ sub startup {
				uid             => $uid,
				db              => $db,
				with_data       => 1,
				with_timestamps => 1
				with_timestamps => 1,
				with_visibility => 1,
			);

			if ($in_transit) {
@@ -1425,6 +1445,8 @@ sub startup {
					messages      => $in_transit->{messages},
					extra_data    => $in_transit->{data},
					comment       => $in_transit->{user_data}{comment},
					visibility    => $in_transit->{visibility},
					visibility_str => $in_transit->{visibility_str},
				};

				my $traewelling = $self->traewelling->get(
@@ -2205,6 +2227,7 @@ sub startup {
	$authed_r->get('/history/:year/:month')->to('traveling#monthly_history');
	$authed_r->get('/journey/add')->to('traveling#add_journey_form');
	$authed_r->get('/journey/comment')->to('traveling#comment_form');
	$authed_r->get('/journey/visibility')->to('traveling#visibility_form');
	$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');
@@ -2215,6 +2238,7 @@ sub startup {
	$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/visibility')->to('traveling#visibility_form');
	$authed_r->post('/journey/edit')->to('traveling#edit_journey');
	$authed_r->post('/journey/passenger_rights/*filename')
	  ->to('passengerrights#generate');
+114 −0
Original line number Diff line number Diff line
@@ -1312,6 +1312,120 @@ my @migrations = (
			}
		);
	},

	# v32 -> v33
	# add optional per-status visibility that overrides global visibility
	sub {
		my ($db) = @_;
		$db->query(
			qq{
				alter table journeys add column visibility smallint;
				alter table in_transit add column visibility smallint;
				drop view journeys_str;
				drop view in_transit_str;
				create view journeys_str as select
					journeys.id as journey_id, user_id,
					train_type, train_line, train_no, train_id,
					extract(epoch from checkin_time) as checkin_ts,
					extract(epoch from sched_departure) as sched_dep_ts,
					extract(epoch from real_departure) as real_dep_ts,
					checkin_station_id as dep_eva,
					dep_station.ds100 as dep_ds100,
					dep_station.name as dep_name,
					dep_station.lat as dep_lat,
					dep_station.lon as dep_lon,
					extract(epoch from checkout_time) as checkout_ts,
					extract(epoch from sched_arrival) as sched_arr_ts,
					extract(epoch from real_arrival) as real_arr_ts,
					checkout_station_id as arr_eva,
					arr_station.ds100 as arr_ds100,
					arr_station.name as arr_name,
					arr_station.lat as arr_lat,
					arr_station.lon as arr_lon,
					polylines.polyline as polyline,
					visibility,
					cancelled, edited, route, messages, user_data,
					dep_platform, arr_platform
					from journeys
					left join polylines on polylines.id = polyline_id
					left join stations as dep_station on checkin_station_id = dep_station.eva
					left join stations as arr_station on checkout_station_id = arr_station.eva
					;
				create view in_transit_str as select
					user_id,
					train_type, train_line, train_no, train_id,
					extract(epoch from checkin_time) as checkin_ts,
					extract(epoch from sched_departure) as sched_dep_ts,
					extract(epoch from real_departure) as real_dep_ts,
					checkin_station_id as dep_eva,
					dep_station.ds100 as dep_ds100,
					dep_station.name as dep_name,
					dep_station.lat as dep_lat,
					dep_station.lon as dep_lon,
					extract(epoch from checkout_time) as checkout_ts,
					extract(epoch from sched_arrival) as sched_arr_ts,
					extract(epoch from real_arrival) as real_arr_ts,
					checkout_station_id as arr_eva,
					arr_station.ds100 as arr_ds100,
					arr_station.name as arr_name,
					arr_station.lat as arr_lat,
					arr_station.lon as arr_lon,
					polylines.polyline as polyline,
					visibility,
					cancelled, route, messages, user_data,
					dep_platform, arr_platform, data
					from in_transit
					left join polylines on polylines.id = polyline_id
					left join stations as dep_station on checkin_station_id = dep_station.eva
					left join stations as arr_station on checkout_station_id = arr_station.eva
					;
			}
		);
		my $res = $db->select( 'users', [ 'id', 'public_level' ] );
		while ( my $row = $res->hash ) {
			my $old_level = $row->{public_level};
			my $new_level = 0;
			if ( $old_level & 0x01 ) {

				# status: account required
				$new_level = 80;
			}
			if ( $old_level & 0x02 ) {

				# status: public
				$new_level = 100;
			}
			if ( $old_level & 0x04 ) {

				# comment public
				$new_level |= 0x80;
			}
			if ( $old_level & 0x10 ) {

				# past: account required
				$new_level |= 0x100;
			}
			if ( $old_level & 0x20 ) {

				# past: public
				$new_level |= 0x200;
			}
			if ( $old_level & 0x40 ) {

				# past: infinite (default is 4 weeks)
				$new_level |= 0x400;
			}
			my $r = $db->update(
				'users',
				{ public_level => $new_level },
				{ id           => $row->{id} }
			)->rows;
			if ( $r != 1 ) {
				die("oh no");
			}
		}
		$db->update( 'schema_version', { version => 33 } );
	},
);

sub sync_stations {
+35 −43
Original line number Diff line number Diff line
@@ -9,6 +9,22 @@ use Crypt::Eksblowfish::Bcrypt qw(bcrypt en_base64);
use JSON;
use UUID::Tiny qw(:std);

my %visibility_itoa = (
	100 => 'public',
	80  => 'travelynx',
	60  => 'followers',
	30  => 'unlisted',
	10  => 'private',
);

my %visibility_atoi = (
	public    => 100,
	travelynx => 80,
	followers => 60,
	unlisted  => 30,
	private   => 10,
);

# Internal Helpers

sub hash_password {
@@ -438,50 +454,30 @@ sub privacy {
	my $public_level = $user->{is_public};

	if ( $self->param('action') and $self->param('action') eq 'save' ) {
		if ( $self->param('status_level') eq 'intern' ) {
			$public_level |= 0x01;
			$public_level &= ~0x02;
		}
		elsif ( $self->param('status_level') eq 'extern' ) {
			$public_level |= 0x02;
			$public_level &= ~0x01;
		}
		else {
			$public_level &= ~0x03;
		my %opt;
		my $default_visibility
		  = $visibility_atoi{ $self->param('status_level') };
		if ( defined $default_visibility ) {
			$opt{default_visibility} = $default_visibility;
		}

		# public comment with non-public status does not make sense
		if (    $self->param('public_comment')
			and $self->param('status_level') ne 'private' )
		{
			$public_level |= 0x04;
		}
		else {
			$public_level &= ~0x04;
		}
		$opt{comments_visible} = $self->param('public_comment') ? 1 : 0;

		$opt{past_all} = $self->param('history_age') eq 'infinite' ? 1 : 0;

		if ( $self->param('history_level') eq 'intern' ) {
			$public_level |= 0x10;
			$public_level &= ~0x20;
			$opt{past_visible} = 1;
		}
		elsif ( $self->param('history_level') eq 'extern' ) {
			$public_level |= 0x20;
			$public_level &= ~0x10;
			$opt{past_visible} = 2;
		}
		else {
			$public_level &= ~0x30;
		}

		if ( $self->param('history_age') eq 'infinite' ) {
			$public_level |= 0x40;
		}
		else {
			$public_level &= ~0x40;
			$opt{past_visible} = 0;
		}

		$self->users->set_privacy(
			uid => $user->{id},
			level => $public_level
			%opt
		);

		$self->flash( success => 'privacy' );
@@ -489,18 +485,14 @@ sub privacy {
	}
	else {
		$self->param(
			  status_level => $public_level & 0x01 ? 'intern'
			: $public_level & 0x02 ? 'extern'
			:                        'private'
		);
		$self->param( public_comment => $public_level & 0x04 ? 1 : 0 );
			status_level => $visibility_itoa{ $user->{default_visibility} } );
		$self->param( public_comment => $user->{comments_visible} );
		$self->param(
			  history_level => $public_level & 0x10 ? 'intern'
			: $public_level & 0x20 ? 'extern'
			  history_level => $user->{past_visible} & 0x01 ? 'intern'
			: $user->{past_visible} & 0x02 ? 'extern'
			:                                'private'
		);
		$self->param(
			history_age => $public_level & 0x40 ? 'infinite' : 'month' );
		$self->param( history_age => $user->{past_all} ? 'infinite' : 'month' );
		$self->render( 'privacy', name => $user->{name} );
	}
}
+432 −236
Original line number Diff line number Diff line
@@ -370,6 +370,14 @@ sub get_connecting_trains_p {
	return $promise;
}

sub compute_effective_visibility {
	my ( $self, $default_visibility, $journey_visibility ) = @_;
	if ( $journey_visibility eq 'default' ) {
		return $default_visibility;
	}
	return $journey_visibility;
}

# Controllers

sub homepage {
@@ -378,6 +386,10 @@ sub homepage {
		my $status = $self->get_user_status;
		my @recent_targets;
		if ( $status->{checked_in} ) {
			my $journey_visibility
			  = $self->compute_effective_visibility(
				$self->current_user->{default_visibility_str},
				$status->{visibility_str} );
			if ( defined $status->{arrival_countdown}
				and $status->{arrival_countdown} < ( 40 * 60 ) )
			{
@@ -390,10 +402,9 @@ sub homepage {
							version => $self->app->config->{version}
							  // 'UNKNOWN',
							user_status        => $status,
							journey_visibility => $journey_visibility,
							connections        => $connecting_trains,
							transit_fyi        => $transit_fyi,
							with_autocomplete => 1,
							with_geolocation  => 1
						);
						$self->users->mark_seen(
							uid => $self->current_user->{id} );
@@ -405,8 +416,7 @@ sub homepage {
							version => $self->app->config->{version}
							  // 'UNKNOWN',
							user_status        => $status,
							with_autocomplete => 1,
							with_geolocation  => 1
							journey_visibility => $journey_visibility,
						);
						$self->users->mark_seen(
							uid => $self->current_user->{id} );
@@ -414,6 +424,16 @@ sub homepage {
				)->wait;
				return;
			}
			else {
				$self->render(
					'landingpage',
					version     => $self->app->config->{version} // 'UNKNOWN',
					user_status => $status,
					journey_visibility => $journey_visibility,
				);
				$self->users->mark_seen( uid => $self->current_user->{id} );
				return;
			}
		}
		else {
			@recent_targets = uniq_by { $_->{eva} }
@@ -439,6 +459,26 @@ sub homepage {
	}
}

sub status_token_ok {
	my ( $self, $status, $ts2_ext ) = @_;
	my $token = $self->param('token') // q{};

	my ( $eva, $ts, $ts2 ) = split( qr{-}, $token );
	if ( not $ts ) {
		return;
	}

	$ts2 //= $ts2_ext;

	if (    $eva == $status->{dep_eva}
		and $ts == $status->{timestamp}->epoch
		and $ts2 == $status->{sched_departure}->epoch )
	{
		return 1;
	}
	return;
}

sub user_status {
	my ($self) = @_;

@@ -446,47 +486,33 @@ sub user_status {
	my $ts   = $self->stash('ts') // 0;
	my $user = $self->users->get_privacy_by_name( name => $name );

	if ( not $user or not $user->{public_level} & 0x03 ) {
	if ( not $user ) {
		$self->render('not_found');
		return;
	}

	if ( $user->{public_level} & 0x01 and not $self->is_user_authenticated ) {
		$self->render( 'login', redirect_to => $self->req->url );
		return;
	}

	my $status = $self->get_user_status( $user->{id} );
	my $journey;

	if (
		$ts
		and ( not $status->{checked_in}
			or $status->{sched_departure}->epoch != $ts )
		and (
			$user->{public_level} & 0x20
			or (    $user->{public_level} & 0x10
				and $self->is_user_authenticated )
		)
	  )
	{
		for my $candidate (
			$self->journeys->get(
				uid   => $user->{id},
				limit => 10,
				limit => 20,
			)
		  )
		{
			if ( $candidate->{sched_dep_ts} eq $ts ) {
				$journey = $self->journeys->get_single(
					uid           => $user->{id},
					journey_id    => $candidate->{id},
					verbose       => 1,
					with_datetime => 1,
					with_polyline => 1,
				);
				$self->redirect_to("/p/${name}/j/$candidate->{id}");
				return;
			}
		}
		$self->render('not_found');
		return;
	}

	my %tw_data = (
@@ -502,24 +528,30 @@ sub user_status {
		site_name => 'travelynx',
	);

	if ($journey) {
		$og_data{title} = $tw_data{title} = sprintf( 'Fahrt von %s nach %s',
			$journey->{from_name}, $journey->{to_name} );
		$og_data{description} = $tw_data{description}
		  = $journey->{rt_arrival}->strftime('Ankunft am %d.%m.%Y um %H:%M');
		$og_data{url} .= "/${ts}";
	}
	elsif (
		$ts
		and ( not $status->{checked_in}
			or $status->{sched_departure}->epoch != $ts )
	my $visibility;
	if ( $status->{checked_in} ) {
		$visibility
		  = $self->compute_effective_visibility(
			$user->{default_visibility_str},
			$status->{visibility_str} );
		if (
			not(
				$visibility eq 'public'
				or (    $visibility eq 'unlisted'
					and $self->status_token_ok( $status, $ts ) )
				or (
					$visibility eq 'travelynx'
					and (  $self->is_user_authenticated
						or $self->status_token_ok( $status, $ts ) )
				)
			)
		  )
		{
		$og_data{title}       = $tw_data{title} = "Bahnfahrt beendet";
		$og_data{description} = $tw_data{description}
		  = "${name} hat das Ziel erreicht";
			$status->{checked_in} = 0;
		}
	elsif ( $status->{checked_in} ) {
	}

	if ( $status->{checked_in} ) {
		$og_data{url} .= '/' . $status->{sched_departure}->epoch;
		$og_data{title}       = $tw_data{title}       = "${name} ist unterwegs";
		$og_data{description} = $tw_data{description} = sprintf(
@@ -537,40 +569,19 @@ sub user_status {
	else {
		$og_data{title} = $tw_data{title}
		  = "${name} ist gerade nicht eingecheckt";
		$og_data{description} = $tw_data{description}
		  = "Letztes Fahrtziel: $status->{arr_name}";
		$og_data{description} = $tw_data{description} = q{};
	}

	if ($journey) {
		if ( not $user->{public_level} & 0x04 ) {
			delete $journey->{user_data}{comment};
		}
		my $map_data = $self->journeys_to_map_data(
			journeys       => [$journey],
			include_manual => 1,
		);
		$self->render(
			'journey',
			error     => undef,
			with_map  => 1,
			readonly  => 1,
			journey   => $journey,
			twitter   => \%tw_data,
			opengraph => \%og_data,
			%{$map_data},
		);
	}
	else {
	$self->render(
		'user_status',
		name               => $name,
		public_level       => $user->{public_level},
		journey            => $status,
		journey_visibility => $visibility,
		twitter            => \%tw_data,
		opengraph          => \%og_data,
	);
}
}

sub public_profile {
	my ($self) = @_;
@@ -578,49 +589,78 @@ sub public_profile {
	my $name = $self->stash('name');
	my $user = $self->users->get_privacy_by_name( name => $name );

	if ( not $user ) {
		$self->render('not_found');
	}

	my $status = $self->get_user_status( $user->{id} );
	my $visibility;
	if ( $status->{checked_in} ) {
		$visibility
		  = $self->compute_effective_visibility(
			$user->{default_visibility_str},
			$status->{visibility_str} );
		if (
		$user
		and (
			$user->{public_level} & 0x22
			or (    $user->{public_level} & 0x11
				and $self->is_user_authenticated )
			not(
				$visibility eq 'public'
				or (    $visibility eq 'unlisted'
					and $self->status_token_ok($status) )
				or (
					$visibility eq 'travelynx'
					and (  $self->is_user_authenticated
						or $self->status_token_ok($status) )
				)
			)
		  )
		{
		my $status = $self->get_user_status( $user->{id} );
		my @journeys;
		if ( $user->{public_level} & 0x40 ) {
			@journeys = $self->journeys->get(
			$status->{checked_in} = 0;
		}
	}

	my %opt = (
		uid           => $user->{id},
		limit         => 10,
		with_datetime => 1
	);

	if ( not $user->{past_all} ) {
		my $now = DateTime->now( time_zone => 'Europe/Berlin' );
		$opt{before} = DateTime->now( time_zone => 'Europe/Berlin' );
		$opt{after}  = $now->clone->subtract( weeks => 4 );
	}

	if (
		$user->{default_visibility_str} eq 'public'
		or (    $user->{default_visibility_str} eq 'travelynx'
			and $self->is_user_authenticated )
	  )
	{
		$opt{with_default_visibility} = 1;
	}
	else {
			my $now       = DateTime->now( time_zone => 'Europe/Berlin' );
			my $month_ago = $now->clone->subtract( weeks => 4 );
			@journeys = $self->journeys->get(
				uid           => $user->{id},
				limit         => 10,
				with_datetime => 1,
				after         => $month_ago,
				before        => $now
			);
		$opt{with_default_visibility} = 0;
	}

	if ( $self->is_user_authenticated ) {
		$opt{min_visibility} = 'travelynx';
	}
	else {
		$opt{min_visibility} = 'public';
	}

	my @journeys = $self->journeys->get(%opt);

	$self->render(
		'profile',
		name               => $name,
		uid                => $user->{id},
		public_level       => $user->{public_level},
		journey            => $status,
		journey_visibility => $visibility,
		journeys           => [@journeys],
		version            => $self->app->config->{version} // 'UNKNOWN',
	);
}
	else {
		$self->render('not_found');
	}
}

sub public_journey_details {
	my ($self)     = @_;
@@ -630,7 +670,7 @@ sub public_journey_details {

	$self->param( journey_id => $journey_id );

	if ( not( $journey_id and $journey_id =~ m{ ^ \d+ $ }x ) ) {
	if ( not( $user and $journey_id and $journey_id =~ m{ ^ \d+ $ }x ) ) {
		$self->render(
			'journey',
			status  => 404,
@@ -640,32 +680,53 @@ sub public_journey_details {
		return;
	}

	if (
		$user
		and (
			$user->{public_level} & 0x20
			or (    $user->{public_level} & 0x10
				and $self->is_user_authenticated )
		)
	  )
	{
	my $journey = $self->journeys->get_single(
		uid             => $user->{id},
		journey_id      => $journey_id,
		verbose         => 1,
		with_datetime   => 1,
		with_polyline   => 1,
		with_visibility => 1,
	);

		if ( not( $user->{public_level} & 0x40 ) ) {
			my $month_ago = DateTime->now( time_zone => 'Europe/Berlin' )
			  ->subtract( weeks => 4 )->epoch;
			if ( $journey and $journey->{rt_dep_ts} < $month_ago ) {
				$journey = undef;
	if ( not $journey ) {
		$self->render(
			'journey',
			status  => 404,
			error   => 'notfound',
			journey => {}
		);
		return;
	}

	my $visibility
	  = $self->compute_effective_visibility( $user->{default_visibility_str},
		$journey->{visibility_str} );

	if (
		not(
			$visibility eq 'public'
			or (    $visibility eq 'unlisted'
				and $self->status_token_ok($journey) )
			or (
				$visibility eq 'travelynx'
				and (  $self->is_user_authenticated
					or $self->status_token_ok($journey) )
			)
		)
	  )
	{
		$self->render(
			'journey',
			status  => 404,
			error   => 'notfound',
			journey => {}
		);
		return;
	}

		if ($journey) {
	# TODO re-add age check unless status_token_ok (helper function?)

	my $title = sprintf( 'Fahrt von %s nach %s am %s',
		$journey->{from_name}, $journey->{to_name},
		$journey->{rt_arrival}->strftime('%d.%m.%Y') );
@@ -722,17 +783,10 @@ sub public_journey_details {
		readonly           => 1,
		twitter            => \%tw_data,
		opengraph          => \%og_data,
		journey_visibility => $visibility,
		%{$map_data},
	);
}
		else {
			$self->render('not_found');
		}
	}
	else {
		$self->render('not_found');
	}
}

sub public_status_card {
	my ($self) = @_;
@@ -743,27 +797,43 @@ sub public_status_card {

	delete $self->stash->{layout};

	if ( not $user ) {
		$self->render('not_found');
		return;
	}

	my $status = $self->get_user_status( $user->{id} );
	my $visibility;
	if ( $status->{checked_in} ) {
		$visibility
		  = $self->compute_effective_visibility(
			$user->{default_visibility_str},
			$status->{visibility_str} );
		if (
		$user
		and (
			$user->{public_level} & 0x02
			or (    $user->{public_level} & 0x01
				and $self->is_user_authenticated )
			not(
				$visibility eq 'public'
				or (    $visibility eq 'unlisted'
					and $self->status_token_ok($status) )
				or (
					$visibility eq 'travelynx'
					and (  $self->is_user_authenticated
						or $self->status_token_ok($status) )
				)
			)
		  )
		{
		my $status = $self->get_user_status( $user->{id} );
			$status->{checked_in} = 0;
		}
	}

	$self->render(
		'_public_status_card',
		name               => $name,
		public_level       => $user->{public_level},
			journey      => $status
		journey            => $status,
		journey_visibility => $visibility,
	);
}
	else {
		$self->render('not_found');
	}
}

sub status_card {
	my ($self) = @_;
@@ -772,6 +842,10 @@ sub status_card {
	delete $self->stash->{layout};

	if ( $status->{checked_in} ) {
		my $journey_visibility
		  = $self->compute_effective_visibility(
			$self->current_user->{default_visibility_str},
			$status->{visibility_str} );
		if ( defined $status->{arrival_countdown}
			and $status->{arrival_countdown} < ( 40 * 60 ) )
		{
@@ -782,18 +856,27 @@ sub status_card {
					$self->render(
						'_checked_in',
						journey            => $status,
						journey_visibility => $journey_visibility,
						connections        => $connecting_trains,
						transit_fyi        => $transit_fyi
					);
				}
			)->catch(
				sub {
					$self->render( '_checked_in', journey => $status );
					$self->render(
						'_checked_in',
						journey            => $status,
						journey_visibility => $journey_visibility,
					);
				}
			)->wait;
			return;
		}
		$self->render( '_checked_in', journey => $status );
		$self->render(
			'_checked_in',
			journey            => $status,
			journey_visibility => $journey_visibility,
		);
	}
	elsif ( $status->{cancellation} ) {
		$self->render_later;
@@ -1698,6 +1781,7 @@ sub journey_details {
		verbose         => 1,
		with_datetime   => 1,
		with_polyline   => 1,
		with_visibility => 1,
	);

	if ($journey) {
@@ -1705,15 +1789,18 @@ sub journey_details {
			journeys       => [$journey],
			include_manual => 1,
		);
		my $with_share;
		my $share_text;
		my $with_share = $user->{is_public} & 0x40 ? 1 : 0;
		if ( not $with_share and $user->{is_public} & 0x20 ) {
			my $month_ago = DateTime->now( time_zone => 'Europe/Berlin' )
			  ->subtract( weeks => 4 )->epoch;
			$with_share = $journey->{rt_dep_ts} > $month_ago ? 1 : 0;
		}

		if ($with_share) {
		my $visibility
		  = $self->compute_effective_visibility(
			$user->{default_visibility_str},
			$journey->{visibility_str} );

		if (   $visibility eq 'public'
			or $visibility eq 'travelynx'
			or $visibility eq 'unlisted' )
		{
			my $delay = 'pünktlich ';
			if ( $journey->{rt_arrival} != $journey->{sched_arrival} ) {
				$delay = sprintf(
@@ -1724,6 +1811,7 @@ sub journey_details {
					) / 60
				);
			}
			$with_share = 1;
			$share_text
			  = $journey->{km_route}
			  ? sprintf( '%.0f km', $journey->{km_route} )
@@ -1733,10 +1821,12 @@ sub journey_details {
				$delay,           $journey->{rt_arrival}->strftime('%H:%M') );
		}

		# TODO add token if visibility != public
		$self->render(
			'journey',
			error              => undef,
			journey            => $journey,
			journey_visibility => $visibility,
			with_map           => 1,
			with_share         => $with_share,
			share_text         => $share_text,
@@ -1754,6 +1844,112 @@ sub journey_details {

}

sub visibility_form {
	my ($self)     = @_;
	my $dep_ts     = $self->param('dep_ts');
	my $journey_id = $self->param('id');
	my $action     = $self->param('action') // 'none';
	my $user       = $self->current_user;
	my $user_level = $user->{default_visibility_str};
	my $uid        = $user->{id};
	my $status     = $self->get_user_status;
	my $visibility = $status->{visibility};
	my $journey;

	if ($journey_id) {
		$journey = $self->journeys->get_single(
			uid             => $uid,
			journey_id      => $journey_id,
			with_datetime   => 1,
			with_visibility => 1,
		);
		$visibility = $journey->{visibility};
	}

	if ( $action eq 'save' ) {
		if ( $self->validation->csrf_protect->has_error('csrf_token') ) {
			$self->render(
				'edit_visibility',
				error      => 'csrf',
				user_level => $user_level,
				journey    => {}
			);
		}
		elsif ( $dep_ts and $dep_ts != $status->{sched_departure}->epoch ) {

			# TODO find and update appropriate past journey (if it exists)
			$self->render(
				'edit_visibility',
				error      => 'old',
				user_level => $user_level,
				journey    => {}
			);
		}
		else {
			$self->app->log->debug("set visibility");
			if ($dep_ts) {
				$self->in_transit->update_visibility(
					uid        => $uid,
					visibility => $self->param('status_level'),
				);
				$self->redirect_to('/');
			}
			elsif ($journey_id) {
				$self->journeys->update_visibility(
					uid        => $uid,
					id         => $journey_id,
					visibility => $self->param('status_level'),
				);
				$self->redirect_to( '/journey/' . $journey_id );
			}
		}
		return;
	}

	# todo use visibility_str
	if ( not defined $visibility ) {
		$self->param( status_level => 'default' );
	}
	elsif ( $visibility == 100 ) {
		$self->param( status_level => 'public' );
	}
	elsif ( $visibility == 80 ) {
		$self->param( status_level => 'travelynx' );
	}
	elsif ( $visibility == 30 ) {
		$self->param( status_level => 'unlisted' );
	}
	elsif ( $visibility == 10 ) {
		$self->param( status_level => 'private' );
	}

	if ($journey_id) {
		$self->render(
			'edit_visibility',
			error      => undef,
			user_level => $user_level,
			journey    => $journey
		);
	}
	elsif ( $status->{checked_in} ) {
		$self->param( dep_ts => $status->{sched_departure}->epoch );
		$self->render(
			'edit_visibility',
			error      => undef,
			user_level => $user_level,
			journey    => $status
		);
	}
	else {
		$self->render(
			'edit_visibility',
			error      => 'notfound',
			user_level => $user_level,
			journey    => {}
		);
	}
}

sub comment_form {
	my ($self) = @_;
	my $dep_ts = $self->param('dep_ts');
+49 −2

File changed.

Preview size limit exceeded, changes collapsed.

Loading