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
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
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
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))