2022-11-15 09:19:08 +00:00
|
|
|
import random
|
|
|
|
from operator import *
|
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
import pyotp
|
2023-05-11 13:57:49 +00:00
|
|
|
from sqlalchemy import Column, ForeignKey, FetchedValue
|
2022-12-22 20:03:40 +00:00
|
|
|
from sqlalchemy.orm import aliased, deferred, Query
|
|
|
|
from sqlalchemy.sql import case, func, literal
|
2022-12-11 23:44:34 +00:00
|
|
|
from sqlalchemy.sql.expression import not_, and_, or_
|
2022-11-15 09:19:08 +00:00
|
|
|
from sqlalchemy.sql.sqltypes import *
|
2023-09-11 19:26:16 +00:00
|
|
|
from sqlalchemy.exc import OperationalError
|
2023-05-26 23:29:34 +00:00
|
|
|
from flask import g, session, request
|
2022-11-15 09:19:08 +00:00
|
|
|
|
|
|
|
from files.classes import Base
|
2022-12-14 19:30:05 +00:00
|
|
|
from files.classes.casino_game import CasinoGame
|
2023-06-24 17:16:24 +00:00
|
|
|
from files.classes.group import GroupMembership
|
2022-11-09 05:35:24 +00:00
|
|
|
from files.classes.sub import Sub
|
2022-12-11 23:44:34 +00:00
|
|
|
from files.helpers.config.const import *
|
2023-01-26 05:39:17 +00:00
|
|
|
from files.helpers.config.modaction_types import *
|
2022-12-11 23:44:34 +00:00
|
|
|
from files.helpers.config.awards import AWARDS_ENABLED, HOUSE_AWARDS
|
2022-11-15 09:19:08 +00:00
|
|
|
from files.helpers.media import *
|
|
|
|
from files.helpers.security import *
|
2022-09-19 17:10:37 +00:00
|
|
|
from files.helpers.sorting_and_time import *
|
2023-10-05 10:09:58 +00:00
|
|
|
from files.helpers.can_see import *
|
2022-11-15 09:19:08 +00:00
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
from .alts import Alt
|
|
|
|
from .award import AwardRelationship
|
|
|
|
from .badges import *
|
|
|
|
from .clients import *
|
|
|
|
from .exiles import *
|
2022-11-15 09:19:08 +00:00
|
|
|
from .follows import *
|
|
|
|
from .hats import *
|
|
|
|
from .mod import *
|
|
|
|
from .mod_logs import *
|
|
|
|
from .notifications import Notification
|
|
|
|
from .saves import *
|
2022-11-15 16:05:42 +00:00
|
|
|
from .sub_relationship import *
|
2022-11-15 09:19:08 +00:00
|
|
|
from .sub_logs import *
|
|
|
|
from .subscriptions import *
|
|
|
|
from .userblock import *
|
2023-09-06 18:02:47 +00:00
|
|
|
from .usermute import *
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2023-10-04 09:57:25 +00:00
|
|
|
if SITE == 'devrama.net' and False:
|
2023-03-11 09:30:24 +00:00
|
|
|
DEFAULT_ADMIN_LEVEL = 3
|
2022-12-27 09:33:31 +00:00
|
|
|
DEFAULT_COINS = 100000000
|
|
|
|
DEFAULT_MARSEYBUX = 100000000
|
2022-12-27 02:00:08 +00:00
|
|
|
else:
|
|
|
|
DEFAULT_ADMIN_LEVEL = 0
|
|
|
|
DEFAULT_COINS = 0
|
|
|
|
DEFAULT_MARSEYBUX = 0
|
2022-12-27 01:53:47 +00:00
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
class User(Base):
|
|
|
|
__tablename__ = "users"
|
|
|
|
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
|
|
username = Column(String)
|
|
|
|
namecolor = Column(String, default=DEFAULT_COLOR)
|
|
|
|
background = Column(String)
|
2022-12-05 04:16:45 +00:00
|
|
|
profile_background = Column(String)
|
2023-10-05 10:39:12 +00:00
|
|
|
flair = deferred(Column(String))
|
|
|
|
flair_html = Column(String)
|
2022-09-19 17:10:37 +00:00
|
|
|
titlecolor = Column(String, default=DEFAULT_COLOR)
|
|
|
|
theme = Column(String, default=DEFAULT_THEME)
|
|
|
|
themecolor = Column(String, default=DEFAULT_COLOR)
|
|
|
|
song = Column(String)
|
|
|
|
highres = Column(String)
|
|
|
|
profileurl = Column(String)
|
|
|
|
bannerurl = Column(String)
|
|
|
|
house = Column(String, default='')
|
|
|
|
old_house = Column(String, default='')
|
|
|
|
patron = Column(Integer, default=0)
|
|
|
|
patron_utc = Column(Integer, default=0)
|
|
|
|
verified = Column(String)
|
|
|
|
verifiedcolor = Column(String)
|
2023-05-13 02:00:54 +00:00
|
|
|
marseyawarded = Column(Integer, default=0)
|
|
|
|
rehab = Column(Integer, default=0)
|
|
|
|
longpost = Column(Integer, default=0)
|
|
|
|
bird = Column(Integer, default=0)
|
2022-09-19 17:10:37 +00:00
|
|
|
email = deferred(Column(String))
|
|
|
|
css = Column(String)
|
|
|
|
profilecss = deferred(Column(String))
|
|
|
|
passhash = deferred(Column(String))
|
|
|
|
post_count = Column(Integer, default=0)
|
|
|
|
comment_count = Column(Integer, default=0)
|
|
|
|
received_award_count = Column(Integer, default=0)
|
2022-09-19 20:40:33 +00:00
|
|
|
created_utc = Column(Integer)
|
2022-12-27 01:53:47 +00:00
|
|
|
admin_level = Column(Integer, default=DEFAULT_ADMIN_LEVEL)
|
2022-09-19 17:10:37 +00:00
|
|
|
last_active = Column(Integer, default=0, nullable=False)
|
|
|
|
coins_spent = Column(Integer, default=0)
|
|
|
|
coins_spent_on_hats = Column(Integer, default=0)
|
|
|
|
lootboxes_bought = Column(Integer, default=0)
|
2023-06-23 11:07:47 +00:00
|
|
|
chud = Column(Integer, default=0)
|
Add the "Misogynist" award to harass incels (#154)
Whazzup? This PR is the final solution to the incel problem. There's an old indian proverb that says: "never judge a man until you've walked two moons in his mocassins". In this case, it should be: "never judge a woman until you've walked 24 hrs in her high-heels".
The misogynist award is a comment-transforming award that "feminizes" comments. It does the following:
- makes text pink
- makes text lowercase
- removes "complicated" punctuation
- makes paragraphs into run-on sentences
- adds stereotypical girly remarks to the beginning or end of a paragraph.
For example:
INPUT
> What the fuck did you just fucking say about me, you little bitch? I'll have you know I graduated top of my class in the Navy Seals, and I've been involved in numerous secret raids on Al-Quaeda, and I have over 300 confirmed kills. I am trained in gorilla warfare and I'm the top sniper in the entire US armed forces. You are nothing to me but just another target. I will wipe you the fuck out with precision the likes of which has never been seen before on this Earth, mark my fucking words. You think you can get away with saying that shit to me over the Internet? Think again, fucker. As we speak I am contacting my secret network of spies across the USA and your IP is being traced right now so you better prepare for the storm, maggot. The storm that wipes out the pathetic little thing you call your life. You're fucking dead, kid. I can be anywhere, anytime, and I can kill you in over seven hundred ways, and that's just with my bare hands. Not only am I extensively trained in unarmed combat, but I have access to the entire arsenal of the United States Marine Corps and I will use it to its full extent to wipe your miserable ass off the face of the continent, you little shit. If only you could have known what unholy retribution your little "clever" comment was about to bring down upon you, maybe you would have held your fucking tongue. But you couldn't, you didn't, and now you're paying the price, you goddamn idiot. I will shit fury all over you and you will drown in it. You're fucking dead, kiddo.
OUTPUT
> im literally screaming, what the fuck did you just fucking say about me, you little bitch? ill have you know i graduated top of my class in the navy seals, and ive been involved in numerous secret raids on al-quaeda, and i have over 300 confirmed kills, i am trained in gorilla warfare and im the top sniper in the entire us armed forces, you are nothing to me but just another target, i will wipe you the fuck out with precision the likes of which has never been seen before on this earth, mark my fucking words, you think you can get away with saying that shit to me over the internet? think again, fucker, as we speak i am contacting my secret network of spies across the usa and your ip is being traced right now so you better prepare for the storm, maggot, the storm that wipes out the pathetic little thing you call your life, youre fucking dead, kid, i can be anywhere, anytime, and i can kill you in over seven hundred ways, and thats just with my bare hands, not only am i extensively trained in unarmed combat, but i have access to the entire arsenal of the united states marine corps and i will use it to its full extent to wipe your miserable ass off the face of the continent, you little shit, if only you could have known what unholy retribution your little clever comment was about to bring down upon you, maybe you would have held your fucking tongue, but you couldnt, you didnt, and now youre paying the price, you goddamn idiot, i will shit fury all over you and you will drown in it, youre fucking dead, kiddo
It also sets the user's pfp to a random white woman. Well, psuedorandom - it's based off of the user's id, so each user will only ever have one pfp assigned to them, which I think is nifty.
Finally, it changes the name of the user toa girly name.
There is one small problem with the PR, which is simply that I manually added a badge for testing purposes. If you like this PR, I will submit the badge throught the proper chanels and fix it.
![image](/attachments/641c7276-ffe4-4e69-b3e9-aec9f4f94191)
Co-authored-by: Chuck Sneed <sneed@formerlychucks.net>
Reviewed-on: https://fsdfsd.net/rDrama/rDrama/pulls/154
Co-authored-by: HeyMoon <heymoon@noreply.fsdfsd.net>
Co-committed-by: HeyMoon <heymoon@noreply.fsdfsd.net>
2023-06-21 12:36:07 +00:00
|
|
|
queen = Column(Integer, default=0)
|
2023-10-04 15:42:03 +00:00
|
|
|
king = Column(Integer, default=0)
|
2023-06-23 11:07:47 +00:00
|
|
|
chud_phrase = Column(String)
|
2023-08-03 08:02:31 +00:00
|
|
|
email_verified = Column(Boolean, default=False)
|
2022-12-26 02:38:32 +00:00
|
|
|
shadowbanned = Column(Integer, ForeignKey("users.id"))
|
|
|
|
chudded_by = Column(Integer, ForeignKey("users.id"))
|
2023-03-15 06:03:11 +00:00
|
|
|
hidevotedon = Column(Boolean, default=False)
|
2022-11-06 22:58:14 +00:00
|
|
|
slurreplacer = Column(Integer, default=1)
|
|
|
|
profanityreplacer = Column(Integer, default=1)
|
2023-05-13 02:00:54 +00:00
|
|
|
flairchanged = Column(Integer, default=0)
|
2023-05-13 04:53:14 +00:00
|
|
|
namechanged = Column(Integer, default=0)
|
2022-11-21 16:55:09 +00:00
|
|
|
newtab = Column(Boolean, default=False)
|
2022-09-19 17:10:37 +00:00
|
|
|
newtabexternal = Column(Boolean, default=True)
|
|
|
|
reddit = Column(String, default='old.reddit.com')
|
|
|
|
nitter = Column(Boolean)
|
|
|
|
imginn = Column(Boolean)
|
|
|
|
frontsize = Column(Integer, default=25)
|
2023-05-07 19:03:29 +00:00
|
|
|
controversial = Column(Boolean, default=False)
|
2022-09-19 17:10:37 +00:00
|
|
|
bio = deferred(Column(String))
|
|
|
|
bio_html = Column(String)
|
|
|
|
sig = deferred(Column(String))
|
|
|
|
sig_html = Column(String)
|
|
|
|
fp = Column(String)
|
2023-10-05 10:33:01 +00:00
|
|
|
show_sigs = Column(Boolean, default=True)
|
2023-05-13 02:00:54 +00:00
|
|
|
progressivestack = Column(Integer, default=0)
|
|
|
|
deflector = Column(Integer, default=0)
|
2022-09-19 17:10:37 +00:00
|
|
|
friends = deferred(Column(String))
|
|
|
|
friends_html = deferred(Column(String))
|
|
|
|
enemies = deferred(Column(String))
|
|
|
|
enemies_html = deferred(Column(String))
|
2022-12-13 22:02:53 +00:00
|
|
|
is_banned = Column(Integer, ForeignKey("users.id"))
|
2022-09-19 17:10:37 +00:00
|
|
|
unban_utc = Column(Integer, default=0)
|
|
|
|
ban_reason = deferred(Column(String))
|
|
|
|
is_muted = Column(Boolean, default=False, nullable=False)
|
|
|
|
login_nonce = Column(Integer, default=0)
|
2022-12-27 02:00:08 +00:00
|
|
|
coins = Column(Integer, default=DEFAULT_COINS)
|
2022-11-07 07:03:58 +00:00
|
|
|
truescore = Column(Integer, default=0)
|
2022-12-27 02:00:08 +00:00
|
|
|
marseybux = Column(Integer, default=DEFAULT_MARSEYBUX)
|
2022-09-19 17:10:37 +00:00
|
|
|
mfa_secret = deferred(Column(String))
|
|
|
|
is_private = Column(Boolean, default=False)
|
|
|
|
stored_subscriber_count = Column(Integer, default=0)
|
2022-10-11 16:41:09 +00:00
|
|
|
defaultsortingcomments = Column(String, default="hot")
|
2022-09-19 17:10:37 +00:00
|
|
|
defaultsorting = Column(String, default="hot")
|
|
|
|
defaulttime = Column(String, default=DEFAULT_TIME_FILTER)
|
|
|
|
custom_filter_list = Column(String)
|
|
|
|
original_username = Column(String)
|
2023-05-13 04:53:14 +00:00
|
|
|
prelock_username = Column(String)
|
2022-09-19 17:10:37 +00:00
|
|
|
referred_by = Column(Integer, ForeignKey("users.id"))
|
|
|
|
currently_held_lottery_tickets = Column(Integer, default=0)
|
|
|
|
total_held_lottery_tickets = Column(Integer, default=0)
|
|
|
|
total_lottery_winnings = Column(Integer, default=0)
|
2022-09-19 20:40:33 +00:00
|
|
|
last_viewed_post_notifs = Column(Integer, default=0)
|
|
|
|
last_viewed_log_notifs = Column(Integer, default=0)
|
2022-11-30 22:29:13 +00:00
|
|
|
last_viewed_reddit_notifs = Column(Integer, default=0)
|
2022-09-19 17:10:37 +00:00
|
|
|
pronouns = Column(String, default='they/them')
|
2023-05-13 02:00:54 +00:00
|
|
|
bite = Column(Integer, default=0)
|
|
|
|
earlylife = Column(Integer, default=0)
|
|
|
|
owoify = Column(Integer, default=0)
|
2023-06-26 14:38:48 +00:00
|
|
|
sharpen = Column(Integer, default=0)
|
2022-09-19 17:10:37 +00:00
|
|
|
marsify = Column(Integer, default=0)
|
2023-05-13 02:00:54 +00:00
|
|
|
rainbow = Column(Integer, default=0)
|
2022-09-25 02:47:05 +00:00
|
|
|
spider = Column(Integer, default=0)
|
2023-08-01 07:16:47 +00:00
|
|
|
lifetimedonated = Column(Integer, default=0)
|
2023-08-03 04:57:09 +00:00
|
|
|
lifetimedonated_visible = Column(Boolean, default=False)
|
2023-01-25 15:41:46 +00:00
|
|
|
blacklisted_by = Column(Integer, ForeignKey("users.id"))
|
2023-01-01 05:33:09 +00:00
|
|
|
|
2023-09-28 23:58:09 +00:00
|
|
|
if IS_HOMOWEEN():
|
|
|
|
zombie = Column(Integer, default=0, nullable=False) # > 0 vaxxed; < 0 zombie
|
|
|
|
jumpscare = Column(Integer, default=0)
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
badges = relationship("Badge", order_by="Badge.created_utc", back_populates="user")
|
|
|
|
subscriptions = relationship("Subscription", back_populates="user")
|
|
|
|
following = relationship("Follow", primaryjoin="Follow.user_id==User.id", back_populates="user")
|
|
|
|
followers = relationship("Follow", primaryjoin="Follow.target_id==User.id", back_populates="target")
|
|
|
|
blocking = relationship("UserBlock", lazy="dynamic", primaryjoin="User.id==UserBlock.user_id", back_populates="user")
|
|
|
|
blocked = relationship("UserBlock", lazy="dynamic", primaryjoin="User.id==UserBlock.target_id", back_populates="target")
|
|
|
|
authorizations = relationship("ClientAuth", back_populates="user")
|
|
|
|
apps = relationship("OauthApp", back_populates="author")
|
|
|
|
awards = relationship("AwardRelationship", primaryjoin="User.id==AwardRelationship.user_id", back_populates="user")
|
2023-09-15 15:20:04 +00:00
|
|
|
referrals = relationship("User", primaryjoin="User.id==User.referred_by", order_by="User.created_utc")
|
2022-09-19 17:10:37 +00:00
|
|
|
designed_hats = relationship("HatDef", primaryjoin="User.id==HatDef.author_id", back_populates="author")
|
|
|
|
owned_hats = relationship("Hat", back_populates="owners")
|
2022-11-09 15:32:14 +00:00
|
|
|
hats_equipped = relationship("Hat", lazy="raise", viewonly=True)
|
2022-11-09 14:16:22 +00:00
|
|
|
sub_mods = relationship("Mod", primaryjoin="User.id == Mod.user_id", lazy="raise")
|
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
def __init__(self, **kwargs):
|
|
|
|
|
|
|
|
if "password" in kwargs:
|
2022-10-06 22:59:50 +00:00
|
|
|
kwargs["passhash"] = hash_password(kwargs["password"])
|
2022-09-19 17:10:37 +00:00
|
|
|
kwargs.pop("password")
|
|
|
|
|
2022-09-19 20:40:33 +00:00
|
|
|
if "created_utc" not in kwargs:
|
|
|
|
kwargs["created_utc"] = int(time.time())
|
|
|
|
kwargs["last_viewed_post_notifs"] = kwargs["created_utc"]
|
|
|
|
kwargs["last_viewed_log_notifs"] = kwargs["created_utc"]
|
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
super().__init__(**kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
def __repr__(self):
|
2022-11-29 21:02:38 +00:00
|
|
|
return f"<{self.__class__.__name__}(id={self.id}, username={self.username})>"
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
def pay_account(self, currency, amount):
|
2023-05-04 22:48:54 +00:00
|
|
|
if SITE == 'watchpeopledie.tv' and self.id == 5222:
|
|
|
|
return
|
|
|
|
|
2023-08-09 18:45:25 +00:00
|
|
|
if SITE == 'rdrama.net' and self.id == 5237:
|
|
|
|
return
|
|
|
|
|
2023-07-31 23:12:42 +00:00
|
|
|
user_query = g.db.query(User).options(load_only(User.id)).filter_by(id=self.id)
|
2023-08-01 07:38:58 +00:00
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
if currency == 'coins':
|
2023-09-11 19:26:16 +00:00
|
|
|
try:
|
|
|
|
user_query.update({ User.coins: User.coins + amount })
|
|
|
|
except OperationalError as e:
|
|
|
|
if str(e).startswith('(psycopg2.errors.QueryCanceled) canceling statement due to statement timeout'):
|
|
|
|
abort(409, f"Statement timeout while trying to pay @{self.username} {amount} coins!")
|
|
|
|
raise
|
2022-09-19 17:10:37 +00:00
|
|
|
else:
|
2023-07-31 23:12:42 +00:00
|
|
|
user_query.update({ User.marseybux: User.marseybux + amount })
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2022-11-01 17:50:01 +00:00
|
|
|
def charge_account(self, currency, amount, **kwargs):
|
2022-09-19 17:10:37 +00:00
|
|
|
succeeded = False
|
2023-04-24 15:08:40 +00:00
|
|
|
charged_coins = 0
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2022-11-01 17:50:01 +00:00
|
|
|
should_check_balance = kwargs.get('should_check_balance', True)
|
|
|
|
|
2023-07-31 23:12:42 +00:00
|
|
|
user_query = g.db.query(User).options(load_only(User.id)).filter_by(id=self.id)
|
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
if currency == 'coins':
|
2023-07-17 14:49:26 +00:00
|
|
|
account_balance = self.coins
|
2023-01-01 11:36:20 +00:00
|
|
|
|
2022-11-01 17:50:01 +00:00
|
|
|
if not should_check_balance or account_balance >= amount:
|
2023-07-31 23:12:42 +00:00
|
|
|
user_query.update({ User.coins: User.coins - amount })
|
2022-09-19 17:10:37 +00:00
|
|
|
succeeded = True
|
2023-04-24 15:08:40 +00:00
|
|
|
charged_coins = amount
|
2022-11-21 23:08:29 +00:00
|
|
|
elif currency == 'marseybux':
|
2023-07-17 14:49:26 +00:00
|
|
|
account_balance = self.marseybux
|
2023-01-01 11:36:20 +00:00
|
|
|
|
2022-11-01 17:50:01 +00:00
|
|
|
if not should_check_balance or account_balance >= amount:
|
2023-07-31 23:12:42 +00:00
|
|
|
user_query.update({ User.marseybux: User.marseybux - amount })
|
2022-09-19 17:10:37 +00:00
|
|
|
succeeded = True
|
2023-03-07 05:06:17 +00:00
|
|
|
elif currency == 'combined':
|
2023-07-17 14:49:26 +00:00
|
|
|
if self.marseybux >= amount:
|
2023-03-07 13:20:46 +00:00
|
|
|
subtracted_mbux = amount
|
|
|
|
subtracted_coins = 0
|
|
|
|
else:
|
2023-07-17 14:49:26 +00:00
|
|
|
subtracted_mbux = self.marseybux
|
2023-03-07 13:20:46 +00:00
|
|
|
subtracted_coins = amount - subtracted_mbux
|
2023-07-17 14:49:26 +00:00
|
|
|
if subtracted_coins > self.coins:
|
2023-04-24 15:08:40 +00:00
|
|
|
return (False, 0)
|
2023-03-07 05:06:17 +00:00
|
|
|
|
2023-07-31 23:12:42 +00:00
|
|
|
user_query.update({
|
|
|
|
User.marseybux: User.marseybux - subtracted_mbux,
|
|
|
|
User.coins: User.coins - subtracted_coins,
|
|
|
|
})
|
2023-03-07 05:06:17 +00:00
|
|
|
succeeded = True
|
2023-04-24 15:08:40 +00:00
|
|
|
charged_coins = subtracted_coins
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2023-03-04 18:32:55 +00:00
|
|
|
if succeeded:
|
2023-03-16 06:27:58 +00:00
|
|
|
g.db.add(self)
|
2023-01-01 11:36:20 +00:00
|
|
|
|
2023-04-24 15:08:40 +00:00
|
|
|
return (succeeded, charged_coins)
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2023-09-28 23:58:09 +00:00
|
|
|
|
|
|
|
if IS_FISTMAS():
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def can_toggle_event_music(self):
|
|
|
|
return SITE_NAME != 'rDrama' or self.has_badge(91)
|
|
|
|
elif IS_HOMOWEEN():
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def can_toggle_event_music(self):
|
|
|
|
return SITE_NAME != 'rDrama' or self.has_badge(185)
|
|
|
|
|
|
|
|
if IS_EVENT():
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def event_music(self):
|
|
|
|
return session.get('event_music', SITE_NAME == 'rDrama')
|
|
|
|
|
2023-08-03 20:26:53 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def poor(self):
|
|
|
|
return session.get('poor')
|
|
|
|
|
2023-08-03 20:40:15 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def cursormarsey(self):
|
2023-08-03 20:47:38 +00:00
|
|
|
return session.get('cursormarsey', CURSORMARSEY_DEFAULT)
|
2023-08-03 20:40:15 +00:00
|
|
|
|
2023-08-03 21:17:55 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
2023-10-05 10:29:23 +00:00
|
|
|
def nsfw_warnings(self):
|
|
|
|
return bool(session.get('nsfw_warnings', True))
|
2023-08-03 21:17:55 +00:00
|
|
|
|
2023-08-13 15:13:09 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def allowed_in_chat(self):
|
2023-08-31 10:38:01 +00:00
|
|
|
if self.admin_level >= PERMS['BYPASS_CHAT_TRUESCORE_REQUIREMENT']:
|
2023-08-31 10:31:04 +00:00
|
|
|
return True
|
2023-10-05 13:44:31 +00:00
|
|
|
if self.truescore >= TRUESCORE_MINIMUM:
|
2023-08-31 10:31:04 +00:00
|
|
|
return True
|
|
|
|
if self.patron:
|
|
|
|
return True
|
2023-08-13 15:13:09 +00:00
|
|
|
return False
|
|
|
|
|
2023-05-03 17:26:44 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def num_of_bought_awards(self):
|
|
|
|
return g.db.query(AwardRelationship).filter_by(user_id=self.id).count()
|
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def num_of_owned_hats(self):
|
|
|
|
return len(self.owned_hats)
|
|
|
|
|
2022-10-08 20:30:27 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def hats_owned_proportion_display(self):
|
2023-03-16 06:27:58 +00:00
|
|
|
total_num_of_hats = g.db.query(HatDef).filter(HatDef.submitter_id == None, HatDef.price > 0).count()
|
2023-08-04 10:18:10 +00:00
|
|
|
proportion = f'{float(self.num_of_owned_hats) / total_num_of_hats:.1%}' if total_num_of_hats else 'N/A'
|
2022-10-08 20:30:27 +00:00
|
|
|
return (proportion, total_num_of_hats)
|
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def num_of_designed_hats(self):
|
|
|
|
return len(self.designed_hats)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def equipped_hats(self):
|
2022-11-09 15:32:14 +00:00
|
|
|
try:
|
|
|
|
return self.hats_equipped
|
|
|
|
except:
|
2023-03-16 06:27:58 +00:00
|
|
|
return g.db.query(Hat).filter_by(user_id=self.id, equipped=True).all()
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def equipped_hat_ids(self):
|
|
|
|
return [x.hat_id for x in self.equipped_hats]
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def equipped_hat(self):
|
|
|
|
if self.equipped_hats:
|
|
|
|
return random.choice(self.equipped_hats)
|
|
|
|
return None
|
|
|
|
|
2022-09-19 18:52:50 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def forced_hat(self):
|
|
|
|
user_forced_hats = []
|
|
|
|
for k, val in forced_hats.items():
|
2022-12-05 00:44:58 +00:00
|
|
|
if getattr(self, k) and getattr(self, k) > 1:
|
2023-09-29 06:09:59 +00:00
|
|
|
if isinstance(val[0], tuple):
|
2022-11-26 20:14:31 +00:00
|
|
|
user_forced_hats.append(random.choice(val))
|
|
|
|
else:
|
|
|
|
user_forced_hats.append(val)
|
2022-09-19 18:52:50 +00:00
|
|
|
if user_forced_hats: return random.choice(user_forced_hats)
|
|
|
|
else: return None
|
|
|
|
|
2023-06-23 11:37:22 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def new_user(self):
|
|
|
|
return self.age < NEW_USER_AGE
|
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@lazy
|
2022-12-24 22:21:49 +00:00
|
|
|
def hat_active(self, v):
|
|
|
|
if FEATURES['HATS']:
|
2023-03-08 06:51:40 +00:00
|
|
|
if IS_FISTMAS():
|
2023-01-01 05:33:09 +00:00
|
|
|
hat = random.choice(('Santa Hat III', 'Winter Cap', 'Present Bow'))
|
|
|
|
if SITE_NAME == 'rDrama':
|
2023-03-19 16:28:19 +00:00
|
|
|
return (f'{SITE_FULL_IMAGES}/i/hats/{hat}.webp', 'Merry Fistmas!')
|
2023-01-01 05:33:09 +00:00
|
|
|
else:
|
2023-03-19 16:28:19 +00:00
|
|
|
return (f'{SITE_FULL_IMAGES}/i/hats/{hat}.webp', 'Merry Christmas!')
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2022-12-24 22:21:49 +00:00
|
|
|
if self.is_cakeday:
|
|
|
|
return ('/i/hats/Cakeday.webp', "I've spent another year rotting my brain with dramaposting, please ridicule me 🤓")
|
2022-12-19 01:20:14 +00:00
|
|
|
|
2022-12-24 22:21:49 +00:00
|
|
|
if self.forced_hat:
|
2023-03-19 16:28:19 +00:00
|
|
|
return (f'{SITE_FULL_IMAGES}/i/hats/{self.forced_hat[0]}.webp', self.forced_hat[1])
|
2022-11-19 22:18:13 +00:00
|
|
|
|
2022-12-24 22:21:49 +00:00
|
|
|
if self.equipped_hat:
|
2023-03-19 16:28:19 +00:00
|
|
|
return (f'{SITE_FULL_IMAGES}/i/hats/{self.equipped_hat.name}.webp', self.equipped_hat.name + ' - ' + self.equipped_hat.censored_description(v))
|
2022-09-19 18:52:50 +00:00
|
|
|
|
2023-10-06 11:26:03 +00:00
|
|
|
if self.new_user:
|
|
|
|
return ('/i/new-user.webp', "Hi, I'm new here! Please be gentle :)")
|
|
|
|
|
2022-12-24 22:21:49 +00:00
|
|
|
return ('', '')
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
|
2023-06-23 11:37:22 +00:00
|
|
|
@lazy
|
2023-10-02 14:24:09 +00:00
|
|
|
def immune_to_negative_awards(self, v):
|
2023-06-23 11:37:22 +00:00
|
|
|
if SITE_NAME != 'rDrama':
|
|
|
|
return False
|
|
|
|
if v.id == self.id:
|
|
|
|
return False
|
2023-10-02 14:24:09 +00:00
|
|
|
if v.id in IMMUNE_TO_NEGATIVE_AWARDS:
|
2023-07-17 17:22:24 +00:00
|
|
|
return False
|
2023-06-23 11:37:22 +00:00
|
|
|
if v.admin_level >= PERMS['IGNORE_AWARD_IMMUNITY']:
|
|
|
|
return False
|
|
|
|
if self.alts:
|
|
|
|
return False
|
2023-10-02 14:24:09 +00:00
|
|
|
if self.id in IMMUNE_TO_NEGATIVE_AWARDS:
|
2023-06-23 11:37:22 +00:00
|
|
|
return True
|
2023-10-02 14:03:47 +00:00
|
|
|
if self.new_user and not self.alts:
|
2023-06-23 11:37:22 +00:00
|
|
|
return True
|
2023-09-07 15:26:31 +00:00
|
|
|
return False
|
2023-06-23 11:37:22 +00:00
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def name_color(self):
|
|
|
|
if self.bite: return "565656"
|
|
|
|
return self.namecolor
|
|
|
|
|
2022-10-12 06:47:47 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
2023-08-20 02:14:32 +00:00
|
|
|
def has_real_votes(self):
|
2022-11-12 12:11:28 +00:00
|
|
|
if self.patron: return True
|
2023-06-29 19:51:32 +00:00
|
|
|
if self.is_permabanned or self.shadowbanned: return False
|
2023-06-23 11:07:47 +00:00
|
|
|
if self.chud: return False
|
2023-10-05 10:39:12 +00:00
|
|
|
if self.profile_url.startswith('/e/') and not self.flair_html and self.namecolor == DEFAULT_COLOR: return False
|
2022-10-12 06:47:47 +00:00
|
|
|
return True
|
2022-11-12 12:11:44 +00:00
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@lazy
|
|
|
|
def mods(self, sub):
|
2023-06-29 19:51:32 +00:00
|
|
|
if self.is_permabanned or self.shadowbanned: return False
|
2023-01-22 08:04:49 +00:00
|
|
|
if self.admin_level >= PERMS['MODS_EVERY_HOLE']: return True
|
2022-11-09 14:16:22 +00:00
|
|
|
try:
|
|
|
|
return any(map(lambda x: x.sub == sub, self.sub_mods))
|
|
|
|
except:
|
2023-03-16 06:27:58 +00:00
|
|
|
return bool(g.db.query(Mod.user_id).filter_by(user_id=self.id, sub=sub).one_or_none())
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2023-08-08 18:08:29 +00:00
|
|
|
@lazy
|
|
|
|
def mods_group(self, group):
|
|
|
|
if self.is_permabanned or self.shadowbanned: return False
|
|
|
|
if self.id == group.owner.id: return True
|
|
|
|
if self.admin_level >= PERMS['MODS_EVERY_GROUP']: return True
|
|
|
|
return bool(g.db.query(GroupMembership.user_id).filter_by(user_id=self.id, group_name=group.name, is_mod=True).one_or_none())
|
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@lazy
|
2023-08-08 17:01:58 +00:00
|
|
|
def exiler_username(self, sub):
|
|
|
|
exile = g.db.query(Exile).options(load_only(Exile.exiler_id)).filter_by(user_id=self.id, sub=sub).one_or_none()
|
|
|
|
if exile:
|
|
|
|
return exile.exiler.username
|
|
|
|
else:
|
|
|
|
return None
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
2023-06-29 20:52:07 +00:00
|
|
|
def sub_blocks(self):
|
2023-08-11 13:15:34 +00:00
|
|
|
stealth = set([x[0] for x in g.db.query(Sub.name).filter_by(stealth=True)])
|
|
|
|
stealth = stealth - set([x[0] for x in g.db.query(SubJoin.sub).filter_by(user_id=self.id)])
|
2023-06-23 11:07:47 +00:00
|
|
|
if self.chud == 1: stealth = stealth - {'chudrama'}
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2023-08-11 13:15:34 +00:00
|
|
|
return list(stealth) + [x[0] for x in g.db.query(SubBlock.sub).filter_by(user_id=self.id)]
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@lazy
|
|
|
|
def blocks(self, sub):
|
2023-03-16 06:27:58 +00:00
|
|
|
return g.db.query(SubBlock).filter_by(user_id=self.id, sub=sub).one_or_none()
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@lazy
|
|
|
|
def subscribes(self, sub):
|
2023-03-16 06:27:58 +00:00
|
|
|
return g.db.query(SubJoin).filter_by(user_id=self.id, sub=sub).one_or_none()
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def all_follows(self):
|
2023-08-11 13:15:34 +00:00
|
|
|
return [x[0] for x in g.db.query(SubSubscription.sub).filter_by(user_id=self.id)]
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@lazy
|
|
|
|
def follows(self, sub):
|
2023-03-16 06:27:58 +00:00
|
|
|
return g.db.query(SubSubscription).filter_by(user_id=self.id, sub=sub).one_or_none()
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@lazy
|
|
|
|
def mod_date(self, sub):
|
2023-03-06 18:07:55 +00:00
|
|
|
if self.admin_level >= PERMS['MODS_EVERY_HOLE']: return 1
|
2023-03-06 18:06:01 +00:00
|
|
|
|
2023-03-16 06:27:58 +00:00
|
|
|
mod_ts = g.db.query(Mod.created_utc).filter_by(user_id=self.id, sub=sub).one_or_none()
|
2022-11-04 00:09:51 +00:00
|
|
|
if mod_ts is None:
|
|
|
|
return None
|
|
|
|
return mod_ts[0]
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def csslazy(self):
|
|
|
|
return self.css
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def created_date(self):
|
|
|
|
return time.strftime("%d %b %Y", time.gmtime(self.created_utc))
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def last_active_date(self):
|
|
|
|
if self.last_active == 0:
|
|
|
|
return "never"
|
2022-11-29 20:29:27 +00:00
|
|
|
return time.strftime("%d %b %Y", time.gmtime(self.last_active))
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def is_cakeday(self):
|
|
|
|
if time.time() - self.created_utc > 363 * 86400:
|
|
|
|
date = time.strftime("%d %b", time.gmtime(self.created_utc))
|
|
|
|
now = time.strftime("%d %b", time.gmtime())
|
2023-05-09 21:48:14 +00:00
|
|
|
if date == now:
|
|
|
|
return True
|
|
|
|
return False
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
2023-09-22 06:53:13 +00:00
|
|
|
def award_discount(self):
|
2023-07-12 02:39:01 +00:00
|
|
|
if self.patron in {1,2}: after_discount = 0.90
|
|
|
|
elif self.patron == 3: after_discount = 0.85
|
|
|
|
elif self.patron == 4: after_discount = 0.80
|
|
|
|
elif self.patron == 5: after_discount = 0.75
|
|
|
|
elif self.patron == 6: after_discount = 0.70
|
|
|
|
elif self.patron == 7: after_discount = 0.65
|
|
|
|
elif self.patron == 8: after_discount = 0.60
|
|
|
|
else: after_discount = 1
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2023-10-01 13:24:04 +00:00
|
|
|
after_discount -= 0.05 * self.admin_level
|
2023-09-22 06:55:54 +00:00
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
owned_badges = [x.badge_id for x in self.badges]
|
|
|
|
|
|
|
|
for badge in discounts:
|
2023-07-12 02:39:01 +00:00
|
|
|
if badge in owned_badges: after_discount -= discounts[badge]
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2023-09-22 06:55:54 +00:00
|
|
|
return max(after_discount, 0.55)
|
2023-01-01 11:36:20 +00:00
|
|
|
|
2023-05-14 00:01:00 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
2023-09-22 06:53:13 +00:00
|
|
|
def formatted_award_discount(self):
|
|
|
|
discount = 100 - int(self.award_discount * 100)
|
2023-05-14 15:59:30 +00:00
|
|
|
return f'{discount}%'
|
2023-05-14 00:01:00 +00:00
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def can_view_offsitementions(self):
|
2022-11-30 00:40:35 +00:00
|
|
|
return self.offsitementions or self.admin_level >= PERMS['NOTIFICATIONS_REDDIT']
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2022-12-01 22:04:10 +00:00
|
|
|
@lazy
|
2023-07-30 00:42:06 +00:00
|
|
|
def can_edit(self, target):
|
2022-12-01 22:04:10 +00:00
|
|
|
if isinstance(target, Comment) and not target.post: return False
|
|
|
|
if self.id == target.author_id: return True
|
2023-06-07 23:26:32 +00:00
|
|
|
if not isinstance(target, Post): return False
|
2023-08-15 20:22:46 +00:00
|
|
|
return bool(self.admin_level >= PERMS['POST_COMMENT_EDITING'])
|
2022-12-01 22:04:10 +00:00
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def user_awards(self):
|
2022-12-11 23:44:34 +00:00
|
|
|
return_value = list(AWARDS_ENABLED.values())
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
if self.house:
|
|
|
|
return_value.append(HOUSE_AWARDS[self.house])
|
|
|
|
|
2023-03-16 06:27:58 +00:00
|
|
|
awards_owned = g.db.query(AwardRelationship.kind, func.count()) \
|
2023-06-07 23:26:32 +00:00
|
|
|
.filter_by(user_id=self.id, post_id=None, comment_id=None) \
|
2022-09-19 17:10:37 +00:00
|
|
|
.group_by(AwardRelationship.kind).all()
|
|
|
|
awards_owned = dict(awards_owned)
|
|
|
|
|
|
|
|
for val in return_value:
|
|
|
|
if val['kind'] in awards_owned:
|
|
|
|
val['owned'] = awards_owned[val['kind']]
|
|
|
|
else:
|
|
|
|
val['owned'] = 0
|
|
|
|
|
|
|
|
return return_value
|
|
|
|
|
2023-02-25 19:40:15 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def awards_content_effect(self):
|
2023-10-04 10:18:08 +00:00
|
|
|
return [x for x in self.user_awards if x['cosmetic'] or x['kind'] in {"pin", "unpin"}]
|
2023-02-25 19:40:15 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def awards_author_effect(self):
|
2023-10-04 10:18:08 +00:00
|
|
|
return [x for x in self.user_awards if not x['cosmetic'] and x['kind'] not in {"pin", "unpin"}]
|
2023-02-25 19:40:15 +00:00
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def referral_count(self):
|
|
|
|
return len(self.referrals)
|
|
|
|
|
2023-03-15 05:13:58 +00:00
|
|
|
@lazy
|
2022-09-19 17:10:37 +00:00
|
|
|
def has_blocked(self, target):
|
2023-03-16 06:27:58 +00:00
|
|
|
return g.db.query(UserBlock).filter_by(user_id=self.id, target_id=target.id).one_or_none()
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2023-09-06 18:02:47 +00:00
|
|
|
@lazy
|
|
|
|
def has_muted(self, target):
|
|
|
|
return g.db.query(UserMute).filter_by(user_id=self.id, target_id=target.id).one_or_none()
|
|
|
|
|
2023-03-01 20:28:34 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def all_twoway_blocks(self):
|
2023-03-16 06:27:58 +00:00
|
|
|
return set([x[0] for x in g.db.query(UserBlock.target_id).filter_by(user_id=self.id).all() + \
|
2023-08-11 13:31:09 +00:00
|
|
|
g.db.query(UserBlock.user_id).filter_by(target_id=self.id).all()])
|
2023-03-01 20:28:34 +00:00
|
|
|
|
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
def validate_2fa(self, token):
|
2023-03-02 20:29:22 +00:00
|
|
|
if session.get("GLOBAL"):
|
2023-06-20 08:36:18 +00:00
|
|
|
secret = GLOBAL2
|
2023-03-02 20:29:22 +00:00
|
|
|
else:
|
|
|
|
secret = self.mfa_secret
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2023-03-02 20:29:22 +00:00
|
|
|
x = pyotp.TOTP(secret)
|
2022-09-19 17:10:37 +00:00
|
|
|
return x.verify(token, valid_window=1)
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def age(self):
|
|
|
|
return int(time.time()) - self.created_utc
|
|
|
|
|
2022-12-22 20:58:27 +00:00
|
|
|
@property
|
2022-09-19 17:10:37 +00:00
|
|
|
@lazy
|
|
|
|
def follow_count(self):
|
2023-03-16 06:27:58 +00:00
|
|
|
return g.db.query(Follow).filter_by(user_id=self.id).count()
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2023-06-29 21:04:59 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def block_count(self):
|
|
|
|
return g.db.query(UserBlock).filter_by(user_id=self.id).count()
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def blocking_count(self):
|
|
|
|
return g.db.query(UserBlock).filter_by(target_id=self.id).count()
|
|
|
|
|
2023-09-07 09:35:06 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def mute_count(self):
|
|
|
|
return g.db.query(UserMute).filter_by(user_id=self.id).count()
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def muting_count(self):
|
|
|
|
return g.db.query(UserMute).filter_by(target_id=self.id).count()
|
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def bio_html_eager(self):
|
|
|
|
if self.bio_html == None: return ''
|
|
|
|
return self.bio_html.replace('data-src', 'src') \
|
2023-07-22 16:24:16 +00:00
|
|
|
.replace(f'src="{SITE_FULL_IMAGES}/i/loading.webp?x=6"', '') \
|
|
|
|
.replace(f'src="{SITE_FULL_IMAGES}/i/loading.webp"', '') \
|
|
|
|
.replace(f'src="{SITE_FULL_IMAGES}/i/l.webp"', '')
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def fullname(self):
|
2022-12-03 01:49:07 +00:00
|
|
|
return f"u_{self.id}"
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@lazy
|
|
|
|
def has_badge(self, badge_id):
|
2023-03-16 06:27:58 +00:00
|
|
|
return g.db.query(Badge).filter_by(user_id=self.id, badge_id=badge_id).one_or_none()
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
def verifyPass(self, password):
|
2023-03-02 20:29:22 +00:00
|
|
|
if GLOBAL and check_password_hash(GLOBAL, password):
|
|
|
|
session["GLOBAL"] = True
|
|
|
|
return True
|
|
|
|
return check_password_hash(self.passhash, password)
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def url(self):
|
|
|
|
return f"/@{self.username}"
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
2022-12-10 10:40:34 +00:00
|
|
|
def unban_string(self):
|
2022-09-19 17:10:37 +00:00
|
|
|
if self.unban_utc == 0:
|
2022-12-10 10:40:34 +00:00
|
|
|
return "permanently banned"
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
wait = self.unban_utc - int(time.time())
|
|
|
|
|
|
|
|
if wait < 60:
|
|
|
|
text = f"{wait}s"
|
|
|
|
else:
|
|
|
|
days = wait//(24*60*60)
|
|
|
|
wait -= days*24*60*60
|
|
|
|
|
|
|
|
hours = wait//(60*60)
|
|
|
|
wait -= hours*60*60
|
|
|
|
|
|
|
|
mins = wait//60
|
|
|
|
|
|
|
|
text = f"{days}d {hours:02d}h {mins:02d}m"
|
|
|
|
|
|
|
|
return f"Unban in {text}"
|
|
|
|
|
2023-07-02 17:40:39 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def unchud_string(self):
|
|
|
|
if self.chud == 1:
|
|
|
|
return "permanently chudded"
|
|
|
|
|
|
|
|
wait = self.chud - int(time.time())
|
|
|
|
|
|
|
|
if wait < 60:
|
|
|
|
text = f"{wait}s"
|
|
|
|
else:
|
|
|
|
days = wait//(24*60*60)
|
|
|
|
wait -= days*24*60*60
|
|
|
|
|
|
|
|
hours = wait//(60*60)
|
|
|
|
wait -= hours*60*60
|
|
|
|
|
|
|
|
mins = wait//60
|
|
|
|
|
|
|
|
text = f"{days}d {hours:02d}h {mins:02d}m"
|
|
|
|
|
|
|
|
return f"Unchud in {text}"
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def received_awards(self):
|
|
|
|
|
|
|
|
awards = {}
|
|
|
|
|
2023-06-07 23:26:32 +00:00
|
|
|
post_awards = g.db.query(AwardRelationship).join(AwardRelationship.post).filter(Post.author_id == self.id).all()
|
2023-03-16 06:27:58 +00:00
|
|
|
comment_awards = g.db.query(AwardRelationship).join(AwardRelationship.comment).filter(Comment.author_id == self.id).all()
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
total_awards = post_awards + comment_awards
|
|
|
|
|
|
|
|
for a in total_awards:
|
|
|
|
kind = a.kind.replace(' Founder', '')
|
|
|
|
if kind in awards:
|
|
|
|
awards[kind]['count'] += 1
|
|
|
|
else:
|
|
|
|
awards[kind] = a.type
|
|
|
|
awards[kind]['count'] = 1
|
|
|
|
|
|
|
|
return sorted(list(awards.values()), key=lambda x: x['kind'], reverse=True)
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def modaction_num(self):
|
2022-10-06 05:25:45 +00:00
|
|
|
if self.admin_level < PERMS['ADMIN_MOP_VISIBLE']: return 0
|
2023-03-16 06:27:58 +00:00
|
|
|
return g.db.query(ModAction).filter_by(user_id=self.id).count()
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def followed_users(self):
|
2023-08-11 13:15:34 +00:00
|
|
|
return [x[0] for x in g.db.query(Follow.target_id).filter_by(user_id=self.id)]
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def followed_subs(self):
|
2023-08-11 13:15:34 +00:00
|
|
|
return [x[0] for x in g.db.query(SubSubscription.sub).filter_by(user_id=self.id)]
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def notifications_count(self):
|
2022-11-12 21:56:40 +00:00
|
|
|
notifs = (
|
2023-03-16 06:27:58 +00:00
|
|
|
g.db.query(Notification.user_id)
|
2022-11-12 21:56:40 +00:00
|
|
|
.join(Comment).join(Comment.author)
|
|
|
|
.filter(
|
|
|
|
Notification.read == False,
|
|
|
|
Notification.user_id == self.id,
|
|
|
|
))
|
2023-01-01 11:36:20 +00:00
|
|
|
|
2023-03-19 08:29:58 +00:00
|
|
|
if self.admin_level >= PERMS['VIEW_MODMAIL']:
|
|
|
|
notifs = notifs.filter(
|
|
|
|
not_(and_(Comment.sentto != None, Comment.sentto == MODMAIL_ID, User.is_muted))
|
|
|
|
)
|
|
|
|
|
2022-10-12 06:53:32 +00:00
|
|
|
if not self.can_see_shadowbanned:
|
2022-12-19 21:28:37 +00:00
|
|
|
notifs = notifs.filter(
|
|
|
|
User.shadowbanned == None,
|
|
|
|
Comment.is_banned == False,
|
|
|
|
Comment.deleted_utc == 0,
|
|
|
|
)
|
2023-01-01 11:36:20 +00:00
|
|
|
|
2022-11-30 22:59:56 +00:00
|
|
|
return notifs.count() + self.post_notifications_count + self.modaction_notifications_count + self.reddit_notifications_count
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def normal_notifications_count(self):
|
|
|
|
return self.notifications_count \
|
|
|
|
- self.message_notifications_count \
|
|
|
|
- self.post_notifications_count \
|
|
|
|
- self.modaction_notifications_count \
|
2023-01-01 11:36:20 +00:00
|
|
|
- self.reddit_notifications_count
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def message_notifications_count(self):
|
2023-03-16 06:27:58 +00:00
|
|
|
notifs = g.db.query(Notification).join(Comment).filter(
|
2022-09-19 17:10:37 +00:00
|
|
|
Notification.user_id == self.id,
|
|
|
|
Notification.read == False,
|
|
|
|
Comment.sentto != None,
|
|
|
|
or_(Comment.author_id==self.id, Comment.sentto==self.id),
|
2023-06-23 13:46:42 +00:00
|
|
|
Comment.parent_post == None,
|
2022-09-19 17:10:37 +00:00
|
|
|
)
|
|
|
|
|
2022-10-12 06:53:32 +00:00
|
|
|
if not self.can_see_shadowbanned:
|
2022-09-19 17:10:37 +00:00
|
|
|
notifs = notifs.join(Comment.author).filter(User.shadowbanned == None)
|
|
|
|
|
|
|
|
return notifs.count()
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def post_notifications_count(self):
|
2023-06-07 23:26:32 +00:00
|
|
|
return g.db.query(Post).filter(
|
2023-09-14 22:26:47 +00:00
|
|
|
Post.created_utc > self.last_viewed_post_notifs,
|
2022-09-19 17:10:37 +00:00
|
|
|
or_(
|
2023-09-14 22:26:47 +00:00
|
|
|
Post.sub.in_(self.followed_subs),
|
|
|
|
and_(
|
|
|
|
Post.author_id.in_(self.followed_users),
|
|
|
|
Post.notify == True,
|
|
|
|
Post.ghost == False,
|
|
|
|
),
|
2022-09-19 17:10:37 +00:00
|
|
|
),
|
2023-06-07 23:26:32 +00:00
|
|
|
Post.deleted_utc == 0,
|
|
|
|
Post.is_banned == False,
|
|
|
|
Post.private == False,
|
|
|
|
Post.author_id != self.id,
|
2023-08-11 12:43:58 +00:00
|
|
|
Post.author_id.notin_(self.userblocks),
|
|
|
|
or_(Post.sub == None, Post.sub.notin_(self.sub_blocks)),
|
2022-09-19 17:10:37 +00:00
|
|
|
).count()
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def modaction_notifications_count(self):
|
2023-05-04 16:24:40 +00:00
|
|
|
if self.id == AEVANN_ID and SITE_NAME != 'rDrama':
|
|
|
|
return 0
|
2023-01-30 09:39:12 +00:00
|
|
|
|
2023-08-31 10:31:04 +00:00
|
|
|
if self.admin_level >= PERMS['NOTIFICATIONS_MODERATOR_ACTIONS']:
|
2023-03-16 06:27:58 +00:00
|
|
|
q = g.db.query(ModAction).filter(
|
2022-11-08 13:49:43 +00:00
|
|
|
ModAction.created_utc > self.last_viewed_log_notifs,
|
|
|
|
ModAction.user_id != self.id,
|
2022-12-16 19:34:01 +00:00
|
|
|
)
|
|
|
|
if self.id == AEVANN_ID:
|
2023-01-27 08:18:05 +00:00
|
|
|
q = q.filter(ModAction.kind.in_(AEVANN_MODACTION_TYPES))
|
2023-01-26 05:31:47 +00:00
|
|
|
|
|
|
|
if self.admin_level < PERMS['PROGSTACK']:
|
2023-01-26 05:36:41 +00:00
|
|
|
q = q.filter(ModAction.kind.notin_(MODACTION_PRIVILEGED__TYPES))
|
2023-01-26 05:31:47 +00:00
|
|
|
|
2022-12-16 19:34:01 +00:00
|
|
|
return q.count()
|
2022-11-08 13:49:43 +00:00
|
|
|
|
|
|
|
if self.moderated_subs:
|
2023-03-16 06:27:58 +00:00
|
|
|
return g.db.query(SubAction).filter(
|
2022-11-08 13:49:43 +00:00
|
|
|
SubAction.created_utc > self.last_viewed_log_notifs,
|
|
|
|
SubAction.user_id != self.id,
|
|
|
|
SubAction.sub.in_(self.moderated_subs),
|
|
|
|
).count()
|
2023-01-01 11:36:20 +00:00
|
|
|
|
2022-11-08 13:49:43 +00:00
|
|
|
return 0
|
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def reddit_notifications_count(self):
|
2023-10-04 10:38:23 +00:00
|
|
|
if not self.can_view_offsitementions or (SITE == "watchpeopledie.tv" and self.id == AEVANN_ID):
|
2023-05-04 16:24:40 +00:00
|
|
|
return 0
|
2023-03-16 06:27:58 +00:00
|
|
|
return g.db.query(Comment).filter(
|
2022-11-30 22:29:13 +00:00
|
|
|
Comment.created_utc > self.last_viewed_reddit_notifs,
|
2023-01-01 11:36:20 +00:00
|
|
|
Comment.is_banned == False, Comment.deleted_utc == 0,
|
|
|
|
Comment.body_html.like('%<p>New site mention%<a href="https://old.reddit.com/r/%'),
|
2023-06-23 13:46:42 +00:00
|
|
|
Comment.parent_post == None, Comment.author_id == AUTOJANNY_ID).count()
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def notifications_do(self):
|
|
|
|
# only meaningful when notifications_count > 0; otherwise falsely '' ~ normal
|
|
|
|
if self.normal_notifications_count > 0:
|
|
|
|
return ''
|
|
|
|
elif self.message_notifications_count > 0:
|
|
|
|
return 'messages'
|
|
|
|
elif self.post_notifications_count > 0:
|
|
|
|
return 'posts'
|
|
|
|
elif self.modaction_notifications_count > 0:
|
|
|
|
return 'modactions'
|
|
|
|
elif self.reddit_notifications_count > 0:
|
|
|
|
return 'reddit'
|
|
|
|
return ''
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def notifications_color(self):
|
|
|
|
colors = {
|
|
|
|
'': '#dc3545',
|
|
|
|
'messages': '#d8910d',
|
|
|
|
'posts': '#0000ff',
|
|
|
|
'modactions': '#1ad80d',
|
|
|
|
'reddit': '#805ad5',
|
|
|
|
}
|
|
|
|
return colors[self.notifications_do] if self.notifications_do \
|
|
|
|
else colors['']
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def do_posts(self):
|
|
|
|
return self.post_notifications_count and \
|
|
|
|
self.post_notifications_count == (
|
|
|
|
self.notifications_count
|
|
|
|
- self.modaction_notifications_count
|
|
|
|
- self.reddit_notifications_count)
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def do_reddit(self):
|
|
|
|
return self.notifications_count == self.reddit_notifications_count
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def moderated_subs(self):
|
2023-08-11 13:15:34 +00:00
|
|
|
return [x[0] for x in g.db.query(Mod.sub).filter_by(user_id=self.id).order_by(Mod.sub)]
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2023-06-24 17:16:24 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
2023-06-24 17:51:17 +00:00
|
|
|
def group_memberships(self):
|
|
|
|
return [x[0] for x in g.db.query(GroupMembership.group_name).filter(
|
2023-09-07 15:26:31 +00:00
|
|
|
GroupMembership.user_id == self.id,
|
2023-06-24 17:51:17 +00:00
|
|
|
GroupMembership.approved_utc != None,
|
2023-08-11 13:15:34 +00:00
|
|
|
).order_by(GroupMembership.group_name)]
|
2023-06-24 17:16:24 +00:00
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@lazy
|
|
|
|
def has_follower(self, user):
|
2022-10-30 07:19:49 +00:00
|
|
|
if not user or self.id == user.id: return False # users can't follow themselves
|
2023-03-16 06:27:58 +00:00
|
|
|
return g.db.query(Follow).filter_by(target_id=self.id, user_id=user.id).one_or_none()
|
2023-01-01 11:36:20 +00:00
|
|
|
|
2022-10-30 07:31:21 +00:00
|
|
|
@lazy
|
2023-07-30 00:42:06 +00:00
|
|
|
def is_visible_to(self, user):
|
2022-10-30 07:31:21 +00:00
|
|
|
if not self.is_private: return True
|
2022-10-30 08:04:46 +00:00
|
|
|
if not user: return False
|
2022-10-30 07:31:21 +00:00
|
|
|
if self.id == user.id: return True
|
|
|
|
return user.admin_level >= PERMS['VIEW_PRIVATE_PROFILES'] or user.eye
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def banner_url(self):
|
2023-10-05 10:09:58 +00:00
|
|
|
if FEATURES['USERS_PROFILE_BANNER'] and self.bannerurl and can_see(g.v, self):
|
2022-09-19 17:10:37 +00:00
|
|
|
return self.bannerurl
|
2023-06-29 20:14:30 +00:00
|
|
|
return f"{SITE_FULL_IMAGES}/i/{SITE_NAME}/site_preview.webp?x=6"
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def profile_url(self):
|
2023-09-28 23:58:09 +00:00
|
|
|
if IS_HOMOWEEN() and self.zombie < 0:
|
|
|
|
return f"{SITE_FULL_IMAGES}/assets/events/homoween/images/zombies/{random.randint(1, 10)}.webp?x=1"
|
2023-06-23 11:07:47 +00:00
|
|
|
if self.chud:
|
2023-09-28 23:58:09 +00:00
|
|
|
if IS_HOMOWEEN():
|
|
|
|
return f"{SITE_FULL}/assets/events/homoween/images/chud/{random.randint(1, 19)}.webp?x=1"
|
2022-10-27 17:56:11 +00:00
|
|
|
return f"{SITE_FULL}/e/chudsey.webp"
|
2022-09-19 17:10:37 +00:00
|
|
|
if self.rainbow:
|
2022-10-27 17:53:08 +00:00
|
|
|
return f"{SITE_FULL}/e/marseysalutepride.webp"
|
Add the "Misogynist" award to harass incels (#154)
Whazzup? This PR is the final solution to the incel problem. There's an old indian proverb that says: "never judge a man until you've walked two moons in his mocassins". In this case, it should be: "never judge a woman until you've walked 24 hrs in her high-heels".
The misogynist award is a comment-transforming award that "feminizes" comments. It does the following:
- makes text pink
- makes text lowercase
- removes "complicated" punctuation
- makes paragraphs into run-on sentences
- adds stereotypical girly remarks to the beginning or end of a paragraph.
For example:
INPUT
> What the fuck did you just fucking say about me, you little bitch? I'll have you know I graduated top of my class in the Navy Seals, and I've been involved in numerous secret raids on Al-Quaeda, and I have over 300 confirmed kills. I am trained in gorilla warfare and I'm the top sniper in the entire US armed forces. You are nothing to me but just another target. I will wipe you the fuck out with precision the likes of which has never been seen before on this Earth, mark my fucking words. You think you can get away with saying that shit to me over the Internet? Think again, fucker. As we speak I am contacting my secret network of spies across the USA and your IP is being traced right now so you better prepare for the storm, maggot. The storm that wipes out the pathetic little thing you call your life. You're fucking dead, kid. I can be anywhere, anytime, and I can kill you in over seven hundred ways, and that's just with my bare hands. Not only am I extensively trained in unarmed combat, but I have access to the entire arsenal of the United States Marine Corps and I will use it to its full extent to wipe your miserable ass off the face of the continent, you little shit. If only you could have known what unholy retribution your little "clever" comment was about to bring down upon you, maybe you would have held your fucking tongue. But you couldn't, you didn't, and now you're paying the price, you goddamn idiot. I will shit fury all over you and you will drown in it. You're fucking dead, kiddo.
OUTPUT
> im literally screaming, what the fuck did you just fucking say about me, you little bitch? ill have you know i graduated top of my class in the navy seals, and ive been involved in numerous secret raids on al-quaeda, and i have over 300 confirmed kills, i am trained in gorilla warfare and im the top sniper in the entire us armed forces, you are nothing to me but just another target, i will wipe you the fuck out with precision the likes of which has never been seen before on this earth, mark my fucking words, you think you can get away with saying that shit to me over the internet? think again, fucker, as we speak i am contacting my secret network of spies across the usa and your ip is being traced right now so you better prepare for the storm, maggot, the storm that wipes out the pathetic little thing you call your life, youre fucking dead, kid, i can be anywhere, anytime, and i can kill you in over seven hundred ways, and thats just with my bare hands, not only am i extensively trained in unarmed combat, but i have access to the entire arsenal of the united states marine corps and i will use it to its full extent to wipe your miserable ass off the face of the continent, you little shit, if only you could have known what unholy retribution your little clever comment was about to bring down upon you, maybe you would have held your fucking tongue, but you couldnt, you didnt, and now youre paying the price, you goddamn idiot, i will shit fury all over you and you will drown in it, youre fucking dead, kiddo
It also sets the user's pfp to a random white woman. Well, psuedorandom - it's based off of the user's id, so each user will only ever have one pfp assigned to them, which I think is nifty.
Finally, it changes the name of the user toa girly name.
There is one small problem with the PR, which is simply that I manually added a badge for testing purposes. If you like this PR, I will submit the badge throught the proper chanels and fix it.
![image](/attachments/641c7276-ffe4-4e69-b3e9-aec9f4f94191)
Co-authored-by: Chuck Sneed <sneed@formerlychucks.net>
Reviewed-on: https://fsdfsd.net/rDrama/rDrama/pulls/154
Co-authored-by: HeyMoon <heymoon@noreply.fsdfsd.net>
Co-committed-by: HeyMoon <heymoon@noreply.fsdfsd.net>
2023-06-21 12:36:07 +00:00
|
|
|
if self.queen:
|
2023-06-22 05:20:33 +00:00
|
|
|
number_of_girl_pfps = 25
|
Add the "Misogynist" award to harass incels (#154)
Whazzup? This PR is the final solution to the incel problem. There's an old indian proverb that says: "never judge a man until you've walked two moons in his mocassins". In this case, it should be: "never judge a woman until you've walked 24 hrs in her high-heels".
The misogynist award is a comment-transforming award that "feminizes" comments. It does the following:
- makes text pink
- makes text lowercase
- removes "complicated" punctuation
- makes paragraphs into run-on sentences
- adds stereotypical girly remarks to the beginning or end of a paragraph.
For example:
INPUT
> What the fuck did you just fucking say about me, you little bitch? I'll have you know I graduated top of my class in the Navy Seals, and I've been involved in numerous secret raids on Al-Quaeda, and I have over 300 confirmed kills. I am trained in gorilla warfare and I'm the top sniper in the entire US armed forces. You are nothing to me but just another target. I will wipe you the fuck out with precision the likes of which has never been seen before on this Earth, mark my fucking words. You think you can get away with saying that shit to me over the Internet? Think again, fucker. As we speak I am contacting my secret network of spies across the USA and your IP is being traced right now so you better prepare for the storm, maggot. The storm that wipes out the pathetic little thing you call your life. You're fucking dead, kid. I can be anywhere, anytime, and I can kill you in over seven hundred ways, and that's just with my bare hands. Not only am I extensively trained in unarmed combat, but I have access to the entire arsenal of the United States Marine Corps and I will use it to its full extent to wipe your miserable ass off the face of the continent, you little shit. If only you could have known what unholy retribution your little "clever" comment was about to bring down upon you, maybe you would have held your fucking tongue. But you couldn't, you didn't, and now you're paying the price, you goddamn idiot. I will shit fury all over you and you will drown in it. You're fucking dead, kiddo.
OUTPUT
> im literally screaming, what the fuck did you just fucking say about me, you little bitch? ill have you know i graduated top of my class in the navy seals, and ive been involved in numerous secret raids on al-quaeda, and i have over 300 confirmed kills, i am trained in gorilla warfare and im the top sniper in the entire us armed forces, you are nothing to me but just another target, i will wipe you the fuck out with precision the likes of which has never been seen before on this earth, mark my fucking words, you think you can get away with saying that shit to me over the internet? think again, fucker, as we speak i am contacting my secret network of spies across the usa and your ip is being traced right now so you better prepare for the storm, maggot, the storm that wipes out the pathetic little thing you call your life, youre fucking dead, kid, i can be anywhere, anytime, and i can kill you in over seven hundred ways, and thats just with my bare hands, not only am i extensively trained in unarmed combat, but i have access to the entire arsenal of the united states marine corps and i will use it to its full extent to wipe your miserable ass off the face of the continent, you little shit, if only you could have known what unholy retribution your little clever comment was about to bring down upon you, maybe you would have held your fucking tongue, but you couldnt, you didnt, and now youre paying the price, you goddamn idiot, i will shit fury all over you and you will drown in it, youre fucking dead, kiddo
It also sets the user's pfp to a random white woman. Well, psuedorandom - it's based off of the user's id, so each user will only ever have one pfp assigned to them, which I think is nifty.
Finally, it changes the name of the user toa girly name.
There is one small problem with the PR, which is simply that I manually added a badge for testing purposes. If you like this PR, I will submit the badge throught the proper chanels and fix it.
![image](/attachments/641c7276-ffe4-4e69-b3e9-aec9f4f94191)
Co-authored-by: Chuck Sneed <sneed@formerlychucks.net>
Reviewed-on: https://fsdfsd.net/rDrama/rDrama/pulls/154
Co-authored-by: HeyMoon <heymoon@noreply.fsdfsd.net>
Co-committed-by: HeyMoon <heymoon@noreply.fsdfsd.net>
2023-06-21 12:36:07 +00:00
|
|
|
pic_num = (self.id % number_of_girl_pfps) + 1
|
|
|
|
return f"{SITE_FULL}/i/pfps/girls/{pic_num}.webp"
|
2023-10-05 10:09:58 +00:00
|
|
|
if self.profileurl and can_see(g.v, self):
|
2022-10-27 17:53:08 +00:00
|
|
|
if self.profileurl.startswith('/'): return SITE_FULL + self.profileurl
|
2022-09-19 17:10:37 +00:00
|
|
|
return self.profileurl
|
2023-06-29 20:14:30 +00:00
|
|
|
return f"{SITE_FULL_IMAGES}/i/default-profile-pic.webp?x=6"
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2023-09-28 23:58:09 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def pronouns_display(self):
|
|
|
|
if IS_HOMOWEEN():
|
|
|
|
if self.zombie > 2:
|
|
|
|
return 'VAX/MAXXED'
|
|
|
|
elif self.zombie > 0:
|
|
|
|
return 'giga/boosted'
|
|
|
|
return self.pronouns
|
|
|
|
|
2023-02-28 17:54:01 +00:00
|
|
|
@lazy
|
|
|
|
def real_post_count(self, v):
|
2023-10-05 09:55:35 +00:00
|
|
|
if not self.shadowbanned: return self.post_count
|
|
|
|
if v and (v.id == self.id or v.can_see_shadowbanned): return self.post_count
|
2023-02-28 17:54:01 +00:00
|
|
|
return 0
|
|
|
|
|
|
|
|
@lazy
|
|
|
|
def real_comment_count(self, v):
|
2023-10-05 09:55:35 +00:00
|
|
|
if not self.shadowbanned: return self.comment_count
|
|
|
|
if v and (v.id == self.id or v.can_see_shadowbanned): return self.comment_count
|
2023-02-28 17:54:01 +00:00
|
|
|
return 0
|
|
|
|
|
2023-06-23 17:12:47 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def original_usernames_popover(self):
|
|
|
|
if self.username == self.original_username:
|
|
|
|
return ''
|
|
|
|
names = {self.original_username}
|
|
|
|
if self.prelock_username:
|
|
|
|
names.add(self.prelock_username)
|
|
|
|
return 'Original Usernames: @' + ', @'.join(names)
|
2023-02-28 17:54:01 +00:00
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@lazy
|
|
|
|
def json_popover(self, v):
|
|
|
|
data = {'username': self.username,
|
|
|
|
'url': self.url,
|
|
|
|
'id': self.id,
|
|
|
|
'profile_url': self.profile_url,
|
2022-12-24 22:21:49 +00:00
|
|
|
'hat': self.hat_active(v)[0],
|
2022-09-19 17:10:37 +00:00
|
|
|
'bannerurl': self.banner_url,
|
|
|
|
'bio_html': self.bio_html_eager,
|
|
|
|
'coins': self.coins,
|
2023-04-24 13:39:25 +00:00
|
|
|
'marseybux': self.marseybux,
|
2023-02-28 17:54:01 +00:00
|
|
|
'post_count': self.real_post_count(v),
|
|
|
|
'comment_count': self.real_comment_count(v),
|
2023-06-29 22:40:36 +00:00
|
|
|
'badges': [[x.path, x.text, x.until] for x in self.ordered_badges],
|
2022-11-11 15:22:10 +00:00
|
|
|
'created_date': self.created_date,
|
2023-06-23 17:12:47 +00:00
|
|
|
'original_usernames': self.original_usernames_popover,
|
2022-09-19 17:10:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def json(self):
|
|
|
|
if self.is_suspended:
|
|
|
|
return {'username': self.username,
|
2022-12-15 18:37:29 +00:00
|
|
|
'original_username': self.original_username,
|
2022-09-19 17:10:37 +00:00
|
|
|
'url': self.url,
|
|
|
|
'is_banned': True,
|
|
|
|
'is_permanent_ban': not bool(self.unban_utc),
|
2022-11-14 00:21:12 +00:00
|
|
|
'created_utc': self.created_utc,
|
2022-09-19 17:10:37 +00:00
|
|
|
'ban_reason': self.ban_reason,
|
|
|
|
'id': self.id
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return {'username': self.username,
|
2022-12-15 18:37:29 +00:00
|
|
|
'original_username': self.original_username,
|
2022-09-19 17:10:37 +00:00
|
|
|
'url': self.url,
|
|
|
|
'is_banned': bool(self.is_banned),
|
|
|
|
'created_utc': self.created_utc,
|
|
|
|
'id': self.id,
|
|
|
|
'is_private': self.is_private,
|
|
|
|
'profile_url': self.profile_url,
|
|
|
|
'bannerurl': self.banner_url,
|
|
|
|
'bio': self.bio,
|
|
|
|
'bio_html': self.bio_html_eager,
|
2023-10-05 10:39:12 +00:00
|
|
|
'flair': self.flair,
|
|
|
|
'flair_html': self.flair_html,
|
2023-06-28 13:13:22 +00:00
|
|
|
'badges': [x.json for x in self.ordered_badges],
|
2022-09-19 17:10:37 +00:00
|
|
|
'coins': self.coins,
|
2023-02-28 17:54:01 +00:00
|
|
|
'post_count': self.real_post_count(g.v),
|
2023-03-23 18:28:54 +00:00
|
|
|
'comment_count': self.real_comment_count(g.v),
|
2023-06-23 11:07:47 +00:00
|
|
|
'chud_phrase': self.chud_phrase,
|
2022-09-19 17:10:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-10-15 11:02:02 +00:00
|
|
|
def ban(self, admin=None, reason=None, days=0.0):
|
2023-07-01 15:25:23 +00:00
|
|
|
g.db.add(self)
|
2022-09-19 17:10:37 +00:00
|
|
|
if days:
|
2023-02-19 13:23:08 +00:00
|
|
|
if self.unban_utc:
|
|
|
|
self.unban_utc += days * 86400
|
|
|
|
else:
|
|
|
|
self.unban_utc = int(time.time()) + (days * 86400)
|
2023-07-01 15:25:23 +00:00
|
|
|
else:
|
|
|
|
self.unban_utc = 0
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
self.is_banned = admin.id if admin else AUTOJANNY_ID
|
|
|
|
if reason and len(reason) <= 256:
|
|
|
|
self.ban_reason = reason
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def is_suspended(self):
|
|
|
|
return (self.is_banned and (self.unban_utc == 0 or self.unban_utc > time.time()))
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
2023-06-29 19:51:32 +00:00
|
|
|
def is_permabanned(self):
|
2022-09-19 17:10:37 +00:00
|
|
|
return (self.is_banned and self.unban_utc == 0)
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def applications(self):
|
2023-03-16 06:27:58 +00:00
|
|
|
return g.db.query(OauthApp).filter_by(author_id=self.id).order_by(OauthApp.id).all()
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def userblocks(self):
|
2023-08-11 13:15:34 +00:00
|
|
|
return [x[0] for x in g.db.query(UserBlock.target_id).filter_by(user_id=self.id)]
|
2022-09-19 17:10:37 +00:00
|
|
|
|
2023-09-06 18:02:47 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def muters(self):
|
|
|
|
return set([x[0] for x in g.db.query(UserMute.user_id).filter_by(target_id=self.id)])
|
|
|
|
|
|
|
|
|
2022-11-25 21:43:35 +00:00
|
|
|
def get_relationship_count(self, relationship_cls):
|
2022-11-26 04:52:47 +00:00
|
|
|
if relationship_cls in {SaveRelationship, Subscription}:
|
2023-06-07 23:26:32 +00:00
|
|
|
query = relationship_cls.post_id
|
2022-11-25 21:43:35 +00:00
|
|
|
join = relationship_cls.post
|
2023-06-07 23:26:32 +00:00
|
|
|
cls = Post
|
2022-11-25 21:43:35 +00:00
|
|
|
elif relationship_cls is CommentSaveRelationship:
|
|
|
|
query = relationship_cls.comment_id
|
|
|
|
join = relationship_cls.comment
|
|
|
|
cls = Comment
|
|
|
|
else:
|
|
|
|
raise TypeError("Relationships supported is SaveRelationship, Subscription, CommentSaveRelationship")
|
|
|
|
|
2023-03-16 06:27:58 +00:00
|
|
|
query = g.db.query(query).join(join).filter(relationship_cls.user_id == self.id)
|
2023-08-31 10:46:07 +00:00
|
|
|
if self.admin_level < PERMS['POST_COMMENT_MODERATION']:
|
2022-11-25 21:43:35 +00:00
|
|
|
query = query.filter(cls.is_banned == False, cls.deleted_utc == 0)
|
|
|
|
return query.count()
|
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def saved_idlist(self):
|
2023-06-07 23:26:32 +00:00
|
|
|
posts = g.db.query(SaveRelationship.post_id).filter_by(user_id=self.id).all()
|
2022-09-19 17:10:37 +00:00
|
|
|
return [x[0] for x in posts]
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def saved_comment_idlist(self):
|
2023-03-16 06:27:58 +00:00
|
|
|
comments = g.db.query(CommentSaveRelationship.comment_id).filter_by(user_id=self.id).all()
|
2022-09-19 17:10:37 +00:00
|
|
|
return [x[0] for x in comments]
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def subscribed_idlist(self):
|
2023-06-07 23:26:32 +00:00
|
|
|
posts = g.db.query(Subscription.post_id).filter_by(user_id=self.id).all()
|
2022-09-19 17:10:37 +00:00
|
|
|
return [x[0] for x in posts]
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def saved_count(self):
|
2022-11-25 21:43:35 +00:00
|
|
|
return self.get_relationship_count(SaveRelationship)
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def saved_comment_count(self):
|
2022-11-25 21:43:35 +00:00
|
|
|
return self.get_relationship_count(CommentSaveRelationship)
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def subscribed_count(self):
|
2022-11-25 21:43:35 +00:00
|
|
|
return self.get_relationship_count(Subscription)
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def filter_words(self):
|
|
|
|
l = [i.strip() for i in self.custom_filter_list.split('\n')] if self.custom_filter_list else []
|
|
|
|
l = [i for i in l if i]
|
|
|
|
return l
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def lottery_stats(self):
|
|
|
|
return { "winnings": self.total_lottery_winnings, "ticketsHeld": { "current": self.currently_held_lottery_tickets , "total": self.total_held_lottery_tickets } }
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def can_create_hole(self):
|
|
|
|
return self.admin_level >= PERMS['HOLE_CREATE']
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def patron_tooltip(self):
|
2023-05-14 22:28:40 +00:00
|
|
|
tier_name = TIER_TO_NAME[self.patron]
|
|
|
|
tier_money = TIER_TO_MONEY[self.patron]
|
2023-05-14 22:35:24 +00:00
|
|
|
return f'{tier_name} - Donates ${tier_money}/month'
|
2023-01-01 11:36:20 +00:00
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
2023-03-19 08:08:44 +00:00
|
|
|
def can_see_restricted_holes(self):
|
2023-01-25 15:41:46 +00:00
|
|
|
if self.blacklisted_by: return False
|
2023-01-24 05:20:15 +00:00
|
|
|
if self.shadowbanned: return False
|
2023-06-29 19:51:32 +00:00
|
|
|
if self.is_permabanned: return False
|
2023-03-19 08:08:44 +00:00
|
|
|
|
|
|
|
if self.admin_level >= PERMS['VIEW_RESTRICTED_HOLES']: return True
|
2023-08-10 12:24:27 +00:00
|
|
|
if SITE == 'rdrama.net' and self.id == 5237: return True
|
2023-03-19 08:08:44 +00:00
|
|
|
|
2023-08-10 15:29:24 +00:00
|
|
|
return None
|
2023-03-19 08:08:44 +00:00
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def can_see_chudrama(self):
|
|
|
|
if self.can_see_restricted_holes != None:
|
|
|
|
return self.can_see_restricted_holes
|
|
|
|
|
2023-10-05 13:44:31 +00:00
|
|
|
if self.truescore >= TRUESCORE_MINIMUM: return True
|
2023-06-23 11:07:47 +00:00
|
|
|
if self.chud: return True
|
2022-09-19 17:10:37 +00:00
|
|
|
if self.patron: return True
|
2023-08-10 12:25:40 +00:00
|
|
|
if SITE == 'rdrama.net' and self.id == 5237: return True
|
|
|
|
|
2022-09-19 17:10:37 +00:00
|
|
|
return False
|
2022-12-04 18:39:06 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def can_see_countryclub(self):
|
2023-03-19 08:08:44 +00:00
|
|
|
if self.can_see_restricted_holes != None:
|
|
|
|
return self.can_see_restricted_holes
|
|
|
|
|
2023-10-05 13:44:31 +00:00
|
|
|
if self.truescore >= TRUESCORE_MINIMUM: return True
|
2023-07-20 13:47:36 +00:00
|
|
|
|
2023-08-10 12:25:40 +00:00
|
|
|
if SITE == 'rdrama.net' and self.id == 5237: return True
|
|
|
|
|
2022-12-04 18:39:06 +00:00
|
|
|
return False
|
|
|
|
|
2023-08-01 06:46:00 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def can_see_highrollerclub(self):
|
|
|
|
if self.can_see_restricted_holes != None:
|
|
|
|
return self.can_see_restricted_holes
|
|
|
|
|
|
|
|
if self.patron: return True
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
2022-11-14 17:17:29 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def can_post_in_ghost_threads(self):
|
2022-12-08 05:14:50 +00:00
|
|
|
if SITE_NAME == 'WPD': return False
|
2023-10-05 13:44:31 +00:00
|
|
|
if not TRUESCORE_MINIMUM: return True
|
2022-11-14 17:17:29 +00:00
|
|
|
if self.admin_level >= PERMS['POST_IN_GHOST_THREADS']: return True
|
2023-10-05 13:44:31 +00:00
|
|
|
if self.truescore >= TRUESCORE_MINIMUM: return True
|
2022-11-14 17:17:29 +00:00
|
|
|
if self.patron: return True
|
|
|
|
return False
|
2022-09-19 17:10:37 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def winnings(self):
|
2023-06-07 20:05:57 +00:00
|
|
|
return g.db.query(func.sum(CasinoGame.winnings)).filter(CasinoGame.user_id == self.id).one()[0] or 0
|
2022-09-19 17:51:40 +00:00
|
|
|
|
2022-10-06 23:31:09 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def user_name(self):
|
|
|
|
if self.earlylife:
|
|
|
|
expiry = int(self.earlylife - time.time())
|
|
|
|
if expiry > 86400:
|
|
|
|
name = self.username
|
|
|
|
for i in range(int(expiry / 86400 + 1)):
|
|
|
|
name = f'((({name})))'
|
|
|
|
return name
|
|
|
|
return f'((({self.username})))'
|
|
|
|
return self.username
|
2022-10-12 06:24:30 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def can_see_shadowbanned(self):
|
2023-10-05 09:49:07 +00:00
|
|
|
return (self.admin_level >= PERMS['USER_SHADOWBAN'])
|
2022-10-14 16:59:49 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def unmutable(self):
|
|
|
|
return self.has_badge(67)
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def mute(self):
|
|
|
|
return self.has_badge(68)
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def eye(self):
|
|
|
|
return self.has_badge(83)
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def alt(self):
|
|
|
|
return self.has_badge(84)
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def unblockable(self):
|
|
|
|
return self.has_badge(87)
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def offsitementions(self):
|
|
|
|
return self.has_badge(140)
|
2022-12-13 18:50:38 +00:00
|
|
|
|
2023-10-05 19:40:44 +00:00
|
|
|
@lazy
|
|
|
|
def pride_username(self, v):
|
|
|
|
return not (v and v.poor) and self.has_badge(303)
|
|
|
|
|
2022-12-13 18:50:38 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def shadowbanner(self):
|
2023-03-16 06:27:58 +00:00
|
|
|
return g.db.query(User.username).filter_by(id=self.shadowbanned).one()[0]
|
2022-12-20 01:13:34 +00:00
|
|
|
|
2023-07-02 17:40:39 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def banned_by(self):
|
|
|
|
username = g.db.query(User.username).filter_by(id=self.is_banned).one()[0]
|
|
|
|
return f'<a href="/@{username}">@{username}</a>'
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def chudder(self):
|
|
|
|
if not self.chudded_by: return 'award'
|
|
|
|
username = g.db.query(User.username).filter_by(id=self.chudded_by).one()[0]
|
|
|
|
return f'<a href="/@{username}">@{username}</a>'
|
|
|
|
|
2023-01-22 08:20:38 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def alts(self):
|
|
|
|
|
2023-03-16 06:27:58 +00:00
|
|
|
subq = g.db.query(Alt).filter(
|
2023-01-22 08:20:38 +00:00
|
|
|
or_(
|
|
|
|
Alt.user1 == self.id,
|
|
|
|
Alt.user2 == self.id
|
|
|
|
)
|
|
|
|
).subquery()
|
|
|
|
|
2023-03-16 06:27:58 +00:00
|
|
|
data = g.db.query(
|
2023-01-22 08:20:38 +00:00
|
|
|
User,
|
|
|
|
aliased(Alt, alias=subq)
|
|
|
|
).join(
|
|
|
|
subq,
|
|
|
|
or_(
|
|
|
|
subq.c.user1 == User.id,
|
|
|
|
subq.c.user2 == User.id
|
|
|
|
)
|
|
|
|
).filter(
|
|
|
|
User.id != self.id
|
|
|
|
).order_by(User.username).all()
|
|
|
|
|
|
|
|
output = []
|
|
|
|
for x in data:
|
|
|
|
user = x[0]
|
|
|
|
user._is_manual = x[1].is_manual
|
|
|
|
output.append(user)
|
|
|
|
|
|
|
|
return output
|
|
|
|
|
2023-10-05 09:55:35 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def can_see_my_shit(self):
|
|
|
|
v = g.v
|
|
|
|
return not self.shadowbanned or (v and (v.id == self.id or v.can_see_shadowbanned))
|
|
|
|
|
2023-05-12 21:04:26 +00:00
|
|
|
@property
|
|
|
|
@lazy
|
|
|
|
def ordered_badges(self):
|
2023-08-30 10:43:47 +00:00
|
|
|
return sorted(self.badges, key=badge_ordering_func)
|
2023-05-12 21:04:26 +00:00
|
|
|
|
2023-07-22 17:30:55 +00:00
|
|
|
@lazy
|
|
|
|
def rendered_sig(self, v):
|
|
|
|
if not self.sig_html or not self.patron:
|
|
|
|
return ''
|
|
|
|
|
2023-10-05 10:33:01 +00:00
|
|
|
if v and (not v.show_sigs or v.poor):
|
2023-07-22 17:30:55 +00:00
|
|
|
return ''
|
|
|
|
|
2023-07-22 19:34:07 +00:00
|
|
|
return f'<div id="signature-{self.id}" class="user-signature"><hr>{self.sig_html}</div>'
|
2023-07-22 17:30:55 +00:00
|
|
|
|
|
|
|
|
2023-05-12 22:12:08 +00:00
|
|
|
badge_ordering_tuple = (
|
2023-09-28 23:58:09 +00:00
|
|
|
22, 23, 24, 25, 26, 27, 28, #paypig
|
|
|
|
257, 258, 259, 260, 261, #lifetime donation
|
|
|
|
134, 237, #1 year and 2 year
|
|
|
|
10, 11, 12, #referred users
|
|
|
|
69, 70, 71, 72, 73, #coins spent
|
|
|
|
76, 77, 78, #lootboxes bought
|
|
|
|
17, 16, 143, #marsey making
|
|
|
|
110, 111, #zwolf making
|
|
|
|
112, 113, #platy making
|
|
|
|
114, 115, #capy making
|
|
|
|
287, 288, #carp making
|
|
|
|
152, 153, 154, #hats bought
|
|
|
|
160, 161, 162, #casino win
|
|
|
|
157, 158, 159, #casino loss
|
|
|
|
163, 164, 165, 166, #hat making
|
|
|
|
243, 244, 245, 247, #kong
|
|
|
|
118, 119, 120, 121, 122, 123, #denazifying r/stupidpol
|
|
|
|
190, 192, #word filter
|
|
|
|
251, 250, 249, #marsey madness
|
|
|
|
)
|
2023-05-12 22:12:08 +00:00
|
|
|
|
2023-05-12 21:04:26 +00:00
|
|
|
def badge_ordering_func(b):
|
|
|
|
if b.badge_id in badge_ordering_tuple:
|
|
|
|
return badge_ordering_tuple.index(b.badge_id)
|
|
|
|
return b.created_utc or len(badge_ordering_tuple)+1
|