forked from rDrama/rDrama
1
0
Fork 0

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

master
Aevann1 2022-10-07 05:25:37 +02:00
commit b608a514e4
69 changed files with 589 additions and 495 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

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

View File

@ -326,8 +326,8 @@ class Submission(Base):
@lazy
def realbody(self, v, listing=False):
if self.club and not (v and (v.paid_dues or v.id == self.author_id)): return f"<p>{CC} ONLY</p>"
if self.deleted_utc != 0 and not (v and (v.admin_level >= 2 or v.id == self.author.id)): return "[Deleted by user]"
if self.is_banned and not (v and v.admin_level >= 2): return "[Removed by admins]"
if self.deleted_utc != 0 and not (v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or v.id == self.author.id)): return "[Deleted by user]"
if self.is_banned and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']): return "[Removed by admins]"
body = self.body_html or ""
@ -369,7 +369,7 @@ class Submission(Base):
if o.exclusive == 3:
body += " - <b>WINNER!</b>"
if not winner and v and v.admin_level > 2:
if not winner and v and v.admin_level >= PERMS['POST_BETS_DISTRIBUTE']:
body += f'''<button class="btn btn-primary distribute" onclick="this.nextElementSibling.classList.remove('d-none');this.classList.add('d-none')">Declare winner</button><button class="btn btn-primary distribute d-none" onclick="post_toast(this,'/distribute/{o.id}',true)">Are you sure?</button>'''
body += "</div>"
else:
@ -395,8 +395,8 @@ class Submission(Base):
@lazy
def plainbody(self, v):
if self.deleted_utc != 0 and not (v and (v.admin_level >= 2 or v.id == self.author.id)): return "[Deleted by user]"
if self.is_banned and not (v and v.admin_level >= 2): return "[Removed by admins]"
if self.deleted_utc != 0 and not (v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or v.id == self.author.id)): return "[Deleted by user]"
if self.is_banned and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']): return "[Removed by admins]"
if self.club and not (v and (v.paid_dues or v.id == self.author_id)): return f"<p>{CC} ONLY</p>"
body = self.body

View File

@ -285,7 +285,7 @@ class User(Base):
@lazy
def mods(self, sub):
if self.is_suspended_permanently or self.shadowbanned: return False
return self.admin_level > 2 or bool(g.db.query(Mod.user_id).filter_by(user_id=self.id, sub=sub).one_or_none())
return self.admin_level >= PERMS['HOLE_GLOBAL_MODERATION'] or bool(g.db.query(Mod.user_id).filter_by(user_id=self.id, sub=sub).one_or_none())
@lazy
def exiled_from(self, sub):
@ -319,7 +319,7 @@ class User(Base):
@lazy
def mod_date(self, sub):
if self.admin_level >= 3: return 1
if self.admin_level >= PERMS['HOLE_GLOBAL_MODERATION']: return 1
mod = g.db.query(Mod).filter_by(user_id=self.id, sub=sub).one_or_none()
if not mod: return None
return mod.created_utc
@ -414,9 +414,10 @@ class User(Base):
@property
@lazy
def paid_dues(self):
if not FEATURES['COUNTRY_CLUB']:
return True
return not self.shadowbanned and not (self.is_banned and not self.unban_utc) and (self.admin_level or self.club_allowed or (self.club_allowed != False and self.truecoins >= dues))
if not FEATURES['COUNTRY_CLUB']: return True
if self.shadowbanned: return False
if self.is_suspended_permanently: return False
return self.admin_level >= PERMS['VIEW_CLUB'] or self.club_allowed or (self.club_allowed != False and self.truecoins >= dues)
@lazy
def any_block_exists(self, other):
@ -453,11 +454,11 @@ class User(Base):
@cache.memoize(timeout=86400)
def userpagelisting(self, site=None, v=None, page=1, sort="new", t="all"):
if self.shadowbanned and not (v and (v.admin_level > 1 or v.id == self.id)): return []
if self.shadowbanned and not (v and (v.admin_level >= PERMS['USER_SHADOWBAN'] or v.id == self.id)): return []
posts = g.db.query(Submission.id).filter_by(author_id=self.id, is_pinned=False)
if not (v and (v.admin_level > 1 or v.id == self.id)):
if not (v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or v.id == self.id)):
posts = posts.filter_by(is_banned=False, private=False, ghost=False, deleted_utc=0)
posts = apply_time_filter(t, posts, Submission)
@ -565,7 +566,7 @@ class User(Base):
@property
@lazy
def modaction_num(self):
if self.admin_level < 2: return 0
if self.admin_level < PERMS['ADMIN_MOP_VISIBLE']: return 0
return g.db.query(ModAction).filter_by(user_id=self.id).count()
@property
@ -585,7 +586,7 @@ class User(Base):
Notification.user_id == self.id, Notification.read == False,
Comment.is_banned == False, Comment.deleted_utc == 0)
if not self.shadowbanned and self.admin_level < 3:
if not self.shadowbanned and self.admin_level < PERMS['USER_SHADOWBAN']:
notifs = notifs.join(Comment.author).filter(User.shadowbanned == None)
return notifs.count() + self.post_notifications_count + self.modaction_notifications_count
@ -610,7 +611,7 @@ class User(Base):
Comment.parent_submission == None,
)
if not self.shadowbanned and self.admin_level < 3:
if not self.shadowbanned and self.admin_level < PERMS['USER_SHADOWBAN']:
notifs = notifs.join(Comment.author).filter(User.shadowbanned == None)
return notifs.count()
@ -767,8 +768,8 @@ class User(Base):
'bannerurl': self.banner_url,
'bio_html': self.bio_html_eager,
'coins': self.coins,
'post_count': 0 if self.shadowbanned and not (v and (v.shadowbanned or v.admin_level >= 2)) else self.post_count,
'comment_count': 0 if self.shadowbanned and not (v and (v.shadowbanned or v.admin_level >= 2)) else self.comment_count,
'post_count': 0 if self.shadowbanned and not (v and (v.shadowbanned or v.admin_level >= PERMS['USER_SHADOWBAN'])) else self.post_count,
'comment_count': 0 if self.shadowbanned and not (v and (v.shadowbanned or v.admin_level >= PERMS['USER_SHADOWBAN'])) else self.comment_count,
'badges': [x.path for x in self.badges],
}
@ -895,7 +896,7 @@ class User(Base):
def viewers_recorded(self):
if SITE_NAME == 'WPD': # WPD gets profile views
return True
elif self.admin_level >= 2: # Admins get profile views
elif self.admin_level >= PERMS['VIEW_PROFILE_VIEWS']: # Admins get profile views
return True
elif self.patron: # Patrons get profile views as a perk
return True
@ -919,7 +920,7 @@ class User(Base):
@property
@lazy
def can_see_chudrama(self):
if self.admin_level: return True
if self.admin_level >= PERMS['VIEW_CHUDRAMA']: return True
if self.client: return True
if self.truecoins >= 5000: return True
if self.agendaposter: return True

View File

@ -95,7 +95,7 @@ def NOTIFY_USERS(text, v):
notify_users.add(user.id)
if SITE_NAME == "WPD" and 'daisy' in text.lower():
admin_ids = [x[0] for x in g.db.query(User.id).filter(User.admin_level > 0).all()]
admin_ids = [x[0] for x in g.db.query(User.id).filter(User.admin_level >= PERMS['NOTIFICATIONS_SPECIFIC_WPD_COMMENTS']).all()]
notify_users.update(admin_ids)
return notify_users - bots

View File

@ -121,12 +121,76 @@ AGENDAPOSTER_MSG_HTML = """<p>Hi <a href="/id/{id}"><img loading="lazy" src="/pp
################################################################################
PERMS = { # Minimum admin_level to perform action.
'ADMIN_ADD': 3, # note: explicitly disabled on rDrama
'ADMIN_REMOVE': 3,
'ADMIN_ADD_PERM_LEVEL': 2, # permission level given when user added via site
'ADMIN_ACTIONS_REVERT': 3,
'ADMIN_MOP_VISIBLE': 2,
'ADMIN_HOME_VISIBLE': 2,
'DOMAINS_BAN': 3,
'HOLE_CREATE': 0,
'HOLE_GLOBAL_MODERATION': 3,
'FLAGS_REMOVE': 2,
'VOTES_VISIBLE': 0,
'USER_BLOCKS_VISIBLE': 0,
'USER_FOLLOWS_VISIBLE': 0,
'USER_VOTERS_VISIBLE': 0,
'POST_COMMENT_MODERATION': 2,
'POST_COMMENT_DISTINGUISH': 1,
'POST_COMMENT_MODERATION_TOOLS_VISIBLE': 2, # note: does not affect API at all
'POST_EDITING': 3,
'USER_BADGES': 2,
'USER_BAN': 2,
'USER_SHADOWBAN': 2,
'USER_AGENDAPOSTER': 2,
'USER_CLUB_ALLOW_BAN': 2,
'USER_LINK': 2,
'USER_MERGE': 3, # note: extra check for Aevann
'USER_TITLE_CHANGE': 2,
'USER_MODERATION_TOOLS_VISIBLE': 2, # note: does not affect API at all
'POST_TO_CHANGELOG': 1, # note: code contributors can also post to changelog
'POST_TO_POLL_THREAD': 2,
'POST_BETS': 3,
'POST_BETS_DISTRIBUTE': 3, # probably should be the same as POST_BETS but w/e
'BYPASS_PIN_LIMIT': 3,
'VIEW_PENDING_SUBMITTED_MARSEYS': 3,
'VIEW_PENDING_SUBMITTED_HATS': 3,
'MODERATE_PENDING_SUBMITTED_MARSEYS': 3, # note: there is an extra check so that only """carp""" can approve them
'MODERATE_PENDING_SUBMITTED_HATS': 3, # note: there is an extra check so that only """carp""" can approve them
'UPDATE_MARSEYS': 3, # note: extra check is here for 4 different users
'UPDATE_HATS': 3, # note: extra check is here for 4 different users
'BUY_GHOST_AWARD': 2,
'LOTTERY_ADMIN': 3,
'LOTTERY_VIEW_PARTICIPANTS': 2,
'VIEW_MODMAIL': 2,
'VIEW_CLUB': 1,
'VIEW_CHUDRAMA': 1,
'VIEW_PRIVATE_PROFILES': 2,
'VIEW_ALTS': 2,
'VIEW_PROFILE_VIEWS': 2,
'VIEW_SORTED_ADMIN_LIST': 3,
'VIEW_ACTIVE_USERS': 2,
'VIEW_ALL_USERS': 2,
'VIEW_ALT_VOTES': 2,
'VIEW_LAST_ACTIVE': 2,
'VIEW_PATRONS': 3, # note: extra check for Aevann, carp, or snakes
'VIEW_VOTE_BUTTONS_ON_USER_PAGE': 2,
'PRINT_MARSEYBUX_FOR_KIPPY_ON_PCMEMES': 3, # note: explicitly disabled on rDrama
'SITE_SETTINGS': 3,
'SITE_SETTINGS_SIDEBARS_BANNERS_BADGES': 3,
'SITE_SETTINGS_SNAPPY_QUOTES': 3,
'SITE_SETTINGS_UNDER_ATTACK': 3,
'SITE_CACHE_PURGE_CDN': 3,
'SITE_CACHE_DUMP_INTERNAL': 2,
'NOTIFICATIONS_HOLE_INACTIVITY_DELETION': 2,
'NOTIFICATIONS_HOLE_CREATION': 2,
'NOTIFICATIONS_FROM_SHADOWBANNED_USERS': 3,
'NOTIFICATIONS_MODMAIL': 3,
'NOTIFICATIONS_SPECIFIC_WPD_COMMENTS': 1,
'MESSAGE_BLOCKED_USERS': 1,
'APPS_MODERATION': 3,
'STREAMERS_MODERATION': 2,
'UNKNOWN_ADMIN_LEVEL2_PERM4': 2, # TODO: figure out what this is and remove it if unnecessary
}
FEATURES = {
@ -217,6 +281,7 @@ GIFT_NOTIF_ID = 5
if SITE == 'rdrama.net':
FEATURES['PRONOUNS'] = True
FEATURES['HOUSES'] = True
PERMS['ADMIN_ADD_PERM_LEVEL'] = 0 # extra check here to disallow adding admins on site
SIDEBAR_THREAD = 37696
BANNER_THREAD = 37697

View File

@ -65,7 +65,7 @@ def sub_inactive_purge_task():
dead_holes = g.db.query(Sub).filter(Sub.name.notin_(active_holes)).all()
names = [x.name for x in dead_holes]
admins = [x[0] for x in g.db.query(User.id).filter(User.admin_level > 1).all()]
admins = [x[0] for x in g.db.query(User.id).filter(User.admin_level >= PERMS['NOTIFICATIONS_HOLE_INACTIVITY_DELETION']).all()]
mods = g.db.query(Mod).filter(Mod.sub.in_(names)).all()
for x in mods:

View File

@ -39,7 +39,7 @@ def get_user(username, v=None, graceful=False, rendered=False, include_blocks=Fa
user = user.one_or_none()
if not user or (user.shadowbanned and not (include_shadowbanned or (v and (v.admin_level >= 2 or v.shadowbanned)))):
if not user or (user.shadowbanned and not (include_shadowbanned or (v and (v.admin_level >= PERMS['USER_SHADOWBAN'] or v.shadowbanned)))):
if not graceful: abort(404)
else: return None
@ -95,7 +95,7 @@ def get_account(id, v=None, graceful=False, include_blocks=False, include_shadow
user = g.db.get(User, id)
if not user or (user.shadowbanned and not (include_shadowbanned or (v and (v.admin_level >= 2 or v.shadowbanned)))):
if not user or (user.shadowbanned and not (include_shadowbanned or (v and (v.admin_level >= PERMS['USER_SHADOWBAN'] or v.shadowbanned)))):
if not graceful: abort(404)
else: return None
@ -264,7 +264,7 @@ def get_comments(cids, v=None, load_parent=False):
blocked.c.target_id,
).filter(Comment.id.in_(cids))
if not (v and (v.shadowbanned or v.admin_level >= 2)):
if not (v and (v.shadowbanned or v.admin_level >= PERMS['USER_SHADOWBAN'])):
comments = comments.join(Comment.author).filter(User.shadowbanned == None)
comments = comments.join(

View File

@ -22,28 +22,29 @@ import requests
from urllib.parse import quote, urlencode
@app.post('/kippy')
@admin_level_required(3)
@admin_level_required(PERMS['PRINT_MARSEYBUX_FOR_KIPPY_ON_PCMEMES'])
def kippy(v):
if SITE == 'rdrama.net': abort(404)
kippy = get_account(KIPPY_ID)
kippy.procoins += 10000
g.db.add(kippy)
return '10k marseycoins printed!'
@app.get('/admin/loggedin')
@admin_level_required(2)
@admin_level_required(PERMS['VIEW_ACTIVE_USERS'])
def loggedin_list(v):
ids = [x for x,val in cache.get(f'{SITE}_loggedin').items() if time.time()-val < LOGGEDIN_ACTIVE_TIME]
users = g.db.query(User).filter(User.id.in_(ids)).order_by(User.admin_level.desc(), User.truecoins.desc()).all()
return render_template("loggedin.html", v=v, users=users)
@app.get('/admin/loggedout')
@admin_level_required(2)
@admin_level_required(PERMS['VIEW_ACTIVE_USERS'])
def loggedout_list(v):
users = sorted([val[1] for x,val in cache.get(f'{SITE}_loggedout').items() if time.time()-val[0] < LOGGEDIN_ACTIVE_TIME])
return render_template("loggedout.html", v=v, users=users)
@app.get('/admin/merge/<id1>/<id2>')
@admin_level_required(3)
@admin_level_required(PERMS['USER_MERGE'])
def merge(v, id1, id2):
if v.id != AEVANN_ID: abort(403)
@ -105,7 +106,7 @@ def merge(v, id1, id2):
@app.get('/admin/merge_all/<id>')
@admin_level_required(3)
@admin_level_required(PERMS['USER_MERGE'])
def merge_all(v, id):
if v.id != AEVANN_ID: abort(403)
@ -155,13 +156,13 @@ def merge_all(v, id):
@app.post("/@<username>/make_admin")
@admin_level_required(3)
@admin_level_required(PERMS['ADMIN_ADD'])
def make_admin(v, username):
if SITE == 'rdrama.net': abort(403)
user = get_user(username)
user.admin_level = 2
user.admin_level = PERMS['ADMIN_ADD_PERM_LEVEL']
g.db.add(user)
ma = ModAction(
@ -175,7 +176,7 @@ def make_admin(v, username):
@app.post("/@<username>/remove_admin")
@admin_level_required(3)
@admin_level_required(PERMS['ADMIN_REMOVE'])
def remove_admin(v, username):
user = get_user(username)
user.admin_level = 0
@ -192,7 +193,7 @@ def remove_admin(v, username):
@app.post("/distribute/<option_id>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(3)
@admin_level_required(PERMS['POST_BETS_DISTRIBUTE'])
def distribute(v, option_id):
autojanny = get_account(AUTOJANNY_ID)
if autojanny.coins == 0: return {"error": "@AutoJanny has 0 coins"}, 400
@ -248,7 +249,7 @@ def distribute(v, option_id):
@app.post("/@<username>/revert_actions")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(3)
@admin_level_required(PERMS['ADMIN_ACTIONS_REVERT'])
def revert_actions(v, username):
user = get_user(username)
@ -298,7 +299,7 @@ def revert_actions(v, username):
@app.post("/@<username>/club_allow")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['USER_CLUB_ALLOW_BAN'])
def club_allow(v, username):
u = get_user(username, v=v)
@ -324,7 +325,7 @@ def club_allow(v, username):
@app.post("/@<username>/club_ban")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['USER_CLUB_ALLOW_BAN'])
def club_ban(v, username):
u = get_user(username, v=v)
@ -351,13 +352,13 @@ def club_ban(v, username):
@app.get("/admin/shadowbanned")
@auth_required
def shadowbanned(v):
if not (v and v.admin_level > 1): abort(404)
if not (v and v.admin_level >= PERMS['USER_SHADOWBAN']): abort(404)
users = g.db.query(User).filter(User.shadowbanned != None).order_by(User.shadowbanned).all()
return render_template("shadowbanned.html", v=v, users=users)
@app.get("/admin/image_posts")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def image_posts_listing(v):
try: page = int(request.values.get('page', 1))
@ -375,7 +376,7 @@ def image_posts_listing(v):
@app.get("/admin/reported/posts")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def reported_posts(v):
page = max(1, int(request.values.get("page", 1)))
@ -396,7 +397,7 @@ def reported_posts(v):
@app.get("/admin/reported/comments")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def reported_comments(v):
page = max(1, int(request.values.get("page", 1)))
@ -421,11 +422,11 @@ def reported_comments(v):
standalone=True)
@app.get("/admin")
@admin_level_required(2)
@admin_level_required(PERMS['ADMIN_HOME_VISIBLE'])
def admin_home(v):
under_attack = False
if v.admin_level > 2:
if v.admin_level >= PERMS['SITE_SETTINGS_UNDER_ATTACK']:
if CF_ZONE == 'blahblahblah': response = 'high'
else: response = requests.get(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/settings/security_level', headers=CF_HEADERS, timeout=5).json()['result']['value']
under_attack = response == 'under_attack'
@ -453,7 +454,7 @@ def admin_git_head():
return gitref
@app.post("/admin/site_settings/<setting>")
@admin_level_required(3)
@admin_level_required(PERMS['SITE_SETTINGS'])
def change_settings(v, setting):
site_settings = app.config['SETTINGS']
site_settings[setting] = not site_settings[setting]
@ -474,7 +475,7 @@ def change_settings(v, setting):
@app.post("/admin/purge_cache")
@admin_level_required(3)
@admin_level_required(PERMS['SITE_CACHE_PURGE_CDN'])
def purge_cache(v):
online = cache.get(ONLINE_STR)
cache.clear()
@ -493,7 +494,7 @@ def purge_cache(v):
@app.post("/admin/under_attack")
@admin_level_required(3)
@admin_level_required(PERMS['SITE_SETTINGS_UNDER_ATTACK'])
def under_attack(v):
response = requests.get(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/settings/security_level', headers=CF_HEADERS, timeout=5).json()['result']['value']
@ -519,7 +520,7 @@ def under_attack(v):
return {"error": "Failed to enable under attack mode."}, 400
@app.get("/admin/badge_grant")
@admin_level_required(2)
@admin_level_required(PERMS['USER_BADGES'])
def badge_grant_get(v):
if not FEATURES['BADGES']:
abort(404)
@ -530,7 +531,7 @@ def badge_grant_get(v):
@app.post("/admin/badge_grant")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['USER_BADGES'])
def badge_grant_post(v):
if not FEATURES['BADGES']:
abort(404)
@ -580,7 +581,7 @@ def badge_grant_post(v):
@app.get("/admin/badge_remove")
@admin_level_required(2)
@admin_level_required(PERMS['USER_BADGES'])
def badge_remove_get(v):
if not FEATURES['BADGES']:
abort(404)
@ -592,7 +593,7 @@ def badge_remove_get(v):
@app.post("/admin/badge_remove")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['USER_BADGES'])
def badge_remove_post(v):
if not FEATURES['BADGES']:
abort(404)
@ -629,7 +630,7 @@ def badge_remove_post(v):
@app.get("/admin/users")
@admin_level_required(2)
@admin_level_required(PERMS['VIEW_ALL_USERS'])
def users_list(v):
try: page = int(request.values.get("page", 1))
@ -650,7 +651,7 @@ def users_list(v):
@app.get("/admin/alt_votes")
@admin_level_required(2)
@admin_level_required(PERMS['VIEW_ALT_VOTES'])
def alt_votes_get(v):
u1 = request.values.get("u1")
@ -757,7 +758,7 @@ def alt_votes_get(v):
@app.post("/admin/link_accounts")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['USER_LINK'])
def admin_link_accounts(v):
u1 = int(request.values.get("u1"))
@ -787,7 +788,7 @@ def admin_link_accounts(v):
@app.get("/admin/removed/posts")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def admin_removed(v):
try: page = int(request.values.get("page", 1))
@ -814,7 +815,7 @@ def admin_removed(v):
@app.get("/admin/removed/comments")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def admin_removed_comments(v):
try: page = int(request.values.get("page", 1))
@ -839,7 +840,7 @@ def admin_removed_comments(v):
@app.post("/agendaposter/<user_id>")
@admin_level_required(2)
@admin_level_required(PERMS['USER_AGENDAPOSTER'])
def agendaposter(user_id, v):
user = get_account(user_id)
@ -873,7 +874,7 @@ def agendaposter(user_id, v):
@app.post("/unagendaposter/<user_id>")
@admin_level_required(2)
@admin_level_required(PERMS['USER_AGENDAPOSTER'])
def unagendaposter(user_id, v):
user = get_account(user_id)
@ -902,7 +903,7 @@ def unagendaposter(user_id, v):
@app.post("/shadowban/<user_id>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['USER_SHADOWBAN'])
def shadowban(user_id, v):
user = get_account(user_id)
if user.admin_level != 0: abort(403)
@ -932,7 +933,7 @@ def shadowban(user_id, v):
@app.post("/unshadowban/<user_id>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['USER_SHADOWBAN'])
def unshadowban(user_id, v):
user = get_account(user_id)
user.shadowbanned = None
@ -957,7 +958,7 @@ def unshadowban(user_id, v):
@app.post("/admin/title_change/<user_id>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['USER_TITLE_CHANGE'])
def admin_title_change(user_id, v):
user = get_account(user_id)
@ -992,7 +993,7 @@ def admin_title_change(user_id, v):
@app.post("/ban_user/<user_id>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['USER_BAN'])
def ban_user(user_id, v):
user = get_account(user_id)
@ -1055,7 +1056,7 @@ def ban_user(user_id, v):
@app.post("/unban_user/<user_id>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['USER_BAN'])
def unban_user(user_id, v):
user = get_account(user_id)
if not user.is_banned:
@ -1086,7 +1087,7 @@ def unban_user(user_id, v):
@app.post("/mute_user/<int:user_id>/<int:mute_status>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['USER_BAN'])
def mute_user(v, user_id, mute_status):
user = get_account(user_id)
@ -1116,7 +1117,7 @@ def mute_user(v, user_id, mute_status):
@app.post("/remove_post/<post_id>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def remove_post(post_id, v):
post = get_post(post_id)
post.is_banned = True
@ -1148,7 +1149,7 @@ def remove_post(post_id, v):
@app.post("/approve_post/<post_id>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def approve_post(post_id, v):
post = get_post(post_id)
@ -1179,11 +1180,11 @@ def approve_post(post_id, v):
@app.post("/distinguish/<post_id>")
@admin_level_required(1)
@admin_level_required(PERMS['POST_COMMENT_DISTINGUISH'])
def distinguish_post(post_id, v):
post = get_post(post_id)
if post.author_id != v.id and v.admin_level < 2 : abort(403)
if post.author_id != v.id and v.admin_level < PERMS['POST_COMMENT_MODERATION']: abort(403)
if post.distinguish_level:
post.distinguish_level = 0
@ -1207,7 +1208,7 @@ def distinguish_post(post_id, v):
@app.post("/sticky/<post_id>")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def sticky_post(post_id, v):
if not FEATURES['PINS']:
abort(403)
@ -1216,7 +1217,7 @@ def sticky_post(post_id, v):
if not post.stickied:
pins = g.db.query(Submission).filter(Submission.stickied != None, Submission.is_banned == False).count()
if pins >= PIN_LIMIT:
if v.admin_level > 2:
if v.admin_level >= PERMS['BYPASS_PIN_LIMIT']:
post.stickied = v.username
post.stickied_utc = int(time.time()) + 3600
else: return {"error": f"Can't exceed {PIN_LIMIT} pinned posts limit!"}, 403
@ -1237,7 +1238,7 @@ def sticky_post(post_id, v):
return {"message": "Post pinned!"}
@app.post("/unsticky/<post_id>")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def unsticky_post(post_id, v):
post = get_post(post_id)
@ -1262,7 +1263,7 @@ def unsticky_post(post_id, v):
return {"message": "Post unpinned!"}
@app.post("/sticky_comment/<cid>")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def sticky_comment(cid, v):
comment = get_comment(cid, v=v)
@ -1286,7 +1287,7 @@ def sticky_comment(cid, v):
@app.post("/unsticky_comment/<cid>")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def unsticky_comment(cid, v):
comment = get_comment(cid, v=v)
@ -1313,7 +1314,7 @@ def unsticky_comment(cid, v):
@app.post("/remove_comment/<c_id>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def remove_comment(c_id, v):
comment = get_comment(c_id)
@ -1333,7 +1334,7 @@ def remove_comment(c_id, v):
@app.post("/approve_comment/<c_id>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def approve_comment(c_id, v):
comment = get_comment(c_id)
@ -1360,7 +1361,7 @@ def approve_comment(c_id, v):
@app.post("/distinguish_comment/<c_id>")
@admin_level_required(1)
@admin_level_required(PERMS['POST_COMMENT_DISTINGUISH'])
def admin_distinguish_comment(c_id, v):
@ -1389,7 +1390,7 @@ def admin_distinguish_comment(c_id, v):
else: return {"message": "Comment undistinguished!"}
@app.get("/admin/dump_cache")
@admin_level_required(2)
@admin_level_required(PERMS['SITE_CACHE_DUMP_INTERNAL'])
def admin_dump_cache(v):
online = cache.get(ONLINE_STR)
cache.clear()
@ -1405,7 +1406,7 @@ def admin_dump_cache(v):
@app.get("/admin/banned_domains/")
@admin_level_required(3)
@admin_level_required(PERMS['DOMAINS_BAN'])
def admin_banned_domains(v):
banned_domains = g.db.query(BannedDomain).all()
@ -1413,7 +1414,7 @@ def admin_banned_domains(v):
@app.post("/admin/banned_domains")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(3)
@admin_level_required(PERMS['DOMAINS_BAN'])
def admin_toggle_ban_domain(v):
domain=request.values.get("domain", "").strip()
@ -1446,7 +1447,7 @@ def admin_toggle_ban_domain(v):
@app.post("/admin/nuke_user")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def admin_nuke_user(v):
user=get_user(request.values.get("user"))
@ -1479,7 +1480,7 @@ def admin_nuke_user(v):
@app.post("/admin/unnuke_user")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def admin_nunuke_user(v):
user=get_user(request.values.get("user"))

View File

@ -22,7 +22,7 @@ def asset_submissions(path):
@app.get("/submit/marseys")
@auth_required
def submit_marseys(v):
if v.admin_level > 2:
if v.admin_level >= PERMS['VIEW_PENDING_SUBMITTED_MARSEYS']:
marseys = g.db.query(Marsey).filter(Marsey.submitter_id != None).all()
else:
marseys = g.db.query(Marsey).filter(Marsey.submitter_id == v.id).all()
@ -44,7 +44,7 @@ def submit_marsey(v):
username = request.values.get('author').lower().strip()
def error(error):
if v.admin_level > 2: marseys = g.db.query(Marsey).filter(Marsey.submitter_id != None).all()
if v.admin_level >= PERMS['VIEW_PENDING_SUBMITTED_MARSEYS']: marseys = g.db.query(Marsey).filter(Marsey.submitter_id != None).all()
else: marseys = g.db.query(Marsey).filter(Marsey.submitter_id == v.id).all()
for marsey in marseys:
marsey.author = g.db.query(User.username).filter_by(id=marsey.author_id).one()[0]
@ -82,7 +82,7 @@ def submit_marsey(v):
g.db.add(marsey)
g.db.flush()
if v.admin_level > 2: marseys = g.db.query(Marsey).filter(Marsey.submitter_id != None).all()
if v.admin_level >= PERMS['VIEW_PENDING_SUBMITTED_MARSEYS']: marseys = g.db.query(Marsey).filter(Marsey.submitter_id != None).all()
else: marseys = g.db.query(Marsey).filter(Marsey.submitter_id == v.id).all()
for marsey in marseys:
marsey.author = g.db.query(User.username).filter_by(id=marsey.author_id).one()[0]
@ -92,7 +92,7 @@ def submit_marsey(v):
@app.post("/admin/approve/marsey/<name>")
@admin_level_required(3)
@admin_level_required(PERMS['MODERATE_PENDING_SUBMITTED_MARSEYS'])
def approve_marsey(v, name):
if AEVANN_ID and v.id not in (AEVANN_ID, CARP_ID, SNAKES_ID):
return {"error": "Only Carp can approve marseys!"}, 403
@ -186,7 +186,7 @@ def remove_marsey(v, name):
@app.get("/submit/hats")
@auth_required
def submit_hats(v):
if v.admin_level > 2: hats = g.db.query(HatDef).filter(HatDef.submitter_id != None).all()
if v.admin_level >= PERMS['VIEW_PENDING_SUBMITTED_HATS']: hats = g.db.query(HatDef).filter(HatDef.submitter_id != None).all()
else: hats = g.db.query(HatDef).filter(HatDef.submitter_id == v.id).all()
return render_template("submit_hats.html", v=v, hats=hats)
@ -200,7 +200,7 @@ def submit_hat(v):
username = request.values.get('author').strip()
def error(error):
if v.admin_level > 2: hats = g.db.query(HatDef).filter(HatDef.submitter_id != None).all()
if v.admin_level >= PERMS['VIEW_PENDING_SUBMITTED_HATS']: hats = g.db.query(HatDef).filter(HatDef.submitter_id != None).all()
else: hats = g.db.query(HatDef).filter(HatDef.submitter_id == v.id).all()
return render_template("submit_hats.html", v=v, hats=hats, error=error, name=name, description=description, username=username), 400
@ -245,13 +245,13 @@ def submit_hat(v):
g.db.commit()
if v.admin_level > 2: hats = g.db.query(HatDef).filter(HatDef.submitter_id != None).all()
if v.admin_level >= PERMS['VIEW_PENDING_SUBMITTED_HATS']: hats = g.db.query(HatDef).filter(HatDef.submitter_id != None).all()
else: hats = g.db.query(HatDef).filter(HatDef.submitter_id == v.id).all()
return render_template("submit_hats.html", v=v, hats=hats, msg=f"'{name}' submitted successfully!")
@app.post("/admin/approve/hat/<name>")
@admin_level_required(3)
@admin_level_required(PERMS['MODERATE_PENDING_SUBMITTED_HATS'])
def approve_hat(v, name):
if AEVANN_ID and v.id not in (AEVANN_ID, CARP_ID, SNAKES_ID):
return {"error": "Only Carp can approve hats!"}, 403
@ -345,7 +345,7 @@ def remove_hat(v, name):
@app.get("/admin/update/marseys")
@admin_level_required(3)
@admin_level_required(PERMS['UPDATE_MARSEYS'])
def update_marseys(v):
if AEVANN_ID and v.id not in (AEVANN_ID, CARP_ID, GEESE_ID, SNAKES_ID):
abort(403)
@ -354,7 +354,7 @@ def update_marseys(v):
@app.post("/admin/update/marseys")
@admin_level_required(3)
@admin_level_required(PERMS['UPDATE_MARSEYS'])
def update_marsey(v):
if AEVANN_ID and v.id not in (AEVANN_ID, CARP_ID, GEESE_ID, SNAKES_ID):
abort(403)
@ -408,7 +408,7 @@ def update_marsey(v):
@app.get("/admin/update/hats")
@admin_level_required(3)
@admin_level_required(PERMS['UPDATE_HATS'])
def update_hats(v):
if AEVANN_ID and v.id not in (AEVANN_ID, CARP_ID, GEESE_ID, SNAKES_ID):
abort(403)
@ -417,7 +417,7 @@ def update_hats(v):
@app.post("/admin/update/hats")
@admin_level_required(3)
@admin_level_required(PERMS['UPDATE_HATS'])
def update_hat(v):
if AEVANN_ID and v.id not in (AEVANN_ID, CARP_ID, GEESE_ID, SNAKES_ID):
abort(403)

View File

@ -51,7 +51,7 @@ def buy(v, award):
if award == 'benefactor' and not request.values.get("mb"):
return {"error": "You can only buy the Benefactor award with marseybux."}, 403
if award == 'ghost' and v.admin_level < 2:
if award == 'ghost' and v.admin_level < PERMS['BUY_GHOST_AWARD']:
return {"error": "Only admins can buy this award."}, 403
AWARDS = deepcopy(AWARDS2)
@ -209,7 +209,7 @@ def award_thing(v, thing_type, id):
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 > 2:
if v.admin_level >= PERMS['USER_BAN']:
log_link = f'/{thing_type}/{thing.id}'
reason = f'<a href="{log_link}">{log_link}</a>'
@ -233,7 +233,7 @@ def award_thing(v, thing_type, id):
author.ban_reason = None
send_repeatable_notification(author.id, "You have been unbanned!")
if v.admin_level > 2:
if v.admin_level >= PERMS['USER_BAN']:
ma=ModAction(
kind="unban_user",
user_id=v.id,
@ -246,7 +246,7 @@ def award_thing(v, thing_type, 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 > 2:
if v.admin_level >= PERMS['USER_BAN']:
log_link = f'/{thing_type}/{thing.id}'
reason = f'<a href="{log_link}">{log_link}</a>'
@ -294,7 +294,7 @@ def award_thing(v, thing_type, id):
badge_grant(user=author, badge_id=28)
if v.admin_level > 2:
if v.admin_level >= PERMS['USER_AGENDAPOSTER']:
ma = ModAction(
kind="agendaposter",
user_id=v.id,

View File

@ -97,7 +97,7 @@ def speak(data, v):
total += 1
if v.admin_level > 1:
if v.admin_level >= PERMS['USER_BAN']:
text = text.lower()
for i in mute_regex.finditer(text):
username = i.group(1).lower()
@ -153,7 +153,7 @@ def typing_indicator(data, v):
@socketio.on('delete')
@admin_level_required(2)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def delete(text, v):
for message in messages:

View File

@ -41,7 +41,7 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None):
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 >= 2):
if comment.author.shadowbanned and not (v and v.shadowbanned) and not (v and v.admin_level >= PERMS['USER_SHADOWBAN']):
abort(404)
if v and request.values.get("read"):
@ -52,7 +52,7 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None):
if comment.post and comment.post.club and not (v and (v.paid_dues or v.id in [comment.author_id, comment.post.author_id])): abort(403)
if not comment.parent_submission and not (v and (comment.author.id == v.id or comment.sentto == v.id)) and not (v and v.admin_level > 1) : abort(403)
if not comment.parent_submission and not (v and (comment.author.id == v.id or comment.sentto == v.id)) and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']) : abort(403)
if not pid:
if comment.parent_submission: pid = comment.parent_submission
@ -96,7 +96,7 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None):
blocked.c.target_id,
)
if not (v and v.shadowbanned) and not (v and v.admin_level >= 2):
if not (v and v.shadowbanned) and not (v and v.admin_level >= PERMS['USER_SHADOWBAN']):
comments = comments.join(Comment.author).filter(User.shadowbanned == None)
comments=comments.filter(
@ -127,7 +127,7 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None):
if request.headers.get("Authorization"): return top_comment.json
else:
if post.is_banned and not (v and (v.admin_level > 1 or post.author_id == v.id)): template = "submission_banned.html"
if post.is_banned and not (v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or post.author_id == v.id)): template = "submission_banned.html"
else: template = "submission.html"
return render_template(template, v=v, p=post, sort=sort, comment_info=comment_info, render_replies=True, sub=post.subr)
@ -156,7 +156,7 @@ def comment(v):
parent_comment_id = None
level = 1
if POLL_THREAD and parent.id == POLL_THREAD and v.admin_level < 2: abort(403)
if POLL_THREAD and parent.id == POLL_THREAD and v.admin_level < PERMS['POST_TO_POLL_THREAD']: abort(403)
elif parent_fullname.startswith("c_"):
parent = get_comment(parent_fullname.split("_")[1], v=v)
parent_comment_id = parent.id
@ -196,7 +196,7 @@ def comment(v):
file.save(oldname)
image = process_image(oldname, patron=v.patron)
if image == "": return {"error":"Image upload failed"}, 400
if v.admin_level > 2 and level == 1:
if v.admin_level >= PERMS['SITE_SETTINGS_SIDEBARS_BANNERS_BADGES'] and level == 1:
if parent_post.id == SIDEBAR_THREAD:
li = sorted(os.listdir(f'files/assets/images/{SITE_NAME}/sidebar'),
key=lambda e: int(e.split('.webp')[0]))[-1]
@ -239,7 +239,7 @@ def comment(v):
body = body.strip()
if v.admin_level > 2 and parent_post.id == SNAPPY_THREAD and level == 1:
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:
f.write('\n{[para]}\n' + body)
@ -263,7 +263,7 @@ def comment(v):
).first()
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 < 2:
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
is_bot = v.id != 12125 and (bool(request.headers.get("Authorization")) or (SITE == 'pcmemes.net' and v.id == SNAPPY_ID))
@ -914,7 +914,7 @@ def handle_wordle_action(cid, v):
def toggle_comment_nsfw(cid, v):
comment = get_comment(cid)
if comment.author_id != v.id and not v.admin_level > 1 and not (comment.post.sub and v.mods(comment.post.sub)):
if comment.author_id != v.id and not v.admin_level >= PERMS['POST_COMMENT_MODERATION'] and not (comment.post.sub and v.mods(comment.post.sub)):
abort(403)
if comment.over_18 and v.is_suspended_permanently:
@ -924,7 +924,7 @@ def toggle_comment_nsfw(cid, v):
g.db.add(comment)
if comment.author_id != v.id:
if v.admin_level > 2:
if v.admin_level >= PERMS['POST_COMMENT_MODERATION']:
ma = ModAction(
kind = "set_nsfw_comment" if comment.over_18 else "unset_nsfw_comment",
user_id = v.id,

View File

@ -239,7 +239,7 @@ def comment_idlist(page=1, v=None, nsfw=False, sort="new", t="all", gt=0, lt=0,
comments = g.db.query(Comment.id).filter(Comment.parent_submission != None, Comment.author_id.notin_(v.userblocks))
if v.admin_level < 2:
if v.admin_level < PERMS['POST_COMMENT_MODERATION']:
private = [x[0] for x in g.db.query(Submission.id).filter(Submission.private == True).all()]
comments = comments.filter(Comment.is_banned==False, Comment.deleted_utc == 0, Comment.parent_submission.notin_(private))

View File

@ -8,7 +8,7 @@ from files.helpers.lottery import *
import requests
@app.post("/lottery/end")
@admin_level_required(3)
@admin_level_required(PERMS['LOTTERY_ADMIN'])
@casino_required
def lottery_end(v):
success, message = end_lottery_session()
@ -16,7 +16,7 @@ def lottery_end(v):
@app.post("/lottery/start")
@admin_level_required(3)
@admin_level_required(PERMS['LOTTERY_ADMIN'])
@casino_required
def lottery_start(v):
start_new_lottery_session()
@ -51,7 +51,7 @@ def lottery_active(v):
return {"message": "", "stats": {"user": v.lottery_stats, "lottery": lottery, "participants": participants}}
@app.get("/admin/lottery/participants")
@admin_level_required(2)
@admin_level_required(PERMS['LOTTERY_VIEW_PARTICIPANTS'])
@casino_required
def lottery_admin(v):
participants = get_users_participating_in_lottery()

View File

@ -36,7 +36,7 @@ def unread(v):
@app.get("/notifications/modmail")
@admin_level_required(2)
@admin_level_required(PERMS['VIEW_MODMAIL'])
def notifications_modmail(v):
try: page = max(int(request.values.get("page", 1)), 1)
except: page = 1
@ -75,7 +75,7 @@ def notifications_messages(v):
Comment.parent_submission == None,
Comment.level == 1,
)
if not v.shadowbanned and v.admin_level < 3:
if not v.shadowbanned and v.admin_level < PERMS['NOTIFICATIONS_FROM_SHADOWBANNED_USERS']:
message_threads = message_threads.join(Comment.author) \
.filter(User.shadowbanned == None)
@ -258,7 +258,7 @@ def notifications(v):
or_(Comment.sentto == None, Comment.sentto == 2),
).order_by(Notification.created_utc.desc())
if not (v and (v.shadowbanned or v.admin_level > 2)):
if not (v and (v.shadowbanned or v.admin_level >= PERMS['NOTIFICATIONS_FROM_SHADOWBANNED_USERS'])):
comments = comments.join(Comment.author).filter(User.shadowbanned == None)
comments = comments.offset(25 * (page - 1)).limit(26).all()

View File

@ -83,7 +83,7 @@ def request_api_keys(v):
new_comment.top_comment_id = new_comment.id
for admin in g.db.query(User).filter(User.admin_level > 2).all():
for admin in g.db.query(User).filter(User.admin_level >= PERMS['APPS_MODERATION']).all():
notif = Notification(comment_id=new_comment.id, user_id=admin.id)
g.db.add(notif)
@ -137,7 +137,7 @@ def edit_oauth_app(v, aid):
@app.post("/admin/app/approve/<aid>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(3)
@admin_level_required(PERMS['APPS_MODERATION'])
def admin_app_approve(v, aid):
app = g.db.get(OauthApp, aid)
@ -173,7 +173,7 @@ def admin_app_approve(v, aid):
@app.post("/admin/app/revoke/<aid>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(3)
@admin_level_required(PERMS['APPS_MODERATION'])
def admin_app_revoke(v, aid):
app = g.db.get(OauthApp, aid)
@ -198,7 +198,7 @@ def admin_app_revoke(v, aid):
@app.post("/admin/app/reject/<aid>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@admin_level_required(3)
@admin_level_required(PERMS['APPS_MODERATION'])
def admin_app_reject(v, aid):
app = g.db.get(OauthApp, aid)
@ -223,7 +223,7 @@ def admin_app_reject(v, aid):
@app.get("/admin/app/<aid>")
@admin_level_required(3)
@admin_level_required(PERMS['APPS_MODERATION'])
def admin_app_id(v, aid):
aid=aid
oauth = g.db.get(OauthApp, aid)
@ -244,7 +244,7 @@ def admin_app_id(v, aid):
)
@app.get("/admin/app/<aid>/comments")
@admin_level_required(3)
@admin_level_required(PERMS['APPS_MODERATION'])
def admin_app_id_comments(v, aid):
aid=aid
@ -271,7 +271,7 @@ def admin_app_id_comments(v, aid):
@app.get("/admin/apps")
@admin_level_required(3)
@admin_level_required(PERMS['APPS_MODERATION'])
def admin_apps_list(v):
apps = g.db.query(OauthApp).order_by(OauthApp.id.desc()).all()

View File

@ -35,7 +35,7 @@ def club_post(pid, v):
abort(403)
post = get_post(pid)
if post.author_id != v.id and v.admin_level < 2: abort(403)
if post.author_id != v.id and v.admin_level < PERMS['POST_COMMENT_MODERATION']: abort(403)
if not post.club:
post.club = True
@ -106,8 +106,7 @@ def publish(pid, v):
cache.delete_memoized(frontlist)
cache.delete_memoized(User.userpagelisting)
if (v.admin_level > 0 or v.has_badge(3)) and post.sub == 'changelog':
send_changelog_message(post.permalink)
send_changelog_message(post.permalink)
if SITE == 'watchpeopledie.co':
send_wpd_message(post.permalink)
@ -168,7 +167,7 @@ def post_id(pid, anything=None, v=None, sub=None):
blocked.c.target_id,
)
if not (v and v.shadowbanned) and not (v and v.admin_level >= 2):
if not (v and v.shadowbanned) and not (v and v.admin_level >= PERMS['USER_SHADOWBAN']):
comments = comments.join(Comment.author).filter(User.shadowbanned == None)
comments=comments.filter(Comment.parent_submission == post.id, Comment.level < 10).join(
@ -258,7 +257,7 @@ def post_id(pid, anything=None, v=None, sub=None):
template = "submission.html"
if (post.is_banned or post.author.shadowbanned) \
and not (v and (v.admin_level >= 2 or post.author_id == v.id)):
and not (v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or post.author_id == v.id)):
template = "submission_banned.html"
return render_template(template, v=v, p=post, ids=list(ids),
@ -290,7 +289,7 @@ def viewmore(v, pid, sort, offset):
blocked.c.target_id,
).filter(Comment.parent_submission == pid, Comment.stickied == None, Comment.id.notin_(ids), Comment.level < 10)
if not (v and v.shadowbanned) and not (v and v.admin_level >= 2):
if not (v and v.shadowbanned) and not (v and v.admin_level >= PERMS['USER_SHADOWBAN']):
comments = comments.join(Comment.author).filter(User.shadowbanned == None)
comments=comments.join(
@ -409,14 +408,13 @@ def morecomments(v, cid):
@auth_required
def edit_post(pid, v):
p = get_post(pid)
if v.id != p.author_id and v.admin_level < PERMS['POST_EDITING']:
abort(403)
title = sanitize_raw_title(request.values.get("title", ""))
body = sanitize_raw_body(request.values.get("body", ""))
if v.id != p.author_id and v.admin_level < 2:
abort(403)
if v.id == p.author_id:
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
return {"error":"You have to type more than 280 characters!"}, 403
@ -717,8 +715,9 @@ def submit_post(v, sub=None):
sub = request.values.get("sub", "").lower().replace('/h/','').strip()
if sub == 'changelog':
allowed = g.db.query(User.id).filter(User.admin_level > 0).all() + g.db.query(Badge.user_id).filter_by(badge_id=3).all()
if sub == 'changelog' and not v.admin_level >= PERMS['POST_TO_CHANGELOG']:
# we also allow 'code contributor' badgeholders to post to the changelog hole
allowed = g.db.query(Badge.user_id).filter_by(badge_id=3).all()
allowed = [x[0] for x in allowed]
if v.id not in allowed: return error(f"You don't have sufficient permissions to post in /h/changelog")
@ -876,7 +875,7 @@ def submit_post(v, sub=None):
if len(url) > 2048:
return error("There's a 2048 character limit for URLs.")
if v and v.admin_level > 2:
if v and v.admin_level >= PERMS['POST_BETS']:
bets = []
for i in bet_regex.finditer(body):
bets.append(i.group(1))
@ -963,7 +962,7 @@ def submit_post(v, sub=None):
)
g.db.add(choice)
if v and v.admin_level > 2:
if v and v.admin_level >= PERMS['POST_BETS']:
for bet in bets:
bet = SubmissionOption(
submission_id=post.id,
@ -1067,7 +1066,7 @@ def submit_post(v, sub=None):
cache.delete_memoized(frontlist)
cache.delete_memoized(User.userpagelisting)
if (v.admin_level > 0 or v.has_badge(3)) and post.sub == 'changelog' and not post.private:
if post.sub == 'changelog' and not post.private:
send_changelog_message(post.permalink)
if not post.private and SITE == 'watchpeopledie.co':
@ -1133,7 +1132,7 @@ def undelete_post_pid(pid, v):
def toggle_post_nsfw(pid, v):
post = get_post(pid)
if post.author_id != v.id and not v.admin_level > 1 and not (post.sub and v.mods(post.sub)):
if post.author_id != v.id and not v.admin_level >= PERMS['POST_COMMENT_MODERATION'] and not (post.sub and v.mods(post.sub)):
abort(403)
if post.over_18 and v.is_suspended_permanently:
@ -1143,7 +1142,7 @@ def toggle_post_nsfw(pid, v):
g.db.add(post)
if post.author_id != v.id:
if v.admin_level > 2:
if v.admin_level >= PERMS['POST_COMMENT_MODERATION']:
ma = ModAction(
kind = "set_nsfw" if post.over_18 else "unset_nsfw",
user_id = v.id,

View File

@ -30,10 +30,10 @@ def flag_post(pid, v):
if len(reason) > 350: return {"error": "Too long."}, 400
if reason.startswith('!') and (v.admin_level > 1 or post.sub and v.mods(post.sub)):
if reason.startswith('!') and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or post.sub and v.mods(post.sub)):
post.flair = reason[1:]
g.db.add(post)
if v.admin_level > 1:
if v.admin_level >= PERMS['POST_COMMENT_MODERATION']:
ma=ModAction(
kind="flair_post",
user_id=v.id,
@ -51,7 +51,7 @@ def flag_post(pid, v):
)
g.db.add(ma)
elif reason.startswith('/h/') and (v.admin_level >= 2 or v.id == post.author_id or (reason == '/h/chudrama' and v.mods(post.sub))):
elif reason.startswith('/h/') and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or v.id == post.author_id or (reason == '/h/chudrama' and v.mods(post.sub))):
sub_from = post.sub
sub_to = reason[3:].strip().lower()
@ -95,7 +95,7 @@ def flag_post(pid, v):
g.db.add(ma)
if v.id != post.author_id:
if v.admin_level >= 3: position = 'Admin'
if v.admin_level >= PERMS['POST_COMMENT_MODERATION']: position = 'Admin'
else: position = 'Mod'
message = f"@{v.username} ({position}) has moved [{post.title}]({post.shortlink}) to /h/{post.sub}"
send_repeatable_notification(post.author_id, message)

View File

@ -61,17 +61,19 @@ def searchposts(v):
if not v.paid_dues:
posts = posts.filter(Submission.club == False)
if v.admin_level < 2:
if v.admin_level < PERMS['POST_COMMENT_MODERATION']:
posts = posts.filter(
Submission.deleted_utc == 0,
Submission.is_banned == False,
Submission.private == False,
User.shadowbanned == None)
Submission.private == False)
if v.admin_level < PERMS['USER_SHADOWBAN']:
posts = posts.filter(User.shadowbanned == None)
if 'author' in criteria:
posts = posts.filter(Submission.ghost == False)
author = get_user(criteria['author'], v=v, include_shadowbanned=False)
if author.is_private and author.id != v.id and v.admin_level < 2 and not v.eye:
if author.is_private and author.id != v.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye:
if request.headers.get("Authorization"):
return {"error": f"@{author.username}'s profile is private; You can't use the 'author' syntax on them"}, 400
return render_template("search.html",
@ -198,7 +200,7 @@ def searchcomments(v):
if 'author' in criteria:
comments = comments.filter(Comment.ghost == False)
author = get_user(criteria['author'], v=v, include_shadowbanned=False)
if author.is_private and author.id != v.id and v.admin_level < 2 and not v.eye:
if author.is_private and author.id != v.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye:
if request.headers.get("Authorization"):
return {"error": f"@{author.username}'s profile is private; You can't use the 'author' syntax on them"}, 400
@ -220,7 +222,7 @@ def searchcomments(v):
comments = apply_time_filter(t, comments, Comment)
if v.admin_level < 2:
if v.admin_level < PERMS['POST_COMMENT_MODERATION']:
private = [x[0] for x in g.db.query(Submission.id).filter(Submission.private == True).all()]
comments = comments.filter(Comment.is_banned==False, Comment.deleted_utc == 0, Comment.parent_submission.notin_(private))
@ -282,7 +284,7 @@ def searchusers(v):
)
)
if v.admin_level < 2:
if v.admin_level < PERMS['USER_SHADOWBAN']:
users = users.filter(User.shadowbanned == None)
users=users.order_by(User.username.ilike(term).desc(), User.stored_subscriber_count.desc())

View File

@ -104,7 +104,7 @@ def daily_chart(v):
@app.get("/patrons")
@app.get("/paypigs")
@admin_level_required(3)
@admin_level_required(PERMS['VIEW_PATRONS'])
def patrons(v):
if AEVANN_ID and v.id not in (AEVANN_ID, CARP_ID, SNAKES_ID): abort(404)
@ -116,7 +116,7 @@ def patrons(v):
@app.get("/badmins")
@auth_required
def admins(v):
if v and v.admin_level > 2:
if v.admin_level >= PERMS['VIEW_SORTED_ADMIN_LIST']:
admins = g.db.query(User).filter(User.admin_level>1).order_by(User.truecoins.desc()).all()
admins += g.db.query(User).filter(User.admin_level==1).order_by(User.truecoins.desc()).all()
else: admins = g.db.query(User).filter(User.admin_level>0).order_by(User.truecoins.desc()).all()
@ -137,7 +137,7 @@ def log(v):
kind = request.values.get("kind")
if v and v.admin_level > 1: types = ACTIONTYPES
if v and v.admin_level >= PERMS['USER_SHADOWBAN']: types = ACTIONTYPES
else: types = ACTIONTYPES2
if kind and kind not in types:
@ -145,7 +145,7 @@ def log(v):
actions = []
else:
actions = g.db.query(ModAction)
if not (v and v.admin_level >= 2):
if not (v and v.admin_level >= PERMS['USER_SHADOWBAN']):
actions = actions.filter(ModAction.kind.notin_(["shadowban","unshadowban"]))
if admin_id:
@ -162,7 +162,7 @@ def log(v):
next_exists=len(actions)>25
actions=actions[:25]
admins = [x[0] for x in g.db.query(User.username).filter(User.admin_level >= 2).order_by(User.username).all()]
admins = [x[0] for x in g.db.query(User.username).filter(User.admin_level >= PERMS['ADMIN_MOP_VISIBLE']).order_by(User.username).all()]
return render_template("log.html", v=v, admins=admins, types=types, admin=admin, type=kind, actions=actions, next_exists=next_exists, page=page)
@ -177,9 +177,9 @@ def log_item(id, v):
if not action: abort(404)
admins = [x[0] for x in g.db.query(User.username).filter(User.admin_level > 1).all()]
admins = [x[0] for x in g.db.query(User.username).filter(User.admin_level >= PERMS['ADMIN_MOP_VISIBLE']).all()]
if v and v.admin_level > 1: types = ACTIONTYPES
if v and v.admin_level >= PERMS['USER_SHADOWBAN']: types = ACTIONTYPES
else: types = ACTIONTYPES2
return render_template("log.html", v=v, actions=[action], next_exists=False, page=1, action=action, admins=admins, types=types)
@ -232,7 +232,7 @@ def submit_contact(v):
g.db.flush()
new_comment.top_comment_id = new_comment.id
admins = g.db.query(User).filter(User.admin_level > 2)
admins = g.db.query(User).filter(User.admin_level >= PERMS['NOTIFICATIONS_MODMAIL'])
if SITE == 'watchpeopledie.co':
admins = admins.filter(User.id != AEVANN_ID)
@ -556,7 +556,7 @@ if SITE == 'pcmemes.net':
return render_template('live.html', v=v, live=live, offline=offline)
@app.post('/live/add')
@admin_level_required(2)
@admin_level_required(PERMS['STREAMERS_MODERATION'])
def live_add(v):
link = request.values.get('link').strip()
@ -595,7 +595,7 @@ if SITE == 'pcmemes.net':
return redirect('/live')
@app.post('/live/remove')
@admin_level_required(2)
@admin_level_required(PERMS['STREAMERS_MODERATION'])
def live_remove(v):
id = request.values.get('id').strip()
if not id: abort(400)

View File

@ -345,7 +345,7 @@ def create_sub2(v):
mod = Mod(user_id=v.id, sub=sub.name)
g.db.add(mod)
admins = [x[0] for x in g.db.query(User.id).filter(User.admin_level > 1, User.id != v.id).all()]
admins = [x[0] for x in g.db.query(User.id).filter(User.admin_level >= PERMS['NOTIFICATIONS_HOLE_CREATION'], User.id != v.id).all()]
for admin in admins:
send_repeatable_notification(admin, f":!marseyparty: /h/{sub} has been created by @{v.username} :marseyparty:")
@ -366,7 +366,7 @@ def kick(v, pid):
old = post.sub
post.sub = None
if v.admin_level >= 3 and v.id != post.author_id:
if v.admin_level >= PERMS['HOLE_GLOBAL_MODERATION'] and v.id != post.author_id:
old_str = f'<a href="/h/{old}">/h/{old}</a>'
ma = ModAction(
kind='move_hole',
@ -385,7 +385,7 @@ def kick(v, pid):
g.db.add(ma)
if v.id != post.author_id:
if v.admin_level >= 3: position = 'Admin'
if v.admin_level >= PERMS['HOLE_GLOBAL_MODERATION']: position = 'Admin'
else: position = 'Mod'
message = f"@{v.username} ({position}) has moved [{post.title}]({post.shortlink}) from /h/{old} to the main feed!"
send_repeatable_notification(post.author_id, message)

View File

@ -26,7 +26,7 @@ from .login import check_for_alts
@auth_required
def upvoters_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 < 2 and not v.eye)): abort(403)
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)
@ -48,7 +48,7 @@ def upvoters_posts(v, username, uid):
@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 < 2 and not v.eye)): abort(403)
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)
@ -70,7 +70,7 @@ def upvoters_comments(v, username, uid):
@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 < 2 and not v.eye)): abort(403)
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)
@ -92,7 +92,7 @@ def downvoters_posts(v, username, uid):
@auth_required
def downvoters_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 < 2 and not v.eye)): abort(403)
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)
@ -117,7 +117,7 @@ def downvoters_comments(v, username, uid):
@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 < 2 and not v.eye)): abort(403)
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)
@ -139,7 +139,7 @@ def upvoting_posts(v, username, uid):
@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 < 2 and not v.eye)): abort(403)
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)
@ -161,7 +161,7 @@ def upvoting_comments(v, username, uid):
@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 < 2 and not v.eye)): abort(403)
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)
@ -183,7 +183,7 @@ def downvoting_posts(v, username, uid):
@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 < 2 and not v.eye)): abort(403)
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)
@ -205,7 +205,7 @@ def downvoting_comments(v, username, uid):
@auth_required
def user_upvoted_posts(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 < 2 and not v.eye)): abort(403)
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)))
@ -231,7 +231,7 @@ def user_upvoted_posts(v, username):
@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 < 2 and not v.eye)): abort(403)
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)))
@ -674,7 +674,7 @@ def message2(v, username):
if hasattr(user, 'is_blocking') and user.is_blocking:
return {"error": "You're blocking this user."}, 403
if v.admin_level <= 1 and hasattr(user, 'is_blocked') and user.is_blocked:
if v.admin_level <= PERMS['MESSAGE_BLOCKED_USERS'] and hasattr(user, 'is_blocked') and user.is_blocked:
return {"error": "This user is blocking you."}, 403
message = request.values.get("message", "").strip()[:10000].strip()
@ -810,7 +810,7 @@ def messagereply(v):
if c.top_comment.sentto == 2:
admins = g.db.query(User.id).filter(User.admin_level > 2, User.id != v.id)
admins = g.db.query(User.id).filter(User.admin_level >= PERMS['NOTIFICATIONS_MODMAIL'], User.id != v.id)
if SITE == 'watchpeopledie.co':
admins = admins.filter(User.id != AEVANN_ID)
@ -961,7 +961,7 @@ def u_username(username, v=None):
g.db.commit()
if u.is_private and (not v or (v.id != u.id and v.admin_level < 2 and not v.eye)):
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)):
if request.headers.get("Authorization") or request.headers.get("xhr") or request.path.endswith(".json"):
return {"error": "This userpage is private"}, 403
@ -1049,7 +1049,7 @@ def u_username_comments(username, v=None):
return render_template("userpage_reserved.html", u=u, v=v)
if u.is_private and (not v or (v.id != u.id and v.admin_level < 2 and not v.eye)):
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)):
if request.headers.get("Authorization") or request.headers.get("xhr") or request.path.endswith(".json"):
return {"error": "This userpage is private"}, 403
return render_template("userpage_private.html", u=u, v=v)
@ -1074,7 +1074,7 @@ def u_username_comments(username, v=None):
Comment.parent_submission != None
)
if not v or (v.id != u.id and v.admin_level < 2):
if not v or (v.id != u.id and v.admin_level < PERMS['POST_COMMENT_MODERATION']):
comments = comments.filter(
Comment.is_banned == False,
Comment.ghost == False,

View File

@ -10,19 +10,21 @@
<pre></pre>
<h3 class="pb-2">Admin Tools</h3>
{% if v.admin_level > 2 and (SITE_NAME == 'rDrama' or SIDEBAR_THREAD or BANNER_THREAD or BADGE_THREAD or SNAPPY_THREAD) %}
{% if (v.admin_level >= PERMS['SITE_SETTINGS_SIDEBARS_BANNERS_BADGES'] or v.admin_level >= PERMS['SITE_SETTINGS_SNAPPY_QUOTES']) and (SITE_NAME == 'rDrama' or SIDEBAR_THREAD or BANNER_THREAD or BADGE_THREAD or SNAPPY_THREAD) %}
<h4>Add Stuff</h4>
<ul>
{% if SIDEBAR_THREAD %}
<li><a href="/post/{{SIDEBAR_THREAD}}">Add Sidebar Images</a></li>
{% if v.admin_level >= PERMS['SITE_SETTINGS_SIDEBARS_BANNERS_BADGES'] %}
{% if SIDEBAR_THREAD %}
<li><a href="/post/{{SIDEBAR_THREAD}}">Add Sidebar Images</a></li>
{% endif %}
{% if BANNER_THREAD %}
<li><a href="/post/{{BANNER_THREAD}}">Add Banners</a></li>
{% endif %}
{% if BADGE_THREAD %}
<li><a href="/post/{{BADGE_THREAD}}">Add Badges</a></li>
{% endif %}
{% endif %}
{% if BANNER_THREAD %}
<li><a href="/post/{{BANNER_THREAD}}">Add Banners</a></li>
{% endif %}
{% if BADGE_THREAD %}
<li><a href="/post/{{BADGE_THREAD}}">Add Badges</a></li>
{% endif %}
{% if SNAPPY_THREAD %}
{% if SNAPPY_THREAD and v.admin_level >= PERMS['SITE_SETTINGS_SNAPPY_QUOTES'] %}
<li><a href="/post/{{SNAPPY_THREAD}}">Add Snappy Quotes</a></li>
{% endif %}
{% if SITE_NAME == 'rDrama' %}
@ -35,16 +37,22 @@
<h4>Content</h4>
<ul>
<li><a href="/log">Moderation Log</a></li>
<li><a href="/admin/image_posts">Image Posts</a></li>
<li><a href="/admin/reported/posts">Reported Posts/Comments</a></li>
<li><a href="/admin/removed/posts">Removed Posts/Comments</a></li>
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
<li><a href="/admin/image_posts">Image Posts</a></li>
<li><a href="/admin/reported/posts">Reported Posts/Comments</a></li>
<li><a href="/admin/removed/posts">Removed Posts/Comments</a></li>
{% endif %}
</ul>
<h4>Users</h4>
<ul>
<li><a href="/admin/users">Users Feed</a></li>
<li><a href="/admin/shadowbanned">Shadowbanned Users</a></li>
<li><a href="/banned">Permabanned Users</a></li>
{% if v.admin_level >= PERMS['VIEW_ALL_USERS'] %}
<li><a href="/admin/users">Users Feed</a></li>
{% endif %}
{% if v.admin_level >= PERMS['USER_SHADOWBAN'] %}
<li><a href="/admin/shadowbanned">Shadowbanned Users</a></li>
{% endif %}
<li><a href="/banned">Permabanned Users</a></li>
{% if FEATURES['AWARDS'] -%}
<li><a href="/agendaposters">Users with Chud Theme</a></li>
<li><a href="/grassed">Currently Grassed Users</a></li>
@ -52,8 +60,10 @@
{% if FEATURES['PROCOINS'] and (not AEVANN_ID or v.id in (AEVANN_ID, CARP_ID, SNAKES_ID)) -%}
<li><a href="/patrons">Patrons</a></li>
{%- endif %}
<li><a href="/admin/loggedin">Currently Logged-in Users</a></li>
<li><a href="/admin/loggedout">Currently Logged-out Users</a></li>
{% if v.admin_level >= PERMS['VIEW_ACTIVE_USERS'] %}
<li><a href="/admin/loggedin">Currently Logged-in Users</a></li>
<li><a href="/admin/loggedout">Currently Logged-out Users</a></li>
{% endif %}
</ul>
<h4>Safety</h4>
@ -65,7 +75,7 @@
{% if FEATURES['BADGES'] or FEATURES['AWARDS'] -%}
<h4>Grant</h4>
<ul>
{% if FEATURES['BADGES'] -%}
{% if FEATURES['BADGES'] and v.admin_level >= PERMS['USER_BADGES'] -%}
<li><a href="/admin/badge_grant">Grant Badges</a></li>
<li><a href="/admin/badge_remove">Remove Badges</a></li>
{%- endif %}
@ -89,11 +99,15 @@
<h4>Configuration</h4>
<ul>
<li><a href="/create_hole">Create {{ HOLE_NAME | capitalize }}</a></li>
<li><a href="/admin/apps">Apps</a></li>
{% if v.admin_level >= PERMS['HOLE_CREATE'] %}
<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>
{% endif %}
</ul>
{% if v.admin_level > 2 %}
{% if v.admin_level >= PERMS['SITE_SETTINGS'] %}
<pre></pre>
<div class="custom-control custom-switch">
<input autocomplete="off" type="checkbox" class="custom-control-input" id="signups" {% if site_settings['Signups'] %}checked{% endif %} onchange="post_toast(this,'/admin/site_settings/Signups');">
@ -119,15 +133,17 @@
<input autocomplete="off" type="checkbox" class="custom-control-input" id="Read-only mode" {% if site_settings['Read-only mode'] %}checked{% endif %} onchange="post_toast(this,'/admin/site_settings/Read-only mode');">
<label class="custom-control-label" for="Read-only mode">Read-only mode</label>
</div>
<div class="custom-control custom-switch">
<input autocomplete="off" type="checkbox" class="custom-control-input" id="under_attack" name="under_attack" {% if under_attack%}checked{% endif %} onchange="post_toast(this,'/admin/under_attack');">
<label class="custom-control-label" for="under_attack">Under attack mode</label>
</div>
<button class="btn btn-primary mt-3" onclick="post_toast(this,'/admin/purge_cache');" style="margin-bottom: 2em;">PURGE CACHE</button>
{% if v.admin_level >= PERMS['SITE_SETTINGS_UNDER_ATTACK'] %}
<div class="custom-control custom-switch">
<input autocomplete="off" type="checkbox" class="custom-control-input" id="under_attack" name="under_attack" {% if under_attack%}checked{% endif %} onchange="post_toast(this,'/admin/under_attack');">
<label class="custom-control-label" for="under_attack">Under attack mode</label>
</div>
{% endif %}
{% if v.admin_level >= PERMS['SITE_CACHE_PURGE_CDN'] %}
<button class="btn btn-primary mt-3" onclick="post_toast(this,'/admin/purge_cache');" style="margin-bottom: 2em;">PURGE CACHE</button>
{% endif %}
<br>
{% if SITE_NAME == 'PCM' %}
{% if SITE_NAME == 'PCM' and v.admin_level >= PERMS['PRINT_MARSEYBUX_FOR_KIPPY_ON_PCMEMES'] %}
<button class="btn btn-primary" onclick="post_toast(this,'/kippy');" style="margin-bottom: 2em;">Print 10k Marseybux</button>
{% endif %}
{% endif %}

View File

@ -32,7 +32,7 @@
id="root"
data-id="{{v.id}}"
data-username="{{v.username}}"
data-admin="{{v.admin_level > 1}}"
data-admin="{{v.admin_level >= PERMS['ADMIN_MOP_VISIBLE']}}"
data-censored="{{v.slurreplacer}}"
data-sitename="{{SITE_NAME}}"
data-themecolor="{{v.themecolor}}"

View File

@ -21,14 +21,14 @@
{% set score=ups-downs %}
{% if render_replies %}
{% if v and (v.shadowbanned or v.admin_level >= 2) %}
{% if v and (v.shadowbanned or v.admin_level >= PERMS['USER_SHADOWBAN']) %}
{% set replies=c.replies3(sort) %}
{% else %}
{% set replies=c.replies(sort) %}
{% endif %}
{% endif %}
{% if c.is_blocking and not c.ghost or (c.is_banned or c.deleted_utc) and not (v and v.admin_level > 1) and not (v and v.id==c.author_id) %}
{% if c.is_blocking and not c.ghost or (c.is_banned or c.deleted_utc) and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']) and not (v and v.id==c.author_id) %}
<div id="comment-{{c.id}}" class="comment">
<span class="comment-collapse-desktop d-none d-md-block" style="border-left: 2px solid #{{c.author.name_color}}"onclick="collapse_comment('{{c.id}}', this.parentElement)"></span>
@ -140,7 +140,7 @@
{% 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 > 1 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 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 %}
<i id='pinned-{{c.id}}'class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Pinned by @{{c.stickied}}" {% if c.stickied_utc %}onmouseover="pinned_timestamp('pinned-{{c.id}}')" data-timestamp={{c.stickied_utc}} {% endif %}></i>
{% endif %}
@ -298,7 +298,7 @@
<div class="post-actions">
<ul class="list-inline text-right d-flex">
<li class="list-inline-item mr-auto">
{% if v and v.admin_level > 1 %}
{% if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
<a role="button" data-bs-toggle="modal" data-bs-target="#adminModal-{{c.id}}">
<i class="fas fa-broom"></i>
</a>
@ -315,7 +315,7 @@
</a>
</li>
{% if v and request.path.startswith('/@') and v.admin_level < 2 %}
{% if v and request.path.startswith('/@') and v.admin_level < PERMS['VIEW_VOTE_BUTTONS_ON_USER_PAGE'] %}
<li id="voting-{{c.id}}-mobile" class="voting list-inline-item d-md-none">
{% if voted==1 %}
<span class="mr-2 arrow-up comment-{{c.id}}-up active"></span>
@ -366,7 +366,7 @@
<ul class="d-none d-md-flex list-inline text-right text-md-left"><li>
{% if v and request.path.startswith('/@') and v.admin_level < 2%}
{% if v and request.path.startswith('/@') and v.admin_level < PERMS['VIEW_VOTE_BUTTONS_ON_USER_PAGE'] %}
{% if voted==1 %}
<button class="btn caction py-0 m-0 px-3 nobackground arrow-up mx-0 comment-{{c.id}}-up active"></button>
{% endif %}
@ -383,7 +383,7 @@
<span data-bs-toggle="tooltip" data-bs-placement="top" title="+{{ups}} | -{{downs}}" class="comment-score-{{c.id}} score comment-score-{{c.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}{% if c.controversial %} controversial{% endif %}">{{score}}</span>
</button>
{% if v and request.path.startswith('/@') and v.admin_level < 2 %}
{% if v and request.path.startswith('/@') and v.admin_level < PERMS['VIEW_VOTE_BUTTONS_ON_USER_PAGE'] %}
{% if voted==-1 %}
<li class=" arrow-down py-0 m-0 px-3 comment-{{c.id}}-down active"></li>
{% endif %}
@ -432,7 +432,7 @@
<button style="margin-top:0.2rem" class="btn caction py-0 nobackground px-1 text-muted" data-bs-toggle="dropdown" aria-expanded="false"><i class="fas fa-ellipsis-h fa-fw"></i></button>
<ul class="dropdown-menu">
{% if v.admin_level and v.id==c.author_id %}
{% if v.admin_level >= PERMS['POST_COMMENT_DISTINGUISH'] and (v.id == c.author_id or v.admin_level >= PERMS['POST_COMMENT_MODERATION']) %}
<button id="undistinguish-{{c.id}}" class="dropdown-item list-inline-item d-none {% if c.distinguish_level %}d-md-block{% endif %} text-info" onclick="post_toast(this,'/distinguish_comment/{{c.id}}','distinguish-{{c.id}}','undistinguish-{{c.id}}','d-md-block')"><i class="fas fa-id-badge text-info fa-fw"></i>Undistinguish</button>
<button id="distinguish-{{c.id}}" class="dropdown-item list-inline-item d-none {% if not c.distinguish_level %}d-md-block{% endif %} text-info" onclick="post_toast(this,'/distinguish_comment/{{c.id}}','distinguish-{{c.id}}','undistinguish-{{c.id}}','d-md-block')"><i class="fas fa-id-badge text-info fa-fw"></i>Distinguish</button>
{% endif %}
@ -446,7 +446,7 @@
{% if c.post %}
{% set url = "" %}
{% if v.admin_level > 1%}
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
{% set url = "sticky_comment" %}
{% elif v.id == c.post.author_id %}
{% set url = "pin_comment" %}
@ -462,7 +462,7 @@
{% endif %}
{% if v.admin_level > 1 %}
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
{% if "/reported/" in request.path %}
<button class="dropdown-item list-inline-item text-success" onclick="approveComment('{{c.id}}')"><i class="fas fa-check text-success fa-fw"></i>Approve</button>
<button class="dropdown-item list-inline-item text-danger" onclick="removeComment('{{c.id}}')"><i class="fas fa-ban text-danger fa-fw"></i>Remove</button>
@ -480,17 +480,17 @@
{% endif %}
{% endif %}
{% if c.parent_submission and (c.author_id==v.id or v.admin_level > 1 or (c.post.sub and v.mods(c.post.sub))) %}
{% if c.parent_submission and (c.author_id==v.id or v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or (c.post.sub and v.mods(c.post.sub))) %}
<button id="unmark-{{c.id}}" class="dropdown-item list-inline-item d-none {% if c.over_18 %}d-md-block{% endif %} text-danger" onclick="post_toast(this,'/toggle_comment_nsfw/{{c.id}}','mark-{{c.id}}','unmark-{{c.id}}','d-md-block')"><i class="fas fa-eye-evil text-danger fa-fw"></i>Unmark +18</button>
<button id="mark-{{c.id}}" class="dropdown-item list-inline-item d-none {% if not c.over_18 %}d-md-block{% endif %} text-danger" onclick="post_toast(this,'/toggle_comment_nsfw/{{c.id}}','mark-{{c.id}}','unmark-{{c.id}}','d-md-block')"><i class="fas fa-eye-evil text-danger fa-fw"></i>Mark +18</button>
{% endif %}
{% if v.admin_level > 1 and v.id != c.author_id %}
{% if v.admin_level >= PERMS['USER_BAN'] and v.id != c.author_id %}
<button id="unban-{{c.id}}" class="dropdown-item list-inline-item d-none {% if c.author.is_suspended %}d-md-block{% endif %} text-success" onclick="post_toast(this,'/unban_user/{{c.author_id}}','ban-{{c.id}}','unban-{{c.id}}','d-md-block')"><i class="fas fa-user-slash text-success fa-fw"></i>Unban user</button>
<button id="ban-{{c.id}}" class="dropdown-item list-inline-item d-none {% if not c.author.is_suspended %}d-md-block{% endif %} text-danger" data-bs-toggle="modal" data-bs-target="#banModal" onclick="banModal('/comment/{{c.id}}', '{{c.author.id}}', '{{c.author_name}}')"><i class="fas fa-user-slash text-danger fa-fw"></i>Ban user</button>
{% endif %}
{% if v.admin_level > 1 and c.oauth_app %}
{% if v.admin_level >= PERMS['APPS_MODERATION'] and c.oauth_app %}
<a href="{{c.oauth_app.permalink}}/comments" class="dropdown-item list-inline-item d-none d-md-block text-primary"><i class="fas fa-code text-primary fa-fw"></i>API App</a>
{% endif %}
</ul>
@ -567,7 +567,7 @@
</div>
{% if request.path.startswith('/notifications') and c.level == 1 and c.sentto and not c.parent_submission and c.author_id != AUTOJANNY_ID %}
{% if (v and v.admin_level >= 2) and (c.sentto == 2) and not c.author.is_muted %}
{% if (v and v.admin_level >= PERMS['USER_BAN']) and (c.sentto == 2) and not c.author.is_muted %}
<a class="btn btn-primary" role="button" id="mute-user-{{c.id}}" onclick="adminMuteUser({{c.author_id}}, 1, {{c.id}})">Mute</a>
{% endif %}
@ -653,7 +653,7 @@
<a id="unmark2-{{c.id}}" class="{% if not c.over_18 %}d-none{% endif %} list-group-item text-danger" role="button" onclick="post_toast(this,'/toggle_comment_nsfw/{{c.id}}','mark2-{{c.id}}','unmark2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-eye-evil text-danger mr-2"></i>Unmark +18</a>
{% endif %}
{% if v.admin_level < 2 %}
{% if v.admin_level < PERMS['POST_COMMENT_MODERATION'] %}
{% if c.post and v.id == c.post.author_id %}
<a id="pin2-{{c.id}}" class="list-group-item {% if c.stickied %}d-none{% endif %} text-info" role="button" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast(this,'/pin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info mr-2"></i>Pin</a>
<a id="unpin2-{{c.id}}" class="list-group-item {% if not c.stickied %}d-none{% endif %} text-info" role="button" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast(this,'/unpin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info mr-2"></i>Unpin</a>
@ -682,7 +682,7 @@
{% if v and v.admin_level > 1 %}
{% if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION_TOOLS_VISIBLE'] %}
<div class="modal fade d-md-none" id="adminModal-{{c.id}}" tabindex="-1" role="dialog" aria-labelledby="actionsModalTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
@ -707,20 +707,21 @@
<a id="unmark2-{{c.id}}" class="{% if not c.over_18 %}d-none{% endif %} list-group-item text-danger" role="button" onclick="post_toast(this,'/toggle_comment_nsfw/{{c.id}}','mark2-{{c.id}}','unmark2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-eye-evil text-danger mr-2"></i>Unmark +18</a>
{% endif %}
{% if v.id != c.author_id %}
{% if v.id != c.author_id and v.admin_level >= PERMS['USER_BAN'] %}
<a id="ban2-{{c.id}}" class="{% if c.author.is_banned %}d-none{% endif %} list-group-item text-danger" data-bs-dismiss="modal" data-bs-toggle="modal" data-bs-target="#banModal" onclick="banModal('/comment/{{c.id}}', '{{c.author.id}}', '{{c.author_name}}')" role="button"><i class="fas fa-user-slash text-danger fa-fw mr-2"></i>Ban user</a>
<a id="unban2-{{c.id}}" class="{% if not c.author.is_banned %}d-none{% endif %} list-group-item text-success" role="button" onclick="post_toast(this,'/unban_user/{{c.author_id}}','ban2-{{c.id}}','unban2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-user-minus fa-fw text-success mr-2"></i>Unban user</a>
{% endif %}
{% if "/reported/" in request.path %}
<a class="list-group-item text-danger" role="button" onclick="removeComment2('{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-ban text-danger mr-2"></i>Remove</a>
<a class="list-group-item text-success" role="button" onclick="approveComment2('{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-check text-success mr-2"></i>Approve</a>
{% else %}
<a id="remove2-{{c.id}}" class="{% if c.is_banned %}d-none{% endif %} list-group-item text-danger" role="button" onclick="removeComment2('{{c.id}}','approve2-{{c.id}}','remove2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-ban text-danger mr-2"></i>Remove</a>
<a id="approve2-{{c.id}}" class="{% if not c.is_banned %}d-none{% endif %} list-group-item text-success" role="button" onclick="approveComment2('{{c.id}}','approve2-{{c.id}}','remove2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-check text-success mr-2"></i>Approve</a>
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
{% if "/reported/" in request.path %}
<a class="list-group-item text-danger" role="button" onclick="removeComment2('{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-ban text-danger mr-2"></i>Remove</a>
<a class="list-group-item text-success" role="button" onclick="approveComment2('{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-check text-success mr-2"></i>Approve</a>
{% else %}
<a id="remove2-{{c.id}}" class="{% if c.is_banned %}d-none{% endif %} list-group-item text-danger" role="button" onclick="removeComment2('{{c.id}}','approve2-{{c.id}}','remove2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-ban text-danger mr-2"></i>Remove</a>
<a id="approve2-{{c.id}}" class="{% if not c.is_banned %}d-none{% endif %} list-group-item text-success" role="button" onclick="approveComment2('{{c.id}}','approve2-{{c.id}}','remove2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-check text-success mr-2"></i>Approve</a>
{% endif %}
{% endif %}
{% if c.oauth_app %}
{% if c.oauth_app and v.admin_level >= PERMS['APPS_MODERATION'] %}
<a href="{{c.oauth_app.permalink}}/comments" class="list-group-item text-info"><i class="fas fa-code text-info mr-2"></i>API App</a>
{% endif %}
</ul>
@ -755,7 +756,7 @@
{% if v %}
{% include "gif_modal.html" %}
{% include "emoji_modal.html" %}
{% if v.admin_level > 1 %}
{% if v.admin_level >= PERMS['USER_BAN'] %}
{% include "ban_modal.html" %}
{% endif %}
@ -819,7 +820,7 @@
<script defer src="{{'js/clipboard.js' | asset}}"></script>
{% if v and v.admin_level >= 2 %}
{% if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION_TOOLS_VISIBLE'] %}
<script defer src="{{'js/comments_admin.js' | asset}}"></script>
{% endif %}

View File

@ -116,7 +116,7 @@
{% endif %}
{% if not err %}
{% if v and v.admin_level > 1 %}
{% if v and v.admin_level >= PERMS['ADMIN_HOME_VISIBLE'] %}
<a class="mobile-nav-icon d-md-none" href="/admin"><i class="fas fa-crown align-middle text-gray-500 black"></i></a>
{% endif %}
@ -161,7 +161,7 @@
</li>
{% endif %}
{% if v.admin_level > 1 %}
{% if v.admin_level >= PERMS['ADMIN_HOME_VISIBLE'] %}
<li class="nav-item d-flex align-items-center justify-content-center text-center mx-1">
<a class="nav-link" href="/admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Admin Tools"><i class="fas fa-crown"></i></a>
</li>

View File

@ -54,7 +54,7 @@
<td>{{name}}</td>
<td>{{title}}</td>
<td>{{viewers}} watching</td>
{% if v and v.admin_level > 1 %}
{% if v and v.admin_level >= PERMS['STREAMERS_MODERATION'] %}
<td>
<form action="/live/remove" method="post">
<input type="hidden" name="formkey" value="{{v.formkey}}">
@ -80,7 +80,7 @@
<td>{{name}}</td>
<td>{{actual}} ago</td>
<td>{{views}} views</td>
{% if v and v.admin_level > 1 %}
{% if v and v.admin_level >= PERMS['STREAMERS_MODERATION'] %}
<td>
<form action="/live/remove" method="post">
<input type="hidden" name="formkey" value="{{v.formkey}}">
@ -96,7 +96,7 @@
</table>
</div>
{% if v and v.admin_level > 1 %}
{% if v and v.admin_level >= PERMS['STREAMERS_MODERATION'] %}
<form action="/live/add" method="post">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input class="form-control" autocomplete="off" type="text" name="link" class="form-control" placeholder="Enter channel link.." required>

View File

@ -10,7 +10,7 @@
/>
</div>
<div class="lottery-page--stats">
{% if v.admin_level > 2 %}
{% if v.admin_level >= PERMS['LOTTERY_ADMIN'] %}
<div
class="lottery-page--stat"
style="position: relative; padding-top: 1rem; overflow: hidden"

View File

@ -37,7 +37,7 @@
</a>
</li>
{% endif %}
{% if v.admin_level >= 2 %}
{% if v.admin_level >= PERMS['VIEW_MODMAIL'] %}
<li class="nav-item">
<a class="nav-link py-3{% if request.path == '/notifications/modmail' %} active{% endif %}" href="/notifications/modmail">
Modmail

View File

@ -40,12 +40,12 @@
{% if v %}
<a class="list-inline-item" role="button" data-bs-toggle="dropdown" aria-expanded="false"><i class="fas fa-ellipsis-h fa-fw"></i></a>
<ul class="dropdown-menu">
{% if v.admin_level %}
{% if v.admin_level >= PERMS['POST_COMMENT_DISTINGUISH'] %}
<a id="distinguish-{{p.id}}" class="dropdown-item {% if p.distinguish_level %}d-none{% endif %} list-inline-item text-info" role="button" onclick="post_toast(this,'/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}','d-none')"><i class="fas fa-crown"></i>Distinguish</a>
<a id="undistinguish-{{p.id}}" class="dropdown-item {% if not p.distinguish_level %}d-none{% endif %} list-inline-item text-info" role="button" onclick="post_toast(this,'/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}','d-none')"><i class="fas fa-crown"></i>Undistinguish</a>
{% endif %}
{% if v.admin_level > 1 %}
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
<a id="pin-{{p.id}}" class="dropdown-item {% if p.stickied %}d-none{% endif %} list-inline-item text-info" role="button" onclick="post_toast(this,'/sticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}','d-none')"><i class="fas fa-thumbtack fa-rotate--45"></i>Pin</a>
<a id="unpin-{{p.id}}" class="dropdown-item {% if not p.stickied %}d-none{% endif %} list-inline-item text-info" role="button" onclick="post_toast(this,'/unsticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}','d-none')"><i class="fas fa-thumbtack fa-rotate--45"></i>Unpin</a>
{% endif %}
@ -55,12 +55,12 @@
<a id="hole-unpin-{{p.id}}" class="dropdown-item {% if not p.hole_pinned %}d-none{% endif %} list-inline-item text-info" role="button" onclick="post_toast(this,'/hole_unpin/{{p.id}}','hole-pin-{{p.id}}','hole-unpin-{{p.id}}','d-none')"><i class="fas fa-thumbtack fa-rotate--45"></i>Unpin from /h/{{p.sub}}</a>
{% endif %}
{% if FEATURES['COUNTRY_CLUB'] and (v.admin_level > 1 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,'/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>
{% 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>
{% endif %}
{% if v.admin_level > 1 %}
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
{% if "/reported/" in request.path %}
{% if v.id != p.author.id %}<a class="dropdown-item list-inline-item text-danger" role="button" onclick="post_toast(this,'/remove_post/{{p.id}}')"><i class="fas fa-ban"></i>Remove</a>{% endif %}
<a class="dropdown-item list-inline-item text-success" role="button" onclick="post_toast(this,'/approve_post/{{p.id}}')"><i class="fas fa-check"></i>Approve</a>
@ -93,12 +93,12 @@
{% endif %}
{% if v.id==p.author_id or v.admin_level > 1 or (p.sub and v.mods(p.sub)) %}
{% if v.id==p.author_id or v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or (p.sub and v.mods(p.sub)) %}
<a id="mark-{{p.id}}" class="dropdown-item {% if p.over_18 %}d-none{% endif %} list-inline-item text-danger" role="button" onclick="post_toast(this,'/toggle_post_nsfw/{{p.id}}','mark-{{p.id}}','unmark-{{p.id}}','d-none')"><i class="fas fa-eye-evil"></i>Mark +18</a>
<a id="unmark-{{p.id}}" class="dropdown-item {% if not p.over_18 %}d-none{% endif %} list-inline-item text-success" role="button" onclick="post_toast(this,'/toggle_post_nsfw/{{p.id}}','mark-{{p.id}}','unmark-{{p.id}}','d-none')"><i class="fas fa-eye-evil"></i>Unmark +18</a>
{% endif %}
{% if v.admin_level > 1 and v.id != p.author_id %}
{% if v.admin_level >= PERMS['USER_BAN'] and v.id != p.author_id %}
<a id="ban-{{p.id}}" class="dropdown-item {% if p.author.is_suspended %}d-none{% endif %} list-inline-item text-danger" id="exile-comment-{{p.id}}" role="button" data-bs-toggle="modal" data-bs-target="#banModal" onclick="banModal('/post/{{p.id}}', '{{p.author.id}}', '{{p.author_name}}')"><i class="fas fa-user-slash text-danger fa-fw"></i>Ban user</a>
<a id="unban-{{p.id}}" class="dropdown-item {% if not p.author.is_suspended %}d-none{% endif %} list-inline-item text-danger" id="unexile2-user-{{p.id}}" role="button" onclick="post_toast(this,'/unban_user/{{p.author_id}}','ban-{{p.id}}','unban-{{p.id}}','d-none')"><i class="fas fa-user-slash"></i>Unban user</a>
{% endif %}

View File

@ -9,7 +9,7 @@
</div>
<div class="modal-body">
<ul class="list-group post-actions">
{% if (request.path.startswith('/post/') or request.path.startswith('/h/')) and v.admin_level > 2 and p.id %}
{% if (request.path.startswith('/post/') or request.path.startswith('/h/')) and v.admin_level >= PERMS['POST_EDITING'] and p.id %}
<button class="nobackground btn btn-link btn-block btn-lg text-left text-muted" data-bs-dismiss="modal" onclick="togglePostEdit('{{p.id}}')"><i class="far fa-edit text-center text-muted mr-2"></i>Edit</button>
{% endif %}
@ -17,31 +17,30 @@
<button id="club2-{{p.id}}" class="{% if p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-info text-left" role="button" onclick="post_toast(this,'/club_post/{{p.id}}','club2-{{p.id}}','unclub2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-eye-slash mr-2"></i>Mark club</button>
<button id="unclub2-{{p.id}}" class="{% if not p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-info text-left" role="button" onclick="post_toast(this,'/unclub_post/{{p.id}}','club2-{{p.id}}','unclub2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-eye mr-2"></i>Unmark club</button>
{%- endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_DISTINGUISH'] and (v.id == c.author_id or v.admin_level >= PERMS['POST_COMMENT_MODERATION']) %}
<button id="distinguish2-{{p.id}}" class="{% if p.distinguish_level %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" role="button" onclick="post_toast(this,'/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-crown text-center text-primary mr-2"></i>Distinguish</button>
<button id="undistinguish2-{{p.id}}" class="{% if not p.distinguish_level %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" role="button" onclick="post_toast(this,'/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-crown text-center text-primary mr-2"></i>Undistinguish</button>
<button id="pin2-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" role="button" onclick="post_toast(this,'/sticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center text-primary mr-2"></i>Pin</button>
<button id="unpin2-{{p.id}}" class="{% if not p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" role="button" onclick="post_toast(this,'/unsticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center text-primary mr-2"></i>Unpin</button>
{% if "/reported/" in request.path %}
<button class="nobackground btn btn-link btn-block btn-lg text-danger text-left" role="button" onclick="post_toast(this,'/remove_post/{{p.id}}')" data-bs-dismiss="modal"><i class="far fa-ban text-center mr-2"></i>Remove</button>
<button class="nobackground btn btn-link btn-block btn-lg text-success text-left" role="button" onclick="post_toast(this,'/approve_post/{{p.id}}')" data-bs-dismiss="modal"><i class="far fa-check text-center mr-2"></i>Approve</button>
{% else %}
<button id="remove2-{{p.id}}" class="{% if p.is_banned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-danger text-left" role="button" onclick="post_toast(this,'/remove_post/{{p.id}}','remove2-{{p.id}}','approve2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="far fa-ban text-center mr-2"></i>Remove</button>
<button id="approve2-{{p.id}}" class="{% if not p.is_banned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-success text-left" role="button" onclick="post_toast(this,'/approve_post/{{p.id}}','remove2-{{p.id}}','approve2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="far fa-check text-center mr-2"></i>Approve</button>
{% endif %}
{% if p.oauth_app %}
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
<button id="pin2-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" role="button" onclick="post_toast(this,'/sticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center text-primary mr-2"></i>Pin</button>
<button id="unpin2-{{p.id}}" class="{% if not p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" role="button" onclick="post_toast(this,'/unsticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center text-primary mr-2"></i>Unpin</button>
{% if "/reported/" in request.path %}
<button class="nobackground btn btn-link btn-block btn-lg text-danger text-left" role="button" onclick="post_toast(this,'/remove_post/{{p.id}}')" data-bs-dismiss="modal"><i class="far fa-ban text-center mr-2"></i>Remove</button>
<button class="nobackground btn btn-link btn-block btn-lg text-success text-left" role="button" onclick="post_toast(this,'/approve_post/{{p.id}}')" data-bs-dismiss="modal"><i class="far fa-check text-center mr-2"></i>Approve</button>
{% else %}
<button id="remove2-{{p.id}}" class="{% if p.is_banned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-danger text-left" role="button" onclick="post_toast(this,'/remove_post/{{p.id}}','remove2-{{p.id}}','approve2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="far fa-ban text-center mr-2"></i>Remove</button>
<button id="approve2-{{p.id}}" class="{% if not p.is_banned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-success text-left" role="button" onclick="post_toast(this,'/approve_post/{{p.id}}','remove2-{{p.id}}','approve2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="far fa-check text-center mr-2"></i>Approve</button>
{% endif %}
{% endif %}
{% if p.oauth_app and v.admin_level >= PERMS['APPS_MODERATION'] %}
<a href="{{p.oauth_app.permalink}}"><button class="nobackground btn btn-link btn-block btn-lg text-muted text-left"><i class="far fa-code text-center text-info mr-2"></i>API App</button></a>
{% endif %}
<button id="mark2-{{p.id}}" class="{% if p.over_18 %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-danger" onclick="post_toast(this,'/toggle_post_nsfw/{{p.id}}','mark2-{{p.id}}','unmark2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="far fa-eye-evil text-center text-danger mr-2"></i>Mark +18</button>
<button id="unmark2-{{p.id}}" class="{% if not p.over_18 %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-danger" onclick="post_toast(this,'/toggle_post_nsfw/{{p.id}}','mark2-{{p.id}}','unmark2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="far fa-eye-evil text-center text-danger mr-2"></i>Unmark +18</button>
{% if v.id != p.author_id %}
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
<button id="mark2-{{p.id}}" class="{% if p.over_18 %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-danger" onclick="post_toast(this,'/toggle_post_nsfw/{{p.id}}','mark2-{{p.id}}','unmark2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="far fa-eye-evil text-center text-danger mr-2"></i>Mark +18</button>
<button id="unmark2-{{p.id}}" class="{% if not p.over_18 %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-danger" onclick="post_toast(this,'/toggle_post_nsfw/{{p.id}}','mark2-{{p.id}}','unmark2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="far fa-eye-evil text-center text-danger mr-2"></i>Unmark +18</button>
{% endif %}
{% if v.id != p.author_id and v.admin_level >= PERMS['USER_BAN'] %}
<button id="ban2-{{p.id}}" data-bs-dismiss="modal" data-bs-toggle="modal" data-bs-target="#banModal" onclick="banModal('/post/{{p.id}}', '{{p.author.id}}', '{{p.author_name}}')" class="{% if p.author.is_suspended %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-danger text-left" role="button"><i class="fas fa-user-minus mr-2"></i>Ban user</button>
<button id="unban2-{{p.id}}" class="{% if not p.author.is_suspended %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-success text-left" role="button" onclick="post_toast(this,'/unban_user/{{p.author_id}}','ban2-{{p.id}}','unban2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-user-minus mr-2"></i>Unban user</button>
{% endif %}

View File

@ -53,7 +53,7 @@
{% block subNav %}
{% set mod = (v and v.admin_level > 1) %}
{% set mod = (v and v.admin_level >= PERMS['UNKNOWN_ADMIN_LEVEL2_PERM4']) %}
{% if not request.path.startswith('/h/') %}
<div class="container-fluid bg-white sticky d-none d-md-block" style="padding-top: 50px; padding-bottom: 0 !important;">
<div class="row box-shadow-bottom">

View File

@ -11,7 +11,7 @@
{% set voted=-2 %}
{% endif %}
{% set v_forbid_deleted = (p.deleted_utc != 0) and not (v and v.admin_level >= 2) and not (v and v.id == p.author_id) %}
{% set v_forbid_deleted = (p.deleted_utc != 0) and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']) and not (v and v.id == p.author_id) %}
{% block title %}
@ -590,7 +590,7 @@
</div>
{% endif %}
{% if v and v.admin_level > 1 %}
{% if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION_TOOLS_VISIBLE'] %}
{% include "post_admin_actions_mobile.html" %}
{% endif %}
@ -640,7 +640,7 @@
<i class="{{a.class_list}} px-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{a.title}} Award given by @{{a.user.username}}"></i>
{% endfor %}
{% if v and v.admin_level > 1 and p.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title='Shadowbanned by @{{p.author.shadowbanned}} for "{{p.author.ban_reason}}"'></i>{% endif %}
{% if v and v.admin_level >= PERMS['USER_SHADOWBAN'] and p.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title='Shadowbanned by @{{p.author.shadowbanned}} for "{{p.author.ban_reason}}"'></i>{% endif %}
{% if p.stickied %}
<i id='pinned-{{p.id}}' class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Pinned by @{{p.stickied}}" {% if p.stickied_utc %}onmouseover="pinned_timestamp('pinned-{{p.id}}')" data-timestamp={{p.stickied_utc}} {% endif %}></i>
@ -790,7 +790,7 @@
</div>
{% endif %}
{% if v and (v.id==p.author_id or v.admin_level > 2) and not v.is_suspended %}
{% if v and (v.id==p.author_id or v.admin_level >= PERMS['POST_EDITING']) and not v.is_suspended %}
<div id="edit-post-body-{{p.id}}" class="d-none comment-write collapsed child">
<form id="post-edit-form-{{p.id}}" action="/edit_post/{{p.id}}" method="post" enctype="multipart/form-data">
<input type="hidden" name="formkey" value="{{v.formkey}}">
@ -844,7 +844,7 @@
</a>
</li>
{% if v and (v.id==p.author_id or v.admin_level > 1 and v.admin_level > 2) %}
{% if v and (v.id==p.author_id or v.admin_level >= PERMS['POST_EDITING']) %}
<a class="list-inline-item" role="button" onclick="togglePostEdit('{{p.id}}')"><i class="fas fa-edit"></i>Edit</a>
{% endif %}
@ -902,7 +902,7 @@
<span class="text-info d-none {{p.id}}-new-comments"></span>
</a>
{% if v and v.admin_level > 1 %}
{% if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION_TOOLS_VISIBLE'] %}
<a class="ml-2" role="button" data-bs-toggle="modal" data-bs-target="#adminModal-{{p.id}}">
<i class="fas fa-broom"></i>
</a>
@ -1092,7 +1092,7 @@
{% include "report_post_modal.html" %}
{% endif %}
{% if v and (v.id == p.author_id or v.admin_level > 1 and v.admin_level > 2) %}
{% if v and (v.id == p.author_id or v.admin_level >= PERMS['POST_EDITING']) %}
<script defer src="{{'js/togglePostEdit.js' | asset}}"></script>
{% endif %}

View File

@ -43,7 +43,7 @@
</div>
</div>
{% if v and v.admin_level > 1 and p.body_html %}
{% if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION'] and p.body_html %}
<div class="post-body mt-4 mb-2">
{{p.body_html | safe}}
</div>

View File

@ -28,7 +28,7 @@
{% set voted=-2 %}
{% endif %}
{% set v_forbid_deleted = (p.deleted_utc != 0 or p.is_banned) and not (v and v.admin_level >= 2) and not (v and v.id == p.author_id) %}
{% set v_forbid_deleted = (p.deleted_utc != 0 or p.is_banned) and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']) and not (v and v.id == p.author_id) %}
{% if p.active_flags(v) %}
<div id="flaggers-{{p.id}}" class="flaggers d-none">
@ -48,7 +48,7 @@
{% if not postembed %}
<div class="voting my-2 d-none d-md-flex pr-2">
{% if v and request.path.startswith('/@') and v.admin_level < 2 %}
{% if v and request.path.startswith('/@') and v.admin_level < PERMS['VIEW_VOTE_BUTTONS_ON_USER_PAGE'] %}
<div tabindex="0" role="button" onclick="vote('post', '{{p.id}}', '1')" class="post-{{p.id}}-up mx-auto arrow-up upvote-button post-{{p.id}}-up {% if voted==1 %}active{% else %}d-none{% endif %}"></div>
<span class="post-score-{{p.id}} score post-score-{{p.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}{% if p.controversial %} controversial{% endif %}"{% if not p.is_banned %} data-bs-toggle="tooltip" data-bs-placement="right" title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
@ -133,7 +133,7 @@
<i class="{{a.class_list}} px-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{a.title}} Award given by @{{a.user.username}}"></i>
{% endfor %}
{% if v and v.admin_level > 1 and p.author.shadowbanned %}
{% if v and v.admin_level >= PERMS['USER_SHADOWBAN'] and p.author.shadowbanned %}
<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title='Shadowbanned by @{{p.author.shadowbanned}} for "{{p.author.ban_reason}}"'></i>
{% endif %}
@ -225,7 +225,7 @@
<span class="text-info d-none {{p.id}}-new-comments"></span>
</a>
{% if v and v.admin_level > 1 %}
{% if v and v.admin_level >= PERMS['ADMIN_HOME_VISIBLE'] %}
<a class="ml-2" role="button" data-bs-toggle="modal" data-bs-target="#adminModal-{{p.id}}">
<i class="fas fa-broom"></i>
</a>
@ -245,7 +245,7 @@
</li>
{% endif %}
{% if not postembed %}
{% if v and request.path.startswith('/@') and v.admin_level < 2 %}
{% if v and request.path.startswith('/@') and v.admin_level < PERMS['VIEW_VOTE_BUTTONS_ON_USER_PAGE'] %}
<li id="voting-{{p.id}}-mobile" class="voting list-inline-item d-md-none">
<span tabindex="0" role="button" onclick="vote('post-mobile', '{{p.id}}', '1')" class="post-mobile-{{p.id}}-up mx-0 pr-1 arrow-up upvote-button post-{{p.id}}-up {% if voted==1 %}active{% else %}d-none{% endif %}"></span>
@ -311,7 +311,7 @@
</script>
{% if v and v.admin_level > 1 %}
{% if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
{% include "post_admin_actions_mobile.html" %}
{% endif %}
@ -418,7 +418,7 @@
{% if v %}
{% include "delete_post_modal.html" %}
{% include "report_post_modal.html" %}
{% if v.admin_level > 1 %}
{% if v.admin_level >= PERMS['USER_BAN'] %}
{% include "ban_modal.html" %}
{% endif %}
{% endif %}

View File

@ -184,7 +184,7 @@
</div>
<div class="d-flex my-4 mx-3">
<a role="button" class="btn btn-primary ml-auto" onclick="remove_hat(this, '{{hat.name}}')">Remove</a>
{% if v.admin_level > 2 %}
{% if v.admin_level >= PERMS['MODERATE_PENDING_SUBMITTED_HATS'] %}
<a role="button" class="btn btn-primary ml-3" onclick="approve_hat(this, '{{hat.name}}')">Approve</a>
{% endif %}
</div>

View File

@ -182,7 +182,7 @@
</div>
<div class="d-flex my-4 mx-3">
<a role="button" class="btn btn-primary ml-auto" onclick="remove_marsey(this, '{{marsey.name}}')">Remove</a>
{% if v.admin_level > 2 %}
{% if v.admin_level >= PERMS['MODERATE_PENDING_SUBMITTED_MARSEYS'] %}
<a role="button" class="btn btn-primary ml-3" onclick="approve_marsey(this, '{{marsey.name}}')">Approve</a>
{% endif %}
</div>

View File

@ -29,7 +29,7 @@
<div id="profile--joined">Joined on <span id="profile--joined--time" data-time="{{u.created_utc}}"></span></div>
{% if v.admin_level >= 2 -%}
{% if v.admin_level >= PERMS['VIEW_LAST_ACTIVE'] -%}
<div id="profile--lastactive" class="mt-3">Last active on <span id="profile--lastactive--time" data-time="{{u.last_active}}"></span></div>
{%- endif %}

View File

@ -58,7 +58,7 @@
<h5 class="text-primary" id="profile--unban">{{u.unban_string}}</h5>
{% endif %}
{% endif %}
{% if v and v.admin_level >= 2 and u.shadowbanned %}
{% if v and v.admin_level >= PERMS['USER_SHADOWBAN'] and u.shadowbanned %}
<h5 class="text-primary" id="profile--shadowbanned">SHADOWBANNED USER
{% if u.ban_reason %}:
{{u.ban_reason | safe}}
@ -87,7 +87,7 @@
<span id="profile--verified"><i class="fas fa-badge-check align-middle ml-2 {% if u.verified=='Glowiefied' %}glow{% endif %}" style="color:{% if u.verifiedcolor %}#{{u.verifiedcolor}}{% else %}#1DA1F2{% endif %}" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{u.verified}}"></i></span>
{% endif %}
{% if u.admin_level > 1 %}
{% if u.admin_level >= PERMS['ADMIN_MOP_VISIBLE'] %}
<span id="profile--mop">
<i class="fas fa-broom text-admin align-middle ml-2" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Admin"></i>
</span>
@ -151,7 +151,7 @@
<span id="profile--joined">joined <span id="profile--joined--time" data-bs-toggle="tooltip" data-bs-placement="bottom" onmouseover="timestamp('profile--joined--time','{{u.created_utc}}')">{{u.created_date}}</span></span>
{% if v and v.admin_level >= 2 -%}
{% if v and v.admin_level >= PERMS['VIEW_LAST_ACTIVE'] -%}
<span id="profile--lastactive" class="ml-2">last active <span id="profile--lastactive--time" data-bs-toggle="tooltip" data-bs-placement="bottom" onmouseover="timestamp('profile--lastactive--time','{{u.last_active}}')">{{u.last_active_date}}</span></span>
{%- endif %}
</div>
@ -218,16 +218,14 @@
<a class="btn btn-primary" role="button" onclick="post_toast(this,'/settings/block?username={{u.username}}',true)">Block</a>
{% if v.admin_level > 2 %}
{% if SITE != 'rdrama.net' %}
<a id="admin" class="{% if u.admin_level > 1 %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast(this,'/@{{u.username}}/make_admin','admin','unadmin','d-none')">Make admin</a>
{% endif %}
<a id="unadmin" class="{% if u.admin_level < 2 %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast(this,'/@{{u.username}}/remove_admin','admin','unadmin','d-none')">Remove admin</a>
{% if u.admin_level > 1 %}
<a class="btn btn-primary" role="button" onclick="post_toast(this,'/@{{u.username}}/revert_actions')">Revert admin actions</a>
{% endif %}
{% if v.admin_level >= PERMS['ADMIN_ADD'] and SITE != 'rdrama.net' %}
<a id="admin" class="{% if u.admin_level >= PERMS['ADMIN_ADD_PERM_LEVEL'] %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast(this,'/@{{u.username}}/make_admin','admin','unadmin','d-none')">Make admin</a>
{% endif %}
{% if v.admin_level >= PERMS['ADMIN_REMOVE'] %}
<a id="unadmin" class="{% if u.admin_level < 1 %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast(this,'/@{{u.username}}/remove_admin','admin','unadmin','d-none')">Remove admin</a>
{% endif %}
{% if v.admin_level >= PERMS['ADMIN_ACTIONS_REVERT'] %}
<a class="btn btn-primary" role="button" onclick="post_toast(this,'/@{{u.username}}/revert_actions')">Revert admin actions</a>
{% endif %}
</div>
@ -272,9 +270,10 @@
<a class="btn btn-secondary" role="button" onclick="toggle()">Toggle anthem</a>
{% endif %}
{% if v and v.id != u.id and v.admin_level > 1 %}
{% if v and v.id != u.id and v.admin_level >= PERMS['USER_MODERATION_TOOLS_VISIBLE'] %}
<br><br>
<div class="body d-lg-flex border-bottom">
{% if v.admin_level >= PERMS['USER_TITLE_CHANGE'] %}
<div class="w-lg-100">
<form action="/admin/title_change/{{u.id}}" method="post">
@ -292,86 +291,88 @@
</div>
</form>
</div>
{% endif %}
</div>
<pre></pre>
<pre></pre>
{% if u.is_suspended %}
<form action="/unban_user/{{u.id}}" method="post" action="">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input type="hidden" name="redir" value="true">
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Unban user">
</form>
{% else %}
<form action="/ban_user/{{u.id}}" method="post" action="">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input type="hidden" name="redir" value="true">
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Ban Reason" oninput="document.getElementById('user-ban-submit').disabled=false" required>
<input autocomplete="off" style="font-size:11px" type="number" step="any" class="form-control" name="days" placeholder="Days (blank = permanent)">
<div class="custom-control custom-checkbox mb-1">
<input autocomplete="off" type="checkbox" id="alts-2-desktop" class="custom-control-input" name="alts" value="1">
<label class="custom-control-label" for="alts-2-desktop">Include alts</label>
</div>
<input autocomplete="off" id="user-ban-submit" type="submit" onclick="disable(this)" class="btn btn-danger" value="Ban user" disabled>
</form>
{% if v.admin_level >= PERMS['USER_BAN'] %}
{% if u.is_suspended %}
<form action="/unban_user/{{u.id}}" method="post" action="">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input type="hidden" name="redir" value="true">
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Unban user">
</form>
{% else %}
<form action="/ban_user/{{u.id}}" method="post" action="">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input type="hidden" name="redir" value="true">
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Ban Reason" oninput="document.getElementById('user-ban-submit').disabled=false" required>
<input autocomplete="off" style="font-size:11px" type="number" step="any" class="form-control" name="days" placeholder="Days (blank = permanent)">
<div class="custom-control custom-checkbox mb-1">
<input autocomplete="off" type="checkbox" id="alts-2-desktop" class="custom-control-input" name="alts" value="1">
<label class="custom-control-label" for="alts-2-desktop">Include alts</label>
</div>
<input autocomplete="off" id="user-ban-submit" type="submit" onclick="disable(this)" class="btn btn-danger" value="Ban user" disabled>
</form>
{% endif %}
{% endif %}
<pre></pre>
<pre></pre>
{% if u.shadowbanned %}
<form action="/unshadowban/{{u.id}}" method="post" action="">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Unshadowban user">
</form>
{% else %}
<form action="/shadowban/{{u.id}}" method="post" action="">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Shadowban Reason" oninput="document.getElementById('user-shadowban-submit').disabled=false" required>
<div class="custom-control custom-checkbox mb-1">
{% if v.admin_level >= PERMS['USER_SHADOWBAN'] %}
{% if u.shadowbanned %}
<form action="/unshadowban/{{u.id}}" method="post" action="">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Unshadowban user">
</form>
{% else %}
<form action="/shadowban/{{u.id}}" method="post" action="">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Shadowban Reason" oninput="document.getElementById('user-shadowban-submit').disabled=false" required>
<div class="custom-control custom-checkbox mb-1">
<input autocomplete="off" type="checkbox" id="shadowban-alts-2-desktop" class="custom-control-input" name="alts" value="1">
<label class="custom-control-label" for="shadowban-alts-2-desktop">Include alts</label>
</div>
<input autocomplete="off" id="user-shadowban-submit" type="submit" onclick="disable(this)" class="btn btn-danger" value="Shadowban user" disabled>
</div>
<input autocomplete="off" id="user-shadowban-submit" type="submit" onclick="disable(this)" class="btn btn-danger" value="Shadowban user" disabled>
</form>
{% endif %}
{% endif %}
<pre></pre>
<pre></pre>
{% if v and v.admin_level >= PERMS['USER_AGENDAPOSTER'] %}
<form id="agendaposter1" class="{% if u.agendaposter %}d-none{% endif %}" action="/agendaposter/{{u.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input autocomplete="off" type="number" step="any" name="days" class="form-control" placeholder="Days (0 or blank = permanent)">
<input type="submit" onclick="disable(this)" class="btn btn-danger" value="Lock Chud Theme">
</form>
<pre></pre>
<a id="unagendaposter" class="{% if not u.agendaposter %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/unagendaposter/{{u.id}}','agendaposter1','unagendaposter','d-none')">Disable Chud Theme</a>
{% endif %}
<pre></pre>
{% if v and v.admin_level >= PERMS['USER_BAN'] %}
<a id="mute-user" class="{% if u.is_muted %}d-none{% endif %} btn btn-danger" role="button" onclick="post_toast(this,'/mute_user/{{u.id}}/1','mute-user','unmute-user','d-none')">Mute</a>
<a id="unmute-user" class="{% if not u.is_muted %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/mute_user/{{u.id}}/0','mute-user','unmute-user','d-none')">Unmute</a>
{% endif %}
<pre></pre>
{% if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
<form action="/admin/unnuke_user" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="hidden" name="user" value="{{u.username}}">
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Approve User's Content">
</form>
<pre></pre>
<form action="/admin/nuke_user" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="hidden" name="user" value="{{u.username}}">
<input type="submit" onclick="disable(this)" class="btn btn-danger" value="Remove User's Content">
</form>
{% endif %}
<pre></pre>
<pre></pre>
<form id="agendaposter1" class="{% if u.agendaposter %}d-none{% endif %}" action="/agendaposter/{{u.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input autocomplete="off" type="number" step="any" name="days" class="form-control" placeholder="Days (0 or blank = permanent)">
<input type="submit" onclick="disable(this)" class="btn btn-danger" value="Lock Chud Theme">
</form>
<pre></pre>
<a id="unagendaposter" class="{% if not u.agendaposter %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/unagendaposter/{{u.id}}','agendaposter1','unagendaposter','d-none')">Disable Chud Theme</a>
<pre></pre>
<a id="mute-user" class="{% if u.is_muted %}d-none{% endif %} btn btn-danger" role="button" onclick="post_toast(this,'/mute_user/{{u.id}}/1','mute-user','unmute-user','d-none')">Mute</a>
<a id="unmute-user" class="{% if not u.is_muted %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/mute_user/{{u.id}}/0','mute-user','unmute-user','d-none')">Unmute</a>
<pre></pre>
<form action="/admin/unnuke_user" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="hidden" name="user" value="{{u.username}}">
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Approve User's Content">
</form>
<pre></pre>
<form action="/admin/nuke_user" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="hidden" name="user" value="{{u.username}}">
<input type="submit" onclick="disable(this)" class="btn btn-danger" value="Remove User's Content">
</form>
<pre></pre>
{% if FEATURES['COUNTRY_CLUB'] -%}
<button id="grant2" class="{% if u.paid_dues %}d-none{% endif %} btn btn-success" onclick="post_toast(this,'/@{{u.username}}/club_allow','grant2','bar2','d-none')">Grant club access</button>
<button id="bar2" class="{% if u.club_allowed == False %}d-none{% endif %} btn btn-danger" onclick="post_toast(this,'/@{{u.username}}/club_ban','grant2','bar2','d-none')">Bar from club</button>
{%- endif %}
{% if FEATURES['COUNTRY_CLUB'] and v and v.admin_level >= PERMS['USER_CLUB_ALLOW_BAN'] %}
<pre></pre>
<button id="grant2" class="{% if u.paid_dues %}d-none{% endif %} btn btn-success" onclick="post_toast(this,'/@{{u.username}}/club_allow','grant2','bar2','d-none')">Grant club access</button>
<button id="bar2" class="{% if u.club_allowed == False %}d-none{% endif %} btn btn-danger" onclick="post_toast(this,'/@{{u.username}}/club_ban','grant2','bar2','d-none')">Bar from club</button>
{% endif %}
{% endif %}
<pre></pre>
<div id="profile--info">
<p id="profile--info--id">User ID: {{u.id}}</p>
@ -379,9 +380,9 @@
<p id="profile--info--truescore">True score: {{u.truecoins}}</p>
<p id="profile--info--winnings">Winnings: {{u.winnings}}</p>
{% if u.is_private %}
<p id="profile--info--private">User has private mode enabled.</p>
<p id="profile--info--private">User has private mode enabled</p>
{% endif %}
{% if v and (v.admin_level > 1 or v.alt) %}
{% if v and (v.admin_level >= PERMS['VIEW_ALTS'] or v.alt) %}
<span id="profile--alts">Alts:</span>
<ul id="profile--alts-list">
{% for account in u.alts_unique %}
@ -440,7 +441,7 @@
{% if u.unban_utc %}<h5 class="text-primary" id="profile-mobile--unban">{{u.unban_string}}</h5>{% endif %}
{% endif %}
{% if v and v.admin_level >= 2 and u.shadowbanned %}
{% if v and v.admin_level >= PERMS['USER_SHADOWBAN'] and u.shadowbanned %}
<h5 class="text-primary" id="profile-mobile--banned">SHADOWBANNED USER{% if u.ban_reason %}: {{u.ban_reason | safe}}{% endif %} (by <a href="/@{{u.shadowbanned}}">@{{u.shadowbanned}}</a>)</h5>
{% endif %}
@ -464,7 +465,7 @@
<span id="profile-mobile--verified"><i class="fas fa-badge-check align-middle ml-2 {% if u.verified=='Glowiefied' %}glow{% endif %}" style="color:{% if u.verifiedcolor %}#{{u.verifiedcolor}}{% else %}#1DA1F2{% endif %}" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{u.verified}}"></i></span>&nbsp;
{% endif %}
{% if u.admin_level > 1 %}
{% if u.admin_level >= PERMS['ADMIN_MOP_VISIBLE'] %}
<span id="profile-mobile--mop">
<i class="fas fa-broom text-admin align-middle ml-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Admin"></i>
</span>
@ -508,7 +509,7 @@
<br><span id="profile-mobile--joined">joined <span id="profile-mobile--joined--time" data-bs-toggle="tooltip" data-bs-placement="bottom" onmouseover="timestamp('profile-mobile--joined--time','{{u.created_utc}}')" class="font-weight-bold">{{u.created_date}}</span></span>
{% if v and v.admin_level >= 2 -%}
{% if v and v.admin_level >= PERMS['VIEW_LAST_ACTIVE'] -%}
<br><span id="profile-mobile--lastactive">last active <span id="profile-mobile--lastactive--time" data-bs-toggle="tooltip" data-bs-placement="bottom" onmouseover="timestamp('profile-mobile--lastactive--time','{{u.last_active}}')" class="font-weight-bold">{{u.last_active_date}}</span></span>
{%- endif %}
</div>
@ -587,16 +588,16 @@
<a class="btn btn-primary" role="button" onclick="post_toast(this,'/settings/block?username={{u.username}}',true)">Block</a>
{% if v.admin_level > 2 %}
{% if SITE != 'rdrama.net' %}
<a id="admin2" class="{% if u.admin_level > 1 %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast(this,'/@{{u.username}}/make_admin','admin2','unadmin2','d-none')">Make admin</a>
{% endif %}
{% if v.admin_level >= PERMS['ADMIN_ADD'] and SITE != 'rdrama.net' %}
<a id="admin2" class="{% if u.admin_level >= PERMS['ADMIN_ADD_PERM_LEVEL'] %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast(this,'/@{{u.username}}/make_admin','admin2','unadmin2','d-none')">Make admin</a>
{% endif %}
<a id="unadmin2" class="{% if u.admin_level < 2 %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast(this,'/@{{u.username}}/remove_admin','admin2','unadmin2','d-none')">Remove admin</a>
{% if v.admin_level >= PERMS['ADMIN_REMOVE'] %}
<a id="unadmin2" class="{% if u.admin_level < 1 %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast(this,'/@{{u.username}}/remove_admin','admin2','unadmin2','d-none')">Remove admin</a>
{% endif %}
{% if u.admin_level > 1 %}
<a class="btn btn-primary" role="button" onclick="post_toast(this,'/@{{u.username}}/revert_actions')">Revert admin actions</a>
{% endif %}
{% if v.admin_level >= PERMS['ADMIN_ACTIONS_REVERT'] %}
<a class="btn btn-primary" role="button" onclick="post_toast(this,'/@{{u.username}}/revert_actions')">Revert admin actions</a>
{% endif %}
<form class="d-none toggleable" id='message-mobile' action="/@{{u.username}}/message" onsubmit="submitFormAjax(event)">
@ -631,105 +632,107 @@
<button class="btn btn-primary mt-2 mb-3" onclick="transferBux(true)">Gift</button>
</div>
{% if v.admin_level > 1 %}
{% if v and v.admin_level >= PERMS['USER_MODERATION_TOOLS_VISIBLE'] %}
{% if FEATURES['COUNTRY_CLUB'] -%}
<button id="grant" class="{% if u.paid_dues %}d-none{% endif %} btn btn-success" onclick="post_toast(this,'/@{{u.username}}/club_allow','grant','bar','d-none')">Grant club access</button>
<button id="bar" class="{% if u.club_allowed == False %}d-none{% endif %} btn btn-danger" onclick="post_toast(this,'/@{{u.username}}/club_ban','grant','bar','d-none')">Bar from club</button>
{%- endif %}
{% if FEATURES['COUNTRY_CLUB'] and v.admin_level >= PERMS['USER_CLUB_ALLOW_BAN'] -%}
<button id="grant" class="{% if u.paid_dues %}d-none{% endif %} btn btn-success" onclick="post_toast(this,'/@{{u.username}}/club_allow','grant','bar','d-none')">Grant club access</button>
<button id="bar" class="{% if u.club_allowed == False %}d-none{% endif %} btn btn-danger" onclick="post_toast(this,'/@{{u.username}}/club_ban','grant','bar','d-none')">Bar from club</button>
{%- endif %}
<br><br>
<div class="body d-lg-flex border-bottom">
<div class="w-lg-100">
<form action="/admin/title_change/{{u.id}}" method="post">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input maxlength=100 autocomplete="off" id="customtitlebody-mobile" type="text" name="title" class="form-control" placeholder='Enter a flair here' value="{% if u.customtitleplain %}{{u.customtitleplain}}{% endif %}">
<div class="d-flex mt-2">
<a class="format" role="button"><i class="btn btn-secondary format d-inline-block m-0 fas fa-smile-beam" onclick="loadEmojis('customtitlebody-mobile')" aria-hidden="true" data-bs-toggle="modal" data-bs-target="#emojiModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add Emoji"></i></a>
&nbsp;&nbsp;&nbsp;
<div class="custom-control custom-checkbox">
<input autocomplete="off" type="checkbox" class="custom-control-input" id="locked-mobile" name="locked" {% if u.flairchanged %}checked{% endif %}>
<label class="custom-control-label" for="locked-mobile">locked</label>
{% if v.admin_level >= PERMS['USER_TITLE_CHANGE'] %}
<div class="w-lg-100">
<form action="/admin/title_change/{{u.id}}" method="post">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input maxlength=100 autocomplete="off" id="customtitlebody-mobile" type="text" name="title" class="form-control" placeholder='Enter a flair here' value="{% if u.customtitleplain %}{{u.customtitleplain}}{% endif %}">
<div class="d-flex mt-2">
<a class="format" role="button"><i class="btn btn-secondary format d-inline-block m-0 fas fa-smile-beam" onclick="loadEmojis('customtitlebody-mobile')" aria-hidden="true" data-bs-toggle="modal" data-bs-target="#emojiModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add Emoji"></i></a>
&nbsp;&nbsp;&nbsp;
<div class="custom-control custom-checkbox">
<input autocomplete="off" type="checkbox" class="custom-control-input" id="locked-mobile" name="locked" {% if u.flairchanged %}checked{% endif %}>
<label class="custom-control-label" for="locked-mobile">locked</label>
</div>
&nbsp;&nbsp;&nbsp;
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" onclick="disable(this)" value="Change Flair">
</div>
&nbsp;&nbsp;&nbsp;
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" onclick="disable(this)" value="Change Flair">
</div>
</form>
</div>
</form>
</div>
{% endif %}
</div>
<pre></pre>
<pre></pre>
{% if u.is_suspended %}
<form action="/unban_user/{{u.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="hidden" name="redir" value="true">
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Unban user">
</form>
{% else %}
<form action="/ban_user/{{u.id}}" method="post">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input type="hidden" name="redir" value="true">
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Ban Reason" oninput="document.getElementById('user-ban-submit2').disabled=false" required>
<input autocomplete="off" style="font-size:11px" type="number" step="any" class="form-control" name="days" placeholder="Days (blank = permanent)">
<div class="custom-control custom-checkbox mb-1">
<input autocomplete="off" type="checkbox" id="alts-2-mobile" class="custom-control-input" name="alts" value="1">
<label class="custom-control-label" for="alts-2-mobile">Include alts</label>
</div>
<input autocomplete="off" id="user-ban-submit2" type="submit" onclick="disable(this)" class="btn btn-danger" value="Ban user" disabled>
</form>
{% if v.admin_level >= PERMS['USER_BAN'] %}
{% if u.is_suspended %}
<form action="/unban_user/{{u.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="hidden" name="redir" value="true">
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Unban user">
</form>
{% else %}
<form action="/ban_user/{{u.id}}" method="post">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input type="hidden" name="redir" value="true">
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Ban Reason" oninput="document.getElementById('user-ban-submit2').disabled=false" required>
<input autocomplete="off" style="font-size:11px" type="number" step="any" class="form-control" name="days" placeholder="Days (blank = permanent)">
<div class="custom-control custom-checkbox mb-1">
<input autocomplete="off" type="checkbox" id="alts-2-mobile" class="custom-control-input" name="alts" value="1">
<label class="custom-control-label" for="alts-2-mobile">Include alts</label>
</div>
<input autocomplete="off" id="user-ban-submit2" type="submit" onclick="disable(this)" class="btn btn-danger" value="Ban user" disabled>
</form>
{% endif %}
{% endif %}
<pre></pre>
<pre></pre>
{% if u.shadowbanned %}
<form action="/unshadowban/{{u.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Unshadowban user">
</form>
{% else %}
<form action="/shadowban/{{u.id}}" method="post">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Shadowban Reason" oninput="document.getElementById('user-shadowban-submit2').disabled=false" required>
<div class="custom-control custom-checkbox mb-1">
<input autocomplete="off" type="checkbox" id="shadowban-alts-2-mobile" class="custom-control-input" name="alts" value="1">
<label class="custom-control-label" for="shadowban-alts-2-mobile">Include alts</label>
</div>
<input autocomplete="off" id="user-shadowban-submit2" type="submit" onclick="disable(this)" class="btn btn-danger" value="Shadowban user" disabled>
</form>
{% if v.admin_level >= PERMS['USER_SHADOWBAN'] %}
{% if u.shadowbanned %}
<form action="/unshadowban/{{u.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Unshadowban user">
</form>
{% else %}
<form action="/shadowban/{{u.id}}" method="post">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Shadowban Reason" oninput="document.getElementById('user-shadowban-submit2').disabled=false" required>
<div class="custom-control custom-checkbox mb-1">
<input autocomplete="off" type="checkbox" id="shadowban-alts-2-mobile" class="custom-control-input" name="alts" value="1">
<label class="custom-control-label" for="shadowban-alts-2-mobile">Include alts</label>
</div>
<input autocomplete="off" id="user-shadowban-submit2" type="submit" onclick="disable(this)" class="btn btn-danger" value="Shadowban user" disabled>
</form>
{% endif %}
{% endif %}
<pre></pre>
<pre></pre>
<form id="agendaposter2" class="{% if u.agendaposter %}d-none{% endif %}" action="/agendaposter/{{u.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input autocomplete="off" type="number" step="any" name="days" class="form-control" placeholder="Days (0 or blank = permanent)">
<input type="submit" onclick="disable(this)" class="btn btn-danger" value="Lock Chud Theme">
</form>
{% if v.admin_level >= PERMS['USER_AGENDAPOSTER'] %}
<form id="agendaposter2" class="{% if u.agendaposter %}d-none{% endif %}" action="/agendaposter/{{u.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input autocomplete="off" type="number" step="any" name="days" class="form-control" placeholder="Days (0 or blank = permanent)">
<input type="submit" onclick="disable(this)" class="btn btn-danger" value="Lock Chud Theme">
</form>
<pre></pre>
<a id="unagendaposter2" class="{% if not u.agendaposter %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/unagendaposter/{{u.id}}','agendaposter2','unagendaposter2','d-none')">Disable Chud Theme</a>
<pre></pre>
{% endif %}
{% if v.admin_level >= PERMS['USER_BAN'] %}
<a id="mute-user2" class="{% if u.is_muted %}d-none{% endif %} btn btn-danger" role="button" onclick="post_toast(this,'/mute_user/{{u.id}}/1','mute-user2','unmute-user2','d-none')">Mute</a>
<a id="unmute-user2" class="{% if not u.is_muted %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/mute_user/{{u.id}}/0','mute-user2','unmute-user2','d-none')">Unmute</a>
{% endif %}
<pre></pre>
<a id="unagendaposter2" class="{% if not u.agendaposter %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/unagendaposter/{{u.id}}','agendaposter2','unagendaposter2','d-none')">Disable Chud Theme</a>
<pre></pre>
<a id="mute-user2" class="{% if u.is_muted %}d-none{% endif %} btn btn-danger" role="button" onclick="post_toast(this,'/mute_user/{{u.id}}/1','mute-user2','unmute-user2','d-none')">Mute</a>
<a id="unmute-user2" class="{% if not u.is_muted %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/mute_user/{{u.id}}/0','mute-user2','unmute-user2','d-none')">Unmute</a>
<pre></pre>
<form action="/admin/unnuke_user" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="hidden" name="user" value="{{u.username}}">
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Approve User's Content">
</form>
<pre></pre>
<form action="/admin/nuke_user" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="hidden" name="user" value="{{u.username}}">
<input type="submit" onclick="disable(this)" class="btn btn-danger" value="Remove User's Content">
</form>
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
<form action="/admin/unnuke_user" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="hidden" name="user" value="{{u.username}}">
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Approve User's Content">
</form>
<pre></pre>
<form action="/admin/nuke_user" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="hidden" name="user" value="{{u.username}}">
<input type="submit" onclick="disable(this)" class="btn btn-danger" value="Remove User's Content">
</form>
{% endif %}
{% endif %}
{% endif %}
<pre></pre>
@ -739,9 +742,9 @@
<p id="profile-mobile--info--truescore">True score: {{u.truecoins}}</p>
<p id="profile-mobile--info--winnings">Winnings: {{u.winnings}}</p>
{% if u.is_private %}
<p id="profile-mobile--info--private">User has private mode enabled.</p>
<p id="profile-mobile--info--private">User has private mode enabled</p>
{% endif %}
{% if v and (v.admin_level > 1 or v.alt) %}
{% if v and (v.admin_level >= PERMS['VIEW_ALTS'] or v.alt) %}
<span id="profile-mobile--alts">Alts:</span>
<ul id="profile-mobile--alts-list">
{% for account in u.alts_unique %}

View File

@ -268,25 +268,22 @@ INSERT INTO public.hat_defs VALUES (779, 'nemean lion hood', 'Like a true roman,
INSERT INTO public.hat_defs VALUES (780, 'Winged Hussar', 'To battle with wings on your head!', 2, 500, NULL, 1664731432);
INSERT INTO public.hat_defs VALUES (786, 'Ricks hair', 'Wubba lubba dub dub', 2, 500, NULL, 1664930047);
INSERT INTO public.hat_defs VALUES (781, 'BTC', 'Only wear this if you''re worth billions.', 2, 500, NULL, 1664750970);
INSERT INTO public.hat_defs VALUES (803, 'BERSERKER HELM', 'BERSERKER HELM', 2, 500, NULL, 1665088512);
INSERT INTO public.hat_defs VALUES (790, 'LGBTUSSR Officer Hat 2', 'Be fascist and GAYYY!', 2, 1000, NULL, 1664994701);
INSERT INTO public.hat_defs VALUES (793, 'Pornhub', 'We all know why you bought this...', 2, 500, NULL, 1664995981);
INSERT INTO public.hat_defs VALUES (795, 'Ass Eater', 'Good announcement, now show us eating yours.', 2, 500, NULL, 1664996448);
INSERT INTO public.hat_defs VALUES (796, 'Pinhead Mask', 'Your mask is a bit... small.-Happy Halloween!', 2, 500, NULL, 1664997385);
INSERT INTO public.hat_defs VALUES (801, 'Ramen', 'Eatin'' ramen, watchin'' ramen, bein'' ramen', 2, 500, NULL, 1665000479);
INSERT INTO public.hat_defs VALUES (804, 'TF2 Stacked', 'Why wear one hat when you can wear 3!-momomo', 2, 500, NULL, 1665102373);
INSERT INTO public.hat_defs VALUES (806, 'Lotus', 'Now you look and smell pretty like a lotus!-sarah', 2, 500, NULL, 1665103737);
INSERT INTO public.hat_defs VALUES (797, 'Happy Halloween', '🦇 a spooopy title for you 🎃', 2, 500, NULL, 1664998497);
INSERT INTO public.hat_defs VALUES (798, 'BOO', '👻 floating little baby ghosties …… BOO!', 2, 500, NULL, 1664998569);
INSERT INTO public.hat_defs VALUES (799, 'Boobies', 'sorry no, not those kind of boobies', 2, 500, NULL, 1664998710);
INSERT INTO public.hat_defs VALUES (800, 'Peekaboo', 'this little guy will watch over you, just remember to feed him!', 2, 500, NULL, 1664998845);
INSERT INTO public.hat_defs VALUES (723, 'Hohol', 'Мій предок :)', 2, 500, NULL, 1663892328);
INSERT INTO public.hat_defs VALUES (750, 'Cave Man', 'UNGA BUNGA UNGA BUNGA OOO OOO', 2, 500, NULL, 1664595865);
INSERT INTO public.hat_defs VALUES (753, 'Doom Guy', 'RIP AND TEAR', 2, 500, NULL, 1664595933);
INSERT INTO public.hat_defs VALUES (807, 'The Capy', 'You''re the chosen one! No one can hurt you!', 2, 500, NULL, 1665104052);
INSERT INTO public.hat_defs VALUES (92, 'Top Hat (black)', 'Traditional. Classy. Elegant.', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (714, 'Captain Falcon', 'The chad that every smash player wanted to imitate, if only his moveset included a shower.', 2, 500, NULL, 1663474615);
INSERT INTO public.hat_defs VALUES (715, 'Inspector Gadget', '"Go go Gadget Brown Bricks!"', 2, 500, NULL, 1663477536);
@ -294,6 +291,11 @@ INSERT INTO public.hat_defs VALUES (724, 'Spartan Helmet', 'THIS IS SPARTA!', 2,
INSERT INTO public.hat_defs VALUES (751, 'Butter', 'Southern-fried and full of love.', 2, 500, NULL, 1664595886);
INSERT INTO public.hat_defs VALUES (754, 'Crusader helmet', 'RETAKE THE HOLY LAND!', 2, 500, NULL, 1664595954);
INSERT INTO public.hat_defs VALUES (766, 'book', 'i can read! heheh', 2, 500, NULL, 1664645746);
INSERT INTO public.hat_defs VALUES (787, 'Turban', 'Turban with Bindi Dot (Namaste)', 2, 500, NULL, 1664980060);
INSERT INTO public.hat_defs VALUES (788, 'LGBTUSSR Officer Hat', 'Rule with an iron fist... And use that iron fist for more than ruling ;)', 2, 1000, NULL, 1664994148);
INSERT INTO public.hat_defs VALUES (808, 'The Capy 2', 'The drippiest and pimpiest capybara out there.', 2, 500, NULL, 1665104484);
INSERT INTO public.hat_defs VALUES (676, 'Kepi', 'Army cap for those unlucky enough to be French', 2, 500, NULL, 1663303083);
INSERT INTO public.hat_defs VALUES (678, 'Turkroach', 'Come on Carp this one''s hilarious. It''s semi transparent to clarify', 2, 500, NULL, 1663305640);
INSERT INTO public.hat_defs VALUES (679, 'Judge Dredd', 'THIS USER IS THE LAW', 2, 500, NULL, 1663309533);
@ -939,7 +941,7 @@ INSERT INTO public.hat_defs VALUES (504, 'Iron Crown of Lombardy', 'This isn''t
-- Name: hat_defs_id_seq; Type: SEQUENCE SET; Schema: public; Owner: -
--
SELECT pg_catalog.setval('public.hat_defs_id_seq', 803, true);
SELECT pg_catalog.setval('public.hat_defs_id_seq', 810, true);
--
@ -996,6 +998,7 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseyamazon',2,'warehouse piss bottle driver wagecuck piss jug pissbottle pissjug wagie',NULL),
('marseyamber',2,'dalle2 generated',NULL),
('marseyamogus',2,'sussy baka impostor imposter stonetoss among us shh vent',NULL),
('marseyanalvore',2,'anal vore soy shock carp goatse',1665109289),
('marseyandjesus',2,'christianity christian jesus god love cute wholesome happy hug',NULL),
('marseyandmarcus',2,'bed sleeping cuddling cuddle marseyismywaifu',NULL),
('marseyangel',2,'reaction angelic happy innocent',NULL),
@ -1203,8 +1206,8 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseycapitalistmanlet',2,'money top hat rich landlord cigar llm tophat',NULL),
('marseycapy',2,'capybara rodent aevann happy cute',NULL),
('marseycapy2022',2,'aevann caypbara new year party celebration',NULL),
('marseycapyautism',2,'capy aevann autism hat patient capybara',1665095792),
('marseycapyautismchad',2,'capy aevann autism hat patient capybara chad gigachad',1665098772),
('marseycapyautism',2,'capy aevann autism hat patient capybara administrator jannie janitor',1665095792),
('marseycapyautismchad',2,'capy aevann autism hat patient administrator moderator jannie capybara chad gigachad',1665098772),
('marseycapybigbrain',2,'capybara aevann smart codecel brain',NULL),
('marseycapyblackface',2,'racist minstrelsy bowtie racism capybara aevann',NULL),
('marseycapyblowkiss',2,'capybara rodent aevann happy cute love',NULL),

View File

@ -3110,4 +3110,8 @@ Get. a GODSDAMNED. Grip.
⠀⠻⣷⣶⣿⣇⠀⠀⠀⢠⣼⣿⣿⣿⣿⣿⣿⣿⣛⣛⣻⠉⠁⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢸⣿⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢸⣿⣀⣀⣀⣼⡿⢿⣿⣿⣿⣿⣿⡿⣿⣿⡿
```
```
{[para]}
https://rdrama.net/videos/166388867180554.mp4
{[para]}
Mashallah, a few more russian chimpouts and we will finally get the mandate by pussified westerners to put the remaining muskovites up against the wall while they look the other way.