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
Ejemplo n.º 3
0
 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__)
Ejemplo n.º 4
0
 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
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    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__)