Merge branch 'frost' of https://github.com/Aevann1/rDrama into frost
|
@ -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;
|
||||
}
|
||||
|
|
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 9.8 KiB |
After Width: | Height: | Size: 9.6 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 8.5 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 9.6 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 124 KiB |
After Width: | Height: | Size: 157 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 108 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 173 KiB |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 209 KiB |
After Width: | Height: | Size: 914 B |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.3 KiB |
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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("𒐪","")
|
||||
|
|
|
@ -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()):
|
||||
|
@ -163,13 +155,14 @@ def comment(v):
|
|||
level = parent.level + 1
|
||||
if parent.author_id == v.id: rts = True
|
||||
else: abort(400)
|
||||
|
||||
|
||||
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()):
|
||||
|
|
|
@ -21,18 +21,20 @@ 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')
|
||||
if not state or not '.' in state: abort(400)
|
||||
state = state.split('.')
|
||||
timestamp= state[0]
|
||||
state= state[1]
|
||||
|
||||
|
||||
now=int(time.time())
|
||||
state=request.values.get('state','').split('.')
|
||||
|
||||
timestamp=state[0]
|
||||
|
||||
state=state[1]
|
||||
|
||||
if int(timestamp) < now-600:
|
||||
try:
|
||||
if int(timestamp) < now-600:
|
||||
abort(400)
|
||||
except:
|
||||
abort(400)
|
||||
|
||||
if not validate_hash(f"{timestamp}+{v.id}+discord", state):
|
||||
|
|
|
@ -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!"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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]}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
<h4>Configuration</h4>
|
||||
<ul>
|
||||
{% if v.admin_level >= PERMS['HOLE_CREATE'] %}
|
||||
<li><a href="/create_hole">Create {{ HOLE_NAME | capitalize }}</a></li>
|
||||
<li><a href="/create_hole">Create {{HOLE_NAME | capitalize}}</a></li>
|
||||
{% endif %}
|
||||
{% if v.admin_level >= PERMS['APPS_MODERATION'] %}
|
||||
<li><a href="/admin/apps">Apps</a></li>
|
||||
|
@ -150,7 +150,7 @@
|
|||
|
||||
<h4>Server Status</h4>
|
||||
<div>
|
||||
Live Revision: <code>{{ gitref }}</code> <br>
|
||||
Live Revision: <code>{{gitref}}</code> <br>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
</td>
|
||||
<td>{{badge.description}}</td>
|
||||
{%- set ct = counts[badge.id] if badge.id in counts else (0, 0) %}
|
||||
<td class="badges-rarity-qty"><a href="/badge_owners/{{badge.id}}">{{ ct[0] }}</a></td>
|
||||
<td class="badges-rarity-ratio">{{ "{:0.3f}".format(ct[1]) }}%</td>
|
||||
<td class="badges-rarity-qty"><a href="/badge_owners/{{badge.id}}">{{ct[0]}}</a></td>
|
||||
<td class="badges-rarity-ratio">{{"{:0.3f}".format(ct[1])}}%</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
@ -41,4 +41,4 @@
|
|||
|
||||
<script defer src="{{'js/sort_table.js' | asset}}"></script>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -138,7 +138,7 @@
|
|||
{% if c.bannedfor %}
|
||||
<i class="fas fa-hammer-crash text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User was banned for this comment {{c.bannedfor}}"></i>
|
||||
{% endif %}
|
||||
{% if c.active_flags(v) %}<a class="btn btn-primary" style="padding:1px 5px; font-size:10px"role="button" onclick="document.getElementById('flaggers-{{c.id}}').classList.toggle('d-none')">{{c.active_flags(v)}} Report{{ help.plural(c.active_flags(v)) }}</a>{% endif %}
|
||||
{% if c.active_flags(v) %}<a class="btn btn-primary" style="padding:1px 5px; font-size:10px"role="button" onclick="document.getElementById('flaggers-{{c.id}}').classList.toggle('d-none')">{{c.active_flags(v)}} Report{{help.plural(c.active_flags(v))}}</a>{% endif %}
|
||||
{% if c.over_18 %}<span class="badge badge-danger text-small-extra mr-1">+18</span>{% endif %}
|
||||
{% if v and v.admin_level >= PERMS['USER_SHADOWBAN'] and c.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title='Shadowbanned by @{{c.author.shadowbanned}} for "{{c.author.ban_reason}}"'></i>{% endif %}
|
||||
{% if c.stickied %}
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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>
|
||||
|
@ -28,4 +28,4 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -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>
|
||||
|
@ -28,4 +28,4 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -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,13 +27,13 @@
|
|||
</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>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -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't drama we won'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>
|
||||
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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 %}
|
||||
|
@ -31,4 +31,4 @@
|
|||
|
||||
<script defer src="{{'js/following.js' | asset}}"></script>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -521,7 +521,7 @@ line breaks
|
|||
This is a <a href='https://www.w3schools.com/tags/tag_a.asp'>link</a>
|
||||
</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>
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
' throwing shade right now',
|
||||
]
|
||||
-%}
|
||||
{{g.loggedin_counter+g.loggedout_counter}} {{ VISITORS_HERE_FLAVOR|random|safe }} ({{ g.loggedin_counter }} logged in)
|
||||
{{g.loggedin_counter+g.loggedout_counter}} {{VISITORS_HERE_FLAVOR|random|safe}} ({{g.loggedin_counter}} logged in)
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{g.loggedin_counter+g.loggedout_counter}} people here now ({{g.loggedin_counter}} logged in)
|
||||
|
@ -225,7 +225,7 @@
|
|||
</div>
|
||||
<div class="text-left pl-2">
|
||||
<div style="color: #{{v.name_color}}" class="text-small font-weight-bold"><span id="header--username" {% if v.patron %}class="patron" style="background-color:#{{v.name_color}}"{% endif %}>{{v.user_name}}</span></div>
|
||||
<div class="header--currency"><img alt="coins" class="mr-1 ml-1" data-bs-toggle="tooltip" data-bs-placement="bottom" src="{{'coins.webp' | asset_siteimg}}" title="coins" aria-label="coins"><span id="user-coins-amount">{{v.coins}}</span>{% if not FEATURES['PROCOINS'] %} Coin{{ help.plural(v.coins) }}{% endif %}</div>
|
||||
<div class="header--currency"><img alt="coins" class="mr-1 ml-1" data-bs-toggle="tooltip" data-bs-placement="bottom" src="{{'coins.webp' | asset_siteimg}}" title="coins" aria-label="coins"><span id="user-coins-amount">{{v.coins}}</span>{% if not FEATURES['PROCOINS'] %} Coin{{help.plural(v.coins)}}{% endif %}</div>
|
||||
{% if FEATURES['PROCOINS'] %}
|
||||
<div class="header--currency"><img alt="marseybux" class="mr-1 ml-1" data-bs-toggle="tooltip" data-bs-placement="bottom" src="/i/marseybux.webp?v=2000" title="Marseybux" aria-label="Marseybux"><span id="user-bux-amount">{{v.procoins}}</span></div>
|
||||
{% endif %}
|
||||
|
@ -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 %}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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">—</span>
|
||||
<a id="srd-discuss" href="{{ journoid[2] }}">(discuss)</a>
|
||||
<a id="srd-discuss" href="{{journoid[2]}}">(discuss)</a>
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<td>
|
||||
<img class="contain" alt="2{{user.patron}}" loading="lazy" width=29.33 height=32 src="/i/{{SITE_NAME}}/patron_badges/2{{user.patron}}.webp?v=1">
|
||||
{% if user.patron_utc %}
|
||||
<i class="{{ benefactor_def['icon'] }} {{ benefactor_def['color'] }} px-1"></i>
|
||||
<i class="{{benefactor_def['icon']}} {{benefactor_def['color']}} px-1"></i>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -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'] %}
|
||||
|
|
|
@ -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 %}
|
||||
|
@ -275,4 +275,4 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
@ -48,4 +48,4 @@
|
|||
<img class="mb-4" alt="sidebar image" onclick="expandDesktopImage()" loading="lazy" src="{{image}}" width=100%>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
{% if error %}
|
||||
<p class="mb-0">
|
||||
<span class="text-danger text-small" style="vertical-align: sub;">{{ error }}</span>
|
||||
<span class="text-danger text-small" style="vertical-align: sub;">{{error}}</span>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
|
@ -59,4 +59,4 @@
|
|||
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|