def oembed(request): """ A view that adheres to `OEmbed Spec <http://oembed.com>`_ of what a provider endpoint should do. Any :class:`monocle.providers.Provider` that is configured to be exposed can be provided via this view. Both ``maxwidth`` and ``maxheight`` are honored, but no other URL parameter is. This implies that all responses are delivered as JSON (i.e. ``format=json``). XML is not supported. If a request specifies ``format=xml`` or some other unknown format other than JSON, a 501 response is returned. If no provider is found, or a provider is not exposed, a 404 is returned. If no resource can be retrieved from the found provider, or it is invalid, a 404 is also returned. Else the resource is returned as JSON. """ url = request.GET.get('url') format = request.GET.get('format', 'json').lower() if not url: return HttpResponseBadRequest('Paramater URL is missing') # TODO: Support xml if format != 'json': return HttpResponseNotImplemented('OEmbed format %s not implemented' % format) # Get optional and trim None params = { 'maxwidth': request.GET.get('maxwidth'), 'maxheight': request.GET.get('maxheight') } # Filter nones and non-numbers for k, v in params.items(): if not v: del params[k] else: # Coerce try: params[k] = int(v) except ValueError: del params[k] provider = registry.match(url) # 404 on resource not found on non-exposed endpoint if not provider or not provider.expose: return HttpResponseNotFound('OEmbed for this URL not available') resource = provider.get_resource(url, **params) if resource.is_valid: callback = request.GET.get('callback') if callback: return HttpResponse('%s(%s);' % (callback, resource.json), mimetype='application/json') return HttpResponse(resource.json, mimetype='application/json') else: return HttpResponseNotFound('OEmbed resource is invalid or unavailable')
def enrich(self, content, maxwidth=None, maxheight=None): """ Returns an enriched version of content that replaces all URLs that have a provider with valid resource data. By default, all providers are considered for possible replacement. However, if the consumer's ``skip_internal`` attribute is True and internal provider responses are not configured to be cached, no matched URL that is an internal provider will be rendered. This is useful if any prefetching is to occur where rendering internal providers may be wasted effort. :param string content: Content to enrich :param integer maxwidth: Maximum width of resource :param integer maxheight: Maximum height of resource :returns: A version of specific content with matched URLs replaced with rendered resources """ for url in self.url_regex.findall(content): provider = registry.match(url) if not provider: logger.debug('No provider match for %s' % url) continue # Bypass internal providers if they aren't cached if (self.skip_internal and isinstance(provider, InternalProvider) and not settings.CACHE_INTERNAL_PROVIDERS): logger.debug('Skipping uncached internal provider') continue # This is generally a safeguard against bad provider implementations try: resource = provider.get_resource(url, maxwidth=maxwidth, maxheight=maxheight) except: logger.exception('Failed to get resource from provider %s' % provider) else: if not resource.is_valid: logger.warning('Provider %s returned a bad resource' % provider) logger.debug('Embedding %s for url %s' % (resource, url)) content = content.replace(url, resource.render()) return content