diff --git a/files/assets/css/main.css b/files/assets/css/main.css index 495f984d0..689e7a6c5 100644 --- a/files/assets/css/main.css +++ b/files/assets/css/main.css @@ -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; } diff --git a/files/assets/images/pfps/girls/1.webp b/files/assets/images/pfps/girls/1.webp new file mode 100644 index 000000000..ab8208eb5 Binary files /dev/null and b/files/assets/images/pfps/girls/1.webp differ diff --git a/files/assets/images/pfps/girls/2.webp b/files/assets/images/pfps/girls/2.webp new file mode 100644 index 000000000..a04e28082 Binary files /dev/null and b/files/assets/images/pfps/girls/2.webp differ diff --git a/files/assets/images/pfps/girls/3.webp b/files/assets/images/pfps/girls/3.webp new file mode 100644 index 000000000..4188d035b Binary files /dev/null and b/files/assets/images/pfps/girls/3.webp differ diff --git a/files/assets/images/pfps/girls/4.webp b/files/assets/images/pfps/girls/4.webp new file mode 100644 index 000000000..5f37595a1 Binary files /dev/null and b/files/assets/images/pfps/girls/4.webp differ diff --git a/files/assets/images/pfps/girls/5.webp b/files/assets/images/pfps/girls/5.webp new file mode 100644 index 000000000..036fa5629 Binary files /dev/null and b/files/assets/images/pfps/girls/5.webp differ diff --git a/files/assets/images/pfps/girls/6.webp b/files/assets/images/pfps/girls/6.webp new file mode 100644 index 000000000..bd7239fb4 Binary files /dev/null and b/files/assets/images/pfps/girls/6.webp differ diff --git a/files/assets/images/pfps/girls/7.webp b/files/assets/images/pfps/girls/7.webp new file mode 100644 index 000000000..be6611b54 Binary files /dev/null and b/files/assets/images/pfps/girls/7.webp differ diff --git a/files/assets/images/pfps/girls/8.webp b/files/assets/images/pfps/girls/8.webp new file mode 100644 index 000000000..973a57232 Binary files /dev/null and b/files/assets/images/pfps/girls/8.webp differ diff --git a/files/classes/user.py b/files/classes/user.py index 12928e14a..d3f1f0027 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -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 diff --git a/files/helpers/config/awards.py b/files/helpers/config/awards.py index 2796ed30d..7d5feaad4 100644 --- a/files/helpers/config/awards.py +++ b/files/helpers/config/awards.py @@ -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", diff --git a/files/helpers/config/const.py b/files/helpers/config/const.py index 78daaf48a..29ed29b11 100644 --- a/files/helpers/config/const.py +++ b/files/helpers/config/const.py @@ -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 = { "(?&&' 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 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 '

&&' 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_ap(tag.string, obj.author.username)) - obj.body_html = str(soup).replace('','').replace('','') + # TODO: Replace this code to make it more generic + #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_ap(tag.string, obj.author.username)) + obj.body_html = str(soup).replace('','').replace('','') - #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 diff --git a/files/routes/awards.py b/files/routes/awards.py index 609ac4d09..5c005ea5d 100644 --- a/files/routes/awards.py +++ b/files/routes/awards.py @@ -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!"} + diff --git a/files/routes/settings.py b/files/routes/settings.py index cdaec5626..89b01e2bd 100644 --- a/files/routes/settings.py +++ b/files/routes/settings.py @@ -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) diff --git a/files/templates/comments.html b/files/templates/comments.html index 6e6ca3e6d..9c6c08406 100644 --- a/files/templates/comments.html +++ b/files/templates/comments.html @@ -242,7 +242,7 @@ {% endif %} {% set realbody = c.realbody(v) %} -

+
{{realbody | safe}}
{% if c.parent_submission or c.wall_user_id %} diff --git a/files/templates/post.html b/files/templates/post.html index fec118e65..d214e567f 100644 --- a/files/templates/post.html +++ b/files/templates/post.html @@ -81,13 +81,13 @@ {% if p.realurl(v) and not v_forbid_deleted %}

- + {% if p.flair %}{{p.flair | safe}}{% endif %} {{p.realtitle(v) | safe}}

{% else %} -

+

{% if p.flair %}{{p.flair | safe}}{% endif %} {{p.realtitle(v) | safe}}

@@ -117,7 +117,7 @@ {% endif %} -
+
{% if p.is_image %}
diff --git a/files/templates/post_listing.html b/files/templates/post_listing.html index 6a4f9c94b..5773901ab 100644 --- a/files/templates/post_listing.html +++ b/files/templates/post_listing.html @@ -208,7 +208,7 @@ {% if not v_forbid_deleted %} {% if p.realbody(v, listing=True) %} -
+
{{p.realbody(v, listing=True) | safe}}
{% endif %} diff --git a/files/templates/settings/personal.html b/files/templates/settings/personal.html index 72184bc68..8c7fb56f9 100644 --- a/files/templates/settings/personal.html +++ b/files/templates/settings/personal.html @@ -163,10 +163,10 @@

Your original username will always stay reserved for you: {{v.original_username}}

- + 3-25 characters, including letters, numbers, _ , and -
- +
@@ -271,8 +271,8 @@ {% endif %} -{% if v.namechanged %} - +{% if v.namechanged or v.queen%} + {% endif %} diff --git a/migrations/20230617-add-misogynist-award.sql b/migrations/20230617-add-misogynist-award.sql new file mode 100644 index 000000000..f4e910817 --- /dev/null +++ b/migrations/20230617-add-misogynist-award.sql @@ -0,0 +1 @@ +alter table users add column queen integer; \ No newline at end of file diff --git a/schema.sql b/schema.sql index f2c8a9657..1ab968a8a 100644 --- a/schema.sql +++ b/schema.sql @@ -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 ); diff --git a/seed-db.sql b/seed-db.sql index 071731e2c..50963aaaa 100644 --- a/seed-db.sql +++ b/seed-db.sql @@ -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: - --