remove country club system and replace it with a 3 tier thing: (#41)

- /h/masterbaiters: 1 TS - for gayops

- /h/countryclub: 1000 TS - for anything requiring secrecy and doesnt need critical mass - have to make it a rule that u cant post gayops in /h/countryclub

- /h/chudrama: 5000 TS - for chad+stud posts

EDIT: i removed the /h/masterbaiters gate, but u can bring it back if u want
Co-authored-by: Aevann1 <randomname42029@gmail.com>
Co-authored-by: Snakes <duolsm@outlook.com>
Reviewed-on: #41
Co-authored-by: Aevann <aevann@noreply.fsdfsd.net>
Co-committed-by: Aevann <aevann@noreply.fsdfsd.net>
pull/44/head
Aevann 2022-12-04 18:39:06 +00:00 committed by Snakes
parent 29070c78a9
commit e105035272
45 changed files with 550 additions and 268 deletions

1
env
View File

@ -26,7 +26,6 @@ export GUMROAD_LINK="blahblahblah"
export GUMROAD_ID="blahblahblah"
export CARD_VIEW="0"
export DISABLE_DOWNVOTES="0"
export DUES="0"
export DEFAULT_THEME="midnight"
export DEFAULT_COLOR="805ad5"
export EMAIL="blahblahblah@gmail.com"

View File

@ -5953,7 +5953,6 @@ g {
.fa-gift:before{content:"\f06b"}
.fa-gingerbread-man:before{content:"\f79d"}
.fa-globe:before{content:"\f0ac"}
.fa-golf-club:before{content:"\f451"}
.fa-home-alt:before{content:"\f015"}
.fa-id-badge:before{content:"\f2c1"}
.fa-id-card:before{content:"\f2c2"}
@ -6065,7 +6064,6 @@ g {
.fa-trees:before{content:"\f724"}
.fa-flashlight:before{content:"\f8b8"}
.fa-candy-corn:before{content:"\f6bd"}
.fa-club:before{content:"\f327"}
.fa-shirt:before{content:"\f553"}
.fa-bone:before{content:"\f5d7"}
.fa-jack-o-lantern:before{content:"\f30e"}

View File

@ -6,7 +6,6 @@ document.getElementById('post-notify').checked = localStorage.getItem("post-noti
document.getElementById('post-new').checked = localStorage.getItem("post-new") == 'true'
document.getElementById('post-nsfw').checked = localStorage.getItem("post-nsfw") == 'true'
document.getElementById('post-private').checked = localStorage.getItem("post-private") == 'true'
document.getElementById('post-club').checked = localStorage.getItem("post-club") == 'true'
document.getElementById('post-ghost').checked = localStorage.getItem("post-ghost") == 'true'
markdown(document.getElementById("post-text"));
@ -121,7 +120,6 @@ function savetext() {
localStorage.setItem("post-new", document.getElementById('post-new').checked)
localStorage.setItem("post-nsfw", document.getElementById('post-nsfw').checked)
localStorage.setItem("post-private", document.getElementById('post-private').checked)
localStorage.setItem("post-club", document.getElementById('post-club').checked)
localStorage.setItem("post-ghost", document.getElementById('post-ghost').checked)
}

View File

@ -243,8 +243,6 @@ class Comment(Base):
@lazy
def realbody(self, v):
if self.post and self.post.club and not (v and (v.paid_dues or v.id in {self.author_id, self.post.author_id} or (self.parent_comment and v.id == self.parent_comment.author_id))):
return f"<p>{CC} ONLY</p>"
if self.deleted_utc != 0 and not (v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or v.id == self.author.id)): return "[Deleted by user]"
if self.is_banned and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']) and not (v and v.id == self.author.id): return ""
@ -301,8 +299,6 @@ class Comment(Base):
@lazy
def plainbody(self, v):
if self.post and self.post.club and not (v and (v.paid_dues or v.id in {self.author_id, self.post.author_id} or (self.parent_comment and v.id == self.parent_comment.author_id))):
return f"{CC} ONLY"
if self.deleted_utc != 0 and not (v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or v.id == self.author.id)): return "[Deleted by user]"
if self.is_banned and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']) and not (v and v.id == self.author.id): return ""

View File

@ -50,7 +50,7 @@ class ModAction(Base):
@property
@lazy
def string(self):
output = ACTIONTYPES[self.kind]["str"].format(self=self, cc=CC_TITLE)
output = ACTIONTYPES[self.kind]["str"].format(self=self)
if self.note: output += f" <i>({self.note})</i>"
return output
@ -59,7 +59,6 @@ class ModAction(Base):
def target_link(self):
if self.target_user: return f'<a href="{self.target_user.url}">{self.target_user.username}</a>'
elif self.target_post:
if self.target_post.club: return f'<a href="{self.target_post.permalink}">{CC} ONLY</a>'
return censor_slurs(f'<a href="{self.target_post.permalink}">{self.target_post.title_html}</a>', None)
elif self.target_comment_id: return f'<a href="/comment/{self.target_comment_id}?context=8#context">comment</a>'
@ -119,16 +118,6 @@ ACTIONTYPES = {
"icon": 'fa-user-slash',
"color": 'bg-danger'
},
'club_allow': {
"str": 'allowed user {self.target_link} into the {cc}',
"icon": 'fa-golf-club',
"color": 'bg-success'
},
'club_ban': {
"str": 'disallowed user {self.target_link} from the {cc}',
"icon": 'fa-golf-club',
"color": 'bg-danger'
},
'delete_report': {
"str": 'deleted report on {self.target_link}',
"icon": 'fa-flag',
@ -409,16 +398,6 @@ ACTIONTYPES = {
"icon": 'fa-cat',
"color": 'bg-success'
},
'club_post': {
"str": 'moved post {self.target_link} to the {cc}',
"icon": 'fa-club',
"color": 'bg-success'
},
'unclub_post': {
"str": 'removed post {self.target_link} from the {cc}',
"icon": 'fa-club',
"color": 'bg-muted'
},
}
ACTIONTYPES2 = deepcopy(ACTIONTYPES)

View File

@ -41,7 +41,7 @@ class SubAction(Base):
@property
@lazy
def string(self):
output = ACTIONTYPES[self.kind]["str"].format(self=self, cc=CC_TITLE)
output = ACTIONTYPES[self.kind]["str"].format(self=self)
if self._note: output += f" <i>({self._note})</i>"
return output
@ -50,7 +50,6 @@ class SubAction(Base):
def target_link(self):
if self.target_user: return f'<a href="{self.target_user.url}">{self.target_user.username}</a>'
elif self.target_post:
if self.target_post.club: return f'<a href="{self.target_post.permalink}">{CC} ONLY</a>'
return censor_slurs(f'<a href="{self.target_post.permalink}">{self.target_post.title_html}</a>', None)
elif self.target_comment_id: return f'<a href="/comment/{self.target_comment_id}?context=8#context">comment</a>'

View File

@ -38,7 +38,6 @@ class Submission(Base):
sub = Column(String, ForeignKey("subs.name"))
is_pinned = Column(Boolean, default=False)
private = Column(Boolean, default=False)
club = Column(Boolean, default=False)
comment_count = Column(Integer, default=0)
is_approved = Column(Integer, ForeignKey("users.id"))
over_18 = Column(Boolean, default=False)
@ -113,8 +112,6 @@ class Submission(Base):
link = f"/post/{self.id}"
if self.sub: link = f"/h/{self.sub}{link}"
if self.club: return link + '/-'
output = title_regex.sub('', self.title.lower())
output = output.split()[:6]
output = '-'.join(output)
@ -210,7 +207,6 @@ class Submission(Base):
'distinguish_level': self.distinguish_level,
'voted': self.voted if hasattr(self, 'voted') else 0,
'flags': flags,
'club': self.club,
'author': '👻' if self.ghost else self.author.json,
'comment_count': self.comment_count
}
@ -270,7 +266,6 @@ class Submission(Base):
@lazy
def realbody(self, v, listing=False):
if self.club and not (v and (v.paid_dues or v.id == self.author_id)): return f"<p>{CC} ONLY</p>"
if self.deleted_utc != 0 and not (v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or v.id == self.author.id)): return "[Deleted by user]"
if self.is_banned and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']) and not (v and v.id == self.author.id): return ""
@ -333,7 +328,6 @@ class Submission(Base):
def plainbody(self, v):
if self.deleted_utc != 0 and not (v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or v.id == self.author.id)): return "[Deleted by user]"
if self.is_banned and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']) and not (v and v.id == self.author.id): return ""
if self.club and not (v and (v.paid_dues or v.id == self.author_id)): return f"<p>{CC} ONLY</p>"
body = self.body
if not body: return ""
@ -348,12 +342,7 @@ class Submission(Base):
@lazy
def realtitle(self, v):
if self.club and not (v and (v.paid_dues or v.id == self.author_id)):
if v: return random.choice(TROLLTITLES).format(username=v.username)
elif DUES == -2: return f'Please make an account to see this post'
else: return f'{CC} MEMBERS ONLY'
elif self.title_html: title = self.title_html
else: title = self.title
title = self.title_html
title = censor_slurs(title, v)
@ -364,10 +353,7 @@ class Submission(Base):
@lazy
def plaintitle(self, v):
if self.club and not (v and (v.paid_dues or v.id == self.author_id)):
if v: return random.choice(TROLLTITLES).format(username=v.username)
else: return f'{CC} MEMBERS ONLY'
else: title = self.title
title = self.title
title = censor_slurs(title, v).replace('<img loading="lazy" data-bs-toggle="tooltip" alt=":marseytrain:" title=":marseytrain:" src="/e/marseytrain.webp">', ':marseytrain:')

View File

@ -109,7 +109,6 @@ class User(Base):
unban_utc = Column(Integer, default=0)
ban_reason = deferred(Column(String))
is_muted = Column(Boolean, default=False, nullable=False)
club_allowed = Column(Boolean)
login_nonce = Column(Integer, default=0)
coins = Column(Integer, default=0)
truescore = Column(Integer, default=0)
@ -451,14 +450,6 @@ class User(Base):
def has_blocked(self, target):
return g.db.query(UserBlock).filter_by(user_id=self.id, target_id=target.id).one_or_none()
@property
@lazy
def paid_dues(self):
if not FEATURES['COUNTRY_CLUB']: return True
if self.shadowbanned: return False
if self.is_suspended_permanently: return False
return self.admin_level >= PERMS['VIEW_CLUB'] or self.club_allowed or (self.club_allowed != False and self.truescore >= DUES)
@lazy
def any_block_exists(self, other):
@ -1015,11 +1006,8 @@ class User(Base):
if other.is_banned: return False
if other.deleted_utc: return False
if other.author.shadowbanned and not (user and user.can_see_shadowbanned): return False
if isinstance(other, Submission):
if other.club and not (user and user.paid_dues): return False
if other.sub == 'chudrama' and not (user and user.can_see_chudrama): return False
else:
if other.parent_submission and not cls.can_see_content(user, other.post): return False
if isinstance(other, Comment):
if other.parent_submission and not cls.can_see(user, other.post): return False
return True
@classmethod
@ -1045,7 +1033,9 @@ class User(Base):
if other.parent_submission and other.post.sub and not cls.can_see(user, other.post.subr): return False
# if other.parent_submission and not cls.can_see(user, other.post): return False
elif isinstance(other, Sub):
return other.name != 'chudrama' or (user and user.can_see_chudrama)
if other.name == 'chudrama': return bool(user) and user.can_see_chudrama
if other.name == 'countryclub': return bool(user) and user.can_see_countryclub
if other.name == 'masterbaiters': return bool(user) and user.can_see_masterbaiters
elif isinstance(other, User):
return (user and user.id == other.id) or (user and user.can_see_shadowbanned) or not other.shadowbanned
return True
@ -1055,17 +1045,33 @@ class User(Base):
def can_see_chudrama(self):
if self.admin_level >= PERMS['VIEW_CHUDRAMA']: return True
if self.client: return True
if self.truescore >= 5000: return True
if self.truescore >= TRUESCORE_CHUDRAMA_MINIMUM: return True
if self.agendaposter: return True
if self.patron: return True
return False
@property
@lazy
def can_see_countryclub(self):
if self.shadowbanned: return False
if self.is_suspended_permanently: return False
if self.agendaposter == 1: return False
if self.admin_level >= PERMS['VIEW_CLUB']: return True
if self.truescore >= TRUESCORE_CLUB_MINIMUM: return True
return False
@property
@lazy
def can_see_masterbaiters(self):
if self.shadowbanned: return False
if self.is_suspended_permanently: return False
return True
@property
@lazy
def can_post_in_ghost_threads(self):
if not TRUESCORE_GHOST_MINIMUM: return True
if self.admin_level >= PERMS['POST_IN_GHOST_THREADS']: return True
if self.club_allowed: return True
if self.truescore >= TRUESCORE_GHOST_MINIMUM: return True
if self.patron: return True
return False

View File

@ -29,7 +29,6 @@ GUMROAD_TOKEN = environ.get("GUMROAD_TOKEN", DEFAULT_CONFIG_VALUE).strip()
GUMROAD_LINK = environ.get("GUMROAD_LINK", DEFAULT_CONFIG_VALUE).strip()
GUMROAD_ID = environ.get("GUMROAD_ID", DEFAULT_CONFIG_VALUE).strip()
DISABLE_DOWNVOTES = bool(int(environ.get("DISABLE_DOWNVOTES", "0").strip()))
DUES = int(environ.get("DUES", "0").strip())
DEFAULT_THEME = environ.get("DEFAULT_THEME", "midnight").strip()
DEFAULT_COLOR = environ.get("DEFAULT_COLOR", "805ad5").strip()
CARD_VIEW = bool(int(environ.get("CARD_VIEW", "0").strip()))
@ -69,10 +68,6 @@ REDDIT_NOTIFS_CACHE_KEY = "reddit_notifications"
MARSEYS_CACHE_KEY = "marseys"
EMOJIS_CACHE_KEY = "emojis"
if SITE_NAME == 'PCM': CC = "SPLASH MOUNTAIN"
else: CC = "COUNTRY CLUB"
CC_TITLE = CC.title()
CASINO_RELEASE_DAY = 1662825600
if SITE_NAME == 'rDrama': patron = 'Paypig'
@ -241,7 +236,6 @@ PERMS = { # Minimum admin_level to perform action.
'USER_BAN': 2,
'USER_SHADOWBAN': 2,
'USER_AGENDAPOSTER': 2,
'USER_CLUB_ALLOW_BAN': 2,
'USER_LINK': 2,
'USER_MERGE': 3, # note: extra check for Aevann
'USER_TITLE_CHANGE': 2,
@ -300,7 +294,6 @@ FEATURES = {
'AWARDS': True,
'CHAT': True,
'PINS': True,
'COUNTRY_CLUB': True,
'PRONOUNS': False,
'BADGES': True,
'HATS': True,
@ -403,6 +396,8 @@ COSMETIC_AWARD_COIN_AWARD_PCT = 0.10
TRUESCORE_CHAT_MINIMUM = 0
TRUESCORE_DONATE_MINIMUM = 100
TRUESCORE_GHOST_MINIMUM = 0
TRUESCORE_CHUDRAMA_MINIMUM = 5000
TRUESCORE_CLUB_MINIMUM = 1000
CHAT_DISPLAY_USER_COUNT_MINIMUM = 0
LOGGEDIN_ACTIVE_TIME = 15 * 60

View File

@ -295,58 +295,6 @@ def revert_actions(v, username):
return {"message": f"@{user.username}'s admin actions have been reverted!"}
@app.post("/@<username>/club_allow")
@limiter.limit(DEFAULT_RATELIMIT_SLOWER)
@admin_level_required(PERMS['USER_CLUB_ALLOW_BAN'])
def club_allow(v, username):
u = get_user(username, v=v)
if u.admin_level >= v.admin_level: abort(403, 'noob')
u.club_allowed = True
g.db.add(u)
for x in u.alts_unique:
x.club_allowed = True
g.db.add(x)
ma = ModAction(
kind="club_allow",
user_id=v.id,
target_user_id=u.id
)
g.db.add(ma)
send_repeatable_notification(u.id, f"@{v.username} (Admin) has inducted you into the {CC_TITLE}!")
return {"message": f"@{u.username} has been allowed into the {CC_TITLE}!"}
@app.post("/@<username>/club_ban")
@limiter.limit(DEFAULT_RATELIMIT_SLOWER)
@admin_level_required(PERMS['USER_CLUB_ALLOW_BAN'])
def club_ban(v, username):
u = get_user(username, v=v)
if u.admin_level >= v.admin_level: abort(403, 'noob')
u.club_allowed = False
for x in u.alts_unique:
u.club_allowed = False
g.db.add(x)
ma = ModAction(
kind="club_ban",
user_id=v.id,
target_user_id=u.id
)
g.db.add(ma)
send_repeatable_notification(u.id, f"@{v.username} (Admin) has disallowed you from the {CC_TITLE}!")
return {"message": f"@{u.username} has been disallowed from the {CC_TITLE}. Deserved."}
@app.get("/admin/shadowbanned")
@admin_level_required(PERMS['USER_SHADOWBAN'])
def shadowbanned(v):

View File

@ -39,7 +39,7 @@ user_ids_to_socket_ids = {}
@app.get("/chat")
@is_not_permabanned
def chat(v):
if TRUESCORE_CHAT_MINIMUM and v.truescore < TRUESCORE_CHAT_MINIMUM and not v.club_allowed:
if TRUESCORE_CHAT_MINIMUM and v.truescore < TRUESCORE_CHAT_MINIMUM:
abort(403, f"Need at least {TRUESCORE_CHAT_MINIMUM} truescore for access to chat.")
return render_template("chat.html", v=v, messages=messages)
@ -51,7 +51,8 @@ def chat(v):
def speak(data, v):
limiter.check()
if v.is_banned: return '', 403
if TRUESCORE_CHAT_MINIMUM and v.truescore < TRUESCORE_CHAT_MINIMUM and not v.club_allowed: return '', 403
if TRUESCORE_CHAT_MINIMUM and v.truescore < TRUESCORE_CHAT_MINIMUM:
return '', 403
vname = v.username.lower()
if vname in muted and not v.admin_level >= PERMS['CHAT_BYPASS_MUTE']:

View File

@ -33,7 +33,6 @@ WORDLE_COLOR_MAPPINGS = {-1: "🟥", 0: "🟨", 1: "🟩"}
def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None):
comment = get_comment(cid, v=v)
if not User.can_see(v, comment): abort(404)
if comment.post and comment.post.club and not User.can_see_content(v, comment): abort(403)
if v and request.values.get("read"):
notif = g.db.query(Notification).filter_by(comment_id=cid, user_id=v.id, read=False).one_or_none()
@ -112,8 +111,6 @@ def comment(v):
if sub in ('furry','vampire','racist','femboy') and not v.client and not v.house.lower().startswith(sub):
abort(403, f"You need to be a member of House {sub.capitalize()} to comment in /h/{sub}")
if parent_post.club and not (v and (v.paid_dues or v.id == parent_post.author_id)): abort(403)
if not User.can_see(v, parent): abort(404)
if parent.deleted_utc != 0: abort(404)

View File

@ -18,7 +18,8 @@ from files.__main__ import app, cache, limiter
def front_all(v, sub=None, subdomain=None):
if sub:
sub = get_sub_by_name(sub, graceful=True)
if sub and not User.can_see(v, sub): abort(403, "You need 5000 truescore to be able to see /h/chudrama")
if sub and not User.can_see(v, sub):
abort(403)
if (request.path.startswith('/h/') or request.path.startswith('/s/')) and not sub: abort(404)
@ -220,9 +221,6 @@ def comment_idlist(v=None, page=1, sort="new", t="all", gt=0, lt=0, site=None):
Comment.author_id.notin_(v.userblocks),
)
if not v.paid_dues:
comments = comments.filter(Submission.club == False)
if gt: comments = comments.filter(Comment.created_utc > gt)
if lt: comments = comments.filter(Comment.created_utc < lt)

View File

@ -77,13 +77,13 @@ def calc_users():
def inject_constants():
return {"environ":environ, "SITE":SITE, "SITE_NAME":SITE_NAME, "SITE_FULL":SITE_FULL,
"AUTOJANNY_ID":AUTOJANNY_ID, "MODMAIL_ID":MODMAIL_ID, "VAPID_PUBLIC_KEY":VAPID_PUBLIC_KEY,
"CC":CC, "CC_TITLE":CC_TITLE, "listdir":listdir, "os_path":path, "AEVANN_ID":AEVANN_ID,
"listdir":listdir, "os_path":path, "AEVANN_ID":AEVANN_ID,
"PIZZASHILL_ID":PIZZASHILL_ID, "DEFAULT_COLOR":DEFAULT_COLOR,
"COLORS":COLORS, "time":time, "PERMS":PERMS, "FEATURES":FEATURES,
"HOLE_NAME":HOLE_NAME, "HOLE_STYLE_FLAIR":HOLE_STYLE_FLAIR, "HOLE_REQUIRED":HOLE_REQUIRED,
"GUMROAD_LINK":GUMROAD_LINK, "DEFAULT_THEME":DEFAULT_THEME, "DESCRIPTION":DESCRIPTION,
"has_sidebar":has_sidebar, "has_logo":has_logo,
"FP":FP, "CHAT_DISPLAY_USER_COUNT_MINIMUM":CHAT_DISPLAY_USER_COUNT_MINIMUM, "patron":patron, "DUES":DUES,
"FP":FP, "CHAT_DISPLAY_USER_COUNT_MINIMUM":CHAT_DISPLAY_USER_COUNT_MINIMUM, "patron":patron,
"SIDEBAR_THREAD":SIDEBAR_THREAD, "BANNER_THREAD":BANNER_THREAD,
"BADGE_THREAD":BADGE_THREAD, "SNAPPY_THREAD":SNAPPY_THREAD,
"KOFI_TOKEN":KOFI_TOKEN, "KOFI_LINK":KOFI_LINK,

View File

@ -33,55 +33,6 @@ from files.__main__ import app, limiter
titleheaders = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36"}
@app.post("/club_post/<pid>")
@feature_required('COUNTRY_CLUB')
@auth_required
def club_post(pid, v):
post = get_post(pid)
if post.author_id != v.id and v.admin_level < PERMS['POST_COMMENT_MODERATION']: abort(403)
if not post.club:
post.club = True
g.db.add(post)
if post.author_id != v.id:
ma = ModAction(
kind = "club_post",
user_id = v.id,
target_submission_id = post.id,
)
g.db.add(ma)
message = f"@{v.username} (Admin) has marked [{post.title}]({post.shortlink}) as {CC_TITLE}!"
send_repeatable_notification(post.author_id, message)
return {"message": f"Post has been marked as {CC_TITLE}!"}
@app.post("/unclub_post/<pid>")
@feature_required('COUNTRY_CLUB')
@auth_required
def unclub_post(pid, v):
post = get_post(pid)
if post.author_id != v.id and v.admin_level < PERMS['POST_COMMENT_MODERATION']: abort(403)
if post.club:
post.club = False
g.db.add(post)
if post.author_id != v.id:
ma = ModAction(
kind = "unclub_post",
user_id = v.id,
target_submission_id = post.id,
)
g.db.add(ma)
message = f"@{v.username} (Admin) has unmarked [{post.title}]({post.shortlink}) as {CC_TITLE}!"
send_repeatable_notification(post.author_id, message)
return {"message": f"Post has been unmarked as {CC_TITLE}!"}
@app.post("/publish/<pid>")
@limiter.limit(DEFAULT_RATELIMIT_SLOWER)
@auth_required
@ -139,7 +90,6 @@ def submit_get(v:User, sub=None):
def post_id(pid, anything=None, v=None, sub=None):
post = get_post(pid, v=v)
if not User.can_see(v, post): abort(403)
if not User.can_see_content(v, post) and post.club: abort(403)
if post.over_18 and not (v and v.over_18) and session.get('over_18', 0) < int(time.time()):
if g.is_api_or_xhr: return {"error":"Must be 18+ to view"}, 451
@ -234,7 +184,6 @@ def post_id(pid, anything=None, v=None, sub=None):
@auth_desired_with_logingate
def viewmore(v, pid, sort, offset):
post = get_post(pid, v=v)
if post.club and not (v and (v.paid_dues or v.id == post.author_id)): abort(403)
try:
offset = int(offset)
except: abort(400)
@ -783,7 +732,6 @@ def submit_post(v:User, sub=None):
flag_new = request.values.get("new", False, bool) or 'megathread' in title.lower()
flag_over_18 = request.values.get("over_18", False, bool)
flag_private = request.values.get("private", False, bool)
flag_club = (request.values.get("club", False, bool) and FEATURES['COUNTRY_CLUB'])
flag_ghost = request.values.get("ghost", False, bool) and v.can_post_in_ghost_threads
if embed and len(embed) > 1500: embed = None
@ -795,7 +743,6 @@ def submit_post(v:User, sub=None):
post = Submission(
private=flag_private,
notify=flag_notify,
club=flag_club,
author_id=v.id,
over_18=flag_over_18,
new=flag_new,

View File

@ -19,7 +19,6 @@ valid_params = [
'before',
'after',
'title',
'cc',
search_operator_hole,
]
@ -61,9 +60,6 @@ def searchposts(v:User):
.join(Submission.author) \
.filter(Submission.author_id.notin_(v.userblocks))
if not v.paid_dues:
posts = posts.filter(Submission.club == False)
if v.admin_level < PERMS['POST_COMMENT_MODERATION']:
posts = posts.filter(
Submission.deleted_utc == 0,
@ -143,13 +139,6 @@ def searchposts(v:User):
except: abort(400)
posts = posts.filter(Submission.created_utc < before)
if 'cc' in criteria:
cc = criteria['cc'].lower().strip()
if cc == 'true': cc = True
elif cc == 'false': cc = False
else: abort(400)
posts = posts.filter(Submission.club == cc)
posts = apply_time_filter(t, posts, Submission)
posts = sort_objects(sort, posts, Submission,
@ -236,10 +225,6 @@ def searchcomments(v:User):
comments = comments.filter(Comment.is_banned==False, Comment.deleted_utc == 0, Comment.parent_submission.notin_(private))
if not v.paid_dues:
club = [x[0] for x in g.db.query(Submission.id).filter(Submission.club == True).all()]
comments = comments.filter(Comment.parent_submission.notin_(club))
if 'after' in criteria:
after = criteria['after']
try: after = int(after)

View File

@ -122,15 +122,17 @@ def block_sub(v:User, sub):
@app.post("/h/<sub>/unblock")
@auth_required
def unblock_sub(v:User, sub):
sub = get_sub_by_name(sub).name
if sub == "chudrama" and not v.can_see_chudrama: abort(403)
block = g.db.query(SubBlock).filter_by(user_id=v.id, sub=sub).one_or_none()
sub = get_sub_by_name(sub)
if not User.can_see(v, sub):
abort(403)
block = g.db.query(SubBlock).filter_by(user_id=v.id, sub=sub.name).one_or_none()
if block:
g.db.delete(block)
cache.delete_memoized(frontlist)
return {"message": f"/h/{sub} unblocked successfully!"}
return {"message": f"/h/{sub.name} unblocked successfully!"}
@app.post("/h/<sub>/subscribe")
@ -162,7 +164,8 @@ def unsubscribe_sub(v:User, sub):
@auth_required
def follow_sub(v:User, sub):
sub = get_sub_by_name(sub)
if sub.name == "chudrama" and not v.can_see_chudrama: abort(403)
if not User.can_see(v, sub):
abort(403)
existing = g.db.query(SubSubscription).filter_by(user_id=v.id, sub=sub.name).one_or_none()
if not existing:
subscription = SubSubscription(user_id=v.id, sub=sub.name)
@ -186,7 +189,8 @@ def unfollow_sub(v:User, sub):
@auth_required
def mods(v:User, sub):
sub = get_sub_by_name(sub)
if sub.name == "chudrama" and not v.can_see_chudrama: abort(403)
if not User.can_see(v, sub):
abort(403)
users = g.db.query(User, Mod).join(Mod).filter_by(sub=sub.name).order_by(Mod.created_utc).all()
return render_template("sub/mods.html", v=v, sub=sub, users=users)
@ -196,7 +200,8 @@ def mods(v:User, sub):
@auth_required
def sub_exilees(v:User, sub):
sub = get_sub_by_name(sub)
if sub.name == "chudrama" and not v.can_see_chudrama: abort(403)
if not User.can_see(v, sub):
abort(403)
users = g.db.query(User, Exile).join(Exile, Exile.user_id==User.id) \
.filter_by(sub=sub.name) \
.order_by(nullslast(Exile.created_utc.desc()), User.username).all()
@ -208,7 +213,8 @@ def sub_exilees(v:User, sub):
@auth_required
def sub_blockers(v:User, sub):
sub = get_sub_by_name(sub)
if sub.name == "chudrama" and not v.can_see_chudrama: abort(403)
if not User.can_see(v, sub):
abort(403)
users = g.db.query(User, SubBlock).join(SubBlock) \
.filter_by(sub=sub.name) \
.order_by(nullslast(SubBlock.created_utc.desc()), User.username).all()
@ -221,7 +227,8 @@ def sub_blockers(v:User, sub):
@auth_required
def sub_followers(v:User, sub):
sub = get_sub_by_name(sub)
if sub.name == "chudrama" and not v.can_see_chudrama: abort(403)
if not User.can_see(v, sub):
abort(403)
users = g.db.query(User, SubSubscription).join(SubSubscription) \
.filter_by(sub=sub.name) \
.order_by(nullslast(SubSubscription.created_utc.desc()), User.username).all()
@ -701,7 +708,8 @@ def mod_unpin(cid, v):
@auth_required
def hole_log(v:User, sub):
sub = get_sub_by_name(sub)
if sub.name == "chudrama" and not v.can_see_chudrama: abort(403)
if not User.can_see(v, sub):
abort(403)
try: page = max(int(request.values.get("page", 1)), 1)
except: page = 1
@ -741,7 +749,8 @@ def hole_log(v:User, sub):
@auth_required
def hole_log_item(id, v, sub):
sub = get_sub_by_name(sub)
if sub.name == "chudrama" and not v.can_see_chudrama: abort(403)
if not User.can_see(v, sub):
abort(403)
try: id = int(id)
except: abort(404)

View File

@ -508,7 +508,7 @@
{% endif %}
</div>
{% if v and v.id != c.author_id and c.body and not (c.post and c.post.club and not v.paid_dues) %}
{% if v and v.id != c.author_id and c.body %}
<div autocomplete="off" class="markdown d-none card border my-2 p-3 comment-box form-control rounded" id="markdown-{{c.id}}" readonly>{{c.body.strip()}}</div>
{% endif %}

View File

@ -57,10 +57,6 @@
<button type="button" id="hole-pin-{{p.id}}" class="dropdown-item {% if p.hole_pinned %}d-none{% endif %} list-inline-item text-info" onclick="postToastSwitch(this,'/hole_pin/{{p.id}}','hole-pin-{{p.id}}','hole-unpin-{{p.id}}','d-none')"><i class="fas fa-thumbtack fa-rotate--45"></i>Pin to /h/{{p.sub}}</button>
<button type="button" id="hole-unpin-{{p.id}}" class="dropdown-item {% if not p.hole_pinned %}d-none{% endif %} list-inline-item text-info" onclick="postToastSwitch(this,'/hole_unpin/{{p.id}}','hole-pin-{{p.id}}','hole-unpin-{{p.id}}','d-none')"><i class="fas fa-thumbtack fa-rotate--45"></i>Unpin from /h/{{p.sub}}</button>
{% endif %}
{% if FEATURES['COUNTRY_CLUB'] and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or v.id == p.author_id) %}
<button type="button" id="club-{{p.id}}" class="dropdown-item {% if p.club %}d-none{% endif %} list-inline-item text-info" onclick="postToastSwitch(this,'/club_post/{{p.id}}','club-{{p.id}}','unclub-{{p.id}}','d-none')"><i class="fas fa-eye-slash"></i>Mark club</button>
<button type="button" id="unclub-{{p.id}}" class="dropdown-item {% if not p.club %}d-none{% endif %} list-inline-item text-info" onclick="postToastSwitch(this,'/unclub_post/{{p.id}}','club-{{p.id}}','unclub-{{p.id}}','d-none')"><i class="fas fa-eye"></i>Unmark club</button>
{% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
<button type="button" id="remove-{{p.id}}" class="dropdown-item {% if p.is_banned %}d-none{% endif %} list-inline-item text-danger" onclick="removePost(this,'{{p.id}}','remove-{{p.id}}','approve-{{p.id}}','d-none')"><i class="fas fa-ban"></i>Remove</button>
<button type="button" id="approve-{{p.id}}" class="dropdown-item {% if not p.is_banned and request.path != '/admin/reported/posts' %}d-none{% endif %} list-inline-item text-success" onclick="approvePost(this,'{{p.id}}','remove-{{p.id}}','approve-{{p.id}}','d-none')"><i class="fas fa-check"></i>Approve</button>

View File

@ -42,12 +42,6 @@
<button type="button" id="undelete-{{p.id}}" class="{% if not p.deleted_utc %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-success" onclick="postToastSwitch(this,'/undelete_post/{{p.id}}', 'delete-{{p.id}}', 'undelete-{{p.id}}','d-none');document.getElementById('post-{{p.id}}').classList.remove('deleted')" data-bs-dismiss="modal"><i class="far fa-trash-alt text-center mr-2"></i>Undelete</button>
<button type="button" id="delete-{{p.id}}" class="{% if p.deleted_utc %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-danger" data-bs-toggle="modal" data-bs-dismiss="modal" data-bs-target="#deletePostModal" onclick="delete_postModal(this, '{{p.id}}')"><i class="far fa-trash-alt mr-2"></i>Delete</button>
{% if FEATURES['COUNTRY_CLUB'] -%}
<button type="button" id="club3-{{p.id}}" class="{% if p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-danger text-left" onclick="postToastSwitch(this,'/club_post/{{p.id}}','club3-{{p.id}}','unclub3-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-eye-slash mr-2"></i>Mark club</button>
<button type="button" id="unclub3-{{p.id}}" class="{% if not p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-success text-left" onclick="postToastSwitch(this,'/unclub_post/{{p.id}}','club3-{{p.id}}','unclub3-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-eye mr-2"></i>Unmark club</button>
{%- endif %}
{% else %}
{% if not p.ghost %}
<button type="button" id="unblock2-{{p.id}}" class="nobackground btn btn-link btn-block btn-lg text-success text-left{% if not p.is_blocking %} d-none{% endif %}" data-bs-dismiss="modal" onclick="postToastSwitch(this,'/settings/unblock?username={{p.author.username}}','block2-{{p.id}}','unblock2-{{p.id}}','d-none')"><i class="fas fa-eye mr-2 text-success"></i>Unblock user</button>

View File

@ -17,10 +17,6 @@
<button type="button" class="nobackground btn btn-link btn-block btn-lg text-left text-muted" data-bs-dismiss="modal" onclick="togglePostEdit('{{p.id}}')"><i class="far fa-edit text-center text-muted mr-2"></i>Edit</button>
{% endif %}
{% if FEATURES['COUNTRY_CLUB'] -%}
<button type="button" id="club2-{{p.id}}" class="{% if p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-info text-left" onclick="postToastSwitch(this,'/club_post/{{p.id}}','club2-{{p.id}}','unclub2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-eye-slash mr-2"></i>Mark club</button>
<button type="button" id="unclub2-{{p.id}}" class="{% if not p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-info text-left" onclick="postToastSwitch(this,'/unclub_post/{{p.id}}','club2-{{p.id}}','unclub2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-eye mr-2"></i>Unmark club</button>
{%- endif %}
{% if v.can_edit(p) %}
<button id="{{p.id}}-sort-new-mobile" type="button" class="{% if p.new %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" onclick="postToastSwitch(this, '/post/{{p.id}}/new', this.id, '{{p.id}}-unsort-new-mobile', 'd-none', null, 'PUT')" data-bs-dismiss="modal"><i class="fas fa-sparkles text-center text-primary mr-2"></i>Set Default Sort New</button>
<button id="{{p.id}}-unsort-new-mobile" type="button" class="{% if not p.new %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" id="{{p.id}}-unsort-new-mobile" onclick="postToastSwitch(this, '/post/{{p.id}}/new', this.id, '{{p.id}}-sort-new-mobile', 'd-none', null, 'DELETE')" data-bs-dismiss="modal"><i class="fas fa-sparkles text-center text-primary mr-2"></i>Unset Default Sort New</button>

View File

@ -68,10 +68,6 @@
<div style="display: inline-block; width: 150px; text-align: center;">Post Title Only:</div>
<button type="button" onClick="addParam()" class="searchparam mb-1">title:true</button>
</div>
<div>
<div style="display: inline-block; width: 150px; text-align: center;">Country Club:</div>
<button type="button" onClick="addParam()" class="searchparam mb-1">cc:true</button>
</div>
{% endif %}
</div>
</div>

View File

@ -64,12 +64,6 @@
{% block content %}
{% if SITE == 'pcmemes.net' %}
{% set cc='SPLASH MOUNTAIN' %}
{% else %}
{% set cc='COUNTRY CLUB' %}
{% endif %}
<div class="row mb-3">
<div id="post-root" class="col-12">
@ -101,14 +95,12 @@
{% 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' %}agendaposter{% 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)}}">
{% if p.club %}<span class="patron font-weight-bolder mr-1" style="background-color:red; font-size:12px; line-height:2;">{{CC}}</span>{% 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}}
</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' %}agendaposter{% endif %} {% if p.author.rainbow %}rainbow-text{% endif %}">
{% if p.club %}<span class="patron font-weight-bolder mr-1" style="background-color:red; font-size:12px; line-height:2;">{{CC}}</span>{% 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>
@ -518,7 +510,6 @@
localStorage.setItem("post-new", false)
localStorage.setItem("post-nsfw", false)
localStorage.setItem("post-private", false)
localStorage.setItem("post-club", false)
localStorage.setItem("post-ghost", false)
</script>
{% endif %}

View File

@ -4,12 +4,6 @@
{% include "modals/award.html" %}
{% endif %}
{% if SITE == 'pcmemes.net' %}
{% set cc='SPLASH MOUNTAIN' %}
{% else %}
{% set cc='COUNTRY CLUB' %}
{% endif %}
{% if not v or v.highlightcomments %}
<script defer src="{{'js/highlightcomments.js' | asset}}"></script>
{% endif %}
@ -79,9 +73,7 @@
{% if not v_forbid_deleted %}
<div class="card-thumbnail mt-3">
{% if p.club and not (v and (v.paid_dues or v.id == p.author_id)) %}
<img alt="post thumbnail" loading="lazy" src="/e/marseyglow.webp" class="post-img">
{% elif not p.url %}
{% if not p.url %}
<a {% if v and v.newtab %}data-target="t"target="_blank"{% endif %} href="{{p.permalink}}">
<img alt="post thumbnail" loading="lazy" src="{{p.thumb_url}}" class="post-img">
</a>
@ -118,7 +110,6 @@
</div>
<h5 class="card-title post-title text-left w-lg-95 pb-0 pb-md-1">
<a id="{{p.id}}-title" {% if v and v.newtab %}data-target="t"target="_blank"{% endif %} href="{{p.permalink}}" class="{% if p.sub %}sub{% endif %} stretched-link {% if p.author.agendaposter and p.sub != 'chudrama' %}agendaposter{% endif %}">
{% if p.club %}<span class="patron font-weight-bolder mr-1" style="background-color:red; font-size:12px; line-height:2;">{{CC}}</span>{% 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}}
</a></h5>
@ -237,7 +228,7 @@
{% endif %}
{% if (not p.club or v and (v.paid_dues or v.id == p.author_id)) and not v_forbid_deleted %}
{% 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' %}agendaposter{% endif %} {% if p.author.rainbow %}rainbow-text{% endif %} post-preview" id="post-text-{{p.id}}">
{{p.realbody(v, listing=True) | safe}}

View File

@ -83,12 +83,6 @@
<input autocomplete="off" type="checkbox" class="custom-control-input" id="post-private" name="private" onchange="savetext()">
<label class="custom-control-label" for="post-private">Draft</label>
</div>
{% if FEATURES['COUNTRY_CLUB'] -%}
<div class="custom-control custom-checkbox">
<input autocomplete="off" type="checkbox" class="custom-control-input" id="post-club" name="club" onchange="savetext()">
<label class="custom-control-label" for="post-club">{{CC_TITLE}} thread {% if DUES <= 0 %}(hides threads from logged-out users){% endif %}</label>
</div>
{%- endif %}
<div class="custom-control custom-checkbox mb-5">
{% if v.can_post_in_ghost_threads %}
<input onchange='ghost_toggle(this)' autocomplete="off" type="checkbox" class="custom-control-input" id="post-ghost" name="ghost">

View File

@ -101,10 +101,6 @@
<input type="submit" onclick="disable(this)" class="btn btn-danger" value="Remove User's Content">
</form>
{% endif %}
{% if FEATURES['COUNTRY_CLUB'] and v and v.admin_level >= PERMS['USER_CLUB_ALLOW_BAN'] %}
<button type="button" id="grant-{{deviceType}}" class="mt-1 {% if u.paid_dues %}d-none{% endif %} btn btn-success" onclick="postToastSwitch(this,'/@{{u.username}}/club_allow','grant-{{deviceType}}','bar-{{deviceType}}','d-none')">Grant club access</button>
<button type="button" id="bar-{{deviceType}}" class="{% if u.club_allowed == False %}d-none{% endif %} btn btn-danger" onclick="postToastSwitch(this,'/@{{u.username}}/club_ban','grant-{{deviceType}}','bar-{{deviceType}}','d-none')">Bar from club</button>
{% endif %}
</div>
</div>
{% endif %}

View File

@ -0,0 +1,109 @@
CREATE TABLE public.submission_options (
id integer PRIMARY KEY,
submission_id integer NOT NULL,
body_html character varying(500) NOT NULL,
exclusive boolean NOT NULL
);
CREATE INDEX option_submission ON public.submission_options USING btree (submission_id);
ALTER TABLE ONLY public.submission_options
ADD CONSTRAINT option_submission_fkey FOREIGN KEY (submission_id) REFERENCES public.submissions(id) MATCH FULL;
CREATE SEQUENCE public.submission_option_id_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE ONLY public.submission_options ALTER COLUMN id SET DEFAULT nextval('public.submission_option_id_seq'::regclass);
CREATE TABLE public.submission_option_votes (
option_id integer NOT NULL,
user_id integer NOT NULL,
created_utc integer NOT NULL,
submission_id integer
);
ALTER TABLE ONLY public.submission_option_votes
ADD CONSTRAINT submission_option_votes_pkey PRIMARY KEY (option_id, user_id);
ALTER TABLE ONLY public.submission_option_votes
ADD CONSTRAINT vote_option_fkey FOREIGN KEY (option_id) REFERENCES public.submission_options(id) MATCH FULL;
ALTER TABLE ONLY public.submission_option_votes
ADD CONSTRAINT vote_user_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) MATCH FULL;
ALTER TABLE ONLY public.submission_option_votes
ADD CONSTRAINT vote_submission_fkey FOREIGN KEY (submission_id) REFERENCES public.submissions(id) MATCH FULL;
CREATE TABLE public.comment_options (
id integer PRIMARY KEY,
comment_id integer NOT NULL,
body_html character varying(500) NOT NULL,
exclusive boolean NOT NULL
);
CREATE INDEX option_comment ON public.comment_options USING btree (comment_id);
ALTER TABLE ONLY public.comment_options
ADD CONSTRAINT option_comment_fkey FOREIGN KEY (comment_id) REFERENCES public.comments(id) MATCH FULL;
CREATE SEQUENCE public.comment_option_id_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE ONLY public.comment_options ALTER COLUMN id SET DEFAULT nextval('public.comment_option_id_seq'::regclass);
CREATE TABLE public.comment_option_votes (
option_id integer NOT NULL,
user_id integer NOT NULL,
created_utc integer NOT NULL,
comment_id integer
);
ALTER TABLE ONLY public.comment_option_votes
ADD CONSTRAINT comment_option_votes_pkey PRIMARY KEY (option_id, user_id);
ALTER TABLE ONLY public.comment_option_votes
ADD CONSTRAINT vote_option_fkey FOREIGN KEY (option_id) REFERENCES public.comment_options(id) MATCH FULL;
ALTER TABLE ONLY public.comment_option_votes
ADD CONSTRAINT vote_user_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) MATCH FULL;
ALTER TABLE ONLY public.comment_option_votes
ADD CONSTRAINT vote_comment_fkey FOREIGN KEY (comment_id) REFERENCES public.comments(id) MATCH FULL;

View File

@ -0,0 +1,2 @@
alter table users add column last_viewed_post_notifs int not null default 0;
alter table users alter column last_viewed_post_notifs drop default;

View File

@ -0,0 +1,2 @@
alter table users add column pronouns varchar(11) not null default 'they/them';
alter table users alter column pronouns drop default;

View File

@ -0,0 +1,2 @@
alter table users add column last_viewed_log_notifs int not null default 0;
alter table users alter column last_viewed_log_notifs drop default;

View File

@ -0,0 +1,15 @@
CREATE TYPE casino_game_kind AS ENUM ('blackjack', 'slots');
CREATE TYPE casino_game_currency AS ENUM ('coins', 'procoins');
CREATE TABLE casino_games (
id SERIAL PRIMARY KEY,
user_id integer NOT NULL REFERENCES users(id),
created_utc integer NOT NULL,
active boolean NOT NULL DEFAULT true,
currency casino_game_currency NOT NULL,
wager integer NOT NULL,
winnings integer NOT NULL,
kind casino_game_kind NOT NULL,
game_state jsonb NOT NULL
);

View File

@ -0,0 +1,249 @@
CREATE TABLE public.hat_defs (
id integer PRIMARY KEY,
name character varying(50) NOT NULL UNIQUE,
description character varying(300) NOT NULL,
author_id integer NOT NULL,
price integer NOT NULL
);
CREATE SEQUENCE public.hat_defs_id_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE public.hat_defs_id_seq OWNED BY public.hat_defs.id;
ALTER TABLE ONLY public.hat_defs ALTER COLUMN id SET DEFAULT nextval('public.hat_defs_id_seq'::regclass);
ALTER TABLE ONLY public.hat_defs
ADD CONSTRAINT hat_defs_author_id_fkey FOREIGN KEY (author_id) REFERENCES public.users(id);
CREATE TABLE public.hats (
hat_id integer NOT NULL,
user_id integer NOT NULL
);
ALTER TABLE ONLY public.hats
ADD CONSTRAINT hats_pkey PRIMARY KEY (user_id, hat_id);
ALTER TABLE ONLY public.hats
ADD CONSTRAINT hats_hat_id_fkey FOREIGN KEY (hat_id) REFERENCES public.hat_defs(id);
ALTER TABLE ONLY public.hats
ADD CONSTRAINT hats_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id);
alter table users add column coins_spent_on_hats integer DEFAULT 0 NOT NULL;
alter table users add column equipped_hat_id integer;
ALTER TABLE ONLY public.users
ADD CONSTRAINT users_equipped_hat_id_fkey FOREIGN KEY (equipped_hat_id) REFERENCES public.hat_defs(id);
insert into hat_defs (name, description, author_id, price) values
('Ushanka', 'The People''s Hat', 2, 500),
('Fur Hat', 'The first step on your path to fursuit ownership', 2, 500),
('Cat Ears I', 'Mew :3', 2, 500),
('Cat Ears II', 'Meow :3', 2, 500),
('Playboy Bunny', 'Will this bring daddy back?', 2, 500),
('Macaroni', 'Get it? Like the song lol', 2, 500),
('Pirate', 'BUTT pirate', 2, 500),
('Pirate Captain', 'Like a regular butt pirate, but for tops only', 2, 500),
('Dreads', 'Finally, an excuse for poor hygiene', 2, 500),
('The XXXTentacion', 'Pay homage to your favorite dead criminal!', 2, 500),
('the 6ix9ine', 'The finest piece of snitch couture on the market', 2, 500),
('The Elvis', 'Remember when this dude nailed a 13-year-old?', 2, 500),
('Gussy Hat', 'Let everyone know that you''re NOT a rapist. Honest.', 2, 500),
('Riveter', 'Can you do it? Really?', 2, 500),
('Top Hat (leprechaun)', 'LLM but Irish', 2, 500),
('Drinky Beer Hat', 'I actually didn''t know these were real things until I made this', 2, 500),
('Viking', 'Rape, pillage, never bathe. Live the dream.', 2, 500),
('Nonspecific Military Officer Hat', '[removed]', 2, 500),
('Soviet Officer I', 'OUR hat', 2, 500),
('Nonspecific Military Officer Hat II', '[removed]', 2, 500),
('Soviet Officer II', 'High fashion war criminal chic', 2, 500),
('Southern Gentleman', 'Slaveowner? Fried chicken chain founder? You decide!', 2, 500),
('Cowboy I', 'Make him wish he could quit you', 2, 500),
('Cowboy II', 'You''re my favorite deputy!', 2, 500),
('Halo', 'Dramamine criticized this one and now I''m too self-conscious about it to write a description', 2, 500),
('Fedora I', 'M''arsey', 2, 500),
('Bowler', 'Why would you need a hat to go bowling?', 2, 500),
('Du Rag (black)', 'Shitty bandana 1/6', 2, 500),
('Du Rag (red)', 'Shitty bandana 2/6', 2, 500),
('Du Rag (blue)', 'Shitty bandana 3/6', 2, 500),
('Du Rag (purple)', 'Shitty bandana 4/6', 2, 500),
('Du Rag (green)', 'Shitty bandana 5/6', 2, 500),
('Du Rag (yellow)', 'Shitty bandana 6/6', 2, 500),
('Ash Ketchum', 'You''re not so different, you and he', 2, 500),
('The Hotep', 'Traditional kangwear. POC ONLY.', 2, 500),
('Roman', 'Reddit delenda est', 2, 500),
('Confederate Soldier Cap', 'Basically the Gryffindor of American history', 2, 500),
('Northern Aggressor Soldier Cap', 'Slytherin irl', 2, 500),
('Rhodesian Light Infantry Beret', 'Rhodesians never die. Immortality guaranteed!', 2, 500),
('Magyar Headdress', 'Channel your inner QuadNarca and join Orban''s elite cavalry', 2, 500),
('The Senator Warren', 'heya heya heya heya heya heya heya heya heya heya heya', 2, 500),
('Please Be Patient I Have Autism', 'The OFFICIAL hat of rDrama.net', 2, 500),
('Samurai Helmet', 'Never be mistaken for a baka gaijin again', 2, 500),
('Watermelmet', 'Hydration and head protection all rolled into one stylish headpiece', 2, 500),
('Frankenstein', 'Akshually, Frankenstein was the scientist. The monster didn''t have a name.', 2, 500),
('The Drumpf', 'Orange hair bad', 2, 500),
('Tinfoil Hat', 'Keep Bill Gates'' 5G vaccine OUT of your precious brain!', 2, 500),
('Fez', 'Isn''t it CUTE?', 2, 500),
('Ching Chong', 'Me Chinese Me No Dumb Me Stick Finger In Daddy''s Bum', 2, 500),
('Octopus Friend', 'Awwwwwww!', 2, 500),
('In The Navy', 'It''s not gay', 2, 500),
('Seaman', 'semen lol', 2, 500),
('Flower Crown I', 'oh god i have to write descriptions for 15 flower crowns', 2, 500),
('Flower Crown II', 'A very cute flower crown', 2, 500),
('Flower Crown III', 'A super cute flower crown', 2, 500),
('Flower Crown IV', 'A really cute flower crown', 2, 500),
('Flower Crown V', 'The cutest flower crown?', 2, 500),
('Flower Crown VI', 'An extremely cute flower crown', 2, 500),
('Flower Crown VII', 'A flower crown that''s just so cute', 2, 500),
('Flower Crown VIII', 'A majorly cute flower crown', 2, 500),
('Flower Crown IX', 'A mega cute flower crown', 2, 500),
('Flower Crown X', 'An ultra cute flower crown', 2, 500),
('Flower Crown XI', 'Definitely the cutest flower crown', 2, 500),
('Flower Crown XII', 'A hella cute flower crown', 2, 500),
('Flower Crown XIII', 'An experimental anti-gravity cute flower crown', 2, 500),
('Flower Crown XIV', 'An adorably cute flower crown', 2, 500),
('Flower Crown XV', 'The final cute flower crown', 2, 500),
('Bow', 'What a cute little bow omg', 2, 500),
('BIPOCsmoke', 'It''s a Newport. You know it''s a Newport.', 2, 500),
('Gigachin', 'Aw yeah, this user definitely supports trans rights', 2, 500),
('Queensguard', 'A bear died for this', 2, 500),
('Queen Crown', 'Don''t be a drag', 2, 500),
('King Crown', 'King is like the n word, only racists and black people should be allowed to say it', 2, 500),
('Pope Hat', 'Matthew 16:18', 2, 500),
('Heebhead', 'Do NOT google the Lavon Affair', 2, 500),
('Zoomie Zoom Zoom', 'Underage user, do not interact', 2, 500),
('Sombrero I', 'El Autistico', 2, 500),
('Sombrero II', 'El Autistico Grandisimo', 2, 500),
('Crypto Billionaire', 'Sorry about the ice cream machine', 2, 500),
('Burger King Crown', 'I''m gonna say it', 2, 500),
('Burger King', 'You can have it your way and you still chose this', 2, 500),
('Wendys', 'Sassy social media intern', 2, 500),
('KFC', 'Popeyes is too far away', 2, 500),
('In-N-Out', 'Kill the commiefornian', 2, 500),
('Carls Jr', 'Purveyor of literally the finest food in the world', 2, 500),
('Whataburger', 'Texans don''t know any better', 2, 500),
('Five Guys', 'I love having 5 guys in my mouth', 2, 500),
('Taco Bell', 'Enabler of drunken mistakes', 2, 500),
('Marsey-In-A-Box', 'Awww you''re playing make-believe!', 2, 500),
('Orthodox Hood', 'User is a schismatic lunatic', 2, 500),
('Afro', 'Pool''s closed motherlover', 2, 500),
('Top Hat (black)', 'Traditional. Classy. Elegant.', 2, 500),
('Wizard I', 'Three decades a KHHV', 2, 500),
('Wizard II', 'Avada kedavra ✨', 2, 500),
('Witch I', 'Hex the patriarchy', 2, 500),
('Witch II', 'Bardfinn cosplay gear', 2, 500),
('Sun Hat', 'Tradwife simplicity', 2, 500),
('Obey Snapback', 'The timeless classic', 2, 500),
('Thug Life Snapback', 'User confirmed mayo', 2, 500),
('Supreme Snapback', 'Drip so hard omg', 2, 500),
('Make America Great Again', 'The official headgear of stochastic terrorists everywhere', 2, 500),
('Born To Feel', 'Do you pee standing up?', 2, 500),
('Fortunate Son', 'BORN TO SHIT FORCED TO WIPE', 2, 500),
('WWI', 'How is this supposed to offer any meaningful protection??', 2, 500),
('Pickelhaube', 'Inarguably the most fashionable of all contemporary military headgear ', 2, 500),
('Wehrmacht', 'What a cool helmet, I bet the people who wore it were real classy folks ', 2, 500),
('Chair Force', 'Yeah I''m a combat veteran, I''ve seen shit you wouldn''t believe. One time the wifi was out for almost an hour. ', 2, 500),
('Helmet w Dog Tags', 'More like dog fags lol', 2, 500),
('Urban Camo Helmet', 'Man urban camo is cool', 2, 500),
('Nightvision Helmet', 'Four-eyed freak', 2, 500),
('Helmet w Mesh', 'Sexy fishnet stocking helmet', 2, 500),
('Tojo Helmet', 'Artifact from Weeb War II', 2, 500),
('Officers Cap', 'Get fragged bozo', 2, 500),
('Jailbird Cap', 'The apex of prison fashion. Why did we stop using this?', 2, 500),
('P-Hat (green)', 'Zezima fanboy', 2, 500),
('P-Hat (red)', 'おれはPigAmericanですおれはばか i am average american man i enjoy bad game runescape', 2, 500),
('P-Hat (yellow)', 'PISS HAT PISS HAT', 2, 500),
('P-Hat (blue)', 'Ughhhh coming up with different descriptions for RuneScape party hats', 2, 500),
('P-Hat (pink)', 'It''s pink.', 2, 500),
('P-Hat (rainbow)', 'LGBTscape 😍', 2, 500),
('Newsboy', 'Or newsgirl. It''s okay, the hat is actually gender-neutral.', 2, 500),
('Whirly Tard Hat I', 'Wouldn''t it be neat if they could make one that like uses body heat or whatever to keep the propeller in a state of constant motion', 2, 500),
('Dunce Cap', 'You retard. Imbecile. Utter buffoon. Oaf. Nincompoop. Idiot. Moron. CLOWN.', 2, 500),
('Beret', 'Literally the most basic possible hat choice. Please do better. ', 2, 500),
('Mario', 'BING BING WAHOO ', 2, 500),
('Luigi', 'LING LING LAHOO', 2, 500),
('Wing Cap', 'If the hat''s wings are what provide the thrust necessary for flight then how does it stay on and let YOU fly with it huh', 2, 500),
('Metal Mario', 'Mario hat but with yelling and lots of double bass and distorted guitars and shit heck yeah', 2, 500),
('Cappy', 'A sentient hat-creature that''s actually a pretty horrifying parasite if you think about it', 2, 500),
('Wario', 'For the fat, yellow, extremely flatulent dramautist (in loving memory of Bidpots)', 2, 500),
('Waluigi', 'Coming soon to Smash for sure', 2, 500),
('Top Hat (kek)', 'Technically a top hat, shut up', 2, 500),
('Top Hat (white)', 'Oh, how dignified', 2, 500),
('Top Hat (striped)', 'Tim Burton''s take on the top hat', 2, 500),
('Top Hat (checkered)', 'Actually chessed, but that''s not really a word.', 2, 500),
('Top Hat (march hare)', 'April hare, May hare, June hare, July hare,', 2, 500),
('Top Hat (mad hatter)', 'Hatters mad [x24]', 2, 500),
('Top Hat (red)', 'Top hat, menstrual edition', 2, 500),
('Top Hat (uncle sam)', 'THIS HAT WAS FACT-CHECKED BY TRUE AMERICAN PATRIOTS', 2, 500),
('Fireperson I', 'In loving memory of r/HateForFirefighters', 2, 500),
('Constable', 'Useless bong cop nonsense', 2, 500),
('NYPD Officer', 'This user is authorized to stop, frisk and cavity search you at any time for any reason', 2, 500),
('Crossing Guard', 'We love Officer Marsey!', 2, 500),
('Paper Sailor', 'As idle as a paper ship, upon a paper ocean. Paper, paper, everywhere.', 2, 500),
('FBI', 'Federal Bussy Inspector', 2, 500),
('CIA', 'Cisgender Incineration Agency', 2, 500),
('ATF', 'Ass-Tickling Faggot. HIDE YOUR DOG!', 2, 500),
('Graduate', 'This hat signifies that the bearer has completed four (4) years of pan-african gender studies coursework', 2, 500),
('Nurse', 'Minor TikTok celebrity, OnlyFans top 91%', 2, 500),
('Farmer', 'Feed & Seed shopper', 2, 500),
('Farmette', 'Feed & Seed shoppette', 2, 500),
('Kung Lao', 'Why did I make a Kung Lao hat', 2, 500),
('Top Hat (steampunk)', 'Like a regular top hat but with goggles and gears', 2, 500),
('Brain Hat', 'Peter Griffin''s dog', 2, 500),
('The TED_SIMP', 'Wear this hat to express your undying adoration for carp', 2, 500),
('The Brandon', 'Listen here fat', 2, 500),
('The Brandon II', 'LISTEN HERE FAT', 2, 500),
('The King George', 'Proto-drag if you think about it', 2, 500),
('The Mao', 'Our hair!', 2, 500),
('The Young Stalin', 'Pockmarks not included', 2, 500),
('The Ripe Stalin', 'An homage to the #1 most prolific killer of commies in world history', 2, 500),
('The Austrian Painter', 'For aficionados of mid-20th century fine artists slash authors', 2, 500),
('Kenny I', 'User''s life insurance claim was rejected', 2, 500),
('Modern Major General', 'For my military knowledge, though I''m plucky and adventury / Has only been brought down to the beginning of the century / But still, in matters vegetable, animal, and mineral / I am the very model of a modern Major-General', 2, 500),
('Red Star Cap', 'Cannon fodder', 2, 500),
('Cartman', 'Fat antisemite - the archetypal rDrama user', 2, 500),
('Cheesehead', 'For fans of the Green Gay Fudge Packers', 2, 500),
('Kyle', 'ngl I don''t watch South Park so idk the difference between this and Stan', 2, 500),
('Stan', 'ngl I don''t watch South Park so idk the difference between this and Kyle', 2, 500),
('Kenny II', 'Like Kenny I except it shows more of your ugly face', 2, 500),
('The Cleopatra', 'Did you know she was actually white?', 2, 500),
('Pimp Hat I', 'Women are objects', 2, 500),
('Devil Horns', 'Satan is so cool and quirky!!!', 2, 500),
('Nooticer', 'THIS USER IS ENGAGED IN THOUGHTCRIME. DO NOT INTERACT.', 2, 500),
('Airpods', 'oh god oh fuck he cant hear us', 2, 500),
('Maskmaxxer', 'Why aren''t there two? Are you trying to kill us?', 2, 500),
('The Tupac', 'dead nigger storage', 2, 500),
('Media Executive', 'despite making up just 2% of the population,', 2, 500),
('Surgeon', 'Lobotomize me daddy', 2, 500),
('Mouseketeer', 'please don''t sue please don''t sue please don''t sue please don''t sue please don''t sue', 2, 500),
('Karen', 'Let me speak to your manager', 2, 500),
('Badass Fighter Ace', ' Top Gun™ Maverick® Now Showing In Theaters!', 2, 500),
('Taqiyah', 'It''s not a yarmulke I swear', 2, 500),
('Cock', 'DM me yours!', 2, 500),
('Nervous, Sweating', '>mfw', 2, 500),
('The Cat', 'does this really need a description', 2, 500),
('Noose', 'Cope or rope', 2, 500),
('The Penny', 'This shower cap bonnet is perfect for hiding nappy, alopecia-ridden hair', 2, 500),
('Hard Hat (yellow)', 'A rock hard, throbbing, veiny hat. Check out the girth on this thing', 2, 500),
('Hard Hat (white)', 'The mayo variant of the hard hat, used to signify someone of importance, or a visitor, at a job site', 2, 500),
('Beret (TF2)', 'Stylish vidya-variant of the beret', 2, 500),
('Texas Ten Gallon', 'Yeehaw!', 2, 500),
('Demoman', 'KaBOOM', 2, 500),
('Fireperson II', 'For extinguishing hot threads', 2, 500),
('Miners Hat', 'Please don''t touch minors', 2, 500),
('Old Man Hat', 'AKA the Wizdumb', 2, 500),
('Pimp Hat II', 'Women are people and they deserve respect just kidding they should suck my penis', 2, 500),
('Whirly Tard Hat II', 'Propeller go brrrrrrrrrr', 2, 500),
('Family Man Free Hat', 'It''s a good show!', 2, 500),
('Engineer', 'Choo choo!', 2, 500),
('Vexillaurius Helmet', 'Degenerates like you belong on rDrama', 2, 500),
('Astronaut Helmet', 'See you, space marsey', 2, 500);

View File

@ -0,0 +1,6 @@
alter table marseys add column submitter_id int;
ALTER TABLE ONLY public.marseys
ADD CONSTRAINT marsey_submitter_fkey FOREIGN KEY (submitter_id) REFERENCES public.users(id);
CREATE INDEX marseys_idx4 ON public.marseys USING btree (submitter_id);

View File

@ -0,0 +1,6 @@
alter table hat_defs add column submitter_id int;
ALTER TABLE ONLY public.hat_defs
ADD CONSTRAINT hat_def_submitter_fkey FOREIGN KEY (submitter_id) REFERENCES public.users(id);
CREATE INDEX hat_defs_submitter_id_idx ON public.hat_defs USING btree (submitter_id);

View File

@ -0,0 +1,2 @@
alter table submissions add column notify bool not null default true;
alter table submissions alter column notify drop default;

View File

@ -0,0 +1 @@
ALTER TYPE casino_game_kind ADD VALUE 'roulette';

View File

@ -0,0 +1,22 @@
alter table alts add column created_utc int;
alter table award_relationships add column created_utc int;
alter table badge_defs add column created_utc int;
alter table oauth_apps add column created_utc int;
alter table client_auths add column created_utc int;
alter table banneddomains add column created_utc int;
alter table exiles add column created_utc int;
alter table hat_defs add column created_utc int;
alter table hats add column created_utc int;
alter table lotteries add column created_utc int;
alter table marseys add column created_utc int;
alter table submission_options add column created_utc int;
alter table comment_options add column created_utc int;
alter table save_relationship add column created_utc int;
alter table comment_save_relationship add column created_utc int;
alter table sub_blocks add column created_utc int;
alter table sub_joins add column created_utc int;
alter table sub_subscriptions add column created_utc int;
alter table subs add column created_utc int;
alter table subscriptions add column created_utc int;
alter table userblocks add column created_utc int;
alter table viewers add column created_utc int;

View File

@ -0,0 +1,9 @@
CREATE TABLE public.transactions (
id character varying(36) PRIMARY KEY,
created_utc integer NOT NULL,
type character varying(12) NOT NULL,
amount integer NOT NULL,
email character varying(255) NOT NULL
);
CREATE INDEX transactions_email_idx ON public.transactions USING btree (email);

View File

@ -0,0 +1 @@
alter table users drop column winnings;

View File

@ -0,0 +1 @@
alter table users add column spider int;

View File

@ -0,0 +1,43 @@
CREATE TABLE public.subactions (
id integer PRIMARY KEY,
sub character varying(25) NOT NULL,
user_id integer,
target_user_id integer,
target_submission_id integer,
target_comment_id integer,
created_utc integer NOT NULL,
kind character varying(32) DEFAULT NULL::character varying,
_note character varying(500) DEFAULT NULL::character varying
);
CREATE SEQUENCE public.subactions_id_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE public.subactions_id_seq OWNED BY public.subactions.id;
ALTER TABLE ONLY public.subactions ALTER COLUMN id SET DEFAULT nextval('public.subactions_id_seq'::regclass);
CREATE INDEX fki_subactions_user_fkey ON public.subactions USING btree (target_user_id);
CREATE INDEX modaction_action_idx ON public.subactions USING btree (kind);
CREATE INDEX modaction_pid_idx ON public.subactions USING btree (target_submission_id);
ALTER TABLE ONLY public.subactions
ADD CONSTRAINT subactions_submission_fkey FOREIGN KEY (target_submission_id) REFERENCES public.submissions(id);
CREATE INDEX modaction_cid_idx ON public.subactions USING btree (target_comment_id);
ALTER TABLE ONLY public.subactions
ADD CONSTRAINT subactions_comment_fkey FOREIGN KEY (target_comment_id) REFERENCES public.comments(id);
ALTER TABLE ONLY public.subactions
ADD CONSTRAINT subactions_user_fkey FOREIGN KEY (target_user_id) REFERENCES public.users(id);
ALTER TABLE ONLY public.subactions
ADD CONSTRAINT subactions_sub_fkey FOREIGN KEY (sub) REFERENCES public.subs(name);

View File

@ -0,0 +1,3 @@
ALTER TABLE public.comments ADD COLUMN body_ts tsvector
GENERATED ALWAYS AS (to_tsvector('english', body)) STORED;
CREATE INDEX comments_body_ts_idx ON public.comments USING GIN (body_ts);

View File

@ -0,0 +1,13 @@
CREATE TABLE public.media (
kind character varying(5) NOT NULL,
filename character varying(55) NOT NULL,
user_id Integer NOT NULL,
created_utc integer NOT NULL,
size integer NOT NULL
);
ALTER TABLE ONLY public.media
ADD CONSTRAINT media_pkey PRIMARY KEY (kind, filename);
ALTER TABLE ONLY public.media
ADD CONSTRAINT media_user_fkey FOREIGN KEY (user_id) REFERENCES public.users(id);

View File

@ -0,0 +1,4 @@
UPDATE submissions SET sub = 'countryclub' WHERE club = true AND sub IS NULL;
DELETE FROM modactions WHERE kind IN ('club_allow','club_ban','club_post','unclub_post');
ALTER TABLE submissions DROP COLUMN club;
ALTER TABLE users DROP COLUMN club_allowed;

View File

@ -107,7 +107,6 @@ CREATE TABLE public.submissions (
is_bot boolean DEFAULT false NOT NULL,
bannedfor character varying(40),
comment_count integer DEFAULT 0 NOT NULL,
club boolean DEFAULT false NOT NULL,
stickied character varying(40),
title character varying(500) NOT NULL,
url character varying(2083),
@ -989,7 +988,6 @@ CREATE TABLE public.users (
highlightcomments boolean DEFAULT true NOT NULL,
nitter boolean,
truescore integer DEFAULT 0 NOT NULL,
club_allowed boolean,
frontsize integer DEFAULT 25 NOT NULL,
coins_spent integer DEFAULT 0 NOT NULL,
marseybux integer DEFAULT 0 NOT NULL,
@ -2722,4 +2720,3 @@ ALTER TABLE ONLY public.comment_option_votes
--
-- PostgreSQL database dump complete
--