Example #1
0
def prune_data(weeks=10, days=1):

    # Delete spam
    spam_posts = Post.objects.filter(spam=Post.SPAM)
    logger.info(f"Deleting {spam_posts.count()} spam posts")
    spam_posts.delete()

    past_days = now() - timedelta(days=days)
    post_views = PostView.objects.filter(date__lt=past_days)
    logger.info(f"Deleting {post_views.count()} post views")
    post_views.delete()

    # Reduce overall messages.
    weeks_since = now() - timedelta(weeks=weeks)
    messages = Message.objects.filter(sent_at__lt=weeks_since)
    logger.info(f"Deleting {messages.count()} messages")
    messages.delete()

    # Get rid of too many messages
    users = User.objects.annotate(total=Count("recipients")).filter(
        total__gt=MAX_MSG)[:100]
    for user in users:
        since = now() - timedelta(days=1)
        Message.objects.filter(user=user, sent_at__lt=since).delete()

    return
Example #2
0
def get_jobs(user, tag="", order="", limit=None):
    """
    Generates a post list on a topic.
    """
    query = Job.objects.all()

    if tag:
        query = query.filter(tags__name=tag.lower())

    # Apply post ordering.
    if ORDER_MAPPER.get(order):
        ordering = ORDER_MAPPER.get(order)
        query = query.order_by(ordering)
    else:
        query = query.order_by("-creation_date")

    days = LIMIT_MAP.get(limit, 0)
    # Apply time limit if required.
    if days:
        delta = util.now() - timedelta(days=days)
        query = query.filter(lastedit_date__gt=delta)

    # Select related information used during rendering.
    query = query.select_related("author__profile")

    return query
Example #3
0
def get_posts(user, topic="", tag="", order="", limit=None):
    """
    Generates a post list on a topic.
    """
    # Topics are case insensitive.
    topic = topic or LATEST
    topic = topic.lower()

    # Detect known post types.
    post_type = POST_TYPE_MAPPER.get(topic)
    query = Post.objects.valid_posts(u=user, is_toplevel=True)

    # Determines how to start the preform_search.
    if post_type:
        query = query.filter(type=post_type)
    elif topic == OPEN:
        query = query.filter(type=Post.QUESTION, answer_count=0)
    elif topic == BOOKMARKS and user.is_authenticated:
        query = query.filter(votes__author=user, votes__type=Vote.BOOKMARK)
    elif topic == FOLLOWING and user.is_authenticated:
        query = query.filter(subs__user=user)
    elif topic == MYPOSTS and user.is_authenticated:
        query = query.filter(author=user)
    elif topic == MYVOTES and user.is_authenticated:
        query = query.filter(votes__post__author=user)
    elif topic == MYTAGS and user.is_authenticated:
        tags = user.profile.my_tags.split(",")
        query = query.filter(tags__name__in=tags)

    if user.is_anonymous or not user.profile.is_moderator:
        query = query.exclude(Q(spam=Post.SPAM) | Q(status=Post.DELETED))
    # Filter by tags if specified.
    if tag:
        query = query.filter(tags__name=tag.lower())

    # Apply post ordering.
    if ORDER_MAPPER.get(order):
        ordering = ORDER_MAPPER.get(order)
        query = query.order_by(ordering)
    else:
        query = query.order_by("-rank")

    days = LIMIT_MAP.get(limit, 0)
    # Apply time limit if required.
    if days:
        delta = util.now() - timedelta(days=days)
        query = query.filter(lastedit_date__gt=delta)

    # Select related information used during rendering.
    query = query.select_related("root").select_related(
        "author__profile", "lastedit_user__profile")

    return query
Example #4
0
def get_start(days, cursor):
    """
    Return the start date stored in database
    """

    if days < 0:
        recent = Sync.objects.filter(pk=1).first()
        recent = recent.last_synced if recent else most_recent(cursor=cursor)
        recent = recent + timedelta(days=2)
    else:
        # Get the most recently created post on the remote server.
        recent = Post.objects.old().order_by("-creation_date").first()
        recent = recent.creation_date if recent else None
        recent = recent - timedelta(days=2)

    start = recent or util.now()

    return start
Example #5
0
def community_list(request):

    users = User.objects.select_related("profile")

    page = request.GET.get("page", 1)
    ordering = request.GET.get("order", "visit")
    limit_to = request.GET.get("limit", "time")
    query = request.GET.get('query', '')
    query = query.replace("'", "").replace('"', '').strip()

    days = LIMIT_MAP.get(limit_to, 0)

    if days:
        delta = util.now() - timedelta(days=days)
        users = users.filter(profile__last_login__gt=delta)

    if query and len(query) > 2:
        db_query = Q(profile__name__icontains=query) | Q(profile__uid__icontains=query) | \
                   Q(username__icontains=query) | Q(email__icontains=query)
        users = users.filter(db_query)

    # Remove the cache when filters are given.
    no_cache = days or (query and len(query) > 2) or ordering
    cache_key = None if no_cache else USERS_LIST_KEY

    order = ORDER_MAPPER.get(ordering, "visit")
    users = users.filter(profile__state__in=[Profile.NEW, Profile.TRUSTED])
    users = users.order_by(order)

    # Create the paginator
    paginator = CachedPaginator(cache_key=cache_key,
                                object_list=users,
                                per_page=settings.POSTS_PER_PAGE)
    users = paginator.get_page(page)
    context = dict(tab="community",
                   users=users,
                   query=query,
                   order=ordering,
                   limit=limit_to)

    return render(request, "community_list.html", context=context)
Example #6
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.spool(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)
Example #7
0
 def items(self):
     # Delay posts hours.
     delay_time = now() - timedelta(hours=2)
     posts = Post.objects.valid_posts(creation_date__lt=delay_time).exclude(
         type=Post.BLOG).order_by('-creation_date')
     return posts[:FEED_COUNT]