Пример #1
0
    def render_opensearchdescription(self, request, context, template_name):
        description = OPENSEARCH.OpenSearchDescription()

        meta = OpenSearchView.opensearch_meta.copy()
        meta.update(self.search_view.opensearch_meta)
        for key, value in meta.iteritems():
            if value is not None:
                description.append(OPENSEARCH(key, value))

        for image in self.search_view.opensearch_images:
            description.append(OPENSEARCH.Image(image['url'],
                                                height=unicode(image.get('height', 16)),
                                                width=unicode(image.get('width', 16)),
                                                type=unicode(image.get('type' ,'image/x-icon'))))

        for renderer in Conneg(obj=self.search_view).renderers:
            template = request.build_absolute_uri('?') + '?q={searchTerms}&page={startPage?}&format='+renderer.format
            for mimetype in renderer.mimetypes:
                url = OPENSEARCH.Url(type=mimetype.value,
                                     template=template,
                                     rel='results')
                description.append(url)

        return HttpResponse(etree.tostring(description, pretty_print=True, xml_declaration=True),
                            mimetype='application/xml')
Пример #2
0
    def testAll(self):
        for rdf_processor in self._ALL:
            endpoint = mock.Mock(spec=humfrey.sparql.endpoint.Endpoint)
            graph = rdflib.ConjunctiveGraph()
            doc_uri = rdflib.URIRef('http://example.org/doc/Foo')
            subject_uri = rdflib.URIRef('http://example.org/id/Foo')
            subject = resource.Resource(subject_uri, graph, endpoint)

            #import pdb;pdb.set_trace()
            doc_view = views.DocView()
            renderers = Conneg(obj=doc_view).renderers

            request = self.factory.get('')

            doc_view.context = {
                'graph': graph,
                'doc_uri': doc_uri,
                'subject_uri': subject_uri,
                'subject': subject,
                'endpoint': endpoint
            }
            doc_view.context['renderers'] = [
                doc_view.renderer_for_context(request, renderer)
                for renderer in renderers
            ]

            rdf_processor(request=request, context=doc_view.context)

            self.assertFalse(
                endpoint.query.called,
                "The RDF processor should not be touching the endpoint (at the moment)"
            )
            self.check_valid_terms(graph)
            self.assertIsInstance(doc_view.context, (type(None), dict))
Пример #3
0
 def dispatch(self, request, *args, **kwargs):
     # This is handy for the view to work out what renderers will
     # be attempted, and to manipulate the list if necessary.
     # Also handy for middleware to check whether the view was a
     # BaseContentNegotiatedView, and which renderers were preferred.
     if self.context is None:
         self.context = {}
     self.request = request
     self.args = args
     self.kwargs = kwargs
     self.conneg = Conneg(obj=self)
     self.set_renderers(request)
     return super(BaseContentNegotiatedView, self).dispatch(request, *args, **kwargs)
Пример #4
0
    def dispatch(self, request, *args, **kwargs):
        # This is handy for the view to work out what renderers will
        # be attempted, and to manipulate the list if necessary.
        # Also handy for middleware to check whether the view was a
        # BaseContentNegotiatedView, and which renderers were preferred.
        if self.context is None:
            self.context = {'additional_headers': {}}

        format_url_parameter = kwargs.pop(self._format_url_parameter, None)
        if format_url_parameter:
            self.format_override = [format_url_parameter]
        elif request.REQUEST.get(self._format_override_parameter):
            self.format_override = request.REQUEST[self._format_override_parameter].split(',')
        else:
            self.format_override = None

        self.request = request
        self.args = args
        self.kwargs = kwargs
        self.conneg = Conneg(obj=self)
        self.set_renderers(request)
        return super(BaseContentNegotiatedView, self).dispatch(request, *args, **kwargs)
Пример #5
0
class BaseContentNegotiatedView(View):
    conneg = None
    context = None
    _default_format = None
    _force_fallback_format = None
    _format_override_parameter = 'format'
    _format_override_extension = False
    
    template_name = None

    @classonlymethod
    def as_view(cls, **initkwargs):
        view = super(BaseContentNegotiatedView, cls).as_view(**initkwargs)
        view.conneg = Conneg(obj=cls)
        return view

    def dispatch(self, request, *args, **kwargs):
        # This is handy for the view to work out what renderers will
        # be attempted, and to manipulate the list if necessary.
        # Also handy for middleware to check whether the view was a
        # BaseContentNegotiatedView, and which renderers were preferred.
        if self.context is None:
            self.context = {}
        self.request = request
        self.args = args
        self.kwargs = kwargs
        self.conneg = Conneg(obj=self)
        self.set_renderers(request)
        return super(BaseContentNegotiatedView, self).dispatch(request, *args, **kwargs)

    def set_renderers(self, request=None, context=None, template_name=None):
        """
        Makes sure that the renderers attribute on the request is up
        to date. renderers_for_view keeps track of the view that
        is attempting to render the request, so that if the request
        has been delegated to another view we know to recalculate
        the applicable renderers. When called multiple times on the
        same view this will be very low-cost for subsequent calls.
        """
        request, context, template_name = self.get_render_params(request, context, template_name)

        args = (self.conneg, context, template_name,
                self._default_format, self._force_fallback_format, self._format_override_parameter)
        if getattr(request, 'renderers_for_args', None) != args:
            fallback_formats = self._force_fallback_format or ()
            if not isinstance(fallback_formats, (list, tuple)):
                fallback_formats = (fallback_formats,)
            if request.REQUEST.get(self._format_override_parameter):
                format_override = request.REQUEST[self._format_override_parameter].split(',')
            elif self._format_override_extension and \
                    request.path.rfind("/") < request.path.rfind("."):
                _, format_override = request.path.rsplit(".", 1)
                format_override = (str(format_override),)
            else:
                format_override = None
            request.renderers = self.conneg.get_renderers(request=request,
                                                          context=context,
                                                          template_name=template_name,
                                                          accept_header=request.META.get('HTTP_ACCEPT'),
                                                          formats=format_override,
                                                          default_format=self._default_format,
                                                          fallback_formats=fallback_formats)
            request.renderers_for_view = args
        self.context['renderers'] = [self.renderer_for_context(request, r) for r in self.conneg.renderers]
        return request.renderers

    def get_render_params(self, request, context, template_name):
        if not template_name:
            template_name = self.template_name
            if isinstance(template_name, basestring) and template_name.endswith('.html'):
                template_name = template_name[:-5]
        return request or self.request, context or self.context, template_name

    def render(self, request=None, context=None, template_name=None):
        """
        Returns a HttpResponse of the right media type as specified by the
        request.
        
        context can contain status_code and additional_headers members, to set
        the HTTP status code and headers of the request, respectively.
        template_name should lack a file-type suffix (e.g. '.html', as
        renderers will append this as necessary.
        """
        request, context, template_name = self.get_render_params(request, context, template_name)

        self.set_renderers()

        status_code = context.pop('status_code', httplib.OK)
        additional_headers = context.pop('additional_headers', {})

        for renderer in request.renderers:
            response = renderer(request, context, template_name)
            if response is NotImplemented:
                continue
            response.status_code = status_code
            response.renderer = renderer
            break
        else:
            tried_mimetypes = list(itertools.chain(*[r.mimetypes for r in request.renderers]))
            response = self.http_not_acceptable(request, tried_mimetypes)
            response.renderer = None
        for key, value in additional_headers.iteritems():
            response[key] = value

        # We're doing content-negotiation, so tell the user-agent that the
        # response will vary depending on the accept header.
        patch_vary_headers(response, ('Accept',))
        return response

    def http_not_acceptable(self, request, tried_mimetypes, *args, **kwargs):
        response = http.HttpResponse("""\
Your Accept header didn't contain any supported media ranges.

Supported ranges are:

 * %s\n""" % '\n * '.join(sorted('%s (%s; %s)' % (f.name, ", ".join(m.value for m in f.mimetypes), f.format) for f in request.renderers if not any(m in tried_mimetypes for m in f.mimetypes))), mimetype="text/plain")
        response.status_code = httplib.NOT_ACCEPTABLE
        return response

    def head(self, request, *args, **kwargs):
        handle_get = getattr(self, 'get', None)
        if handle_get:
            response = handle_get(request, *args, **kwargs)
            response.content = ''
            return response
        else:
            return self.http_method_not_allowed(request, *args, **kwargs)

    def options(self, request, *args, **kwargs):
        response = http.HttpResponse()
        response['Accept'] = ','.join(m.upper() for m in sorted(self.http_method_names) if hasattr(self, m))
        return response

    @classmethod
    def parse_accept_header(cls, accept):
        warnings.warn("The parse_accept_header method has moved to django_conneg.http.MediaType")
        return MediaType.parse_accept_header(accept)

    def render_to_format(self, request=None, context=None, template_name=None, format=None):
        request, context, template_name = self.get_render_params(request, context, template_name)
        self.set_renderers()

        status_code = context.pop('status_code', httplib.OK)
        additional_headers = context.pop('additional_headers', {})

        for renderer in self.conneg.renderers_by_format.get(format, ()):
            response = renderer(request, context, template_name)
            if response is not NotImplemented:
                break
        else:
            response = self.http_not_acceptable(request, ())
            renderer = None

        response.status_code = status_code
        response.renderer = renderer
        for key, value in additional_headers.iteritems():
            response[key] = value
        return response

    def join_template_name(self, template_name, extension):
        """
        Appends an extension to a template_name or list of template_names.
        """
        if template_name is None:
            return None
        if isinstance(template_name, (list, tuple)):
            return tuple('.'.join([n, extension]) for n in template_name)
        if isinstance(template_name, basestring):
            return '.'.join([template_name, extension])
        raise AssertionError('template_name not of correct type: %r' % type(template_name))

    def renderer_for_context(self, request, renderer):
        return {'name': renderer.name,
                'priority': renderer.priority,
                'mimetypes': [m.value for m in renderer.mimetypes],
                'format': renderer.format,
                'url': self.url_for_format(request, renderer.format)}

    def url_for_format(self, request, format):
        qs = urlparse.parse_qs(request.META.get('QUERY_STRING', ''))
        qs['format'] = [format]
        return '?{0}'.format(urllib.urlencode(qs, True))