Пример #1
0
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")
Пример #2
0
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")