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
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
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
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
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
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
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
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
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')
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')