Esempio n. 1
0
    def _parse_category_header(self, header_value):
        categories = []
        category_headers = HttpCategoryHeaders()
        category_headers.parse(header_value)
        for term, attributes in category_headers.all():
            param = {}
            for k, v in attributes:
                param[k] = v

            # Category scheme
            try:
                scheme = param['scheme']
            except KeyError:
                raise HttpHeaderError('Category scheme not specified')

            # Category, Kind or Mixin?
            t = param.get('class')
            cls = Category
            if t and t.lower() == 'kind':
                cls = Kind
            elif t and t.lower() == 'mixin':
                cls = Mixin
            elif not t and param.get('location'):
                cls = Mixin

            # Related Kind/Mixin
            try:
                t = param['rel']
                r_scheme, r_term = t.split('#', 1)
                r_scheme += '#'
                related = cls(r_term, r_scheme)
            except KeyError, ValueError:
                related = None

            # Supported attributes (mutable)
            try:
                attributes = []
                SPEC_PLAIN = re.compile(r'^([a-z0-9._-]+)$')
                SPEC_PROPS = re.compile(r'^([a-z0-9._-]+){(.*)}$')
                for attr_spec in param['attributes'].split():
                    attr_kwargs = {}
                    m = SPEC_PLAIN.match(attr_spec)
                    if not m:
                        m = SPEC_PROPS.match(attr_spec)
                        if not m:
                            raise HttpHeaderError('%s: Invalid attribute specification in Category header' % attr_spec)
                        else:
                            for prop in m.groups()[1].split():
                                if prop == 'required':
                                    attr_kwargs['required'] = True
                                if prop == 'immutable':
                                    attr_kwargs['mutable'] = False
                    attributes.append(Attribute(m.groups()[0], **attr_kwargs))
            except KeyError, IndexError:
                attributes = None
Esempio n. 2
0
    def category_headers(self, obj):
        # Category headers
        category_headers = HttpCategoryHeaders()
        for category in obj.categories:
            params = []
            params.append(('scheme', category.scheme))

            cat_class = category.__class__.__name__.lower()
            # FIXME: this is a bug in the spec, fix it?
            if cat_class == 'category': cat_class = 'action'
            params.append(('class', cat_class))

            if category.title:
                params.append(('title', category.title))

            if 'category_discovery' in obj.render_flags:
                if category.related:
                    params.append(('rel', category.related))
                if category.attributes:
                    attr_defs = []
                    for attr in category.unique_attributes.itervalues():
                        attr_props = []
                        if not attr.mutable and not attr.required:
                            attr_props.append('immutable')
                        elif attr.required:
                            attr_props.append('required')
                        attr_def = attr.name
                        if attr_props:
                            attr_def += '{%s}' % ' '.join(attr_props)
                        attr_defs.append(attr_def)
                    params.append(('attributes', ' '.join(attr_defs)))
                if hasattr(category, 'actions') and category.actions:
                    params.append(
                        ('actions',
                         ' '.join([str(cat) for cat in category.actions])))
                if hasattr(category, 'location') and category.location:
                    params.append(('location',
                                   obj.translator.url_build(category.location,
                                                            path_only=True)))

            category_headers.add(category.term, params)
        return category_headers
Esempio n. 3
0
    def category_headers(self, obj):
        # Category headers
        category_headers = HttpCategoryHeaders()
        for category in obj.categories:
            params = []
            params.append(('scheme',  category.scheme))

            cat_class = category.__class__.__name__.lower()
            # FIXME: this is a bug in the spec, fix it?
            if cat_class == 'category': cat_class = 'action'
            params.append(('class',  cat_class))

            if category.title:
                params.append(('title',  category.title))

            if 'category_discovery' in obj.render_flags:
                if category.related:
                    params.append(('rel',  category.related))
                if category.attributes:
                    attr_defs=[]
                    for attr in category.unique_attributes.itervalues():
                        attr_props=[]
                        if not attr.mutable and not attr.required:
                            attr_props.append('immutable')
                        elif attr.required:
                            attr_props.append('required')
                        attr_def = attr.name
                        if attr_props:
                            attr_def += '{%s}' % ' '.join(attr_props)
                        attr_defs.append(attr_def)
                    params.append(('attributes', ' '.join(attr_defs)))
                if hasattr(category, 'actions') and category.actions:
                    params.append(('actions', ' '.join([str(cat) for cat in category.actions])))
                if hasattr(category, 'location') and category.location:
                    params.append(('location',
                        obj.translator.url_build(category.location, path_only=True)))

            category_headers.add(category.term, params)
        return category_headers
Esempio n. 4
0
    def _parse_category_header(self, header_value):
        categories = []
        category_headers = HttpCategoryHeaders()
        category_headers.parse(header_value)
        for term, attributes in category_headers.all():
            param = {}
            for k, v in attributes:
                param[k] = v

            # Category scheme
            try:
                scheme = param['scheme']
            except KeyError:
                raise HttpHeaderError('Category scheme not specified')

            # Category, Kind or Mixin?
            t = param.get('class')
            cls = Category
            if t and t.lower() == 'kind':
                cls = Kind
            elif t and t.lower() == 'mixin':
                cls = Mixin
            elif not t and param.get('location'):
                cls = Mixin

            # Related Kind/Mixin
            try:
                t = param['rel']
                r_scheme, r_term = t.split('#', 1)
                r_scheme += '#'
                related = cls(r_term, r_scheme)
            except KeyError, ValueError:
                related = None

            # Supported attributes (mutable)
            try:
                attributes = param['attributes'].split()
            except KeyError:
                attributes = None

            # Supported actions
            try:
                t =  param['actions'].split()
            except KeyError:
                actions = None
            else:
                actions = []
                for action in param['actions'].split():
                    try:
                        a_term, a_scheme = action.split('#', 1)
                    except ValueError:
                        pass
                    else:
                        actions.append(Category(a_term, a_scheme))

            # Keyword args for Category
            kwargs = {
                    'title': param.get('title'),
                    'attributes': attributes
            }

            # Additional keyword args for Kind/Mixin
            if cls == Kind or cls == Mixin:
                kwargs['related'] = related
                kwargs['actions'] = actions
                location = param.get('location')
                if location:
                    kwargs['location'] = self.translator.url_strip(location)

            # Append instance to categories list
            try:
                categories.append(cls(term, scheme, **kwargs))
            except Category.Invalid as e:
                raise HttpHeaderError('%s: Invalid Category header: %s' % (scheme+term, e))