def link_format_from_message(message): try: if message.opt.content_format == media_types_rev['application/link-format']: return parse(message.payload.decode('utf8')) elif message.opt.content_format == media_types_rev['application/link-format+json']: return LinkFormat.from_json_string(message.payload.decode('utf8')) elif message.opt.content_format == media_types_rev['application/link-format+cbor']: return LinkFormat.from_cbor_bytes(message.payload) else: raise error.UnsupportedMediaType() except (UnicodeDecodeError, link_header.ParseException): raise error.BadRequest()
def get_links(): links = site.get_resources_as_linkheader() for l in links.links: if l.href == "/sensors/light": l.attr_pairs.append( ("anchor", "coap://spurious.example.com:5683")) return LinkFormat(links.links)
async def render_get(self, request): query = query_split(request) candidates = self.common_rd.get_endpoints() for search_key, search_value in query.items(): if search_key in ('page', 'count'): continue # filtered last if search_value.endswith('*'): matches = lambda x, start=search_value[:-1]: x.startswith(start) else: matches = lambda x: x == search_value if search_key in ('if', 'rt'): candidates = (c for c in candidates if any(any(matches(x) for x in getattr(r, search_key, '').split()) for r in c.get_based_links().links)) continue if search_key == 'href': candidates = (c for c in candidates if matches(c.href) or any(matches(r.href) for r in c.get_based_links().links) ) continue candidates = (c for c in candidates if (search_key in c.registration_parameters and matches(c.registration_parameters[search_key])) or any(_link_matches(r, search_key, matches) for r in c.get_based_links().links) ) candidates = _paginate(candidates, query) result = [c.get_host_link() for c in candidates] return link_format_to_message(request, LinkFormat(result))
def get_links(): links = site.get_resources_as_linkheader() links.links.append(Link("/t", anchor="sensors/temp", rel="alternate")) links.links.append( Link("http://www.example.com/sensors/t123", anchor="sensors/temp", rel="describedby")) return LinkFormat(links.links)
def __init__(self, path, network_remote, delete_cb, update_cb, registration_parameters): # note that this can not modify d and ep any more, since they were # already used in keying to a path self.path = path self.links = LinkFormat([]) self._delete_cb = delete_cb self._update_cb = update_cb self.update_params(network_remote, registration_parameters, is_initial=True)
def link_format_from_message(message): """Convert a response message into a LinkFormat object This expects an explicit media type set on the response (or was explicitly requested) """ certain_format = message.opt.content_format if certain_format is None: certain_format = message.request.opt.accept try: if certain_format == media_types_rev['application/link-format']: return parse(message.payload.decode('utf8')) elif certain_format == media_types_rev['application/link-format+json']: return LinkFormat.from_json_string(message.payload.decode('utf8')) elif certain_format == media_types_rev['application/link-format+cbor']: return LinkFormat.from_cbor_bytes(message.payload) else: raise error.UnsupportedMediaType() except (UnicodeDecodeError, link_header.ParseException): raise error.BadRequest()
async def render_get(self, request): query = query_split(request) eps = self.common_rd.get_endpoints() candidates = ((e, c) for e in eps for c in e.get_based_links().links) for search_key, search_values in query.items(): if search_key in ('page', 'count'): continue # filtered last for search_value in search_values: if search_value is not None and search_value.endswith('*'): def matches(x, start=search_value[:-1]): return x.startswith(start) else: def matches(x, search_value=search_value): return x == search_value if search_key in ('if', 'rt'): def matches(x, original_matches=matches): return any(original_matches(v) for v in x.split()) if search_key == 'href': candidates = ( (e, c) for (e, c) in candidates if matches(c.href) or matches( e.href ) # FIXME: They SHOULD give this as relative as we do, but don't have to ) continue candidates = ( (e, c) for (e, c) in candidates if _link_matches(c, search_key, matches) or ( search_key in e.registration_parameters and any( matches(x) for x in e.registration_parameters[search_key]))) # strip endpoint candidates = (c for (e, c) in candidates) candidates = _paginate(candidates, query) # strip needless anchors candidates = [ Link(l.href, [(k, v) for (k, v) in l.attr_pairs if k != 'anchor']) if dict(l.attr_pairs)['anchor'] == urljoin(l.href, '/') else l for l in candidates ] return link_format_to_message(request, LinkFormat(candidates))
def get_based_links(self): """Produce a LinkFormat object that represents all statements in the registration, resolved to the registration's base (and thus suitable for comparing anchors).""" result = [] for l in self.links.links: href = urljoin(self.base, l.href) if 'anchor' in l: absanchor = urljoin(self.base, l.anchor) data = [(k, v) for (k, v) in l.attr_pairs if k != 'anchor' ] + [['anchor', absanchor]] else: data = l.attr_pairs + [['anchor', urljoin(href, '/')]] result.append(Link(href, data)) return LinkFormat(result)
async def render_get(self, request): query = query_split(request) eps = self.common_rd.get_endpoints() candidates = ((e, c) for e in eps for c in e.get_based_links().links) for search_key, search_value in query.items(): if search_key in ('page', 'count'): continue # filtered last # FIXME: maybe we need query_split to turn ?rt=foo&obs into {'rt': # 'foo', 'obs': True} to match on obs, and then this needs more # type checking if search_value.endswith('*'): matches = lambda x, start=search_value[:-1]: x.startswith(start ) else: matches = lambda x: x == search_value if search_key in ('if', 'rt'): candidates = ((e, c) for (e, c) in candidates if any( matches(x) for x in " ".join(getattr(c, search_key, ())).split())) continue if search_key == 'href': candidates = ( (e, c) for (e, c) in candidates if matches(urljoin(e.base, c.href)) or matches( e.href ) # FIXME: actually resolved e, but so far we've avoided knowing our own ) continue candidates = ((e, c) for (e, c) in candidates if _link_matches(c, search_key, matches) or (search_key in e.registration_parameters and matches(e.registration_parameters[search_key]))) # strip endpoint candidates = (c for (e, c) in candidates) candidates = _paginate(candidates, query) return link_format_to_message(request, LinkFormat(candidates))
def __init__(self, static_registration_parameters, path, network_remote, delete_cb, update_cb, registration_parameters): # note that this can not modify d and ep any more, since they are # already part of the key and possibly the path self.path = path self.links = LinkFormat([]) self._delete_cb = delete_cb self._update_cb = update_cb self.registration_parameters = static_registration_parameters self.lt = 90000 self.base_is_explicit = False self.update_params(network_remote, registration_parameters, is_initial=True)
def get_based_links(self): """Produce a LinkFormat object that represents all statements in the registration, resolved to the registration's base (and thus suitable for serving from the lookup interface). This implements Limited Link Format as described in Appendix C of draft-ietf-core-resource-directory-25.""" result = [] for l in self.links.links: if 'anchor' in l: absanchor = urljoin(self.base, l.anchor) data = [(k, v) for (k, v) in l.attr_pairs if k != 'anchor' ] + [['anchor', absanchor]] else: data = l.attr_pairs + [['anchor', self.base]] href = urljoin(self.base, l.href) result.append(Link(href, data)) return LinkFormat(result)
def get_based_links(self): """Produce a LinkFormat object that represents all statements in the registration, resolved to the registration's base (and thus suitable for serving from the lookup interface). If protocol negotiation is implemented and base becomes a list, this function will probably grow parameters that hint at which base to use. """ result = [] for l in self.links.links: if 'anchor' in l: absanchor = urljoin(self.base, l.anchor) data = [(k, v) for (k, v) in l.attr_pairs if k != 'anchor'] + [['anchor', absanchor]] href = urljoin(absanchor, l.href) else: data = l.attr_pairs + [['anchor', self.base]] href = urljoin(self.base, l.href) result.append(Link(href, data)) return LinkFormat(result)