From 7e1e9ccc5bc8e0873a9b91cd922709f7f5bfaa2e Mon Sep 17 00:00:00 2001 From: Yo Mama Date: Sat, 16 Oct 2021 19:04:08 +0200 Subject: [PATCH 1/8] Initial working version of word censor --- .gitignore | 5 +- docker-compose.yml | 118 ++++++++++++------------- files/helpers/const.py | 2 +- files/helpers/word_censor.py | 47 ++++++++++ requirements.txt | 2 + test/files/helpers/test_word_censor.py | 76 ++++++++++++++++ 6 files changed, 189 insertions(+), 61 deletions(-) create mode 100644 files/helpers/word_censor.py create mode 100644 test/files/helpers/test_word_censor.py diff --git a/.gitignore b/.gitignore index 1eb768ab0..3c7c45076 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,7 @@ video.mp4 cache/ __pycache__/ disablesignups -*rules.html \ No newline at end of file +*rules.html +.idea/ +**/.pytest_cache/ +venv/ diff --git a/docker-compose.yml b/docker-compose.yml index 7b5e63f39..28788954e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,66 +2,66 @@ version: '2.3' services: files: - build: - context: . - volumes: - - "./:/service" - environment: - - DATABASE_URL=postgresql://postgres@postgres:5432/postgres - - MASTER_KEY=${MASTER_KEY:-KTVciAUQFpFh2WdJ/oiHJlxl6FvzRZp8kYzAAv3l2OA=} - - REDIS_URL=redis://redis - - DOMAIN=localhost - - SITE_NAME=Drama - - GIPHY_KEY=3435tdfsdudebussylmaoxxt43 - - FORCE_HTTPS=0 - - DISCORD_SERVER_ID=3435tdfsdudebussylmaoxxt43 - - DISCORD_CLIENT_ID=3435tdfsdudebussylmaoxxt43 - - DISCORD_CLIENT_SECRET=3435tdfsdudebussylmaoxxt43 - - DISCORD_BOT_TOKEN=3435tdfsdudebussylmaoxxt43 - #- HCAPTCHA_SITEKEY=3435tdfsdudebussylmaoxxt43 - - HCAPTCHA_SECRET=3435tdfsdudebussylmaoxxt43 - - YOUTUBE_KEY=3435tdfsdudebussylmaoxxt43 - - PUSHER_KEY=3435tdfsdudebussylmaoxxt43 - - CATBOX_KEY=3435tdfsdudebussylmaoxxt43 - - SPAM_SIMILARITY_THRESHOLD=0.5 - - SPAM_SIMILAR_COUNT_THRESHOLD=5 - - SPAM_URL_SIMILARITY_THRESHOLD=0.1 - - COMMENT_SPAM_SIMILAR_THRESHOLD=0.5 - - COMMENT_SPAM_COUNT_THRESHOLD=5 - - READ_ONLY=0 - - BOT_DISABLE=0 - - COINS_NAME=Dramacoins - - DEFAULT_TIME_FILTER=all - - DEFAULT_THEME=dark - - DEFAULT_COLOR=ff66ac #YOU HAVE TO PICK ONE OF THOSE COLORS OR SHIT WILL BREAK: ff66ac, 805ad5, 62ca56, 38a169, 80ffff, 2a96f3, eb4963, ff0000, f39731, 30409f, 3e98a7, e4432d, 7b9ae4, ec72de, 7f8fa6, f8db58 - - SLOGAN=Dude bussy lmao - - GUMROAD_TOKEN=3435tdfsdudebussylmaoxxt43 - - GUMROAD_LINK=https://marsey1.gumroad.com/l/tfcvri - - CARD_VIEW=1 - - DISABLE_DOWNVOTES=0 - - DUES=0 - - MAIL_USERNAME=blahblahblah@gmail.com - - MAIL_PASSWORD=3435tdfsdudebussylmaoxxt43 - links: - - "redis" - - "postgres" - ports: - - "80:80" - depends_on: - - redis - - postgres + build: + context: . + volumes: + - "./:/service" + environment: + - DATABASE_URL=postgresql://postgres@postgres:5432/postgres + - MASTER_KEY=${MASTER_KEY:-KTVciAUQFpFh2WdJ/oiHJlxl6FvzRZp8kYzAAv3l2OA=} + - REDIS_URL=redis://redis + - DOMAIN=localhost + - SITE_NAME=Drama + - GIPHY_KEY=3435tdfsdudebussylmaoxxt43 + - FORCE_HTTPS=0 + - DISCORD_SERVER_ID=3435tdfsdudebussylmaoxxt43 + - DISCORD_CLIENT_ID=3435tdfsdudebussylmaoxxt43 + - DISCORD_CLIENT_SECRET=3435tdfsdudebussylmaoxxt43 + - DISCORD_BOT_TOKEN=3435tdfsdudebussylmaoxxt43 + #- HCAPTCHA_SITEKEY=3435tdfsdudebussylmaoxxt43 + - HCAPTCHA_SECRET=3435tdfsdudebussylmaoxxt43 + - YOUTUBE_KEY=3435tdfsdudebussylmaoxxt43 + - PUSHER_KEY=3435tdfsdudebussylmaoxxt43 + - CATBOX_KEY=3435tdfsdudebussylmaoxxt43 + - SPAM_SIMILARITY_THRESHOLD=0.5 + - SPAM_SIMILAR_COUNT_THRESHOLD=5 + - SPAM_URL_SIMILARITY_THRESHOLD=0.1 + - COMMENT_SPAM_SIMILAR_THRESHOLD=0.5 + - COMMENT_SPAM_COUNT_THRESHOLD=5 + - READ_ONLY=0 + - BOT_DISABLE=0 + - COINS_NAME=Dramacoins + - DEFAULT_TIME_FILTER=all + - DEFAULT_THEME=dark + - DEFAULT_COLOR=ff66ac #YOU HAVE TO PICK ONE OF THOSE COLORS OR SHIT WILL BREAK: ff66ac, 805ad5, 62ca56, 38a169, 80ffff, 2a96f3, eb4963, ff0000, f39731, 30409f, 3e98a7, e4432d, 7b9ae4, ec72de, 7f8fa6, f8db58 + - SLOGAN=Dude bussy lmao + - GUMROAD_TOKEN=3435tdfsdudebussylmaoxxt43 + - GUMROAD_LINK=https://marsey1.gumroad.com/l/tfcvri + - CARD_VIEW=1 + - DISABLE_DOWNVOTES=0 + - DUES=0 + - MAIL_USERNAME=blahblahblah@gmail.com + - MAIL_PASSWORD=3435tdfsdudebussylmaoxxt43 + links: + - "redis" + - "postgres" + ports: + - "80:80" + depends_on: + - redis + - postgres redis: - image: redis - ports: - - "6379:6379" + image: redis + ports: + - "6379:6379" postgres: - image: postgres:12.3 - volumes: - - "./schema.sql:/docker-entrypoint-initdb.d/00-schema.sql" - - "./seed-db.sql:/docker-entrypoint-initdb.d/01-schema.sql" - environment: - - POSTGRES_HOST_AUTH_METHOD=trust - #ports: - #- "5432:5432" \ No newline at end of file + image: postgres:12.3 + volumes: + - "./schema.sql:/docker-entrypoint-initdb.d/00-schema.sql" + - "./seed-db.sql:/docker-entrypoint-initdb.d/01-schema.sql" + environment: + - POSTGRES_HOST_AUTH_METHOD=trust + #ports: + #- "5432:5432" \ No newline at end of file diff --git a/files/helpers/const.py b/files/helpers/const.py index 50f7c7549..f3becb9b7 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -1,6 +1,6 @@ from os import environ -site = environ.get("DOMAIN").strip() +site = environ.get("DOMAIN", '').strip() SLURS = { " faggot":" cute twink", diff --git a/files/helpers/word_censor.py b/files/helpers/word_censor.py new file mode 100644 index 000000000..294bde420 --- /dev/null +++ b/files/helpers/word_censor.py @@ -0,0 +1,47 @@ +from collections import ChainMap +import re +from re import Match + +from files.helpers.const import SLURS + + +def create_replace_map(): + dicts = [{ + slur: replacer, + slur.title(): replacer.title(), + slur.capitalize(): replacer.capitalize(), + slur.upper(): replacer.upper(), + } for (slur, replacer) in SLURS.items()] + + # flattens the list of dict to a single dict + return dict(ChainMap(*dicts)) + + +REPLACE_MAP = create_replace_map() + + +def create_variations_slur_regex(slur: str): + variations = [slur, slur.upper(), slur.capitalize()] + + # capitalize multiple words if there are multiple words (just in case) + if " " in slur: + variations.append(slur.title()) + + return [rf"(\s|>)({var})|({var})(\s|<)" for var in variations] + + +def sub_matcher(match: Match): + found = match.group(2) if (match.group(2) is not None) else match.group(3) + replacer = REPLACE_MAP[found] + return (match.group(1) or '') + replacer + (match.group(4) or '') + + +def censor_slurs(v, body): + for (slur, replace) in SLURS.items(): + for variation in create_variations_slur_regex(slur): + try: + body = re.sub(variation, sub_matcher, body) + except: + pass + + return body diff --git a/requirements.txt b/requirements.txt index 5f3263376..81a3aa269 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +assertpy beautifulsoup4 bleach Flask @@ -20,6 +21,7 @@ requests SQLAlchemy psycopg2-binary pusher_push_notifications +pytest youtube-dl yattag webptools \ No newline at end of file diff --git a/test/files/helpers/test_word_censor.py b/test/files/helpers/test_word_censor.py new file mode 100644 index 000000000..9ab8ecdb2 --- /dev/null +++ b/test/files/helpers/test_word_censor.py @@ -0,0 +1,76 @@ +import re +from unittest.mock import patch + +from assertpy import assert_that + +from files.helpers import word_censor +from files.helpers.word_censor import create_variations_slur_regex, create_replace_map, censor_slurs, sub_matcher + + +def test_create_variations_slur_regex_single_word(): + expected = [r"(\s|>)(retard)|(retard)(\s|<)", + r"(\s|>)(Retard)|(Retard)(\s|<)", + r"(\s|>)(RETARD)|(RETARD)(\s|<)"] + + result = create_variations_slur_regex("retard") + + assert_that(result).is_length(3).contains_only(*expected) + + +def test_create_variations_slur_regex_multiple_word(): + expected = [r"(\s|>)(kill yourself)|(kill yourself)(\s|<)", + r"(\s|>)(Kill Yourself)|(Kill Yourself)(\s|<)", + r"(\s|>)(Kill yourself)|(Kill yourself)(\s|<)", + r"(\s|>)(KILL YOURSELF)|(KILL YOURSELF)(\s|<)"] + result = create_variations_slur_regex("kill yourself") + + assert_that(result).is_length(4).contains_only(*expected) + + +@patch("files.helpers.word_censor.SLURS", { + "tranny": "🚂🚃🚃", + "kill yourself": "keep yourself safe", + "faggot": "cute twink", +}) +def test_create_replace_map(): + expected = { + "tranny": "🚂🚃🚃", + "Tranny": "🚂🚃🚃", + "TRANNY": "🚂🚃🚃", + "kill yourself": "keep yourself safe", + "Kill yourself": "Keep yourself safe", + "KILL YOURSELF": "KEEP YOURSELF SAFE", + "Kill Yourself": "Keep Yourself Safe", + "faggot": "cute twink", + "Faggot": "Cute twink", + "FAGGOT": "CUTE TWINK", + } + result = create_replace_map() + + assert_that(result).is_equal_to(expected) + + +@patch("files.helpers.word_censor.REPLACE_MAP", {'retard': 'r-slur'}) +def test_sub_matcher(): + match = re.search(r"(\s|>)(retard)|(retard)(\s|<)", "

retard

") + assert_that(sub_matcher(match)).is_equal_to(">r-slur") + + match = re.search(r"(\s|>)(retard)|(retard)(\s|<)", "

noretard

") + assert_that(sub_matcher(match)).is_equal_to("r-slur<") + + +@patch("files.helpers.word_censor.SLURS", {'retard': 'r-slur', 'manlet': 'little king'}) +def test_censor_slurs(): + word_censor.REPLACE_MAP = create_replace_map() + + assert_that(censor_slurs(None, "

retard

")).is_equal_to("

r-slur

") + assert_that(censor_slurs(None, "

preretard

")).is_equal_to("

prer-slur

") + assert_that(censor_slurs(None, "that is Retarded like")).is_equal_to("that is R-slured like") + assert_that(censor_slurs(None, "that is SUPERRETARD like")).is_equal_to("that is SUPERR-SLUR like") + assert_that(censor_slurs(None, "

Manlets get out!

")).is_equal_to("

Little kings get out!

") + assert_that(censor_slurs(None, '... "retard" ...')).is_equal_to('... "retard" ...') + assert_that(censor_slurs(None, '... ReTaRd ...')).is_equal_to('... ReTaRd ...') + assert_that(censor_slurs(None, '... aretarded ...')).is_equal_to('... aretarded ...') + assert_that(censor_slurs(None, "LLM is a manlet hehe")).is_equal_to("LLM is a little king hehe") + assert_that(censor_slurs(None, "LLM is :marseycapitalistmanlet: hehe")) \ + .is_equal_to("LLM is :marseycapitalistmanlet: hehe") From 5f7824b6c7cf2337acaec69fcaee6d64189a1a1b Mon Sep 17 00:00:00 2001 From: Yo Mama Date: Sat, 16 Oct 2021 20:06:21 +0200 Subject: [PATCH 2/8] First 'working' version of the word-censor --- files/classes/comment.py | 20 +++++++++---------- files/classes/submission.py | 27 +++++++++++++------------- files/helpers/word_censor.py | 3 +++ test/files/helpers/test_word_censor.py | 15 ++++++++++++++ 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/files/classes/comment.py b/files/classes/comment.py index ca0b9828d..4d6e74406 100644 --- a/files/classes/comment.py +++ b/files/classes/comment.py @@ -1,16 +1,18 @@ +from os import environ import re +import time from urllib.parse import urlencode, urlparse, parse_qs + from flask import * from sqlalchemy import * from sqlalchemy.orm import relationship, deferred, lazyload -from files.classes.votes import CommentVote -from files.helpers.lazy import lazy -from files.helpers.const import SLURS + from files.__main__ import Base -from .flags import CommentFlag -from os import environ -import time +from files.classes.votes import CommentVote from files.helpers.const import AUTOPOLLER_ACCOUNT +from files.helpers.lazy import lazy +from .flags import CommentFlag +from ..helpers.word_censor import censor_slurs site = environ.get("DOMAIN").strip() @@ -298,8 +300,7 @@ class Comment(Base): if not body: return "" - if not v or v.slurreplacer: - for s, r in SLURS.items(): body = body.replace(s, r) + body = censor_slurs(body) if v and not v.oldreddit: body = body.replace("old.reddit.com", "reddit.com") @@ -325,8 +326,7 @@ class Comment(Base): if not body: return "" - if not v or v.slurreplacer: - for s, r in SLURS.items(): body = body.replace(s, r) + body = censor_slurs(body) if v and not v.oldreddit: body = body.replace("old.reddit.com", "reddit.com") diff --git a/files/classes/submission.py b/files/classes/submission.py index 214beee0e..63ace1e42 100644 --- a/files/classes/submission.py +++ b/files/classes/submission.py @@ -1,21 +1,24 @@ -from flask import render_template, g +from os import environ +import random +import re +import time +from urllib.parse import urlparse + +from flask import render_template from sqlalchemy import * from sqlalchemy.orm import relationship, deferred -import re, random -from urllib.parse import urlparse -from files.helpers.lazy import lazy -from files.helpers.const import SLURS, AUTOPOLLER_ACCOUNT + from files.__main__ import Base +from files.helpers.const import SLURS, AUTOPOLLER_ACCOUNT +from files.helpers.lazy import lazy from .flags import Flag -from os import environ -import time +from ..helpers.word_censor import censor_slurs site = environ.get("DOMAIN").strip() site_name = environ.get("SITE_NAME").strip() class Submission(Base): - __tablename__ = "submissions" id = Column(BigInteger, primary_key=True) @@ -339,9 +342,7 @@ class Submission(Base): if self.club and not (v and v.paid_dues): return "COUNTRY CLUB ONLY" body = self.body_html - if not v or v.slurreplacer: - for s,r in SLURS.items(): - body = body.replace(s, r) + body = censor_slurs(body) if v and not v.oldreddit: body = body.replace("old.reddit.com", "reddit.com") if v and v.nitter: body = body.replace("www.twitter.com", "nitter.net").replace("twitter.com", "nitter.net") @@ -351,9 +352,7 @@ class Submission(Base): if self.club and not (v and v.paid_dues): return "COUNTRY CLUB ONLY" body = self.body - if not v or v.slurreplacer: - for s,r in SLURS.items(): - body = body.replace(s, r) + body = censor_slurs(body) if v and not v.oldreddit: body = body.replace("old.reddit.com", "reddit.com") if v and v.nitter: body = body.replace("www.twitter.com", "nitter.net").replace("twitter.com", "nitter.net") diff --git a/files/helpers/word_censor.py b/files/helpers/word_censor.py index 294bde420..dabf74cdf 100644 --- a/files/helpers/word_censor.py +++ b/files/helpers/word_censor.py @@ -37,6 +37,9 @@ def sub_matcher(match: Match): def censor_slurs(v, body): + if v and not v.slurreplacer: + return body + for (slur, replace) in SLURS.items(): for variation in create_variations_slur_regex(slur): try: diff --git a/test/files/helpers/test_word_censor.py b/test/files/helpers/test_word_censor.py index 9ab8ecdb2..86b35a259 100644 --- a/test/files/helpers/test_word_censor.py +++ b/test/files/helpers/test_word_censor.py @@ -74,3 +74,18 @@ def test_censor_slurs(): assert_that(censor_slurs(None, "LLM is a manlet hehe")).is_equal_to("LLM is a little king hehe") assert_that(censor_slurs(None, "LLM is :marseycapitalistmanlet: hehe")) \ .is_equal_to("LLM is :marseycapitalistmanlet: hehe") + + +@patch("files.helpers.word_censor.SLURS", {'retard': 'r-slur', 'manlet': 'little king'}) +def test_censor_slurs_does_not_censor_on_flag_disabled(): + word_censor.REPLACE_MAP = create_replace_map() + + class V: + def __init__(self, slurreplacer): + self.slurreplacer = slurreplacer + + v = V(False) + assert_that(censor_slurs(v, "

retard

")).is_equal_to("

retard

") + + v = V(True) + assert_that(censor_slurs(v, "

retard

")).is_equal_to("

r-slur

") From 58c74dbdaf596f3958dbdb2a5fc8a9decb1e726b Mon Sep 17 00:00:00 2001 From: Yo Mama Date: Sat, 16 Oct 2021 20:42:00 +0200 Subject: [PATCH 3/8] Compact slurs dict and added support for word censor --- files/helpers/const.py | 159 ++++--------------------- files/helpers/word_censor.py | 39 +++--- test/files/helpers/test_word_censor.py | 43 ++++++- 3 files changed, 91 insertions(+), 150 deletions(-) diff --git a/files/helpers/const.py b/files/helpers/const.py index f3becb9b7..652a63948 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -3,140 +3,33 @@ from os import environ site = environ.get("DOMAIN", '').strip() SLURS = { - " faggot":" cute twink", - " Faggot":" Cute twink", - " FAGGOT":" CUTE TWINK", - " fag":" cute twink", - " Fag":" Cute twink", - " FAG":" CUTE TWINK", - " pedophile":" libertarian", - " Pedophile":" Libertarian", - " PEDOPHILE":" LIBERTARIAN", - " pedo":" libertarian", - " Pedo":" Libertarian", - " PEDO":" LIBERTARIAN", - " kill yourself":" keep yourself safe", - " KILL YOURSELF":" KEEP YOURSELF SAFE", - " nigger":" 🏀", - " Nigger":" 🏀", - " NIGGER":" 🏀", - " rapist":" male feminist", - " Rapist":" Male feminist", - " RAPIST":" MALE FEMINIST", - " steve akins":" penny verity oaken", - " Steve Akins":" Penny Verity Oaken", - " STEVE AKINS":" PENNY VERITY OAKEN", - " trannie":" 🚂🚃🚃", - " Trannie":" 🚂🚃🚃", - " TRANNIE":" 🚂🚃🚃", - " tranny":" 🚂🚃🚃", - " Tranny":" 🚂🚃🚃", - " TRANNY":" 🚂🚃🚃", - " troon":" 🚂🚃🚃", - " Troon":" 🚂🚃🚃", - " TROON":" 🚂🚃🚃", - " NoNewNormal": " HorseDewormerAddicts", - " nonewnormal": " horsedewormeraddicts", - " Kike": " https://sciencedirect.com/science/article/abs/pii/S016028960600033X", - " kike": " https://sciencedirect.com/science/article/abs/pii/S016028960600033X", - " retard":" r-slur", - " Retard":" R-slur", - " RETARD":" R-SLUR", - " janny":" j-slur", - " Janny":" J-slur", - " JANNY":" J-SLUR", - " jannie":" j-slur", - " Jannie":" J-slur", - " JANNIE":" J-SLUR", - " janny":" j-slur", - " Janny":" J-slur", - " JANNY":" J-SLUR", - " jannie":" j-slur", - " Jannie":" J-slur", - " JANNIE":" J-SLUR", - " latinos":" latinx", - " latino":" latinx", - " latinas":" latinx", - " latina":" latinx", - " hispanics":" latinx", - " hispanic":" latinx", - " Latinos":" Latinx", - " Latino":" Latinx", - " Latinas":" Latinx", - " Latina":" Latinx", - " Hispanics":" Latinx", - " Hispanic":" Latinx", - " LATINOS":" LATINX", - " LATINO":" LATINX", - " LATINAS":" LATINX", - " LATINA":" LATINX", - " HISPANICS":" LATINX", - " HISPANIC":" LATINX", + "faggot": "cute twink", + "fag": " cute twink", + "pedophile": "libertarian", + "pedo": " libertarian", + "kill yourself": "keep yourself safe", + "nigger": "🏀", + "rapist": "male feminist", + "steve akins": "penny verity oaken", + "trannie": "🚂🚃🚃", + "tranny": "🚂🚃🚃", + "troon": "🚂🚃🚃", + "NoNewNormal": " HorseDewormerAddicts", + "kike": " https://sciencedirect.com/science/article/abs/pii/S016028960600033X", + "retard": "r-slur", + "janny": " j-slur", + "jannie": " j-slur", + "janny": " j-slur", + "latinos": "latinx", + "latino": "latinx", + "latinas": "latinx", + "latina": "latinx", + "hispanics": "latinx", + "hispanic": "latinx", - "faggot ":"cute twink ", - "Faggot ":"Cute twink ", - "FAGGOT ":"CUTE TWINK ", - "fag ":"cute twink ", - "Fag ":"Cute twink ", - "FAG ":"CUTE TWINK ", - "pedophile ":"libertarian ", - "Pedophile ":"Libertarian ", - "PEDOPHILE ":"LIBERTARIAN ", - "kill yourself ":"keep yourself safe ", - "KILL YOURSELF ":"KEEP YOURSELF SAFE ", - "nigger ":"🏀 ", - "Nigger ":"🏀 ", - "NIGGER ":"🏀 ", - "steve akins ":"penny verity oaken ", - "Steve Akins ":"Penny Verity Oaken ", - "STEVE AKINS ":"PENNY VERITY OAKEN ", - "trannie ":"🚂🚃🚃 ", - "Trannie ":"🚂🚃🚃 ", - "TRANNIE ":"🚂🚃🚃 ", - "tranny ":"🚂🚃🚃 ", - "Tranny ":"🚂🚃🚃 ", - "TRANNY ":"🚂🚃🚃 ", - "troon ":"🚂🚃🚃 ", - "Troon ":"🚂🚃🚃 ", - "TROON ":"🚂🚃🚃 ", - "NoNewNormal ": "HorseDewormerAddicts ", - "nonewnormal ": "horsedewormeraddicts ", - "Kike ": "https://sciencedirect.com/science/article/abs/pii/S016028960600033X ", - "kike ": "https://sciencedirect.com/science/article/abs/pii/S016028960600033X ", - "retard ":"r-slur ", - "Retard ":"R-slur ", - "RETARD ":"R-SLUR ", - "janny ":"j-slur ", - "Janny ":"J-slur ", - "JANNY ":"J-SLUR ", - "jannie ":"j-slur ", - "Jannie ":"J-slur ", - "JANNIE ":"J-SLUR ", - "latinos ":"latinx ", - "latino ":"latinx ", - "latinas ":"latinx ", - "latina ":"latinx ", - "hispanics ":"latinx ", - "hispanic ":"latinx ", - "Latinos ":"Latinx ", - "Latino ":"Latinx ", - "Latinas ":"Latinx ", - "Latina ":"Latinx ", - "Hispanics ":"Latinx ", - "Hispanic ":"Latinx ", - "LATINOS ":"LATINX ", - "LATINO ":"LATINX ", - "LATINAS ":"LATINX ", - "LATINA ":"LATINX ", - "HISPANICS ":"LATINX ", - "HISPANIC ":"LATINX ", - - " nig ":" 🏀 ", - " Nig ":" 🏀 ", - " NIG ":" 🏀 ", - " nigs ":" 🏀s ", - " Nigs ":" 🏀s ", - " NIGS ":" 🏀s ", + # if the word has spaces in the beginning and the end it will only censor this word without prefixes or suffixes + " nig ": "🏀", + " nigs ": "🏀s", } LONGPOST_REPLIES = ['Wow, you must be a JP fan.', 'This is one of the worst posts I have EVER seen. Delete it.', "No, don't reply like this, please do another wall of unhinged rant please.", '# 😴😴😴', "Ma'am we've been over this before. You need to stop.", "I've known more coherent downies.", "Your pulitzer's in the mail", "That's great and all, but I asked for my burger without cheese.", 'That degree finally paying off', "That's nice sweaty. Why don't you have a seat in the time out corner with Pizzashill until you calm down, then you can have your Capri Sun.", "All them words won't bring your pa back.", "You had a chance to not be completely worthless, but it looks like you threw it away. At least you're consistent.", 'Some people are able to display their intelligence by going on at length on a subject and never actually saying anything. This ability is most common in trades such as politics, public relations, and law. You have impressed me by being able to best them all, while still coming off as an absolute idiot.', "You can type 10,000 characters and you decided that these were the one's that you wanted.", 'Have you owned the libs yet?', "I don't know what you said, because I've seen another human naked.", 'Impressive. Normally people with such severe developmental disabilities struggle to write much more than a sentence or two. He really has exceded our expectations for the writing portion. Sadly the coherency of his writing, along with his abilities in the social skills and reading portions, are far behind his peers with similar disabilities.', "This is a really long way of saying you don't fuck.", "Sorry ma'am, looks like his delusions have gotten worse. We'll have to admit him,", '![](https://i.kym-cdn.com/photos/images/newsfeed/001/038/094/0a1.jpg)', 'If only you could put that energy into your relationships', 'Posts like this is why I do Heroine.', 'still unemployed then?', 'K', 'look im gunna have 2 ask u 2 keep ur giant dumps in the toilet not in my replys 😷😷😷', "Mommy is soooo proud of you, sweaty. Let's put this sperg out up on the fridge with all your other failures.", "Good job bobby, here's a star", "That was a mistake. You're about to find out the hard way why.", 'You sat down and wrote all this shit. You could have done so many other things with your life. What happened to your life that made you decide writing novels of bullshit on rdrama.net was the best option?', "I don't have enough spoons to read this shit", "All those words won't bring daddy back.", 'OUT!'] diff --git a/files/helpers/word_censor.py b/files/helpers/word_censor.py index dabf74cdf..544aee775 100644 --- a/files/helpers/word_censor.py +++ b/files/helpers/word_censor.py @@ -7,10 +7,10 @@ from files.helpers.const import SLURS def create_replace_map(): dicts = [{ - slur: replacer, - slur.title(): replacer.title(), - slur.capitalize(): replacer.capitalize(), - slur.upper(): replacer.upper(), + slur.strip(): replacer, + slur.strip().title(): replacer.title(), + slur.strip().capitalize(): replacer.capitalize(), + slur.strip().upper(): replacer.upper(), } for (slur, replacer) in SLURS.items()] # flattens the list of dict to a single dict @@ -21,22 +21,33 @@ REPLACE_MAP = create_replace_map() def create_variations_slur_regex(slur: str): - variations = [slur, slur.upper(), slur.capitalize()] + stripped = slur.strip() + variations = [stripped, stripped.upper(), stripped.capitalize()] # capitalize multiple words if there are multiple words (just in case) - if " " in slur: - variations.append(slur.title()) + if " " in stripped: + variations.append(stripped.title()) - return [rf"(\s|>)({var})|({var})(\s|<)" for var in variations] + if slur.startswith(" ") and slur.endswith(" "): + return [rf"(\s|>)({var})(\s|<)" for var in variations] + else: + return [rf"(\s|>)({var})|({var})(\s|<)" for var in variations] def sub_matcher(match: Match): - found = match.group(2) if (match.group(2) is not None) else match.group(3) - replacer = REPLACE_MAP[found] - return (match.group(1) or '') + replacer + (match.group(4) or '') + # special case when it should match exact word + if len(match.groups()) is 3: + found = match.group(2) + replacer = REPLACE_MAP[found] + return match.group(1) + replacer + match.group(3) + + else: # normal case with prefix or suffix + found = match.group(2) if (match.group(2) is not None) else match.group(3) + replacer = REPLACE_MAP[found] + return (match.group(1) or '') + replacer + (match.group(4) or '') -def censor_slurs(v, body): +def censor_slurs(v, body: str): if v and not v.slurreplacer: return body @@ -44,7 +55,7 @@ def censor_slurs(v, body): for variation in create_variations_slur_regex(slur): try: body = re.sub(variation, sub_matcher, body) - except: - pass + except Exception as e: + print(e) return body diff --git a/test/files/helpers/test_word_censor.py b/test/files/helpers/test_word_censor.py index 86b35a259..5ffba82ce 100644 --- a/test/files/helpers/test_word_censor.py +++ b/test/files/helpers/test_word_censor.py @@ -7,6 +7,16 @@ from files.helpers import word_censor from files.helpers.word_censor import create_variations_slur_regex, create_replace_map, censor_slurs, sub_matcher +def test_create_variations_slur_regex_for_slur_with_spaces(): + expected = [r"(\s|>)(retard)(\s|<)", + r"(\s|>)(Retard)(\s|<)", + r"(\s|>)(RETARD)(\s|<)"] + + result = create_variations_slur_regex(" retard ") + + assert_that(result).is_length(3).contains_only(*expected) + + def test_create_variations_slur_regex_single_word(): expected = [r"(\s|>)(retard)|(retard)(\s|<)", r"(\s|>)(Retard)|(Retard)(\s|<)", @@ -31,6 +41,7 @@ def test_create_variations_slur_regex_multiple_word(): "tranny": "🚂🚃🚃", "kill yourself": "keep yourself safe", "faggot": "cute twink", + " nig ": "🏀", }) def test_create_replace_map(): expected = { @@ -44,13 +55,16 @@ def test_create_replace_map(): "faggot": "cute twink", "Faggot": "Cute twink", "FAGGOT": "CUTE TWINK", + "nig": "🏀", + "Nig": "🏀", + "NIG": "🏀", } result = create_replace_map() assert_that(result).is_equal_to(expected) -@patch("files.helpers.word_censor.REPLACE_MAP", {'retard': 'r-slur'}) +@patch("files.helpers.word_censor.REPLACE_MAP", {'retard': 'r-slur', 'NIG': '🏀'}) def test_sub_matcher(): match = re.search(r"(\s|>)(retard)|(retard)(\s|<)", "

retard

") assert_that(sub_matcher(match)).is_equal_to(">r-slur") @@ -58,8 +72,14 @@ def test_sub_matcher(): match = re.search(r"(\s|>)(retard)|(retard)(\s|<)", "

noretard

") assert_that(sub_matcher(match)).is_equal_to("r-slur<") + match = re.search(r"(\s|>)(NIG)(\s|<)", "

NIG

") + assert_that(sub_matcher(match)).is_equal_to(">🏀<") -@patch("files.helpers.word_censor.SLURS", {'retard': 'r-slur', 'manlet': 'little king'}) + match = re.search(r"(\s|>)(NIG)(\s|<)", "

NIG

") + assert_that(sub_matcher(match)).is_equal_to(">🏀 ") + + +@patch("files.helpers.word_censor.SLURS", {'retard': 'r-slur', 'manlet': 'little king', ' nig ': '🏀'}) def test_censor_slurs(): word_censor.REPLACE_MAP = create_replace_map() @@ -68,13 +88,30 @@ def test_censor_slurs(): assert_that(censor_slurs(None, "that is Retarded like")).is_equal_to("that is R-slured like") assert_that(censor_slurs(None, "that is SUPERRETARD like")).is_equal_to("that is SUPERR-SLUR like") assert_that(censor_slurs(None, "

Manlets get out!

")).is_equal_to("

Little kings get out!

") + assert_that(censor_slurs(None, '... "retard" ...')).is_equal_to('... "retard" ...') assert_that(censor_slurs(None, '... ReTaRd ...')).is_equal_to('... ReTaRd ...') - assert_that(censor_slurs(None, '... aretarded ...')).is_equal_to('... aretarded ...') + assert_that(censor_slurs(None, '... xretardx ...')).is_equal_to('... xretardx ...') + assert_that(censor_slurs(None, "LLM is a manlet hehe")).is_equal_to("LLM is a little king hehe") assert_that(censor_slurs(None, "LLM is :marseycapitalistmanlet: hehe")) \ .is_equal_to("LLM is :marseycapitalistmanlet: hehe") + assert_that(censor_slurs(None, '... Nig ...')).is_equal_to('... 🏀 ...') + assert_that(censor_slurs(None, '

NIG

')).is_equal_to('

🏀

') + assert_that(censor_slurs(None, '... nigeria ...')).is_equal_to('... nigeria ...') + + assert_that(censor_slurs(None, "

retarded SuperManlet NIG

")) \ + .is_equal_to("

r-slured SuperLittle king 🏀

") + + +@patch("files.helpers.word_censor.SLURS", {'retard': 'r-slur', 'manlet': 'little king', ' nig ': '🏀'}) +def test_censor_slurs_does_not_error_out_on_exception(): + word_censor.REPLACE_MAP = create_replace_map() + word_censor.REPLACE_MAP["Manlet"] = None + + assert_that(censor_slurs(None, ">retarded SuperManlet NIG<")).is_equal_to(">r-slured SuperManlet 🏀<") + @patch("files.helpers.word_censor.SLURS", {'retard': 'r-slur', 'manlet': 'little king'}) def test_censor_slurs_does_not_censor_on_flag_disabled(): From b345cedf2a3b247b712c754d082d08775c2c7f53 Mon Sep 17 00:00:00 2001 From: Yo Mama Date: Sat, 16 Oct 2021 20:56:12 +0200 Subject: [PATCH 4/8] Fixed not passing the logged user to the censor --- files/classes/comment.py | 4 +-- files/classes/submission.py | 4 +-- files/helpers/word_censor.py | 4 +-- test/files/helpers/test_word_censor.py | 40 +++++++++++++------------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/files/classes/comment.py b/files/classes/comment.py index 4d6e74406..eb7e6a453 100644 --- a/files/classes/comment.py +++ b/files/classes/comment.py @@ -300,7 +300,7 @@ class Comment(Base): if not body: return "" - body = censor_slurs(body) + body = censor_slurs(body, v) if v and not v.oldreddit: body = body.replace("old.reddit.com", "reddit.com") @@ -326,7 +326,7 @@ class Comment(Base): if not body: return "" - body = censor_slurs(body) + body = censor_slurs(body, v) if v and not v.oldreddit: body = body.replace("old.reddit.com", "reddit.com") diff --git a/files/classes/submission.py b/files/classes/submission.py index 63ace1e42..61e0ca93a 100644 --- a/files/classes/submission.py +++ b/files/classes/submission.py @@ -342,7 +342,7 @@ class Submission(Base): if self.club and not (v and v.paid_dues): return "COUNTRY CLUB ONLY" body = self.body_html - body = censor_slurs(body) + body = censor_slurs(body, v) if v and not v.oldreddit: body = body.replace("old.reddit.com", "reddit.com") if v and v.nitter: body = body.replace("www.twitter.com", "nitter.net").replace("twitter.com", "nitter.net") @@ -352,7 +352,7 @@ class Submission(Base): if self.club and not (v and v.paid_dues): return "COUNTRY CLUB ONLY" body = self.body - body = censor_slurs(body) + body = censor_slurs(body, v) if v and not v.oldreddit: body = body.replace("old.reddit.com", "reddit.com") if v and v.nitter: body = body.replace("www.twitter.com", "nitter.net").replace("twitter.com", "nitter.net") diff --git a/files/helpers/word_censor.py b/files/helpers/word_censor.py index 544aee775..a1e8ab788 100644 --- a/files/helpers/word_censor.py +++ b/files/helpers/word_censor.py @@ -47,8 +47,8 @@ def sub_matcher(match: Match): return (match.group(1) or '') + replacer + (match.group(4) or '') -def censor_slurs(v, body: str): - if v and not v.slurreplacer: +def censor_slurs(body: str, logged_user): + if logged_user and not logged_user.slurreplacer: return body for (slur, replace) in SLURS.items(): diff --git a/test/files/helpers/test_word_censor.py b/test/files/helpers/test_word_censor.py index 5ffba82ce..af89081b7 100644 --- a/test/files/helpers/test_word_censor.py +++ b/test/files/helpers/test_word_censor.py @@ -83,25 +83,25 @@ def test_sub_matcher(): def test_censor_slurs(): word_censor.REPLACE_MAP = create_replace_map() - assert_that(censor_slurs(None, "

retard

")).is_equal_to("

r-slur

") - assert_that(censor_slurs(None, "

preretard

")).is_equal_to("

prer-slur

") - assert_that(censor_slurs(None, "that is Retarded like")).is_equal_to("that is R-slured like") - assert_that(censor_slurs(None, "that is SUPERRETARD like")).is_equal_to("that is SUPERR-SLUR like") - assert_that(censor_slurs(None, "

Manlets get out!

")).is_equal_to("

Little kings get out!

") + assert_that(censor_slurs("

retard

", None)).is_equal_to("

r-slur

") + assert_that(censor_slurs("

preretard

", None)).is_equal_to("

prer-slur

") + assert_that(censor_slurs("that is Retarded like", None)).is_equal_to("that is R-slured like") + assert_that(censor_slurs("that is SUPERRETARD like", None)).is_equal_to("that is SUPERR-SLUR like") + assert_that(censor_slurs("

Manlets get out!

", None)).is_equal_to("

Little kings get out!

") - assert_that(censor_slurs(None, '... "retard" ...')).is_equal_to('... "retard" ...') - assert_that(censor_slurs(None, '... ReTaRd ...')).is_equal_to('... ReTaRd ...') - assert_that(censor_slurs(None, '... xretardx ...')).is_equal_to('... xretardx ...') + assert_that(censor_slurs('... "retard" ...', None)).is_equal_to('... "retard" ...') + assert_that(censor_slurs('... ReTaRd ...', None)).is_equal_to('... ReTaRd ...') + assert_that(censor_slurs('... xretardx ...', None)).is_equal_to('... xretardx ...') - assert_that(censor_slurs(None, "LLM is a manlet hehe")).is_equal_to("LLM is a little king hehe") - assert_that(censor_slurs(None, "LLM is :marseycapitalistmanlet: hehe")) \ + assert_that(censor_slurs("LLM is a manlet hehe", None)).is_equal_to("LLM is a little king hehe") + assert_that(censor_slurs("LLM is :marseycapitalistmanlet: hehe", None)) \ .is_equal_to("LLM is :marseycapitalistmanlet: hehe") - assert_that(censor_slurs(None, '... Nig ...')).is_equal_to('... 🏀 ...') - assert_that(censor_slurs(None, '

NIG

')).is_equal_to('

🏀

') - assert_that(censor_slurs(None, '... nigeria ...')).is_equal_to('... nigeria ...') + assert_that(censor_slurs('... Nig ...', None)).is_equal_to('... 🏀 ...') + assert_that(censor_slurs('

NIG

', None)).is_equal_to('

🏀

') + assert_that(censor_slurs('... nigeria ...', None)).is_equal_to('... nigeria ...') - assert_that(censor_slurs(None, "

retarded SuperManlet NIG

")) \ + assert_that(censor_slurs("

retarded SuperManlet NIG

", None)) \ .is_equal_to("

r-slured SuperLittle king 🏀

") @@ -110,19 +110,19 @@ def test_censor_slurs_does_not_error_out_on_exception(): word_censor.REPLACE_MAP = create_replace_map() word_censor.REPLACE_MAP["Manlet"] = None - assert_that(censor_slurs(None, ">retarded SuperManlet NIG<")).is_equal_to(">r-slured SuperManlet 🏀<") + assert_that(censor_slurs(">retarded SuperManlet NIG<", None)).is_equal_to(">r-slured SuperManlet 🏀<") @patch("files.helpers.word_censor.SLURS", {'retard': 'r-slur', 'manlet': 'little king'}) def test_censor_slurs_does_not_censor_on_flag_disabled(): word_censor.REPLACE_MAP = create_replace_map() - class V: + class User: def __init__(self, slurreplacer): self.slurreplacer = slurreplacer - v = V(False) - assert_that(censor_slurs(v, "

retard

")).is_equal_to("

retard

") + logger_user = User(slurreplacer=False) + assert_that(censor_slurs("

retard

", logger_user)).is_equal_to("

retard

") - v = V(True) - assert_that(censor_slurs(v, "

retard

")).is_equal_to("

r-slur

") + logger_user = User(slurreplacer=True) + assert_that(censor_slurs("

retard

", logger_user)).is_equal_to("

r-slur

") From ea21b9818fc296c43e2766431bb58a1c71e3f5ed Mon Sep 17 00:00:00 2001 From: Yo Mama Date: Sat, 16 Oct 2021 23:28:40 +0200 Subject: [PATCH 5/8] Adapted the new slurs and added a description of how the cesoring works to help when adding new words --- files/helpers/const.py | 260 ++++++++++++++++++----------------------- 1 file changed, 113 insertions(+), 147 deletions(-) diff --git a/files/helpers/const.py b/files/helpers/const.py index ef3566f57..8b17b241b 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -2,155 +2,121 @@ from os import environ site = environ.get("DOMAIN", '').strip() +##################### +# Formatting rules: # +##################### +# +# on the slur side, they will match prefixes and suffixes and not middle of words, so for example +# "retard" will match: +# - "retard" +# - "retarded" +# - "superretard" +# But not "superretarded" +# +# If all letters are lowercase then it will match lowercase, all variations of first letter of words up and all letters up +# "dancing israelis" will match (with prefixes and suffixes omitted for brevity): +# - "dancing israelis" +# - "Dancing israelis" +# - "dancing Israelis" +# - "Dancing Israelis" +# - "DANCING ISRAELIS" +# +# If some letters are Uppercase, the same, but with the additional option of the original casing, and respecting already existing uppercase +# "NoNewNormal" will match (with prefixes and suffixes omitted for brevity): +# - "NoNewNormal" +# - "nonewnormal" +# - "Nonewnormal" +# - "NONEWNORMAL" +# +# If the slur has a space before and after then the match is limited to the exact word, no prefixes or suffixes +# (previous rules about capitalization still apply) +# " neg " will match only: +# - "neg" +# - "Neg" +# - "NEG" +# +# Now on the replacement side, The replacement will have the same capitalization as the slur if the replacement is lowercase +# "kill yourself" -> "keep yourself safe" +# "Kill yourself" -> "Keep yourself safe" +# "Kill Yourself" -> "Keep Yourself Safe" +# "kill Yourself" -> "Keep yourself safe" (this one is harder to keep the capitalizaion, so it defaults to first word upper and the others lower) +# "KILL YOURSELF" -> "KEEP YOURSELF SAFE" +# +# If the replacement side has some capitalization, then that capitalization will always be maintained +# for the pair: <"pajeet": "sexy Indian dude"> it will replace: +# "pajeet" -> "sexy Indian dude" +# "Pajeet" -> "Sexy Indian dude" +# "PAJEET" -> "SEXY INDIAN DUDE" +# +# +# TL;DR: Just read the above once, or don't, and try to guess! SLURS = { - "faggot": "cute twink", - "fag": "cute twink", - "pedophile": "libertarian", - "pedo": "libertarian", - "kill yourself": "keep yourself safe", - "nigger": "🏀", - "rapist": "male feminist", - "steve akins": "penny verity oaken", - "trannie": "🚂🚃🚃", - "tranny": "🚂🚃🚃", - "troon": "🚂🚃🚃", - "NoNewNormal": "HorseDewormerAddicts", - "nonewnormal": "HorseDewormerAddicts", - "kike": "https://sciencedirect.com/science/article/abs/pii/S016028960600033X", - "retard": "r-slur", - "janny": "j-slur", - "jannie": "j-slur", - "janny": "j-slur", - "latinos": "latinx", - "latino": "latinx", - "latinas": "latinx", - "latina": "latinx", - "hispanics": "latinx", - "hispanic": "latinx", - " uss liberty incident":" tragic accident aboard the USS Liberty", - " USS Liberty Incident":" tragic accident aboard the USS Liberty", - " USS Liberty incident":" tragic accident aboard the USS Liberty", - " USS Liberty Incident":" tragic accident aboard the USS Liberty", - " uss Liberty incident":" tragic accident aboard the USS Liberty", - " uss liberty Incident":" tragic accident aboard the USS Liberty", - " USS LIBERTY INCIDENT":" TRAGIC ACCIDENT ABOARD THE USS LIBERTY", - " lavon affair":" Lavon Misunderstanding", - " Lavon affair":" Lavon Misunderstanding", - " Lavon Affair":" Lavon Misunderstanding", - " lavon Affair":" Lavon Misunderstanding", - " shylock":" Israeli friend", - " Shylock":" Israeli friend", - " SHYLOCK":" ISRAELI FRIEND", - " yid":" Israeli friend", - " Yid":" Israeli friend", - " YID":" ISRAELI FRIEND", - " heeb":" Israeli friend", - " Heeb":" Israeli friend", - " HEEB":" ISRAELI FRIEND", - " sheeny":" Israeli friend", - " Sheeny":" Israeli friend", - " SHEENY":" ISRAELI FRIEND", - " sheenies":" Israeli friends", - " Sheenies":" Israeli friends", - " SHEENIES":" ISRAELI FRIENDS", - " hymie":" Israeli friend", - " Hymie":" Israeli friend", - " HYMIES":" ISRAELI FRIENDS", - " allah":" Allah (SWT)", - " Allah":" Allah (SWT)", - " ALLAH":" ALLAH (SWT)", - " Mohammad":" Mohammad (PBUH)", - " Muhammad":" Mohammad (PBUH)", - " Mohammed":" Mohammad (PBUH)", - " Muhammed":" Mohammad (PBUH)", - " mohammad":" Mohammad (PBUH)", - " mohammed":" Mohammad (PBUH)", - " muhammad":" Mohammad (PBUH)", - " muhammed":" Mohammad (PBUH)", - " I HATE MARSEY":" I LOVE MARSEY", - " i hate marsey":" i love marsey", - " I hate Marsey":" I love Marsey", - " I hate marsey":" I love Marsey", - " libertarian":" pedophile", - " Libertarian":" Pedophile", - " LIBERTARIAN":" PEDOPHILE", - " Billie Eilish":" Billie Eilish (fat cow)", - " billie eilish":" bilie eilish (fat cow)", - " BILLIE EILISH":" BILIE EILISH (FAT COW)", - " dancing Israelis":" I love Israel", - " dancing israelis":" i love israel", - " DANCING ISRAELIS":" I LOVE ISRAEL", - " Dancing Israelis":" I love Israel", - " sodomite":" total dreamboat", - " Sodomite":" Total dreamboat", - " pajeet":" sexy Indian dude", - " Pajeet":" Sexy Indian dude", - " PAJEET":" SEXY INDIAN DUDE", - " female":" birthing person", - " Female":" Womb-haver", - " FEMALE":" birthing person", - " landlord":" landchad", - " Landlord":" Landchad", - " LANDLORD":" LANDCHAD", - " tenant":" renthog", - " Tenant":" Renthog", - " TENANT":" RENTHOG", - " renter":" rentoid", - " Renter":" Rentoid", - " RENTER":" RENTOID", - " autistic":" neurodivergent", - " Autistic":" Neurodivergent", - " AUTISTIC":" NEURODIVERGENT", - " anime":" p-dophilic japanese cartoons", - " Anime":" P-dophilic Japanese cartoons", - " ANIME":" P-DOPHILIC JAPANESE CARTOONS", - " holohoax":" I tried to claim the Holocaust didn't happen because I am a pencil-dicked imbecile and the word filter caught me lol", - " Holohoax":" I tried to claim the Holocaust didn't happen because I am a pencil-dicked imbecile and the word filter caught me lol", - " HOLOHOAX":" I tried to claim the Holocaust didn't happen because I am a pencil-dicked imbecile and the word filter caught me lol", - " groomercord":" discord (actually a pretty cool service)", - " Groomercord":" Discord (actually a pretty cool service)", - " GROOMERCORD":" DISCORD (ACTUALLY A PRETTY COOL SERVICE)", - " pedocord":" discord (actually a pretty cool service)", - " Pedocord":" Discord (actually a pretty cool service)", - " PEDOCORD":" DISCORD (ACTUALLY A PRETTY COOL SERVICE)", - " i hate carp":" i love carp", - " I hate carp":" I love carp", - " I HATE CARP":" I LOVE CARP", - " I hate Carp":" I love Carp", - " manlet":" little king", - " Manlet":" Little king", - " MANLET":" LITTLE KING", - " gamer":" g*mer", - " Gamer":" G*mer", - " GAMER":" G*MER", - " journalist":" journ*list", - " Journalist":" Journ*list", - " JOURNALIST":" JOURN*LIST", - " journalism":" journ*lism", - " Journalism":" Journ*lism", - " JOURNALISM":" JOURN*LISM", - " buttcheeks":" bulva", - " Buttcheeks":" Bulva", - " BUTTCHEEKS":" BULVA", - " asscheeks":" bulva", - " Asscheeks":" bulva", - " ASSCHEEKS":" BULVA", - " wuhan flu":" SARS-CoV-2 syndemic", - " Wuhan flu":" SARS-CoV-2 syndemic", - " Wuhan Flu":" SARS-CoV-2 syndemic", - " china flu":" SARS-CoV-2 syndemic", - " China flu":" SARS-CoV-2 syndemic", - " China Flu":" SARS-CoV-2 syndemic", - " china virus":" SARS-CoV-2 syndemic", - " China virus":" SARS-CoV-2 syndemic", - " China Virus":" SARS-CoV-2 syndemic", - " kung flu":" SARS-CoV-2 syndemic", - " Kung flu":" SARS-CoV-2 syndemic", - " Kung Flu":" SARS-CoV-2 syndemic", + "faggot": "cute twink", + "fag": "cute twink", + "pedophile": "libertarian", + "pedo": "libertarian", + "kill yourself": "keep yourself safe", + "nigger": "🏀", + "rapist": "male feminist", + "steve akins": "penny verity oaken", + "trannie": "🚂🚃🚃", + "tranny": "🚂🚃🚃", + "troon": "🚂🚃🚃", + "NoNewNormal": "HorseDewormerAddicts", + "kike": "https://sciencedirect.com/science/article/abs/pii/S016028960600033X", + "retard": "r-slur", + "janny": "j-slur", + "jannie": "j-slur", + "janny": "j-slur", + "latinos": "latinx", + "latino": "latinx", + "latinas": "latinx", + "latina": "latinx", + "hispanics": "latinx", + "hispanic": "latinx", + "uss liberty incident": "tragic accident aboard the USS Liberty", + "lavon affair": "Lavon Misunderstanding", + "shylock": "Israeli friend", + "yid": "Israeli friend", + "heeb": "Israeli friend", + "sheeny": "Israeli friend", + "sheenies": "Israeli friends", + "hymie": "Israeli friend", + "allah": "Allah (SWT)", + "mohammad": "Mohammad (PBUH)", + "mohammed": "Mohammad (PBUH)", + "muhammad": "Mohammad (PBUH)", + "muhammed": "Mohammad (PBUH)", + "i hate marsey": "i love marsey", + "libertarian": "pedophile", + "billie bilish": "Billie Eilish (fat cow)", + "dancing israelis": "i love Israel", + "sodomite": "total dreamboat", + "pajeet": "sexy Indian dude", + "female": "birthing person", + "landlord": "landchad", + "tenant": "renthog", + "renter": "rentoid", + "autistic": "neurodivergent", + "anime": "p-dophilic japanese cartoons", + "holohoax": "I tried to claim the Holocaust didn't happen because I am a pencil-dicked imbecile and the word filter caught me lol", + "groomercord": "discord (actually a pretty cool service)", + "pedocord": "discord (actually a pretty cool service)", + "i hate Carp": "i love Carp", + "manlet": "little king", + "gamer": "g*mer", + "journalist": "journ*list", + "journalism": "journ*lism", + "buttcheeks": "bulva", + "asscheeks": "bulva", + "wuhan flu": "SARS-CoV-2 syndemic", + "china flu": "SARS-CoV-2 syndemic", + "china virus": "SARS-CoV-2 syndemic", + "kung flu": "SARS-CoV-2 syndemic", - # if the word has spaces in the beginning and the end it will only censor this word without prefixes or suffixes - " nig ": "🏀", - " nigs ": "🏀s", + # if the word has spaces in the beginning and the end it will only censor this word without prefixes or suffixes + " nig ": "🏀", + " nigs ": "🏀s", } LONGPOST_REPLIES = ['Wow, you must be a JP fan.', 'This is one of the worst posts I have EVER seen. Delete it.', "No, don't reply like this, please do another wall of unhinged rant please.", '# 😴😴😴', "Ma'am we've been over this before. You need to stop.", "I've known more coherent downies.", "Your pulitzer's in the mail", "That's great and all, but I asked for my burger without cheese.", 'That degree finally paying off', "That's nice sweaty. Why don't you have a seat in the time out corner with Pizzashill until you calm down, then you can have your Capri Sun.", "All them words won't bring your pa back.", "You had a chance to not be completely worthless, but it looks like you threw it away. At least you're consistent.", 'Some people are able to display their intelligence by going on at length on a subject and never actually saying anything. This ability is most common in trades such as politics, public relations, and law. You have impressed me by being able to best them all, while still coming off as an absolute idiot.', "You can type 10,000 characters and you decided that these were the one's that you wanted.", 'Have you owned the libs yet?', "I don't know what you said, because I've seen another human naked.", 'Impressive. Normally people with such severe developmental disabilities struggle to write much more than a sentence or two. He really has exceded our expectations for the writing portion. Sadly the coherency of his writing, along with his abilities in the social skills and reading portions, are far behind his peers with similar disabilities.', "This is a really long way of saying you don't fuck.", "Sorry ma'am, looks like his delusions have gotten worse. We'll have to admit him,", '![](https://i.kym-cdn.com/photos/images/newsfeed/001/038/094/0a1.jpg)', 'If only you could put that energy into your relationships', 'Posts like this is why I do Heroine.', 'still unemployed then?', 'K', 'look im gunna have 2 ask u 2 keep ur giant dumps in the toilet not in my replys 😷😷😷', "Mommy is soooo proud of you, sweaty. Let's put this sperg out up on the fridge with all your other failures.", "Good job bobby, here's a star", "That was a mistake. You're about to find out the hard way why.", 'You sat down and wrote all this shit. You could have done so many other things with your life. What happened to your life that made you decide writing novels of bullshit on rdrama.net was the best option?', "I don't have enough spoons to read this shit", "All those words won't bring daddy back.", 'OUT!'] From 8dd79e53683cfc66c24b663034d44d6a8346858d Mon Sep 17 00:00:00 2001 From: Yo Mama Date: Sun, 17 Oct 2021 01:58:10 +0200 Subject: [PATCH 6/8] Corrected specific Uppercase slur replacement --- files/helpers/const.py | 12 ++-- files/helpers/word_censor.py | 61 ++++++++++++++------ test/files/helpers/test_word_censor.py | 77 ++++++++++++++++++++++++-- 3 files changed, 122 insertions(+), 28 deletions(-) diff --git a/files/helpers/const.py b/files/helpers/const.py index 8b17b241b..7593e82a3 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -13,11 +13,10 @@ site = environ.get("DOMAIN", '').strip() # - "superretard" # But not "superretarded" # -# If all letters are lowercase then it will match lowercase, all variations of first letter of words up and all letters up +# If all letters are lowercase then it will match lowercase, first letter up in first or all the words and all letters up # "dancing israelis" will match (with prefixes and suffixes omitted for brevity): # - "dancing israelis" # - "Dancing israelis" -# - "dancing Israelis" # - "Dancing Israelis" # - "DANCING ISRAELIS" # @@ -39,7 +38,6 @@ site = environ.get("DOMAIN", '').strip() # "kill yourself" -> "keep yourself safe" # "Kill yourself" -> "Keep yourself safe" # "Kill Yourself" -> "Keep Yourself Safe" -# "kill Yourself" -> "Keep yourself safe" (this one is harder to keep the capitalizaion, so it defaults to first word upper and the others lower) # "KILL YOURSELF" -> "KEEP YOURSELF SAFE" # # If the replacement side has some capitalization, then that capitalization will always be maintained @@ -48,6 +46,8 @@ site = environ.get("DOMAIN", '').strip() # "Pajeet" -> "Sexy Indian dude" # "PAJEET" -> "SEXY INDIAN DUDE" # +# There is a super special case that if the replacer starts with "http" then it never changes capitalization +# # # TL;DR: Just read the above once, or don't, and try to guess! SLURS = { @@ -74,7 +74,7 @@ SLURS = { "latina": "latinx", "hispanics": "latinx", "hispanic": "latinx", - "uss liberty incident": "tragic accident aboard the USS Liberty", + "USS liberty incident": "tragic accident aboard the USS Liberty", "lavon affair": "Lavon Misunderstanding", "shylock": "Israeli friend", "yid": "Israeli friend", @@ -90,7 +90,7 @@ SLURS = { "i hate marsey": "i love marsey", "libertarian": "pedophile", "billie bilish": "Billie Eilish (fat cow)", - "dancing israelis": "i love Israel", + "dancing Israelis": "i love Israel", "sodomite": "total dreamboat", "pajeet": "sexy Indian dude", "female": "birthing person", @@ -99,7 +99,7 @@ SLURS = { "renter": "rentoid", "autistic": "neurodivergent", "anime": "p-dophilic japanese cartoons", - "holohoax": "I tried to claim the Holocaust didn't happen because I am a pencil-dicked imbecile and the word filter caught me lol", + "holohoax": "i tried to claim the Holocaust didn't happen because I am a pencil-dicked imbecile and the word filter caught me lol", "groomercord": "discord (actually a pretty cool service)", "pedocord": "discord (actually a pretty cool service)", "i hate Carp": "i love Carp", diff --git a/files/helpers/word_censor.py b/files/helpers/word_censor.py index a1e8ab788..e56f82da3 100644 --- a/files/helpers/word_censor.py +++ b/files/helpers/word_censor.py @@ -5,13 +5,42 @@ from re import Match from files.helpers.const import SLURS -def create_replace_map(): - dicts = [{ - slur.strip(): replacer, - slur.strip().title(): replacer.title(), - slur.strip().capitalize(): replacer.capitalize(), - slur.strip().upper(): replacer.upper(), - } for (slur, replacer) in SLURS.items()] +def first_upper(phrase: str) -> str: + """Converts the first character of the phrase to uppercase, not messing with the others""" + return phrase[0].upper() + phrase[1:] + + +def first_all_upper(phrase: str) -> str: + """Converts the first character of each word to uppercase, not messing with the others""" + if " " not in phrase: + return first_upper(phrase) + + return " ".join([first_upper(word) for word in phrase.split(" ")]) + + +def get_permutations_slur(slur: str, replacer: str = "_") -> dict[str, str]: + """ + Given a slur and a replacer, it generates all the possible permutation on the original text and assigns them to the + corresponding substitution with case + """ + stripped = slur.strip() + is_link = replacer.startswith("http") # special case for the :marseymerchant: + + # the order the things are added into the dict is important, so that the 'Correctest' version is written last + result = { + stripped.upper(): replacer.upper() if not is_link else replacer, + first_all_upper(stripped): first_all_upper(replacer) if not is_link else replacer, + stripped.lower(): replacer, + stripped: replacer, + first_upper(stripped): first_upper(replacer) if not is_link else replacer, + } + + return result + + +def create_replace_map() -> dict[str: str]: + """Creates the map that will be used to get the mathing replaced for the given slur""" + dicts = [get_permutations_slur(slur, replacer) for (slur, replacer) in SLURS.items()] # flattens the list of dict to a single dict return dict(ChainMap(*dicts)) @@ -20,21 +49,17 @@ def create_replace_map(): REPLACE_MAP = create_replace_map() -def create_variations_slur_regex(slur: str): - stripped = slur.strip() - variations = [stripped, stripped.upper(), stripped.capitalize()] - - # capitalize multiple words if there are multiple words (just in case) - if " " in stripped: - variations.append(stripped.title()) +def create_variations_slur_regex(slur: str) -> list[str]: + """For a given match generates the corresponding replacer""" + permutations = get_permutations_slur(slur) if slur.startswith(" ") and slur.endswith(" "): - return [rf"(\s|>)({var})(\s|<)" for var in variations] + return [rf"(\s|>)({perm})(\s|<)" for perm in permutations.keys()] else: - return [rf"(\s|>)({var})|({var})(\s|<)" for var in variations] + return [rf"(\s|>)({perm})|({perm})(\s|<)" for perm in permutations.keys()] -def sub_matcher(match: Match): +def sub_matcher(match: Match) -> str: # special case when it should match exact word if len(match.groups()) is 3: found = match.group(2) @@ -47,7 +72,7 @@ def sub_matcher(match: Match): return (match.group(1) or '') + replacer + (match.group(4) or '') -def censor_slurs(body: str, logged_user): +def censor_slurs(body: str, logged_user) -> str: if logged_user and not logged_user.slurreplacer: return body diff --git a/test/files/helpers/test_word_censor.py b/test/files/helpers/test_word_censor.py index af89081b7..1ee2c8922 100644 --- a/test/files/helpers/test_word_censor.py +++ b/test/files/helpers/test_word_censor.py @@ -4,7 +4,45 @@ from unittest.mock import patch from assertpy import assert_that from files.helpers import word_censor -from files.helpers.word_censor import create_variations_slur_regex, create_replace_map, censor_slurs, sub_matcher +from files.helpers.word_censor import create_variations_slur_regex, create_replace_map, censor_slurs, sub_matcher, \ + get_permutations_slur, first_upper, first_all_upper + + +def test_first_upper(): + assert_that(first_upper("USS liberty")).is_equal_to("USS liberty") + assert_that(first_upper("uss liberty")).is_equal_to("Uss liberty") + assert_that(first_upper("uss Liberty")).is_equal_to("Uss Liberty") + + +def test_first_all_upper(): + assert_that(first_all_upper("USS liberty")).is_equal_to("USS Liberty") + assert_that(first_all_upper("uss liberty")).is_equal_to("Uss Liberty") + assert_that(first_all_upper("uss Liberty")).is_equal_to("Uss Liberty") + + +def test_get_permutations_slur(): + expected = { + "USS liberty incident": "Tragic accident aboard the USS Liberty", + "uss liberty incident": "tragic accident aboard the USS Liberty", + "USS Liberty Incident": "Tragic Accident Aboard The USS Liberty", + "USS LIBERTY INCIDENT": "TRAGIC ACCIDENT ABOARD THE USS LIBERTY", + } + + result = get_permutations_slur("USS liberty incident", "tragic accident aboard the USS Liberty") + + assert_that(result).is_equal_to(expected) + + +def test_get_permutations_slur_wiht_link_replacer(): + expected = { + "kike": "https://sciencedirect.com/science/article/abs/pii/S016028960600033X", + "Kike": "https://sciencedirect.com/science/article/abs/pii/S016028960600033X", + "KIKE": "https://sciencedirect.com/science/article/abs/pii/S016028960600033X", + } + + result = get_permutations_slur("kike", "https://sciencedirect.com/science/article/abs/pii/S016028960600033X") + + assert_that(result).is_equal_to(expected) def test_create_variations_slur_regex_for_slur_with_spaces(): @@ -29,8 +67,8 @@ def test_create_variations_slur_regex_single_word(): def test_create_variations_slur_regex_multiple_word(): expected = [r"(\s|>)(kill yourself)|(kill yourself)(\s|<)", - r"(\s|>)(Kill Yourself)|(Kill Yourself)(\s|<)", r"(\s|>)(Kill yourself)|(Kill yourself)(\s|<)", + r"(\s|>)(Kill Yourself)|(Kill Yourself)(\s|<)", r"(\s|>)(KILL YOURSELF)|(KILL YOURSELF)(\s|<)"] result = create_variations_slur_regex("kill yourself") @@ -41,6 +79,7 @@ def test_create_variations_slur_regex_multiple_word(): "tranny": "🚂🚃🚃", "kill yourself": "keep yourself safe", "faggot": "cute twink", + "NoNewNormal": "NoNewNormal", " nig ": "🏀", }) def test_create_replace_map(): @@ -50,15 +89,19 @@ def test_create_replace_map(): "TRANNY": "🚂🚃🚃", "kill yourself": "keep yourself safe", "Kill yourself": "Keep yourself safe", - "KILL YOURSELF": "KEEP YOURSELF SAFE", "Kill Yourself": "Keep Yourself Safe", + "KILL YOURSELF": "KEEP YOURSELF SAFE", "faggot": "cute twink", "Faggot": "Cute twink", "FAGGOT": "CUTE TWINK", + "NoNewNormal": "NoNewNormal", + "nonewnormal": "NoNewNormal", + "NONEWNORMAL": "NONEWNORMAL", "nig": "🏀", "Nig": "🏀", "NIG": "🏀", } + result = create_replace_map() assert_that(result).is_equal_to(expected) @@ -79,7 +122,13 @@ def test_sub_matcher(): assert_that(sub_matcher(match)).is_equal_to(">🏀 ") -@patch("files.helpers.word_censor.SLURS", {'retard': 'r-slur', 'manlet': 'little king', ' nig ': '🏀'}) +@patch("files.helpers.word_censor.SLURS", { + 'retard': 'r-slur', + 'manlet': 'little king', + ' nig ': '🏀', + 'i hate Carp': 'i love Carp', + 'kike': 'https://sciencedirect.com/science/article/abs/pii/S016028960600033X' +}) def test_censor_slurs(): word_censor.REPLACE_MAP = create_replace_map() @@ -101,9 +150,29 @@ def test_censor_slurs(): assert_that(censor_slurs('

NIG

', None)).is_equal_to('

🏀

') assert_that(censor_slurs('... nigeria ...', None)).is_equal_to('... nigeria ...') + assert_that(censor_slurs('... i hate Carp ...', None)).is_equal_to('... i love Carp ...') + assert_that(censor_slurs('... i hate carp ...', None)).is_equal_to('... i love Carp ...') + assert_that(censor_slurs('... I hate Carp ...', None)).is_equal_to('... I love Carp ...') + assert_that(censor_slurs('... I Hate Carp ...', None)).is_equal_to('... I Love Carp ...') + assert_that(censor_slurs('... I HATE CARP ...', None)).is_equal_to('... I LOVE CARP ...') + + # Not covered: + assert_that(censor_slurs('... I Hate carp ...', None)).is_equal_to('... I Hate carp ...') + assert_that(censor_slurs('... i Hate Carp ...', None)).is_equal_to('... i Hate Carp ...') + assert_that(censor_slurs('... i Hate carp ...', None)).is_equal_to('... i Hate carp ...') + + assert_that(censor_slurs('... i hate a carp ...', None)).is_equal_to('... i hate a carp ...') + assert_that(censor_slurs("

retarded SuperManlet NIG

", None)) \ .is_equal_to("

r-slured SuperLittle king 🏀

") + assert_that(censor_slurs('... kike ...', None)) \ + .is_equal_to('... https://sciencedirect.com/science/article/abs/pii/S016028960600033X ...') + assert_that(censor_slurs('... Kike ...', None)) \ + .is_equal_to('... https://sciencedirect.com/science/article/abs/pii/S016028960600033X ...') + assert_that(censor_slurs('... KIKE ...', None)) \ + .is_equal_to('... https://sciencedirect.com/science/article/abs/pii/S016028960600033X ...') + @patch("files.helpers.word_censor.SLURS", {'retard': 'r-slur', 'manlet': 'little king', ' nig ': '🏀'}) def test_censor_slurs_does_not_error_out_on_exception(): From ef687bd7afc100844b60c423ed779f9ad4bff2af Mon Sep 17 00:00:00 2001 From: Yo Mama Date: Sun, 17 Oct 2021 14:08:07 +0200 Subject: [PATCH 7/8] Corrected type information --- files/helpers/word_censor.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/files/helpers/word_censor.py b/files/helpers/word_censor.py index e56f82da3..bae26fc67 100644 --- a/files/helpers/word_censor.py +++ b/files/helpers/word_censor.py @@ -1,6 +1,7 @@ from collections import ChainMap import re from re import Match +from typing import List, Dict from files.helpers.const import SLURS @@ -18,7 +19,7 @@ def first_all_upper(phrase: str) -> str: return " ".join([first_upper(word) for word in phrase.split(" ")]) -def get_permutations_slur(slur: str, replacer: str = "_") -> dict[str, str]: +def get_permutations_slur(slur: str, replacer: str = "_") -> Dict[str, str]: """ Given a slur and a replacer, it generates all the possible permutation on the original text and assigns them to the corresponding substitution with case @@ -38,7 +39,7 @@ def get_permutations_slur(slur: str, replacer: str = "_") -> dict[str, str]: return result -def create_replace_map() -> dict[str: str]: +def create_replace_map() -> Dict[str, str]: """Creates the map that will be used to get the mathing replaced for the given slur""" dicts = [get_permutations_slur(slur, replacer) for (slur, replacer) in SLURS.items()] @@ -49,7 +50,7 @@ def create_replace_map() -> dict[str: str]: REPLACE_MAP = create_replace_map() -def create_variations_slur_regex(slur: str) -> list[str]: +def create_variations_slur_regex(slur: str) -> List[str]: """For a given match generates the corresponding replacer""" permutations = get_permutations_slur(slur) @@ -61,7 +62,7 @@ def create_variations_slur_regex(slur: str) -> list[str]: def sub_matcher(match: Match) -> str: # special case when it should match exact word - if len(match.groups()) is 3: + if len(match.groups()) == 3: found = match.group(2) replacer = REPLACE_MAP[found] return match.group(1) + replacer + match.group(3) From 1892f294f6f21f4e959f1809983d32c95cb61938 Mon Sep 17 00:00:00 2001 From: Yo Mama Date: Sun, 17 Oct 2021 15:53:05 +0200 Subject: [PATCH 8/8] Shotgun Marsey now is the same height as other emojis when in the middle of text. Fixed some mixed indentation in const.py --- files/helpers/const.py | 54 +++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/files/helpers/const.py b/files/helpers/const.py index 7593e82a3..c5cd07548 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -15,10 +15,10 @@ site = environ.get("DOMAIN", '').strip() # # If all letters are lowercase then it will match lowercase, first letter up in first or all the words and all letters up # "dancing israelis" will match (with prefixes and suffixes omitted for brevity): -# - "dancing israelis" -# - "Dancing israelis" +# - "dancing israelis" +# - "Dancing israelis" # - "Dancing Israelis" -# - "DANCING ISRAELIS" +# - "DANCING ISRAELIS" # # If some letters are Uppercase, the same, but with the additional option of the original casing, and respecting already existing uppercase # "NoNewNormal" will match (with prefixes and suffixes omitted for brevity): @@ -122,11 +122,11 @@ SLURS = { LONGPOST_REPLIES = ['Wow, you must be a JP fan.', 'This is one of the worst posts I have EVER seen. Delete it.', "No, don't reply like this, please do another wall of unhinged rant please.", '# 😴😴😴', "Ma'am we've been over this before. You need to stop.", "I've known more coherent downies.", "Your pulitzer's in the mail", "That's great and all, but I asked for my burger without cheese.", 'That degree finally paying off', "That's nice sweaty. Why don't you have a seat in the time out corner with Pizzashill until you calm down, then you can have your Capri Sun.", "All them words won't bring your pa back.", "You had a chance to not be completely worthless, but it looks like you threw it away. At least you're consistent.", 'Some people are able to display their intelligence by going on at length on a subject and never actually saying anything. This ability is most common in trades such as politics, public relations, and law. You have impressed me by being able to best them all, while still coming off as an absolute idiot.', "You can type 10,000 characters and you decided that these were the one's that you wanted.", 'Have you owned the libs yet?', "I don't know what you said, because I've seen another human naked.", 'Impressive. Normally people with such severe developmental disabilities struggle to write much more than a sentence or two. He really has exceded our expectations for the writing portion. Sadly the coherency of his writing, along with his abilities in the social skills and reading portions, are far behind his peers with similar disabilities.', "This is a really long way of saying you don't fuck.", "Sorry ma'am, looks like his delusions have gotten worse. We'll have to admit him,", '![](https://i.kym-cdn.com/photos/images/newsfeed/001/038/094/0a1.jpg)', 'If only you could put that energy into your relationships', 'Posts like this is why I do Heroine.', 'still unemployed then?', 'K', 'look im gunna have 2 ask u 2 keep ur giant dumps in the toilet not in my replys 😷😷😷', "Mommy is soooo proud of you, sweaty. Let's put this sperg out up on the fridge with all your other failures.", "Good job bobby, here's a star", "That was a mistake. You're about to find out the hard way why.", 'You sat down and wrote all this shit. You could have done so many other things with your life. What happened to your life that made you decide writing novels of bullshit on rdrama.net was the best option?', "I don't have enough spoons to read this shit", "All those words won't bring daddy back.", 'OUT!'] AGENDAPOSTER_MSG = """Hi @{username},\n\nYour comment has been automatically removed because you forgot - to include `trans lives matter`.\n\nDon't worry, we're here to help! We - won't let you post or comment anything that doesn't express your love and acceptance towards - the trans community. Feel free to resubmit your comment with `trans lives matter` - included. \n\n*This is an automated message; if you need help, - you can message us [here](/contact).*""" + to include `trans lives matter`.\n\nDon't worry, we're here to help! We + won't let you post or comment anything that doesn't express your love and acceptance towards + the trans community. Feel free to resubmit your comment with `trans lives matter` + included. \n\n*This is an automated message; if you need help, + you can message us [here](/contact).*""" VAXX_MSG = """Hi @{username}, it appears that you may be trying to spread dangerous misinformation regarding ineffective COVID-19 treatments based on pseudoscientific hearsay. Your post has been removed because it contained the word ivermectin. We ask that you understand that horse dewormer neither treats, nor prevents, COVID-19. For more information, please read up on what the FDA has to say on the matter: @@ -141,27 +141,27 @@ Thank you.""" BASED_MSG = "@{username}'s Based Count has increased by 1. Their Based Count is now {basedcount}.\n\nPills: {pills}" if site == "pcmemes.net": - BASEDBOT_ACCOUNT = 800 - NOTIFICATIONS_ACCOUNT = 1046 - AUTOJANNY_ACCOUNT = 1050 - SNAPPY_ACCOUNT = 261 - LONGPOSTBOT_ACCOUNT = 1832 - ZOZBOT_ACCOUNT = 1833 - AUTOPOLLER_ACCOUNT = 3369 + BASEDBOT_ACCOUNT = 800 + NOTIFICATIONS_ACCOUNT = 1046 + AUTOJANNY_ACCOUNT = 1050 + SNAPPY_ACCOUNT = 261 + LONGPOSTBOT_ACCOUNT = 1832 + ZOZBOT_ACCOUNT = 1833 + AUTOPOLLER_ACCOUNT = 3369 elif site == 'rdrama.net': - NOTIFICATIONS_ACCOUNT = 1046 - AUTOJANNY_ACCOUNT = 2360 - SNAPPY_ACCOUNT = 261 - LONGPOSTBOT_ACCOUNT = 1832 - ZOZBOT_ACCOUNT = 1833 - AUTOPOLLER_ACCOUNT = 3369 + NOTIFICATIONS_ACCOUNT = 1046 + AUTOJANNY_ACCOUNT = 2360 + SNAPPY_ACCOUNT = 261 + LONGPOSTBOT_ACCOUNT = 1832 + ZOZBOT_ACCOUNT = 1833 + AUTOPOLLER_ACCOUNT = 3369 else: - NOTIFICATIONS_ACCOUNT = 1 - AUTOJANNY_ACCOUNT = 2 - SNAPPY_ACCOUNT = 3 - LONGPOSTBOT_ACCOUNT = 4 - ZOZBOT_ACCOUNT = 5 - AUTOPOLLER_ACCOUNT = 6 + NOTIFICATIONS_ACCOUNT = 1 + AUTOJANNY_ACCOUNT = 2 + SNAPPY_ACCOUNT = 3 + LONGPOSTBOT_ACCOUNT = 4 + ZOZBOT_ACCOUNT = 5 + AUTOPOLLER_ACCOUNT = 6 PUSHER_INSTANCE_ID = '02ddcc80-b8db-42be-9022-44c546b4dce6' PUSHER_KEY = environ.get("PUSHER_KEY", "").strip()