Add the "Misogynist" award to harass incels #154

Merged
Aevann merged 11 commits from :misogynist_award into master 2023-06-21 12:36:08 +00:00
24 changed files with 234 additions and 40 deletions

View File

@ -88,6 +88,7 @@
.fa-link:before{content:"\f0c1"}
.fa-link-slash:before{content:"\f127"}
.fa-lock:before{content:"\f023"}
.fa-phone:before{content:"\f095"}
.fa-lock-alt:before{content:"\f30d"}
.fa-search:before{content:"\f002"}
.fa-cloudflare:before{content:"\e07d"}
@ -6669,6 +6670,12 @@ g {
font-weight: 700 !important;
}
.queen:not(a) {
color: hotpink !important;
font-weight: 700 !important;
text-transform: lowercase !important;
}
.rainbow-text:not(a) > p {
color: transparent !important;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -96,6 +96,7 @@ class User(Base):
coins_spent_on_hats = Column(Integer, default=0)
lootboxes_bought = Column(Integer, default=0)
agendaposter = Column(Integer, default=0)
queen = Column(Integer, default=0)
agendaposter_phrase = Column(String)
is_activated = Column(Boolean, default=False)
shadowbanned = Column(Integer, ForeignKey("users.id"))
@ -816,6 +817,10 @@ class User(Base):
return f"{SITE_FULL}/e/chudsey.webp"
if self.rainbow:
return f"{SITE_FULL}/e/marseysalutepride.webp"
if self.queen:
number_of_girl_pfps = 8
pic_num = (self.id % number_of_girl_pfps) + 1
return f"{SITE_FULL}/i/pfps/girls/{pic_num}.webp"
if self.profileurl and self.can_see_my_shit:
if self.profileurl.startswith('/'): return SITE_FULL + self.profileurl
return self.profileurl

View File

@ -531,6 +531,18 @@ AWARDS = {
"ghost": False,
"enabled": True,
},
"queen": {
"kind": "queen",
"title": "Queen",
"description": "Gets the recipient in touch with their feminine side for 24 hours.",
"icon": "fas fa-phone",
"color": "text-purple",
"price": 1000,
"deflectable": True,
"cosmetic": False,
"ghost": False,
"enabled": True,
},
"offsitementions": {
"kind": "offsitementions",
"title": "Y'all Seein' Eye",

View File

@ -101,6 +101,77 @@ AJ_REPLACEMENTS = {
'EVERYBODY': 'EVERYPONY',
}
GIRL_PHRASES = [
"ok so $",
"literally, $",
"i feel like $",
"my heart is telling me $",
"its almost as if $",
"omg! $",
"im literally screaming, $",
"$ and thats the tea, sis",
"$ but go off i guess",
"$ but go off",
"$, karen",
"$ but its whatever"
]
GIRL_NAME_PREFIX = [
'the',
'a',
'another',
'justA',
'one',
'that',
'itsA',
'theOnly'
]
GIRL_NAME_ADJECTIVE = [
'starry',
'serene',
'sweet',
'pretty',
'cute',
'chonky',
'fuzzy',
'bitchy',
'slutty',
'lovely',
'comfy',
'hot',
'funky',
'polite',
'cute',
'sexy',
'silver',
'juicy',
'magical',
'nice',
'normal'
]
GIRL_NAME_NOUN = [
'crown',
'throne',
'lake',
'tree',
'candy',
'gal',
'idol',
'teddy',
'queen',
'girl',
'woman',
'lady',
'ghost',
'friend',
'doll',
'bear',
'witch',
'bitch',
'duck',
'cottage',
'fairy',
]
SLURS = {
"(?<!\\bs)nigger": "BIPOC",
"negroid": "BIPOC",
@ -1084,6 +1155,7 @@ forced_hats = {
"earlylife": ("The Merchant", "SHUT IT DOWN, the goys know!"),
"marsify": ("Marsified", "I can't pick my own Marseys, help!"),
"is_suspended": ("Behind Bars", "This user is banned and needs to do better!"),
"queen": ("Emoji Crown (hearts and shooting stars)", "This user is getting in touch with her feminine side 🥰"),
"agendaposter": (("Egg_irl", "This user is getting in touch with xir identity!"),
("Trans Flag", "Just in case you forgot, trans lives matter."),
("Trans Flag II", "Your egg is cracked; wear it with pride!"),

View File

@ -209,6 +209,10 @@ def _award_timers_task():
_process_timer(User.earlylife, [169], "The earlylife award you received has expired!")
_process_timer(User.marsify, [170], "The marsify award you received has expired!")
_process_timer(User.rainbow, [171], "The rainbow award you received has expired!")
_process_timer(User.queen, [285], "The queen award you received has expired!", {
User.username: User.prelock_username,
User.prelock_username: None,
})
_process_timer(User.spider, [179], "The spider award you received has expired!")
_process_timer(User.namechanged, [281], "The namelock award you received has expired. You're now back to your old username!", {
User.username: User.prelock_username,

View File

@ -69,6 +69,10 @@ torture_regex = re.compile('(^|\s)(i|me)($|\s)', flags=re.I|re.A)
torture_regex2 = re.compile("(^|\s)(i'm)($|\s)", flags=re.I|re.A)
torture_regex3 = re.compile("(^|\s)(my|mine)($|\s)", flags=re.I|re.A)
sentence_ending_regex = re.compile('(\.)', flags=re.I|re.A)
normal_punctuation_regex = re.compile('(\"|\')', flags=re.I|re.A)
more_than_one_comma_regex = re.compile('\,\,+', flags=re.I|re.A)
image_check_regex = re.compile(f'!\[\]\(((?!(https:\/\/({hosts})\/|\/)).*?)\)', flags=re.A)
video_regex_extensions = '|'.join(VIDEO_FORMATS)

View File

@ -677,8 +677,6 @@ def validate_css(css):
return True, ""
def torture_ap(string, username):
if not string: return string
for k, l in AJ_REPLACEMENTS.items():
@ -688,9 +686,37 @@ def torture_ap(string, username):
string = torture_regex3.sub(rf"\1@{username}'s\3", string)
return string
def torture_queen(string, key):
if not string: return string
string = string.lower()
string = sentence_ending_regex.sub(", and", string)
string = normal_punctuation_regex.sub("", string)
string = more_than_one_comma_regex.sub(",", string)
if string[-5:] == ', and':
string = string[:-5]
girl_phrase = GIRL_PHRASES[key%len(GIRL_PHRASES)]
string = girl_phrase.replace("$", string)
return string
def torture_object(obj, torture_method):
#torture body_html
if obj.body_html and '<p>&amp;&amp;' not in obj.body_html and '<p>$$' not in obj.body_html and '<p>##' 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('<html><body>','').replace('</body></html>','')
#torture title_html and check for agendaposter_phrase in plain title and leave if it's there
if isinstance(obj, Post):
obj.title_html = torture_method(obj.title_html)
def complies_with_chud(obj):
#check for cases where u should leave
if not obj.author.agendaposter: return True
if not (obj.author.agendaposter or obj.author.queen): return True
if obj.author.marseyawarded: return True
if isinstance(obj, Post):
if obj.id in ADMIGGER_THREADS: return True
@ -699,31 +725,36 @@ def complies_with_chud(obj):
if obj.parent_submission in ADMIGGER_THREADS: return True
if obj.post.sub == "chudrama": return True
#perserve old body_html to be used in checking for chud phrase
old_body_html = obj.body_html
if obj.author.agendaposter:
#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 '<p>&amp;&amp;' not in obj.body_html and '<p>$$' not in obj.body_html and '<p>##' 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_ap(tag.string, obj.author.username))
obj.body_html = str(soup).replace('<html><body>','').replace('</body></html>','')
# TODO: Replace this code to make it more generic
#torture body_html
if obj.body_html and '<p>&amp;&amp;' not in obj.body_html and '<p>$$' not in obj.body_html and '<p>##' 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_ap(tag.string, obj.author.username))
obj.body_html = str(soup).replace('<html><body>','').replace('</body></html>','')
#torture title_html and check for agendaposter_phrase in plain title and leave if it's there
if isinstance(obj, Post):
obj.title_html = torture_ap(obj.title_html, obj.author.username)
if obj.author.agendaposter_phrase in obj.title.lower():
return True
#torture title_html and check for agendaposter_phrase in plain title and leave if it's there
if isinstance(obj, Post):
obj.title_html = torture_ap(obj.title_html, obj.author.username)
if obj.author.agendaposter_phrase in obj.title.lower():
return True
#check for agendaposter_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 obj.author.agendaposter_phrase in text.lower():
return True
#check for agendaposter_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 obj.author.agendaposter_phrase in text.lower():
return True
return False
return False
elif obj.author.queen:
torture_object(obj, torture_queen)
return True

View File

@ -312,11 +312,59 @@ def award_thing(v, thing_type, id):
cache.delete_memoized(frontlist)
else: thing.stickied_utc = t
g.db.add(thing)
elif kind == "queen":
if author.agendaposter:
abort(409, f"{safe_username} is under the effect of a conflicting award: Chud award!")
if author.namechanged:
abort(409, f"{safe_username} is under the effect of a conflicting award: Namelock award!")
if author.marseyawarded:
abort(409, f"{safe_username} is under the effect of a conflicting award: Marsey award!")
if author.marsify:
abort(409, f"{safe_username} is under the effect of a conflicting award: Marsify award!")
if author.owoify:
abort(409, f"{safe_username} is under the effect of a conflicting award: OwOify award!")
if not author.queen:
adjective = GIRL_NAME_ADJECTIVE[author.id%20].capitalize()
noun = GIRL_NAME_NOUN[(int(author.id/20))%20].capitalize()
prefix = GIRL_NAME_PREFIX[(int((id/20)/20))%8]
prefix = prefix[0].upper() + prefix[1:]
number = int(((author.id/20)/20)/8)
new_name = f"{prefix}{adjective}{noun}"+ (str(number) if number > 0 else "")
if not valid_username_regex.fullmatch(new_name):
new_name = f"SomeWeirdGirl{random.randrange(100000)}"
existing = get_user(new_name, graceful=True)
if existing and existing.id != author.id:
if len(new_name) < 23:
new_name = f"{new_name}_{random.randrange(pow(10, 23-len(new_name)))}"
else:
new_name = f"SomeQuirkyGirl{random.randrange(100000)}"
if not author.prelock_username:
author.prelock_username = author.username
author.username = new_name
if author.queen and time.time() < author.queen: author.queen += 86400
else: author.queen = int(time.time()) + 86400
badge_grant(user=author, badge_id=285)
elif kind == "agendaposter":
if thing_type == 'post' and thing.sub == 'chudrama' \
or thing_type == 'comment' and thing.post and thing.post.sub == 'chudrama':
abort(403, "You can't give the chud award in /h/chudrama")
if author.queen:
abort(409, f"{safe_username} is under the effect of a conflicting award: Queen award!")
if author.marseyawarded:
abort(409, f"{safe_username} is under the effect of a conflicting award: Marsey award!")
@ -354,6 +402,10 @@ def award_thing(v, thing_type, id):
author.flairchanged = int(time.time()) + 86400
badge_grant(user=author, badge_id=96)
elif kind == "namelock":
if author.queen:
abort(409, f"{safe_username} is under the effect of a conflicting award: Queen award!")
new_name = note.strip().lstrip('@')
if not new_name and author.namechanged:
author.namechanged += 86400
@ -377,6 +429,8 @@ def award_thing(v, thing_type, id):
elif kind == "marsey":
if author.agendaposter:
abort(409, f"{safe_username} is under the effect of a conflicting award: Chud award!")
if author.queen:
abort(409, f"{safe_username} is under the effect of a conflicting award: Queen award!")
if author.marseyawarded: author.marseyawarded += 86400
else: author.marseyawarded = int(time.time()) + 86400
@ -433,6 +487,8 @@ def award_thing(v, thing_type, id):
elif kind == 'marsify':
if author.agendaposter:
abort(409, f"{safe_username} is under the effect of a conflicting award: Chud award!")
if author.queen:
abort(409, f"{safe_username} is under the effect of a conflicting award: Queen award!")
if not author.marsify or author.marsify != 1:
if author.marsify: author.marsify += 86400
@ -463,6 +519,8 @@ def award_thing(v, thing_type, id):
elif ("Furry" in kind and kind == v.house) or kind == 'owoify':
if author.agendaposter:
abort(409, f"{safe_username} is under the effect of a conflicting award: Chud award!")
if author.queen:
abort(409, f"{safe_username} is under the effect of a conflicting award: Queen award!")
if author.owoify: author.owoify += 21600
else: author.owoify = int(time.time()) + 21600
@ -492,3 +550,4 @@ def award_thing(v, thing_type, id):
g.db.add(author)
return {"message": f"{AWARDS[kind]['title']} award given to {thing_type} successfully!"}

View File

@ -721,7 +721,7 @@ def settings_advanced_get(v:User):
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def settings_name_change(v):
if v.namechanged: abort(403)
if v.namechanged or v.queen: abort(403)
if v.shadowbanned: abort(500)

View File

@ -242,7 +242,7 @@
{% endif %}
{% set realbody = c.realbody(v) %}
<div id="comment-text-{{c.id}}" class="comment-text mb-0 {% if c.author.agendaposter and not (c.parent_submission and c.post.sub == 'chudrama') %}text-uppercase agendaposter-img agendaposter-{{c.id_last_num}}{% endif %} {% if c.author.rainbow %}rainbow-text{% endif %}">
<div id="comment-text-{{c.id}}" class="comment-text mb-0 {% if c.author.agendaposter and not (c.parent_submission and c.post.sub == 'chudrama') %}text-uppercase agendaposter-img agendaposter-{{c.id_last_num}}{% endif %} {% if c.author.rainbow %}rainbow-text{% endif %} {%if c.author.queen%}queen{%endif%}">
{{realbody | safe}}
</div>
{% if c.parent_submission or c.wall_user_id %}

View File

@ -81,13 +81,13 @@
{% if p.realurl(v) and not v_forbid_deleted %}
<h1 id="post-title" class="card-title post-title text-left mb-md-3 {% if p.author.agendaposter and p.sub != 'chudrama' %}text-uppercase{% endif %}">
<a {% if p.author.rainbow %}class="rainbow-text"{% endif %} {% if not v or v.newtabexternal %}target="_blank"{% endif %} rel="nofollow noopener" href="{{p.realurl(v)}}">
<a {% if p.author.rainbow %}class="rainbow-text"{% endif %} {%if p.author.queen%}queen{%endif%} {% if not v or v.newtabexternal %}target="_blank"{% endif %} rel="nofollow noopener" href="{{p.realurl(v)}}">
{% if p.flair %}<span class="patron font-weight-bolder mr-1" style="background-color:var(--primary); font-size:12px; line-height:2;">{{p.flair | safe}}</span>{% endif %}
{{p.realtitle(v) | safe}}
</a>
</h1>
{% else %}
<h1 id="post-title" class="card-title post-title text-left mb-md-3 {% if p.author.agendaposter and p.sub != 'chudrama' %}text-uppercase{% endif %} {% if p.author.rainbow %}rainbow-text{% endif %}">
<h1 id="post-title" class="card-title post-title text-left mb-md-3 {% if p.author.agendaposter and p.sub != 'chudrama' %}text-uppercase{% endif %} {% if p.author.rainbow %}rainbow-text{% endif %} {%if p.author.queen%}queen{%endif%}">
{% if p.flair %}<span class="patron font-weight-bolder mr-1" style="background-color:var(--primary); font-size:12px; line-height:2;">{{p.flair | safe}}</span>{% endif %}
{{p.realtitle(v) | safe}}
</h1>
@ -117,7 +117,7 @@
{% endif %}
<div id="post-text" class="{% if p.author.agendaposter and p.sub != 'chudrama' %}text-uppercase agendaposter-img agendaposter-{{p.id_last_num}}{% endif %} {% if p.author.rainbow %}rainbow-text{% endif %}">
<div id="post-text" class="{% if p.author.agendaposter and p.sub != 'chudrama' %}text-uppercase agendaposter-img agendaposter-{{p.id_last_num}}{% endif %} {% if p.author.rainbow %}rainbow-text{% endif %} {%if p.author.queen%}queen{%endif%}">
{% if p.is_image %}
<div class="row no-gutters mb-4">
<div class="col">

View File

@ -208,7 +208,7 @@
{% if not v_forbid_deleted %}
{% if p.realbody(v, listing=True) %}
<div class="d-none card rounded border {% if p.author.agendaposter and p.sub != 'chudrama' %}text-uppercase agendaposter-img agendaposter-{{p.id_last_num}}{% endif %} {% if p.author.rainbow %}rainbow-text{% endif %} post-preview" id="post-text-{{p.id}}">
<div class="d-none card rounded border {% if p.author.agendaposter and p.sub != 'chudrama' %}text-uppercase agendaposter-img agendaposter-{{p.id_last_num}}{% endif %} {% if p.author.rainbow %}rainbow-text{% endif %} {%if p.author.queen%}queen{%endif%} post-preview" id="post-text-{{p.id}}">
{{p.realbody(v, listing=True) | safe}}
</div>
{% endif %}

View File

@ -163,10 +163,10 @@
<p>Your original username will always stay reserved for you: <code>{{v.original_username}}</code></p>
<form action="/settings/name_change" method="post">
<input hidden name="formkey" value="{{v|formkey}}">
<input id="name-body" autocomplete="off" type="text" name="name" class="form-control" value="{{v.username}}" {% if v.namechanged %}disabled{% endif %}>
<input id="name-body" autocomplete="off" type="text" name="name" class="form-control" value="{{v.username}}" {% if v.namechanged or v.queen %}disabled{% endif %}>
<small>3-25 characters, including letters, numbers, _ , and -</small>
<div class="d-flex mt-2">
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Change Display Name" {% if v.namechanged %}disabled{% endif %}>
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Change Display Name" {% if v.namechanged or v.queen%}disabled{% endif %}>
</div>
</form>
</div>
@ -271,8 +271,8 @@
<script defer src="{{'js/flairchanged.js' | asset}}"></script>
{% endif %}
{% if v.namechanged %}
<input hidden id="namechanged" value="{{v.namechanged}}">
{% if v.namechanged or v.queen%}
<input hidden id="namechanged" value="{{v.namechanged if v.namechanged else v.queen}}">
<script defer src="{{'js/namechanged.js' | asset}}"></script>
{% endif %}

View File

@ -0,0 +1 @@
alter table users add column queen integer;

View File

@ -249,7 +249,8 @@ CREATE TABLE public.users (
hidevotedon boolean DEFAULT false NOT NULL,
agendaposter_phrase character varying(35),
prelock_username character varying(30),
namechanged integer
namechanged integer,
queen integer
);

View File

@ -244,8 +244,6 @@ INSERT INTO public.badge_defs VALUES (283, 'Summer Fun', 'Awarded for contributi
INSERT INTO public.badge_defs VALUES (284, 'In Memoriam Theodroa', 'When God calls one of His most blessed angels home, the heavens rejoice while we are left behind to weep with the rain.', 1686502188);
INSERT INTO public.badge_defs VALUES (285, 'Queen', 'This user SLAYS 💅👠💄', 1687282987);
--
-- Name: badge_defs_id_seq; Type: SEQUENCE SET; Schema: public; Owner: -
--