Esempio n. 1
0
    def tag(self, new_tags, strict=False, expiration=None):
        """Tags an observable.

        An observable can be tagged to add more information as to what it represents.

        Args:
            new_tags:
                An array of strings to tag the observable with.
            strict:
                Set to ``True`` to replace all existing tags with the ``new_tags``.
            expiration:
                Timedelta field after which the Tag will not be considered fresh anymore.

        Returns:
            A fresh Observable instance as reloaded from the database.

        """

        new_tags = iterify(new_tags)

        if strict:
            remove = set([t.name for t in self.tags]) - set(new_tags)
            for tag in remove:
                self.modify(pull__tags__name=tag)

        tagged = False
        for new_tag in new_tags:
            if new_tag.strip() != '':
                tagged = True

                new_tag = Tag(name=new_tag)
                new_tag.clean()

                try:  # check if tag is a replacement
                    tag = Tag.objects.get(replaces=new_tag.name)
                except DoesNotExist:
                    tag = Tag.get_or_create(name=new_tag.name)

                if not expiration:
                    expiration = tag.default_expiration

                extra_tags = tag.produces + [tag]

                # search for related entities and link them
                for e in Entity.objects(tags__in=[tag.name]):
                    self.active_link_to(e, 'Tagged', 'tags', clean_old=False)

                for tag in extra_tags:
                    if not self.modify(
                        {"tags__name": tag.name},
                            set__tags__S__fresh=True,
                            set__tags__S__last_seen=datetime.utcnow()):
                        self.modify(push__tags=ObservableTag(
                            name=tag.name, expiration=expiration))
                        tag.modify(inc__count=1)

        if tagged:
            self.update(set__last_tagged=datetime.utcnow())

        return self.reload()