示例#1
0
    def output_mention_link(self, m):

        handle = m.group("handle")
        # Query user and get the link
        user = User.objects.filter(username=handle).first()
        if user:
            profile = reverse("user_profile",
                              kwargs=dict(uid=user.profile.uid))
            link = f'<a href="{profile}">{user.profile.name}</a>'
            # Subscribe mentioned users to post.
            if self.root:
                # Create user subscription if it does not already exist.
                auth.create_subscription(post=self.root,
                                         user=user,
                                         update=True)
        else:
            link = m.group(0)

        return link
示例#2
0
def notify_watched_tags(post):
    """
    Create a subscription to a post when
    """
    from biostar.accounts.models import User
    from biostar.forum import auth

    # Skip non top level posts.
    if not post.is_toplevel:
        return

    # Iterate over tags and get users that are watching them
    users = [User.objects.filter(profile__watched_tags__contains=tag) for tag in post.tags.all()]

    # Flatten nested iterable.
    users = set(u for qs in users for u in qs)

    # Subscribe users to this post and send them emails.
    for user in users:
        auth.create_subscription(post=post.root, user=user)

    return
示例#3
0
def finalize_post(sender, instance, created, **kwargs):

    # Determine the root of the post.
    root = instance.root if instance.root is not None else instance

    # Update last contributor, last editor, and last edit date to the thread
    Post.objects.filter(uid=root.uid).update(
        lastedit_user=instance.lastedit_user,
        last_contributor=instance.last_contributor,
        lastedit_date=instance.lastedit_date)

    # Get newly created subscriptions since the last edit date.
    subs = Subscription.objects.filter(date__gte=instance.lastedit_date,
                                       post=instance.root)

    if created:
        # Make the Uid user friendly
        instance.uid = instance.uid or f"p{instance.pk}"

        if instance.parent:
            # When the parent is set the root must follow the parent root.
            instance.root = instance.parent.root
        else:
            # When there is no parent, root and parent are set to itself.
            instance.root = instance.parent = instance

        # Answers and comments may only have comments associated with them.
        if instance.parent.type in (Post.ANSWER, Post.COMMENT):
            instance.type = Post.COMMENT

        # Sanity check.
        assert instance.root and instance.parent

        if instance.is_toplevel:
            # Add tags for top level posts.
            tags = [
                Tag.objects.get_or_create(name=name)[0]
                for name in instance.parse_tags()
            ]
            instance.tags.remove()
            instance.tags.add(*tags)
        else:
            # Title is inherited from top level.
            instance.title = "%s: %s" % (instance.get_type_display(),
                                         instance.root.title[:80])

        # Make the last editor first in the list of contributors
        # Done on post creation to avoid moderators being added for editing a post.
        instance.root.thread_users.remove(instance.lastedit_user)
        instance.root.thread_users.add(instance.lastedit_user)

        # Update this post rank on create and not every edit.
        instance.rank = instance.lastedit_date.timestamp()

        # Save the instance.
        instance.save()
        instance.update_parent_counts()

        # Bump the root rank when a new descendant is added.
        Post.objects.filter(uid=instance.root.uid).update(
            rank=util.now().timestamp())

        # Create subscription to the root.
        auth.create_subscription(post=instance.root, user=instance.author)

        # Get all subscribed users when a new post is created
        subs = Subscription.objects.filter(post=instance.root)

        # Notify users who are watching tags in this post
        #tasks.notify_watched_tags(post=instance)

        # Give it a spam score.
        tasks.spam_scoring.spool(post=instance)

    # Add this post to the spam index if it's spam.
    tasks.update_spam_index.spool(post=instance)

    # Ensure posts get re-indexed after being edited.
    Post.objects.filter(uid=instance.uid).update(indexed=False)

    # Exclude current authors from receiving messages from themselves
    subs = subs.exclude(
        Q(type=Subscription.NO_MESSAGES) | Q(user=instance.author))
    extra_context = dict(post=instance)
    tasks.notify_followers.spool(subs=subs,
                                 author=instance.author,
                                 extra_context=extra_context)
示例#4
0
def finalize_post(sender, instance, created, **kwargs):

    # Determine the root of the post.
    root = instance.root if instance.root is not None else instance

    # Update last contributor, last editor, and last edit date to the thread
    Post.objects.filter(uid=root.uid).update(
        lastedit_user=instance.lastedit_user,
        lastedit_date=instance.lastedit_date)

    # Get newly created subscriptions since the last edit date.
    subs = Subscription.objects.filter(date__gte=instance.lastedit_date,
                                       post=instance.root)
    extra_context = dict()

    if created:
        # Make the uid user friendly
        instance.uid = instance.uid or f"9{instance.pk}"

        if instance.parent:
            # When the parent is set the root must follow the parent root.
            instance.root = instance.parent.root
        else:
            # When there is no parent, root and parent are set to itself.
            instance.root = instance.parent = instance

        # Answers and comments may only have comments associated with them.
        if instance.parent.type in (Post.ANSWER, Post.COMMENT):
            instance.type = Post.COMMENT

        # Sanity check.
        assert instance.root and instance.parent

        # Make the last editor first in the list of contributors
        # Done on post creation to avoid moderators being added for editing a post.
        instance.root.thread_users.remove(instance.lastedit_user)
        instance.root.thread_users.add(instance.lastedit_user)

        # Update this post rank on create and not every edit.
        instance.rank = instance.lastedit_date.timestamp()

        # Save the instance.
        instance.save()
        instance.update_parent_counts()

        # Bump the root rank when a new answer is added.
        if instance.is_answer:
            Post.objects.filter(uid=instance.root.uid).update(
                rank=util.now().timestamp())

        # Create subscription to the root.
        auth.create_subscription(post=instance.root, user=instance.author)

        # Get all subscribed users when a new post is created
        subs = Subscription.objects.filter(post=instance.root)

        # Notify users who are watching tags in this post
        tasks.notify_watched_tags.spool(uid=instance.uid,
                                        extra_context=extra_context)

        # Send out mailing list when post is created.
        tasks.mailing_list.spool(uid=instance.uid, extra_context=extra_context)

    # Set the tags on the instance.
    if instance.is_toplevel:
        tags = [
            Tag.objects.get_or_create(name=name)[0]
            for name in instance.parse_tags()
        ]
        instance.tags.clear()
        instance.tags.add(*tags)

    # Ensure spam posts get closed status
    if instance.is_spam:
        Post.objects.filter(uid=instance.uid).update(status=Post.CLOSED)

    if not instance.is_toplevel:
        # Title is inherited from top level.
        title = f"{instance.get_type_display()}: {instance.root.title[:80]}"
        Post.objects.filter(uid=instance.uid).update(title=title)

    # Ensure posts get re-indexed after being edited.
    Post.objects.filter(uid=instance.uid).update(indexed=False)

    # Exclude current authors from receiving messages from themselves
    subs = subs.exclude(
        Q(type=Subscription.NO_MESSAGES) | Q(user=instance.author))

    sub_ids = list(subs.values_list('id', flat=True))

    # Notify subscribers
    tasks.notify_followers.spool(sub_ids=sub_ids,
                                 author_id=instance.author.pk,
                                 uid=instance.uid,
                                 extra_context=extra_context)