def route(self, request, *args, **kwargs): params = request.POST if request.method == 'POST' else request.GET form = RouteForm(params, request=request) if not form.is_valid(): return Response({ 'errors': form.errors, }, status=400) options = RouteOptions.get_for_request(request) try: options.update(params, ignore_unknown=True) except ValidationError as e: return Response({ 'errors': (str(e), ), }, status=400) try: route = Router.load().get_route( origin=form.cleaned_data['origin'], destination=form.cleaned_data['destination'], permissions=AccessPermission.get_for_request(request), options=options) except NotYetRoutable: return Response({ 'error': _('Not yet routable, try again shortly.'), }) except LocationUnreachable: return Response({ 'error': _('Unreachable location.'), }) except NoRouteFound: return Response({ 'error': _('No route found.'), }) origin_values = api_stats_clean_location_value( form.cleaned_data['origin'].pk) destination_values = api_stats_clean_location_value( form.cleaned_data['destination'].pk) increment_cache_key('apistats__route') for origin_value in origin_values: for destination_value in destination_values: increment_cache_key('apistats__route_tuple_%s_%s' % (origin_value, destination_value)) for value in origin_values: increment_cache_key('apistats__route_origin_%s' % value) for value in destination_values: increment_cache_key('apistats__route_destination_%s' % value) return Response({ 'request': { 'origin': form.cleaned_data['origin'].pk, 'destination': form.cleaned_data['destination'].pk, }, 'options': options.serialize(), 'result': route.serialize(locations=visible_locations_for_request(request)), })
def get_user_data(request): permissions = AccessPermission.get_for_request(request) result = { 'logged_in': bool(request.user.is_authenticated), 'allow_editor': can_access_editor(request), 'allow_control_panel': request.user_permissions.control_panel, 'has_positions': Position.user_has_positions(request.user) } if permissions: result.update({ 'title': _('not logged in'), 'subtitle': ungettext_lazy('%d area unlocked', '%d areas unlocked', len(permissions)) % len(permissions), 'permissions': tuple(permissions), }) else: result.update({ 'title': _('Login'), 'subtitle': None, 'permissions': (), }) if request.user.is_authenticated: result['title'] = request.user.username return result
def get_custom_location_for_request(slug: str, request): match = re.match(r'^c:(?P<level>[a-z0-9-_]+):(?P<x>-?\d+(\.\d+)?):(?P<y>-?\d+(\.\d+)?)$', slug) if match is None: return None level = levels_by_short_label_for_request(request).get(match.group('level')) if not isinstance(level, Level): return None return CustomLocation(level, float(match.group('x')), float(match.group('y')), AccessPermission.get_for_request(request))
def set_tile_access_cookie(request, response): access_permissions = AccessPermission.get_for_request(request) if access_permissions: cookie = build_tile_access_cookie(access_permissions, settings.SECRET_TILE_KEY) response.set_cookie(settings.TILE_ACCESS_COOKIE_NAME, cookie, max_age=60, domain=settings.TILE_ACCESS_COOKIE_DOMAIN, httponly=settings.TILE_ACCESS_COOKIE_HTTPONLY, secure=settings.TILE_ACCESS_COOKIE_SECURE) else: response.delete_cookie(settings.TILE_ACCESS_COOKIE_NAME) response['Cache-Control'] = 'no-cache'
def locate(self, request, *args, **kwargs): try: location = Locator.load().locate(request.data, permissions=AccessPermission.get_for_request(request)) if location is not None: increment_cache_key('apistats__locate__%s' % location.pk) except ValidationError: return Response({ 'errors': (_('Invalid scan data.'),), }, status=400) return Response({'location': None if location is None else location.serialize(simple_geometry=True)})
def route(self, request, *args, **kwargs): params = request.POST if request.method == 'POST' else request.GET form = RouteForm(params, request=request) if not form.is_valid(): return Response({ 'errors': form.errors, }, status=400) options = RouteOptions.get_for_request(request) try: options.update(params, ignore_unknown=True) except ValidationError as e: return Response({ 'errors': (str(e), ), }, status=400) try: route = Router.load().get_route(origin=form.cleaned_data['origin'], destination=form.cleaned_data['destination'], permissions=AccessPermission.get_for_request(request), options=options) except NotYetRoutable: return Response({ 'error': _('Not yet routable, try again shortly.'), }) except LocationUnreachable: return Response({ 'error': _('Unreachable location.'), }) except NoRouteFound: return Response({ 'error': _('No route found.'), }) origin_values = api_stats_clean_location_value(form.cleaned_data['origin'].pk) destination_values = api_stats_clean_location_value(form.cleaned_data['destination'].pk) increment_cache_key('apistats__route') for origin_value in origin_values: for destination_value in destination_values: increment_cache_key('apistats__route_tuple_%s_%s' % (origin_value, destination_value)) for value in origin_values: increment_cache_key('apistats__route_origin_%s' % value) for value in destination_values: increment_cache_key('apistats__route_destination_%s' % value) return Response({ 'request': { 'origin': form.cleaned_data['origin'].pk, 'destination': form.cleaned_data['destination'].pk, }, 'options': options.serialize(), 'result': route.serialize(locations=visible_locations_for_request(request)), })
def locate(self, request, *args, **kwargs): try: location = Locator.load().locate( request.data, permissions=AccessPermission.get_for_request(request)) except ValidationError: return Response({ 'errors': (_('Invalid scan data.'), ), }, status=400) return Response({ 'location': None if location is None else location.serialize( simple_geometry=True) })
def get_user_data(request): permissions = AccessPermission.get_for_request(request) result = { 'logged_in': bool(request.user.is_authenticated), } if permissions: result.update({ 'title': _('not logged in'), 'subtitle': ungettext_lazy('%d area unlocked', '%d areas unlocked', len(permissions)) % len(permissions), 'permissions': tuple(permissions), }) else: result.update({ 'title': _('Login'), 'subtitle': None, 'permissions': (), }) if request.user.is_authenticated: result['title'] = request.user.username return result
def get_user_data(request): permissions = AccessPermission.get_for_request(request) result = { 'logged_in': bool(request.user.is_authenticated), 'allow_editor': can_access_editor(request), 'allow_control_panel': request.user_permissions.control_panel, } if permissions: result.update({ 'title': _('not logged in'), 'subtitle': ungettext_lazy('%d area unlocked', '%d areas unlocked', len(permissions)) % len(permissions), 'permissions': tuple(permissions), }) else: result.update({ 'title': _('Login'), 'subtitle': None, 'permissions': (), }) if request.user.is_authenticated: result['title'] = request.user.username return result
def graph_edit(request, level=None, space=None): if not request.user_permissions.can_access_base_mapdata: raise PermissionDenied Level = request.changeset.wrap_model('Level') Space = request.changeset.wrap_model('Space') GraphNode = request.changeset.wrap_model('GraphNode') GraphEdge = request.changeset.wrap_model('GraphEdge') can_edit = request.changeset.can_edit(request) ctx = { 'path': request.path, 'can_edit': can_edit, 'levels': Level.objects.filter(Level.q_for_request(request), on_top_of__isnull=True), 'level_url': 'editor.levels.graph', } create_nodes = False if level is not None: level = get_object_or_404(Level.objects.filter(Level.q_for_request(request)), pk=level) ctx.update({ 'back_url': reverse('editor.levels.detail', kwargs={'pk': level.pk}), 'back_title': _('back to level'), 'level': level, 'geometry_url': '/api/editor/geometries/?level='+str(level.primary_level_pk), }) elif space is not None: queryset = Space.objects.filter(Space.q_for_request(request)).select_related('level').defer('geometry') space = get_object_or_404(queryset, pk=space) level = space.level ctx.update({ 'space': space, 'level': space.level, 'back_url': reverse('editor.spaces.detail', kwargs={'level': level.pk, 'pk': space.pk}), 'back_title': _('back to space'), 'parent_url': reverse('editor.levels.graph', kwargs={'level': level.pk}), 'parent_title': _('to level graph'), 'geometry_url': '/api/editor/geometries/?space='+str(space.pk), }) create_nodes = True if request.method == 'POST': changeset_exceeded = get_changeset_exceeded(request) graphnode_changes = {} if changeset_exceeded: graphnode_changes = request.changeset.get_changed_objects_by_model('GraphNode') if request.POST.get('delete') == '1': # Delete this graphnode! node = get_object_or_404(GraphNode, pk=request.POST.get('pk')) if changeset_exceeded and node.pk not in graphnode_changes: messages.error(request, _('You can not delete this graph node because your changeset is full.')) return redirect(request.path) if request.POST.get('delete_confirm') == '1': with request.changeset.lock_to_edit(request) as changeset: if changeset.can_edit(request): node.edges_from_here.all().delete() node.edges_to_here.all().delete() node.delete() else: messages.error(request, _('You can not edit changes on this changeset.')) return redirect(request.path) messages.success(request, _('Graph Node was successfully deleted.')) return redirect(request.path) return render(request, 'editor/delete.html', { 'model_title': GraphNode._meta.verbose_name, 'pk': node.pk, 'obj_title': node.title }) permissions = AccessPermission.get_for_request(request) | set([None]) edge_settings_form = GraphEdgeSettingsForm(instance=GraphEdge(), request=request, data=request.POST) graph_action_form = GraphEditorActionForm(request=request, allow_clicked_position=create_nodes, data=request.POST) if edge_settings_form.is_valid() and graph_action_form.is_valid(): goto_space = graph_action_form.cleaned_data['goto_space'] if goto_space is not None: return redirect(reverse('editor.spaces.graph', kwargs={'space': goto_space.pk})) set_active_node = False active_node = graph_action_form.cleaned_data['active_node'] clicked_node = graph_action_form.cleaned_data['clicked_node'] clicked_position = graph_action_form.cleaned_data.get('clicked_position') if clicked_node is not None and clicked_position is None: if active_node is None: active_node = clicked_node set_active_node = True elif active_node == clicked_node: active_node = None set_active_node = True else: with request.changeset.lock_to_edit(request) as changeset: if changeset.can_edit(request): connect_nodes(request, active_node, clicked_node, edge_settings_form) active_node = clicked_node if edge_settings_form.cleaned_data['activate_next'] else None set_active_node = True else: messages.error(request, _('You can not edit changes on this changeset.')) elif (clicked_node is None and clicked_position is not None and active_node is None and space.geometry.contains(clicked_position)): if changeset_exceeded: messages.error(request, _('You can not add graph nodes because your changeset is full.')) return redirect(request.path) with request.changeset.lock_to_edit(request) as changeset: if changeset.can_edit(request): node = GraphNode(space=space, geometry=clicked_position) node.save() messages.success(request, _('New graph node created.')) active_node = None set_active_node = True else: messages.error(request, _('You can not edit changes on this changeset.')) if set_active_node: connections = {} if active_node: for self_node, other_node in (('from_node', 'to_node'), ('to_node', 'from_node')): conn_qs = GraphEdge.objects.filter(Q(**{self_node+'__pk': active_node.pk})) conn_qs = conn_qs.select_related(other_node+'__space', other_node+'__space__level', 'waytype', 'access_restriction') for edge in conn_qs: edge.other_node = getattr(edge, other_node) if (edge.other_node.space.access_restriction_id not in permissions or edge.other_node.space.level.access_restriction_id not in permissions): continue connections.setdefault(edge.other_node.space_id, []).append(edge) connections = sorted( connections.values(), key=lambda c: (c[0].other_node.space.level == level, c[0].other_node.space == space, c[0].other_node.space.level.base_altitude) ) ctx.update({ 'set_active_node': set_active_node, 'active_node': active_node, 'active_node_connections': connections, }) else: edge_settings_form = GraphEdgeSettingsForm(request=request) graph_action_form = GraphEditorActionForm(request=request, allow_clicked_position=create_nodes) ctx.update({ 'edge_settings_form': edge_settings_form, 'graph_action_form': graph_action_form, 'create_nodes': create_nodes, }) return render(request, 'editor/graph.html', ctx)
def graph_edit(request, level=None, space=None): Level = request.changeset.wrap_model('Level') Space = request.changeset.wrap_model('Space') GraphNode = request.changeset.wrap_model('GraphNode') GraphEdge = request.changeset.wrap_model('GraphEdge') can_edit = request.changeset.can_edit(request) ctx = { 'path': request.path, 'can_edit': can_edit, 'levels': Level.objects.filter(Level.q_for_request(request), on_top_of__isnull=True), 'level_url': 'editor.levels.graph', } create_nodes = False if level is not None: level = get_object_or_404(Level.objects.filter( Level.q_for_request(request)), pk=level) ctx.update({ 'back_url': reverse('editor.levels.detail', kwargs={'pk': level.pk}), 'back_title': _('back to level'), 'level': level, 'geometry_url': '/api/editor/geometries/?level=' + str(level.primary_level_pk), }) elif space is not None: queryset = Space.objects.filter(Space.q_for_request( request)).select_related('level').defer('geometry') space = get_object_or_404(queryset, pk=space) level = space.level ctx.update({ 'space': space, 'level': space.level, 'back_url': reverse('editor.spaces.detail', kwargs={ 'level': level.pk, 'pk': space.pk }), 'back_title': _('back to space'), 'parent_url': reverse('editor.levels.graph', kwargs={'level': level.pk}), 'parent_title': _('to level graph'), 'geometry_url': '/api/editor/geometries/?space=' + str(space.pk), }) create_nodes = True if request.method == 'POST': changeset_exceeded = get_changeset_exceeded(request) graphnode_changes = {} if changeset_exceeded: graphnode_changes = request.changeset.get_changed_objects_by_model( 'GraphNode') if request.POST.get('delete') == '1': # Delete this graphnode! node = get_object_or_404(GraphNode, pk=request.POST.get('pk')) if changeset_exceeded and node.pk not in graphnode_changes: messages.error( request, _('You can not delete this graph node because your changeset is full.' )) return redirect(request.path) if request.POST.get('delete_confirm') == '1': with request.changeset.lock_to_edit(request) as changeset: if changeset.can_edit(request): node.edges_from_here.all().delete() node.edges_to_here.all().delete() node.delete() else: messages.error( request, _('You can not edit changes on this changeset.')) return redirect(request.path) messages.success(request, _('Graph Node was successfully deleted.')) return redirect(request.path) return render( request, 'editor/delete.html', { 'model_title': GraphNode._meta.verbose_name, 'pk': node.pk, 'obj_title': node.title }) permissions = AccessPermission.get_for_request(request) | set([None]) edge_settings_form = GraphEdgeSettingsForm(instance=GraphEdge(), request=request, data=request.POST) graph_action_form = GraphEditorActionForm( request=request, allow_clicked_position=create_nodes, data=request.POST) if edge_settings_form.is_valid() and graph_action_form.is_valid(): goto_space = graph_action_form.cleaned_data['goto_space'] if goto_space is not None: return redirect( reverse('editor.spaces.graph', kwargs={'space': goto_space.pk})) set_active_node = False active_node = graph_action_form.cleaned_data['active_node'] clicked_node = graph_action_form.cleaned_data['clicked_node'] clicked_position = graph_action_form.cleaned_data.get( 'clicked_position') if clicked_node is not None and clicked_position is None: if active_node is None: active_node = clicked_node set_active_node = True elif active_node == clicked_node: active_node = None set_active_node = True else: with request.changeset.lock_to_edit(request) as changeset: if changeset.can_edit(request): connect_nodes(request, active_node, clicked_node, edge_settings_form) active_node = clicked_node if edge_settings_form.cleaned_data[ 'activate_next'] else None set_active_node = True else: messages.error( request, _('You can not edit changes on this changeset.' )) elif (clicked_node is None and clicked_position is not None and active_node is None and space.geometry.contains(clicked_position)): if changeset_exceeded: messages.error( request, _('You can not add graph nodes because your changeset is full.' )) return redirect(request.path) with request.changeset.lock_to_edit(request) as changeset: if changeset.can_edit(request): node = GraphNode(space=space, geometry=clicked_position) node.save() messages.success(request, _('New graph node created.')) active_node = None set_active_node = True else: messages.error( request, _('You can not edit changes on this changeset.')) if set_active_node: connections = {} if active_node: for self_node, other_node in (('from_node', 'to_node'), ('to_node', 'from_node')): conn_qs = GraphEdge.objects.filter( Q(**{self_node + '__pk': active_node.pk})) conn_qs = conn_qs.select_related( other_node + '__space', other_node + '__space__level', 'waytype', 'access_restriction') for edge in conn_qs: edge.other_node = getattr(edge, other_node) if (edge.other_node.space.access_restriction_id not in permissions or edge.other_node.space.level. access_restriction_id not in permissions): continue connections.setdefault(edge.other_node.space_id, []).append(edge) connections = sorted( connections.values(), key=lambda c: (c[0].other_node.space.level == level, c[ 0].other_node.space == space, c[0].other_node.space .level.base_altitude)) ctx.update({ 'set_active_node': set_active_node, 'active_node': active_node, 'active_node_connections': connections, }) else: edge_settings_form = GraphEdgeSettingsForm(request=request) graph_action_form = GraphEditorActionForm( request=request, allow_clicked_position=create_nodes) ctx.update({ 'edge_settings_form': edge_settings_form, 'graph_action_form': graph_action_form, 'create_nodes': create_nodes, }) return render(request, 'editor/graph.html', ctx)
def locate(self, request, *args, **kwargs): if isinstance(request.data, list): stations_data = request.data data = {} else: data = request.data if 'stations' not in data: return Response({ 'errors': (_('stations is missing.'), ), }, status=400) stations_data = data['stations'] try: location = Locator.load().locate( stations_data, permissions=AccessPermission.get_for_request(request)) if location is not None: increment_cache_key('apistats__locate__%s' % location.pk) except ValidationError: return Response({ 'errors': (_('Invalid scan data.'), ), }, status=400) if 'set_position' in data and location: set_position = data['set_position'] if not set_position.startswith('p:'): return Response({ 'errors': (_('Invalid set_position.'), ), }, status=400) try: position = Position.objects.get(secret=set_position[2:]) except Position.DoesNotExist: return Response({ 'errors': (_('Invalid set_position.'), ), }, status=400) form_data = { **data, 'coordinates_id': None if location is None else location.pk, } form = PositionAPIUpdateForm(instance=position, data=form_data, request=request) if not form.is_valid(): return Response({ 'errors': form.errors, }, status=400) form.save() return Response({ 'location': None if location is None else location.serialize( simple_geometry=True) })