async def _getTagDelEdits(self, tag, init=False): path = s_chop.tagpath(tag) name = '.'.join(path) if self.form.isrunt: raise s_exc.IsRuntForm(mesg='Cannot delete tags from runt nodes.', form=self.form.full, tag=tag) curv = self.tags.get(name, s_common.novalu) if curv is s_common.novalu: return () pref = name + '.' todel = [(len(t), t) for t in self.tags.keys() if t.startswith(pref)] if len(path) > 1: parent = '.'.join(path[:-1]) # retrieve a list of prunable tags prune = await self.snap.core.getTagPrune(parent) if prune: tree = self._getTagTree() for prunetag in reversed(prune): node = tree for step in prunetag.split('.'): node = node[1].get(step) if node is None: break if node is not None and len(node[1]) == 1: todel.append((len(node[0]), node[0])) continue break todel.sort(reverse=True) # order matters... edits = [] for _, subtag in todel: edits.extend(self._getTagPropDel(subtag)) edits.append((s_layer.EDIT_TAG_DEL, (subtag, None), ())) edits.extend(self._getTagPropDel(name)) edits.append((s_layer.EDIT_TAG_DEL, (name, None), ())) return edits
async def _getAddTagEdits(self, node, tags): edits = [] for tag, valu in tags.items(): path = s_chop.tagpath(tag) name = '.'.join(path) if not await self.core.isTagValid(name): await self.warn( f'Tag {tag} does not meet the regex for the tree.') continue tagnode = await self.addTagNode(name) isnow = tagnode.get('isnow') if isnow: await self.warn(f'Tag {name} is now {isnow}') name = isnow path = isnow.split('.') if isinstance(valu, list): valu = tuple(valu) if valu != (None, None): try: valu = self.core.model.type('ival').norm(valu)[0] except asyncio.CancelledError: # pragma: no cover TODO: remove once >= py 3.8 only raise except Exception as e: await self.warn(f'Bad tag value: #{tag}={valu}') continue curv = None if node is not None: curv = node.tags.get(name) if curv == valu: continue if curv is None: tags = s_chop.tags(name) for tag in tags[:-1]: if node is not None and node.tags.get(tag) is not None: continue await self.addTagNode(tag) edits.append( (s_layer.EDIT_TAG_SET, (tag, (None, None), None), ())) else: valu = s_time.ival(*valu, *curv) edits.append((s_layer.EDIT_TAG_SET, (name, valu, None), ())) return edits
async def delTag(self, tag, init=False): ''' Delete a tag from the node. ''' path = s_chop.tagpath(tag) name = '.'.join(path) if self.isrunt: raise s_exc.IsRuntForm(mesg='Cannot delete tags from runt nodes.', form=self.form.full, tag=tag) curv = self.tags.pop(name, s_common.novalu) if curv is s_common.novalu: return False pref = name + '.' tagprops = [x for x in self.tagprops.keys() if x[0] == name] subtags = [(len(t), t) for t in self.tags.keys() if t.startswith(pref)] subtags.sort(reverse=True) removed = [] for sublen, subtag in subtags: valu = self.tags.pop(subtag, None) removed.append((subtag, valu)) tagprops.extend( [x for x in self.tagprops.keys() if x[0] == subtag]) removed.append((name, curv)) info = {'univ': True} sops = [('prop:del', (self.buid, self.form.name, '#' + t, info)) for (t, v) in removed] sops.extend([('tag:prop:del', (self.buid, self.form.name, tag, prop, {})) for (tag, prop) in tagprops]) # fire all the splices splices = [ self.snap.splice('tag:del', ndef=self.ndef, tag=t, valu=v) for (t, v) in removed ] await self.snap.stor(sops, splices) # fire all the handlers / triggers [await self.snap.core.runTagDel(self, t, v) for (t, v) in removed]
async def addTag(self, tag, valu=(None, None)): if self.isrunt: raise s_exc.IsRuntForm(mesg='Cannot add tags to runt nodes.', form=self.form.full, tag=tag) path = s_chop.tagpath(tag) name = '.'.join(path) tagnode = await self.snap.addTagNode(name) # implement tag renames... isnow = tagnode.get('isnow') if isnow: await self.snap.warn(f'tag {name} is now {isnow}') name = isnow path = isnow.split('.') if isinstance(valu, list): valu = tuple(valu) if valu != (None, None): valu = self.snap.model.type('ival').norm(valu)[0] curv = self.tags.get(name) if curv == valu: return elif curv is None: tags = s_chop.tags(name) for tag in tags[:-1]: if self.tags.get(tag) is not None: continue await self._addTagRaw(tag, (None, None)) await self._addTagRaw(tags[-1], valu) return # merge values into one interval valu = s_time.ival(*valu, *curv) indx = self.snap.model.types['ival'].indx(valu) info = {'univ': True} await self._setTagProp(name, valu, indx, info)
async def delTag(self, tag, init=False): ''' Delete a tag from the node. ''' path = s_chop.tagpath(tag) name = '.'.join(path) if self.isrunt: raise s_exc.IsRuntForm(mesg='Cannot delete tags from runt nodes.', form=self.form.full, tag=tag) curv = self.tags.pop(name, s_common.novalu) if curv is s_common.novalu: return False pref = name + '.' subtags = [(len(t), t) for t in self.tags.keys() if t.startswith(pref)] subtags.sort(reverse=True) removed = [] for sublen, subtag in subtags: valu = self.tags.pop(subtag, None) removed.append((subtag, valu)) removed.append((name, curv)) info = {'univ': True} sops = [('prop:del', (self.buid, self.form.name, '#' + t, info)) for (t, v) in removed] # fire all the splices splices = [self.snap.splice('tag:del', ndef=self.ndef, tag=t, valu=v) for (t, v) in removed] await self.snap.stor(sops, splices) # fire all the handlers / triggers [await self.snap.core.runTagDel(self, t, v) for (t, v) in removed]
async def delTag(self, tag, init=False): ''' Delete a tag from the node. ''' path = s_chop.tagpath(tag) name = '.'.join(path) if self.form.isrunt: raise s_exc.IsRuntForm(mesg='Cannot delete tags from runt nodes.', form=self.form.full, tag=tag) curv = self.tags.get(name, s_common.novalu) if curv is s_common.novalu: return False pref = name + '.' subtags = [(len(t), t) for t in self.tags.keys() if t.startswith(pref)] subtags.sort(reverse=True) # order matters... edits = [] for _, subtag in subtags: edits.extend(self._getTagPropDel(subtag)) edits.append((s_layer.EDIT_TAG_DEL, (subtag, None), ())) edits.extend(self._getTagPropDel(name)) edits.append((s_layer.EDIT_TAG_DEL, (name, None), ())) nodeedit = (self.buid, self.form.name, edits) await self.snap.applyNodeEdit(nodeedit)
async def addTag(self, tag, valu=(None, None)): ''' Add a tag to a node. Args: tag (str): The tag to add to the node. valu: The optional tag value. If specified, this must be a value that norms as a valid time interval as an ival. Returns: None: This returns None. ''' if self.form.isrunt: raise s_exc.IsRuntForm(mesg='Cannot add tags to runt nodes.', form=self.form.full, tag=tag) path = s_chop.tagpath(tag) name = '.'.join(path) if not await self.snap.core.isTagValid(name): mesg = f'The tag does not meet the regex for the tree.' raise s_exc.BadTag(mesg=mesg) tagnode = await self.snap.addTagNode(name) # implement tag renames... isnow = tagnode.get('isnow') if isnow: await self.snap.warn(f'tag {name} is now {isnow}') name = isnow path = isnow.split('.') if isinstance(valu, list): valu = tuple(valu) if valu != (None, None): valu = self.snap.core.model.type('ival').norm(valu)[0] curv = self.tags.get(name) if curv == valu: return edits = [] if curv is None: tags = s_chop.tags(name) for tag in tags[:-1]: if self.tags.get(tag) is not None: continue await self.snap.addTagNode(tag) edits.append( (s_layer.EDIT_TAG_SET, (tag, (None, None), None), ())) else: # merge values into one interval valu = s_time.ival(*valu, *curv) if valu == curv: return edits.append((s_layer.EDIT_TAG_SET, (name, valu, None), ())) nodeedit = (self.buid, self.form.name, edits) await self.snap.applyNodeEdit(nodeedit)
async def addTag(self, tag, valu=(None, None)): ''' Add a tag to a node. Args: tag (str): The tag to add to the node. valu: The optional tag value. If specified, this must be a value that norms as a valid time interval as an ival. Returns: None: This returns None. ''' if self.isrunt: raise s_exc.IsRuntForm(mesg='Cannot add tags to runt nodes.', form=self.form.full, tag=tag) path = s_chop.tagpath(tag) name = '.'.join(path) tagnode = await self.snap.addTagNode(name) # implement tag renames... isnow = tagnode.get('isnow') if isnow: await self.snap.warn(f'tag {name} is now {isnow}') name = isnow path = isnow.split('.') if isinstance(valu, list): valu = tuple(valu) if valu != (None, None): valu = self.snap.model.type('ival').norm(valu)[0] curv = self.tags.get(name) if curv == valu: return elif curv is None: tags = s_chop.tags(name) for tag in tags[:-1]: if self.tags.get(tag) is not None: continue await self._addTagRaw(tag, (None, None)) await self._addTagRaw(tags[-1], valu) return # merge values into one interval valu = s_time.ival(*valu, *curv) if valu == curv: return indx = self.snap.model.types['ival'].indx(valu) info = {'univ': True} await self._setTagProp(name, valu, indx, info)