Example #1
0
 def top(self, tab):
     filters = {
         "yesterday": {"date_created__date": timezone.localtime(time_threshold(hours=24)).date()},
         "week": {"date_created__lte": time_threshold(days=7), "date_created__gte": time_threshold(days=14)},
     }
     return (
         Entry.objects.filter(**filters.get(tab), vote_rate__gt=0, topic__is_censored=False)
         .order_by("-vote_rate")
         .annotate(title=F("topic__title"), slug=F("pk"))
         .values(*self.values)
     )[: settings.TOPICS_PER_PAGE_DEFAULT]
Example #2
0
 def get_context_data(self, **kwargs):
     context = super().get_context_data(**kwargs)
     context["recent_drafts"] = (Entry.objects_all.filter(
         Q(date_created__gte=time_threshold(hours=24))
         | Q(date_edited__gte=time_threshold(hours=24)),
         is_draft=True,
         author=self.request.user,
     ).select_related("topic").only(
         "topic__title", "date_created", "date_edited").alias(
             last_edited=Coalesce(F("date_edited"), F(
                 "date_created"))).order_by("-last_edited")[:5])
     return context
Example #3
0
    def novice_queue(self):
        if self.last_activity < time_threshold(hours=24):
            # NoviceActivityMiddleware ensures that logged in novices will always
            # pass this check. It is not possible to see the queue of users
            # with no activity in last one day.
            return None

        def interqueue(user):
            active_siblings = Author.in_novice_list.annotate_activity(
                Author.in_novice_list.exclude(pk=user.pk).filter(
                    queue_priority=user.queue_priority)).filter(
                        is_active_today=True)

            if active_siblings.exists():
                return active_siblings.filter(
                    application_date__lt=user.application_date).count() + 1
            return 1

        equal_and_superior = Author.in_novice_list.exclude(pk=self.pk).filter(
            queue_priority__gte=self.queue_priority)

        if equal_and_superior.exists():
            superior = equal_and_superior.filter(
                queue_priority__gt=self.queue_priority)

            if superior_count := superior.count():
                return superior_count + interqueue(self)
            return interqueue(self)
Example #4
0
    def has_exceeded_vote_limit(self, against=None):
        """Check vote limits. This is done before the vote is registered."""

        # Notice: couldn't filter on unions, so both models are explicitly written.
        h24 = {"date_created__gte": time_threshold(hours=24)}  # Filter objects that has been created in last 24 hours.

        upvoted = UpvotedEntries.objects.filter(author=self)
        downvoted = DownvotedEntries.objects.filter(author=self)

        daily_vote_count = upvoted.filter(**h24).count() + downvoted.filter(**h24).count()

        if daily_vote_count >= settings.DAILY_VOTE_LIMIT:
            return True, gettext("you have used up all the vote claims you have today. try again later.")

        if against:
            upvoted_against = upvoted.filter(entry__author=against).count()
            downvoted_against = downvoted.filter(entry__author=against).count()
            total_votes_against = upvoted_against + downvoted_against

            if total_votes_against >= settings.TOTAL_VOTE_LIMIT_PER_USER:
                return True, gettext("sorry, you have been haunting this person for a long time.")

            daily_upvoted_against = upvoted.filter(entry__author=against, **h24).count()
            daily_downvoted_against = downvoted.filter(entry__author=against, **h24).count()
            daily_votes_against = daily_upvoted_against + daily_downvoted_against

            if daily_votes_against >= settings.DAILY_VOTE_LIMIT_PER_USER:
                return True, gettext("this person has taken enough of your votes today, maybe try other users?")

        return False, None
Example #5
0
    def form_valid(self, form):
        image = form.save(commit=False)

        if self.request.user.is_novice or not self.request.user.is_accessible:
            return HttpResponseBadRequest(
                gettext("you lack the required permissions."))

        if Image.objects.filter(
                author=self.request.user,
                date_created__gte=time_threshold(hours=24)
        ).count(
        ) >= settings.DAILY_IMAGE_UPLOAD_LIMIT and not self.request.user.has_perm(
                "dictionary.add_image"):
            return HttpResponseBadRequest(
                gettext(
                    "you have reached the upload limit (%(limit)d images in a 24 hour period). try again later."
                ) % {"limit": settings.DAILY_IMAGE_UPLOAD_LIMIT})

        if image.file.size > settings.MAX_UPLOAD_SIZE:
            return HttpResponseBadRequest(
                gettext("this file is too large. (%.1f> MB)") %
                settings.MAX_UPLOAD_SIZE / 1048576)

        if settings.COMPRESS_IMAGES and image.file.size > settings.COMPRESS_THRESHOLD:
            image.file = compress(image.file)

        image.author = self.request.user
        image.save()
        return JsonResponse({"slug": image.slug})
Example #6
0
 def acquaintances_entries(self, user):
     return (Topic.objects.values(*self.values).filter(
         entries__is_draft=False,
         entries__date_created__gte=time_threshold(hours=120),
         entries__author__in=user.following.all(),
     ).annotate(latest=Max("entries__date_created"),
                count=Count("entries")).order_by("-latest"))
    def acquaintances(self):
        """Shows the entries of followed users."""
        filters = {"author__in": self.request.user.following.all()}

        # 120 hours defined in TopicQueryHandler's acquaintances_entries
        if self.request.GET.get("recent") is not None:
            filters["date_created__gte"] = time_threshold(hours=120)

        return self.topic.entries.filter(**filters)
Example #8
0
    def form_valid(self, form):
        instance = form.save(commit=False)

        if self.request.user.is_authenticated:
            instance.reporter_email = self.request.user.email
            instance.is_verified = True

        if GeneralReport.objects.filter(
                reporter_email=instance.reporter_email,
                date_created__gte=time_threshold(minutes=15)).exists():
            notifications.error(
                self.request,
                _("it hasn't been long since you last sent a report."),
                extra_tags="persistent")
            return self.form_invalid(form)

        # User is already logged in, no verification required.
        if self.request.user.is_authenticated:
            notifications.success(
                self.request,
                _("your report request has been successfully sent."),
                extra_tags="persistent")
            return super().form_valid(form)

        # Prepare and send a verification email.
        key = instance.key
        link = f"{settings.PROTOCOL}://{settings.DOMAIN}{reverse('verify-report', kwargs={'key': key})}"

        message = _(
            "in order reporting form to reach us, you need to follow the link given below."
            " if you are in mindset such as 'what the hell? i did not send such report', you"
            " can continue with your life as if nothing ever happened. the link:"
        )

        body = f'<p>{message}</p><a href="{link}">{link}</a>'

        try:
            email = EmailMessage(_("confirmation of reporting"), body,
                                 settings.FROM_EMAIL,
                                 [instance.reporter_email])
            email.content_subtype = "html"
            email.send()
            notifications.info(
                self.request,
                _("a confirmation link has been sent to your e-mail address."
                  " your report will reach us if you follow the given link."),
                extra_tags="persistent",
            )
        except (SMTPException, ConnectionRefusedError):
            return self.form_invalid(form)

        return super().form_valid(form)
Example #9
0
 def acquaintances_favorites(self, user):
     return (Entry.objects_published.values("topic").filter(
         favorited_by__in=user.following.all(),
         entryfavorites__date_created__gte=time_threshold(
             hours=24)).annotate(
                 title=Concat(F("topic__title"),
                              Value(" (#"),
                              F("pk"),
                              Value(")"),
                              output_field=CharField()),
                 slug=F("pk"),
                 latest=Max("entryfavorites__date_created"),
             ).order_by("-latest").values(*self.values))
Example #10
0
    def mutate(_root, info, topic, category, direction):
        topic = get_object_or_404(Topic, slug=topic)

        if not all((
                direction in (-1, 1),
                info.context.user.is_accessible,
                not info.context.user.is_novice,
                info.context.user.has_perm(
                    "dictionary.can_suggest_categories"),
                topic.allow_suggestions,
        )):
            raise ValueError(
                _("we couldn't handle your request. try again later."))

        suggestion_count_today = Suggestion.objects.filter(
            author=info.context.user,
            date_created__gte=time_threshold(hours=24)).count()

        if suggestion_count_today >= settings.SUGGESTIONS_PER_DAY:
            raise ValueError(
                _("you have used up all the suggestion claims you have today. try again later."
                  ))

        category = get_object_or_404(Category.objects_all, slug=category)
        kwargs = {
            "author": info.context.user,
            "topic": topic,
            "category": category
        }

        try:
            obj = Suggestion.objects.get(direction=direction, **kwargs)
            obj.delete()
        except Suggestion.DoesNotExist:
            obj, created = Suggestion.objects.update_or_create(
                defaults={"direction": direction}, **kwargs)

            kwargs.pop("category")
            if created and Suggestion.objects.filter(
                    **kwargs).count() > settings.SUGGESTIONS_PER_TOPIC:
                obj.delete()
                raise ValueError(
                    ngettext(
                        "you can only suggest %(count)d channel per topic.",
                        "you can only suggest %(count)d channels per topic.",
                        settings.SUGGESTIONS_PER_TOPIC,
                    ) % {"count": settings.SUGGESTIONS_PER_TOPIC})

        return SuggestCategory()
Example #11
0
 def __call__(self, request):
     if (request.user.is_authenticated and request.user.is_novice
             and request.user.application_status == "PN"
             and request.user.is_accessible):
         last_activity = request.user.last_activity
         if last_activity is None or last_activity < time_threshold(
                 hours=24):
             Author.objects.filter(id=request.user.id).update(
                 last_activity=timezone.now(),
                 queue_priority=F("queue_priority") + 1)
     # Code to be executed for each request before
     # the view (and later middleware) are called.
     response = self.get_response(request)
     # Code to be executed for each request/response after
     # the view is called.
     return response
Example #12
0
    def form_valid(self, form):
        previous_backup_exists = BackUp.objects.filter(
            author=self.request.user, date_created__gte=time_threshold(hours=24)
        ).exists()

        if previous_backup_exists:
            notifications.error(
                self.request, _("you have already requested a backup file today."), extra_tags="persistent"
            )
            return self.form_invalid(form)

        # Delete previous backup.
        for backup in BackUp.objects.filter(author=self.request.user):
            backup.delete()

        backup = form.save(commit=False)
        backup.author = self.request.user
        return super().form_valid(form)
Example #13
0
    def get(self, request, token):
        try:
            token_hashed = hashlib.blake2b(token.bytes).hexdigest()
            verification_object = UserVerification.objects.get(
                verification_token=token_hashed, expiration_date__gte=time_threshold(hours=24)
            )
        except UserVerification.DoesNotExist:
            return self.render_to_response()

        author = verification_object.author

        if not author.is_active:
            author.is_active = True
            author.save()
        else:
            author.email = verification_object.new_email
            author.save()

        self.success = True
        UserVerification.objects.filter(author=author).delete()
        return self.render_to_response()
Example #14
0
    def get(self, *args, **kwargs):
        key = kwargs.get("key")
        report = GeneralReport.objects.filter(
            is_verified=False,
            date_created__gte=time_threshold(hours=24),
            key=key).first()

        if report is not None:
            report.is_verified = True
            report.date_verified = timezone.now()
            report.save()
            notifications.success(
                self.request,
                _("your report request was successfully sent."),
                extra_tags="persistent")
        else:
            notifications.error(
                self.request,
                _("unfortunately your report request was not sent. the confirmation link is invalid;"
                  " please check the confirmation link. <strong>confirmation link is only valid for"
                  " 24 hours after it was sent.</strong>"),
                extra_tags="persistent",
            )
        return redirect(reverse("home"))
Example #15
0
def purge_images():
    """Delete expired images (Not bulk deleting so as to delete actual image files)."""
    expired = Image.objects.filter(is_deleted=True,
                                   date_created__lte=time_threshold(hours=120))
    for image in expired:
        image.delete()
Example #16
0
def purge_reports():
    """Delete expired reports."""
    GeneralReport.objects.filter(
        is_verified=False,
        date_created__lte=time_threshold(hours=24)).delete()
Example #17
0
def purge_verifications():
    """Delete expired verifications."""
    UserVerification.objects.filter(expiration_date__lte=time_threshold(
        hours=24)).delete()
Example #18
0
 def email_confirmed(self):
     return not self.userverification_set.filter(
         expiration_date__gte=time_threshold(hours=24)).exists()
Example #19
0
 def get_entry_count_by_threshold(self, **timedelta_kwargs):
     return (self.entry_set(manager="objects_published").filter(
         date_created__gte=time_threshold(**timedelta_kwargs)).count())
Example #20
0
 def annotate_activity(queryset):
     return queryset.annotate(is_active_today=Case(
         When(Q(last_activity__gte=time_threshold(hours=24)), then=True),
         default=False,
         output_field=BooleanField(),
     ))
Example #21
0
    def followups(self, user):  # noqa
        """
        Author: Emre Tuna (https://github.com/emretuna01) <*****@*****.**>

        todo: If you can convert this to native orm or create a queryset that will result in same data, please do.
        Update: An ORM implementation was made, but it was too slow compared to
        this solution. See: https://gist.github.com/realsuayip/9d2c5365cbe6e43d1fe282a556d0f6d5

        I tried to make the sql easy-to-read, but failed as there were many
        aliases that I couldn't find meaningful names. They are named arbitrarily,
        if you think you can make it more readable, please do.

        Query Description: List topics on condition that the user has entries in
        (written in last 24 hours), along with count of entries that were
        written after the user's latest entry on that topic.
        """

        pk = user.pk
        threshold = time_threshold(hours=120)  # in 5 days

        with connection.cursor() as cursor:
            cursor.execute(
                """
            select
              s.title,
              s.slug,
              s.count
            from
              (
                select
                  tt.title,
                  tt.slug,
                  e.count,
                  e.max_id
                from
                  (
                    select
                      z.topic_id,
                      count(
                        case
                        when z.id > k.max_id
                        and not z.is_draft
                        and z.author_id not in (
                          select to_author_id
                          from dictionary_author_blocked
                          where from_author_id = k.sender_id
                        )
                        and case
                            when not k.sender_is_novice then
                            not (select is_novice from dictionary_author where id = z.author_id)
                            else true end
                        then z.id end
                      ) as count,
                      k.max_id
                    from
                      dictionary_entry z
                      inner join (
                        select
                          topic_id,
                          max(de.id) as max_id,
                          de.author_id as sender_id,
                          (select is_novice from dictionary_author where id = de.author_id) as sender_is_novice
                        from
                          dictionary_entry de
                        where
                          de.date_created >= %s
                          and de.author_id = %s
                        group by
                          author_id,
                          topic_id
                      ) k on k.topic_id = z.topic_id
                    group by
                      z.topic_id,
                      k.max_id
                  ) e
                  inner join dictionary_topic tt on tt.id = e.topic_id
              ) s
            where
              s.count > 0
            order by
              s.max_id desc
            """,
                [threshold, pk],
            )

            columns = [col[0] for col in cursor.description]
            return [dict(zip(columns, row)) for row in cursor.fetchall()]
 def novices(self):
     return self.topic.entries.filter(author__is_novice=True, date_created__gte=time_threshold(hours=24))
Example #23
0
 def day_filter(self):
     return {"entries__date_created__gte": time_threshold(hours=24)}
 def today(self):
     return self.topic.entries.filter(date_created__gte=time_threshold(hours=24))
Example #25
0
 def counter(hours):
     return Count("entries", filter=Q(entries__date_created__gte=time_threshold(hours=hours)))
Example #26
0
 def weeklygoods(self):
     return self.entries.filter(vote_rate__gt=0, date_created__gte=time_threshold(days=7))