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