def _setattr(req, *opts): """ Sets entity attributes on the working document :param req: The request :param opts: Options (not used) :return: A modified working document Transforms the working document by setting the specified attribute on all of the EntityDescriptor elements of the active document. **Examples** .. code-block:: yaml - setattr: attr1: value1 attr2: value2 ... Normally this would be combined with the 'merge' feature of fork to add attributes to the working document for later processing. """ if req.t is None: raise PipeException("Your pipeline is missing a select statement.") for e in iter_entities(req.t): #log.debug("setting %s on %s" % (req.args,e.get('entityID'))) req.md.set_entity_attributes(e, req.args) return req.t
def update(self, t, tid=None, ts=None, merge_strategy=None): # log.debug("memory store update: %s: %s" % (repr(t), tid)) relt = root(t) assert (relt is not None) ne = 0 if relt.tag == "{%s}EntityDescriptor" % NS['md']: # log.debug("memory store setting entity descriptor") self._unindex(relt) self._index(relt) self.entities[relt.get('entityID')] = relt # TODO: merge? if tid is not None: self.md[tid] = [relt.get('entityID')] ne += 1 # log.debug("keys %s" % self.md.keys()) elif relt.tag == "{%s}EntitiesDescriptor" % NS['md']: if tid is None: tid = relt.get('Name') lst = [] for e in iter_entities(t): self.update(e) lst.append(e.get('entityID')) ne += 1 self.md[tid] = lst return ne
def first(req, *opts): """ If the working document is a single EntityDescriptor, strip the outer EntitiesDescriptor element and return it. :param req: The request :param opts: Options (unused) :return: returns the first entity descriptor if the working document only contains one Sometimes (eg when running an MDX pipeline) it is usually expected that if a single EntityDescriptor is being returned then the outer EntitiesDescriptor is stripped. This method does exactly that: """ if req.t is None: raise PipeException("Your pipeline is missing a select statement.") gone = object() # sentinel entities = iter_entities(req.t) one = next(entities, gone) if one is gone: return req.t # empty tree - return it as is two = next(entities, gone) # one EntityDescriptor in tree - return just that one if two is gone: return one return req.t
def _reginfo(req, *opts): """ Sets registration info extension on EntityDescription element :param req: The request :param opts: Options (not used) :return: A modified working document Transforms the working document by setting the specified attribute on all of the EntityDescriptor elements of the active document. **Examples** .. code-block:: yaml - reginfo: [policy: <lang>: <registration policy URL>] authority: <registrationAuthority URL> """ if req.t is None: raise PipeException("Your pipeline is missing a select statement.") for e in iter_entities(req.t): req.md.set_reginfo(e, **req.args) return req.t
def _setattr(req, *opts): """ Sets entity attributes on the working document :param req: The request :param opts: Options (not used) :return: A modified working document Transforms the working document by setting the specified attribute on all of the EntityDescriptor elements of the active document. **Examples** .. code-block:: yaml - setattr: attr1: value1 attr2: value2 ... Normally this would be combined with the 'merge' feature of fork to add attributes to the working document for later processing. """ if req.t is None: raise PipeException("Your pipeline is missing a select statement.") for e in iter_entities(req.t): # log.debug("setting %s on %s" % (req.args,e.get('entityID'))) req.md.set_entity_attributes(e, req.args) return req.t
def update(self, t, tid=None, ts=None, merge_strategy=None): # TODO: merge ? log.debug("redis store update: %s: %s" % (t, tid)) relt = root(t) ne = 0 if ts is None: ts = int( _now() + 3600 * 24 * 4) # 4 days is the arbitrary default expiration if relt.tag == "{%s}EntityDescriptor" % NS['md']: if tid is None: tid = relt.get('entityID') with self.rc.pipeline() as p: self.update_entity(relt, t, tid, ts, p) entity_id = relt.get("entityID") if entity_id is not None: self.membership("entities", entity_id, ts, p) for ea, eav in entity_attribute_dict(relt).iteritems(): for v in eav: # log.debug("%s=%s" % (ea, v)) self.membership("{%s}%s" % (ea, v), tid, ts, p) p.zadd("%s#values" % ea, v, ts) p.sadd("#attributes", ea) for hn in ('sha1', 'sha256', 'md5'): tid_hash = hex_digest(tid, hn) p.set("{%s}%s#alias" % (hn, tid_hash), tid) if ts is not None: p.expireat(tid_hash, ts) p.execute() ne += 1 elif relt.tag == "{%s}EntitiesDescriptor" % NS['md']: if tid is None: tid = relt.get('Name') ts = self._expiration(relt) with self.rc.pipeline() as p: self.update_entity(relt, t, tid, ts, p) for e in iter_entities(t): ne += self.update(e, ts=ts) entity_id = e.get("entityID") if entity_id is not None: self.membership(tid, entity_id, ts, p) self.membership("entities", entity_id, ts, p) p.execute() else: raise ValueError("Bad metadata top-level element: '%s'" % root(t).tag) return ne
def discojson(req, *opts): """ Return a discojuice-compatible json representation of the tree :param req: The request :param opts: Options (unusued) :return: returns a JSON array """ if req.t is None: raise PipeException("Your pipeline is missing a select statement.") return json.dumps([req.md.discojson(e) for e in iter_entities(req.t)])
def discojson(req, *opts): """ Return a discojuice-compatible json representation of the tree :param req: The request :param opts: Options (unusued) :return: returns a JSON array """ if req.t is None: raise PipeException("Your pipeline is missing a select statement.") res = [req.md.discojson(e) for e in iter_entities(req.t)] res.sort(key=operator.itemgetter('title')) return json.dumps(res)
def update(self, t, tid=None, ts=None, merge_strategy=None): # TODO: merge ? log.debug("redis store update: %s: %s" % (t, tid)) relt = root(t) ne = 0 if ts is None: ts = int(_now() + 3600 * 24 * 4) # 4 days is the arbitrary default expiration if relt.tag == "{%s}EntityDescriptor" % NS['md']: if tid is None: tid = relt.get('entityID') with self.rc.pipeline() as p: self.update_entity(relt, t, tid, ts, p) entity_id = relt.get("entityID") if entity_id is not None: self.membership("entities", entity_id, ts, p) for ea, eav in entity_attribute_dict(relt).iteritems(): for v in eav: # log.debug("%s=%s" % (ea, v)) self.membership("{%s}%s" % (ea, v), tid, ts, p) p.zadd("%s#values" % ea, v, ts) p.sadd("#attributes", ea) for hn in ('sha1', 'sha256', 'md5'): tid_hash = hex_digest(tid, hn) p.set("{%s}%s#alias" % (hn, tid_hash), tid) if ts is not None: p.expireat(tid_hash, ts) p.execute() ne += 1 elif relt.tag == "{%s}EntitiesDescriptor" % NS['md']: if tid is None: tid = relt.get('Name') ts = self._expiration(relt) with self.rc.pipeline() as p: self.update_entity(relt, t, tid, ts, p) for e in iter_entities(t): ne += self.update(e, ts=ts) entity_id = e.get("entityID") if entity_id is not None: self.membership(tid, entity_id, ts, p) self.membership("entities", entity_id, ts, p) p.execute() else: raise ValueError("Bad metadata top-level element: '%s'" % root(t).tag) return ne
def store(req, *opts): """ Save the working document as separate files :param req: The request :param opts: Options (unused) :return: always returns the unmodified working document Split the working document into EntityDescriptor-parts and save in directory/sha1(@entityID).xml. Note that this does not erase files that may already be in the directory. If you want a "clean" directory, remove it before you call store. """ if req.t is None: raise PipeException("Your pipeline is missing a select statement.") if not req.args: raise PipeException("store requires an argument") target_dir = None if type(req.args) is dict: target_dir = req.args.get('directory', None) else: target_dir = req.args[0] if target_dir is not None: if not os.path.isdir(target_dir): os.makedirs(target_dir) for e in iter_entities(req.t): eid = e.get('entityID') if eid is None or len(eid) == 0: raise PipeException("Missing entityID in %s" % e) m = hashlib.sha1() m.update(eid) d = m.hexdigest() safe_write("%s.xml" % os.path.join(target_dir, d), dumptree(e, pretty_print=True)) return req.t