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