Merge branch 'frost' of https://github.com/Aevann1/rDrama into frost

master
Aevann1 2022-10-10 05:27:37 +00:00
commit 1e8ed876b3
107 changed files with 489 additions and 624 deletions

View File

@ -4026,6 +4026,9 @@ ul.comment-section {
.profile-actions .dropdown-item:hover .fa, .profile-actions .dropdown-item:hover .fas, .profile-actions .dropdown-item:active .far {
color: var(--black);
}
.profile-owned-all-hats {
color: gold;
}
#page .footer h1, #page .footer h2, #page .footer h3, #page .footer h4, #page .footer h5, #page .footer h6, #article .footer h1, #article .footer h2, #article .footer h3, #article .footer h4, #article .footer h5, #article .footer h6 {
font-weight: 600;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,5 +1,5 @@
function removeFollower(event, username) {
post_toast(event.target,'/remove_follow/' + username);
function removeFollower(t, username) {
post_toast(t,'/remove_follow/' + username);
let table = document.getElementById("followers-table");
table.removeChild(event.target.parentElement.parentElement);
table.removeChild(t.parentElement.parentElement);
}

View File

@ -1,5 +1,5 @@
function removeFollowing(event, username) {
post_toast(event.target,'/unfollow/' + username);
function removeFollowing(t, username) {
post_toast(t,'/unfollow/' + username);
let table = document.getElementById("followers-table");
table.removeChild(event.target.parentElement.parentElement);
table.removeChild(t.parentElement.parentElement);
}

File diff suppressed because one or more lines are too long

View File

@ -33,7 +33,7 @@ class OauthApp(Base):
@property
@lazy
def permalink(self):
return f"/admin/app/{self.id}"
return f"{SITE_FULL}/admin/app/{self.id}"
@lazy
def idlist(self, page=1):

View File

@ -208,6 +208,13 @@ class User(Base):
def num_of_owned_hats(self):
return len(self.owned_hats)
@property
@lazy
def hats_owned_proportion_display(self):
total_num_of_hats = g.db.query(HatDef).filter(HatDef.submitter_id == None).count()
proportion = f'{float(self.num_of_owned_hats) / total_num_of_hats:.1%}'
return (proportion, total_num_of_hats)
@property
@lazy
def num_of_designed_hats(self):

View File

@ -191,3 +191,123 @@ def execute_snappy(post, v):
post.comment_count += 1
post.replies = [c]
def execute_zozbot(c, level, parent_submission, v):
if random.random() >= 0.001: return
c2 = Comment(author_id=ZOZBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c.id,
level=level+1,
is_bot=True,
body="zoz",
body_html="<p>zoz</p>",
top_comment_id=c.top_comment_id,
ghost=c.ghost,
distinguish_level=6
)
g.db.add(c2)
g.db.flush()
n = Notification(comment_id=c2.id, user_id=v.id)
g.db.add(n)
c3 = Comment(author_id=ZOZBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c2.id,
level=level+2,
is_bot=True,
body="zle",
body_html="<p>zle</p>",
top_comment_id=c.top_comment_id,
ghost=c.ghost,
distinguish_level=6
)
g.db.add(c3)
g.db.flush()
c4 = Comment(author_id=ZOZBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c3.id,
level=level+3,
is_bot=True,
body="zozzle",
body_html="<p>zozzle</p>",
top_comment_id=c.top_comment_id,
ghost=c.ghost,
distinguish_level=6
)
g.db.add(c4)
zozbot = get_account(ZOZBOT_ID)
zozbot.comment_count += 3
zozbot.coins += 3
g.db.add(zozbot)
def execute_longpostbot(c, level, body, body_html, parent_submission, v):
if not len(c.body.split()) >= 200: return
if "</blockquote>" in body_html: return
body = random.choice(LONGPOST_REPLIES)
if body.startswith('โ–ผ'):
body = body[1:]
vote = CommentVote(user_id=LONGPOSTBOT_ID,
vote_type=-1,
comment_id=c.id,
real = True
)
g.db.add(vote)
c.downvotes = 1
c2 = Comment(author_id=LONGPOSTBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c.id,
level=level+1,
is_bot=True,
body=body,
body_html=f"<p>{body}</p>",
top_comment_id=c.top_comment_id,
ghost=c.ghost
)
g.db.add(c2)
longpostbot = get_account(LONGPOSTBOT_ID)
longpostbot.comment_count += 1
longpostbot.coins += 1
g.db.add(longpostbot)
g.db.flush()
n = Notification(comment_id=c2.id, user_id=v.id)
g.db.add(n)
def execute_basedbot(c, level, body, parent_submission, parent_post, v):
pill = based_regex.match(body)
if level == 1: basedguy = get_account(parent_post.author_id)
else: basedguy = get_account(c.parent_comment.author_id)
basedguy.basedcount += 1
if pill:
if basedguy.pills: basedguy.pills += f", {pill.group(1)}"
else: basedguy.pills += f"{pill.group(1)}"
g.db.add(basedguy)
body2 = f"@{basedguy.username}'s Based Count has increased by 1. Their Based Count is now {basedguy.basedcount}."
if basedguy.pills: body2 += f"\n\nPills: {basedguy.pills}"
body_based_html = sanitize(body2)
c_based = Comment(author_id=BASEDBOT_ID,
parent_submission=parent_submission,
distinguish_level=6,
parent_comment_id=c.id,
level=level+1,
is_bot=True,
body_html=body_based_html,
top_comment_id=c.top_comment_id,
ghost=c.ghost
)
g.db.add(c_based)
g.db.flush()
n = Notification(comment_id=c_based.id, user_id=v.id)
g.db.add(n)

View File

@ -265,6 +265,10 @@ POST_TITLE_LENGTH_LIMIT = 500 # do not make larger than 500 without altering the
POST_TITLE_HTML_LENGTH_LIMIT = 1500 # do not make larger than 1500 without altering the table
POST_BODY_LENGTH_LIMIT = 20000 # do not make larger than 20000 without altering the table
POST_BODY_HTML_LENGTH_LIMIT = 40000 # do not make larger than 40000 without altering the table
COMMENT_BODY_LENGTH_LIMIT = 10000 # do not make larger than 10000 characters without altering the table
COMMENT_BODY_HTML_LENGTH_LIMIT = 20000 # do not make larger than 20000 characters without altering the table
COMMENT_MAX_DEPTH = 200
TRANSFER_MESSAGE_LENGTH_LIMIT = 200 # do not make larger than 10000 characters (comment limit) without altering the table
LOGGEDIN_ACTIVE_TIME = 15 * 60
PFP_DEFAULT_MARSEY = True

View File

@ -195,11 +195,11 @@ def sanitize_raw_title(sanitized):
sanitized = sanitized.strip()
return sanitized[:POST_TITLE_LENGTH_LIMIT]
def sanitize_raw_body(sanitized):
def sanitize_raw_body(sanitized, is_post):
if not sanitized: return ""
sanitized = sanitized.replace('\u200e','').replace('\u200b','').replace("\ufeff", "").replace("\r\n", "\n")
sanitized = sanitized.strip()
return sanitized[:POST_BODY_LENGTH_LIMIT]
return sanitized[:POST_BODY_LENGTH_LIMIT if is_post else COMMENT_BODY_LENGTH_LIMIT]
@with_sigalrm_timeout(5)

View File

@ -853,7 +853,9 @@ def agendaposter(user_id, v):
user.agendaposter = expiry
g.db.add(user)
if days: note = f"for {days} days"
if days:
days_txt = str(days).rstrip('.0')
note = f"for {days_txt} days"
else: note = "permanently"
ma = ModAction(
@ -1015,8 +1017,9 @@ def ban_user(user_id, v):
x.ban(admin=v, reason=reason, days=days)
if days:
if reason: text = f"@{v.username} has banned you for **{days}** days for the following reason:\n\n> {reason}"
else: text = f"@{v.username} has banned you for **{days}** days."
days_txt = str(days).rstrip('.0')
if reason: text = f"@{v.username} has banned you for **{days_txt}** days for the following reason:\n\n> {reason}"
else: text = f"@{v.username} has banned you for **{days_txt}** days."
else:
if reason: text = f"@{v.username} has banned you permanently for the following reason:\n\n> {reason}"
else: text = f"@{v.username} has banned you permanently."
@ -1025,7 +1028,7 @@ def ban_user(user_id, v):
if days == 0: duration = "permanently"
elif days == 1: duration = "for 1 day"
else: duration = f"for {days} days"
else: duration = f"for {days_txt} days"
note = f'reason: "{reason}", duration: {duration}'
ma=ModAction(

View File

@ -209,19 +209,6 @@ def award_thing(v, thing_type, id):
elif author.unban_utc:
author.unban_utc += 86400
send_repeatable_notification(author.id, f"Your account has been banned for **yet another day** for {link}. Seriously man?")
if v.admin_level >= PERMS['USER_BAN']:
log_link = f'/{thing_type}/{thing.id}'
reason = f'<a href="{log_link}">{log_link}</a>'
note = f'reason: "{reason}", duration: for 1 day'
ma=ModAction(
kind="ban_user",
user_id=v.id,
target_user_id=author.id,
_note=note
)
g.db.add(ma)
elif kind == "unban":
if not author.is_suspended or not author.unban_utc or time.time() > author.unban_utc: abort(403)
@ -233,32 +220,11 @@ def award_thing(v, thing_type, id):
author.is_banned = 0
author.ban_reason = None
send_repeatable_notification(author.id, "You have been unbanned!")
if v.admin_level >= PERMS['USER_BAN']:
ma=ModAction(
kind="unban_user",
user_id=v.id,
target_user_id=author.id,
)
g.db.add(ma)
elif kind == "grass":
author.is_banned = AUTOJANNY_ID
author.ban_reason = f"grass award used by @{v.username} on /{thing_type}/{thing.id}"
author.unban_utc = int(time.time()) + 30 * 86400
send_repeatable_notification(author.id, f"Your account has been banned permanently for {link}. You must [provide the admins](/contact) a timestamped picture of you touching grass/snow/sand/ass to get unbanned!")
if v.admin_level >= PERMS['USER_BAN']:
log_link = f'/{thing_type}/{thing.id}'
reason = f'<a href="{log_link}">{log_link}</a>'
note = f'reason: "{reason}", duration: for 30 days'
ma=ModAction(
kind="ban_user",
user_id=v.id,
target_user_id=author.id,
_note=note
)
g.db.add(ma)
elif kind == "pin":
if not FEATURES['PINS']:
abort(403)
@ -294,15 +260,6 @@ def award_thing(v, thing_type, id):
else: author.agendaposter = int(time.time()) + 86400
badge_grant(user=author, badge_id=28)
if v.admin_level >= PERMS['USER_AGENDAPOSTER']:
ma = ModAction(
kind="agendaposter",
user_id=v.id,
target_user_id=author.id,
_note=f"for 1 day"
)
g.db.add(ma)
elif kind == "flairlock":
if thing.ghost: abort(403)
new_name = note[:100].replace("๐’ช","")

View File

@ -33,12 +33,7 @@ WORDLE_COLOR_MAPPINGS = {-1: "๐ŸŸฅ", 0: "๐ŸŸจ", 1: "๐ŸŸฉ"}
@app.get("/logged_out/h/<sub>/post/<pid>/<anything>/<cid>")
@auth_desired_with_logingate
def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None):
try: cid = int(cid)
except: abort(404)
comment = get_comment(cid, v=v)
if not comment.can_see(v): abort(403)
if comment.author.shadowbanned and not (v and v.shadowbanned) and not (v and v.admin_level >= PERMS['USER_SHADOWBAN']):
@ -60,9 +55,6 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None):
elif SITE == 'pcmemes.net': pid = 2487
else: pid = 1
try: pid = int(pid)
except: abort(404)
post = get_post(pid, v=v)
if post.over_18 and not (v and v.over_18) and not session.get('over_18', 0) >= int(time.time()):
@ -167,9 +159,10 @@ def comment(v):
if not parent.can_see(v): abort(404)
if parent.deleted_utc != 0: abort(404)
body = request.values.get("body", "").strip().replace('โ€Ž','')
if level > COMMENT_MAX_DEPTH:
return {"error": f"Max comment level is {COMMENT_MAX_DEPTH}"}, 400
body = body.replace('\r\n', '\n')[:10000]
body = sanitize_raw_body(request.values.get("body", ""), False)
if parent_post.id not in ADMIGGERS:
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
@ -239,7 +232,7 @@ def comment(v):
else:
abort(415)
body = body.strip()
body = body.strip()[:COMMENT_BODY_LENGTH_LIMIT]
if v.admin_level >= PERMS['SITE_SETTINGS_SNAPPY_QUOTES'] and parent_post.id == SNAPPY_THREAD and level == 1:
with open(f"snappy_{SITE_NAME}.txt", "a", encoding="utf-8") as f:
@ -266,9 +259,9 @@ def comment(v):
if existing: return {"error": f"You already made that comment: /comment/{existing.id}"}, 409
if parent.author.any_block_exists(v) and v.admin_level < PERMS['POST_COMMENT_MODERATION']:
return {"error": "You can't reply to users who have blocked you, or users you have blocked."}, 403
return {"error": "You can't reply to users who have blocked you or users that you have blocked."}, 403
is_bot = v.id != 12125 and (bool(request.headers.get("Authorization")) or (SITE == 'pcmemes.net' and v.id == SNAPPY_ID))
is_bot = v.id != BBBB_ID and (bool(request.headers.get("Authorization")) or (SITE == 'pcmemes.net' and v.id == SNAPPY_ID))
if len(body) > 50:
now = int(time.time())
@ -308,10 +301,7 @@ def comment(v):
g.db.commit()
return {"error": "Too much spam!"}, 403
if len(body_html) > 20000: abort(400)
if level > 200:
return {"error": "Max comment level is 200"}, 400
if len(body_html) > COMMENT_BODY_HTML_LENGTH_LIMIT: abort(400)
c = Comment(author_id=v.id,
parent_submission=parent_submission,
@ -321,7 +311,7 @@ def comment(v):
is_bot=is_bot,
app_id=v.client.application.id if v.client else None,
body_html=body_html,
body=body[:10000],
body=body,
ghost=parent_post.ghost
)
@ -355,37 +345,7 @@ def comment(v):
g.db.add(choice)
if SITE == 'pcmemes.net' and c.body.lower().startswith("based"):
pill = based_regex.match(body)
if level == 1: basedguy = get_account(parent_post.author_id)
else: basedguy = get_account(c.parent_comment.author_id)
basedguy.basedcount += 1
if pill:
if basedguy.pills: basedguy.pills += f", {pill.group(1)}"
else: basedguy.pills += f"{pill.group(1)}"
g.db.add(basedguy)
body2 = f"@{basedguy.username}'s Based Count has increased by 1. Their Based Count is now {basedguy.basedcount}."
if basedguy.pills: body2 += f"\n\nPills: {basedguy.pills}"
body_based_html = sanitize(body2)
c_based = Comment(author_id=BASEDBOT_ID,
parent_submission=parent_submission,
distinguish_level=6,
parent_comment_id=c.id,
level=level+1,
is_bot=True,
body_html=body_based_html,
top_comment_id=c.top_comment_id,
ghost=c.ghost
)
g.db.add(c_based)
g.db.flush()
n = Notification(comment_id=c_based.id, user_id=v.id)
g.db.add(n)
execute_basedbot(c, level, body, parent_submission, parent_post, v)
if v.agendaposter and not v.marseyawarded and AGENDAPOSTER_PHRASE not in c.body.lower() and parent_post.sub != 'chudrama':
@ -419,101 +379,9 @@ def comment(v):
n = Notification(comment_id=c_jannied.id, user_id=v.id)
g.db.add(n)
if SITE_NAME == 'rDrama' and len(c.body.split()) >= 200 and "<" not in body and "</blockquote>" not in body_html:
body = random.choice(LONGPOST_REPLIES)
if body.startswith('โ–ผ'):
body = body[1:]
vote = CommentVote(user_id=LONGPOSTBOT_ID,
vote_type=-1,
comment_id=c.id,
real = True
)
g.db.add(vote)
c.downvotes = 1
c2 = Comment(author_id=LONGPOSTBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c.id,
level=level+1,
is_bot=True,
body=body,
body_html=f"<p>{body}</p>",
top_comment_id=c.top_comment_id,
ghost=c.ghost
)
g.db.add(c2)
longpostbot = get_account(LONGPOSTBOT_ID)
longpostbot.comment_count += 1
longpostbot.coins += 1
g.db.add(longpostbot)
g.db.flush()
n = Notification(comment_id=c2.id, user_id=v.id)
g.db.add(n)
if SITE_NAME == 'rDrama' and random.random() < 0.001:
c2 = Comment(author_id=ZOZBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c.id,
level=level+1,
is_bot=True,
body="zoz",
body_html="<p>zoz</p>",
top_comment_id=c.top_comment_id,
ghost=c.ghost,
distinguish_level=6
)
g.db.add(c2)
g.db.flush()
n = Notification(comment_id=c2.id, user_id=v.id)
g.db.add(n)
c3 = Comment(author_id=ZOZBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c2.id,
level=level+2,
is_bot=True,
body="zle",
body_html="<p>zle</p>",
top_comment_id=c.top_comment_id,
ghost=c.ghost,
distinguish_level=6
)
g.db.add(c3)
g.db.flush()
c4 = Comment(author_id=ZOZBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c3.id,
level=level+3,
is_bot=True,
body="zozzle",
body_html="<p>zozzle</p>",
top_comment_id=c.top_comment_id,
ghost=c.ghost,
distinguish_level=6
)
g.db.add(c4)
zozbot = get_account(ZOZBOT_ID)
zozbot.comment_count += 3
zozbot.coins += 3
g.db.add(zozbot)
if SITE_NAME == 'rDrama':
execute_longpostbot(c, level, body, body_html, parent_submission, v)
execute_zozbot(c, level, parent_submission, v)
if not v.shadowbanned:
notify_users = NOTIFY_USERS(body, v)
@ -600,17 +468,15 @@ def comment(v):
@limiter.limit("1/second;10/minute;100/hour;200/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
@auth_required
def edit_comment(cid, v):
c = get_comment(cid, v=v)
if time.time() - c.created_utc > 7*24*60*60 and not (c.post and c.post.private):
return {"error":"You can't edit comments older than 1 week!"}, 403
if c.author_id != v.id: abort(403)
if not c.post: abort(403)
body = request.values.get("body", "").strip().replace('โ€Ž','')
body = body.replace('\r\n', '\n')[:10000]
body = sanitize_raw_body(request.values.get("body", ""), False)
if len(body) < 1 and not (request.files.get("file") and request.headers.get("cf-ipcountry") != "T1"):
return {"error":"You have to actually type something!"}, 400
@ -674,8 +540,7 @@ def edit_comment(cid, v):
return {"error": "Too much spam!"}, 403
body += process_files()
body = body.strip()
body = body.strip()[:COMMENT_BODY_LENGTH_LIMIT] # process_files potentially adds characters to the post
body_for_sanitize = body
if v.owoify:
@ -687,12 +552,12 @@ def edit_comment(cid, v):
body_html = sanitize(body_for_sanitize, golden=False, limit_pings=5, torture=torture)
if len(body_html) > 20000: abort(400)
if len(body_html) > COMMENT_BODY_HTML_LENGTH_LIMIT: abort(400)
if v.marseyawarded and marseyaward_body_regex.search(body_html):
return {"error":"You can only type marseys!"}, 403
c.body = body[:10000]
c.body = body
c.body_html = body_html
if blackjack and any(i in c.body.lower() for i in blackjack.split()):

View File

@ -21,19 +21,21 @@ def join_discord(v):
@app.get("/discord_redirect")
@auth_required
@is_not_permabanned
def discord_redirect(v):
if v.shadowbanned: abort(400)
now = int(time.time())
state=request.values.get('state','').split('.')
state = request.values.get('state')
if not state or not '.' in state: abort(400)
state = state.split('.')
timestamp= state[0]
state= state[1]
try:
if int(timestamp) < now-600:
abort(400)
except:
abort(400)
if not validate_hash(f"{timestamp}+{v.id}+discord", state):
abort(400)

View File

@ -189,7 +189,7 @@ def random_post(v):
@app.get("/random_user")
@auth_required
def random_user(v):
u = g.db.query(User.username).filter(User.song != None).order_by(func.random()).first()
u = g.db.query(User.username).filter(User.song != None, User.shadowbanned == None).order_by(func.random()).first()
if u: u = u[0]
else: return "No users have set a profile anthem so far!"

View File

@ -353,7 +353,7 @@ def viewmore(v, pid, sort, offset):
@auth_desired_with_logingate
def morecomments(v, cid):
try: cid = int(cid)
except: abort(400)
except: abort(404)
tcid = g.db.query(Comment.top_comment_id).filter_by(id=cid).one_or_none()[0]
@ -412,8 +412,7 @@ def edit_post(pid, v):
abort(403)
title = sanitize_raw_title(request.values.get("title", ""))
body = sanitize_raw_body(request.values.get("body", ""))
body = sanitize_raw_body(request.values.get("body", ""), True)
if v.id == p.author_id:
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
@ -695,8 +694,7 @@ def submit_post(v, sub=None):
if '\\' in url: abort(400)
title = sanitize_raw_title(request.values.get("title", ""))
body = sanitize_raw_body(request.values.get("body", ""))
body = sanitize_raw_body(request.values.get("body", ""), True)
def error(error):
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": error}, 400
@ -909,7 +907,7 @@ def submit_post(v, sub=None):
if embed and len(embed) > 1500: embed = None
is_bot = v.id != 12125 and bool(request.headers.get("Authorization")) or (SITE == 'pcmemes.net' and v.id == SNAPPY_ID)
is_bot = v.id != BBBB_ID and bool(request.headers.get("Authorization")) or (SITE == 'pcmemes.net' and v.id == SNAPPY_ID)
if request.values.get("ghost") and v.coins >= 100:
v.coins -= 100

View File

@ -12,9 +12,6 @@ import tldextract
@is_not_permabanned
def exile_post(v, pid):
if v.shadowbanned: return {"error": "Internal Server Error"}, 500
try: pid = int(pid)
except: abort(400)
p = get_post(pid)
sub = p.sub
if not sub: abort(400)
@ -354,9 +351,6 @@ def create_sub2(v):
@app.post("/kick/<pid>")
@is_not_permabanned
def kick(v, pid):
try: pid = int(pid)
except: abort(400)
post = get_post(pid)
if not post.sub: abort(403)

View File

@ -21,10 +21,7 @@ import os
import json
from .login import check_for_alts
@app.get("/@<username>/upvoters/<uid>/posts")
@auth_required
def upvoters_posts(v, username, uid):
def upvoters_downvoters(v, username, uid, cls, vote_cls, vote_dir, template, standalone):
u = get_user(username, v=v, include_shadowbanned=False)
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)): abort(403)
if not (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']): abort(403)
@ -33,7 +30,7 @@ def upvoters_posts(v, username, uid):
page = max(1, int(request.values.get("page", 1)))
listing = g.db.query(Submission).join(Vote).filter(Submission.ghost == False, Submission.is_banned == False, Submission.deleted_utc == 0, Vote.vote_type==1, Submission.author_id==id, Vote.user_id==uid).order_by(Submission.created_utc.desc()).offset(25 * (page - 1)).limit(26).all()
listing = g.db.query(cls).join(vote_cls).filter(cls.ghost == False, cls.is_banned == False, cls.deleted_utc == 0, vote_cls.vote_type==vote_dir, cls.author_id==id, vote_cls.user_id==uid).order_by(cls.created_utc.desc()).offset(25 * (page - 1)).limit(26).all()
listing = [p.id for p in listing]
next_exists = len(listing) > 25
@ -41,56 +38,32 @@ def upvoters_posts(v, username, uid):
listing = get_posts(listing, v=v)
return render_template("voted_posts.html", next_exists=next_exists, listing=listing, page=page, v=v)
return render_template(template, next_exists=next_exists, listing=listing, page=page, v=v, standalone=standalone)
@app.get("/@<username>/upvoters/<uid>/posts")
@auth_required
def upvoters_posts(v, username, uid):
return upvoters_downvoters(v, username, uid, Submission, Vote, 1, "voted_posts.html", None)
@app.get("/@<username>/upvoters/<uid>/comments")
@auth_required
def upvoters_comments(v, username, uid):
u = get_user(username, v=v, include_shadowbanned=False)
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)): abort(403)
if not (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']): abort(403)
id = u.id
uid = int(uid)
page = max(1, int(request.values.get("page", 1)))
listing = g.db.query(Comment).join(CommentVote).filter(Comment.ghost == False, Comment.is_banned == False, Comment.deleted_utc == 0, CommentVote.vote_type==1, Comment.author_id==id, CommentVote.user_id==uid).order_by(Comment.id.desc()).offset(25 * (page - 1)).limit(26).all()
listing = [c.id for c in listing]
next_exists = len(listing) > 25
listing = listing[:25]
listing = get_comments(listing, v=v)
return render_template("voted_comments.html", next_exists=next_exists, listing=listing, page=page, v=v, standalone=True)
return upvoters_downvoters(v, username, uid, Comment, CommentVote, 1, "voted_comments.html", True)
@app.get("/@<username>/downvoters/<uid>/posts")
@auth_required
def downvoters_posts(v, username, uid):
u = get_user(username, v=v, include_shadowbanned=False)
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)): abort(403)
if not (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']): abort(403)
id = u.id
uid = int(uid)
page = max(1, int(request.values.get("page", 1)))
listing = g.db.query(Submission).join(Vote).filter(Submission.ghost == False, Submission.is_banned == False, Submission.deleted_utc == 0, Vote.vote_type==-1, Submission.author_id==id, Vote.user_id==uid).order_by(Submission.created_utc.desc()).offset(25 * (page - 1)).limit(26).all()
listing = [p.id for p in listing]
next_exists = len(listing) > 25
listing = listing[:25]
listing = get_posts(listing, v=v)
return render_template("voted_posts.html", next_exists=next_exists, listing=listing, page=page, v=v)
return upvoters_downvoters(v, username, uid, Submission, Vote, -1, "voted_posts.html", None)
@app.get("/@<username>/downvoters/<uid>/comments")
@auth_required
def downvoters_comments(v, username, uid):
return upvoters_downvoters(v, username, uid, Comment, CommentVote, -1, "voted_comments.html", True)
def upvoting_downvoting(v, username, uid, cls, vote_cls, vote_dir, template, standalone):
u = get_user(username, v=v, include_shadowbanned=False)
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)): abort(403)
if not (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']): abort(403)
@ -99,32 +72,7 @@ def downvoters_comments(v, username, uid):
page = max(1, int(request.values.get("page", 1)))
listing = g.db.query(Comment).join(CommentVote).filter(Comment.ghost == False, Comment.is_banned == False, Comment.deleted_utc == 0, CommentVote.vote_type==-1, Comment.author_id==id, CommentVote.user_id==uid).order_by(Comment.id.desc()).offset(25 * (page - 1)).limit(26).all()
listing = [c.id for c in listing]
next_exists = len(listing) > 25
listing = listing[:25]
listing = get_comments(listing, v=v)
return render_template("voted_comments.html", next_exists=next_exists, listing=listing, page=page, v=v, standalone=True)
@app.get("/@<username>/upvoting/<uid>/posts")
@auth_required
def upvoting_posts(v, username, uid):
u = get_user(username, v=v, include_shadowbanned=False)
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)): abort(403)
if not (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']): abort(403)
id = u.id
uid = int(uid)
page = max(1, int(request.values.get("page", 1)))
listing = g.db.query(Submission).join(Vote).filter(Submission.ghost == False, Submission.is_banned == False, Submission.deleted_utc == 0, Vote.vote_type==1, Vote.user_id==id, Submission.author_id==uid).order_by(Submission.created_utc.desc()).offset(25 * (page - 1)).limit(26).all()
listing = g.db.query(cls).join(vote_cls).filter(cls.ghost == False, cls.is_banned == False, cls.deleted_utc == 0, vote_cls.vote_type==vote_dir, vote_cls.user_id==id, cls.author_id==uid).order_by(cls.created_utc.desc()).offset(25 * (page - 1)).limit(26).all()
listing = [p.id for p in listing]
next_exists = len(listing) > 25
@ -132,125 +80,64 @@ def upvoting_posts(v, username, uid):
listing = get_posts(listing, v=v)
return render_template("voted_posts.html", next_exists=next_exists, listing=listing, page=page, v=v)
return render_template(template, next_exists=next_exists, listing=listing, page=page, v=v, standalone=standalone)
@app.get("/@<username>/upvoting/<uid>/posts")
@auth_required
def upvoting_posts(v, username, uid):
return upvoting_downvoting(v, username, uid, Submission, Vote, 1, "voted_posts.html", None)
@app.get("/@<username>/upvoting/<uid>/comments")
@auth_required
def upvoting_comments(v, username, uid):
u = get_user(username, v=v, include_shadowbanned=False)
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)): abort(403)
if not (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']): abort(403)
id = u.id
uid = int(uid)
page = max(1, int(request.values.get("page", 1)))
listing = g.db.query(Comment).join(CommentVote).filter(Comment.ghost == False, Comment.is_banned == False, Comment.deleted_utc == 0, CommentVote.vote_type==1, CommentVote.user_id==id, Comment.author_id==uid).order_by(Comment.id.desc()).offset(25 * (page - 1)).limit(26).all()
listing = [c.id for c in listing]
next_exists = len(listing) > 25
listing = listing[:25]
listing = get_comments(listing, v=v)
return render_template("voted_comments.html", next_exists=next_exists, listing=listing, page=page, v=v, standalone=True)
return upvoting_downvoting(v, username, uid, Comment, CommentVote, 1, "voted_comments.html", True)
@app.get("/@<username>/downvoting/<uid>/posts")
@auth_required
def downvoting_posts(v, username, uid):
u = get_user(username, v=v, include_shadowbanned=False)
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)): abort(403)
if not (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']): abort(403)
id = u.id
uid = int(uid)
page = max(1, int(request.values.get("page", 1)))
listing = g.db.query(Submission).join(Vote).filter(Submission.ghost == False, Submission.is_banned == False, Submission.deleted_utc == 0, Vote.vote_type==-1, Vote.user_id==id, Submission.author_id==uid).order_by(Submission.created_utc.desc()).offset(25 * (page - 1)).limit(26).all()
listing = [p.id for p in listing]
next_exists = len(listing) > 25
listing = listing[:25]
listing = get_posts(listing, v=v)
return render_template("voted_posts.html", next_exists=next_exists, listing=listing, page=page, v=v)
return upvoting_downvoting(v, username, uid, Submission, Vote, -1, "voted_posts.html", None)
@app.get("/@<username>/downvoting/<uid>/comments")
@auth_required
def downvoting_comments(v, username, uid):
u = get_user(username, v=v, include_shadowbanned=False)
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)): abort(403)
if not (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']): abort(403)
id = u.id
uid = int(uid)
return upvoting_downvoting(v, username, uid, Comment, CommentVote, -1, "voted_comments.html", True)
page = max(1, int(request.values.get("page", 1)))
listing = g.db.query(Comment).join(CommentVote).filter(Comment.ghost == False, Comment.is_banned == False, Comment.deleted_utc == 0, CommentVote.vote_type==-1, CommentVote.user_id==id, Comment.author_id==uid).order_by(Comment.id.desc()).offset(25 * (page - 1)).limit(26).all()
listing = [c.id for c in listing]
next_exists = len(listing) > 25
listing = listing[:25]
listing = get_comments(listing, v=v)
return render_template("voted_comments.html", next_exists=next_exists, listing=listing, page=page, v=v, standalone=True)
@app.get("/@<username>/upvoted/posts")
@auth_required
def user_upvoted_posts(v, username):
def user_voted(v, username, cls, vote_cls, vote_dir, template, standalone):
u = get_user(username, v=v, include_shadowbanned=False)
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)): abort(403)
if not (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']): abort(403)
page = max(1, int(request.values.get("page", 1)))
listing = g.db.query(Submission).join(Vote).filter(
Submission.ghost == False,
Submission.is_banned == False,
Submission.deleted_utc == 0,
Submission.author_id != u.id,
Vote.user_id == u.id,
Vote.vote_type == 1
).order_by(Submission.created_utc.desc()).offset(25 * (page - 1)).limit(26).all()
listing = g.db.query(cls).join(vote_cls).filter(
cls.ghost == False,
cls.is_banned == False,
cls.deleted_utc == 0,
cls.author_id != u.id,
vote_cls.user_id == u.id,
vote_cls.vote_type == vote_dir
).order_by(cls.created_utc.desc()).offset(25 * (page - 1)).limit(26).all()
listing = [p.id for p in listing]
next_exists = len(listing) > 25
listing = listing[:25]
listing = get_posts(listing, v=v)
return render_template("voted_posts.html", next_exists=next_exists, listing=listing, page=page, v=v)
return render_template(template, next_exists=next_exists, listing=listing, page=page, v=v, standalone=standalone)
@app.get("/@<username>/upvoted/posts")
@auth_required
def user_upvoted_posts(v, username):
return user_voted(v, username, Submission, Vote, 1, "voted_posts.html", None)
@app.get("/@<username>/upvoted/comments")
@auth_required
def user_upvoted_comments(v, username):
u = get_user(username, v=v, include_shadowbanned=False)
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)): abort(403)
if not (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']): abort(403)
page = max(1, int(request.values.get("page", 1)))
listing = g.db.query(Comment).join(CommentVote).filter(
Comment.ghost == False,
Comment.is_banned == False,
Comment.deleted_utc == 0,
Comment.author_id != u.id,
CommentVote.user_id == u.id,
CommentVote.vote_type == 1
).order_by(Comment.created_utc.desc()).offset(25 * (page - 1)).limit(26).all()
listing = [c.id for c in listing]
next_exists = len(listing) > 25
listing = listing[:25]
listing = get_comments(listing, v=v)
return render_template("voted_comments.html", next_exists=next_exists, listing=listing, page=page, v=v, standalone=True)
return user_voted(v, username, Comment, CommentVote, -1, "voted_comments.html", True)
@app.get("/poorcels")
@ -274,134 +161,70 @@ def agendaposters(v):
users = g.db.query(User).filter(User.agendaposter > 0).order_by(User.username).all()
return render_template("agendaposters.html", v=v, users=users)
def all_upvoters_downvoters(v, username, vote_dir, is_who_simps_hates):
vote_str = 'votes'
simps_haters = 'voters'
vote_name = 'Neutral'
if vote_dir == 1:
vote_str = 'upvotes'
simps_haters = 'simps for' if is_who_simps_hates else 'simps'
vote_name = 'Up'
elif vote_dir == -1:
vote_str = 'downvotes'
simps_haters = 'hates' if is_who_simps_hates else 'haters'
vote_name = 'Down'
id = get_user(username, v=v, include_shadowbanned=False).id
if not (v.id == id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']):
abort(403)
votes = []
votes2 = []
if is_who_simps_hates:
votes = g.db.query(Submission.author_id, func.count(Submission.author_id)).join(Vote).filter(Submission.ghost == False, Submission.is_banned == False, Submission.deleted_utc == 0, Vote.vote_type==vote_dir, Vote.user_id==id).group_by(Submission.author_id).order_by(func.count(Submission.author_id).desc()).all()
votes2 = g.db.query(Comment.author_id, func.count(Comment.author_id)).join(CommentVote).filter(Comment.ghost == False, Comment.is_banned == False, Comment.deleted_utc == 0, CommentVote.vote_type==vote_dir, CommentVote.user_id==id).group_by(Comment.author_id).order_by(func.count(Comment.author_id).desc()).all()
else:
votes = g.db.query(Vote.user_id, func.count(Vote.user_id)).join(Submission).filter(Submission.ghost == False, Submission.is_banned == False, Submission.deleted_utc == 0, Vote.vote_type==vote_dir, Submission.author_id==id).group_by(Vote.user_id).order_by(func.count(Vote.user_id).desc()).all()
votes2 = g.db.query(CommentVote.user_id, func.count(CommentVote.user_id)).join(Comment).filter(Comment.ghost == False, Comment.is_banned == False, Comment.deleted_utc == 0, CommentVote.vote_type==vote_dir, Comment.author_id==id).group_by(CommentVote.user_id).order_by(func.count(CommentVote.user_id).desc()).all()
votes = Counter(dict(votes)) + Counter(dict(votes2))
total = sum(votes.values())
users = g.db.query(User).filter(User.id.in_(votes.keys())).all()
users2 = []
for user in users:
users2.append((user, votes[user.id]))
users = sorted(users2, key=lambda x: x[1], reverse=True)
try:
pos = [x[0].id for x in users].index(v.id)
pos = (pos+1, users[pos][1])
except: pos = (len(users)+1, 0)
received_given = 'given' if is_who_simps_hates else 'received'
if total == 1: vote_str = vote_str[:-1] # we want to unpluralize if only 1 vote
total = f'{total} {vote_str} {received_given}'
name2 = f'Who @{username} {simps_haters}' if is_who_simps_hates else f'@{username} biggest {simps_haters}'
return render_template("voters.html", v=v, users=users[:25], pos=pos, name=vote_name, name2=name2, total=total)
@app.get("/@<username>/upvoters")
@auth_required
def upvoters(v, username):
id = get_user(username, v=v, include_shadowbanned=False).id
if not (v.id == id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']):
abort(403)
votes = g.db.query(Vote.user_id, func.count(Vote.user_id)).join(Submission).filter(Submission.ghost == False, Submission.is_banned == False, Submission.deleted_utc == 0, Vote.vote_type==1, Submission.author_id==id).group_by(Vote.user_id).order_by(func.count(Vote.user_id).desc()).all()
votes2 = g.db.query(CommentVote.user_id, func.count(CommentVote.user_id)).join(Comment).filter(Comment.ghost == False, Comment.is_banned == False, Comment.deleted_utc == 0, CommentVote.vote_type==1, Comment.author_id==id).group_by(CommentVote.user_id).order_by(func.count(CommentVote.user_id).desc()).all()
votes = Counter(dict(votes)) + Counter(dict(votes2))
total = sum(votes.values())
users = g.db.query(User).filter(User.id.in_(votes.keys())).all()
users2 = []
for user in users: users2.append((user, votes[user.id]))
users = sorted(users2, key=lambda x: x[1], reverse=True)
try:
pos = [x[0].id for x in users].index(v.id)
pos = (pos+1, users[pos][1])
except: pos = (len(users)+1, 0)
if total == 1: total=f'{total} upvote received'
else: total=f'{total} upvotes received'
return render_template("voters.html", v=v, users=users[:25], pos=pos, name='Up', name2=f'@{username} biggest simps', total=total)
return all_upvoters_downvoters(v, username, 1, False)
@app.get("/@<username>/downvoters")
@auth_required
def downvoters(v, username):
id = get_user(username, v=v, include_shadowbanned=False).id
if not (v.id == id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']):
abort(403)
votes = g.db.query(Vote.user_id, func.count(Vote.user_id)).join(Submission).filter(Submission.ghost == False, Submission.is_banned == False, Submission.deleted_utc == 0, Vote.vote_type==-1, Submission.author_id==id).group_by(Vote.user_id).order_by(func.count(Vote.user_id).desc()).all()
votes2 = g.db.query(CommentVote.user_id, func.count(CommentVote.user_id)).join(Comment).filter(Comment.ghost == False, Comment.is_banned == False, Comment.deleted_utc == 0, CommentVote.vote_type==-1, Comment.author_id==id).group_by(CommentVote.user_id).order_by(func.count(CommentVote.user_id).desc()).all()
votes = Counter(dict(votes)) + Counter(dict(votes2))
total = sum(votes.values())
users = g.db.query(User).filter(User.id.in_(votes.keys())).all()
users2 = []
for user in users: users2.append((user, votes[user.id]))
users = sorted(users2, key=lambda x: x[1], reverse=True)
try:
pos = [x[0].id for x in users].index(v.id)
pos = (pos+1, users[pos][1])
except: pos = (len(users)+1, 0)
if total == 1: total=f'{total} downvote received'
else: total=f'{total} downvotes received'
return render_template("voters.html", v=v, users=users[:25], pos=pos, name='Down', name2=f'@{username} biggest haters', total=total)
return all_upvoters_downvoters(v, username, -1, False)
@app.get("/@<username>/upvoting")
@auth_required
def upvoting(v, username):
id = get_user(username, v=v, include_shadowbanned=False).id
if not (v.id == id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']):
abort(403)
votes = g.db.query(Submission.author_id, func.count(Submission.author_id)).join(Vote).filter(Submission.ghost == False, Submission.is_banned == False, Submission.deleted_utc == 0, Vote.vote_type==1, Vote.user_id==id).group_by(Submission.author_id).order_by(func.count(Submission.author_id).desc()).all()
votes2 = g.db.query(Comment.author_id, func.count(Comment.author_id)).join(CommentVote).filter(Comment.ghost == False, Comment.is_banned == False, Comment.deleted_utc == 0, CommentVote.vote_type==1, CommentVote.user_id==id).group_by(Comment.author_id).order_by(func.count(Comment.author_id).desc()).all()
votes = Counter(dict(votes)) + Counter(dict(votes2))
total = sum(votes.values())
users = g.db.query(User).filter(User.id.in_(votes.keys())).all()
users2 = []
for user in users: users2.append((user, votes[user.id]))
users = sorted(users2, key=lambda x: x[1], reverse=True)
try:
pos = [x[0].id for x in users].index(v.id)
pos = (pos+1, users[pos][1])
except: pos = (len(users)+1, 0)
if total == 1: total=f'{total} upvote given'
else: total=f'{total} upvotes given'
return render_template("voters.html", v=v, users=users[:25], pos=pos, name='Up', name2=f'Who @{username} simps for', total=total)
return all_upvoters_downvoters(v, username, 1, True)
@app.get("/@<username>/downvoting")
@auth_required
def downvoting(v, username):
id = get_user(username, v=v, include_shadowbanned=False).id
if not (v.id == id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']):
abort(403)
votes = g.db.query(Submission.author_id, func.count(Submission.author_id)).join(Vote).filter(Submission.ghost == False, Submission.is_banned == False, Submission.deleted_utc == 0, Vote.vote_type==-1, Vote.user_id==id).group_by(Submission.author_id).order_by(func.count(Submission.author_id).desc()).all()
votes2 = g.db.query(Comment.author_id, func.count(Comment.author_id)).join(CommentVote).filter(Comment.ghost == False, Comment.is_banned == False, Comment.deleted_utc == 0, CommentVote.vote_type==-1, CommentVote.user_id==id).group_by(Comment.author_id).order_by(func.count(Comment.author_id).desc()).all()
votes = Counter(dict(votes)) + Counter(dict(votes2))
total = sum(votes.values())
users = g.db.query(User).filter(User.id.in_(votes.keys())).all()
users2 = []
for user in users: users2.append((user, votes[user.id]))
users = sorted(users2, key=lambda x: x[1], reverse=True)
try:
pos = [x[0].id for x in users].index(v.id)
pos = (pos+1, users[pos][1])
except: pos = (len(users)+1, 0)
if total == 1: total=f'{total} downvote given'
else: total=f'{total} downvotes given'
return render_template("voters.html", v=v, users=users[:25], pos=pos, name='Down', name2=f'Who @{username} hates', total=total)
return all_upvoters_downvoters(v, username, -1, True)
@app.post("/@<username>/suicide")
@limiter.limit("1/second;5/day")
@ -452,7 +275,7 @@ def transfer_coins(v, username):
notif_text = f":marseycapitalistmanlet: @{v.username} has gifted you {amount-tax} coins!"
if reason:
if len(reason) > 200: return {"error": "Reason is too long, max 200 characters"},400
if len(reason) > TRANSFER_MESSAGE_LENGTH_LIMIT: return {"error": f"Reason is too long, max {TRANSFER_MESSAGE_LENGTH_LIMIT} characters"},400
notif_text += f"\n\n> {reason}"
log_message += f"\n\n> {reason}"
@ -743,7 +566,7 @@ def message2(v, username):
@auth_required
def messagereply(v):
body = request.values.get("body", "").strip().replace('โ€Ž','')
body = body.replace('\r\n', '\n')[:10000]
body = body.replace('\r\n', '\n')[:COMMENT_BODY_LENGTH_LIMIT]
if not body and not request.files.get("file"): return {"error": "Message is empty!"}, 400
@ -1009,8 +832,6 @@ def u_username(username, v=None):
next_exists=next_exists,
is_following=is_following)
if request.headers.get("Authorization") or request.path.endswith(".json"):
return {"data": [x.json for x in listing]}

View File

@ -258,7 +258,7 @@
<img alt="/h/{{sub}} banner" onclick="expandDesktopImage()" src="{{sub.banner_url}}" width=100% style="object-fit:cover;max-height:min(42vh,30vw)!important">
</a>
{% elif SITE_NAME == 'rDrama' %}
<a href="https://secure.transequality.org/site/Donation2?df_id=1480">
<a rel="nofollow noopener noreferrer" href="https://secure.transequality.org/site/Donation2?df_id=1480">
{% if v and (v.is_banned or v.agendaposter) %}
<img alt="site banner" src="/i/{{SITE_NAME}}/banner2.webp?v=2000" width="100%">
{% else %}

View File

@ -11,11 +11,11 @@
<tbody>
<tr>
<td>Gumroad (subscription)</td>
<td><a href="{{GUMROAD_LINK}}">{{GUMROAD_LINK}}</a></td>
<td><a rel="nofollow noopener noreferrer" href="{{GUMROAD_LINK}}">{{GUMROAD_LINK}}</a></td>
</tr>
<tr>
<td>Gumroad (one-time)</td>
<td><a href="https://kippy.gumroad.com/l/onetime">https://kippy.gumroad.com/l/onetime</a></td>
<td><a rel="nofollow noopener noreferrer" href="https://kippy.gumroad.com/l/onetime">https://kippy.gumroad.com/l/onetime</a></td>
</tr>
<tr>
<td>Ethereum/Brave Attention Token</td>

View File

@ -11,7 +11,7 @@
<tbody>
<tr>
<td>Kofi</td>
<td><a href="{{KOFI_LINK}}">{{KOFI_LINK}}</a></td>
<td><a rel="nofollow noopener noreferrer" href="{{KOFI_LINK}}">{{KOFI_LINK}}</a></td>
</tr>
<tr>
<td>Ethereum/Brave Attention Token</td>

View File

@ -11,7 +11,7 @@
<tbody>
<tr>
<td>Gumroad</td>
<td><a href="{{GUMROAD_LINK}}">{{GUMROAD_LINK}}</a></td>
<td><a rel="nofollow noopener noreferrer" href="{{GUMROAD_LINK}}">{{GUMROAD_LINK}}</a></td>
</tr>
<tr>
<td>Ethereum/Brave Attention Token</td>
@ -27,11 +27,11 @@
</tr>
<tr>
<td>NFTs</td>
<td><a href="https://opensea.io/collection/marsey">https://opensea.io/collection/marsey</a></td>
<td><a rel="nofollow noopener noreferrer" href="https://opensea.io/collection/marsey">https://opensea.io/collection/marsey</a></td>
</tr>
<tr>
<td>Merch</td>
<td><a href="https://redbubble.com/people/rdramanet/explore?sortOrder=top%20selling">https://redbubble.com/people/rdramanet/explore?sortOrder=top%20selling</a></td>
<td><a rel="nofollow noopener noreferrer" href="https://redbubble.com/people/rdramanet/explore?sortOrder=top%20selling">https://redbubble.com/people/rdramanet/explore?sortOrder=top%20selling</a></td>
</tr>
</tbody>
</table>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="description" content="The true home of IP2." />
<meta name="description" content="rdrama.net caters to drama in all forms such as: Real life, videos, photos, gossip, rumors, news sites, Reddit, and Beyondโ„ข. There isn&#39;t drama we won&#39;t touch, and we want it all!" />
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' ajax.cloudflare.com; connect-src 'self'; object-src 'none';" />
@ -38,9 +38,9 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="thumbnail" content="/i/PCM/site_preview.webp?v=3009" />
<meta name="thumbnail" content="/i/rDrama/site_preview.webp?v=3009" />
<link rel="icon" type="image/webp" href="/i/PCM/icon.webp?v=3009" />
<link rel="icon" type="image/webp" href="/i/rDrama/icon.webp?v=3009" />
<title>502 Bad Gateway</title>
@ -49,58 +49,58 @@
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="apple-touch-icon" sizes="180x180" href="/i/PCM/icon.webp?v=3009" />
<link rel="manifest" href="/assets/manifest_PCM.json?v=6" />
<link rel="mask-icon" href="/i/PCM/icon.webp?v=3009" />
<link rel="shortcut icon" href="/i/PCM/icon.webp?v=3009" />
<meta name="apple-mobile-web-app-title" content="PCM" />
<meta name="application-name" content="PCM" />
<link rel="apple-touch-icon" sizes="180x180" href="/i/rDrama/icon.webp?v=3009" />
<link rel="manifest" href="/assets/manifest_rDrama.json?v=6" />
<link rel="mask-icon" href="/i/rDrama/icon.webp?v=3009" />
<link rel="shortcut icon" href="/i/rDrama/icon.webp?v=3009" />
<meta name="apple-mobile-web-app-title" content="rDrama" />
<meta name="application-name" content="rDrama" />
<meta name="msapplication-TileColor" content="#ff66ac" />
<meta name="msapplication-config" content="/assets/browserconfig.xml?v=3009" />
<meta name="theme-color" content="#ff66ac" />
<link rel="apple-touch-startup-image" sizes="320x480" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="640x960" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-icon" sizes="640x1136" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-icon" sizes="750x1334" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="768x1004" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="768x1024" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="828x1792" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1024x748" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1024x768" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1125x2436" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1242x2208" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1242x2688" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1334x750" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1536x2008" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1536x2048" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1668x2224" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1792x828" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2048x1496" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2048x1536" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2048x2732" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2208x1242" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2224x1668" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2436x1125" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2668x1242" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2737x2048" href="/i/PCM/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="320x480" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="640x960" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-icon" sizes="640x1136" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-icon" sizes="750x1334" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="768x1004" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="768x1024" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="828x1792" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1024x748" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1024x768" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1125x2436" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1242x2208" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1242x2688" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1334x750" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1536x2008" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1536x2048" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1668x2224" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="1792x828" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2048x1496" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2048x1536" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2048x2732" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2208x1242" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2224x1668" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2436x1125" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2668x1242" href="/i/rDrama/icon.webp?v=3009" />
<link rel="apple-touch-startup-image" sizes="2737x2048" href="/i/rDrama/icon.webp?v=3009" />
</head>
<body id="error-502">
<a href="https://secure.transequality.org/site/Donation2?df_id=1480">
<img alt="site banner" src="/i/PCM/cached.webp?v=3009" width="100%" />
<a rel="nofollow noopener noreferrer" href="https://secure.transequality.org/site/Donation2?df_id=1480">
<img alt="site banner" src="/i/rDrama/cached.webp?v=3009" width="100%" />
</a>
<nav class="shadow-md fixed-top">
<div class="navbar navbar-expand-md navbar-light" id="navbar">
<div class="container-fluid" style="padding: 0;">
<a href="/" class="navbar-brand mr-auto">
<img id="header--icon" alt="header icon" src="/i/PCM/headericon.webp?v=3009" />
<img id="header--icon" alt="header icon" src="/i/rDrama/headericon.webp?v=3009" />
</a>
<div id="logo-container" class="flex-grow-1 logo-container">
<a href="/">
<img class="ml-1" id="logo" alt="logo" src="/i/PCM/logo.webp?v=3009" width="70" />
<img class="ml-1" id="logo" alt="logo" src="/i/rDrama/logo.webp?v=3009" width="70" />
</a>
</div>

View File

@ -24,7 +24,7 @@
<td>{% include "user_in_table.html" %}</td>
<td {% if follow.created_utc > 1599343262 %}data-time="{{follow.created_utc}}"{% endif %}></td>
{% if v.id == u.id %}
<td><div class="btn btn-danger pr-2" onclick="removeFollower(event, '{{user.username}}')">Remove follow</div></td>
<td><div class="btn btn-danger pr-2" onclick="removeFollower(this, '{{user.username}}')">Remove follow</div></td>
{% endif %}
</tr>
{% endfor %}

View File

@ -22,7 +22,7 @@
<td>{{loop.index}}</td>
<td>{% include "user_in_table.html" %}</td>
{% if v.id == u.id %}
<td><div class="btn btn-danger" onclick="removeFollowing(event, '{{user.username}}')">Unfollow</div></td>
<td><div class="btn btn-danger" onclick="removeFollowing(this, '{{user.username}}')">Unfollow</div></td>
{% endif %}
</tr>
{% endfor %}

View File

@ -521,7 +521,7 @@ line breaks
This is a &lt;a href='https://www.w3schools.com/tags/tag_a.asp'&gt;link&lt;/a&gt;
</td>
<td>
This is a <a href='https://www.w3schools.com/tags/tag_a.asp'>link</a>
This is a <a rel="nofollow noopener noreferrer" href='https://www.w3schools.com/tags/tag_a.asp'>link</a>
</td>
</tr>
<tr>

View File

@ -253,8 +253,8 @@
<a class="dropdown-item" rel="nofollow noopener noreferrer" href="https://rdrama.net/post/18459"><i class="fas fa-bug fa-fw mr-3"></i>Bugs/Suggestions</a>
{% if SITE_NAME == 'rDrama' %}
<a class="dropdown-item" href="https://t.me/rdramanet"><i class="fab fa-telegram fa-fw mr-3"></i>Telegram Channel</a>
<a class="dropdown-item" href="https://t.me/+tOgq7xeeir83OTU0"><i class="fab fa-telegram fa-fw mr-3"></i>Telegram Chat</a>
<a rel="nofollow noopener noreferrer" class="dropdown-item" href="https://t.me/rdramanet"><i class="fab fa-telegram fa-fw mr-3"></i>Telegram Channel</a>
<a rel="nofollow noopener noreferrer" class="dropdown-item" href="https://t.me/+tOgq7xeeir83OTU0"><i class="fab fa-telegram fa-fw mr-3"></i>Telegram Chat</a>
<a class="dropdown-item" href="/discord"><i class="fab fa-discord fa-fw mr-3"></i>Discord</a>
{% endif %}
@ -319,8 +319,8 @@
<a class="nav-item nav-link" rel="nofollow noopener noreferrer" href="https://rdrama.net/post/18459"><i class="fas fa-bug fa-fw mr-3"></i>Bugs/Suggestions</a>
{% if SITE_NAME == 'rDrama' %}
<a class="nav-item nav-link" href="https://t.me/rdramanet"><i class="fab fa-telegram fa-fw mr-3"></i>Telegram Channel</a>
<a class="nav-item nav-link" href="https://t.me/+tOgq7xeeir83OTU0"><i class="fab fa-telegram fa-fw mr-3"></i>Telegram Chat</a>
<a rel="nofollow noopener noreferrer" class="nav-item nav-link" href="https://t.me/rdramanet"><i class="fab fa-telegram fa-fw mr-3"></i>Telegram Channel</a>
<a rel="nofollow noopener noreferrer" class="nav-item nav-link" href="https://t.me/+tOgq7xeeir83OTU0"><i class="fab fa-telegram fa-fw mr-3"></i>Telegram Chat</a>
<a class="nav-item nav-link" href="/discord"><i class="fab fa-discord fa-fw mr-3"></i>Discord</a>
{% endif %}

View File

@ -204,7 +204,7 @@
</style>
<div id="mobile-prompt-container" class="fixed-top">
<div id="mobile-prompt" href="javascript:void(0)" data-bs-toggle="tooltip" data-bs-container="#mobile-prompt-container" data-bs-placement="top" data-bs-trigger="click" data-bs-html="true" title="<i class='beg-icon fas fa-x'></i>Install the {{SITE_NAME}} webapp by saving this page to your home screen!"></div>
<div id="mobile-prompt" data-bs-toggle="tooltip" data-bs-container="#mobile-prompt-container" data-bs-placement="top" data-bs-trigger="click" data-bs-html="true" title="<i class='beg-icon fas fa-x'></i>Install the {{SITE_NAME}} webapp by saving this page to your home screen!"></div>
</div>
<script>
@ -213,7 +213,7 @@
document.addEventListener('DOMContentLoaded', function() {
const tt = bootstrap.Tooltip.getOrCreateInstance(document.getElementById('mobile-prompt'))
tt.show()
document.getElementsByClassName('tooltip')[0].onclick = function(event){
document.getElementsByClassName('tooltip')[0].onclick = function() {
tt.hide()
var xhr = new XMLHttpRequest();
xhr.withCredentials=true;

View File

@ -29,6 +29,6 @@ set JOURNOID_BANNERS = [
-%}
{% set journoid = JOURNOID_BANNERS|random %}
<a id="srd-link" href="{{ journoid[1] }}">{{ journoid[0] }}</a>
<a rel="nofollow noopener noreferrer" id="srd-link" href="{{journoid[1]}}">{{journoid[0]}}</a>
<span id="srd-separator">&mdash;</span>
<a id="srd-discuss" href="{{journoid[2]}}">(discuss)</a>

View File

@ -12,10 +12,13 @@
img.thumb {
border-radius: 4px;
}
.remove-streamer {
width: 50%
}
</style>
<script>
function go_to(e, link) {
if (!e.target.classList.contains('donttrigger'))
if (!e.target.classList.contains('remove-streamer'))
window.open(link, '_blank');
}
</script>
@ -59,7 +62,7 @@
<form action="/live/remove" method="post">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input type="hidden" name="id" value="{{id}}">
<input autocomplete="off" class="btn btn-primary ml-auto donttrigger" data-click="disable(this);this.parentElement.submit()" onclick="areyousure(this)" value="Remove">
<input autocomplete="off" class="btn btn-primary ml-auto remove-streamer" data-click="disable(this);this.parentElement.submit()" onclick="areyousure(this)" value="Remove">
</form>
</td>
{% endif %}
@ -84,7 +87,7 @@
<form action="/live/remove" method="post">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input type="hidden" name="id" value="{{id}}">
<input autocomplete="off" class="btn btn-primary ml-auto donttrigger" data-click="disable(this);this.parentElement.submit()" onclick="areyousure(this)" value="Remove">
<input autocomplete="off" class="btn btn-primary ml-auto remove-streamer" data-click="disable(this);this.parentElement.submit()" onclick="areyousure(this)" value="Remove">
</form>
</td>
{% endif %}

View File

@ -56,8 +56,8 @@
{% endif %}
{% if FEATURES['COUNTRY_CLUB'] and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or v.id == p.author_id) %}
<a id="club-{{p.id}}" class="dropdown-item {% if p.club %}d-none{% endif %} list-inline-item text-info" role="button" onclick="post_toast(this,'/toggle_club/{{p.id}}','club-{{p.id}}','unclub-{{p.id}}','d-none')"><i class="fas fa-eye-slash"></i>Mark club</a>
<a id="unclub-{{p.id}}" class="dropdown-item {% if not p.club %}d-none{% endif %} list-inline-item text-info" role="button" onclick="post_toast(this,'/toggle_club/{{p.id}}','club-{{p.id}}','unclub-{{p.id}}','d-none')"><i class="fas fa-eye"></i>Unmark club</a>
<a id="club-{{p.id}}" class="dropdown-item {% if p.club %}d-none{% endif %} list-inline-item text-info" role="button" onclick="post_toast(this,'/club_post/{{p.id}}','club-{{p.id}}','unclub-{{p.id}}','d-none')"><i class="fas fa-eye-slash"></i>Mark club</a>
<a id="unclub-{{p.id}}" class="dropdown-item {% if not p.club %}d-none{% endif %} list-inline-item text-info" role="button" onclick="post_toast(this,'/unclub_post/{{p.id}}','club-{{p.id}}','unclub-{{p.id}}','d-none')"><i class="fas fa-eye"></i>Unmark club</a>
{% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}

View File

@ -60,9 +60,9 @@
{% if FEATURES['PROCOINS'] %}
<span class="text-small text-muted pl-1">Must be same email as the one you used to donate on
{% if KOFI_TOKEN %}
<a class="text-primary" href="{{KOFI_LINK}}">Kofi</a>
<a rel="nofollow noopener noreferrer" class="text-primary" href="{{KOFI_LINK}}">Kofi</a>
{% else %}
<a class="text-primary" href="{{GUMROAD_LINK}}">Gumroad</a>
<a rel="nofollow noopener noreferrer" class="text-primary" href="{{GUMROAD_LINK}}">Gumroad</a>
{% endif %}
</span>
{% endif %}

View File

@ -29,11 +29,11 @@
<a class="btn btn-primary btn-block" href="/post/4103">BUGS/SUGGESTIONS MEGATHREAD</a>
<a class="btn btn-primary btn-block" href="/post/9694" >OFFICIAL CONSPIRACY THEORY THREAD</a>
<a class="btn btn-primary btn-block" href="/post/10415">OFFICIAL GAMBLING THREAD</a>
<a class="btn btn-primary btn-block" href="https://imgur.com/a/UFGJybS">PCM Watermark Collection</a>
<a class="btn btn-primary btn-block" href="https://imgur.com/a/HxBfECG">TRS</a>
<a class="btn btn-primary btn-block" href="https://imgur.com/a/Wkw11eX">Current RV Cutouts</a>
<a class="btn btn-primary btn-block" href="https://imgur.com/a/B3XHKnD">PCM Shitposter Cutouts (1/?)</a>
<a class="btn btn-primary btn-block" href="https://imgur.com/a/2wDZddF">PCM Shitposter Cutouts (2/?)</a>
<a rel="nofollow noopener noreferrer" class="btn btn-primary btn-block" href="https://imgur.com/a/UFGJybS">PCM Watermark Collection</a>
<a rel="nofollow noopener noreferrer" class="btn btn-primary btn-block" href="https://imgur.com/a/HxBfECG">TRS</a>
<a rel="nofollow noopener noreferrer" class="btn btn-primary btn-block" href="https://imgur.com/a/Wkw11eX">Current RV Cutouts</a>
<a rel="nofollow noopener noreferrer" class="btn btn-primary btn-block" href="https://imgur.com/a/B3XHKnD">PCM Shitposter Cutouts (1/?)</a>
<a rel="nofollow noopener noreferrer" class="btn btn-primary btn-block" href="https://imgur.com/a/2wDZddF">PCM Shitposter Cutouts (2/?)</a>
<p class="mt-4"> Rules: No doxing, No CP or other clearly illegal shit. Thanks.</p>
<p class="mt-4"> This website has nothing to do with Political Compass Memes.</p>

View File

@ -30,6 +30,8 @@
{% endblock %}
{% import 'userpage_admintools.html' as userpage_admintools with context %}
{% set hats_total = u.hats_owned_proportion_display[1] if u else 0 %}
{% set hats_owned_percent = u.hats_owned_proportion_display[0] if u else '' %}
{% block desktopUserBanner %}
@ -253,6 +255,7 @@
<p id="profile--info--spent">Coins spent: {{u.coins_spent}}</p>
<p id="profile--info--truescore">True score: {{u.truecoins}}</p>
<p id="profile--info--winnings">Winnings: {{u.winnings}}</p>
<p id="profile--info--hats-owned" {% if u.num_of_owned_hats == hats_total %}class="profile-owned-all-hats"{% endif %}>{{u.num_of_owned_hats}} / {{hats_total}} hats owned ({{hats_owned_percent}})</p>
{% if u.is_private %}
<p id="profile--info--private">User has private mode enabled</p>
{% endif %}
@ -294,7 +297,7 @@
<div class="container-fluid pb-0 text-center bg-white d-md-none" style="margin-top:-6px;border-radius:0!important;">
<div class="row">
<div class="col px-0">
<a href="{{u.banner_url}}">
<a rel="nofollow noopener noreferrer" href="{{u.banner_url}}">
<img alt="@{{u.username}}'s banner" onclick="expandDesktopImage()" loading="lazy" src="{{u.banner_url}}" width=100% style="object-fit:cover;max-height:30vh!important">
</a>
</div>
@ -496,6 +499,7 @@
<p id="profile-mobile--info--spent">Coins spent: {{u.coins_spent}}</p>
<p id="profile-mobile--info--truescore">True score: {{u.truecoins}}</p>
<p id="profile-mobile--info--winnings">Winnings: {{u.winnings}}</p>
<p id="profile-mobile--info--hats-owned" {% if u.num_of_owned_hats == hats_total %}class="profile-owned-all-hats"{% endif %}>{{u.num_of_owned_hats}} / {{hats_total}} hats owned ({{hats_owned_percent}})</p>
{% if u.is_private %}
<p id="profile-mobile--info--private">User has private mode enabled</p>
{% endif %}

View File

@ -23,10 +23,10 @@
{% macro userAdminToolsUpper(deviceType) %}
{% if v and v.id != u.id and v.admin_level >= PERMS['USER_MODERATION_TOOLS_VISIBLE'] %}
{% if v.admin_level >= PERMS['ADMIN_ADD'] and SITE != 'rdrama.net' %}
<a id="add-admin-{{deviceType}}" class="{% if u.admin_level >= PERMS['ADMIN_ADD_PERM_LEVEL'] %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast(this,'/@{{u.username}}/make_admin','add-admin-{{deviceType}}','remove-admin-{{deviceType}}','d-none')">Make admin</a>
<a id="add-admin-{{deviceType}}" class="{% if u.admin_level >= PERMS['ADMIN_ADD_PERM_LEVEL'] %}d-none{% endif %} btn btn-primary" onclick="post_toast(this,'/@{{u.username}}/make_admin','add-admin-{{deviceType}}','remove-admin-{{deviceType}}','d-none')">Make admin</a>
{% endif %}
{% if v.admin_level >= PERMS['ADMIN_REMOVE'] %}
<a id="remove-admin-{{deviceType}}" class="{% if u.admin_level < 1 %}d-none{% endif %} btn btn-danger" href="javascript:void(0)" onclick="post_toast(this,'/@{{u.username}}/remove_admin','add-admin-{{deviceType}}','remove-admin-{{deviceType}}','d-none')">Remove admin</a>
<a id="remove-admin-{{deviceType}}" class="{% if u.admin_level < 1 %}d-none{% endif %} btn btn-danger" onclick="post_toast(this,'/@{{u.username}}/remove_admin','add-admin-{{deviceType}}','remove-admin-{{deviceType}}','d-none')">Remove admin</a>
{% endif %}
{% if v.admin_level >= PERMS['ADMIN_ACTIONS_REVERT'] and u.admin_level %}
<a class="btn btn-danger" role="button" data-click="post_toast(this,'/@{{u.username}}/revert_actions')" onclick="areyousure(this)">Revert admin actions</a>

View File

@ -284,44 +284,50 @@ INSERT INTO public.hat_defs VALUES (723, 'Hohol', 'ะœั–ะน ะฟั€ะตะดะพะบ :)', 2, 5
INSERT INTO public.hat_defs VALUES (750, 'Cave Man', 'UNGA BUNGA UNGA BUNGA OOO OOO', 2, 500, NULL, 1664595865);
INSERT INTO public.hat_defs VALUES (753, 'Doom Guy', 'RIP AND TEAR', 2, 500, NULL, 1664595933);
INSERT INTO public.hat_defs VALUES (807, 'The Capy', 'You''re the chosen one! No one can hurt you!', 2, 500, NULL, 1665104052);
INSERT INTO public.hat_defs VALUES (92, 'Top Hat (black)', 'Traditional. Classy. Elegant.', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (714, 'Captain Falcon', 'The chad that every smash player wanted to imitate, if only his moveset included a shower.', 2, 500, NULL, 1663474615);
INSERT INTO public.hat_defs VALUES (715, 'Inspector Gadget', '"Go go Gadget Brown Bricks!"', 2, 500, NULL, 1663477536);
INSERT INTO public.hat_defs VALUES (724, 'Spartan Helmet', 'THIS IS SPARTA!', 2, 500, NULL, 1663892367);
INSERT INTO public.hat_defs VALUES (751, 'Butter', 'Southern-fried and full of love.', 2, 500, NULL, 1664595886);
INSERT INTO public.hat_defs VALUES (754, 'Crusader helmet', 'RETAKE THE HOLY LAND!', 2, 500, NULL, 1664595954);
INSERT INTO public.hat_defs VALUES (766, 'book', 'i can read! heheh', 2, 500, NULL, 1664645746);
INSERT INTO public.hat_defs VALUES (787, 'Turban', 'Turban with Bindi Dot (Namaste)', 2, 500, NULL, 1664980060);
INSERT INTO public.hat_defs VALUES (788, 'LGBTUSSR Officer Hat', 'Rule with an iron fist... And use that iron fist for more than ruling ;)', 2, 1000, NULL, 1664994148);
INSERT INTO public.hat_defs VALUES (808, 'The Capy 2', 'The drippiest and pimpiest capybara out there.', 2, 500, NULL, 1665104484);
INSERT INTO public.hat_defs VALUES (676, 'Kepi', 'Army cap for those unlucky enough to be French', 2, 500, NULL, 1663303083);
INSERT INTO public.hat_defs VALUES (678, 'Turkroach', 'Come on Carp this one''s hilarious. It''s semi transparent to clarify', 2, 500, NULL, 1663305640);
INSERT INTO public.hat_defs VALUES (679, 'Judge Dredd', 'THIS USER IS THE LAW', 2, 500, NULL, 1663309533);
INSERT INTO public.hat_defs VALUES (680, 'Hat Stack', 'You are as presumptuous as you are poor and Irish. Challenge not the majesty of my tower of hats.', 2, 500, NULL, 1663310312);
INSERT INTO public.hat_defs VALUES (809, 'Neon cat', 'Nya~ Nya for the neon cat!', 2, 500, NULL, 1665107083);
INSERT INTO public.hat_defs VALUES (813, 'Oni mask 1', 'A scary demonic spirit from japan!? Fucking weeb', 2, 500, NULL, 1665187283);
INSERT INTO public.hat_defs VALUES (814, 'Oni mask 2', 'Time to get funky, Japanese style.', 2, 500, NULL, 1665187310);
INSERT INTO public.hat_defs VALUES (684, 'cans dot wav', 'I am your host, the man they call Ghost.', 2, 500, NULL, 1663378616);
INSERT INTO public.hat_defs VALUES (685, 'The Lawlz II', 'Ben 10 aficionado and connoisseur.', 2, 500, NULL, 1663400628);
INSERT INTO public.hat_defs VALUES (815, 'Top Hat (WPD)', 'A trans-dimensional crossover hat from rDramaโ€™s much cooler big brother', 2, 500, NULL, 1665188158);
INSERT INTO public.hat_defs VALUES (686, 'Pingas', 'Snooping as usual, I see!', 2, 500, NULL, 1663400760);
INSERT INTO public.hat_defs VALUES (687, 'Robbie Rotten', 'Number one hairstyle!', 2, 500, NULL, 1663400876);
INSERT INTO public.hat_defs VALUES (688, 'Stephanie', 'I am not a creep. It was the third image result when I googled "Robbie Rotten hair png"', 2, 500, NULL, 1663400979);
INSERT INTO public.hat_defs VALUES (816, 'Impaled', 'Guess you''re not a vampire.', 2, 500, NULL, 1665188791);
INSERT INTO public.hat_defs VALUES (689, 'Sportacus', 'Official mascot of /h/fatpeoplehate', 2, 500, NULL, 1663401163);
INSERT INTO public.hat_defs VALUES (681, 'Avatar State', 'But when the world needed him most, the Dramatar vanished', 2, 500, NULL, 1663357705);
INSERT INTO public.hat_defs VALUES (682, 'Vampire Mask', 'Totally a current member of House Vampire', 2, 500, NULL, 1663368597);
INSERT INTO public.hat_defs VALUES (817, 'Cyborg', 'Hey do you know the terminator?', 2, 500, NULL, 1665188940);
INSERT INTO public.hat_defs VALUES (818, 'Jarhead', 'What every elden lord needs... A JAR', 2, 500, NULL, 1665189072);
INSERT INTO public.hat_defs VALUES (822, 'Spyglass', 'LAND HOEE', 2, 500, NULL, 1665189991);
INSERT INTO public.hat_defs VALUES (824, 'Hokage', 'You''re finally the HOKAGE!', 2, 500, NULL, 1665190384);
INSERT INTO public.hat_defs VALUES (825, 'Squash', 'Goofy ahh squash on your zombie head.', 2, 500, NULL, 1665190923);
INSERT INTO public.hat_defs VALUES (827, 'Dragon', 'The official hat for @RagnarDanneskjold! Vote Rangar for jannie 2022!', 2, 500, NULL, 1665197323);
INSERT INTO public.hat_defs VALUES (829, 'Femboy', 'Aww what a cute girl! ... Why does "she" have a dick', 2, 500, NULL, 1665255610);
INSERT INTO public.hat_defs VALUES (831, 'On fire', 'HOLY SHIT DUDE YOU''RE ON FIRE.', 2, 1000, NULL, 1665259064);
INSERT INTO public.hat_defs VALUES (832, 'Flowing Petals', 'You look so cute as the petals fall.', 2, 1000, NULL, 1665259202);
INSERT INTO public.hat_defs VALUES (833, 'Butterflies', 'You give me butterflies...', 2, 1000, NULL, 1665259809);
INSERT INTO public.hat_defs VALUES (834, 'Third Eyes', 'OPEN YOUR EYES SHEEPLE', 2, 1000, NULL, 1665259830);
INSERT INTO public.hat_defs VALUES (836, 'BUBBLES', 'AHHH YEAH LETS GOOO BUBBLE TIMES', 2, 1000, NULL, 1665259869);
INSERT INTO public.hat_defs VALUES (838, 'Bats', 'Closest you''ll ever be to batman.', 2, 1000, NULL, 1665260209);
INSERT INTO public.hat_defs VALUES (839, 'Confetti', 'WOOOO you must be special you have confetti!', 2, 1000, NULL, 1665260585);
INSERT INTO public.hat_defs VALUES (840, 'Crawling spider', 'AHHH SPIDER HIT IT', 2, 1000, NULL, 1665260749);
INSERT INTO public.hat_defs VALUES (842, 'Cursor', 'You should click this users profile!', 2, 1000, NULL, 1665260982);
INSERT INTO public.hat_defs VALUES (699, 'Gendo', '"Get in the fucking robot, Marsey."', 2, 500, NULL, 1663431457);
INSERT INTO public.hat_defs VALUES (698, 'Osama', 'Did you ever see that picture of the bin Laden family in the 70''s?', 2, 500, NULL, 1663431148);
INSERT INTO public.hat_defs VALUES (690, 'Dragon Ball Scouter', 'It''s Over 9000!', 2, 500, NULL, 1663428978);
@ -350,12 +356,17 @@ INSERT INTO public.hat_defs VALUES (9, 'Dreads', 'Finally, an excuse for poor hy
INSERT INTO public.hat_defs VALUES (10, 'The XXXTentacion', 'Pay homage to your favorite dead criminal!', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (12, 'The Elvis', 'Remember when this dude nailed a 13-year-old?', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (13, 'Gussy Hat', 'Let everyone know that you''re NOT a rapist. Honest.', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (830, 'Femboy hooters', 'Yes you ARE on the menu', 2, 500, NULL, 1665255628);
INSERT INTO public.hat_defs VALUES (835, 'Rain', 'It''s a sad rainy day', 2, 1000, NULL, 1665259850);
INSERT INTO public.hat_defs VALUES (837, 'Aura (blue)', 'Such power!', 2, 1000, NULL, 1665259885);
INSERT INTO public.hat_defs VALUES (14, 'Riveter', 'Can you do it? Really?', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (15, 'Top Hat (leprechaun)', 'LLM but Irish', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (843, 'Pet Snek', 'This user has a pet snek', 2, 1000, NULL, 1665261142);
INSERT INTO public.hat_defs VALUES (16, 'Drinky Beer Hat', 'I actually didn''t know these were real things until I made this', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (844, 'Snek Peek', 'When the friendly snek sees over your head', 2, 500, NULL, 1665261263);
INSERT INTO public.hat_defs VALUES (17, 'Viking', 'Rape, pillage, never bathe. Live the dream.', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (532, 'Under His Eye', 'WATCH ANOTHER SHOW', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (845, 'Loading', 'please wait', 2, 1000, NULL, 1665261780);
INSERT INTO public.hat_defs VALUES (22, 'Southern Gentleman', 'Slaveowner? Fried chicken chain founder? You decide!', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (23, 'Cowboy I', 'Make him wish he could quit you', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (24, 'Cowboy II', 'You''re my favorite deputy!', 2, 500, NULL, 1662167687);
@ -363,11 +374,16 @@ INSERT INTO public.hat_defs VALUES (25, 'Halo', 'Dramamine criticized this one a
INSERT INTO public.hat_defs VALUES (26, 'Fedora I', 'M''arsey', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (27, 'Bowler', 'Why would you need a hat to go bowling?', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (28, 'Du Rag (black)', 'Shitty bandana 1/6', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (848, 'Music Notes', 'LALALA LA LA', 2, 1000, NULL, 1665262588);
INSERT INTO public.hat_defs VALUES (849, 'Cloudy', 'What a cloudy day.', 2, 1000, NULL, 1665263018);
INSERT INTO public.hat_defs VALUES (850, 'TREX', 'RAWRRRRRRRRRRRRr', 2, 500, NULL, 1665268343);
INSERT INTO public.hat_defs VALUES (29, 'Du Rag (red)', 'Shitty bandana 2/6', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (30, 'Du Rag (blue)', 'Shitty bandana 3/6', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (31, 'Du Rag (purple)', 'Shitty bandana 4/6', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (32, 'Du Rag (green)', 'Shitty bandana 5/6', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (851, 'Dr Pepper', 'The best soda as a hat!', 2, 500, NULL, 1665268361);
INSERT INTO public.hat_defs VALUES (33, 'Du Rag (yellow)', 'Shitty bandana 6/6', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (852, 'Pikmin leaf', 'A classic of the wii you''re now a pikmin!', 2, 500, NULL, 1665268398);
INSERT INTO public.hat_defs VALUES (34, 'Ash Ketchum', 'You''re not so different, you and he', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (35, 'The Hotep', 'Traditional kangwear. POC ONLY.', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (36, 'Roman', 'Reddit delenda est', 2, 500, NULL, 1662167687);
@ -422,8 +438,21 @@ INSERT INTO public.hat_defs VALUES (85, 'Carls Jr', 'Purveyor of literally the f
INSERT INTO public.hat_defs VALUES (86, 'Whataburger', 'Texans don''t know any better', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (87, 'Five Guys', 'I love having 5 guys in my mouth', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (88, 'Taco Bell', 'Enabler of drunken mistakes', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (854, 'Cute Spider', 'My friend Heather calls them web friends', 2, 500, NULL, 1665268447);
INSERT INTO public.hat_defs VALUES (859, 'Freddy Krueger', 'Haunt other people''s nightmares and dreams!', 2, 500, NULL, 1665269059);
INSERT INTO public.hat_defs VALUES (860, 'Turkey Turkey', '๐Ÿฆƒ gobble gobble gobble gobble ๐Ÿฆƒ', 2, 500, NULL, 1665269774);
INSERT INTO public.hat_defs VALUES (862, 'Predator', 'Not the reddit sort', 2, 500, NULL, 1665269828);
INSERT INTO public.hat_defs VALUES (864, 'Predator II', 'Suck that face faggot', 2, 500, NULL, 1665269878);
INSERT INTO public.hat_defs VALUES (870, 'Windmill', 'Why is there a windmill on your head-', 2, 500, NULL, 1665272605);
INSERT INTO public.hat_defs VALUES (869, 'Fluffy Marsey', 'AAAAAHHHHHH LOOK HOW CUTE', 2, 500, NULL, 1665272581);
INSERT INTO public.hat_defs VALUES (89, 'Marsey-In-A-Box', 'Awww you''re playing make-believe!', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (90, 'Orthodox Hood', 'User is a schismatic lunatic', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (853, 'Crab head', '๐Ÿฆ€๐Ÿฆ€๐Ÿฆ€๐Ÿฆ€๐Ÿฆ€๐Ÿฆ€๐Ÿฆ€๐Ÿฆ€๐Ÿฆ€', 2, 500, NULL, 1665268419);
INSERT INTO public.hat_defs VALUES (861, 'Bowl Cut', 'Who cut your hair? Your mom?', 2, 500, NULL, 1665269794);
INSERT INTO public.hat_defs VALUES (866, 'Venom Mask', 'PUT THE TOUNGUE AWAY', 2, 500, NULL, 1665272503);
INSERT INTO public.hat_defs VALUES (871, 'Kirby Beanie', 'Be careful he''ll swallow you', 2, 500, NULL, 1665272632);
INSERT INTO public.hat_defs VALUES (872, 'Pinwheels', 'Holland hat holland hat', 2, 1000, NULL, 1665272653);
INSERT INTO public.hat_defs VALUES (631, 'Country Club Visor', 'What country club members wear when discussing your reddit account', 2, 500, NULL, 1663033011);
INSERT INTO public.hat_defs VALUES (632, 'Jotaro Hat', 'The iconic cap of a buff punchy weebshit guy', 2, 500, NULL, 1663033206);
INSERT INTO public.hat_defs VALUES (629, 'Marisas Big Witch Hat', 'Fascism is when witches wear big hats, the bigger the hat the more fascist you are.', 2, 500, NULL, 1663010108);
@ -439,12 +468,14 @@ INSERT INTO public.hat_defs VALUES (644, 'Poppy', 'The TRUE rDrama mascot', 2, 5
INSERT INTO public.hat_defs VALUES (645, 'The SRDine', 'CANNED', 2, 500, NULL, 1663132545);
INSERT INTO public.hat_defs VALUES (646, 'Turtle Helmet', 'u/awkwardtheturtle is VERY mad at you', 2, 500, NULL, 1663132947);
INSERT INTO public.hat_defs VALUES (648, 'Diamond Helmet', 'So I did some mining off camera...', 2, 500, NULL, 1663133082);
INSERT INTO public.hat_defs VALUES (873, 'Jaws', 'AHH WATCH OUT BELOW YOU', 2, 500, NULL, 1665272685);
INSERT INTO public.hat_defs VALUES (91, 'Afro', 'Pool''s closed motherlover', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (18, 'Nonspecific Military Officer Hat', '[removed]', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (19, 'Soviet Officer I', 'OUR hat', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (408, 'Chef Hat II', 'Toque blanche', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (414, 'Trilby', '*tip*', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (419, 'Alimony Hair', 'Stay norwooding, king', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (874, 'Carp', 'My 100th hat and a Thank you to carp. Now 150 more!', 2, 500, NULL, 1665272718);
INSERT INTO public.hat_defs VALUES (93, 'Wizard I', 'Three decades a KHHV', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (94, 'Wizard II', 'Avada kedavra โœจ', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (95, 'Witch I', 'Hex the patriarchy', 2, 500, NULL, 1662167687);
@ -594,6 +625,9 @@ INSERT INTO public.hat_defs VALUES (542, 'Link (Faces of Evil)', 'Could you eat
INSERT INTO public.hat_defs VALUES (406, 'Amogus', 'I saw you vent', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (415, 'WANTED', 'Dangerous thought criminal. Wanted DEAD ONLY.', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (421, 'Emperor Hat', 'Made in China', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (877, 'Reaper Hood I', 'Spooooooky!', 2, 500, NULL, 1665314511);
INSERT INTO public.hat_defs VALUES (878, 'Reaper Hood II', 'Now with scythe!', 2, 500, NULL, 1665314534);
INSERT INTO public.hat_defs VALUES (397, 'Funko Pop', '...and then he turned himself into Funko Pop. Funniest shit I ever saw.', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (668, 'Maxwell Hat', 'Scribblethot', 2, 500, NULL, 1663279953);
INSERT INTO public.hat_defs VALUES (543, 'Harkinian (Faces of Evil)', 'Marsey mah boy', 2, 500, NULL, 1662167687);
@ -671,6 +705,17 @@ INSERT INTO public.hat_defs VALUES (537, 'The Celtic Kufi', 'Irish were the REAL
INSERT INTO public.hat_defs VALUES (549, 'The Bumper Sticker', 'Turn yourself into a legal liability that could threaten the very site itself!', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (571, 'Purple Emoji Crown', '๐Ÿ’œ๐Ÿ’œ๐Ÿ’œwhen ur selfie needs an emoji crown with a ๐ŸŒป, a ๐Ÿ‘ป, and a ๐Ÿป but u still gotta fit that purple aesthetic ๐Ÿ’œ๐Ÿ’œ๐Ÿ’œ', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (570, 'Carl', 'based and dramapilled llama', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (828, 'monopoly thimbler', 'Even thimblier than the last one', 2, 500, NULL, 1665250441);
INSERT INTO public.hat_defs VALUES (846, 'Twinkle', 'TWINKle', 2, 1000, NULL, 1665261883);
INSERT INTO public.hat_defs VALUES (875, 'Aces Strawhat', 'Idfk what this is man why are you submitting these esoteric fucking hats with no indication of what they are AAAHHHHH', 2, 500, NULL, 1665314089);
INSERT INTO public.hat_defs VALUES (531, 'Zen', 'follow the fish follow the fish follow the fish follow the fish follow the fish', 2, 1000, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (612, 'Wizard Hat (pixel)', 'Some sort of vidya thing idfk', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (614, 'Chickenhead', '๐Ÿค—', 2, 500, NULL, 1662167687);
@ -735,6 +780,9 @@ INSERT INTO public.hat_defs VALUES (284, 'The Gary Plauche', 'We can''t expect G
INSERT INTO public.hat_defs VALUES (292, 'Marsey Smug Mask', 'I''m not seething, you''re seething', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (295, 'Pinkhat', 'It''s a hat and it''s pink and your nan looks adorable in it. Not you, though.', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (400, 'Current Thing (support)', 'Slava Ukraini!', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (847, 'Flaming Sword', '??????????', 2, 1000, NULL, 1665262102);
INSERT INTO public.hat_defs VALUES (310, 'Bandit Bandana', 'This thread ain''t big enough fer the of us', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (327, 'Ageplayer', 'It''s cool if it''s not your thing, just don''t yuck someone else''s yum :)', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (312, 'Super Saiyan', 'Taqueria โ€˜Goku''', 2, 1000, NULL, 1662167687);
@ -814,6 +862,7 @@ INSERT INTO public.hat_defs VALUES (386, 'Curts New Hat', 'Have you *seen* it?',
INSERT INTO public.hat_defs VALUES (387, 'Gray Cowl of Nocturnal', 'Capital!', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (388, 'Tricorne', 'This hat is for TRUE AMERICAN PATRIOTS only', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (404, 'Knight Helmet', 'kNIGht ๐Ÿค—', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (352, 'John Deere Hat', 'She (male) thinks my tractor''s sexy', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (355, 'Chef Hat', 'Cloudflare just bent the knee and I''m nauseated and don''t feel like writing descriptions for hats sorry', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (392, 'Chris-Chan', 'Hat to the extreme!', 2, 500, NULL, 1662167687);
@ -825,6 +874,27 @@ INSERT INTO public.hat_defs VALUES (422, 'Booba', 'O_O', 2, 500, NULL, 166216768
INSERT INTO public.hat_defs VALUES (409, 'AI Core', 'Thought this said AL Core for a minute like Al gore but no it''s ai like the robot thing and apparently it''s from a vidya so here we go description done ๐ŸคŒ', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (424, 'Pearl Clutcher', 'REEEEEEEEEEEEEEEEE', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (462, 'Rasta Hat', 'Jah bless', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (398, 'The Catman', 'This counts as a fursuit', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (401, 'Current Thing (oppose)', 'Denazify Ukraine!', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (402, 'T-34 Tank', 'For denazification purposes', 2, 500, NULL, 1662167687);
@ -952,11 +1022,13 @@ INSERT INTO public.hat_defs VALUES (501, 'Dancing Marsey', 'Omg she''s so happy
INSERT INTO public.hat_defs VALUES (504, 'Iron Crown of Lombardy', 'This isn''t Crusader Kings, stop it', 2, 500, NULL, 1662167687);
--
-- Name: hat_defs_id_seq; Type: SEQUENCE SET; Schema: public; Owner: -
--
SELECT pg_catalog.setval('public.hat_defs_id_seq', 827, true);
SELECT pg_catalog.setval('public.hat_defs_id_seq', 916, true);
--
@ -1148,6 +1220,7 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseyblackcop',2,'police officer acab thin blue line pig bipoc',NULL),
('marseyblackface',2,'moon cricket jogger nigger racism coon racist minstrelsy jigaboo',NULL),
('marseyblackfacexmas',2,'uncle tom moon cricket christmas santa beard nigger racist claus coon',NULL),
('marseyblackgenocide',2,'racist bipoc ni kkk hitler kang kween tariq',1665366740),
('marseyblackmage',2,'magic wizard final fantasy spell video game vidya evil',NULL),
('marseyblind',2,'sight stick disability blind glasses disabled handicapped',NULL),
('marseyblm',2,'social justice black lives matter sjw',NULL),
@ -1385,6 +1458,7 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseycool2',2,'cigarette hip shades sunglasses jacket smoking smoke',NULL),
('marseycoomer',2,'masturbation goon cumbrain porn masturbate',NULL),
('marseycoomer2',2,'gooning masturbation fapping cumming gooner nofap',NULL),
('marseycoomer3',2,'coomer cumming masturbation blueballed',1665238828),
('marseycoonass',2,'student lsu university louisana state',NULL),
('marseycop',2,'acab thin blue line chauvin police officer',NULL),
('marseycop2',2,'police officer acab thin blue line pig',NULL),
@ -1403,6 +1477,7 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseycow',2,'cow fursona skin animal costume furry heifer fursuit',NULL),
('marseycowboy',2,'western pardner reaction hat tootin yeehaw rootin',NULL),
('marseycracka',2,'mayo honkey honky whip buckbreaker buckbreaking whip slaves cotton plantation white nigger master',NULL),
('marseycrayfish',2,'crawfish lobster crustacean water swamp bayou south america usa food animal tasty',1665361807),
('marseycreepy',2,'pervert pedophile weird reaction chomo creeper sketchy molester',NULL),
('marseycringe',2,'pepe frog',NULL),
('marseycringe2',2,'grimace grimacing yikes oof bruh moment',NULL),
@ -1435,10 +1510,12 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseydagothur2',2,'elder scrolls morrowind game mask dagothur',NULL),
('marseydamosuzuki',2,'damo suzuki musician music singer krautrock asian japan germany celebrity',NULL),
('marseydance',2,'excited stomp jump feet step run animated',NULL),
('marseydarkbrandon',2,'biden lasereyes gas sticker evil confused dementia daddy',1665323885),
('marseydarkcarp',2,'lasereyes carpathianflorist fish admin jannie mod banned yalled',1663211530),
('marseydarkcomrade',2,'communist commie pinko lasereyes russian kgb hat soviet ussr tankie',1663254781),
('marseydarkmarsey2',2,'lasereyes redglow scary chudrama',NULL),
('marseydarkpizzashill',2,'chud rightoid leftoid debate owned lasereyes footlocker',1663210672),
('marseydarktrump',2,'maga lasereyes chud republican orange daddy donald',1665323820),
('marseydarkxd',2,'laugh ragecomics lmao despair shadow',NULL),
('marseydarwin',2,'history darwinian euphoric atheist charles',NULL),
('marseydawnbreaker',2,'gamer video game warhammer',NULL),
@ -1749,6 +1826,7 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseyicecream',2,'ice cream sad disappoint pout cry.',NULL),
('marseyicecreamcone',2,'sweet dessert dairy',1663284406),
('marseyidio3',2,'idio3 russia belarus communist commie flask drink computer online monitor display keyboard idio',NULL),
('marseyidk',2,'what weird cringe',1665254242),
('marseyill',2,'winter chilly cold ill sick brr flu',NULL),
('marseyilluminati',2,'eye egypt pyramid big brother watching',NULL),
('marseyilluminati2',2,'eye egypt pyramid big brother watching',NULL),
@ -1861,6 +1939,7 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseyleafeon',2,'trick or treat pokemon halloween eevee costume holiday',NULL),
('marseyleftoidschizo',2,'sjw shitlib radlib liberal cuck redditor soy crazy animated',NULL),
('marseylegion',2,'zombie wolf fallout new vegas fnv caesar courier video game roman',NULL),
('marseylego',2,'marsey lego toy game',1665356921),
('marseylemon',2,'pucker sour lemon fruit citrus tear ',NULL),
('marseylenin',2,'ussr russia communism socialism marxist commie soviet proletariat marxism marxist leninist leninism revolution bolshevik',NULL),
('marseylenny',2,'innuendo dirty sex horny emoticon perverted',NULL),
@ -2013,6 +2092,7 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseyniqab',2,'burka islam muslim burqa',NULL),
('marseyniqabpearlclutch',2,'bombasticpussy sjw snowflake burka burqa',1663350191),
('marseyno',2,'denied refuse rejection reaction ugh deny hand',NULL),
('marseynodox',2,'sign',1665250355),
('marseynooo',2,'reaction snob no way',NULL),
('marseynoooticer',2,'notice stats racist iq chud bigot numbers observe see hmm wrong think thonk',1664406781),
('marseynope',2,'bush grass simpsons homer hide avoid',1663895054),
@ -2401,6 +2481,7 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseysmug4',2,'confident emoticon plain simple smile',1664490741),
('marseysmugautist',2,'autism retard brainlet drool hat',NULL),
('marseysmugretard',2,'srdine drooling brainlet idiot fool buffoon idiot',NULL),
('marseysmugsideeyes',2,'marsey smug',1665254121),
('marseysnap',2,'mad angry furious anger animated snap',NULL),
('marseysnappyautism',2,'snapshillbot hat neurodivergent robot autistic marppy',NULL),
('marseysnappyhug',2,'hug love robot sentient wholesome',1664490893),
@ -2436,6 +2517,8 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseysoylentgrin',2,'numale nu male menslib redditor plebbitor happy glasses soyjak nerd loser beta smile smiling',NULL),
('marseysoypoint',2,'soyboy soy boy beard reaction pointing',NULL),
('marseysoypoint2',2,'wojak soyjak soyjack pointing beta redditors',NULL),
('marseysoypointglow',2,'glowie radioactive pointing',1665352060),
('marseysoypointgold',2,'glow wave',1665351969),
('marseysoyrope',2,'redditor dead suicide kms kys hanging lynched hung soyjak',NULL),
('marseysoyseethe',2,'soyjack soyjak reddit angry yelling wojak',NULL),
('marseyspa',2,'spa towel cucumber facial relax calm selfcare foid hygiene beauty',NULL),
@ -2635,6 +2718,7 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseywholesome',2,'seal award reddit tene',NULL),
('marseywinemom',2,'drunk wine aunt flirt cigarette drunk lush elfbinn fartbinn cougar',NULL),
('marseywink',2,'wink reaction cheeky flirt smirk imply hint',NULL),
('marseywink2',2,'winking',1665254177),
('marseywinner',2,'reaction trophy gold prize first place',NULL),
('marseywise',2,'hood cloak wizard pipe',NULL),
('marseywitch',2,'spooky halloween magick holiday evil scary',NULL),

View File

@ -1807,7 +1807,7 @@ Removed. Ben garrison's "humor" seldom reaches escape velocity. This agendapost
{[para]}
Sunday was her first date with another guy. I felt so happy for her. And tonight she had sex with him. I was more nervous of what my reaction would be afterwords. But when she came home those worries melted away. It felt great to bask in her glow. I am overflowing with joy. There will be work to be done and not easy time but man. This feels good. I'm so excited for this new journey and chapter in our lives.
{[para]}
<a href=https://poal.co/s/conspiracy/423007/522d8f88-641d-431c-85e4-6eff94fe57ef#cmnts>rdrama is exactly what it sounds like. Their goal is to make it so that no one has fun, and they will gladly groom your children and prolapse their anus to do so. They get away with everything they do by bullshitting about non-existent irony and their trolling is considered low-effort to its core.</a>
[rdrama is exactly what it sounds like. Their goal is to make it so that no one has fun, and they will gladly groom your children and prolapse their anus to do so. They get away with everything they do by bullshitting about non-existent irony and their trolling is considered low-effort to its core.](https://poal.co/s/conspiracy/423007/522d8f88-641d-431c-85e4-6eff94fe57ef#cmnts)
{[para]}
I was dating this young, fit, hot girl with a sunny disposition. Then I found out she's only been to 2 continents...and she only has her BA. Like one single BA. I threw up in my fucking mouth and left. I didn't even bother to grab my Naruto backpack.
{[para]}
@ -1843,7 +1843,7 @@ OP is not homosexual. Any comment claiming that he is in a non-opinion way will
{[para]}
Everything I've told you is true, and backed by the experts. I have no mistake to admit here. At this point, I'm convinced you're just trolling; and I'm no longer engaging you.
{[para]}
<B>Watching and reading about Bardfinn made me change my life</B>
**Watching and reading about Bardfinn made me change my life**
I've been in a rut for the past few years because of a bereavement. Finished college but didn't get a job for a few years. I found some joy in communities like r/drama because they reminded me of shit like 4chan and hackforums from back in the day.
But one day I was reading a comment by Bardfinn, clicked on his profile and it really made me want to change my life. I saw the next decades of my life flash before my eyes. Smugposting and bullying people who deserve it, but while not improving myself, gradually falling in to bad habits leading to me spending 18 hours a day in front of a computer before dying of DVT. I saw what Bardfinn did with his life and how he's now stuck in it. He won't get a job or ever pay child support because he's stuck in this life and constantly needs to justify it to himself. He's too invested in it to care about anything else. He unironically bragged about spending 80+ hour weeks 'fighting Nazis'. There is no hope for him.
But there was hope for me, and maybe for you too, reader.
@ -1857,7 +1857,7 @@ I went on rdrama.net hoping to show them that LGBT people aren't all the wholeso
{[para]}
If I ran into this dude, first thought would be to GTFO. I have no desire to blown to smithereens if he disagrees with my sandwich topping choices. Second thought would be what is he over compensating for? Is his ego (and various other parts of him) really that tiny and fragile?
{[para]}
None of us have ever actually given two shits about FDA approval, we only brought it up because, in your state of mind trusting government authority, <B>it should have been important to you.</B>
None of us have ever actually given two shits about FDA approval, we only brought it up because, in your state of mind trusting government authority, **it should have been important to you.**
It's like you all believing in Santa, and we're trying to tell you he's not real, you can know because you never see him. Now one Christmas eve, you're 40 years old, and come up to peek and see, just in case, Santa might be real. And there he is! He's real! You flock to /r/conspiracy, to tell us we were wrong, but it was your wife's boyfriend all along!
{[para]}
Bitch bye ๐Ÿ˜‚๐Ÿ˜‚๐Ÿ˜‚๐Ÿ˜‚ what's cringe is you stereotyping everyone on the planet who smokes weed. The only person here who's awkward, boring, lame and living in a haze here is you buddy. As someone who smokes weed everyday, I love doing things while smoking weed. Whether it be hiking, yoga, working out, studying or reading a book. On top of all of that, I have my own business and I'm getting a degree in Kinesiology. ๐Ÿ˜‚๐Ÿ˜‚๐Ÿ˜‚ also, getting realizations are fun. Maybe you should smoke some weed one day so you can realize how you're projecting your own cringe personality on the rest of your pothead โ€œfriends.โ€
@ -2067,7 +2067,7 @@ wow! nobody gives a fuck about your feelings and why should they? I dont care ab
{[para]}
Literally call your ISP and ask them to disconnect your internet, retard faggot. You're nothing but a shallow, fragile, inbred, nigger, communist, ass pirate. You enjoy sexual stimulation via rectal penetration. You belong in a zoo. You fantasise over the day a gorilla will rape you. Why don't you provide anything of value to anyone around you? It's because your hands are black, negroid.
{[para]}
<h1>NIGGER</h1>
# NIGGER
{[para]}
fuck you stupid fucking nigger faggot eat shit and die kys
{[para]}