From 625ff6b006bdcee8b4f82d9340d4e90d0447224c Mon Sep 17 00:00:00 2001 From: Aevann Date: Sat, 7 Oct 2023 18:35:16 +0300 Subject: [PATCH] more consistency between body-altering awards + effortpost protection --- files/classes/user.py | 2 +- files/helpers/config/awards.py | 10 +-- files/helpers/config/const.py | 1 - files/helpers/queenify.py | 47 ++++++++++++ files/helpers/sanitize.py | 131 ++++++++++++--------------------- files/routes/awards.py | 42 +++++------ files/routes/comments.py | 21 +----- files/routes/posts.py | 15 +--- 8 files changed, 129 insertions(+), 140 deletions(-) create mode 100644 files/helpers/queenify.py diff --git a/files/classes/user.py b/files/classes/user.py index 87fc6b33c..0e6e3d6dc 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -39,7 +39,7 @@ from .subscriptions import * from .userblock import * from .usermute import * -if SITE == 'devrama.net' and False: +if SITE == 'devrama.net': DEFAULT_ADMIN_LEVEL = 3 DEFAULT_COINS = 100000000 DEFAULT_MARSEYBUX = 100000000 diff --git a/files/helpers/config/awards.py b/files/helpers/config/awards.py index 6c81ea622..03188010d 100644 --- a/files/helpers/config/awards.py +++ b/files/helpers/config/awards.py @@ -401,7 +401,7 @@ AWARDS = { "marsify": { "kind": "marsify", "title": "Marsify", - "description": "Marsifies the recipient's comments for 24 hours.", + "description": "Marsifies the recipient's posts and comments for 24 hours.", "icon": "fas fa-cat", "color": "text-white", "price": 100, @@ -427,7 +427,7 @@ AWARDS = { "sharpen": { "kind": "sharpen", "title": "Sharpen", - "description": "Adds a badass edge to all the recipient's comments for 24 hours.", + "description": "Adds a badass edge to all the recipient's posts and comments for 24 hours.", "icon": "fas fa-fire", "color": "text-danger", "price": 200, @@ -583,7 +583,7 @@ AWARDS = { "owoify": { "kind": "owoify", "title": "OwOify", - "description": "OwOifies the recipient's comments for 6 hours.", + "description": "OwOifies the recipient's posts and comments for 6 hours.", "icon": "fas fa-paw-simple", "color": "text-purple", "price": 500, @@ -918,7 +918,7 @@ HOUSE_AWARDS = { "Furry": { "kind": "Furry", "title": "OwOify", - "description": "OwOifies the recipient's comments for 6 hours.", + "description": "OwOifies the recipient's posts and comments for 6 hours.", "icon": "fas fa-paw-simple", "color": "text-purple", "price": 500, @@ -966,7 +966,7 @@ HOUSE_AWARDS = { "Edgy": { "kind": "Edgy", "title": "Sharpen", - "description": "Adds a badass edge to all the recipient's comments for 24 hours.", + "description": "Adds a badass edge to all the recipient's posts and comments for 24 hours.", "icon": "fas fa-fire", "color": "text-danger", "price": 200, diff --git a/files/helpers/config/const.py b/files/helpers/config/const.py index 30db5ccb2..5041a55c3 100644 --- a/files/helpers/config/const.py +++ b/files/helpers/config/const.py @@ -98,7 +98,6 @@ CHUD_REPLACEMENTS = { 'EVERYBODY': 'EVERYPONY', } -PHRASE_CHANCE = 0.5 GIRL_PHRASES = [ "ok so $", "um $", diff --git a/files/helpers/queenify.py b/files/helpers/queenify.py new file mode 100644 index 000000000..d588742a2 --- /dev/null +++ b/files/helpers/queenify.py @@ -0,0 +1,47 @@ +from bs4 import BeautifulSoup + +from files.helpers.regex import * + +def queenify_tag_string(string): + if not string: return string + + result = initial_part_regex.search(string) + initial = result.group(1) if result else "" + string = string.lower() + string = initial_part_regex.sub("", string) + string = sentence_ending_regex.sub(", and", string) + string = superlative_regex.sub(r"literally \g<1>", string) + string = totally_regex.sub(r"totally \g<1>", string) + string = single_repeatable_punctuation.sub(r"\g<1>\g<1>\g<1>", string) + string = greeting_regex.sub(r"hiiiiiiiiii", string) + string = like_after_regex.sub(r"\g<1> like", string) + string = like_before_regex.sub(r"like \g<1>", string) + string = redpilled_regex.sub(r"goodpill\g<2>", string) + string = based_and_x_pilled_regex.sub(r"comfy \g<2> vibes", string) + string = based_regex.sub(r"comfy", string) + string = x_pilled_regex.sub(r"\g<2> vibes", string) + string = xmax_regex.sub(r"normalize good \g<2>s", string) + string = xmaxing_regex.sub(r"normalizing good \g<2>s", string) + string = xmaxed_regex.sub(r"normalized good \g<2>s", string) + + string = normal_punctuation_regex.sub("", string) + string = more_than_one_comma_regex.sub(",", string) + if string[-5:] == ', and': + string = string[:-5] + + if random.random() < 0.5: + girl_phrase = random.choice(GIRL_PHRASES) + string = girl_phrase.replace("$", string) + + return initial + string + +def queenify(html): + if '

&&' in html or '

$$' in html or '

##' in html: + return html + + soup = BeautifulSoup(html, 'lxml') + tags = soup.html.body.find_all(lambda tag: tag.name not in {'blockquote','codeblock','pre'} and tag.string, recursive=False) + for tag in tags: + tag.string.replace_with(queenify_tag_string(tag.string)) + + return str(soup).replace('','').replace('','') diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index 7118dc561..3c64039d8 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -26,6 +26,10 @@ from files.helpers.config.const import * from files.helpers.const_stateful import * from files.helpers.regex import * from files.helpers.get import * +from files.helpers.marsify import * +from files.helpers.owoify import * +from files.helpers.sharpen import * +from files.helpers.queenify import * allowed_tags = ('a','audio','b','big','blockquote','br','center','code','del','details','em','g','h1','h2','h3','h4','h5','h6','hr','i','img','li','lite-youtube','marquee','ol','p','pre','rp','rt','ruby','small','span','spoiler','strike','strong','sub','summary','sup','table','tbody','td','th','thead','tr','u','ul','video') @@ -357,7 +361,7 @@ def handle_youtube_links(url): return html @with_sigalrm_timeout(10) -def sanitize(sanitized, golden=True, limit_pings=0, showmore=False, count_emojis=False, snappy=False, chat=False, blackjack=None, post_mention_notif=False, commenters_ping_post_id=None, obj=None): +def sanitize(sanitized, golden=True, limit_pings=0, showmore=False, count_emojis=False, snappy=False, chat=False, blackjack=None, post_mention_notif=False, commenters_ping_post_id=None, obj=None, author=None): def error(error): if chat: return error, 403 @@ -374,6 +378,16 @@ def sanitize(sanitized, golden=True, limit_pings=0, showmore=False, count_emojis if blackjack and execute_blackjack(v, None, sanitized, blackjack): return '

g

' + if obj and not (isinstance(obj, Post) and len(obj.body) > 1000): + if author.owoify: + sanitized = owoify(sanitized) + if author.marsify and not author.chud: + sanitized = marsify(sanitized) + if obj.sharpened: + sanitized = sharpen(sanitized) + if obj.queened: + sanitized = queenify(sanitized) + if '```' not in sanitized and '
' not in sanitized:
 		sanitized = linefeeds_regex.sub(r'\1\n\n\2', sanitized)
 
@@ -659,12 +673,20 @@ def allowed_attributes_emojis(tag, name, value):
 
 
 @with_sigalrm_timeout(2)
-def filter_emojis_only(title, golden=True, count_emojis=False, obj=None):
+def filter_emojis_only(title, golden=True, count_emojis=False, obj=None, author=None):
 
 	title = title.replace("\n", "").replace("\r", "").replace("\t", "").replace('<','<').replace('>','>')
 
 	title = remove_cuniform(title)
 
+	if obj and not (isinstance(obj, Post) and len(obj.body) > 1000):
+		if author.owoify:
+			title = owoify(title)
+		if author.marsify and not author.chud:
+			title = marsify(title)
+		if obj.sharpened:
+			title = sharpen(title)
+
 	emojis_used = set()
 
 	title = render_emoji(title, emoji_regex2, golden, emojis_used, is_title=True)
@@ -807,60 +829,9 @@ def torture_chud(string, username):
 	string = torture_regex3.sub(rf"\1@{username}'s\3", string)
 	return string
 
-def torture_queen(string, key):
-	if not string: return string
-	result = initial_part_regex.search(string)
-	initial = result.group(1) if result else ""
-	string = string.lower()
-	string = initial_part_regex.sub("", string)
-	string = sentence_ending_regex.sub(", and", string)
-	string = superlative_regex.sub(r"literally \g<1>", string)
-	string = totally_regex.sub(r"totally \g<1>", string)
-	string = single_repeatable_punctuation.sub(r"\g<1>\g<1>\g<1>", string)
-	string = greeting_regex.sub(r"hiiiiiiiiii", string)
-	string = like_after_regex.sub(r"\g<1> like", string)
-	string = like_before_regex.sub(r"like \g<1>", string)
-	string = redpilled_regex.sub(r"goodpill\g<2>", string)
-	string = based_and_x_pilled_regex.sub(r"comfy \g<2> vibes", string)
-	string = based_regex.sub(r"comfy", string)
-	string = x_pilled_regex.sub(r"\g<2> vibes", string)
-	string = xmax_regex.sub(r"normalize good \g<2>s", string)
-	string = xmaxing_regex.sub(r"normalizing good \g<2>s", string)
-	string = xmaxed_regex.sub(r"normalized good \g<2>s", string)
-
-	string = normal_punctuation_regex.sub("", string)
-	string = more_than_one_comma_regex.sub(",", string)
-	if string[-5:] == ', and':
-		string = string[:-5]
-
-	if SITE == 'devrama.net':
-		random.seed(key)
-
-	if random.random() < PHRASE_CHANCE:
-		girl_phrase = random.choice(GIRL_PHRASES)
-		string = girl_phrase.replace("$", string)
-	string = initial + string
-	return string
-
-def torture_object(obj, torture_method):
-	#torture body_html
-	if obj.body_html and '

&&' not in obj.body_html and '

$$' not in obj.body_html and '

##' not in obj.body_html: - soup = BeautifulSoup(obj.body_html, 'lxml') - tags = soup.html.body.find_all(lambda tag: tag.name not in {'blockquote','codeblock','pre'} and tag.string, recursive=False) - i = 0 - for tag in tags: - i+=1 - key = obj.id+i - tag.string.replace_with(torture_method(tag.string, key)) - obj.body_html = str(soup).replace('','').replace('','') - - #torture title_html and check for chud_phrase in plain title and leave if it's there - if isinstance(obj, Post): - obj.title_html = obj.title_html - def complies_with_chud(obj): #check for cases where u should leave - if not (obj.chudded or obj.queened): return True + if not obj.chudded: return True if obj.author.marseyawarded: return True if isinstance(obj, Post): @@ -870,35 +841,31 @@ def complies_with_chud(obj): if obj.parent_post in ADMIGGER_THREADS: return True if obj.post.sub == "chudrama": return True - if obj.chudded: - #perserve old body_html to be used in checking for chud phrase - old_body_html = obj.body_html + #perserve old body_html to be used in checking for chud phrase + old_body_html = obj.body_html - #torture body_html - if obj.body_html and '

&&' not in obj.body_html and '

$$' not in obj.body_html and '

##' not in obj.body_html: - soup = BeautifulSoup(obj.body_html, 'lxml') - tags = soup.html.body.find_all(lambda tag: tag.name not in {'blockquote','codeblock','pre'} and tag.string, recursive=False) - for tag in tags: - tag.string.replace_with(torture_chud(tag.string, obj.author.username)) - obj.body_html = str(soup).replace('','').replace('','') + #torture body_html + if obj.body_html and '

&&' not in obj.body_html and '

$$' not in obj.body_html and '

##' not in obj.body_html: + soup = BeautifulSoup(obj.body_html, 'lxml') + tags = soup.html.body.find_all(lambda tag: tag.name not in {'blockquote','codeblock','pre'} and tag.string, recursive=False) + for tag in tags: + tag.string.replace_with(torture_chud(tag.string, obj.author.username)) + obj.body_html = str(soup).replace('','').replace('','') - #torture title_html and check for chud_phrase in plain title and leave if it's there - if isinstance(obj, Post): - obj.title_html = torture_chud(obj.title_html, obj.author.username) - if not obj.author.chud or obj.author.chud_phrase in obj.title.lower(): - return True + #torture title_html and check for chud_phrase in plain title and leave if it's there + if isinstance(obj, Post): + obj.title_html = torture_chud(obj.title_html, obj.author.username) + if not obj.author.chud or obj.author.chud_phrase in obj.title.lower(): + return True - #check for chud_phrase in body_html - if old_body_html: - excluded_tags = {'del','sub','sup','marquee','spoiler','lite-youtube','video','audio'} - soup = BeautifulSoup(old_body_html, 'lxml') - tags = soup.html.body.find_all(lambda tag: tag.name not in excluded_tags and not tag.attrs, recursive=False) - for tag in tags: - for text in tag.find_all(text=True, recursive=False): - if not obj.author.chud or obj.author.chud_phrase in text.lower(): - return True + #check for chud_phrase in body_html + if old_body_html: + excluded_tags = {'del','sub','sup','marquee','spoiler','lite-youtube','video','audio'} + soup = BeautifulSoup(old_body_html, 'lxml') + tags = soup.html.body.find_all(lambda tag: tag.name not in excluded_tags and not tag.attrs, recursive=False) + for tag in tags: + for text in tag.find_all(text=True, recursive=False): + if not obj.author.chud or obj.author.chud_phrase in text.lower(): + return True - return False - elif obj.queened: - torture_object(obj, torture_queen) - return True + return False diff --git a/files/routes/awards.py b/files/routes/awards.py index dc5ef3be5..9fcc05070 100644 --- a/files/routes/awards.py +++ b/files/routes/awards.py @@ -12,11 +12,8 @@ from files.helpers.config.const import * from files.helpers.slurs_and_profanities import censor_slurs_profanities from files.helpers.config.awards import * from files.helpers.get import * -from files.helpers.marsify import marsify -from files.helpers.owoify import owoify -from files.helpers.sharpen import sharpen from files.helpers.regex import * -from files.helpers.sanitize import filter_emojis_only +from files.helpers.sanitize import * from files.helpers.useractions import * from files.routes.wrappers import * from files.__main__ import app, cache, limiter @@ -235,6 +232,8 @@ def award_thing(v, thing_type, id): link = f"[this {thing_type}]({thing.shortlink})" + alter_body = not (isinstance(thing, Post) and len(thing.body) > 1000) and (not thing.author.deflector or v == thing.author) + if kind == "ban": link = f"/{thing_type}/{thing.id}" if thing_type == 'comment': @@ -347,8 +346,11 @@ def award_thing(v, thing_type, id): badge_grant(user=author, badge_id=285) - if thing_type == 'comment' and (not thing.author.deflector or v == thing.author): + if alter_body: thing.queened = True + thing.body_html = sanitize(thing.body, limit_pings=5, showmore=True, obj=thing, author=author) + if isinstance(thing, Post): + thing.title_html = filter_emojis_only(thing.title, golden=False, obj=thing, author=author) g.db.add(thing) elif kind == "chud": @@ -383,8 +385,9 @@ def award_thing(v, thing_type, id): badge_grant(user=author, badge_id=58) - if thing_type == 'comment' and (not thing.author.deflector or v == thing.author): + if alter_body: thing.chudded = True + complies_with_chud(thing) elif kind == "flairlock": new_name = note[:100] if not new_name and author.flairchanged: @@ -483,11 +486,10 @@ def award_thing(v, thing_type, id): else: author.marsify = int(time.time()) + 86400 badge_grant(user=author, badge_id=170) - if thing_type == 'comment' and (not thing.author.deflector or v == thing.author): - body = thing.body - if author.owoify: body = owoify(body) - body = marsify(body) - thing.body_html = sanitize(body, limit_pings=5, showmore=True) + if alter_body: + thing.body_html = sanitize(thing.body, limit_pings=5, showmore=True, obj=thing, author=author) + if isinstance(thing, Post): + thing.title_html = filter_emojis_only(thing.title, golden=False, obj=thing, author=author) g.db.add(thing) elif "Vampire" in kind and kind == v.house: if author.bite: author.bite += 172800 @@ -512,12 +514,10 @@ def award_thing(v, thing_type, id): else: author.owoify = int(time.time()) + 21600 badge_grant(user=author, badge_id=167) - if thing_type == 'comment' and (not thing.author.deflector or v == thing.author): - body = thing.body - body = owoify(body) - if author.marsify and not author.chud: - body = marsify(body) - thing.body_html = sanitize(body, limit_pings=5, showmore=True) + if alter_body: + thing.body_html = sanitize(thing.body, limit_pings=5, showmore=True, obj=thing, author=author) + if isinstance(thing, Post): + thing.title_html = filter_emojis_only(thing.title, golden=False, obj=thing, author=author) g.db.add(thing) elif ("Edgy" in kind and kind == v.house) or kind == 'sharpen': if author.chud: @@ -527,11 +527,11 @@ def award_thing(v, thing_type, id): else: author.sharpen = int(time.time()) + 86400 badge_grant(user=author, badge_id=289) - if thing_type == 'comment' and (not thing.author.deflector or v == thing.author): - body = thing.body - body = sharpen(body) - thing.body_html = sanitize(body, limit_pings=5, showmore=True) + if alter_body: thing.sharpened = True + thing.body_html = sanitize(thing.body, limit_pings=5, showmore=True, obj=thing, author=author) + if isinstance(thing, Post): + thing.title_html = filter_emojis_only(thing.title, golden=False, obj=thing, author=author) g.db.add(thing) elif ("Femboy" in kind and kind == v.house) or kind == 'rainbow': if author.rainbow: author.rainbow += 86400 diff --git a/files/routes/comments.py b/files/routes/comments.py index 1e5ef543b..f0636f91d 100644 --- a/files/routes/comments.py +++ b/files/routes/comments.py @@ -12,10 +12,7 @@ from files.helpers.alerts import * from files.helpers.cloudflare import purge_files_in_cloudflare_cache from files.helpers.config.const import * from files.helpers.get import * -from files.helpers.marsify import marsify from files.helpers.media import * -from files.helpers.owoify import owoify -from files.helpers.sharpen import sharpen from files.helpers.regex import * from files.helpers.slots import * from files.helpers.treasure import * @@ -256,11 +253,6 @@ def comment(v): f.write('{[para]}\n' + body + '\n') SNAPPY_QUOTES.append(body) - body_for_sanitize = body - if v.owoify: body_for_sanitize = owoify(body_for_sanitize) - if v.marsify and not v.chud: body_for_sanitize = marsify(body_for_sanitize) - if v.sharpen: body_for_sanitize = sharpen(body_for_sanitize) - is_bot = v.client is not None and v.id not in BOT_SYMBOL_HIDDEN chudded = v.chud and not (posting_to_post and post_target.sub == 'chudrama') @@ -283,7 +275,7 @@ def comment(v): c.upvotes = 1 - body_html = sanitize(body_for_sanitize, limit_pings=5, showmore=(not v.marseyawarded), count_emojis=not v.marsify, commenters_ping_post_id=commenters_ping_post_id, obj=c) + body_html = sanitize(body, limit_pings=5, showmore=(not v.marseyawarded), count_emojis=not v.marsify, commenters_ping_post_id=commenters_ping_post_id, obj=c, author=v) if post_target.id not in ADMIGGER_THREADS and not (v.chud and v.chud_phrase in body.lower()): existing = g.db.query(Comment.id).filter( @@ -683,16 +675,7 @@ def edit_comment(cid, v): body = process_files(request.files, v, body) body = body[:COMMENT_BODY_LENGTH_LIMIT].strip() # process_files potentially adds characters to the post - body_for_sanitize = body - - if c.author.owoify: - body_for_sanitize = owoify(body_for_sanitize) - if c.author.marsify and not c.author.chud: - body_for_sanitize = marsify(body_for_sanitize) - if c.sharpened: - body_for_sanitize = sharpen(body_for_sanitize) - - body_html = sanitize(body_for_sanitize, golden=False, limit_pings=5, showmore=(not v.marseyawarded), commenters_ping_post_id=c.parent_post, obj=c) + body_html = sanitize(body, golden=False, limit_pings=5, showmore=(not v.marseyawarded), commenters_ping_post_id=c.parent_post, obj=c, author=c.author) if len(body_html) > COMMENT_BODY_HTML_LENGTH_LIMIT: abort(400) diff --git a/files/routes/posts.py b/files/routes/posts.py index 7ba818c4c..a85faadb6 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -19,7 +19,6 @@ from files.helpers.actions import * from files.helpers.alerts import * from files.helpers.config.const import * from files.helpers.get import * -from files.helpers.sharpen import * from files.helpers.regex import * from files.helpers.sanitize import * from files.helpers.settings import get_setting @@ -531,9 +530,6 @@ def submit_post(v, sub=None): body = process_files(request.files, v, body) body = body[:POST_BODY_LENGTH_LIMIT(v)].strip() # process_files() adds content to the body, so we need to re-strip - body_for_sanitize = body - if v.sharpen: body_for_sanitize = sharpen(body_for_sanitize) - flag_notify = (request.values.get("notify", "on") == "on") flag_new = request.values.get("new", False, bool) or 'megathread' in title.lower() flag_nsfw = FEATURES['NSFW_MARKING'] and request.values.get("nsfw", False, bool) @@ -572,14 +568,14 @@ def submit_post(v, sub=None): sharpened=bool(v.sharpen), ) - title_html = filter_emojis_only(title, count_emojis=True, obj=p) + title_html = filter_emojis_only(title, count_emojis=True, obj=p, author=v) if v.marseyawarded and not marseyaward_title_regex.fullmatch(title_html): abort(400, "You can only type marseys!") p.title_html = title_html - body_html = sanitize(body_for_sanitize, count_emojis=True, limit_pings=100, obj=p) + body_html = sanitize(body, count_emojis=True, limit_pings=100, obj=p, author=v) if v.marseyawarded and marseyaward_body_regex.search(body_html): abort(400, "You can only type marseys!") @@ -1012,7 +1008,7 @@ def edit_post(pid, v): if title != p.title: - title_html = filter_emojis_only(title, golden=False, obj=p) + title_html = filter_emojis_only(title, golden=False, obj=p, author=p.author) if p.author.marseyawarded and not marseyaward_title_regex.fullmatch(title_html): abort(403, "You can only type marseys!") @@ -1027,10 +1023,7 @@ def edit_post(pid, v): body = body[:POST_BODY_LENGTH_LIMIT(v)].strip() # process_files() may be adding stuff to the body if body != p.body: - body_for_sanitize = body - if p.sharpened: body_for_sanitize = sharpen(body_for_sanitize) - - body_html = sanitize(body_for_sanitize, golden=False, limit_pings=100, obj=p) + body_html = sanitize(body, golden=False, limit_pings=100, obj=p, author=p.author) if p.author.marseyawarded and marseyaward_body_regex.search(body_html): abort(403, "You can only type marseys!")