2022-11-15 09:19:08 +00:00
import random
import time
from urllib . parse import quote
2023-03-04 18:33:10 +00:00
from sqlalchemy . sql import func
2022-11-15 09:19:08 +00:00
import gevent
import requests
2024-02-01 17:30:04 +00:00
import math
2022-06-15 19:33:21 +00:00
from flask import g
2023-03-04 18:33:10 +00:00
2023-06-23 16:49:23 +00:00
from files . classes . reports import Report
2022-11-15 09:19:08 +00:00
from files . classes . mod_logs import ModAction
from files . classes . notifications import Notification
2023-06-07 23:26:32 +00:00
from files . classes . polls import CommentOption , PostOption
2023-03-25 22:06:44 +00:00
from files . classes . award import AwardRelationship
2024-02-16 11:44:25 +00:00
from files . classes . hole_relationship import Exile
2022-11-15 09:19:08 +00:00
2023-02-24 06:48:30 +00:00
from files . helpers . alerts import send_repeatable_notification , push_notif
2022-12-11 23:44:34 +00:00
from files . helpers . config . const import *
2023-03-25 22:06:44 +00:00
from files . helpers . config . awards import AWARDS
2022-11-15 09:19:08 +00:00
from files . helpers . const_stateful import *
2022-07-08 11:44:17 +00:00
from files . helpers . get import *
2022-11-30 18:09:31 +00:00
from files . helpers . logging import log_file
2022-07-08 11:44:17 +00:00
from files . helpers . sanitize import *
2022-11-30 17:37:35 +00:00
from files . helpers . settings import get_setting
2022-11-07 00:08:50 +00:00
from files . helpers . slots import check_slots_command
2024-02-12 16:43:34 +00:00
from files . helpers . useractions import badge_grant
2022-07-08 11:44:17 +00:00
2023-07-25 16:42:16 +00:00
from files . routes . routehelpers import check_for_alts
2022-11-15 09:19:08 +00:00
def _archiveorg ( url ) :
2022-11-21 23:52:21 +00:00
try :
2023-10-24 15:15:49 +00:00
requests . post ( ' https://ghostarchive.org/archive2 ' , data = { " archive " : url } , headers = HEADERS , timeout = 10 )
2022-11-21 23:52:21 +00:00
except : pass
try :
2023-10-24 15:15:49 +00:00
requests . get ( f ' https://web.archive.org/save/ { url } ' , headers = HEADERS , timeout = 10 )
2022-09-03 14:24:16 +00:00
except : pass
2022-10-30 22:39:37 +00:00
2022-09-03 03:10:14 +00:00
2023-01-01 11:36:20 +00:00
def archive_url ( url ) :
2023-08-20 16:24:26 +00:00
gevent . spawn ( _archiveorg , url )
2022-09-03 03:10:14 +00:00
if url . startswith ( ' https://instagram.com/ ' ) :
2023-06-24 13:29:28 +00:00
url = url . replace ( ' https://instagram.com/ ' , ' https://imginn.com/ ' )
2023-08-20 16:24:26 +00:00
gevent . spawn ( _archiveorg , url )
2022-09-03 03:10:14 +00:00
2023-03-18 10:59:30 +00:00
def snappy_report ( post , reason ) :
2023-06-23 16:49:23 +00:00
report = Report ( post_id = post . id , user_id = SNAPPY_ID , reason = reason )
g . db . add ( report )
2024-02-20 00:00:21 +00:00
message = f ' @Snappy reported { post . textlink } ) \n \n > { reason } '
2023-03-18 10:59:30 +00:00
send_repeatable_notification ( post . author_id , message )
2023-07-30 00:42:06 +00:00
def execute_snappy ( post , v ) :
2023-10-07 17:55:50 +00:00
if post . hole and g . db . query ( Exile . user_id ) . filter_by ( user_id = SNAPPY_ID , hole = post . hole ) . one_or_none ( ) :
2023-07-25 17:49:56 +00:00
return
2022-12-19 16:19:33 +00:00
ghost = post . ghost
2022-07-08 11:44:17 +00:00
snappy = get_account ( SNAPPY_ID )
2023-08-18 02:21:56 +00:00
ping_cost = 0
2023-07-17 17:24:22 +00:00
2023-07-22 17:44:21 +00:00
post_ping_group_count = len ( list ( group_mention_regex . finditer ( post . body ) ) )
2023-07-29 18:31:40 +00:00
2024-03-05 00:17:52 +00:00
if SITE_NAME == ' rDrama ' and ( v . post_count < = 3 or v . new_user ) :
2024-02-29 14:41:31 +00:00
body = " Hey, I saw that you just joined rdrama and a group of people who hate me are trying to smear my name by calling me a date male feminist. I just wanted to let you know that it ' s not true. If you want all the receipts proving it they ' re right here. \n The TL;DR is that I hooked up with one of the hot girls on rdrama, and since I was twice her age, a lot of the guys here who wanted to bang her got jealous and assumed that the only way I could have managed that was by raping her, even though she herself said both before and afterwards that it was all completely consensual. So now that you ' re the new hot girl on rdrama, I guess they think that I ' m going to somehow seduce you into flying all the way across the country (or some crazy shit like that) to hook up with me and they ' re trying to talk shit about me to make sure that doesnt happen. I don ' t understand it either, but I just wanted to let you know that I ' m a nice guy and I hope you ' ll look at the evidence and make up your own mind instead of listening to all the jealous haters. \n Anyway, with that little intro out of the way, welcome to rdrama! The culture ' s a little rough here and you ' re probably going to get tons of requests to •show boobsU but if you talk to some of the women here first before engaging with all the creepy dudes, they ' ll give you some good advice to avoid stalkers and predators. Or (If you haven ' t been scared off by the rumor mill) you ' re welcome to ask me and I ' m happy to help. \n Just out of curiosity, how did you find this place? "
elif post . hole and post . hole_obj . snappy_quotes :
2024-02-11 10:26:54 +00:00
quotes = post . hole_obj . snappy_quotes . split ( " [para] " )
body = random . choice ( quotes ) . strip ( )
elif SITE_NAME == ' WPD ' and ( ' killing myself ' in post . title . lower ( ) or ( post . hole != ' suicide ' and ' suicide ' in post . title . lower ( ) ) ) :
2023-10-15 15:13:22 +00:00
body = " https://i.watchpeopledie.tv/images/1697382435294321.webp "
elif post_ping_group_count > 3 :
2023-07-22 17:44:21 +00:00
body = " Unnecessary and uncalled for ping :marseydownvotemad: two more strikes and you ' re getting blocked + megadownvoted buddy, don ' t test your luck "
2023-07-22 21:56:47 +00:00
vote = Vote ( user_id = SNAPPY_ID ,
vote_type = - 1 ,
post_id = post . id ,
real = True
)
g . db . add ( vote )
post . downvotes + = 1
2023-07-22 17:44:21 +00:00
elif v . id == CARP_ID :
2023-07-25 14:21:59 +00:00
if random . random ( ) < 0.08 :
2024-01-15 02:21:58 +00:00
body = random . choice ( ( " i love you carp " , " https://i.rdrama.net/images/16614707883108485.webp " , " https://i.rdrama.net/images/1636916964YyM.webp " , " https://youtube.com/watch?v=zRbQHTdsjuY " , " https://i.rdrama.net/images/1696250281381682.webp " , " https://i.rdrama.net/images/16975678508317988.webp " , " https://i.rdrama.net/images/170526627808132.webp " , " https://i.rdrama.net/images/17052853054732056.webp " ) )
2023-05-01 18:41:55 +00:00
elif IS_DKD ( ) :
body = " :#donkeykongfuckoffcarp: "
2023-09-28 23:58:09 +00:00
elif IS_HOMOWEEN ( ) :
body = " F̵̽̉U̷̓̕C̵̟̍K̴̾̍ ̵́̒O̶͐̇F̷͗̐F̴͛̄ ̸̆͠CARP "
2023-10-17 18:45:45 +00:00
elif IS_FISTMAS ( ) :
body = " Merry Christmas Carp :marseychristmasgift2: "
2023-05-01 18:41:55 +00:00
else :
2024-01-17 04:27:30 +00:00
body = " :#carpwavelove: "
2023-08-02 04:18:25 +00:00
elif v . id == AEVANN_ID :
2023-10-01 14:46:34 +00:00
body = " https://i.rdrama.net/images/16909380805064178.webp "
2023-12-15 01:55:56 +00:00
elif SITE == ' rdrama.net ' and v . id == 253 :
2023-10-01 14:46:34 +00:00
body = " https://i.rdrama.net/images/16961715452780113.webp "
2023-12-15 01:55:56 +00:00
elif SITE == ' rdrama.net ' and v . id == 8094 :
body = " https://i.rdrama.net/images/17025988883967621.webp "
2024-01-12 05:50:31 +00:00
elif SITE == ' rdrama.net ' and v . id == 5214 :
body = random . choice ( ( " https://rdrama.net/audio/1704983217764354.mp3 " , " Dear Chiobu: \n \n We are not accepting non-US residents because of difficulty of payment and difficulty of enforcing our Confidentiality Agreement internationally. Additionally, you seem to have opinions incompatible with ours, namely your opinions **Towards the Chinese** and **Towards Transgender Individuals**. We thank you for your interest. " ) )
2024-02-07 23:22:02 +00:00
elif SITE == ' rdrama.net ' and v . id == 9493 :
body = " https://i.rdrama.net/images/16973719400351799.webp "
2022-07-08 11:44:17 +00:00
else :
2023-04-25 17:02:56 +00:00
if IS_DKD ( ) :
2023-05-02 13:49:28 +00:00
SNAPPY_CHOICES = SNAPPY_KONGS
2023-09-28 23:58:09 +00:00
elif IS_FISTMAS ( ) :
SNAPPY_CHOICES = SNAPPY_QUOTES_FISTMAS
elif IS_HOMOWEEN ( ) :
SNAPPY_CHOICES = SNAPPY_QUOTES_HOMOWEEN
2023-05-02 13:49:28 +00:00
elif SNAPPY_MARSEYS and SNAPPY_QUOTES :
2023-09-28 23:58:09 +00:00
if random . random ( ) > 0.5 :
2022-12-19 01:20:14 +00:00
SNAPPY_CHOICES = SNAPPY_QUOTES
2023-01-01 11:36:20 +00:00
else :
2023-05-02 13:49:28 +00:00
SNAPPY_CHOICES = SNAPPY_MARSEYS
elif SNAPPY_MARSEYS :
SNAPPY_CHOICES = SNAPPY_MARSEYS
elif SNAPPY_QUOTES :
SNAPPY_CHOICES = SNAPPY_QUOTES
else :
SNAPPY_CHOICES = [ " " ]
2022-08-15 05:10:15 +00:00
body = random . choice ( SNAPPY_CHOICES ) . strip ( )
2023-10-26 16:40:36 +00:00
body = body . replace ( ' % OP % ' , f ' @ { post . author_name } ' )
2022-12-13 16:36:16 +00:00
if body . startswith ( ' ▼ ' ) or body . startswith ( ' :#marseydownvote ' ) :
2023-01-28 12:01:18 +00:00
if body . startswith ( ' ▼ ' ) : body = body [ 1 : ]
2022-07-08 11:44:17 +00:00
vote = Vote ( user_id = SNAPPY_ID ,
vote_type = - 1 ,
2023-06-07 23:26:32 +00:00
post_id = post . id ,
2022-07-08 11:44:17 +00:00
real = True
)
2023-03-16 06:27:58 +00:00
g . db . add ( vote )
2022-07-08 11:44:17 +00:00
post . downvotes + = 1
if body . startswith ( ' OP is a Trump supporter ' ) :
2023-03-18 10:59:30 +00:00
snappy_report ( post , ' Trump supporter ' )
2022-07-08 11:44:17 +00:00
elif body . startswith ( ' You had your chance. Downvoted and reported ' ) :
2023-03-18 10:59:30 +00:00
snappy_report ( post , ' Retard ' )
2022-11-22 21:45:50 +00:00
elif body . startswith ( ' ▲ ' ) or body . startswith ( ' :#marseyupvote ' ) :
2023-01-28 12:01:18 +00:00
if body . startswith ( ' ▲ ' ) : body = body [ 1 : ]
2022-07-08 11:44:17 +00:00
vote = Vote ( user_id = SNAPPY_ID ,
vote_type = 1 ,
2023-06-07 23:26:32 +00:00
post_id = post . id ,
2022-07-08 11:44:17 +00:00
real = True
)
2023-03-16 06:27:58 +00:00
g . db . add ( vote )
2022-07-08 11:44:17 +00:00
post . upvotes + = 1
2023-10-27 16:04:45 +00:00
elif ' :#marseyghost ' in body :
2022-12-19 16:19:33 +00:00
ghost = True
2023-03-04 18:33:10 +00:00
elif body == ' !slots ' :
body = f ' !slots { snappy . coins } '
elif body == ' !pinggroup ' :
2024-01-03 22:09:23 +00:00
group = g . db . query ( Group ) . filter ( Group . name != ' focusgroup ' ) . order_by ( func . random ( ) ) . first ( )
2023-03-04 18:33:10 +00:00
2023-08-20 16:36:13 +00:00
cost = len ( group . member_ids ) * 5
2023-03-04 18:33:10 +00:00
snappy . charge_account ( ' coins ' , cost )
body = f ' ! { group . name } '
2023-08-01 07:38:58 +00:00
2023-07-17 17:24:22 +00:00
ping_cost = cost
2023-03-25 22:08:36 +00:00
elif body . startswith ( ' :#marseyglow ' ) :
2023-03-25 22:06:44 +00:00
award_object = AwardRelationship (
user_id = snappy . id ,
kind = " glowie " ,
2023-06-07 23:26:32 +00:00
post_id = post . id ,
2024-02-03 03:18:47 +00:00
awarded_utc = time . time ( ) ,
2023-03-25 22:06:44 +00:00
)
g . db . add ( award_object )
2024-02-12 16:35:39 +00:00
awarded_coins = int ( AWARDS [ " glowie " ] [ ' price ' ] * COSMETIC_AWARD_COIN_AWARD_PCT )
2024-03-02 17:24:07 +00:00
post . author . pay_account ( ' coins ' , awarded_coins , f " Glowie award on { post . textlink } " )
2024-02-12 16:35:39 +00:00
2024-02-20 00:00:21 +00:00
msg = f " @Snappy has given { post . textlink } the Glowie Award and you have received { awarded_coins } coins as a result! "
2023-03-25 22:06:44 +00:00
send_repeatable_notification ( post . author . id , msg )
2024-02-12 16:43:34 +00:00
elif body . startswith ( " You ' re a chud, CHUD I tell you " ) :
award_object = AwardRelationship (
user_id = snappy . id ,
kind = " chud " ,
post_id = post . id ,
awarded_utc = time . time ( ) ,
note = " Trans lives matter " ,
)
g . db . add ( award_object )
2024-02-20 00:00:21 +00:00
msg = f " @Snappy has given { post . textlink } the Chud Award \n \n **You now have to say this phrase in all posts and comments you make for 24 hours:** \n \n > Trans lives matter "
2024-02-12 16:43:34 +00:00
send_repeatable_notification ( post . author . id , msg )
2023-03-04 18:33:10 +00:00
2024-02-12 16:43:34 +00:00
if v . chud != 1 :
if v . chud and time . time ( ) < v . chud : v . chud + = 86400
else : v . chud = int ( time . time ( ) ) + 86400
v . chud_phrase = ' trans lives matter '
badge_grant ( user = v , badge_id = 58 )
post . chudded = True
complies_with_chud ( post )
2022-07-08 11:44:17 +00:00
body + = " \n \n "
captured = [ ]
2024-03-05 00:14:52 +00:00
if post . url :
2024-03-01 23:29:51 +00:00
captured . append ( ( post . url , post . url ) )
2022-07-08 11:44:17 +00:00
2024-03-01 23:29:51 +00:00
for i in list ( snappy_url_regex . finditer ( post . body_html . replace ( ' data-src= " ' , ' src= " ' ) ) ) :
2022-07-11 17:45:07 +00:00
href = i . group ( 1 )
if href in [ x [ 0 ] for x in captured ] : continue
2022-07-08 11:44:17 +00:00
title = i . group ( 2 )
2022-07-11 17:45:07 +00:00
captured . append ( ( href , title ) )
2024-03-05 20:40:25 +00:00
captured2 = [ ]
2024-03-05 00:14:52 +00:00
for href , title in captured :
2024-03-05 20:40:25 +00:00
if not ( href . startswith ( ' / ' ) or href . startswith ( f ' { SITE_FULL } / ' ) or href . startswith ( f ' { SITE_FULL_IMAGES } / ' ) ) :
captured2 . append ( ( href , title ) )
2024-03-05 00:14:52 +00:00
2024-03-05 20:40:25 +00:00
if captured2 :
2024-03-01 23:29:51 +00:00
body + = " **Snapshots:** \n \n "
2022-07-11 17:45:07 +00:00
2024-03-05 20:40:25 +00:00
for href , title in captured2 :
2022-07-08 11:44:17 +00:00
if f ' **[ { title } ]( { href } )**: \n \n ' not in body :
addition = f ' **[ { title } ]( { href } )**: \n \n '
2024-03-01 23:29:51 +00:00
if href . startswith ( ' https://old.reddit.com/r/ ' ) :
rev = href . replace ( ' https://old.reddit.com/ ' , ' ' )
addition + = f ' * [undelete.pullpush.io](https://undelete.pullpush.io/ { rev } ) \n \n '
elif href . startswith ( ' https://old.reddit.com/user/ ' ) :
rev = href . replace ( ' https://old.reddit.com/user/ ' , ' ' )
addition + = f " * [search-new.pullpush.io](https://search-new.pullpush.io/?author= { rev } &type=submission) \n \n "
elif href . startswith ( ' https://boards.4chan.org/ ' ) :
rev = href . replace ( ' https://boards.4chan.org/ ' , ' ' )
addition + = f ' * [archived.moe](https://archived.moe/ { rev } ) \n \n '
elif href . startswith ( ' https://scored.co/ ' ) and href != ' https://scored.co/ ' :
rev = href . replace ( ' https://scored.co/ ' , ' ' )
addition + = f ' * [unscored.arete.network](https://unscored.arete.network/ { rev } ) \n \n '
addition + = f ' * [ghostarchive.org](https://ghostarchive.org/search?term= { quote ( href ) } ) \n \n '
addition + = f ' * [archive.org](https://web.archive.org/ { href } ) \n \n '
addition + = f ' * [archive.ph](https://archive.ph/?url= { quote ( href ) } &run=1) (click to archive) \n \n '
2022-10-14 13:19:47 +00:00
if len ( f ' { body } { addition } ' ) > COMMENT_BODY_LENGTH_LIMIT : break
2022-07-08 11:44:17 +00:00
body + = addition
2022-09-03 03:10:14 +00:00
archive_url ( href )
2022-08-15 17:45:43 +00:00
2023-07-30 06:20:02 +00:00
body = body [ : COMMENT_BODY_LENGTH_LIMIT ] . strip ( )
2023-06-22 12:52:31 +00:00
body_html = sanitize ( body , snappy = True , showmore = True )
2022-07-08 11:44:17 +00:00
2022-07-09 10:50:53 +00:00
if len ( body_html ) == 0 :
return
2022-10-14 13:19:47 +00:00
if len ( body_html ) < COMMENT_BODY_HTML_LENGTH_LIMIT :
2022-07-08 11:44:17 +00:00
c = Comment ( author_id = SNAPPY_ID ,
2024-02-16 12:11:08 +00:00
distinguished = True ,
2023-06-23 13:46:42 +00:00
parent_post = post . id ,
2022-07-08 11:44:17 +00:00
level = 1 ,
2023-10-05 10:19:50 +00:00
nsfw = False ,
2022-07-08 11:44:17 +00:00
is_bot = True ,
app_id = None ,
body = body ,
body_html = body_html ,
2023-08-18 02:21:56 +00:00
ghost = ghost ,
ping_cost = ping_cost ,
2022-07-08 11:44:17 +00:00
)
2023-03-16 06:27:58 +00:00
g . db . add ( c )
2022-07-08 11:44:17 +00:00
2022-12-09 05:55:18 +00:00
check_slots_command ( c , v , snappy )
2022-11-07 00:08:50 +00:00
2022-07-08 11:44:17 +00:00
snappy . comment_count + = 1
2022-11-20 10:50:02 +00:00
snappy . pay_account ( ' coins ' , 1 )
2023-03-16 06:27:58 +00:00
g . db . add ( snappy )
2022-07-08 11:44:17 +00:00
2022-07-18 05:10:01 +00:00
if FEATURES [ ' PINS ' ] and ( body . startswith ( ' :#marseypin: ' ) or body . startswith ( ' :#marseypin2: ' ) ) :
2024-02-18 15:29:53 +00:00
post . pinned = " Snappy "
post . pinned_utc = int ( time . time ( ) ) + 3600
2022-07-08 11:44:17 +00:00
2022-10-01 17:37:59 +00:00
elif SITE_NAME == ' rDrama ' and body . startswith ( ' :#marseyban: ' ) :
2022-10-01 17:37:25 +00:00
days = 0.01
reason = f ' <a href= " /post/ { post . id } " >/post/ { post . id } </a> '
v . ban ( admin = snappy , reason = reason , days = days )
text = f " @Snappy has banned you for ** { days } ** days for the following reason: \n \n > { reason } "
send_repeatable_notification ( v . id , text )
duration = f " for { days } days "
2023-08-23 21:57:39 +00:00
ma = ModAction (
2022-10-01 17:37:25 +00:00
kind = " ban_user " ,
user_id = snappy . id ,
target_user_id = v . id ,
2024-03-02 21:01:29 +00:00
_note = f ' duration: { duration } , reason: " { reason } " '
2022-10-01 17:37:25 +00:00
)
2023-03-16 06:27:58 +00:00
g . db . add ( ma )
2022-10-01 17:37:25 +00:00
post . bannedfor = f ' { duration } by @Snappy '
2023-03-16 06:27:58 +00:00
g . db . flush ( )
2022-07-08 11:44:17 +00:00
2023-08-18 02:21:56 +00:00
if c . ping_cost :
for x in group . member_ids :
n = Notification ( comment_id = c . id , user_id = x )
g . db . add ( n )
push_notif ( { x } , f ' New mention of you by @Snappy ' , c . body , c )
2023-04-24 13:47:55 +00:00
2022-07-08 11:44:17 +00:00
c . top_comment_id = c . id
post . comment_count + = 1
2022-07-09 10:50:53 +00:00
post . replies = [ c ]
2022-10-09 13:28:18 +00:00
2023-10-06 13:16:07 +00:00
def execute_zozbot ( c , level , post , v ) :
2024-02-21 20:29:54 +00:00
if not ZOZBOT_ID : return
2023-10-06 13:16:55 +00:00
2023-10-06 17:09:40 +00:00
if random . random ( ) > = 0.001 : return
2023-10-06 13:16:55 +00:00
2023-10-06 13:16:07 +00:00
posting_to_post = isinstance ( post , Post )
2023-10-06 17:09:40 +00:00
2023-10-07 17:55:50 +00:00
if posting_to_post and post . hole and g . db . query ( Exile . user_id ) . filter_by ( user_id = ZOZBOT_ID , hole = post . hole ) . one_or_none ( ) :
2023-10-06 17:09:40 +00:00
return
2022-10-09 13:28:18 +00:00
c2 = Comment ( author_id = ZOZBOT_ID ,
2023-10-06 13:16:07 +00:00
parent_post = post . id if posting_to_post else None ,
wall_user_id = post . id if not posting_to_post else None ,
2022-10-09 13:29:58 +00:00
parent_comment_id = c . id ,
level = level + 1 ,
is_bot = True ,
body = " zoz " ,
2024-02-18 23:46:12 +00:00
body_html = ' <p>zoz</p> ' ,
2022-10-09 13:29:58 +00:00
top_comment_id = c . top_comment_id ,
ghost = c . ghost ,
2024-02-16 12:11:08 +00:00
distinguished = True
2022-10-09 13:29:58 +00:00
)
2022-10-09 13:28:18 +00:00
2023-03-16 06:27:58 +00:00
g . db . add ( c2 )
g . db . flush ( )
2022-10-09 13:28:18 +00:00
n = Notification ( comment_id = c2 . id , user_id = v . id )
2023-03-16 06:27:58 +00:00
g . db . add ( n )
2022-10-09 13:28:18 +00:00
c3 = Comment ( author_id = ZOZBOT_ID ,
2023-10-06 13:16:07 +00:00
parent_post = post . id if posting_to_post else None ,
wall_user_id = post . id if not posting_to_post else None ,
2022-10-09 13:28:18 +00:00
parent_comment_id = c2 . id ,
level = level + 2 ,
is_bot = True ,
body = " zle " ,
2024-02-18 23:46:12 +00:00
body_html = ' <p>zle</p> ' ,
2022-10-09 13:28:18 +00:00
top_comment_id = c . top_comment_id ,
ghost = c . ghost ,
2024-02-16 12:11:08 +00:00
distinguished = True
2022-10-09 13:28:18 +00:00
)
2023-03-16 06:27:58 +00:00
g . db . add ( c3 )
g . db . flush ( )
2022-11-11 08:45:28 +00:00
2022-10-09 13:28:18 +00:00
c4 = Comment ( author_id = ZOZBOT_ID ,
2023-10-06 13:16:07 +00:00
parent_post = post . id if posting_to_post else None ,
wall_user_id = post . id if not posting_to_post else None ,
2022-10-09 13:28:18 +00:00
parent_comment_id = c3 . id ,
level = level + 3 ,
is_bot = True ,
body = " zozzle " ,
2024-02-18 23:46:12 +00:00
body_html = ' <p>zozzle</p> ' ,
2022-10-09 13:28:18 +00:00
top_comment_id = c . top_comment_id ,
ghost = c . ghost ,
2024-02-16 12:11:08 +00:00
distinguished = True
2022-10-09 13:28:18 +00:00
)
2023-03-16 06:27:58 +00:00
g . db . add ( c4 )
2022-10-09 13:28:18 +00:00
zozbot = get_account ( ZOZBOT_ID )
zozbot . comment_count + = 3
2022-11-20 10:50:02 +00:00
zozbot . pay_account ( ' coins ' , 1 )
2023-03-16 06:27:58 +00:00
g . db . add ( zozbot )
2022-10-09 13:28:18 +00:00
2023-06-23 13:46:42 +00:00
if posting_to_post :
2023-10-06 13:16:07 +00:00
post . comment_count + = 3
g . db . add ( post )
2023-02-18 21:59:17 +00:00
2023-02-27 13:35:53 +00:00
push_notif ( { v . id } , f ' New reply by @ { c2 . author_name } ' , " zoz " , c2 )
2023-02-18 21:59:17 +00:00
2023-10-06 13:16:07 +00:00
def execute_longpostbot ( c , level , body , body_html , post , v ) :
2024-02-21 20:30:09 +00:00
if not LONGPOSTBOT_ID : return
2023-10-06 13:16:55 +00:00
2022-10-09 16:40:20 +00:00
if not len ( c . body . split ( ) ) > = 200 : return
2023-10-06 17:09:40 +00:00
2022-10-09 20:13:55 +00:00
if " </blockquote> " in body_html : return
2023-10-06 17:09:40 +00:00
posting_to_post = isinstance ( post , Post )
2023-10-07 17:55:50 +00:00
if posting_to_post and post . hole and g . db . query ( Exile . user_id ) . filter_by ( user_id = LONGPOSTBOT_ID , hole = post . hole ) . one_or_none ( ) :
2023-10-06 17:09:40 +00:00
return
2023-08-10 12:04:20 +00:00
body = random . choice ( LONGPOSTBOT_REPLIES )
2022-10-09 13:28:18 +00:00
if body . startswith ( ' ▼ ' ) :
body = body [ 1 : ]
vote = CommentVote ( user_id = LONGPOSTBOT_ID ,
vote_type = - 1 ,
comment_id = c . id ,
real = True
)
2023-03-16 06:27:58 +00:00
g . db . add ( vote )
2022-10-09 13:28:18 +00:00
c . downvotes = 1
2023-02-25 16:09:20 +00:00
body_html = sanitize ( body )
2022-10-09 13:28:18 +00:00
c2 = Comment ( author_id = LONGPOSTBOT_ID ,
2023-10-06 13:16:07 +00:00
parent_post = post . id if posting_to_post else None ,
wall_user_id = post . id if not posting_to_post else None ,
2022-10-09 13:28:18 +00:00
parent_comment_id = c . id ,
level = level + 1 ,
is_bot = True ,
body = body ,
2023-02-25 16:09:20 +00:00
body_html = body_html ,
2022-10-09 13:28:18 +00:00
top_comment_id = c . top_comment_id ,
ghost = c . ghost
)
2023-03-16 06:27:58 +00:00
g . db . add ( c2 )
2022-10-09 13:28:18 +00:00
longpostbot = get_account ( LONGPOSTBOT_ID )
longpostbot . comment_count + = 1
2022-11-20 10:50:02 +00:00
longpostbot . pay_account ( ' coins ' , 1 )
2023-03-16 06:27:58 +00:00
g . db . add ( longpostbot )
g . db . flush ( )
2022-10-09 13:28:18 +00:00
n = Notification ( comment_id = c2 . id , user_id = v . id )
2023-03-16 06:27:58 +00:00
g . db . add ( n )
2022-10-09 13:49:08 +00:00
2023-06-23 13:46:42 +00:00
if posting_to_post :
2023-10-06 13:16:07 +00:00
post . comment_count + = 1
g . db . add ( post )
2023-02-18 21:59:17 +00:00
2023-02-27 13:35:53 +00:00
push_notif ( { v . id } , f ' New reply by @ { c2 . author_name } ' , c2 . body , c2 )
2023-02-18 21:59:17 +00:00
2023-07-01 15:25:23 +00:00
def tempban_for_spam ( v ) :
text = " Your account has been banned for **1 day** for the following reason: \n \n > Too much spam! "
send_repeatable_notification ( v . id , text )
v . ban ( reason = " Spam " , days = 1 )
2023-08-23 21:57:39 +00:00
ma = ModAction (
2023-07-01 15:25:23 +00:00
kind = " ban_user " ,
user_id = AUTOJANNY_ID ,
target_user_id = v . id ,
2024-03-02 21:01:29 +00:00
_note = f ' duration: for 1 day, reason: " Spam " '
2023-07-01 15:25:23 +00:00
)
g . db . add ( ma )
2023-06-23 13:46:42 +00:00
def execute_antispam_post_check ( title , v , url ) :
2023-08-31 10:38:01 +00:00
if v . admin_level > = PERMS [ ' BYPASS_ANTISPAM_CHECKS ' ] :
2023-08-31 10:31:04 +00:00
return True
2023-08-08 12:04:15 +00:00
2022-10-12 05:11:20 +00:00
now = int ( time . time ( ) )
cutoff = now - 60 * 60 * 24
2023-06-07 23:26:32 +00:00
similar_posts = g . db . query ( Post ) . filter (
Post . author_id == v . id ,
Post . title . op ( ' <-> ' ) ( title ) < SPAM_SIMILARITY_THRESHOLD ,
Post . created_utc > cutoff
2022-10-12 05:11:20 +00:00
) . all ( )
if url :
2023-06-07 23:26:32 +00:00
similar_urls = g . db . query ( Post ) . filter (
Post . author_id == v . id ,
Post . url . op ( ' <-> ' ) ( url ) < SPAM_URL_SIMILARITY_THRESHOLD ,
Post . created_utc > cutoff
2022-10-12 05:11:20 +00:00
) . all ( )
else : similar_urls = [ ]
threshold = SPAM_SIMILAR_COUNT_THRESHOLD
if v . age > = ( 60 * 60 * 24 * 7 ) : threshold * = 3
elif v . age > = ( 60 * 60 * 24 ) : threshold * = 2
if max ( len ( similar_urls ) , len ( similar_posts ) ) > = threshold :
2023-07-01 15:25:23 +00:00
tempban_for_spam ( v )
2022-10-12 05:11:20 +00:00
for post in similar_posts + similar_urls :
post . is_banned = True
2024-02-18 15:29:53 +00:00
post . profile_pinned = False
2022-10-12 05:11:20 +00:00
post . ban_reason = " AutoJanny "
2023-03-16 06:27:58 +00:00
g . db . add ( post )
2024-01-31 21:56:32 +00:00
ma = ModAction (
2022-10-12 05:11:20 +00:00
user_id = AUTOJANNY_ID ,
2023-06-07 23:26:32 +00:00
target_post_id = post . id ,
2022-10-12 05:11:20 +00:00
kind = " ban_post " ,
2024-03-02 21:01:29 +00:00
_note = " Spam "
2022-10-12 05:11:20 +00:00
)
2023-03-16 06:27:58 +00:00
g . db . add ( ma )
2022-10-12 05:11:20 +00:00
return False
return True
2023-07-30 00:42:06 +00:00
def execute_antispam_duplicate_comment_check ( v , body_html ) :
2023-08-31 10:38:01 +00:00
if v . admin_level > = PERMS [ ' BYPASS_ANTISPAM_CHECKS ' ] :
2023-08-31 10:31:04 +00:00
return
if v . id in ANTISPAM_BYPASS_IDS :
return
if v . age > = NOTIFICATION_SPAM_AGE_THRESHOLD :
return
if len ( body_html ) < 16 :
return
2023-03-07 01:08:10 +00:00
2022-11-23 20:45:09 +00:00
ANTISPAM_DUPLICATE_THRESHOLD = 3
2022-11-14 03:48:52 +00:00
compare_time = int ( time . time ( ) ) - 60 * 60 * 24
2023-03-16 06:27:58 +00:00
count = g . db . query ( Comment . id ) . filter ( Comment . body_html == body_html ,
2022-11-23 20:45:09 +00:00
Comment . created_utc > = compare_time ) . count ( )
if count < = ANTISPAM_DUPLICATE_THRESHOLD : return
2023-07-01 15:25:23 +00:00
tempban_for_spam ( v )
2023-03-16 06:27:58 +00:00
g . db . commit ( )
2022-11-14 03:48:52 +00:00
abort ( 403 , " Too much spam! " )
2023-07-30 00:42:06 +00:00
def execute_antispam_comment_check ( body , v ) :
2023-08-31 10:38:01 +00:00
if v . admin_level > = PERMS [ ' BYPASS_ANTISPAM_CHECKS ' ] :
2023-08-31 10:31:04 +00:00
return
2023-03-07 01:08:10 +00:00
2022-10-24 17:27:25 +00:00
if v . id in ANTISPAM_BYPASS_IDS : return
2022-10-12 05:11:20 +00:00
if len ( body ) < = COMMENT_SPAM_LENGTH_THRESHOLD : return
now = int ( time . time ( ) )
cutoff = now - 60 * 60 * 24
2023-03-16 06:27:58 +00:00
similar_comments = g . db . query ( Comment ) . filter (
2022-10-12 05:11:20 +00:00
Comment . author_id == v . id ,
Comment . body . op ( ' <-> ' ) ( body ) < COMMENT_SPAM_SIMILAR_THRESHOLD ,
Comment . created_utc > cutoff
) . all ( )
threshold = COMMENT_SPAM_COUNT_THRESHOLD
if v . age > = ( 60 * 60 * 24 * 7 ) :
threshold * = 3
elif v . age > = ( 60 * 60 * 24 ) :
threshold * = 2
2022-11-11 08:45:28 +00:00
2022-10-12 05:11:20 +00:00
if len ( similar_comments ) < = threshold : return
2023-07-01 15:25:23 +00:00
tempban_for_spam ( v )
2022-10-12 05:11:20 +00:00
for comment in similar_comments :
comment . is_banned = True
comment . ban_reason = " AutoJanny "
2023-03-16 06:27:58 +00:00
g . db . add ( comment )
2024-01-31 21:56:32 +00:00
ma = ModAction (
2022-10-12 05:11:20 +00:00
user_id = AUTOJANNY_ID ,
target_comment_id = comment . id ,
kind = " ban_comment " ,
2024-03-02 21:01:29 +00:00
_note = " Spam "
2022-10-12 05:11:20 +00:00
)
2023-03-16 06:27:58 +00:00
g . db . add ( ma )
g . db . commit ( )
2022-10-21 00:28:05 +00:00
abort ( 403 , " Too much spam! " )
2022-10-23 17:01:00 +00:00
2023-07-30 00:42:06 +00:00
def execute_under_siege ( v , target , body , kind ) :
2023-05-14 22:01:10 +00:00
if v . shadowbanned : return
2023-06-30 20:17:56 +00:00
2023-08-31 10:38:01 +00:00
if v . admin_level > = PERMS [ ' BYPASS_UNDER_SIEGE_MODE ' ] : return
2023-02-27 12:49:19 +00:00
2024-01-31 23:28:39 +00:00
thresholds = cache . get ( " under_siege_thresholds " )
if not thresholds :
thresholds = DEFAULT_UNDER_SIEGE_THRESHOLDS
cache . set ( " under_siege_thresholds " , thresholds )
2023-02-27 12:49:19 +00:00
2024-01-31 23:28:39 +00:00
if v . age > thresholds [ kind ] * 60 :
return
2022-12-18 14:23:59 +00:00
2023-08-11 13:15:34 +00:00
unshadowbannedcels = [ x [ 0 ] for x in g . db . query ( ModAction . target_user_id ) . filter_by ( kind = ' unshadowban ' ) ]
2023-05-14 22:01:10 +00:00
if v . id in unshadowbannedcels : return
2023-07-25 16:42:16 +00:00
check_for_alts ( v )
if v . shadowbanned : return
2023-05-14 22:01:10 +00:00
v . shadowbanned = AUTOJANNY_ID
2024-02-11 14:40:22 +00:00
v . shadowban_reason = " Under Siege "
2023-05-14 22:01:10 +00:00
g . db . add ( v )
if kind == " report " :
2023-06-07 23:26:32 +00:00
if isinstance ( target , Post ) :
2023-05-14 22:01:10 +00:00
reason = f ' report on <a href= " { target . permalink } " >post</a> '
else :
reason = f ' report on <a href= " { target . permalink } " >comment</a> '
2024-02-11 16:45:00 +00:00
elif hasattr ( target , ' permalink ' ) :
reason = f ' <a href= " { target . permalink } " > { kind } </a> '
2023-05-14 22:01:10 +00:00
else :
reason = kind
2024-02-01 17:30:04 +00:00
minutes = math . ceil ( v . age / 60 )
time_taken = f ' { minutes } minute '
if minutes > 1 :
time_taken + = ' s '
2023-05-14 22:01:10 +00:00
ma = ModAction (
kind = " shadowban " ,
user_id = AUTOJANNY_ID ,
target_user_id = v . id ,
2024-03-02 21:01:29 +00:00
_note = f ' reason: " Under Siege ( { reason } , { time_taken } ) " '
2023-05-14 22:01:10 +00:00
)
g . db . add ( ma )
2023-10-17 09:02:46 +00:00
def process_options ( v , target ) :
2023-02-28 22:09:16 +00:00
patterns = [ ( poll_regex , 0 ) , ( choice_regex , 1 ) ]
2023-03-12 17:36:35 +00:00
if v . admin_level > = PERMS [ ' POST_BETS ' ] :
2023-02-28 22:09:16 +00:00
patterns . append ( ( bet_regex , 2 ) )
option_count = 0
2023-03-23 15:52:31 +00:00
option_objects = [ ]
2023-02-28 22:09:16 +00:00
for pattern , exclusive in patterns :
2023-07-14 14:46:35 +00:00
body_html = target . body_html . replace ( ' & ' , ' & ' )
for i in pattern . finditer ( body_html ) :
2023-02-28 22:09:16 +00:00
option_count + = 1
if option_count > POLL_MAX_OPTIONS :
abort ( 400 , f " Max number of poll options is { POLL_MAX_OPTIONS } " )
2023-03-12 18:40:18 +00:00
body = i . group ( 2 )
2023-02-28 22:09:16 +00:00
if len ( body ) > 500 :
2024-02-14 09:34:49 +00:00
abort ( 400 , f " Poll option body is too long (Max 500 characters) " )
2023-02-28 22:09:16 +00:00
2023-06-07 23:26:32 +00:00
if isinstance ( target , Post ) :
cls = PostOption
2023-02-28 22:09:16 +00:00
else :
cls = CommentOption
2023-03-16 06:27:58 +00:00
existing = g . db . query ( cls ) . filter_by (
2023-02-28 22:09:16 +00:00
parent_id = target . id ,
2023-07-14 14:46:35 +00:00
body_html = body ,
2023-02-28 22:09:16 +00:00
exclusive = exclusive ,
2023-02-28 23:46:11 +00:00
) . first ( )
2023-05-05 21:45:25 +00:00
2023-02-28 22:09:16 +00:00
if not existing :
option = cls (
parent_id = target . id ,
2023-07-14 14:46:35 +00:00
body_html = body ,
2023-02-28 22:09:16 +00:00
exclusive = exclusive ,
)
2023-03-23 15:53:01 +00:00
option_objects . append ( option ) #shitty hack to bypass autoflush
2023-03-23 15:52:31 +00:00
g . db . add_all ( option_objects )