remotes/1693045480750635534/spooky-22
Aevann1 2022-03-09 03:44:53 +02:00
parent 89b1f5abf7
commit 514d6ec126
19 changed files with 111 additions and 110 deletions

View File

@ -477,11 +477,15 @@ class User(Base):
@property
@lazy
def profile_url(self):
if self.agendaposter: return f"{SITE_FULL}/static/assets/images/defaultpictures/agendaposter/{random.randint(1, 51)}.webp?v=1008"
if self.agendaposter: return f"/e/marseychud.webp"
if self.profileurl:
if self.profileurl.startswith('/'): return SITE_FULL + self.profileurl
return self.profileurl
if SITE_NAME == 'Drama': return f"{SITE_FULL}/static/assets/images/defaultpictures/{random.randint(1, 150)}.webp?v=1008"
if SITE_NAME == 'Drama':
self.profileurl = '/e/' + random.choice(marseys_const) + '.webp'
g.db.add(self)
g.db.commit()
return self.profileurl
return f"{SITE_FULL}/static/assets/images/default-profile-pic.webp?v=1008"
@lazy

View File

@ -128,7 +128,7 @@ if SITE in {'rdrama.net','devrama.xyz'}:
A_ID = 1230
KIPPY_ID = 7150
TAX_NOTIF_ID = 995
GIFT_NOTIF_ID = 995
PIZZASHILL_ID = 2424
HIL_ID = 4245
CRAT_ID = 747
@ -160,7 +160,7 @@ elif SITE == "pcmemes.net":
A_ID = 0
KIPPY_ID = 1592
PIZZASHILL_ID = 0
TAX_NOTIF_ID = 1592
GIFT_NOTIF_ID = 1592
HIL_ID = 0
CRAT_ID = 0
IDIO_ID = 0
@ -190,7 +190,7 @@ else:
A_ID = 0
KIPPY_ID = 0
TAX_NOTIF_ID = 9
GIFT_NOTIF_ID = 9
PIZZASHILL_ID = 0
HIL_ID = 0
CRAT_ID = 0
@ -634,7 +634,8 @@ dues = int(environ.get("DUES").strip())
christian_emojis = (':#marseyjesus:',':#marseyimmaculate:',':#marseymothermary:',':#marseyfatherjoseph:',':#gigachadorthodox:',':#marseyorthodox:',':#marseyorthodoxpat:')
db = db_session()
marseys_const = [x[0] for x in db.query(Marsey.name).all()] + ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','exclamationpoint','period','questionmark']
marseys_const = [x[0] for x in db.query(Marsey.name).filter(Marsey.name!='marseychud').all()]
marseys_const2 = marseys_const + ['marseychud','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','exclamationpoint','period','questionmark']
db.close()
if SITE_NAME == 'PCM':
@ -648,9 +649,11 @@ else:
valid_password_regex = re.compile("^.{8,100}$", flags=re.A)
marsey_regex = re.compile("^(:[!#A-Za-z0-9]{1,30}?:\s*)+$", flags=re.A)
marseyaward_body_regex = re.compile(">[^<\s+]|[^>\s+]<", flags=re.A)
marsey_regex2 = re.compile("[a-z0-9]{1,30}", flags=re.A)
marseyaward_title_regex = re.compile("(<img[^>]+>)+", flags=re.A)
marsey_regex = re.compile("[a-z0-9]{1,30}", flags=re.A)
image_regex = re.compile("(^https:\/\/.*\.(png|jpg|jpeg|gif|webp|maxwidth=9999|fidelity=high)($|\s))", flags=re.I|re.M|re.A)
@ -715,4 +718,6 @@ def torture_ap(body, username):
body = torture_regex2.sub(rf'\1@{username} is ', body)
return body
YOUTUBE_KEY = environ.get("YOUTUBE_KEY", "").strip()
YOUTUBE_KEY = environ.get("YOUTUBE_KEY", "").strip()
ADMIGGERS = (37696,37697,37749,37833,37838)

View File

@ -16,4 +16,4 @@ def post_embed(id, v):
@app.context_processor
def inject_constants():
return {"environ":environ, "SITE":SITE, "SITE_NAME":SITE_NAME, "SITE_FULL":SITE_FULL, "AUTOJANNY_ID":AUTOJANNY_ID, "NOTIFICATIONS_ID":NOTIFICATIONS_ID, "PUSHER_ID":PUSHER_ID, "CC":CC, "CC_TITLE":CC_TITLE, "listdir":listdir, "MOOSE_ID":MOOSE_ID, "AEVANN_ID":AEVANN_ID, "config":app.config.get, "DEFAULT_COLOR":DEFAULT_COLOR, "COLORS":COLORS}
return {"environ":environ, "SITE":SITE, "SITE_NAME":SITE_NAME, "SITE_FULL":SITE_FULL, "AUTOJANNY_ID":AUTOJANNY_ID, "NOTIFICATIONS_ID":NOTIFICATIONS_ID, "PUSHER_ID":PUSHER_ID, "CC":CC, "CC_TITLE":CC_TITLE, "listdir":listdir, "MOOSE_ID":MOOSE_ID, "AEVANN_ID":AEVANN_ID, "config":app.config.get, "DEFAULT_COLOR":DEFAULT_COLOR, "COLORS":COLORS, "ADMIGGERS":ADMIGGERS}

View File

@ -233,9 +233,9 @@ def sanitize(sanitized, noimages=False, alert=False, comment=False, edit=False):
classes = 'emoji-md'
remoji = emoji
if not edit and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const): classes += ' golden'
if not edit and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const2): classes += ' golden'
if remoji == 'marseyrandom': remoji = choice(marseys_const)
if remoji == 'marseyrandom': remoji = choice(marseys_const2)
if path.isfile(f'files/assets/images/emojis/{remoji}.webp'):
new = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}:" title=":{emoji}:" class="{classes}" src="/e/{remoji}.webp">', new, flags=re.I|re.A)
@ -255,10 +255,10 @@ def sanitize(sanitized, noimages=False, alert=False, comment=False, edit=False):
if emoji.startswith("!"):
emoji = emoji[1:]
classes = 'emoji mirrored'
if not edit and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const): classes += ' golden'
if not edit and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const2): classes += ' golden'
old = emoji
if emoji == 'marseyrandom': emoji = choice(marseys_const)
if emoji == 'marseyrandom': emoji = choice(marseys_const2)
else: emoji = old
if path.isfile(f'files/assets/images/emojis/{emoji}.webp'):
@ -266,10 +266,10 @@ def sanitize(sanitized, noimages=False, alert=False, comment=False, edit=False):
if comment: marseys_used.add(emoji)
else:
classes = 'emoji'
if not edit and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const): classes += ' golden'
if not edit and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const2): classes += ' golden'
old = emoji
if emoji == 'marseyrandom': emoji = choice(marseys_const)
if emoji == 'marseyrandom': emoji = choice(marseys_const2)
else: emoji = old
if path.isfile(f'files/assets/images/emojis/{emoji}.webp'):
@ -345,10 +345,10 @@ def filter_emojis_only(title, edit=False, graceful=False):
if emoji.startswith("!"):
emoji = emoji[1:]
classes = 'emoji mirrored'
if not edit and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const): classes += ' golden'
if not edit and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const2): classes += ' golden'
old = emoji
if emoji == 'marseyrandom': emoji = choice(marseys_const)
if emoji == 'marseyrandom': emoji = choice(marseys_const2)
else: emoji = old
if path.isfile(f'files/assets/images/emojis/{emoji}.webp'):
@ -356,10 +356,10 @@ def filter_emojis_only(title, edit=False, graceful=False):
else:
classes = 'emoji'
if not edit and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const): classes += ' golden'
if not edit and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const2): classes += ' golden'
old = emoji
if emoji == 'marseyrandom': emoji = choice(marseys_const)
if emoji == 'marseyrandom': emoji = choice(marseys_const2)
else: emoji = old
if path.isfile(f'files/assets/images/emojis/{emoji}.webp'):

View File

@ -260,7 +260,7 @@ def award_post(pid, v):
author.ban_reason = f"grass award used by @{v.username} on /post/{post.id}"
author.unban_utc = int(time.time()) + 30 * 86400
link = f"[this post]({post.shortlink})"
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 to get unbanned!")
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!")
elif kind == "pin":
if post.stickied and post.stickied_utc:
post.stickied_utc += 3600
@ -486,7 +486,7 @@ def award_comment(cid, v):
author.ban_reason = f"grass award used by @{v.username} on /comment/{c.id}"
author.unban_utc = int(time.time()) + 30 * 86400
link = f"[this comment]({c.shortlink})"
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 to get unbanned!")
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!")
elif kind == "pin":
if c.is_pinned and c.is_pinned_utc: c.is_pinned_utc += 3600
else:

View File

@ -210,10 +210,7 @@ def api_comment(v):
with open(f"snappy_{SITE_NAME}.txt", "a", encoding="utf-8") as f:
f.write('\n{[para]}\n' + body)
if v.marseyawarded and parent_post.id not in (37696,37697,37749,37833,37838):
if not marsey_regex.fullmatch(body): return {"error":"You can only type marseys!"}, 403
if parent_post.id not in (37696,37697,37749,37833,37838):
if parent_post.id not in ADMIGGERS:
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
return {"error":"You have to type more than 280 characters!"}, 403
elif v.bird and len(body) > 140:
@ -272,7 +269,7 @@ def api_comment(v):
marsey = loads(body.lower())
name = marsey["name"]
if not marsey_regex2.fullmatch(name):
if not marsey_regex.fullmatch(name):
return {"error": "Invalid name!"}, 403
if "author" in marsey: user = get_user(marsey["author"])
@ -332,7 +329,7 @@ def api_comment(v):
body += f"\n\n{url}"
else: return {"error": "Image/Video files only"}, 400
if v.agendaposter and not v.marseyawarded and parent_post.id not in (37696,37697,37749,37833,37838):
if v.agendaposter and not v.marseyawarded and parent_post.id not in ADMIGGERS:
body = torture_ap(body, v.username)
if '#fortune' in body:
@ -341,6 +338,9 @@ def api_comment(v):
body_html = sanitize(body, comment=True)
if v.marseyawarded and parent_post.id not in ADMIGGERS and marseyaward_body_regex.search(body_html):
return {"error":"You can only type marseys!"}, 403
bans = filter_comment_html(body_html)
if bans:
@ -349,7 +349,7 @@ def api_comment(v):
if ban.reason: reason += f" {ban.reason}"
return {"error": reason}, 401
if parent_post.id not in (37696,37697,37749,37833,37838) and '!slots' not in body.lower() and '!blackjack' not in body.lower() and '!wordle' not in body.lower() and AGENDAPOSTER_PHRASE not in body.lower():
if parent_post.id not in ADMIGGERS and '!slots' not in body.lower() and '!blackjack' not in body.lower() and '!wordle' not in body.lower() and AGENDAPOSTER_PHRASE not in body.lower():
existing = g.db.query(Comment.id).filter(Comment.author_id == v.id,
Comment.deleted_utc == 0,
Comment.parent_comment_id == parent_comment_id,
@ -363,7 +363,7 @@ def api_comment(v):
is_bot = bool(request.headers.get("Authorization"))
if '!slots' not in body.lower() and '!blackjack' not in body.lower() and '!wordle' not in body.lower() and parent_post.id not in (37696,37697,37749,37833,37838) and not is_bot and not v.marseyawarded and AGENDAPOSTER_PHRASE not in body.lower() and len(body) > 10:
if '!slots' not in body.lower() and '!blackjack' not in body.lower() and '!wordle' not in body.lower() and parent_post.id not in ADMIGGERS and not is_bot and not v.marseyawarded and AGENDAPOSTER_PHRASE not in body.lower() and len(body) > 10:
now = int(time.time())
cutoff = now - 60 * 60 * 24
@ -477,7 +477,7 @@ def api_comment(v):
n = Notification(comment_id=c_based.id, user_id=v.id)
g.db.add(n)
if parent_post.id not in (37696,37697,37749,37833,37838):
if parent_post.id not in ADMIGGERS:
if v.agendaposter and not v.marseyawarded and AGENDAPOSTER_PHRASE not in c.body.lower():
c.is_banned = True
@ -717,9 +717,6 @@ def edit_comment(cid, v):
return {"error":"You have to actually type something!"}, 400
if body != c.body or request.files.get("file") and request.headers.get("cf-ipcountry") != "T1":
if v.marseyawarded and not marsey_regex.fullmatch(body):
return {"error":"You can only type marseys!"}, 403
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
return {"error":"You have to type more than 280 characters!"}, 403
elif v.bird and len(body) > 140:
@ -821,6 +818,9 @@ def edit_comment(cid, v):
body_html = sanitize(body, edit=True)
if v.marseyawarded and marseyaward_body_regex.search(body_html):
return {"error":"You can only type marseys!"}, 403
if len(body_html) > 20000: abort(400)
c.body = body[:10000]
@ -927,7 +927,8 @@ def pin_comment(cid, v):
if not comment.is_pinned:
if v.id != comment.post.author_id: abort(403)
comment.is_pinned = v.username + " (OP)"
if comment.post.ghost: comment.is_pinned = "(OP)"
else: comment.is_pinned = v.username + " (OP)"
g.db.add(comment)

View File

@ -367,7 +367,7 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, ccmode="false"
elif v.subs == 3:
pins = pins.filter(Submission.sub.in_(v.subbed_subs))
elif v.subs == 4:
pins = pins.filter(Submission.sub.notin_(v.all_blocks))
pins = pins.filter(Submission.sub != None, Submission.sub.notin_(v.all_blocks))
if v and v.admin_level < 2:
pins = pins.filter(Submission.author_id.notin_(v.userblocks))

View File

@ -330,6 +330,8 @@ def sign_up_post(v):
session["history"] = []
else: admin_level=0
profileurl = '/e/' + random.choice(marseys_const) + '.webp'
new_user = User(
username=username,
original_username = username,
@ -337,7 +339,8 @@ def sign_up_post(v):
password=request.values.get("password"),
email=email,
referred_by=ref_id or None,
ban_evade = int(any((x.is_banned or x.shadowbanned) and not x.unban_utc for x in g.db.query(User).filter(User.id.in_(session.get("history", []))).all() if x))
ban_evade = int(any((x.is_banned or x.shadowbanned) and not x.unban_utc for x in g.db.query(User).filter(User.id.in_(session.get("history", []))).all() if x)),
profileurl=profileurl
)
g.db.add(new_user)

View File

@ -20,12 +20,12 @@ import requests
from shutil import copyfile
from sys import stdout
marseys = [f':#{x}:' for x in marseys_const]
marseys = [f':#{x}:' for x in marseys_const2]
if path.exists(f'snappy_{SITE_NAME}.txt'):
with open(f'snappy_{SITE_NAME}.txt', "r", encoding="utf-8") as f:
if SITE == 'pcmemes.net': snappyquotes = f.read().split("{[para]}")
else: snappyquotes = [f.read().split("\n{[para]}\n")] + marseys
else: snappyquotes = f.read().split("\n{[para]}\n") + marseys
else: snappyquotes = marseys
IMGUR_KEY = environ.get("IMGUR_KEY").strip()
@ -464,9 +464,6 @@ def edit_post(pid, v):
if len(body) > 20000: return {"error":"Character limit is 20000!"}, 403
if v.marseyawarded and (not marsey_regex.fullmatch(title) or body and not marsey_regex.fullmatch(body)):
return {"error":"You can only type marseys!"}, 403
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
return {"error":"You have to type more than 280 characters!"}, 403
elif v.bird and len(body) > 140:
@ -476,6 +473,10 @@ def edit_post(pid, v):
if v.agendaposter and not v.marseyawarded: title = torture_ap(title, v.username)
title_html = filter_emojis_only(title, edit=True)
if v.marseyawarded and not marseyaward_title_regex.fullmatch(title_html):
return {"error":"You can only type marseys!"}, 403
p.title = title[:500]
p.title_html = title_html
@ -527,6 +528,9 @@ def edit_post(pid, v):
body_html = sanitize(body, edit=True)
if v.marseyawarded and marseyaward_body_regex.search(body_html):
return {"error":"You can only type marseys!"}, 403
bans = filter_comment_html(body_html)
if bans:
ban = bans[0]
@ -844,6 +848,10 @@ def submit_post(v, sub=None):
if v.agendaposter and not v.marseyawarded: title = torture_ap(title, v.username)
title_html = filter_emojis_only(title, graceful=True)
if v.marseyawarded and not marseyaward_title_regex.fullmatch(title_html):
return {"error":"You can only type marseys!"}, 403
if len(title_html) > 1500: return error("Rendered title is too big!")
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
@ -940,9 +948,6 @@ def submit_post(v, sub=None):
elif len(title) > 500:
return error("There's a 500 character limit for titles.")
if v.marseyawarded and (not marsey_regex.fullmatch(title) or body and not marsey_regex.fullmatch(body)):
return error("You can only type marseys!")
dup = g.db.query(Submission).filter(
Submission.author_id == v.id,
Submission.deleted_utc == 0,
@ -1046,6 +1051,9 @@ def submit_post(v, sub=None):
body_html = sanitize(body)
if v.marseyawarded and marseyaward_body_regex.search(body_html):
return {"error":"You can only type marseys!"}, 403
if len(body_html) > 40000: return error("Submission body too long!")
bans = filter_comment_html(body_html)

View File

@ -82,33 +82,6 @@ def exile_post(v, pid):
@app.post("/unexile/post/<pid>")
@is_not_permabanned
def unexile_post(v, pid):
try: pid = int(pid)
except: abort(400)
p = get_post(pid)
sub = p.sub
if not sub: abort(400)
if not v.mods(sub): abort(403)
u = p.author
if u.exiled_from(sub):
exile = g.db.query(Exile).filter_by(user_id=u.id, sub=sub).one_or_none()
g.db.delete(exile)
send_notification(u.id, f"@{v.username} has revoked your exile from /s/{sub}")
g.db.commit()
return {"message": "User unexiled successfully!"}
@app.post("/exile/comment/<cid>")
@is_not_permabanned
def exile_comment(v, cid):
@ -136,22 +109,13 @@ def exile_comment(v, cid):
return {"message": "User exiled successfully!"}
@app.post("/unexile/comment/<cid>")
@app.post("/s/<sub>/unexile/<uid>")
@is_not_permabanned
def unexile_comment(v, cid):
try: cid = int(cid)
except: abort(400)
c = get_comment(cid)
sub = c.post.sub
if not sub: abort(400)
def unexile(v, sub, uid):
u = get_account(uid)
if not v.mods(sub): abort(403)
u = c.author
if u.exiled_from(sub):
exile = g.db.query(Exile).filter_by(user_id=u.id, sub=sub).one_or_none()
g.db.delete(exile)
@ -160,7 +124,10 @@ def unexile_comment(v, cid):
g.db.commit()
return {"message": "User unexiled successfully!"}
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"message": "User unexiled successfully!"}
return redirect(f'/s/{sub}/exilees')

View File

@ -220,7 +220,7 @@ def transfer_coins(v, username):
else: tax = 0
log_message = f"@{v.username} has transferred {amount} coins to @{receiver.username}"
send_repeatable_notification(TAX_NOTIF_ID, log_message)
send_repeatable_notification(GIFT_NOTIF_ID, log_message)
receiver.coins += amount-tax
v.coins -= amount
@ -251,7 +251,7 @@ def transfer_bux(v, username):
if amount < 100: return {"error": "You have to gift at least 100 marseybux."}, 400
log_message = f"@{v.username} has transferred {amount} Marseybux to @{receiver.username}"
send_repeatable_notification(TAX_NOTIF_ID, log_message)
send_repeatable_notification(GIFT_NOTIF_ID, log_message)
receiver.procoins += amount
v.procoins -= amount
@ -736,7 +736,9 @@ def u_username_comments(username, v=None):
return render_template("userpage_blocked.html", u=u, v=v)
page = max(int(request.values.get("page", "1")), 1)
try: page = max(int(request.values.get("page", "1")), 1)
except: page = 1
sort=request.values.get("sort","new")
t=request.values.get("t","all")

View File

@ -19,7 +19,7 @@ def admin_vote_info_get(v):
else: abort(400)
except: abort(400)
if thing.ghost: abort(403)
if thing.ghost and v.id != AEVANN_ID: abort(403)
if not thing.author:
print(thing.id, flush=True)

View File

@ -265,11 +265,11 @@
<style>
@keyframes c{{c.id}}-tilt {
from {transform: rotate(1deg);}
to {transform: rotate({{c.award_count("tilt")*4}}deg);}
to {transform: rotate({{c.award_count("tilt")}}deg);}
}
.comment-{{c.id}}-only {
animation-name: c{{c.id}}-tilt !important;
animation-duration: 30s !important;
animation-duration: 7s !important;
animation-iteration-count: infinite !important;
animation-direction: alternate !important;
animation-timing-function: linear !important;
@ -498,7 +498,7 @@
{% set sub = c.post.sub %}
{% if sub and v.mods(sub) and not c.author.mods(sub) %}
<button id="exile-{{c.id}}" class="d-none {% if not c.author.exiled_from(sub) %}d-md-block{% endif %} dropdown-item list-inline-item text-danger" onclick="post_toast2(this,'/exile/comment/{{c.id}}','exile-{{c.id}}','unexile-{{c.id}}')"><i class="fas fa-campfire text-danger fa-fw"></i>Exile user</button>
<button id="unexile-{{c.id}}" class="d-none {% if c.author.exiled_from(sub) %}d-md-block{% endif %} dropdown-item list-inline-item text-success" onclick="post_toast2(this,'/unexile/comment/{{c.id}}','exile-{{c.id}}','unexile-{{c.id}}')"><i class="fas fa-campfire text-success fa-fw"></i>Unexile user</button>
<button id="unexile-{{c.id}}" class="d-none {% if c.author.exiled_from(sub) %}d-md-block{% endif %} dropdown-item list-inline-item text-success" onclick="post_toast2(this,'/s/{{sub}}/unexile/{{c.author_id}}','exile-{{c.id}}','unexile-{{c.id}}')"><i class="fas fa-campfire text-success fa-fw"></i>Unexile user</button>
{% endif %}
{% endif %}
@ -674,7 +674,7 @@
{% set sub = c.post.sub %}
{% if sub and v.mods(sub) and not c.author.mods(sub) %}
<a data-bs-dismiss="modal" id="exile2-{{c.id}}" class="{% if c.author.exiled_from(sub) %}d-none{% endif %} list-group-item text-danger" onclick="post_toast2(this,'/exile/comment/{{c.id}}','exile2-{{c.id}}','unexile2-{{c.id}}')"><i class="fas fa-campfire text-danger mr-2"></i>Exile user</a>
<a data-bs-dismiss="modal" id="unexile2-{{c.id}}" class="{% if not c.author.exiled_from(sub) %}d-none{% endif %} list-group-item text-success" onclick="post_toast2(this,'/unexile/comment/{{c.id}}','exile2-{{c.id}}','unexile2-{{c.id}}')"><i class="fas fa-campfire text-success mr-2"></i>Unexile user</a>
<a data-bs-dismiss="modal" id="unexile2-{{c.id}}" class="{% if not c.author.exiled_from(sub) %}d-none{% endif %} list-group-item text-success" onclick="post_toast2(this,'/s/{{sub}}/unexile/{{c.author_id}}','exile2-{{c.id}}','unexile2-{{c.id}}')"><i class="fas fa-campfire text-success mr-2"></i>Unexile user</a>
{% endif %}
{% endif %}
{% endif %}

View File

@ -83,7 +83,7 @@
{% if not p.author.mods(p.sub) %}
<a id="exile-{{p.id}}" class="{% if p.author.exiled_from(p.sub) %}d-none{% endif %} dropdown-item list-inline-item text-danger" role="button" onclick="post_toast2(this,'/exile/post/{{p.id}}','exile-{{p.id}}','unexile-{{p.id}}')"><i class="fas fa-campfire text-danger"></i>Exile user</a>
<a id="unexile-{{p.id}}" class="{% if not p.author.exiled_from(p.sub) %}d-none{% endif %} dropdown-item list-inline-item text-success" role="button" onclick="post_toast2(this,'/unexile/post/{{p.id}}','exile-{{p.id}}','unexile-{{p.id}}')"><i class="fas fa-campfire text-success"></i>Unexile user</a>
<a id="unexile-{{p.id}}" class="{% if not p.author.exiled_from(p.sub) %}d-none{% endif %} dropdown-item list-inline-item text-success" role="button" onclick="post_toast2(this,'/s/{{sub}}/unexile/{{p.author_id}}','exile-{{p.id}}','unexile-{{p.id}}')"><i class="fas fa-campfire text-success"></i>Unexile user</a>
{% endif %}
{% endif %}

View File

@ -55,6 +55,6 @@
{% if not p.author.mods(p.sub) %}
<button data-bs-dismiss="modal" id="exile2" class="{% if p.author.exiled_from(p.sub) %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-danger" onclick="post_toast2(this,'/exile/post/{{p.id}}','exile2','unexile2')"><i class="fas fa-campfire mr-3 text-danger"></i>Exile user</button>
<button data-bs-dismiss="modal" id="unexile2" class="{% if not p.author.exiled_from(p.sub) %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-success" onclick="post_toast2(this,'/unexile/post/{{p.id}}','exile2','unexile2')"><i class="fas fa-campfire mr-3 text-success"></i>Unexile user</button>
<button data-bs-dismiss="modal" id="unexile2" class="{% if not p.author.exiled_from(p.sub) %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-success" onclick="post_toast2(this,'/s/{{sub}}/unexile/{{p.author_id}}','exile2','unexile2')"><i class="fas fa-campfire mr-3 text-success"></i>Unexile user</button>
{% endif %}
{% endif %}

View File

@ -12,6 +12,7 @@
<th>#</th>
<th>Name</th>
<th>Exiled by</th>
<th></th>
</tr>
</thead>
{% for user, exile in users %}
@ -20,6 +21,14 @@
<td>{{loop.index}}</td>
<td><a style="color:#{{user.namecolor}}" href="/@{{user.username}}"><img loading="lazy" src="{{user.profile_url}}" class="pp20"><span {% if user.patron %}class="patron" style="background-color:#{{user.namecolor}}"{% endif %}>{{user.username}}</span></a></td>
<td><a style="color:#{{exiler.namecolor}}" href="/@{{exiler.username}}"><img loading="lazy" src="{{exiler.profile_url}}" class="pp20"><span {% if exiler.patron %}class="patron" style="background-color:#{{exiler.namecolor}}"{% endif %}>{{exiler.username}}</span></a></td>
<td>
{% if v.mods(sub.name) %}
<form action="/s/{{sub.name}}/unexile/{{user.id}}" method="post">
<input autocomplete="off" type="hidden" name="formkey" value="{{v.formkey}}">
<input class="btn btn-primary" style="margin-top:-5px" autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Unexile">
</form>
{% endif %}
</td>
</tr>
{% endfor %}
</table>

View File

@ -460,11 +460,11 @@
<style>
@keyframes post-tilt {
from {transform: rotate(1deg);}
to {transform: rotate({{p.award_count("tilt")*4}}deg);}
to {transform: rotate({{p.award_count("tilt")}}deg);}
}
#post-root {
animation-name: post-tilt !important;
animation-duration: 30s !important;
animation-duration: 7s !important;
animation-iteration-count: infinite !important;
animation-direction: alternate !important;
animation-timing-function: linear !important;
@ -775,7 +775,7 @@
<li class="list-inline-item">
<a {% if v and v.newtab and not g.webview %}target="_blank"{% endif %} href="{{p.permalink}}">
<i class="fas fa-comment-dots"></i>{{p.comment_count}}
<span class="text-info d-none new-comments"></span>
<span class="text-info d-none {{p.id}}-new-comments"></span>
</a>
</li>
@ -842,7 +842,7 @@
<li class="list-inline-item mr-auto">
<a href="{{p.permalink}}">
<i class="fas fa-comment-dots"></i>{{p.comment_count}}
<span class="text-info d-none new-comments"></span>
<span class="text-info d-none {{p.id}}-new-comments"></span>
</a>
{% if v and v.admin_level > 1 %}
@ -922,7 +922,7 @@
<input autocomplete="off" type="hidden" name="parent_fullname" value="t2_{{p.id}}">
<input autocomplete="off" id="reply-form-submission-{{p.fullname}}" type="hidden" name="submission" value="{{p.id}}">
{% if v %}
<textarea autocomplete="off" {% if v.longpost %}minlength="280"{% endif %} maxlength="{% if v.bird %}140{% else %}10000{% endif %}" oninput="markdown('reply-form-body-{{p.fullname}}', 'form-preview-{{p.id}}');charLimit('reply-form-body-{{p.fullname}}','charcount-reply')" id="reply-form-body-{{p.fullname}}" data-fullname="{{p.fullname}}" class="comment-box form-control rounded" id="comment-form" name="body" form="reply-to-{{p.fullname}}" aria-label="With textarea" placeholder="Add your comment..." rows="3"></textarea>
<textarea autocomplete="off" {% if not (p and p.id in ADMIGGERS) %}{% if v.longpost %}minlength="280"{% elif v.bird %}maxlength="140"{% endif %}{% endif %} maxlength="10000" oninput="markdown('reply-form-body-{{p.fullname}}', 'form-preview-{{p.id}}');charLimit('reply-form-body-{{p.fullname}}','charcount-reply')" id="reply-form-body-{{p.fullname}}" data-fullname="{{p.fullname}}" class="comment-box form-control rounded" id="comment-form" name="body" form="reply-to-{{p.fullname}}" aria-label="With textarea" placeholder="Add your comment..." rows="3"></textarea>
{% endif %}
<div class="text-small font-weight-bold mt-1" id="charcount-reply" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></div>
@ -1048,7 +1048,7 @@
{% endif %}
{% if not v or v.highlightcomments %}
<script src="/static/assets/js/new_comments_count.js?v=240"></script>
<script src="/static/assets/js/new_comments_count.js?v=242"></script>
{% endif %}
<script src="/static/assets/js/clipboard.js?v=240"></script>

View File

@ -9,7 +9,7 @@
{% endif %}
{% if not v or v.highlightcomments %}
<script src="/static/assets/js/new_comments_count.js?v=240"></script>
<script src="/static/assets/js/new_comments_count.js?v=242"></script>
{% endif %}
<div style="display:none" id="popover">
@ -52,12 +52,6 @@
{% for p in listing %}
<script>
{% if not v or v.highlightcomments %}
showNewCommentCounts('{{p.id}}', {{p.comment_count}})
{% endif %}
</script>
{% set ups=p.upvotes %}
{% set downs=p.downvotes %}
{% set score=ups-downs %}
@ -225,7 +219,7 @@
<li class="list-inline-item">
<a {% if v and v.newtab and not g.webview %}target="_blank"{% endif %} href="{{p.permalink}}">
<i class="fas fa-comment-dots"></i>{{p.comment_count}}
<span class="text-info d-none new-comments"></span>
<span class="text-info d-none {{p.id}}-new-comments"></span>
</a>
</li>
{% include 'post_actions.html' %}
@ -240,7 +234,7 @@
<li class="list-inline-item mr-auto">
<a {% if v and v.newtab and not g.webview %}target="_blank"{% endif %} href="{{p.permalink}}">
<i class="fas fa-comment-dots"></i>{{p.comment_count}}
<span class="text-info d-none new-comments"></span>
<span class="text-info d-none {{p.id}}-new-comments"></span>
</a>
{% if v and v.admin_level > 1 %}
@ -329,6 +323,13 @@
</div>
{% endif %}
<script>
{% if not v or v.highlightcomments %}
showNewCommentCounts({{p.id}}, {{p.comment_count}})
{% endif %}
</script>
{% if v and v.admin_level > 1 %}
{% include "post_admin_actions_mobile.html" %}
{% endif %}

View File

@ -15,6 +15,7 @@
<p><a href="{{thing.permalink}}">{{thing.permalink}}</a></p>
<p><b>Author:</b> <a href="{{thing.author.url}}">@{{thing.author.username}}</a></p>
<p><b>Author Created At:</b> {{thing.author.created_datetime}}</p>
<p><b>Author Truescore:</b> {{thing.author.truecoins}}</p>
<p><b>Upvotes: </b>{{ups | length}}</p>
<p><b>Downvotes: </b>{{downs | length}}</p>