Esempio n. 1
0
    def fetch(self, request, key=None):
        cross_origin = request.META.get('HTTP_ORIGIN')
        if cross_origin is not None:
            try:
                if request.META['HTTP_HOST'] == urlparse(cross_origin).hostname:
                    cross_origin = None
            except ValueError:
                pass

        increment_cache_key('api_updates_fetch_requests%s' % ('_cross_origin' if cross_origin is not None else ''))

        from c3nav.site.models import SiteUpdate

        result = {
            'last_site_update': SiteUpdate.last_update(),
            'last_map_update': MapUpdate.current_processed_cache_key(),
        }
        if cross_origin is None:
            result.update({
                'user': get_user_data(request),
            })

        response = Response(result)
        if cross_origin is not None:
            response['Access-Control-Allow-Origin'] = cross_origin
            response['Access-Control-Allow-Credentials'] = 'true'
        set_tile_access_cookie(request, response)

        return response
Esempio n. 2
0
    def fetch(self, request, key=None):
        cross_origin = request.META.get('HTTP_ORIGIN')
        if cross_origin is not None:
            try:
                if request.META['HTTP_HOST'] == urlparse(
                        cross_origin).hostname:
                    cross_origin = None
            except ValueError:
                pass

        counter_key = 'api_updates_fetch_requests%s' % (
            '_cross_origin' if cross_origin is not None else '')
        try:
            cache.incr(counter_key)
        except ValueError:
            cache.set(counter_key, 0, None)

        from c3nav.site.models import SiteUpdate

        result = {
            'last_site_update': SiteUpdate.last_update(),
            'last_map_update': MapUpdate.current_processed_cache_key(),
        }
        if cross_origin is None:
            result.update({
                'user': get_user_data(request),
            })

        response = Response(result)
        if cross_origin is not None:
            response['Access-Control-Allow-Origin'] = cross_origin
            response['Access-Control-Allow-Credentials'] = 'true'
        set_tile_access_cookie(request, response)

        return response
Esempio n. 3
0
    def shortest_path(self, restrictions, options):
        options_key = json.dumps(options.data, separators=(',', '='), sort_keys=True)[1:-1]
        cache_key = 'router:shortest_path:%s:%s:%s' % (MapUpdate.current_processed_cache_key(),
                                                       restrictions.cache_key,
                                                       options_key)
        result = cache.get(cache_key)
        if result:
            distances, predecessors = result
            return (np.frombuffer(distances, dtype=np.float64).reshape(self.graph.shape),
                    np.frombuffer(predecessors, dtype=np.int32).reshape(self.graph.shape))

        graph = self.graph.copy()

        # speeds of waytypes, if relevant
        if options['mode'] == 'fastest':
            self.waytypes[0].speed = 1
            self.waytypes[0].speed_up = 1
            self.waytypes[0].extra_seconds = 0
            self.waytypes[0].walk = True

            for waytype in self.waytypes:
                speed = float(waytype.speed)
                speed_up = float(waytype.speed_up)
                if waytype.walk:
                    speed *= options.walk_factor
                    speed_up *= options.walk_factor

                for indices, dir_speed in ((waytype.nonupwards_indices, speed), (waytype.upwards_indices, speed_up)):
                    indices = indices.transpose().tolist()
                    values = graph[indices]
                    values /= dir_speed
                    if waytype.extra_seconds:
                        values += int(waytype.extra_seconds)
                    graph[indices] = values

        # avoid waytypes as specified in settings
        for waytype in self.waytypes[1:]:
            value = options.get('waytype_%s' % waytype.pk, 'allow')
            if value in ('avoid', 'avoid_up'):
                graph[waytype.upwards_indices.transpose().tolist()] *= 100000
            if value in ('avoid', 'avoid_down'):
                graph[waytype.nonupwards_indices.transpose().tolist()] *= 100000

        # exclude spaces and edges
        space_nodes = tuple(reduce(operator.or_, (self.spaces[space].nodes for space in restrictions.spaces), set()))
        graph[space_nodes, :] = np.inf
        graph[:, space_nodes] = np.inf
        if restrictions.additional_nodes:
            graph[tuple(restrictions.additional_nodes), :] = np.inf
            graph[:, tuple(restrictions.additional_nodes)] = np.inf
        graph[restrictions.edges.transpose().tolist()] = np.inf

        distances, predecessors = shortest_path(graph, directed=True, return_predecessors=True)
        print(distances.dtype, predecessors.dtype)
        cache.set(cache_key, (distances.astype(np.float64).tobytes(),
                              predecessors.astype(np.int32).tobytes()), 600)
        return distances, predecessors
Esempio n. 4
0
    def shortest_path(self, restrictions, options):
        options_key = options.serialize_string()
        cache_key = 'router:shortest_path:%s:%s:%s' % (MapUpdate.current_processed_cache_key(),
                                                       restrictions.cache_key,
                                                       options_key)
        result = cache.get(cache_key)
        if result:
            distances, predecessors = result
            return (np.frombuffer(distances, dtype=np.float64).reshape(self.graph.shape),
                    np.frombuffer(predecessors, dtype=np.int32).reshape(self.graph.shape))

        graph = self.graph.copy()

        # speeds of waytypes, if relevant
        if options['mode'] == 'fastest':
            self.waytypes[0].speed = 1
            self.waytypes[0].speed_up = 1
            self.waytypes[0].extra_seconds = 0
            self.waytypes[0].walk = True

            for waytype in self.waytypes:
                speed = float(waytype.speed)
                speed_up = float(waytype.speed_up)
                if waytype.walk:
                    speed *= options.walk_factor
                    speed_up *= options.walk_factor

                for indices, dir_speed in ((waytype.nonupwards_indices, speed), (waytype.upwards_indices, speed_up)):
                    indices = indices.transpose().tolist()
                    values = graph[indices]
                    values /= dir_speed
                    if waytype.extra_seconds:
                        values += int(waytype.extra_seconds)
                    graph[indices] = values

        # avoid waytypes as specified in settings
        for waytype in self.waytypes[1:]:
            value = options.get('waytype_%s' % waytype.pk, 'allow')
            if value in ('avoid', 'avoid_up'):
                graph[waytype.upwards_indices.transpose().tolist()] *= 100000
            if value in ('avoid', 'avoid_down'):
                graph[waytype.nonupwards_indices.transpose().tolist()] *= 100000

        # exclude spaces and edges
        space_nodes = tuple(reduce(operator.or_, (self.spaces[space].nodes for space in restrictions.spaces), set()))
        graph[space_nodes, :] = np.inf
        graph[:, space_nodes] = np.inf
        if restrictions.additional_nodes:
            graph[tuple(restrictions.additional_nodes), :] = np.inf
            graph[:, tuple(restrictions.additional_nodes)] = np.inf
        graph[restrictions.edges.transpose().tolist()] = np.inf

        distances, predecessors = shortest_path(graph, directed=True, return_predecessors=True)
        cache.set(cache_key, (distances.astype(np.float64).tobytes(),
                              predecessors.astype(np.int32).tobytes()), 600)
        return distances, predecessors
Esempio n. 5
0
    def open_cached(cls):
        with cls.cache_lock:
            from c3nav.mapdata.models import MapUpdate
            cache_key = MapUpdate.current_processed_cache_key()
            if cls.cache_key != cache_key:
                cls.cache_key = cache_key
                cls.cached = None

            if cls.cached is None:
                cls.cached = cls.open()

            return cls.cached
Esempio n. 6
0
    def open_level_cached(cls, level_id, mode):
        with cls.cache_lock:
            from c3nav.mapdata.models import MapUpdate
            cache_key = MapUpdate.current_processed_cache_key()
            if cls.cache_key != cache_key:
                cls.cache_key = cache_key
                cls.cached = {}
            else:
                result = cls.cached.get((level_id, mode), None)
                if result is not None:
                    return result

            result = cls.open_level(level_id, mode)
            cls.cached[(level_id, mode)] = result
            return result
Esempio n. 7
0
    def get(cls, level):
        # get the current render data from local variable if no new processed mapupdate exists.
        # this is much faster than any other possible cache
        with cls.cache_lock:
            cache_key = MapUpdate.current_processed_cache_key()
            level_pk = str(level.pk if isinstance(level, Level) else level)
            if cls.cache_key != cache_key:
                cls.cache_key = cache_key
                cls.cached = {}
            else:
                result = cls.cached.get(level_pk, None)
                if result is not None:
                    return result

            pk = level.pk if isinstance(level, Level) else level
            result = pickle.load(open(cls._level_filename(pk), 'rb'))

            cls.cached[level_pk] = result
            return result
Esempio n. 8
0
    def get(cls, level):
        # get the current render data from local variable if no new processed mapupdate exists.
        # this is much faster than any other possible cache
        with cls.cache_lock:
            cache_key = MapUpdate.current_processed_cache_key()
            level_pk = str(level.pk if isinstance(level, Level) else level)
            if cls.cache_key != cache_key:
                cls.cache_key = cache_key
                cls.cached = {}
            else:
                result = cls.cached.get(level_pk, None)
                if result is not None:
                    return result

            pk = level.pk if isinstance(level, Level) else level
            result = pickle.load(open(cls._level_filename(pk), 'rb'))

            cls.cached[level_pk] = result
            return result
Esempio n. 9
0
            os.makedirs(tile_dirname, exist_ok=True)
            with open(tile_filename, 'wb') as f:
                f.write(data)
            with open(last_update_filename, 'w') as f:
                f.write(base_cache_key)
            cache.set(tile_cache_update_cache_key, base_cache_key, 60)

    response = HttpResponse(data, 'image/png')
    response['ETag'] = tile_etag
    response['Cache-Control'] = 'no-cache'
    response['Vary'] = 'Cookie'

    return response


@etag(lambda *args, **kwargs: MapUpdate.current_processed_cache_key())
@no_language()
def map_history(request, level, mode, filetype):
    if not request.user.is_superuser:
        raise PermissionDenied
    level = get_object_or_404(Level, pk=level)

    if mode == 'composite' and level.on_top_of_id is not None:
        raise Http404

    history = MapHistory.open_level(level.pk, mode)
    if filetype == 'png':
        response = HttpResponse(content_type='image/png')
        history.to_image().save(response, format='PNG')
    elif filetype == 'data':
        response = HttpResponse(content_type='application/octet-stream')
Esempio n. 10
0
            os.makedirs(tile_dirname, exist_ok=True)
            with open(tile_filename, 'wb') as f:
                f.write(data)
            with open(last_update_filename, 'w') as f:
                f.write(base_cache_key)
            cache.set(tile_cache_update_cache_key, base_cache_key, 60)

    response = HttpResponse(data, 'image/png')
    response['ETag'] = tile_etag
    response['Cache-Control'] = 'no-cache'
    response['Vary'] = 'Cookie'

    return response


@etag(lambda *args, **kwargs: MapUpdate.current_processed_cache_key())
@no_language()
def map_history(request, level, mode, filetype):
    if not request.user.is_superuser:
        raise PermissionDenied
    level = get_object_or_404(Level, pk=level)

    if mode == 'composite' and level.on_top_of_id is not None:
        raise Http404

    history = MapHistory.open_level(level.pk, mode)
    if filetype == 'png':
        response = HttpResponse(content_type='image/png')
        history.to_image().save(response, format='PNG')
    elif filetype == 'data':
        response = HttpResponse(content_type='application/octet-stream')