Spamas

S
  • 29 Grd '20

Kovoju su spamu, kol kas rankiniu būdu pratryniau didžiąją dalį spamo, bet taip pat planuoju prisėsti ir padaryti apsaugą registracijos metu, kad spameriai iš vis negalėtu užsiregistruoti.

S
  • 29 Grd '20

Praktiškai ištryniau visus spam userius, viso buvo apie 6000 spam useriu. Juos tryniau taip:

from django.contrib.auth.models import User
from textwrap import wrap

lines = []
for user in User.objects.order_by('-date_joined')[:1000]:
    lines += ['', f"{user.pk:>6},  # {user.username:<20} {user.email:<40}"]
    last_comment = getattr(user.st_comments.order_by('-date').first(), 'comment', None)
    if last_comment:
        lines += [''] + wrap(
            last_comment,
            initial_indent=(' ' * 8) + ' # ',
            subsequent_indent=(' ' * 8) + ' # ',
            max_lines=8,
            width=72,
        )

lines = '\n'.join(lines)
print(f"\nUser.objects.filter(pk__in=[\n{lines}\n]).delete()\n\n")

Šis skriptas generuoja paskutinių 1000 užsiregistravusių naudotojų naudotojo vardus, el. pašto adresą ir paskutinį postą. Tada tą sąrašą peržiūriu ir palieku tik spam naudotojus, kuriuos vėliau ištrinu.

Kadangi tryniau tiesiogiai, tai liko neteisingi komentarų skaičiai ir kiti dalykai. Reikės šitą kaip nors sutaisyti.

Kitas dalykas, kad spam useriai toliau sėkmingai registruojasi, reikia stiprinti apsaugą, kad jie negalėtų taip lengvai užsiregistruoti.

Pranešiau apie šią problemą ir Spirit kūrėjams: https://github.com/nitely/S...

S
  • 29 Grd '20

Į registracijos formą įdėjau reCaptcha, tikiuosi tai padės apsisaugoti nuo spam atakos.

https://github.com/sirex/ub...

S
  • 29 Grd '20

Panašu, kad komentarų skaičių ir paskutinio aktyvumo datas pavyko sutaisyti, tokios užklausos pagalba:

from spirit.topic.models import Topic
from spirit.comment.models import Comment
from django.db.models import Case, When, Value, Exists, OuterRef, Subquery, Count, Max


Topic.objects.update(
    comment_count=Case(
        When(
            Exists(
                Comment.objects.
                filter(
                    topic_id=OuterRef('id'),
                    is_removed=False,
                    action=Comment.COMMENT,
                )
            ),
            then=Subquery(
                Comment.objects.
                filter(
                    topic_id=OuterRef('id'),
                    is_removed=False,
                    action=Comment.COMMENT,
                ).
                values('topic_id').
                order_by('topic_id').
                annotate(comment_count=Count('*')).
                values('comment_count')[:1]
            ),
        ),
        default=Value(0),
    ),
    last_active=Subquery(
        Comment.objects.
        filter(topic_id=OuterRef('id')).
        values('topic_id').
        order_by('topic_id').
        annotate(last_active=Max('date')).
        values('last_active')[:1]
    ),
)
S
  • 29 Grd '20

Pataisiau paskutinę problemą, kurią pastebėjau, nusimušusių puslapių numerius, lankytose temose. Pataisau naudodamas tokią užklausą:

from spirit.comment.bookmark.models import CommentBookmark
from django.db.models import Case, When, OuterRef, Subquery, Count, F, PositiveIntegerField


CommentBookmark.objects.update(
    comment_number=Subquery(
        CommentBookmark.objects.
        filter(id=OuterRef('id')).
        values('user_id', 'topic_id', 'comment_number').
        order_by('user_id', 'topic_id', 'comment_number').
        annotate(
            total_comments=Count('topic__comment'),
        ).
        annotate(
            comment_number_=Case(
                When(
                    comment_number__gt=F('total_comments'),
                    then=F('total_comments'),
                ),
                default=F('comment_number'),
                output_field=PositiveIntegerField(),
            ),
        ).
        values('comment_number_')[:1],
    ),
)