class SitegeistView(View): namespace = None def __init__(self, *args, **kwargs): super(SitegeistView, self).__init__(*args, **kwargs) self._geocache = CoordinateCache("view-%s" % self.namespace) def load_data(self, request, coords, **args): """ Load the data dict needed by this view. Subclasses should implement this method. """ raise NotImplementedError("subclass and implement load_data()") def get_template(self): return "sitegeist/panes/%s.html" % self.namespace def _base_response(self, coords): return {"geo": {"ll": [coords.lat, coords.lon], "boundaries": coords}, "data": {}} def _get_bounds(self, request, param="cll"): """ Get coordinates from the HTTP request. The only supported method is via lat and lon querystring params. """ cll = request.GET.get(param) # set default of Sunlight offices lat = DEFAULT_CLL[0] lon = DEFAULT_CLL[1] if cll and LLFORMAT.match(cll): (lat, lon) = cll.split(",") coords = (lat, lon) bounds = boundary_cache.get(coords) if not bounds: bounds = Geo() bounds.lat = lat bounds.lon = lon pt = "POINT(%s %s)" % (lon, lat) for boundary in Boundary.objects.filter(shape__contains=pt): bounds[boundary.set_name].append(boundary.as_dict()) if bounds: boundary_cache.set(coords, bounds) return bounds def _get_response_type(self, request): """ Get the type of response needed by the client. The only supported method for JSON (at this time) is via the HTTP_X_REQUESTED_WITH header with a value of XMLHttpRequest. I lied, you can also pass format=json as a query string param. """ return "json" if request.is_ajax() or request.GET.get("format") == "json" else "html" def get(self, request, **args): """ Process GET request. Defers to the subclass's load_data() method if cached data is not found. """ # get values from response response_type = self._get_response_type(request) bounds = self._get_bounds(request) if bounds: coords = (float(bounds.lat), float(bounds.lon)) logger.debug("attempting cache read width (%s, %s)" % coords) data = self._geocache.get(coords) if not data: # if data is not cached, load it and cache it logger.debug("cache miss, calling load_data()") data = self.load_data(request, bounds, **args) self._geocache.set(coords, data) else: logger.debug("cache hit!!!!") else: coords = None data = {"data": {}} # response rendering if response_type == "html": context = { "coords": coords, "data": data["data"], "vertical_offset": request.GET.get("vo"), "namespace": self.namespace, "show_header": request.GET.get("header") != "0", } return render(request, self.get_template(), context) return HttpResponse(json.dumps(data), content_type="application/json")
class SitegeistView(View): namespace = None def __init__(self, *args, **kwargs): super(SitegeistView, self).__init__(*args, **kwargs) self._geocache = CoordinateCache("view-%s" % self.namespace) def load_data(self, request, coords, **args): """ Load the data dict needed by this view. Subclasses should implement this method. """ raise NotImplementedError("subclass and implement load_data()") def get_template(self): return "sitegeist/panes/%s.html" % self.namespace def _base_response(self, coords): return { "geo": { "ll": [coords.lat, coords.lon], "boundaries": coords, }, "data": {}, } def _get_bounds(self, request, param='cll'): """ Get coordinates from the HTTP request. The only supported method is via lat and lon querystring params. """ cll = request.GET.get(param) # set default of Sunlight offices lat = DEFAULT_CLL[0] lon = DEFAULT_CLL[1] if cll and LLFORMAT.match(cll): (lat, lon) = cll.split(',') coords = (lat, lon) bounds = boundary_cache.get(coords) if not bounds: bounds = Geo() bounds.lat = lat bounds.lon = lon pt = "POINT(%s %s)" % (lon, lat) for boundary in Boundary.objects.filter(shape__contains=pt): bounds[boundary.set_name].append(boundary.as_dict()) if bounds: boundary_cache.set(coords, bounds) return bounds def _get_response_type(self, request): """ Get the type of response needed by the client. The only supported method for JSON (at this time) is via the HTTP_X_REQUESTED_WITH header with a value of XMLHttpRequest. I lied, you can also pass format=json as a query string param. """ return 'json' if request.is_ajax() or request.GET.get( 'format') == 'json' else 'html' def get(self, request, **args): """ Process GET request. Defers to the subclass's load_data() method if cached data is not found. """ # get values from response response_type = self._get_response_type(request) bounds = self._get_bounds(request) if bounds: coords = (float(bounds.lat), float(bounds.lon)) logger.debug("attempting cache read width (%s, %s)" % coords) data = self._geocache.get(coords) if not data: # if data is not cached, load it and cache it logger.debug("cache miss, calling load_data()") data = self.load_data(request, bounds, **args) self._geocache.set(coords, data) else: logger.debug("cache hit!!!!") else: coords = None data = {'data': {}} # response rendering if response_type == 'html': context = { 'coords': coords, 'data': data['data'], 'vertical_offset': request.GET.get('vo'), 'namespace': self.namespace, 'show_header': request.GET.get('header') != "0", } return render(request, self.get_template(), context) return HttpResponse(json.dumps(data), content_type="application/json")