def _validate(self): if self.model is None: raise OEmbedException('Provider %s requires a model' % self.provider_class.__name__) if not self.named_view: raise OEmbedException('Provider %s requires a named_view' % self.provider_class.__name__)
def get_object(self, url): """ Fields to match is a mapping of url params to fields, so for the photos example above, it would be: fields_to_match = { 'object_id': 'id' } This procedure parses out named params from a URL and then uses the fields_to_match dictionary to generate a query. """ params = self.get_params(url) query = {} for key, value in self._meta.fields_to_match.iteritems(): try: query[value] = params[key] except KeyError: raise OEmbedException( '%s was not found in the urlpattern parameters. Valid names are: %s' % (key, ', '.join(params.keys()))) try: obj = self.get_queryset().get(**query) except self._meta.model.DoesNotExist: raise OEmbedException('Requested object not found') return obj
def _validate(self): if self.model is None and self.queryset is None: raise OEmbedException('Provider %s requires a model or queryset' % self.provider_class.__name__) if self.model: self.queryset = self.model._default_manager.all() elif self.queryset: self.model = self.queryset.model if not self.named_view: raise OEmbedException('Provider %s requires a named_view' % self.provider_class.__name__)
def convert_to_resource(self, headers, raw_response, params): if 'content-type' not in headers: raise OEmbedException('Missing mime-type in response') if headers['content-type'] in ('text/javascript', 'application/json'): try: json_response = simplejson.loads(raw_response) resource = OEmbedResource.create(json_response) except ValueError: raise OEmbedException('Unable to parse response json') else: raise OEmbedException('Invalid mime-type - %s' % headers['content-type']) return resource
def get_object(self, url, month_format='%b', day_format='%d'): """ Parses the date from a url and uses it in the query. For objects which are unique for date. """ params = self.get_params(url) try: year = params[self._meta.year_part] month = params[self._meta.month_part] day = params[self._meta.day_part] except KeyError: try: # named lookups failed, so try to get the date using the first # three parameters year, month, day = params['_0'], params['_1'], params['_2'] except KeyError: raise OEmbedException( 'Error extracting date from url parameters') try: tt = time.strptime('%s-%s-%s' % (year, month, day), '%s-%s-%s' % ('%Y', month_format, day_format)) date = datetime.date(*tt[:3]) except ValueError: raise OEmbedException('Error parsing date from: %s' % url) # apply the date-specific lookups if isinstance(self._meta.model._meta.get_field(self._meta.date_field), DateTimeField): min_date = datetime.datetime.combine(date, datetime.time.min) max_date = datetime.datetime.combine(date, datetime.time.max) query = {'%s__range' % self._meta.date_field: (min_date, max_date)} else: query = {self._meta.date_field: date} # apply the regular search lookups for key, value in self._meta.fields_to_match.iteritems(): try: query[value] = params[key] except KeyError: raise OEmbedException( '%s was not found in the urlpattern parameters. Valid names are: %s' % (key, ', '.join(params.keys()))) try: obj = self.get_queryset().get(**query) except self._meta.model.DoesNotExist: raise OEmbedException('Requested object not found') return obj
def get_params(self, url): """ Extract the named parameters from a url regex. If the url regex does not contain named parameters, they will be keyed _0, _1, ... * Named parameters Regex: /photos/^(?P<year>\d{4})/(?P<month>\w{3})/(?P<day>\d{1,2})/(?P<object_id>\d+)/ URL: http://www2.ljworld.com/photos/2009/oct/11/12345/ Return Value: {u'day': '11', u'month': 'oct', u'object_id': '12345', u'year': '2009'} * Unnamed parameters Regex: /blah/([\w-]+)/(\d+)/ URL: http://www.example.com/blah/hello/123/ Return Value: {u'_0': 'hello', u'_1': '123'} """ match = re.match(self.regex, url) if match is not None: params = match.groupdict() if not params: params = {} for i, group in enumerate(match.groups()[1:]): params['_%s' % i] = group return params raise OEmbedException('No regex matched the url %s' % (url))
def _build_regex(self): """ Performs a reverse lookup on a named view and generates a list of regexes that match that object. It generates regexes with the domain name included, using sites provided by the get_sites() method. >>> regex = provider.regex >>> regex.pattern 'http://(www2.kusports.com|www2.ljworld.com|www.lawrence.com)/photos/(?P<year>\\d{4})/(?P<month>\\w{3})/(?P<day>\\d{1,2})/(?P<object_id>\\d+)/$' """ # get the regexes from the urlconf url_patterns = resolver.reverse_dict.get(self._meta.named_view) try: regex = url_patterns[1] except TypeError: raise OEmbedException('Error looking up %s' % self._meta.named_view) # get a list of normalized domains cleaned_sites = self.get_cleaned_sites() site_regexes = [] for site in self.get_sites(): site_regexes.append(cleaned_sites[site.pk][0]) # join the sites together with the regex 'or' sites = '|'.join(site_regexes) # create URL-matching regexes for sites regex = re.compile('(%s)/%s' % (sites, regex)) return regex
def store_providers(self, provider_data): """ Iterate over the returned json and try to sort out any new providers """ if not hasattr(provider_data, '__iter__'): raise OEmbedException('Autodiscovered response not iterable') provider_pks = [] for provider in provider_data: if 'endpoint' not in provider or \ 'matches' not in provider: continue resource_type = provider.get('type') if resource_type not in RESOURCE_TYPES: continue stored_provider, created = StoredProvider.objects.get_or_create( wildcard_regex=provider['matches']) if created: stored_provider.endpoint_url = relative_to_full( provider['endpoint'], provider['matches']) stored_provider.resource_type = resource_type stored_provider.save() provider_pks.append(stored_provider.pk) return StoredProvider.objects.filter(pk__in=provider_pks)
def create(cls, data): if not 'type' in data or not 'version' in data: raise OEmbedException('Missing required fields on OEmbed response.') data['width'] = data.get('width') and int(data['width']) or None data['height'] = data.get('height') and int(data['height']) or None filtered_data = dict([(k, v) for k, v in data.items() if v]) resource = cls() resource.load_data(filtered_data) return resource
def _path_regex(self): named_view = self._meta.named_view.split(':') view = named_view[-1] regex = [] resolver = get_resolver(None) for namespace in named_view[:-1]: pattern, namespace = resolver.namespace_dict.get(namespace) regex.append(pattern) resolver = namespace try: pattern = resolver.reverse_dict.get(view)[1] except TypeError: raise OEmbedException('Error looking up %s' % self._meta.named_view) regex.append(pattern) regex = ''.join(regex) return regex
def _validate(self): super(DjangoDateBasedProvider, self)._validate() if not self._meta.date_field: raise OEmbedException('date_field not found for %s' % self.__class__.__name__)