Merge branch 'master' into patch-5

remotes/1693045480750635534/spooky-22
Aevann1 2021-11-19 11:33:11 -08:00 committed by GitHub
commit cc052ea75d
60 changed files with 945 additions and 685 deletions

View File

@ -8,7 +8,7 @@ services:
- "./:/service"
environment:
- DATABASE_URL=postgresql://postgres@postgres:5432
- MASTER_KEY=${MASTER_KEY:XuxGqp5NyygJrM24b5gt3YgyvFVGdQnwVDwLzLwpu3eQwY}
- MASTER_KEY=XuxGqp5NyygJrM24b5gt3YgyvFVGdQnwVDwLzLwpu3eQwY
- REDIS_URL=redis://redis
- DOMAIN=127.0.0.1
- SITE_NAME=Drama

View File

@ -73,7 +73,7 @@ r=redis.Redis(host=environ.get("REDIS_URL", "redis://127.0.0.1"), decode_respon
limiter = Limiter(
app,
key_func=get_ipaddr,
default_limits=["50/minute"],
default_limits=["3/second;30/minute;100/hour"],
headers_enabled=True,
strategy="fixed-window"
)

View File

@ -7,12 +7,14 @@ from sqlalchemy import *
from sqlalchemy.orm import relationship
from files.__main__ import Base
from files.classes.votes import CommentVote
from files.helpers.const import AUTOPOLLER_ACCOUNT, censor_slurs
from files.helpers.const import AUTOPOLLER_ID, censor_slurs
from files.helpers.lazy import lazy
from .flags import CommentFlag
from random import randint
site = environ.get("DOMAIN").strip()
if site == 'pcmemes.net': cc = "splash mountain"
else: cc = "country club"
class Comment(Base):
@ -78,7 +80,7 @@ class Comment(Base):
@property
@lazy
def options(self):
return [x for x in self.child_comments if x.author_id == AUTOPOLLER_ACCOUNT]
return [x for x in self.child_comments if x.author_id == AUTOPOLLER_ID]
def total_poll_voted(self, v):
if v:
@ -183,7 +185,7 @@ class Comment(Base):
def replies(self):
r = self.__dict__.get("replies", None)
if r: r = [x for x in r if not x.author.shadowbanned]
if not r and r != []: r = sorted([x for x in self.child_comments if not x.author.shadowbanned and x.author_id != AUTOPOLLER_ACCOUNT], key=lambda x: x.score, reverse=True)
if not r and r != []: r = sorted([x for x in self.child_comments if not x.author.shadowbanned and x.author_id != AUTOPOLLER_ID], key=lambda x: x.score, reverse=True)
return r
@replies.setter
@ -201,21 +203,21 @@ class Comment(Base):
@property
def replies3(self):
r = self.__dict__.get("replies", None)
if not r and r != []: r = sorted([x for x in self.child_comments if x.author_id != AUTOPOLLER_ACCOUNT], key=lambda x: x.score, reverse=True)
if not r and r != []: r = sorted([x for x in self.child_comments if x.author_id != AUTOPOLLER_ID], key=lambda x: x.score, reverse=True)
return r
@property
@lazy
def shortlink(self):
return f"http://{site}/comment/{self.id}"
return f"http://{site}/comment/{self.id}#context"
@property
@lazy
def permalink(self):
if self.post and self.post.club: return f"/comment/{self.id}/"
if self.post and self.post.club: return f"/comment/{self.id}?context=9#context"
if self.post: return f"{self.post.permalink}/{self.id}/"
else: return f"/comment/{self.id}/"
if self.post: return f"{self.post.permalink}/{self.id}?context=9#context"
else: return f"/comment/{self.id}?context=9#context"
@property
@lazy
@ -302,7 +304,7 @@ class Comment(Base):
return data
def realbody(self, v):
if self.post and self.post.club and not (v and v.paid_dues): return "<p>COUNTRY CLUB ONLY</p>"
if self.post and self.post.club and not (v and v.paid_dues): return f"<p>{cc} ONLY</p>"
body = self.body_html
@ -335,7 +337,7 @@ class Comment(Base):
return body
def plainbody(self, v):
if self.post and self.post.club and not (v and v.paid_dues): return "<p>COUNTRY CLUB ONLY</p>"
if self.post and self.post.club and not (v and v.paid_dues): return f"<p>{cc} ONLY</p>"
body = self.body

View File

@ -3,6 +3,11 @@ from sqlalchemy.orm import relationship
from files.__main__ import Base
import time
from files.helpers.lazy import lazy
from os import environ
site = environ.get("DOMAIN").strip()
if site == 'pcmemes.net': cc = "splash mountain"
else: cc = "country club"
class ModAction(Base):
__tablename__ = "modactions"
@ -77,7 +82,7 @@ class ModAction(Base):
@lazy
def string(self):
output = ACTIONTYPES[self.kind]["str"].format(self=self)
output = ACTIONTYPES[self.kind]["str"].format(self=self, cc=cc)
if self.note: output += f" <i>({self.note})</i>"
@ -160,12 +165,12 @@ ACTIONTYPES={
"color": "bg-muted",
},
"club_allow":{
"str":'allowed user {self.target_link} into the country club',
"str":'allowed user {self.target_link} into the {cc}',
"icon":"fa-user-slash",
"color": "bg-danger",
},
"club_ban":{
"str":'disallowed user {self.target_link} from the country club',
"str":'disallowed user {self.target_link} from the {cc}',
"icon": "fa-user-slash",
"color": "bg-muted",
},

View File

@ -7,7 +7,7 @@ from flask import render_template
from sqlalchemy import *
from sqlalchemy.orm import relationship
from files.__main__ import Base
from files.helpers.const import AUTOPOLLER_ACCOUNT, censor_slurs, TROLLTITLES
from files.helpers.const import AUTOPOLLER_ID, censor_slurs, TROLLTITLES
from files.helpers.lazy import lazy
from .flags import Flag
from .comment import Comment
@ -15,6 +15,8 @@ from flask import g
site = environ.get("DOMAIN").strip()
site_name = environ.get("SITE_NAME").strip()
if site == 'pcmemes.net': cc = "SPLASH MOUNTAIN"
else: cc = "COUNTRY CLUB"
class Submission(Base):
__tablename__ = "submissions"
@ -78,7 +80,7 @@ class Submission(Base):
@property
@lazy
def options(self):
return g.db.query(Comment).filter_by(parent_submission = self.id, author_id = AUTOPOLLER_ACCOUNT, level=1)
return g.db.query(Comment).filter_by(parent_submission = self.id, author_id = AUTOPOLLER_ID, level=1)
def total_poll_voted(self, v):
if v:
@ -317,7 +319,7 @@ class Submission(Base):
else: return ""
def realbody(self, v):
if self.club and not (v and v.paid_dues): return "<p>COUNTRY CLUB ONLY</p>"
if self.club and not (v and v.paid_dues): return f"<p>{cc} ONLY</p>"
body = self.body_html
body = censor_slurs(body, v)
@ -335,7 +337,7 @@ class Submission(Base):
return body
def plainbody(self, v):
if self.club and not (v and v.paid_dues): return "<p>COUNTRY CLUB ONLY</p>"
if self.club and not (v and v.paid_dues): return f"<p>{cc} ONLY</p>"
body = self.body
body = censor_slurs(body, v)
@ -346,9 +348,9 @@ class Submission(Base):
@lazy
def realtitle(self, v):
if self.club and not (v and v.paid_dues) and not (v and v.admin_level == 6):
if self.club and not (v and v.paid_dues) and not (v and v.admin_level > 1):
if v: return random.choice(TROLLTITLES).format(username=v.username)
else: return 'COUNTRY CLUB MEMBERS ONLY'
else: return f'{cc} MEMBERS ONLY'
elif self.title_html: title = self.title_html
else: title = self.title
@ -358,9 +360,9 @@ class Submission(Base):
@lazy
def plaintitle(self, v):
if self.club and not (v and v.paid_dues) and not (v and v.admin_level == 6):
if self.club and not (v and v.paid_dues) and not (v and v.admin_level > 1):
if v: return random.choice(TROLLTITLES).format(username=v.username)
else: return 'COUNTRY CLUB MEMBERS ONLY'
else: return f'{cc} MEMBERS ONLY'
else: title = self.title
title = censor_slurs(title, v)

View File

@ -50,6 +50,7 @@ class User(Base):
verified = Column(String)
verifiedcolor = Column(String)
marseyawarded = Column(Integer)
longpost = Column(Integer)
email = deferred(Column(String))
css = deferred(Column(String))
profilecss = deferred(Column(String))
@ -81,12 +82,15 @@ class User(Base):
nitter = Column(Boolean)
mute = Column(Boolean)
unmutable = Column(Boolean)
eye = Column(Boolean)
alt = Column(Boolean)
frontsize = Column(Integer, default=25)
controversial = Column(Boolean, default=False)
bio = deferred(Column(String))
bio_html = Column(String)
sig = deferred(Column(String))
sig_html = Column(String)
fp = Column(String)
sigs_disabled = Column(Boolean)
friends = deferred(Column(String))
friends_html = deferred(Column(String))
@ -166,7 +170,6 @@ class User(Base):
return return_value
@property
@lazy
def referral_count(self):
return len(self.referrals)
@ -178,7 +181,7 @@ class User(Base):
@property
@lazy
def paid_dues(self):
return self.admin_level == 6 or self.club_allowed or (self.truecoins > int(environ.get("DUES").strip()) and not self.club_banned)
return self.admin_level > 1 or self.club_allowed or (self.truecoins > int(environ.get("DUES").strip()) and not self.club_banned)
def any_block_exists(self, other):
@ -212,12 +215,12 @@ class User(Base):
@cache.memoize(timeout=86400)
def userpagelisting(self, v=None, page=1, sort="new", t="all"):
if self.shadowbanned and not (v and (v.admin_level >= 3 or v.id == self.id)):
if self.shadowbanned and not (v and (v.admin_level > 1 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 >= 3 or v.id == self.id)):
if not (v and (v.admin_level > 1 or v.id == self.id)):
posts = posts.filter_by(deleted_utc=0, is_banned=False, private=False)
now = int(time.time())
@ -356,7 +359,7 @@ class User(Base):
@property
@lazy
def post_notifications_count(self):
return g.db.query(Notification.id).join(Comment).filter(Notification.user_id == self.id, Notification.read == False, Comment.author_id == AUTOJANNY_ACCOUNT).count()
return g.db.query(Notification.id).join(Comment).filter(Notification.user_id == self.id, Notification.read == False, Comment.author_id == AUTOJANNY_ID).count()
@property
@ -400,13 +403,13 @@ class User(Base):
@lazy
def banner_url(self):
if self.bannerurl: return self.bannerurl
else: return f"http://{site}/assets/images/{site_name}/preview.webp"
else: return f"http://{site}/assets/images/{site_name}/preview.webp?v=2"
@property
@lazy
def profile_url(self):
if self.profileurl: return self.profileurl
elif "rama" in site: return f"http://{site}/assets/images/defaultpictures/{random.randint(1, 150)}.webp"
elif "rama" in site: return f"http://{site}/assets/images/defaultpictures/{random.randint(1, 150)}.webp?v=1"
else: return f"http://{site}/assets/images/default-profile-pic.webp"
@property
@ -464,7 +467,7 @@ class User(Base):
self.profileurl = None
if self.discord_id: remove_user(self)
self.is_banned = admin.id if admin else AUTOJANNY_ACCOUNT
self.is_banned = admin.id if admin else AUTOJANNY_ID
if reason: self.ban_reason = reason
g.db.add(self)

View File

@ -14,8 +14,8 @@ def send_notification(uid, text, autojanny=False):
text_html = sanitize(text_html)
if autojanny: author_id = AUTOJANNY_ACCOUNT
else: author_id = NOTIFICATIONS_ACCOUNT
if autojanny: author_id = AUTOJANNY_ID
else: author_id = NOTIFICATIONS_ID
new_comment = Comment(author_id=author_id,
parent_submission=None,
@ -38,7 +38,7 @@ def send_follow_notif(vid, user, text):
text_html = CustomRenderer().render(mistletoe.Document(text))
text_html = sanitize(text_html)
new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT,
new_comment = Comment(author_id=NOTIFICATIONS_ID,
parent_submission=None,
distinguish_level=6,
body=text,
@ -57,7 +57,7 @@ def send_unfollow_notif(vid, user, text):
text_html = CustomRenderer().render(mistletoe.Document(text))
text_html = sanitize(text_html)
new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT,
new_comment = Comment(author_id=NOTIFICATIONS_ID,
parent_submission=None,
distinguish_level=6,
body=text,
@ -76,7 +76,7 @@ def send_block_notif(vid, user, text):
text_html = CustomRenderer().render(mistletoe.Document(text))
text_html = sanitize(text_html)
new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT,
new_comment = Comment(author_id=NOTIFICATIONS_ID,
parent_submission=None,
distinguish_level=6,
body=text,
@ -95,7 +95,7 @@ def send_unblock_notif(vid, user, text):
text_html = CustomRenderer().render(mistletoe.Document(text))
text_html = sanitize(text_html)
new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT,
new_comment = Comment(author_id=NOTIFICATIONS_ID,
parent_submission=None,
distinguish_level=6,
body=text,

File diff suppressed because one or more lines are too long

View File

@ -209,7 +209,7 @@ def get_comments(cids, v=None, load_parent=False):
blocked.c.id,
).filter(Comment.id.in_(cids))
if not (v and v.shadowbanned) and not (v and v.admin_level == 6):
if not (v and v.shadowbanned) and not (v and v.admin_level > 1):
comments = comments.join(User, User.id == Comment.author_id).filter(User.shadowbanned == None)
comments = comments.join(

View File

@ -35,56 +35,12 @@ def get_logged_in_user():
return x[0]
def check_ban_evade(v):
if not v or not v.ban_evade or v.admin_level > 0 or v.is_suspended: return
if random.randint(0,30) < v.ban_evade:
v.ban(reason="permaban evasion")
send_notification(v.id, "Your account has been permanently suspended for the following reason:\n\n> permaban evasion")
for post in g.db.query(Submission).filter_by(author_id=v.id).all():
if post.is_banned:
continue
post.is_banned=True
post.ban_reason="AutoJanny"
g.db.add(post)
ma=ModAction(
kind="ban_post",
user_id=AUTOJANNY_ACCOUNT,
target_submission_id=post.id,
_note="permaban evasion"
)
g.db.add(ma)
for comment in g.db.query(Comment).filter_by(author_id=v.id).all():
if comment.is_banned:
continue
comment.is_banned=True
comment.ban_reason="AutoJanny"
g.db.add(comment)
try:
ma=ModAction(
kind="ban_comment",
user_id=AUTOJANNY_ACCOUNT,
target_comment_id=comment.id,
_note="ban evasion"
)
g.db.add(ma)
except: pass
else:
v.ban_evade +=1
if v and v.ban_evade and v.admin_level == 0 and not v.is_suspended:
if random.randint(0,30) < v.ban_evade: v.shadowbanned = "AutoJanny"
else: v.ban_evade +=1
g.db.add(v)
g.db.commit()
g.db.commit()
def auth_desired(f):
def wrapper(*args, **kwargs):
@ -128,8 +84,7 @@ def is_not_banned(f):
check_ban_evade(v)
if v.is_suspended:
abort(403)
if v.is_suspended: abort(403)
g.v = v

View File

@ -18,10 +18,11 @@ from .front import frontlist
from files.helpers.discord import add_role
SITE_NAME = environ.get("SITE_NAME", "").strip()
if SITE_NAME == 'PCM': cc = "splash mountain"
else: cc = "country club"
@app.get("/name/<id>/<name>")
@admin_level_required(6)
@admin_level_required(2)
def changename(v, id, name):
if request.host != 'pcmemes.net': abort(403)
user = g.db.query(User).filter_by(id=int(id)).first()
@ -32,9 +33,8 @@ def changename(v, id, name):
return "Username changed!"
return "User not found!"
@app.get("/coins/<id>/<coins>")
@admin_level_required(6)
@admin_level_required(2)
def addcoins(v, id, coins):
if request.host != 'pcmemes.net': abort(403)
user = g.db.query(User).filter_by(id=int(id)).first()
@ -46,7 +46,7 @@ def addcoins(v, id, coins):
return "User not found!"
@app.get("/truescore")
@admin_level_required(6)
@admin_level_required(2)
def truescore(v):
users = g.db.query(User).order_by(User.truecoins.desc()).limit(25).all()
return render_template("truescore.html", v=v, users=users)
@ -54,9 +54,9 @@ def truescore(v):
@app.post("/@<username>/revert_actions")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
def revert_actions(v, username):
if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.id in [1,28,30,995,2513,3333]) or ('rama' not in request.host and 'pcm' not in request.host):
if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host):
user = get_user(username)
if not user: abort(404)
@ -79,7 +79,7 @@ def revert_actions(v, username):
@app.post("/@<username>/club_allow")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
def club_allow(v, username):
u = get_user(username, v=v)
@ -106,11 +106,11 @@ def club_allow(v, username):
g.db.add(ma)
g.db.commit()
return {"message": f"@{username} has been allowed into the country club!"}
return {"message": f"@{username} has been allowed into the {cc}!"}
@app.post("/@<username>/club_ban")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
def club_ban(v, username):
u = get_user(username, v=v)
@ -135,17 +135,17 @@ def club_ban(v, username):
g.db.add(ma)
g.db.commit()
return {"message": f"@{username} has been kicked from the country club. Deserved."}
return {"message": f"@{username} has been kicked from the {cc}. Deserved."}
@app.post("/@<username>/make_admin")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
def make_admin(v, username):
if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.id in [1,28,30,995,2513,3333]) or ('rama' not in request.host and 'pcm' not in request.host):
if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host):
user = get_user(username)
if not user: abort(404)
user.admin_level = 6
user.admin_level = 2
g.db.add(user)
g.db.commit()
return {"message": "User has been made admin!"}
@ -153,9 +153,9 @@ def make_admin(v, username):
@app.post("/@<username>/remove_admin")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
def remove_admin(v, username):
if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.id in [1,28,30,995,2513,3333]) or ('rama' not in request.host and 'pcm' not in request.host):
if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host):
user = get_user(username)
if not user: abort(404)
user.admin_level = 0
@ -166,9 +166,9 @@ def remove_admin(v, username):
@app.post("/@<username>/make_fake_admin")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
def make_fake_admin(v, username):
if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.id in [1,28,30,995,2513,3333]) or ('rama' not in request.host and 'pcm' not in request.host):
if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host):
user = get_user(username)
if not user: abort(404)
user.admin_level = 1
@ -179,9 +179,9 @@ def make_fake_admin(v, username):
@app.post("/@<username>/remove_fake_admin")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
def remove_fake_admin(v, username):
if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.id in [1,28,30,995,2513,3333]) or ('rama' not in request.host and 'pcm' not in request.host):
if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host):
user = get_user(username)
if not user: abort(404)
user.admin_level = 0
@ -192,9 +192,9 @@ def remove_fake_admin(v, username):
@app.post("/admin/monthly")
@limiter.limit("1/day")
@admin_level_required(6)
@admin_level_required(2)
def monthly(v):
if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.id in [1,28,30,995,2513,3333]) or ('rama' not in request.host and 'pcm' not in request.host):
if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host):
thing = g.db.query(AwardRelationship).order_by(AwardRelationship.id.desc()).first().id
for u in g.db.query(User).filter(User.patron > 0).all():
if u.patron == 1: procoins = 2000
@ -212,7 +212,7 @@ def monthly(v):
@app.get('/admin/rules')
@admin_level_required(6)
@admin_level_required(2)
def get_rules(v):
try:
@ -225,7 +225,7 @@ def get_rules(v):
@app.post('/admin/rules')
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
@validate_formkey
def post_rules(v):
@ -249,7 +249,7 @@ def post_rules(v):
@app.get("/admin/shadowbanned")
@auth_required
def shadowbanned(v):
if not (v and v.admin_level == 6): abort(404)
if not (v and v.admin_level > 1): abort(404)
users = [x for x in g.db.query(User).filter(User.shadowbanned != None).all()]
return render_template("banned.html", v=v, users=users)
@ -257,13 +257,13 @@ def shadowbanned(v):
@app.get("/admin/agendaposters")
@auth_required
def agendaposters(v):
if not (v and v.admin_level == 6): abort(404)
if not (v and v.admin_level > 1): abort(404)
users = [x for x in g.db.query(User).filter_by(agendaposter = True).all()]
return render_template("banned.html", v=v, users=users)
@app.get("/admin/image_posts")
@admin_level_required(3)
@admin_level_required(2)
def image_posts_listing(v):
try: page = int(request.values.get('page', 1))
@ -281,7 +281,7 @@ def image_posts_listing(v):
@app.get("/admin/reported/posts")
@admin_level_required(3)
@admin_level_required(2)
def reported_posts(v):
page = max(1, int(request.values.get("page", 1)))
@ -302,7 +302,7 @@ def reported_posts(v):
@app.get("/admin/reported/comments")
@admin_level_required(3)
@admin_level_required(2)
def reported_comments(v):
page = max(1, int(request.values.get("page", 1)))
@ -327,14 +327,14 @@ def reported_comments(v):
standalone=True)
@app.get("/admin")
@admin_level_required(3)
@admin_level_required(2)
def admin_home(v):
with open('./disablesignups', 'r') as f:
x = f.read()
return render_template("admin/admin_home.html", v=v, x=x)
@app.post("/admin/disablesignups")
@admin_level_required(6)
@admin_level_required(2)
@validate_formkey
def disablesignups(v):
with open('./disablesignups', 'r') as f: content = f.read()
@ -348,7 +348,7 @@ def disablesignups(v):
return {"message": "Signups disabled!"}
@app.get("/admin/badge_grant")
@admin_level_required(4)
@admin_level_required(2)
def badge_grant_get(v):
badge_types = g.db.query(BadgeDef).all()
@ -370,7 +370,7 @@ def badge_grant_get(v):
@app.post("/admin/badge_grant")
@limiter.limit("1/second")
@admin_level_required(4)
@admin_level_required(2)
@validate_formkey
def badge_grant_post(v):
@ -431,7 +431,7 @@ def users_list(v):
)
@app.get("/admin/alt_votes")
@admin_level_required(4)
@admin_level_required(2)
def alt_votes_get(v):
if not request.values.get("u1") or not request.values.get("u2"):
@ -541,7 +541,7 @@ def alt_votes_get(v):
@app.post("/admin/link_accounts")
@limiter.limit("1/second")
@admin_level_required(4)
@admin_level_required(2)
@validate_formkey
def admin_link_accounts(v):
@ -561,7 +561,7 @@ def admin_link_accounts(v):
@app.get("/admin/removed")
@admin_level_required(3)
@admin_level_required(2)
def admin_removed(v):
page = int(request.values.get("page", 1))
@ -586,7 +586,7 @@ def admin_removed(v):
@app.post("/agendaposter/<user_id>")
@admin_level_required(6)
@admin_level_required(2)
@validate_formkey
def agendaposter(user_id, v):
user = g.db.query(User).filter_by(id=user_id).first()
@ -639,7 +639,7 @@ def agendaposter(user_id, v):
@app.post("/shadowban/<user_id>")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
@validate_formkey
def shadowban(user_id, v):
user = g.db.query(User).filter_by(id=user_id).first()
@ -665,7 +665,7 @@ def shadowban(user_id, v):
@app.post("/unshadowban/<user_id>")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
@validate_formkey
def unshadowban(user_id, v):
user = g.db.query(User).filter_by(id=user_id).first()
@ -690,7 +690,7 @@ def unshadowban(user_id, v):
@app.post("/admin/verify/<user_id>")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
@validate_formkey
def verify(user_id, v):
user = g.db.query(User).filter_by(id=user_id).first()
@ -709,7 +709,7 @@ def verify(user_id, v):
@app.post("/admin/unverify/<user_id>")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
@validate_formkey
def unverify(user_id, v):
user = g.db.query(User).filter_by(id=user_id).first()
@ -729,7 +729,7 @@ def unverify(user_id, v):
@app.post("/admin/title_change/<user_id>")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
@validate_formkey
def admin_title_change(user_id, v):
@ -763,7 +763,7 @@ def admin_title_change(user_id, v):
@app.post("/ban_user/<user_id>")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
@validate_formkey
def ban_user(user_id, v):
@ -838,7 +838,7 @@ def ban_user(user_id, v):
@app.post("/unban_user/<user_id>")
@limiter.limit("1/second")
@admin_level_required(6)
@admin_level_required(2)
@validate_formkey
def unban_user(user_id, v):
@ -878,7 +878,7 @@ def unban_user(user_id, v):
@app.post("/ban_post/<post_id>")
@limiter.limit("1/second")
@admin_level_required(3)
@admin_level_required(2)
@validate_formkey
def ban_post(post_id, v):
@ -916,7 +916,7 @@ def ban_post(post_id, v):
@app.post("/unban_post/<post_id>")
@limiter.limit("1/second")
@admin_level_required(3)
@admin_level_required(2)
@validate_formkey
def unban_post(post_id, v):
@ -974,7 +974,7 @@ def api_distinguish_post(post_id, v):
@app.post("/sticky/<post_id>")
@admin_level_required(3)
@admin_level_required(2)
def api_sticky_post(post_id, v):
post = g.db.query(Submission).filter_by(id=post_id).first()
@ -994,9 +994,20 @@ def api_sticky_post(post_id, v):
cache.delete_memoized(frontlist)
g.db.commit()
if post.stickied: return {"message": "Post pinned!"}
else: return {"message": "Post unpinned!"}
if post.stickied:
if v.id != post.author_id:
message = f"@{v.username} has pinned your [post](/post/{post_id})!"
existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message).first()
if not existing: send_notification(post.author_id, message)
g.db.commit()
return {"message": "Post pinned!"}
else:
if v.id != post.author_id:
message = f"@{v.username} has unpinned your [post](/post/{post_id})!"
existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message).first()
if not existing: send_notification(post.author_id, message)
g.db.commit()
return {"message": "Post unpinned!"}
@app.post("/ban_comment/<c_id>")
@limiter.limit("1/second")
@ -1075,14 +1086,14 @@ def admin_distinguish_comment(c_id, v):
return html
@app.get("/admin/dump_cache")
@admin_level_required(6)
@admin_level_required(2)
def admin_dump_cache(v):
cache.clear()
return {"message": "Internal cache cleared."}
@app.get("/admin/banned_domains/")
@admin_level_required(4)
@admin_level_required(2)
def admin_banned_domains(v):
banned_domains = g.db.query(BannedDomain).all()
@ -1090,7 +1101,7 @@ def admin_banned_domains(v):
@app.post("/admin/banned_domains")
@limiter.limit("1/second")
@admin_level_required(4)
@admin_level_required(2)
@validate_formkey
def admin_toggle_ban_domain(v):
@ -1126,7 +1137,7 @@ def admin_toggle_ban_domain(v):
@app.post("/admin/nuke_user")
@limiter.limit("1/second")
@admin_level_required(4)
@admin_level_required(2)
@validate_formkey
def admin_nuke_user(v):
@ -1160,7 +1171,7 @@ def admin_nuke_user(v):
@app.post("/admin/unnuke_user")
@limiter.limit("1/second")
@admin_level_required(4)
@admin_level_required(2)
@validate_formkey
def admin_nunuke_user(v):

View File

@ -16,7 +16,7 @@ discounts = {
73: 0.10,
}
AWARDS2 = {
AWARDS3 = {
"ban": {
"kind": "ban",
"title": "1-Day Ban",
@ -55,7 +55,8 @@ def shop(v):
"icon": "fas fa-poop",
"color": "text-black-50",
"owned": 0,
"price": 500
"price": 500,
"MB": True
},
"fireflies": {
"kind": "fireflies",
@ -64,7 +65,8 @@ def shop(v):
"icon": "fas fa-sparkles",
"color": "text-warning",
"owned": 0,
"price": 500
"price": 500,
"MB": True
},
"train": {
"kind": "train",
@ -73,7 +75,8 @@ def shop(v):
"icon": "fas fa-train",
"color": "text-pink",
"owned": 0,
"price": 500
"price": 500,
"MB": True
},
"pin": {
"kind": "pin",
@ -82,7 +85,8 @@ def shop(v):
"icon": "fas fa-thumbtack fa-rotate--45",
"color": "text-warning",
"owned": 0,
"price": 750
"price": 750,
"MB": True
},
"unpin": {
"kind": "unpin",
@ -91,7 +95,18 @@ def shop(v):
"icon": "fas fa-thumbtack fa-rotate--45",
"color": "text-black",
"owned": 0,
"price": 1000
"price": 1000,
"MB": True
},
"pizzashill": {
"kind": "pizzashill",
"title": "Pizzashill",
"description": "Forces the recipient to make all posts/comments > 280 characters for 24 hours.",
"icon": "fas fa-pizza-slice",
"color": "text-orange",
"owned": 0,
"price": 1000,
"MB": True
},
"flairlock": {
"kind": "flairlock",
@ -100,7 +115,8 @@ def shop(v):
"icon": "fas fa-lock",
"color": "text-black",
"owned": 0,
"price": 1250
"price": 1250,
"MB": True
},
"agendaposter": {
"kind": "agendaposter",
@ -109,7 +125,8 @@ def shop(v):
"icon": "fas fa-snooze",
"color": "text-purple",
"owned": 0,
"price": 2500
"price": 2500,
"MB": True
},
"marsey": {
"kind": "marsey",
@ -118,7 +135,8 @@ def shop(v):
"icon": "fas fa-cat",
"color": "text-orange",
"owned": 0,
"price": 3000
"price": 3000,
"MB": True
},
"ban": {
"kind": "ban",
@ -127,7 +145,8 @@ def shop(v):
"icon": "fas fa-gavel",
"color": "text-danger",
"owned": 0,
"price": 3000
"price": 3000,
"MB": True
},
"unban": {
"kind": "unban",
@ -136,7 +155,8 @@ def shop(v):
"icon": "fas fa-gavel",
"color": "text-success",
"owned": 0,
"price": 3500
"price": 3500,
"MB": True
},
"grass": {
"kind": "grass",
@ -145,7 +165,18 @@ def shop(v):
"icon": "fas fa-seedling",
"color": "text-success",
"owned": 0,
"price": 10000
"price": 10000,
"MB": False
},
"eye": {
"kind": "eye",
"title": "All-Seeing Eye",
"description": "Gives the recipient the ability to view private profiles.",
"icon": "fas fa-eye",
"color": "text-silver",
"owned": 0,
"price": 10000,
"MB": False
},
"pause": {
"kind": "pause",
@ -154,7 +185,8 @@ def shop(v):
"icon": "fas fa-volume-mute",
"color": "text-danger",
"owned": 0,
"price": 20000
"price": 20000,
"MB": False
},
"unpausable": {
"kind": "unpausable",
@ -163,7 +195,18 @@ def shop(v):
"icon": "fas fa-volume",
"color": "text-success",
"owned": 0,
"price": 40000
"price": 40000,
"MB": False
},
"alt": {
"kind": "alt",
"title": "Alt-Seeing Eye",
"description": "Gives the recipient the ability to view alts.",
"icon": "fas fa-eye",
"color": "text-gold",
"owned": 0,
"price": 50000,
"MB": False
},
}
@ -231,6 +274,14 @@ def buy(v, award):
"color": "text-black",
"price": 1000
},
"pizzashill": {
"kind": "pizzashill",
"title": "Pizzashill",
"description": "Forces the recipient to make all posts/comments > 280 characters for 24 hours.",
"icon": "fas fa-pizza-slice",
"color": "text-orange",
"price": 1000,
},
"flairlock": {
"kind": "flairlock",
"title": "1-Day Flairlock",
@ -279,6 +330,14 @@ def buy(v, award):
"color": "text-success",
"price": 10000
},
"eye": {
"kind": "eye",
"title": "All-Seeing Eye",
"description": "Gives the recipient the ability to view private profiles.",
"icon": "fas fa-eye",
"color": "text-silver",
"price": 10000
},
"pause": {
"kind": "pause",
"title": "Pause",
@ -295,6 +354,14 @@ def buy(v, award):
"color": "text-success",
"price": 40000
},
"alt": {
"kind": "alt",
"title": "Alt-Seeing Eye",
"description": "Gives the recipient the ability to view alts.",
"icon": "fas fa-eye",
"color": "text-gold",
"price": 50000
},
}
if award not in AWARDS: abort(400)
@ -362,7 +429,7 @@ def buy(v, award):
@auth_required
def award_post(pid, v):
if v.is_suspended and v.unban_utc == 0: return {"error": "forbidden."}, 403
if v.is_banned and not v.unban_utc: return {"error": "forbidden."}, 403
kind = request.values.get("kind", "").strip()
@ -426,7 +493,7 @@ def award_post(pid, v):
author.ban_evade = 0
send_notification(author.id, f"You have been unbanned!")
elif kind == "grass":
author.is_banned = AUTOJANNY_ACCOUNT
author.is_banned = AUTOJANNY_ID
author.ban_reason = f"grass award used by @{v.username} on /post/{post.id}"
link = f"[this post]({post.permalink})"
send_notification(author.id, f"Your account has been suspended permanently for {link}. You must [provide the admins](/contact) a timestamped picture of you touching grass to get unbanned!")
@ -460,16 +527,31 @@ def award_post(pid, v):
author.flairchanged = time.time() + 86400
elif kind == "pause":
author.mute = True
send_notification(995, f"@{v.username} bought {kind} award!")
send_notification(CARP_ID, f"@{v.username} used {kind} award!")
new_badge = Badge(badge_id=68, user_id=author.id)
g.db.add(new_badge)
elif kind == "unpausable":
author.unmutable = True
send_notification(995, f"@{v.username} bought {kind} award!")
send_notification(CARP_ID, f"@{v.username} used {kind} award!")
new_badge = Badge(badge_id=67, user_id=author.id)
g.db.add(new_badge)
elif kind == "marsey":
author.marseyawarded = time.time() + 86400
if author.marseyawarded: author.marseyawarded += 86400
else: author.marseyawarded = time.time() + 86400
elif kind == "pizzashill":
if author.longpost: author.longpost += 86400
else: author.longpost = time.time() + 86400
send_notification(IDIO_ID, f"@{v.username} used {kind} award on {post.shortlink}")
elif kind == "eye":
author.eye = True
send_notification(CARP_ID, f"@{v.username} used {kind} award!")
new_badge = Badge(badge_id=83, user_id=author.id)
g.db.add(new_badge)
elif kind == "alt":
author.alt = True
send_notification(CARP_ID, f"@{v.username} used {kind} award!")
new_badge = Badge(badge_id=84, user_id=author.id)
g.db.add(new_badge)
post.author.received_award_count += 1
g.db.add(post.author)
@ -548,7 +630,7 @@ def award_comment(cid, v):
author.ban_evade = 0
send_notification(author.id, f"You have been unbanned!")
elif kind == "grass":
author.is_banned = AUTOJANNY_ACCOUNT
author.is_banned = AUTOJANNY_ID
author.ban_reason = f"grass award used by @{v.username} on /comment/{c.id}"
link = f"[this comment]({c.permalink})"
send_notification(author.id, f"Your account has been suspended permanently for {link}. You must [provide the admins](/contact) a timestamped picture of you touching grass to get unbanned!")
@ -579,16 +661,31 @@ def award_comment(cid, v):
author.flairchanged = time.time() + 86400
elif kind == "pause":
author.mute = True
send_notification(995, f"@{v.username} bought {kind} award!")
send_notification(CARP_ID, f"@{v.username} used {kind} award!")
new_badge = Badge(badge_id=68, user_id=author.id)
g.db.add(new_badge)
elif kind == "unpausable":
author.unmutable = True
send_notification(995, f"@{v.username} bought {kind} award!")
send_notification(CARP_ID, f"@{v.username} used {kind} award!")
new_badge = Badge(badge_id=67, user_id=author.id)
g.db.add(new_badge)
elif kind == "marsey":
author.marseyawarded = time.time() + 86400
if author.marseyawarded: author.marseyawarded += 86400
else: author.marseyawarded = time.time() + 86400
elif kind == "pizzashill":
if author.longpost: author.longpost += 86400
else: author.longpost = time.time() + 86400
send_notification(IDIO_ID, f"@{v.username} used {kind} award on {c.shortlink}")
elif kind == "eye":
author.eye = True
send_notification(CARP_ID, f"@{v.username} used {kind} award!")
new_badge = Badge(badge_id=83, user_id=author.id)
g.db.add(new_badge)
elif kind == "alt":
author.alt = True
send_notification(CARP_ID, f"@{v.username} used {kind} award!")
new_badge = Badge(badge_id=84, user_id=author.id)
g.db.add(new_badge)
c.author.received_award_count += 1
g.db.add(c.author)
@ -598,20 +695,18 @@ def award_comment(cid, v):
else: return redirect("/")
@app.get("/admin/awards")
@admin_level_required(6)
@admin_level_required(2)
def admin_userawards_get(v):
if request.host == 'rdrama.net' and v.id not in [1,28,30,995,2513,3333]: render_template("admin/awards.html", awards=list(AWARDS2.values()), v=v)
if request.host == 'rdrama.net' and v.admin_level != 3: return render_template("admin/awards.html", awards=list(AWARDS3.values()), v=v)
return render_template("admin/awards.html", awards=list(AWARDS.values()), v=v)
@app.post("/admin/awards")
@limiter.limit("1/second")
@auth_required
@admin_level_required(2)
@validate_formkey
def admin_userawards_post(v):
if v.admin_level < 6: abort(403)
try: u = request.values.get("username").strip()
except: abort(404)
@ -650,145 +745,5 @@ def admin_userawards_post(v):
g.db.commit()
if request.host == 'rdrama.net' and v.id not in [1,28,30,995,2513,3333]: render_template("admin/awards.html", awards=list(AWARDS2.values()), v=v)
return render_template("admin/awards.html", awards=list(AWARDS.values()), v=v)
@app.get("/api/shop/items")
@auth_required
def items(v):
AWARDS = {
"shit": {
"kind": "shit",
"title": "Shit",
"description": "Makes flies swarm the post.",
"icon": "fas fa-poop",
"color": "text-black-50",
"owned": 0,
"price": 500
},
"fireflies": {
"kind": "fireflies",
"title": "Fireflies",
"description": "Makes fireflies swarm the post.",
"icon": "fas fa-sparkles",
"color": "text-warning",
"owned": 0,
"price": 500
},
"train": {
"kind": "train",
"title": "Train",
"description": "Summons a train on the post.",
"icon": "fas fa-train",
"color": "text-pink",
"owned": 0,
"price": 500
},
"pin": {
"kind": "pin",
"title": "1-Hour Pin",
"description": "Pins the post/comment.",
"icon": "fas fa-thumbtack fa-rotate--45",
"color": "text-warning",
"owned": 0,
"price": 750
},
"unpin": {
"kind": "unpin",
"title": "1-Hour Unpin",
"description": "Removes 1 hour from the pin duration of the post/comment.",
"icon": "fas fa-thumbtack fa-rotate--45",
"color": "text-black",
"owned": 0,
"price": 1000
},
"flairlock": {
"kind": "flairlock",
"title": "1-Day Flairlock",
"description": "Sets a flair for the recipient and locks it or 24 hours.",
"icon": "fas fa-lock",
"color": "text-black",
"owned": 0,
"price": 1250
},
"agendaposter": {
"kind": "agendaposter",
"title": "Agendaposter",
"description": "Forces the agendaposter theme on the recipient for 24 hours.",
"icon": "fas fa-snooze",
"color": "text-purple",
"owned": 0,
"price": 2500
},
"marsey": {
"kind": "marsey",
"title": "Marsey",
"description": "Makes the recipient unable to post/comment anything but marsey emojis for 24 hours.",
"icon": "fas fa-cat",
"color": "text-orange",
"owned": 0,
"price": 3000
},
"ban": {
"kind": "ban",
"title": "1-Day Ban",
"description": "Bans the recipient for a day.",
"icon": "fas fa-gavel",
"color": "text-danger",
"owned": 0,
"price": 3000
},
"unban": {
"kind": "unban",
"title": "1-Day Unban",
"description": "Removes 1 day from the ban duration of the recipient.",
"icon": "fas fa-gavel",
"color": "text-success",
"owned": 0,
"price": 3500
},
"grass": {
"kind": "grass",
"title": "Grass",
"description": "Ban the recipient permanently (must provide a timestamped picture of them touching grass to the admins to get unbanned)",
"icon": "fas fa-seedling",
"color": "text-success",
"owned": 0,
"price": 10000
},
"pause": {
"kind": "pause",
"title": "Pause",
"description": "Gives the recipient the ability to pause profile anthems.",
"icon": "fas fa-volume-mute",
"color": "text-danger",
"owned": 0,
"price": 20000
},
"unpausable": {
"kind": "unpausable",
"title": "Unpausable",
"description": "Makes the profile anthem of the recipient unpausable.",
"icon": "fas fa-volume",
"color": "text-success",
"owned": 0,
"price": 40000
},
}
for useraward in g.db.query(AwardRelationship).filter(AwardRelationship.user_id == v.id, AwardRelationship.submission_id == None, AwardRelationship.comment_id == None).all(): AWARDS[useraward.kind]["owned"] += 1
if v.patron == 1: discount = 0.10
elif v.patron == 2: discount = 0.15
elif v.patron == 3: discount = 0.20
elif v.patron == 4: discount = 0.25
elif v.patron == 5: discount = 0.30
else: discount = 0
for badge in [69,70,71,72,73]:
if v.has_badge(badge): discount += discounts[badge]
for val in AWARDS.values(): val["discount"] = discount
return AWARDS
if request.host == 'rdrama.net' and v.admin_level != 3: return render_template("admin/awards.html", awards=list(AWARDS3.values()), v=v)
return render_template("admin/awards.html", awards=list(AWARDS.values()), v=v)

View File

@ -11,8 +11,9 @@ from flask import *
from files.__main__ import app, limiter
from files.helpers.sanitize import filter_title
site = environ.get("DOMAIN").strip()
if site == 'pcmemes.net': cc = "SPLASH MOUNTAIN"
else: cc = "COUNTRY CLUB"
beams_client = PushNotifications(
instance_id=PUSHER_INSTANCE_ID,
@ -46,7 +47,7 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None):
if comment.post and comment.post.club and not (v and v.paid_dues): 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 == 6) : 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 pid:
if comment.parent_submission: pid = comment.parent_submission
@ -90,12 +91,12 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None):
blocked.c.id,
)
if not (v and v.shadowbanned) and not (v and v.admin_level == 6):
if not (v and v.shadowbanned) and not (v and v.admin_level > 1):
comments = comments.join(User, User.id == Comment.author_id).filter(User.shadowbanned == None)
comments=comments.filter(
Comment.parent_submission == post.id,
Comment.author_id != AUTOPOLLER_ACCOUNT
Comment.author_id != AUTOPOLLER_ID
).join(
votes,
votes.c.comment_id == Comment.id,
@ -122,7 +123,7 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None):
if request.headers.get("Authorization"): return top_comment.json
else:
if post.is_banned and not (v and (v.admin_level >= 3 or post.author_id == v.id)): template = "submission_banned.html"
if post.is_banned and not (v and (v.admin_level > 1 or post.author_id == v.id)): template = "submission_banned.html"
else: template = "submission.html"
return render_template(template, v=v, p=post, sort=sort, linked_comment=comment, comment_info=comment_info, render_replies=True)
@ -163,6 +164,12 @@ def api_comment(v):
marregex = list(re.finditer("^(:!?m\w+:\s*)+$", body))
if len(marregex) == 0: return {"error":"You can only type marseys!"}, 403
if v.longpost:
if time.time() > v.longpost:
v.longpost = None
g.db.add(v)
elif len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
if not body and not request.files.get('file'): return {"error":"You need to actually write something!"}, 400
for i in re.finditer('^(https:\/\/.*\.(png|jpg|jpeg|gif|webp|PNG|JPG|JPEG|GIF|WEBP|9999))', body, re.MULTILINE):
@ -187,6 +194,8 @@ def api_comment(v):
if v.marseyawarded and len(list(re.finditer('>[^<\s+]|[^>\s+]<', body_html))) > 0: return {"error":"You can only type marseys!"}, 403
if v.longpost and len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
bans = filter_comment_html(body_html)
if bans:
@ -203,7 +212,7 @@ def api_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 not v.admin_level>=3: return {"error": "You can't reply to users who have blocked you, or users you have blocked."}, 403
if parent.author.any_block_exists(v) and v.admin_level < 2: return {"error": "You can't reply to users who have blocked you, or users you have blocked."}, 403
is_bot = request.headers.get("Authorization")
@ -240,7 +249,7 @@ def api_comment(v):
comment.ban_reason = "AutoJanny"
g.db.add(comment)
ma=ModAction(
user_id=AUTOJANNY_ACCOUNT,
user_id=AUTOJANNY_ID,
target_comment_id=comment.id,
kind="ban_comment",
_note="spam"
@ -255,7 +264,7 @@ def api_comment(v):
parent_submission=parent_submission,
parent_comment_id=parent_comment_id,
level=level,
over_18=parent_post.over_18 or request.values.get("over_18","")=="true",
over_18=request.host == 'pcmemes.net' and v.id == 1578 or parent_post.over_18 or request.values.get("over_18","")=="true",
is_bot=is_bot,
app_id=v.client.application.id if v.client else None,
body_html=body_html,
@ -267,7 +276,7 @@ def api_comment(v):
g.db.flush()
for option in options:
c_option = Comment(author_id=AUTOPOLLER_ACCOUNT,
c_option = Comment(author_id=AUTOPOLLER_ID,
parent_submission=parent_submission,
parent_comment_id=c.id,
level=level+1,
@ -296,7 +305,7 @@ def api_comment(v):
body_based_html = sanitize(body_md)
c_based = Comment(author_id=BASEDBOT_ACCOUNT,
c_based = Comment(author_id=BASEDBOT_ID,
parent_submission=parent_submission,
distinguish_level=6,
parent_comment_id=c.id,
@ -327,7 +336,7 @@ def api_comment(v):
c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=parent_submission,
distinguish_level=6,
parent_comment_id=c.id,
@ -360,7 +369,7 @@ def api_comment(v):
c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=parent_submission,
distinguish_level=6,
parent_comment_id=c.id,
@ -395,7 +404,7 @@ def api_comment(v):
c2 = Comment(author_id=LONGPOSTBOT_ACCOUNT,
c2 = Comment(author_id=LONGPOSTBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c.id,
level=level+1,
@ -405,7 +414,7 @@ def api_comment(v):
g.db.add(c2)
longpostbot = g.db.query(User).filter_by(id = LONGPOSTBOT_ACCOUNT).first()
longpostbot = g.db.query(User).filter_by(id = LONGPOSTBOT_ID).first()
longpostbot.comment_count += 1
longpostbot.coins += 1
g.db.add(longpostbot)
@ -432,7 +441,7 @@ def api_comment(v):
c2 = Comment(author_id=ZOZBOT_ACCOUNT,
c2 = Comment(author_id=ZOZBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c.id,
level=level+1,
@ -458,7 +467,7 @@ def api_comment(v):
c3 = Comment(author_id=ZOZBOT_ACCOUNT,
c3 = Comment(author_id=ZOZBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c2.id,
level=level+2,
@ -480,7 +489,7 @@ def api_comment(v):
body_html2 = sanitize(body_md)
c4 = Comment(author_id=ZOZBOT_ACCOUNT,
c4 = Comment(author_id=ZOZBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c3.id,
level=level+3,
@ -490,7 +499,7 @@ def api_comment(v):
g.db.add(c4)
zozbot = g.db.query(User).filter_by(id = ZOZBOT_ACCOUNT).first()
zozbot = g.db.query(User).filter_by(id = ZOZBOT_ID).first()
zozbot.comment_count += 3
zozbot.coins += 3
g.db.add(zozbot)
@ -511,7 +520,7 @@ def api_comment(v):
for x in g.db.query(Subscription.user_id).filter_by(submission_id=c.parent_submission).all(): notify_users.add(x[0])
if parent.author.id != v.id: notify_users.add(parent.author.id)
if parent.author.id not in [v.id, BASEDBOT_ID, AUTOJANNY_ID, SNAPPY_ID, LONGPOSTBOT_ID, ZOZBOT_ID, AUTOPOLLER_ID]: notify_users.add(parent.author.id)
soup = BeautifulSoup(body_html, features="html.parser")
mentions = soup.find_all("a", href=re.compile("^/@(\w+)"))
@ -526,9 +535,11 @@ def api_comment(v):
if user.id != v.id: notify_users.add(user.id)
if request.host == 'rdrama.net':
if 'aevann' in body_html.lower() and 1 not in notify_users: notify_users.add(1)
if 'joan' in body_html.lower() and 28 not in notify_users: notify_users.add(28)
if 'carp' in body_html.lower() and 995 not in notify_users: notify_users.add(995)
if ('aevan' in body_html.lower() or 'avean' in body_html.lower()) and 1 not in notify_users: notify_users.add(1)
if ('joan' in body_html.lower() or 'pewkie' in body_html.lower()) and 28 not in notify_users: notify_users.add(28)
if 'carp' in body_html.lower() and 995 not in notify_users:
notify_users.add(995)
notify_users.add(541)
if ('idio3' in body_html.lower() or 'idio ' in body_html.lower()) and 30 not in notify_users: notify_users.add(30)
for x in notify_users:
@ -545,7 +556,7 @@ def api_comment(v):
'notification': {
'title': f'New reply by @{v.username}',
'body': c.body,
'deep_link': f'http://{site}{c.permalink}?context=10&read=true#context',
'deep_link': f'http://{site}/comment/{c.id}?context=9&read=true#context',
},
},
},
@ -606,6 +617,12 @@ def edit_comment(cid, v):
marregex = list(re.finditer("^(:!?m\w+:\s*)+$", body))
if len(marregex) == 0: return {"error":"You can only type marseys!"}, 403
if v.longpost:
if time.time() > v.longpost:
v.longpost = None
g.db.add(v)
elif len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
for i in re.finditer('^(https:\/\/.*\.(png|jpg|jpeg|gif|webp|PNG|JPG|JPEG|GIF|WEBP|9999))', body, re.MULTILINE):
if "wikipedia" not in i.group(1): body = body.replace(i.group(1), f'![]({i.group(1)})')
body_md = CustomRenderer().render(mistletoe.Document(body))
@ -613,6 +630,8 @@ def edit_comment(cid, v):
if v.marseyawarded and len(list(re.finditer('>[^<\s+]|[^>\s+]<', body_html))) > 0: return {"error":"You can only type marseys!"}, 403
if v.longpost and len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
bans = filter_comment_html(body_html)
if bans:
@ -695,7 +714,7 @@ def edit_comment(cid, v):
c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=c.parent_submission,
distinguish_level=6,
parent_comment_id=c.id,
@ -729,7 +748,7 @@ def edit_comment(cid, v):
c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=c.parent_submission,
distinguish_level=6,
parent_comment_id=c.id,
@ -767,9 +786,11 @@ def edit_comment(cid, v):
if user.id != v.id: notify_users.add(user.id)
if request.host == 'rdrama.net':
if 'aevann' in body_html.lower() and 1 not in notify_users: notify_users.add(1)
if 'joan' in body_html.lower() and 28 not in notify_users: notify_users.add(28)
if 'carp' in body_html.lower() and 995 not in notify_users: notify_users.add(995)
if ('aevan' in body_html.lower() or 'avean' in body_html.lower()) and 1 not in notify_users: notify_users.add(1)
if ('joan' in body_html.lower() or 'pewkie' in body_html.lower()) and 28 not in notify_users: notify_users.add(28)
if 'carp' in body_html.lower() and 995 not in notify_users:
notify_users.add(995)
notify_users.add(541)
if ('idio3' in body_html.lower() or 'idio ' in body_html.lower()) and 30 not in notify_users: notify_users.add(30)
for x in notify_users:
@ -842,16 +863,16 @@ def toggle_pin_comment(cid, v):
if comment.is_pinned:
if comment.is_pinned.startswith("t:"): abort(403)
else:
if v.admin_level == 6 or comment.is_pinned.endswith(" (OP)"): comment.is_pinned = None
if v.admin_level > 1 or comment.is_pinned.endswith(" (OP)"): comment.is_pinned = None
else: abort(403)
else:
if v.admin_level == 6: comment.is_pinned = v.username
if v.admin_level > 1: comment.is_pinned = v.username
else: comment.is_pinned = v.username + " (OP)"
g.db.add(comment)
g.db.flush()
if v.admin_level == 6:
if v.admin_level > 1:
ma=ModAction(
kind="pin_comment" if comment.is_pinned else "unpin_comment",
user_id=v.id,
@ -861,8 +882,20 @@ def toggle_pin_comment(cid, v):
g.db.commit()
if comment.is_pinned: return {"message": "Comment pinned!"}
else: return {"message": "Comment unpinned!"}
if comment.is_pinned:
if v.id != comment.author_id:
message = f"@{v.username} has pinned your [comment]({comment.permalink})!"
existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message).first()
if not existing: send_notification(comment.author_id, message)
g.db.commit()
return {"message": "Comment pinned!"}
else:
if v.id != comment.author_id:
message = f"@{v.username} has unpinned your [comment]({comment.permalink})!"
existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message).first()
if not existing: send_notification(comment.author_id, message)
g.db.commit()
return {"message": "Comment unpinned!"}
@app.post("/save_comment/<cid>")
@ -878,6 +911,7 @@ def save_comment(cid, v):
if not save:
new_save=SaveRelationship(user_id=v.id, comment_id=comment.id, type=2)
g.db.add(new_save)
try: g.db.commit()
except: g.db.rollback()

View File

@ -116,7 +116,7 @@ def discord_redirect(v):
if x.status_code in [201, 204]:
if v.id in [1,7]:
if v.admin_level > 2:
add_role(v, "owner")
time.sleep(0.1)

View File

@ -28,7 +28,7 @@ def notifications(v):
messages = request.values.get('messages', False)
modmail = request.values.get('modmail', False)
posts = request.values.get('posts', False)
if modmail and v.admin_level == 6:
if modmail and v.admin_level > 1:
comments = g.db.query(Comment).filter(Comment.sentto==0).order_by(Comment.created_utc.desc()).offset(25*(page-1)).limit(26).all()
next_exists = (len(comments) > 25)
comments = comments[:25]
@ -37,7 +37,7 @@ def notifications(v):
next_exists = (len(comments) > 25)
comments = comments[:25]
elif posts:
notifications = v.notifications.join(Notification.comment).filter(Comment.author_id == AUTOJANNY_ACCOUNT).order_by(Notification.id.desc()).offset(25 * (page - 1)).limit(101).all()
notifications = v.notifications.join(Notification.comment).filter(Comment.author_id == AUTOJANNY_ID).order_by(Notification.id.desc()).offset(25 * (page - 1)).limit(101).all()
listing = []
@ -58,7 +58,7 @@ def notifications(v):
notifications = v.notifications.join(Notification.comment).filter(
Comment.is_banned == False,
Comment.deleted_utc == 0,
Comment.author_id != AUTOJANNY_ACCOUNT,
Comment.author_id != AUTOJANNY_ID,
).order_by(Notification.id.desc()).offset(25 * (page - 1)).limit(26).all()
next_exists = (len(notifications) > 25)
@ -299,7 +299,7 @@ def changeloglist(v=None, sort="new", page=1 ,t="all"):
Submission.author_id.notin_(blocked)
)
admins = [x[0] for x in g.db.query(User.id).filter(User.admin_level == 6).all()]
admins = [x[0] for x in g.db.query(User.id).filter(User.admin_level > 1).all()]
posts = posts.filter(Submission.title.ilike('_changelog%'), Submission.author_id.in_(admins))
if t != 'all':
@ -364,13 +364,10 @@ def comment_idlist(page=1, v=None, nsfw=False, sort="new", t="all"):
UserBlock.user_id).filter_by(
target_id=v.id).all()]
comments = comments.filter(
Comment.author_id.notin_(blocking),
Comment.author_id.notin_(blocked)
)
comments = comments.filter(Comment.author_id.notin_(blocking), Comment.author_id.notin_(blocked))
if not v or not v.admin_level >= 3:
comments = comments.filter_by(is_banned=False).filter(Comment.deleted_utc == 0)
if not v or not v.admin_level > 1:
comments = comments.filter(Comment.is_banned==False, Comment.deleted_utc == 0)
now = int(time.time())
if t == 'hour':

View File

@ -27,9 +27,9 @@ def check_for_alts(current_id):
session["history"] = list(past_accs)
for past_id in session["history"]:
if past_id == current_id:
continue
if past_id == MOM_ID or current_id == MOM_ID: break
if past_id == current_id: continue
check1 = g.db.query(Alt).filter_by(
user1=current_id, user2=past_id).first()
@ -72,8 +72,6 @@ def check_for_alts(current_id):
g.db.add(new_alt)
g.db.flush()
# login post procedure
@app.post("/login")
@limiter.limit("1/second")
@ -320,8 +318,8 @@ def sign_up_post(v):
g.db.add(ref_user)
id_1 = g.db.query(User.id).filter_by(id=7).count()
users_count = g.db.query(User.id).count() #paranoid
if id_1 == 0 and users_count < 7: admin_level=6
users_count = g.db.query(User.id).count()
if id_1 == 0 and users_count < 7: admin_level=3
else: admin_level=0
new_user = User(
@ -332,7 +330,7 @@ def sign_up_post(v):
email=email,
created_utc=int(time.time()),
referred_by=ref_id or None,
ban_evade = int(any([x.is_banned and not x.unban_utc for x in g.db.query(User).filter(User.id.in_(tuple(session.get("history", [])))).all() if x])),
ban_evade = int(any([(x.is_banned or x.shadowbanned) and not x.unban_utc for x in g.db.query(User).filter(User.id.in_(tuple(session.get("history", [])))).all() if x])),
agendaposter = any([x.agendaposter for x in g.db.query(User).filter(User.id.in_(tuple(session.get("history", [])))).all() if x]),
club_banned=any([x.club_banned for x in g.db.query(User).filter(User.id.in_(tuple(session.get("history", [])))).all() if x])
)

View File

@ -49,7 +49,7 @@ def request_api_keys(v):
g.db.add(new_app)
send_admin(NOTIFICATIONS_ACCOUNT, f"{v.username} has requested API keys for `{request.values.get('name')}`. You can approve or deny the request [here](/admin/apps).")
send_admin(NOTIFICATIONS_ID, f"{v.username} has requested API keys for `{request.values.get('name')}`. You can approve or deny the request [here](/admin/apps).")
g.db.commit()
@ -101,7 +101,7 @@ def edit_oauth_app(v, aid):
@app.post("/admin/app/approve/<aid>")
@limiter.limit("1/second")
@admin_level_required(3)
@admin_level_required(2)
@validate_formkey
def admin_app_approve(v, aid):
@ -136,7 +136,7 @@ def admin_app_approve(v, aid):
@app.post("/admin/app/revoke/<aid>")
@limiter.limit("1/second")
@admin_level_required(3)
@admin_level_required(2)
@validate_formkey
def admin_app_revoke(v, aid):
@ -162,7 +162,7 @@ def admin_app_revoke(v, aid):
@app.post("/admin/app/reject/<aid>")
@limiter.limit("1/second")
@admin_level_required(3)
@admin_level_required(2)
@validate_formkey
def admin_app_reject(v, aid):
@ -187,7 +187,7 @@ def admin_app_reject(v, aid):
@app.get("/admin/app/<aid>")
@admin_level_required(3)
@admin_level_required(2)
def admin_app_id(v, aid):
aid=aid
@ -213,7 +213,7 @@ def admin_app_id(v, aid):
)
@app.get("/admin/app/<aid>/comments")
@admin_level_required(3)
@admin_level_required(2)
def admin_app_id_comments(v, aid):
aid=aid
@ -242,7 +242,7 @@ def admin_app_id_comments(v, aid):
@app.get("/admin/apps")
@admin_level_required(3)
@admin_level_required(2)
def admin_apps_list(v):
apps = g.db.query(OauthApp).all()

View File

@ -68,9 +68,11 @@ def publish(pid, v):
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
if request.host == 'rdrama.net':
if 'aevann' in f'{post.body_html}{post.title}'.lower() and 1 not in notify_users: notify_users.add(1)
if 'joan' in f'{post.body_html}{post.title}'.lower() and 28 not in notify_users: notify_users.add(28)
if 'carp' in f'{post.body_html}{post.title}'.lower() and 995 not in notify_users: notify_users.add(995)
if ('aevan' in f'{post.body_html}{post.title}'.lower() or 'avean' in f'{post.body_html}{post.title}'.lower()) and 1 not in notify_users: notify_users.add(1)
if ('joan' in f'{post.body_html}{post.title}'.lower() or 'pewkie' in f'{post.body_html}{post.title}'.lower()) and 28 not in notify_users: notify_users.add(28)
if 'carp' in f'{post.body_html}{post.title}'.lower() and 995 not in notify_users:
notify_users.add(995)
notify_users.add(541)
if ('idio3' in f'{post.body_html}{post.title}'.lower() or 'idio ' in f'{post.body_html}{post.title}'.lower()) and 30 not in notify_users: notify_users.add(30)
for x in notify_users: send_notification(x, f"@{v.username} has mentioned you: http://{site}{post.permalink}")
@ -118,7 +120,7 @@ def post_id(pid, anything=None, v=None):
post = get_post(pid, v=v)
if post.club and not (v and v.paid_dues) or post.private and not (v and (v.id == post.author_id or v.admin_level == 6)): abort(403)
if post.club and not (v and v.paid_dues) or post.private and not (v and (v.id == post.author_id or v.admin_level > 1)): abort(403)
if v:
votes = g.db.query(CommentVote).filter_by(user_id=v.id).subquery()
@ -134,12 +136,12 @@ def post_id(pid, anything=None, v=None):
blocked.c.id,
)
if not (v and v.shadowbanned) and not (v and v.admin_level == 6):
if not (v and v.shadowbanned) and not (v and v.admin_level > 1):
comments = comments.join(User, User.id == Comment.author_id).filter(User.shadowbanned == None)
comments=comments.filter(
Comment.parent_submission == post.id,
Comment.author_id != AUTOPOLLER_ACCOUNT,
Comment.author_id != AUTOPOLLER_ID,
).join(
votes,
votes.c.comment_id == Comment.id,
@ -176,7 +178,7 @@ def post_id(pid, anything=None, v=None):
post.replies = [x for x in output if x.is_pinned] + [x for x in output if x.level == 1 and not x.is_pinned]
else:
comments = g.db.query(Comment).join(User, User.id == Comment.author_id).filter(User.shadowbanned == None, Comment.parent_submission == post.id, Comment.author_id != AUTOPOLLER_ACCOUNT)
comments = g.db.query(Comment).join(User, User.id == Comment.author_id).filter(User.shadowbanned == None, Comment.parent_submission == post.id, Comment.author_id != AUTOPOLLER_ID)
if sort == "new":
comments = comments.order_by(Comment.created_utc.desc())
@ -201,7 +203,7 @@ def post_id(pid, anything=None, v=None):
g.db.commit()
if request.headers.get("Authorization"): return post.json
else:
if post.is_banned and not (v and (v.admin_level >= 3 or post.author_id == v.id)): template = "submission_banned.html"
if post.is_banned and not (v and (v.admin_level > 1 or post.author_id == v.id)): template = "submission_banned.html"
else: template = "submission.html"
return render_template(template, v=v, p=post, sort=sort, render_replies=True)
@ -214,7 +216,7 @@ def edit_post(pid, v):
p = get_post(pid)
if p.author_id != v.id and not (v.admin_level == 6 and v.id in [1,28,30,995,2513,3333]): abort(403)
if p.author_id != v.id and not (v.admin_level > 1 and v.admin_level > 2): abort(403)
title = request.values.get("title", "").strip()
body = request.values.get("body", "").strip()
@ -232,6 +234,12 @@ def edit_post(pid, v):
marregex = list(re.finditer("^(:!?m\w+:\s*)+$", body))
if len(marregex) == 0: return {"error":"You can only type marseys!"}, 403
if v.longpost:
if time.time() > v.longpost:
v.longpost = None
g.db.add(v)
elif len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
if title != p.title:
title_html = filter_title(title)
if v.marseyawarded and len(list(re.finditer('>[^<\s+]|[^>\s+]<', title_html))) > 0: return {"error":"You can only type marseys!"}, 403
@ -255,6 +263,9 @@ def edit_post(pid, v):
p.body = body
if v.marseyawarded and len(list(re.finditer('>[^<\s+]|[^>\s+]<', body_html))) > 0: return {"error":"You can only type marseys!"}, 40
if v.longpost and len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
p.body_html = body_html
if "rama" in request.host and "ivermectin" in body_html.lower():
@ -271,7 +282,7 @@ def edit_post(pid, v):
body_jannied_html = sanitize(body_md)
c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=p.id,
level=1,
over_18=False,
@ -303,7 +314,7 @@ def edit_post(pid, v):
body_jannied_html = sanitize(body_md)
c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=p.id,
level=1,
over_18=False,
@ -332,13 +343,15 @@ def edit_post(pid, v):
message = f"@{v.username} has mentioned you: http://{site}{p.permalink}"
if request.host == 'rdrama.net':
if 'aevann' in f'{body_html}{title}'.lower() and 1 not in notify_users: notify_users.add(1)
if 'joan' in f'{body_html}{title}'.lower() and 28 not in notify_users: notify_users.add(28)
if 'carp' in f'{body_html}{title}'.lower() and 995 not in notify_users: notify_users.add(995)
if ('aevan' in f'{body_html}{title}'.lower() or 'avean' in f'{body_html}{title}'.lower()) and 1 not in notify_users: notify_users.add(1)
if ('joan' in f'{body_html}{title}'.lower() or 'pewkie' in f'{body_html}{title}'.lower()) and 28 not in notify_users: notify_users.add(28)
if 'carp' in f'{body_html}{title}'.lower() and 995 not in notify_users:
notify_users.add(995)
notify_users.add(541)
if ('idio3' in f'{body_html}{title}'.lower() or 'idio ' in f'{body_html}{title}'.lower()) and 30 not in notify_users: notify_users.add(30)
for x in notify_users:
existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ACCOUNT, Comment.body == message, Comment.notifiedto == x).first()
existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message, Comment.notifiedto == x).first()
if not existing: send_notification(x, message)
@ -514,8 +527,12 @@ def submit_post(v):
title = request.values.get("title", "").strip()
url = request.values.get("url", "").strip()
title_html = filter_title(title)
body = request.values.get("body", "").strip()
if v.marseyawarded and len(list(re.finditer('>[^<\s+]|[^>\s+]<', title_html))) > 0: return {"error":"You can only type marseys!"}, 40
if v.longpost and len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
if url:
if "/i.imgur.com/" in url: url = url.replace(".png", ".webp").replace(".jpg", ".webp").replace(".jpeg", ".webp")
elif "/media.giphy.com/" in url or "/c.tenor.com/" in url: url = url.replace(".gif", ".webp")
@ -560,13 +577,12 @@ def submit_post(v):
try: embed = requests.get("https://publish.twitter.com/oembed", timeout=5, params={"url":url, "omit_script":"t"}).json()["html"]
except: embed = None
elif "youtu" in domain:
try:
yt_id = re.match(re.compile("^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|shorts\/|\&v=)([^#\&\?]*).*"), url).group(2)
params = parse_qs(urlparse(url).query)
t = params.get('t', params.get('start', [0]))[0].replace('s','')
if t: embed = f"https://youtube.com/embed/{yt_id}?start={t}"
else: embed = f"https://youtube.com/embed/{yt_id}"
except: embed = None
yt_id = re.match(re.compile("^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|shorts\/|\&v=)([^#\&\?]*).*"), url).group(2)
params = parse_qs(urlparse(url).query)
t = params.get('t', params.get('start', [0]))[0]
if isinstance(t, str): t = t.replace('s','')
if t: embed = f"https://youtube.com/embed/{yt_id}?start={t}"
else: embed = f"https://youtube.com/embed/{yt_id}"
elif app.config['SERVER_NAME'] in domain and "/post/" in url and "context" not in url:
id = url.split("/post/")[1]
if "/" in id: id = id.split("/")[0]
@ -586,8 +602,6 @@ def submit_post(v):
elif len(title) > 500:
if request.headers.get("Authorization"): return {"error": "500 character limit for titles"}, 400
else: render_template("submit.html", v=v, error="500 character limit for titles.", title=title[:500], url=url, body=request.values.get("body", "")), 400
body = request.values.get("body", "").strip()
if v.marseyawarded:
if time.time() > v.marseyawarded:
@ -600,6 +614,12 @@ def submit_post(v):
marregex = list(re.finditer("^(:!?m\w+:\s*)+$", body))
if len(marregex) == 0: return {"error":"You can only type marseys!"}, 403
if v.longpost:
if time.time() > v.longpost:
v.longpost = None
g.db.add(v)
elif len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
dup = g.db.query(Submission).filter(
Submission.author_id == v.id,
Submission.deleted_utc == 0,
@ -650,7 +670,7 @@ def submit_post(v):
post.ban_reason = "AutoJanny"
g.db.add(post)
ma=ModAction(
user_id=AUTOJANNY_ACCOUNT,
user_id=AUTOJANNY_ID,
target_submission_id=post.id,
kind="ban_post",
_note="spam"
@ -681,6 +701,8 @@ def submit_post(v):
if v.marseyawarded and len(list(re.finditer('>[^<\s+]|[^>\s+]<', body_html))) > 0: return {"error":"You can only type marseys!"}, 400
if v.longpost and len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
if len(body_html) > 20000: return {"error":"Submission body too long!"}, 400
bans = filter_comment_html(body_html)
@ -698,7 +720,7 @@ def submit_post(v):
private=bool(request.values.get("private","")),
club=club,
author_id=v.id,
over_18=bool(request.values.get("over_18","")),
over_18=request.host == 'pcmemes.net' and v.id == 1578 or bool(request.values.get("over_18","")),
app_id=v.client.application.id if v.client else None,
is_bot = request.headers.get("Authorization"),
url=url,
@ -713,7 +735,7 @@ def submit_post(v):
g.db.flush()
for option in options:
c = Comment(author_id=AUTOPOLLER_ACCOUNT,
c = Comment(author_id=AUTOPOLLER_ID,
parent_submission=new_post.id,
level=1,
body_html=filter_title(option),
@ -781,9 +803,11 @@ def submit_post(v):
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
if request.host == 'rdrama.net':
if 'aevann' in f'{body_html}{title}'.lower() and 1 not in notify_users: notify_users.add(1)
if 'joan' in f'{body_html}{title}'.lower() and 28 not in notify_users: notify_users.add(28)
if 'carp' in f'{body_html}{title}'.lower() and 995 not in notify_users: notify_users.add(995)
if ('aevan' in f'{body_html}{title}'.lower() or 'avean' in f'{body_html}{title}'.lower()) and 1 not in notify_users: notify_users.add(1)
if ('joan' in f'{body_html}{title}'.lower() or 'pewkie' in f'{body_html}{title}'.lower()) and 28 not in notify_users: notify_users.add(28)
if 'carp' in f'{body_html}{title}'.lower() and 995 not in notify_users:
notify_users.add(995)
notify_users.add(541)
if ('idio3' in f'{body_html}{title}'.lower() or 'idio ' in f'{body_html}{title}'.lower()) and 30 not in notify_users: notify_users.add(30)
for x in notify_users: send_notification(x, f"@{v.username} has mentioned you: http://{site}{new_post.permalink}")
@ -812,7 +836,7 @@ def submit_post(v):
body_jannied_html = sanitize(body_md)
c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=new_post.id,
level=1,
over_18=False,
@ -846,7 +870,7 @@ def submit_post(v):
c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=new_post.id,
level=1,
over_18=False,
@ -884,7 +908,7 @@ def submit_post(v):
if new_post.url:
if new_post.url.startswith('https://old.reddit.com/r/'):
rev = new_post.url.replace('https://old.reddit.com/', '')
rev = "* [reveddit.com](https://reveddit.com/{rev})\n"
rev = f"* [reveddit.com](https://reveddit.com/{rev})\n"
else: rev = ''
body += f"Snapshots:\n\n{rev}* [archive.org](https://web.archive.org/{new_post.url})\n* [archive.ph](https://archive.ph/?url={quote(new_post.url)}&run=1) (click to archive)\n\n"
gevent.spawn(archiveorg, new_post.url)
@ -898,7 +922,7 @@ def submit_post(v):
if "Snapshots:\n\n" not in body: body += "Snapshots:\n\n"
body += f'**[{title}]({href})**:\n\n'
body += f'* [reveddit.com](https://reveddit.com/{href})\n'
body += f'* [reveddit.com](https://reveddit.com/{href.replace("https://old.reddit.com/", "")})\n'
body += f'* [archive.org](https://web.archive.org/{href})\n'
body += f'* [archive.ph](https://archive.ph/?url={quote(href)}&run=1) (click to archive)\n\n'
gevent.spawn(archiveorg, href)
@ -907,7 +931,7 @@ def submit_post(v):
body_html = sanitize(body_md)
if len(body_html) < 20000:
c = Comment(author_id=SNAPPY_ACCOUNT,
c = Comment(author_id=SNAPPY_ID,
distinguish_level=6,
parent_submission=new_post.id,
level=1,
@ -919,7 +943,7 @@ def submit_post(v):
g.db.add(c)
snappy = g.db.query(User).filter_by(id = SNAPPY_ACCOUNT).first()
snappy = g.db.query(User).filter_by(id = SNAPPY_ID).first()
snappy.comment_count += 1
snappy.coins += 1
g.db.add(snappy)
@ -936,7 +960,7 @@ def submit_post(v):
cache.delete_memoized(frontlist)
cache.delete_memoized(User.userpagelisting)
if v.admin_level == 6 and "[changelog]" in new_post.title or "(changelog)" in new_post.title:
if v.admin_level > 1 and ("[changelog]" in new_post.title or "(changelog)" in new_post.title):
send_message(f"http://{site}{new_post.permalink}")
cache.delete_memoized(changeloglist)
@ -991,7 +1015,7 @@ def undelete_post_pid(pid, v):
def toggle_comment_nsfw(cid, v):
comment = g.db.query(Comment).filter_by(id=cid).first()
if not comment.author_id == v.id and not v.admin_level >= 3: abort(403)
if not comment.author_id == v.id and not v.admin_level > 1: abort(403)
comment.over_18 = not comment.over_18
g.db.add(comment)
g.db.flush()
@ -1008,7 +1032,7 @@ def toggle_post_nsfw(pid, v):
post = get_post(pid)
if not post.author_id == v.id and not v.admin_level >= 3:
if not post.author_id == v.id and not v.admin_level > 1:
abort(403)
post.over_18 = not post.over_18

View File

@ -69,13 +69,10 @@ def api_flag_comment(cid, v):
@app.post('/del_report/<report_fn>')
@limiter.limit("1/second")
@auth_required
@admin_level_required(2)
@validate_formkey
def remove_report(report_fn, v):
if v.admin_level < 6:
return {"error": "go outside"}, 403
if report_fn.startswith('c'):
report = g.db.query(CommentFlag).filter_by(id=int(report_fn.lstrip('c'))).first()
elif report_fn.startswith('p'):

View File

@ -59,7 +59,9 @@ def searchposts(v):
posts = g.db.query(Submission.id)
if not (v and v.admin_level == 6): posts = posts.filter(Submission.private == False)
if not (v and v.paid_dues): posts = posts.filter(Submission.club == False)
if not (v and v.admin_level > 1): posts = posts.filter(Submission.private == False)
if 'q' in criteria:
words=criteria['q'].split()
@ -90,14 +92,11 @@ def searchposts(v):
)
)
if not(v and v.admin_level >= 3):
posts = posts.filter(
Submission.deleted_utc == 0,
Submission.is_banned == False,
)
if not (v and v.admin_level > 1):
posts.filter(Submission.deleted_utc == 0, Submission.is_banned == False)
if not (v and v.eye): posts = posts.join(User, User.id==Submission.author_id).filter(User.is_private == False)
if v and v.admin_level >= 4:
pass
if v and v.admin_level > 1: pass
elif v:
blocking = [x[0] for x in g.db.query(
UserBlock.target_id).filter_by(
@ -193,8 +192,6 @@ def searchcomments(v):
comments = g.db.query(Comment.id).filter(Comment.parent_submission != None)
if 'q' in criteria:
@ -207,10 +204,8 @@ def searchcomments(v):
if 'author' in criteria: comments = comments.filter(Comment.author_id == get_user(criteria['author']).id)
if not(v and v.admin_level >= 3):
comments = comments.filter(
Comment.deleted_utc == 0,
Comment.is_banned == False)
if not(v and v.admin_level > 1):
comments = comments.join(User, User.id==Comment.author_id).filter(User.is_private == False, Comment.deleted_utc == 0, Comment.is_banned == False)
if t:
now = int(time.time())

View File

@ -236,11 +236,11 @@ def settings_profile_post(v):
user = g.db.query(User).filter_by(username=username).first()
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
if request.host == 'rdrama.net' and 'aevann' in friends_html.lower() and 1 not in notify_users: notify_users.add(1)
if request.host == 'rdrama.net' and ('aevan' in friends_html.lower() or 'avean' in friends_html.lower()) and 1 not in notify_users: notify_users.add(1)
for x in notify_users:
message = f"@{v.username} has added you to their friends list!"
existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ACCOUNT, Comment.body == message, Comment.notifiedto == x).first()
existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message, Comment.notifiedto == x).first()
if not existing: send_notification(x, message)
v.friends = friends[:500]
@ -281,11 +281,11 @@ def settings_profile_post(v):
user = g.db.query(User).filter_by(username=username).first()
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
if request.host == 'rdrama.net' and 'aevann' in enemies_html.lower() and 1 not in notify_users: notify_users.add(1)
if request.host == 'rdrama.net' and ('aevan' in enemies_html.lower() or 'avean' in enemies_html.lower()) and 1 not in notify_users: notify_users.add(1)
for x in notify_users:
message = f"@{v.username} has added you to their enemies list!"
existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ACCOUNT, Comment.body == message, Comment.notifiedto == x).first()
existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message, Comment.notifiedto == x).first()
if not existing: send_notification(x, message)
v.enemies = enemies[:500]
@ -793,7 +793,7 @@ def settings_css(v):
@auth_required
def settings_profilecss_get(v):
if v.truecoins < 1000 and not v.patron and v.admin_level < 6: return f"You must have +1000 {COINS_NAME} or be a patron to set profile css."
if v.truecoins < 1000 and not v.patron and v.admin_level == 0 : return f"You must have +1000 {COINS_NAME} or be a patron to set profile css."
return render_template("settings_profilecss.html", v=v)
@app.post("/settings/profilecss")
@ -825,7 +825,7 @@ def settings_block_user(v):
if v.has_block(user):
return {"error": f"You have already blocked @{user.username}."}, 409
if user.id == NOTIFICATIONS_ACCOUNT:
if user.id == NOTIFICATIONS_ID:
return {"error": "You can't block this user."}, 409
new_block = UserBlock(user_id=v.id,
@ -908,6 +908,8 @@ def settings_content_get(v):
@validate_formkey
def settings_name_change(v):
if v.is_banned and not v.unban_utc: return {"error": "forbidden."}, 403
new_name=request.values.get("name").strip()
if new_name==v.username:

View File

@ -15,7 +15,7 @@ site_name = environ.get("SITE_NAME").strip()
def static_rules(v):
if not path.exists(f'./{site_name} rules.html'):
if v and v.admin_level == 6:
if v and v.admin_level > 1:
return render_template('norules.html', v=v)
else:
abort(404)
@ -87,12 +87,12 @@ def cached_chart():
)
today_cutoff = calendar.timegm(midnight_this_morning)
day = 3600 * 24
day = 3600 * 200
day_cutoffs = [today_cutoff - day * i for i in range(days)]
day_cutoffs.insert(0, calendar.timegm(now))
daily_times = [time.strftime("%d", time.gmtime(day_cutoffs[i + 1])) for i in range(len(day_cutoffs) - 1)][2:][::-1]
daily_times = [time.strftime("%d/%m", time.gmtime(day_cutoffs[i + 1])) for i in range(len(day_cutoffs) - 1)][2:][::-1]
daily_signups = [g.db.query(User.id).filter(User.created_utc < day_cutoffs[i], User.created_utc > day_cutoffs[i + 1]).count() for i in range(len(day_cutoffs) - 1)][2:][::-1]
@ -100,6 +100,8 @@ def cached_chart():
comment_stats = [g.db.query(Comment.id).filter(Comment.created_utc < day_cutoffs[i], Comment.created_utc > day_cutoffs[i + 1],Comment.is_banned == False, Comment.author_id != 1).count() for i in range(len(day_cutoffs) - 1)][2:][::-1]
plt.rcParams["figure.figsize"] = (20,20)
signup_chart = plt.subplot2grid((20, 4), (0, 0), rowspan=5, colspan=4)
posts_chart = plt.subplot2grid((20, 4), (7, 0), rowspan=5, colspan=4)
comments_chart = plt.subplot2grid((20, 4), (14, 0), rowspan=5, colspan=4)
@ -163,7 +165,7 @@ def patrons(v):
@app.get("/badmins")
@auth_desired
def admins(v):
admins = g.db.query(User).filter_by(admin_level=6).order_by(User.coins.desc()).all()
admins = g.db.query(User).filter(User.admin_level>1).order_by(User.coins.desc()).all()
return render_template("admins.html", v=v, admins=admins)
@ -174,7 +176,7 @@ def log(v):
page=int(request.args.get("page",1))
if v and v.admin_level == 6: actions = g.db.query(ModAction).order_by(ModAction.id.desc()).offset(25 * (page - 1)).limit(26).all()
if v and v.admin_level > 1: actions = g.db.query(ModAction).order_by(ModAction.id.desc()).offset(25 * (page - 1)).limit(26).all()
else: actions=g.db.query(ModAction).filter(ModAction.kind!="shadowban", ModAction.kind!="unshadowban", ModAction.kind!="club", ModAction.kind!="unclub", ModAction.kind!="check").order_by(ModAction.id.desc()).offset(25*(page-1)).limit(26).all()
next_exists=len(actions)>25

View File

@ -11,13 +11,87 @@ from files.mail import *
from flask import *
from files.__main__ import app, limiter
from pusher_push_notifications import PushNotifications
from collections import Counter
site = environ.get("DOMAIN").strip()
beams_client = PushNotifications(
instance_id=PUSHER_INSTANCE_ID,
secret_key=PUSHER_KEY,
)
beams_client = PushNotifications(instance_id=PUSHER_INSTANCE_ID, secret_key=PUSHER_KEY)
@app.get("/@<username>/upvoters")
@auth_desired
def upvoters(v, username):
id = get_user(username).id
votes = g.db.query(Vote.user_id, func.count(Vote.user_id)).join(Submission, Vote.submission_id==Submission.id).filter(Vote.vote_type==1, Submission.author_id==id).group_by(Vote.user_id).order_by(func.count(Vote.user_id).desc()).limit(25).all()
votes2 = g.db.query(CommentVote.user_id, func.count(CommentVote.user_id)).join(Comment, CommentVote.comment_id==Comment.id).filter(CommentVote.vote_type==1, Comment.author_id==id).group_by(CommentVote.user_id).order_by(func.count(CommentVote.user_id).desc()).limit(25).all()
votes = Counter(dict(votes)) + Counter(dict(votes2))
users = g.db.query(User).filter(User.id.in_(votes.keys())).all()
users2 = []
for user in users: users2.append((user, votes[user.id]))
users = sorted(users2, key=lambda x: x[1], reverse=True)[:25]
return render_template("voters.html", v=v, users=users, name='Up', name2=f'@{username} biggest simps')
@app.get("/@<username>/downvoters")
@auth_desired
def downvoters(v, username):
id = get_user(username).id
votes = g.db.query(Vote.user_id, func.count(Vote.user_id)).join(Submission, Vote.submission_id==Submission.id).filter(Vote.vote_type==-1, Submission.author_id==id).group_by(Vote.user_id).order_by(func.count(Vote.user_id).desc()).limit(25).all()
votes2 = g.db.query(CommentVote.user_id, func.count(CommentVote.user_id)).join(Comment, CommentVote.comment_id==Comment.id).filter(CommentVote.vote_type==-1, Comment.author_id==id).group_by(CommentVote.user_id).order_by(func.count(CommentVote.user_id).desc()).limit(25).all()
votes = Counter(dict(votes)) + Counter(dict(votes2))
users = g.db.query(User).filter(User.id.in_(votes.keys())).all()
users2 = []
for user in users: users2.append((user, votes[user.id]))
users = sorted(users2, key=lambda x: x[1], reverse=True)[:25]
return render_template("voters.html", v=v, users=users, name='Down', name2=f'@{username} biggest haters')
@app.get("/@<username>/upvoting")
@auth_desired
def upvoting(v, username):
id = get_user(username).id
votes = g.db.query(Submission.author_id, func.count(Submission.author_id)).join(Vote, Vote.submission_id==Submission.id).filter(Vote.vote_type==1, Vote.user_id==id).group_by(Submission.author_id).order_by(func.count(Submission.author_id).desc()).limit(25).all()
votes2 = g.db.query(Comment.author_id, func.count(Comment.author_id)).join(CommentVote, CommentVote.comment_id==Comment.id).filter(CommentVote.vote_type==1, CommentVote.user_id==id).group_by(Comment.author_id).order_by(func.count(Comment.author_id).desc()).limit(25).all()
votes = Counter(dict(votes)) + Counter(dict(votes2))
users = g.db.query(User).filter(User.id.in_(votes.keys())).all()
users2 = []
for user in users: users2.append((user, votes[user.id]))
users = sorted(users2, key=lambda x: x[1], reverse=True)[:25]
return render_template("voters.html", v=v, users=users, name='Up', name2=f'Who @{username} simps for')
@app.get("/@<username>/downvoting")
@auth_desired
def downvoting(v, username):
id = get_user(username).id
votes = g.db.query(Submission.author_id, func.count(Submission.author_id)).join(Vote, Vote.submission_id==Submission.id).filter(Vote.vote_type==-1, Vote.user_id==id).group_by(Submission.author_id).order_by(func.count(Submission.author_id).desc()).limit(25).all()
votes2 = g.db.query(Comment.author_id, func.count(Comment.author_id)).join(CommentVote, CommentVote.comment_id==Comment.id).filter(CommentVote.vote_type==-1, CommentVote.user_id==id).group_by(Comment.author_id).order_by(func.count(Comment.author_id).desc()).limit(25).all()
votes = Counter(dict(votes)) + Counter(dict(votes2))
users = g.db.query(User).filter(User.id.in_(votes.keys())).all()
users2 = []
for user in users: users2.append((user, votes[user.id]))
users = sorted(users2, key=lambda x: x[1], reverse=True)[:25]
return render_template("voters.html", v=v, users=users, name='Down', name2=f'Who @{username} hates')
@app.post("/pay_rent")
@limiter.limit("1/second")
@ -128,12 +202,29 @@ def transfer_coins(v, username):
if v.coins < amount: return {"error": f"You don't have enough {app.config['COINS_NAME']}"}, 400
if amount < 100: return {"error": f"You have to gift at least 100 {app.config['COINS_NAME']}."}, 400
tax = math.ceil(amount*0.015)
tax_receiver = g.db.query(User).filter_by(id=TAX_RECEIVER_ID).first()
tax_receiver.coins += tax
log_message = f"[@{v.username}]({v.url}) has transferred {amount} {app.config['COINS_NAME']} to [@{receiver.username}]({receiver.url})"
send_notification(TAX_RECEIVER_ID, log_message)
g.db.add(tax_receiver)
if not v.patron and not receiver.patron:
tax = math.ceil(amount*0.03)
tax_receiver = g.db.query(User).filter_by(id=TAX_RECEIVER_ID).first()
if request.host == 'rdrama.net': tax_receiver.coins += tax/3
else: tax_receiver.coins += tax
log_message = f"[@{v.username}]({v.url}) has transferred {amount} {app.config['COINS_NAME']} to [@{receiver.username}]({receiver.url})"
send_notification(TAX_RECEIVER_ID, log_message)
g.db.add(tax_receiver)
if request.host == 'rdrama.net':
carp = g.db.query(User).filter_by(id=CARP_ID).first()
carp.coins += tax/3
log_message = f"[@{v.username}]({v.url}) has transferred {amount} {app.config['COINS_NAME']} to [@{receiver.username}]({receiver.url})"
send_notification(CARP_ID, log_message)
g.db.add(carp)
dad = g.db.query(User).filter_by(id=DAD_ID).first()
dad.coins += tax/3
log_message = f"[@{v.username}]({v.url}) has transferred {amount} {app.config['COINS_NAME']} to [@{receiver.username}]({receiver.url})"
send_notification(DAD_ID, log_message)
g.db.add(dad)
else: tax = 0
receiver.coins += amount-tax
v.coins -= amount
send_notification(receiver.id, f"🤑 [@{v.username}]({v.url}) has gifted you {amount-tax} {app.config['COINS_NAME']}!")
@ -422,7 +513,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 < 3)):
if u.is_private and (not v or (v.id != u.id and v.admin_level < 2 and not v.eye)):
if v and u.id == LLM_ID:
if int(time.time()) - v.rent_utc > 600:
@ -433,12 +524,12 @@ def u_username(username, v=None):
else: return render_template("userpage_private.html", time=int(time.time()), u=u, v=v)
if hasattr(u, 'is_blocking') and u.is_blocking and (not v or v.admin_level < 3):
if hasattr(u, 'is_blocking') and u.is_blocking and (not v or v.admin_level < 2):
if request.headers.get("Authorization"): return {"error": f"You are blocking @{u.username}."}
else: return render_template("userpage_blocking.html", u=u, v=v)
if hasattr(u, 'is_blocked') and u.is_blocked and (not v or v.admin_level < 3):
if hasattr(u, 'is_blocked') and u.is_blocked and (not v or v.admin_level < 2):
if request.headers.get("Authorization"): return {"error": "This person is blocking you."}
else: return render_template("userpage_blocked.html", u=u, v=v)
@ -515,7 +606,7 @@ def u_username_comments(username, v=None):
v=v)
if u.is_private and (not v or (v.id != u.id and v.admin_level < 3)):
if u.is_private and (not v or (v.id != u.id and v.admin_level < 2 and not v.eye)):
if v and u.id == LLM_ID:
if int(time.time()) - v.rent_utc > 600:
if request.headers.get("Authorization"): return {"error": "That userpage is private"}
@ -524,13 +615,13 @@ def u_username_comments(username, v=None):
if request.headers.get("Authorization"): return {"error": "That userpage is private"}
else: return render_template("userpage_private.html", time=int(time.time()), u=u, v=v)
if hasattr(u, 'is_blocking') and u.is_blocking and (not v or v.admin_level < 3):
if hasattr(u, 'is_blocking') and u.is_blocking and (not v or v.admin_level < 2):
if request.headers.get("Authorization"): return {"error": f"You are blocking @{u.username}."}
else: return render_template("userpage_blocking.html",
u=u,
v=v)
if hasattr(u, 'is_blocked') and u.is_blocked and (not v or v.admin_level < 3):
if hasattr(u, 'is_blocked') and u.is_blocked and (not v or v.admin_level < 2):
if request.headers.get("Authorization"): return {"error": "This person is blocking you."}
else: return render_template("userpage_blocked.html",
u=u,
@ -738,3 +829,22 @@ def saved_comments(v, username):
page=page,
next_exists=next_exists,
standalone=True)
@app.post("/fp/<fp>")
@auth_required
def fp(v, fp):
if v.username != fp:
v.fp = fp
users = g.db.query(User).filter(User.fp == fp, User.id != v.id).all()
for u in users:
li = [v.id, u.id]
existing = g.db.query(Alt).filter(Alt.user1.in_(li), Alt.user2.in_(li)).first()
if existing: continue
new_alt = Alt(user1=v.id, user2=u.id)
g.db.add(new_alt)
g.db.flush()
print(v.username + ' + ' + u.username)
g.db.add(v)
g.db.commit()
return ''

View File

@ -22,6 +22,8 @@ def admin_vote_info_get(v):
else: abort(400)
except: abort(400)
if thing.author.shadowbanned and not (v and v.admin_level): return render_template('errors/500.html', v=v), 500
if isinstance(thing, Submission):
ups = g.db.query(Vote
@ -61,6 +63,8 @@ def admin_vote_info_get(v):
@validate_formkey
def api_vote_post(post_id, new, v):
if v.is_banned and not v.unban_utc: return {"error": "forbidden."}, 403
if new not in ["-1", "0", "1"]: abort(400)
if request.headers.get("Authorization"): abort(403)
@ -118,6 +122,8 @@ def api_vote_post(post_id, new, v):
@validate_formkey
def api_vote_comment(comment_id, new, v):
if v.is_banned and not v.unban_utc: return {"error": "forbidden."}, 403
if new not in ["-1", "0", "1"]: abort(400)
if request.headers.get("Authorization"): abort(403)

View File

@ -63,7 +63,7 @@
</form>
<pre></pre>
{% if 'rdrama.net' not in request.host or v.id in [1,995,2513] %}
{% if 'rdrama.net' not in request.host or v.admin_level > 2 %}
<div><a class="btn btn-success" href="javascript:void(0)" onclick="post_toast('/admin/monthly')">Grant Monthly Marseybux</a></div>
{% endif %}
{% endblock %}

View File

@ -15,11 +15,11 @@
{% if v %}
<style>:root{--primary:#{{v.themecolor}}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=97">
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/css/agendaposter.css?v=97">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
<link rel="stylesheet" href="/assets/css/main.css?v=118"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=117">
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/css/agendaposter.css?v=117">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
{% else %}
<style>:root{--primary:#{{'DEFAULT_COLOR' | app_config}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=97">
<link rel="stylesheet" href="/assets/css/main.css?v=118"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=117">
{% endif %}
</head>
@ -91,7 +91,7 @@
<div class="splash-overlay"></div>
<img loading="lazy" class="splash-img" src="/assets/images/{{'SITE_NAME' | app_config}}/cover.webp"></img>
<img loading="lazy" class="splash-img" src="/assets/images/{{'SITE_NAME' | app_config}}/cover.webp?v=1"></img>
</div>
</div>

View File

@ -23,11 +23,6 @@
<div class="text-muted">{{award.owned}} owned</div>
</a>
{% endfor %}
<a class="card disabled d-md-none" style="border:none">
<i class="fas fa-volume-mute" style="opacity:0"></i>
<div class="pt-2" style="font-weight: bold; font-size: 14px; color:#E1E1E1">&nbsp;</div>
<div class="text-muted">&nbsp;</div>
</a>
</div>
<label id="notelabel" for="note" class="pt-4">Note (optional):</label>
<input id="kind" name="kind" value="" hidden>
@ -77,7 +72,7 @@
@media (min-width: 767.98px) {
.award-columns {
column-count: 7 !important;
column-count: 8 !important;
}
}
</style>

View File

@ -27,13 +27,13 @@
{% if v %}
{% include "award_modal.html" %}
<script src="https://cdn.jsdelivr.net/npm/marked@3.0.8/lib/marked.min.js"></script>
<script src="/assets/js/comments_v.js?v=69"></script>
<script src="/assets/js/comments_v.js?v=70"></script>
{% endif %}
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js"></script>
{% if v and v.admin_level == 6 %}
{% if v and v.admin_level > 1 %}
<script src="/assets/js/comments_admin.js?v=53"></script>
{% endif %}
@ -173,7 +173,7 @@
{% set downs=c.downvotes %}
{% set score=ups-downs %}
{% if v and (v.shadowbanned or v.admin_level == 6) %}
{% if v and (v.shadowbanned or v.admin_level > 1) %}
{% set replies=c.replies3 %}
{% else %}
{% set replies=c.replies %}
@ -215,11 +215,11 @@
{% endfor %}
</div>
<div id="morecomment-{{c.id}}" class="d-md-none mt-2 more-comments text-small">
<a {% if v %}href="{{c.permalink}}?context=10#context"{% else %}href="/logged_out{{c.permalink}}?context=10#context"{% endif %}>More comments <i class="fas fa-long-arrow-right ml-1"></i></a>
<a {% if v %}href="{{c.shortlink}}"{% else %}href="/logged_out{{c.shortlink}}"{% endif %}>More comments <i class="fas fa-long-arrow-right ml-1"></i></a>
</div>
{% elif replies %}
<div id="morecomment-{{c.id}}" class="mt-2 more-comments text-small">
<a {% if v %}href="{{c.permalink}}?context=10#context"{% else %}href="/logged_out{{c.permalink}}?context=10#context"{% endif %}>More comments <i class="fas fa-long-arrow-right ml-1"></i></a>
<a {% if v %}href="{{c.shortlink}}"{% else %}href="/logged_out{{c.shortlink}}"{% endif %}>More comments <i class="fas fa-long-arrow-right ml-1"></i></a>
</div>
{% endif %}
{% endif %}
@ -255,7 +255,7 @@
{% else %}
<span class="font-weight-bold"><a href="{{c.post.permalink}}">{{c.post.realtitle(v) | safe}}</a></span>
{% endif %}
{% elif c.author_id==NOTIFICATIONS_ACCOUNT or c.author_id==AUTOJANNY_ACCOUNT %}
{% elif c.author_id==NOTIFICATIONS_ID or c.author_id==AUTOJANNY_ID %}
<span class="font-weight-bold">{{'SITE_NAME' | app_config}} Notification</span>
{% else %}
{% if c.sentto == 0 %}
@ -291,7 +291,7 @@
{% endif %}
{% if c.active_flags %}<a class="btn btn-primary" style="padding:1px 5px; font-size:10px;" href="javascript:void(0)" onclick="document.getElementById('flaggers-{{c.id}}').classList.toggle('d-none')">{{c.active_flags}} Reports</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==6 and c.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="Shadowbanned by @{{c.author.shadowbanned}}"></i>{% 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="" data-bs-original-title="Shadowbanned by @{{c.author.shadowbanned}}"></i>{% endif %}
{% if c.is_pinned %}<i id='pinned-{{c.id}}' class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="Pinned {% if c.is_pinned.startswith('t:') %}until {{c.is_pinned[2:]}}{% else %}by @{{c.is_pinned}}{%endif%}"></i>{% endif %}
{% if c.distinguish_level %}<i class="fas fa-broom text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="{{'SITE_NAME' | app_config}} Admin, speaking officially"></i>{% endif %}
{% if c.is_op %}<i class="fas fa-microphone-stand text-info" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="OP"></i>{% endif %}
@ -303,7 +303,7 @@
{% endif %}
<a class="user-name text-decoration-none" data-bs-placement="bottom" data-bs-toggle="popover" data-bs-trigger="focus" data-content-id="popover-{{c.id}}" href="javascript:void(0)" tabindex="0" style="color:#{{c.author.namecolor}}; font-size:12px; font-weight:bold;"><img loading="lazy" src="{{c.author.profile_url}}" class="profile-pic-25 mr-2"><span {% if c.author.patron and not c.distinguish_level %}class="patron" style="background-color:#{{c.author.namecolor}};"{% elif c.distinguish_level and 'rama' in request.host %}class="mod"{% endif %}>{{c.author.username}}</span></a>
{% if c.author.customtitle %}&nbsp;<bdi style="color: #{{c.author.titlecolor}}">&nbsp;{% if c.author.quadrant %}<img loading="lazy" height="20" src="/assets/images/PCM/quadrants/{{c.author.quadrant}}.webp">{% endif %}{{c.author.customtitle | safe}}</bdi>{% endif %}
{% if c.author.customtitle %}&nbsp;<bdi style="color: #{{c.author.titlecolor}}">&nbsp;{% if c.author.quadrant %}<img loading="lazy" height="20" src="/assets/images/PCM/quadrants/{{c.author.quadrant}}.webp?v=1">{% endif %}{{c.author.customtitle | safe}}</bdi>{% endif %}
{% if c.parent_comment_id and not standalone and level<=7 %}<a href="#comment-{{ c.parent_comment_id }}-only" class="text-muted ml-2"><i class="fas fa-reply fa-sm fa-fw fa-flip-horizontal mr-1"></i>{{ c.parent_comment.author.username }}</a>{% endif %}
@ -319,7 +319,7 @@
<pre></pre>
<ul style="padding-left:20px; margin-bottom: 0;">
{% for f in c.ordered_flags %}
<li><a style="font-weight:bold" href="{{f.user.url}}">{{f.user.username}}</a>{% if f.reason %}: {{f.reason | safe}}{% endif %} {% if v.admin_level==6 %}<a href="javascript:void(0)" onclick="post_toast('/del_report/c{{ f.id }}')">[remove]</a>{% endif %}</li>
<li><a style="font-weight:bold" href="{{f.user.url}}">{{f.user.username}}</a>{% if f.reason %}: {{f.reason | safe}}{% endif %} {% if v and v.admin_level > 1 %}<a href="javascript:void(0)" onclick="post_toast('/del_report/c{{ f.id }}')">[remove]</a>{% endif %}</li>
{% endfor %}
</ul>
</div>
@ -347,7 +347,7 @@
{% endif %}
{% if not c.parent_submission and c.author_id!=NOTIFICATIONS_ACCOUNT and c.author_id!=AUTOJANNY_ACCOUNT and c.author_id!=v.id %}
{% if not c.parent_submission and c.author_id!=NOTIFICATIONS_ID and c.author_id!=AUTOJANNY_ID and c.author_id!=v.id %}
<a class="btn btn-primary" href="javascript:void(0)" onclick="document.getElementById('reply-m-{{c.id}}').classList.toggle('d-none')">Reply</a>
<pre></pre>
<div id="reply-m-{{c.id}}" class="d-none">
@ -443,8 +443,8 @@
<a class="list-inline-item text-muted" href="javascript:void(0)" onclick="openReplyBox('{{c.id}}')"><i class="fas fa-reply" aria-hidden="true"></i><span class="d-none d-md-inline-block">Reply</span></a>
{% endif %}
<a class="list-inline-item text-muted d-none d-md-inline-block" {% if v %}href="{{c.permalink}}?context=10#context"{% else %}href="/logged_out{{c.permalink}}?context=10#context"{% endif %}><i class="fas fa-book-open"></i>Context</a>
<a class="list-inline-item text-muted d-none d-md-inline-block copy-link" href="javascript:void(0);" role="button" data-clipboard-text="{% if 'rama' in request.host %}https://freeghettohoes.biz{{c.permalink}}{% else %}{{c.permalink | full_link}}{% endif %}?context=10#context"><i class="fas fa-copy"></i>Copy link</a>
<a class="list-inline-item text-muted d-none d-md-inline-block" {% if v %}href="{{c.permalink}}"{% else %}href="/logged_out{{c.permalink}}"{% endif %}><i class="fas fa-book-open"></i>Context</a>
<a class="list-inline-item text-muted d-none d-md-inline-block copy-link" href="javascript:void(0);" role="button" data-clipboard-text="{% if 'rama' in request.host %}https://freeghettohoes.biz{{c.permalink}}{% else %}{{c.permalink | full_link}}{% endif %}"><i class="fas fa-copy"></i>Copy link</a>
{% if v %}
<a class="list-inline-item text-muted d-none d-md-inline-block" href="javascript:void(0)" data-bs-toggle="modal" data-bs-target="#reportCommentModal" onclick="report_commentModal('{{c.id}}','{{c.author.username}}',)"><i class="fas fa-flag fa-fw"></i>Report</a>
{% endif %}
@ -461,7 +461,7 @@
{% endif %}
{% endif %}
{% if v and v.admin_level==6 and v.id==c.author_id %}
{% if v and v.admin_level > 1 and v.id==c.author_id %}
<a id="undistinguish-{{c.id}}" class="list-inline-item d-none {% if c.distinguish_level %}d-md-inline-block{% endif %} text-info" href="javascript:void(0)" onclick="post_toast3('/distinguish_comment/{{c.id}}','distinguish-{{c.id}}','undistinguish-{{c.id}}','no')"><i class="fas fa-id-badge text-info fa-fw"></i>Undistinguish</a>
<a id="distinguish-{{c.id}}" class="list-inline-item d-none {% if not c.distinguish_level %}d-md-inline-block{% endif %} text-info" href="javascript:void(0)" onclick="post_toast3('/distinguish_comment/{{c.id}}','distinguish-{{c.id}}','undistinguish-{{c.id}}','yes')"><i class="fas fa-id-badge text-info fa-fw"></i>Distinguish</a>
{% endif %}
@ -474,14 +474,14 @@
<a id="block-{{c.id}}" class="{% if not c.is_blocking %}d-md-inline-block{% endif %} list-inline-item d-none text-danger" href="javascript:void(0)" onclick="document.getElementById('block-{{c.id}}').classList.toggle('d-md-inline-block');document.getElementById('prompt-{{c.id}}').classList.toggle('d-md-inline-block');"><i class="fas fa-eye-slash fa-fw text-danger"></i>Block user</a>
{% endif %}
{% if v and c.post and (v.admin_level >= 1 or v.id == c.post.author_id) and c.level == 1 %}
{% if v and c.post and (v.admin_level > 1 or v.id == c.post.author_id) and c.level == 1 %}
<a id="unpin-{{c.id}}" class="{% if c.is_pinned %}d-md-inline-block{% endif %} list-inline-item text-muted d-none text-info" href="javascript:void(0)" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/pin_comment/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Unpin</a>
<a id="pin-{{c.id}}" class="{% if not c.is_pinned %}d-md-inline-block{% endif %} list-inline-item text-muted d-none text-info" href="javascript:void(0)" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/pin_comment/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Pin</a>
{% endif %}
{% if v and v.admin_level>=3 %}
{% if v and v.admin_level > 1 %}
{% if "/reported/" in request.path %}
<a class="list-inline-item text-muted d-none d-md-inline-block text-success" href="javascript:void(0)" onclick="approveComment('{{c.id}}')"><i class="fas fa-check text-success fa-fw"></i>Approve</a>
<a class="list-inline-item text-muted d-none d-md-inline-block text-danger" href="javascript:void(0)" onclick="removeComment('{{c.id}}')"><i class="fas fa-ban text-danger fa-fw"></i>Remove</a>
@ -496,12 +496,12 @@
<a id="mark-{{c.id}}" class="list-inline-item d-none {% if not c.over_18 %}d-md-inline-block{% endif %} text-danger" href="javascript:void(0)" onclick="post_toast3('/toggle_comment_nsfw/{{c.id}}','mark-{{c.id}}','unmark-{{c.id}}')"><i class="fas fa-eye-evil text-danger fa-fw"></i>Mark +18</a>
{% endif %}
{% if v and v.admin_level==6 and v.id != c.author_id %}
{% if v and v.admin_level > 1 and v.id != c.author_id %}
<a id="unban-{{c.id}}" class="list-inline-item d-none {% if c.author.is_suspended %}d-md-inline-block{% endif %} text-success" id="unexile-comment-{{c.id}}" href="javascript:void(0)" onclick="post_toast3('/unban_user/{{c.author_id}}','ban-{{c.id}}','unban-{{c.id}}')"><i class="fas fa-user-slash text-success fa-fw"></i>Unban user</a>
<a id="ban-{{c.id}}" class="list-inline-item d-none {% if not c.author.is_suspended %}d-md-inline-block{% endif %} text-danger" id="exile-comment-{{c.id}}" href="javascript:void(0)" data-bs-toggle="modal" data-bs-target="#banModal" onclick="banModal('/comment/{{c.id}}', '{{ c.author.id }}', '{{c.author.username}}')"><i class="fas fa-user-slash text-danger fa-fw"></i>Ban user</a>
{% endif %}
{% if v and v.admin_level >=4 and c.oauth_app %}
{% if v and v.admin_level > 1 and c.oauth_app %}
<a class="list-inline-item text-muted d-none d-md-inline-block" href="{{c.oauth_app.permalink}}/comments"><i class="fas fa-code fa-fw"></i>API App</a>
{% endif %}
@ -575,11 +575,11 @@
{% endfor %}
</div>
<div id="morecomment-{{c.id}}" class="d-md-none mt-2 more-comments text-small">
<a {% if v %}href="{{c.permalink}}?context=10#context"{% else %}href="/logged_out{{c.permalink}}?context=10#context"{% endif %}>More comments <i class="fas fa-long-arrow-right ml-1"></i></a>
<a {% if v %}href="{{c.shortlink}}"{% else %}href="/logged_out{{c.shortlink}}"{% endif %}>More comments <i class="fas fa-long-arrow-right ml-1"></i></a>
</div>
{% elif replies %}
<div id="morecomment-{{c.id}}" class="mt-2 more-comments text-small">
<a {% if v %}href="{{c.permalink}}#context"{% else %}href="/logged_out{{c.permalink}}#context"{% endif %}>More comments <i class="fas fa-long-arrow-right ml-1"></i></a>
<a {% if v %}href="{{c.shortlink}}"{% else %}href="/logged_out{{c.shortlink}}"{% endif %}>More comments <i class="fas fa-long-arrow-right ml-1"></i></a>
</div>
{% endif %}
{% endif %}
@ -608,9 +608,9 @@
<a id="unsave2-{{c.id}}" class="list-group-item {% if c.id not in v.saved_comment_idlist() %}d-none{% endif %}" href="javascript:void(0)" onclick="post_toast2('/unsave_comment/{{c.id}}','save2-{{c.id}}','unsave2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-save"></i>Unsave</a>
{% endif %}
<a href="javascript:void(0);" role="button" class="list-group-item copy-link" data-bs-dismiss="modal" data-clipboard-text="{% if 'rama' in request.host %}https://freeghettohoes.biz{{c.permalink}}{% else %}{{c.permalink | full_link}}{% endif %}?context=10#context"><i class="fas fa-copy"></i>Copy link</a>
<a href="javascript:void(0);" role="button" class="list-group-item copy-link" data-bs-dismiss="modal" data-clipboard-text="{% if 'rama' in request.host %}https://freeghettohoes.biz{{c.permalink}}{% else %}{{c.permalink | full_link}}{% endif %}"><i class="fas fa-copy"></i>Copy link</a>
<a class="list-group-item" {% if v %} href="{{c.permalink}}?context=10#context" {% else %} href="/logged_out{{c.permalink}}?context=10#context" {% endif %}><i class="fas fa-dna"></i>Context</a>
<a class="list-group-item" {% if v %} href="{{c.permalink}}" {% else %} href="/logged_out{{c.permalink}}" {% endif %}><i class="fas fa-dna"></i>Context</a>
<a href="javascript:void(0)" data-bs-toggle="modal" data-bs-dismiss="modal" data-bs-target="#reportCommentModal" onclick="report_commentModal('{{c.id}}','{{c.author.username}}')" class="list-group-item"><i class="fas fa-flag"></i>Report</a>
@ -624,17 +624,17 @@
{% endif %}
{% endif %}
{% if v and c.post and (v.admin_level >= 1 or v.id == c.post.author_id) and c.level == 1 %}
{% if v and c.post and (v.admin_level > 1 or v.id == c.post.author_id) and c.level == 1 %}
<a id="pin2-{{c.id}}" class="list-group-item {% if c.is_pinned %}d-none{% endif %} text-info" href="javascript:void(0)" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast2('/pin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Pin</a>
<a id="unpin2-{{c.id}}" class="list-group-item {% if not c.is_pinned %}d-none{% endif %} text-info" href="javascript:void(0)" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast2('/pin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Unpin</a>
{% endif %}
{% if v %}
{% if v.admin_level>=1 and v.id==c.author_id %}
{% if v.admin_level > 1 and v.id==c.author_id %}
<a id="distinguish2-{{c.id}}" class="list-group-item {% if c.distinguish_level %}d-none{% endif %} text-info" href="javascript:void(0)" onclick="post_toast2('/distinguish_comment/{{c.id}}','distinguish2-{{c.id}}','undistinguish2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-id-badge text-info"></i>Distinguish</a>
<a id="undistinguish2-{{c.id}}" class="list-group-item {% if not c.distinguish_level %}d-none{% endif %} text-info" href="javascript:void(0)" onclick="post_toast2('/distinguish_comment/{{c.id}}','distinguish2-{{c.id}}','undistinguish2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-id-badge text-info"></i>Undistinguish</a>
{% endif %}
{% if v.admin_level>=3 %}
{% if v.admin_level > 1 %}
{% if "/reported/" in request.path %}
<a class="list-group-item text-danger" href="javascript:void(0)" onclick="removeComment2('{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-ban text-danger"></i>Remove</a>
<a class="list-group-item text-success" href="javascript:void(0)" onclick="approveComment2('{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-check text-success"></i>Approve</a>
@ -643,7 +643,7 @@
<a id="approve2-{{c.id}}" class="{% if not c.is_banned %}d-none{% endif %} list-group-item text-success" href="javascript:void(0)" onclick="approveComment2('{{c.id}}','approve2-{{c.id}}','remove2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-check text-success"></i>Approve</a>
{% endif %}
{% endif %}
{% if v.admin_level >=4 and c.oauth_app %}
{% if v.admin_level > 1 and c.oauth_app %}
<a href="{{c.oauth_app.permalink}}/comments" class="list-group-item text-info" ><i class="fas fa-code text-info"></i>API App</a>
{% endif %}
@ -661,7 +661,7 @@
<a id="unmark2-{{c.id}}" class="{% if not c.over_18 %}d-none{% endif %} list-group-item text-danger" href="javascript:void(0)" onclick="post_toast2('/toggle_comment_nsfw/{{c.id}}','mark2-{{c.id}}','unmark2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-eye-evil text-danger"></i>Unmark +18</a>
{% endif %}
{% if v and (c.post and v.admin_level == 6) %}
{% if v and (c.post and v.admin_level > 1) %}
{% if c.author_id != v.id %}
<a id="ban2-{{c.id}}" class="{% if c.author.is_suspended %}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.username}}')" href="javascript:void(0)"><i class="fas fa-user-slash text-danger fa-fw"></i>Ban user</a>
<a id="unban2-{{c.id}}" class="{% if not c.author.is_suspended %}d-none{% endif %} list-group-item text-success" href="javascript:void(0)" onclick="post_toast2('/unban_user/{{c.author_id}}','ban2-{{c.id}}','unban2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-user-minus fa-fw text-success"></i>Unban user</a>
@ -689,7 +689,7 @@
{% if v %}
{% include "gif_modal.html" %}
{% include "emoji_modal.html" %}
{% if v.admin_level == 6 %}
{% if v.admin_level > 1 %}
{% include "ban_modal.html" %}
{% endif %}

View File

@ -1,6 +1,6 @@
<!DOCTYPE html>
<html lang="en">
<head>
<head>
<script src="/assets/js/lozad.js?v=53"></script>
<script>
const observer = lozad();
@ -80,16 +80,16 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="thumbnail" content="/assets/images/{{'SITE_NAME' | app_config}}/preview.webp">
<meta name="thumbnail" content="/assets/images/{{'SITE_NAME' | app_config}}/preview.webp?v=2">
<link rel="icon" type="image/png" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp">
<link rel="icon" type="image/png" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp?v=1">
{% block title %}
<title>{{'SITE_NAME' | app_config}}</title>
<meta property="og:type" content="article" >
<meta property="og:title" content="{{'SITE_NAME' | app_config}}" >
<meta property="og:site_name" content="{{request.host}}" >
<meta property="og:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp" >
<meta property="og:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp?v=2" >
<meta property="og:url" content="{{request.path | full_link}}">
<meta property="og:description" name="description" content="{{'SITE_NAME' | app_config}} - {{'SLOGAN' | app_config}}">
<meta property="og:author" name="author" content="@{{request.host_url}}" >
@ -100,7 +100,7 @@
<meta name="twitter:title" content="{{'SITE_NAME' | app_config}}" >
<meta name="twitter:creator" content="@{{request.host_url}}">
<meta name="twitter:description" content="{{'SITE_NAME' | app_config}} - {{'SLOGAN' | app_config}}" >
<meta name="twitter:image" content="/assets/images/{{'SITE_NAME' | app_config}}/preview.webp" >
<meta name="twitter:image" content="/assets/images/{{'SITE_NAME' | app_config}}/preview.webp?v=2" >
<meta name="twitter:url" content="{{request.path | full_link}}" >
{% endblock %}
@ -109,12 +109,12 @@
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<link rel="apple-touch-icon" sizes="180x180" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp">
<!---<link rel="icon" type="image/png" sizes="32x32" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp">--->
<link rel="apple-touch-icon" sizes="180x180" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp?v=1">
<!---<link rel="icon" type="image/png" sizes="32x32" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp?v=1">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp?v=1">--->
<link rel="manifest" href="/assets/manifest.json">
<link rel="mask-icon" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp" color="#{{'DEFAULT_COLOR' | app_config}}">
<link rel="shortcut icon" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp">
<link rel="shortcut icon" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp?v=1">
<meta name="apple-mobile-web-app-title" content="{{'SITE_NAME' | app_config}}">
<meta name="application-name" content="{{'SITE_NAME' | app_config}}">
<meta name="msapplication-TileColor" content="#{{'DEFAULT_COLOR' | app_config}}">
@ -254,12 +254,12 @@
{% if v %}
<style>:root{--primary:#{{v.themecolor}}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112">
<link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=97">
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/css/agendaposter.css?v=97">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
<link rel="stylesheet" href="/assets/css/main.css?v=118">
<link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=117">
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/css/agendaposter.css?v=117">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
{% else %}
<style>:root{--primary:#{{'DEFAULT_COLOR' | app_config}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=97">
<link rel="stylesheet" href="/assets/css/main.css?v=118"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=117">
{% endif %}
{% endblock %}
@ -286,7 +286,7 @@
</style>
<a rel="nofollow noopener noreferrer" href="{% if 'rama' in request.host %}https://secure.transequality.org/site/Donation2?df_id=1480{% else %}/{% endif %}">
<img loading="lazy" class="banner" src="/assets/images/{{'SITE_NAME' | app_config}}/{% if v %}banner.webp{% else %}cached.webp{% endif %}" width="100%">
<img loading="lazy" class="banner" src="/assets/images/{{'SITE_NAME' | app_config}}/{% if v %}banner.webp{% else %}cached.webp{% endif %}?v=2" width="100%">
</a>
{% endif %}
{% endblock %}

View File

@ -1,4 +1,4 @@
<script src="/assets/js/emoji_modal.js?v=72"></script>
<script src="/assets/js/emoji_modal.js?v=75"></script>
<style>
a.emojitab {

View File

@ -10,7 +10,7 @@
<div class="row justify-content-center">
<div class="col-10 col-md-5">
<div class="text-center px-3 my-8">
<img loading="lazy" src="/assets/images/emojis/marseybrainlet.webp">
<img loading="lazy" src="/assets/images/emojis/marseybrainlet.webp?v=1">
<pre></pre>
<h1 class="h5">400 Bad Request</h1>
<p class="text-muted mb-5">That request was bad and you should feel bad.</p>

View File

@ -11,7 +11,7 @@
<div class="col-10 col-md-5">
<div class="text-center px-3 my-8">
<img loading="lazy" src="/assets/images/emojis/marseydead.webp">
<img loading="lazy" src="/assets/images/emojis/marseydead.webp?v=1">
<pre></pre>
<h1 class="h5">401 Not Authorized</h1>

View File

@ -10,7 +10,7 @@
<div class="row justify-content-center">
<div class="col-10 col-md-5">
<div class="text-center px-3 my-8">
<img loading="lazy" src="/assets/images/emojis/marseytroll.webp">
<img loading="lazy" src="/assets/images/emojis/marseytroll.webp?v=1">
<pre></pre>
<h1 class="h5">403 Forbidden</h1>
<p class="text-muted mb-5">YOU AREN'T WELCOME HERE GO AWAY</p>

View File

@ -10,7 +10,7 @@
<div class="row justify-content-center">
<div class="col-10 col-md-5">
<div class="text-center px-3 my-8">
<img loading="lazy" src="/assets/images/emojis/marseyconfused.webp">
<img loading="lazy" src="/assets/images/emojis/marseyconfused.webp?v=1">
<pre></pre>
<h1 class="h5">404 Page Not Found</h1>
<p class="text-muted mb-5">Someone typed something wrong and it was probably you, please do better.</p>

View File

@ -10,7 +10,7 @@
<div class="row justify-content-center">
<div class="col-10 col-md-5">
<div class="text-center px-3 my-8">
<img loading="lazy" src="/assets/images/emojis/marseyretard.webp">
<img loading="lazy" src="/assets/images/emojis/marseyretard.webp?v=1">
<pre></pre>
<h1 class="h5">405 Method Not Allowed</h1>
<p class="text-muted mb-5">idk how anyone gets this error but if you see this, remember to follow @carpathianflorist<BR>the original error text here talked about internet gremlins and wtf</p>

View File

@ -10,7 +10,7 @@
<div class="row justify-content-center">
<div class="col-10 col-md-5">
<div class="text-center px-3 my-8">
<img loading="lazy" src="/assets/images/emojis/marseyrentfree.webp">
<img loading="lazy" src="/assets/images/emojis/marseyrentfree.webp?v=1">
<pre></pre>
<h1 class="h5">429 Too Many Requests</h1>
<p class="text-muted mb-5">go spam somewhere else nerd</p>

View File

@ -10,7 +10,7 @@
<div class="row justify-content-center">
<div class="col-10 col-md-5">
<div class="text-center px-3 my-8">
<img loading="lazy" src="/assets/images/emojis/marseydead.webp">
<img loading="lazy" src="/assets/images/emojis/marseydead.webp?v=1">
<pre></pre>
<h1 class="h5">500 Internal Server Error</h1>
<p class="text-muted mb-5">Hiiiii it's carp! I think this error means that there's a timeout error. And I think that means something took too long to load so it decided not to work at all. If you keep seeing this on the same page <I>but not other pages</I>, then something is probably wrong with that specific function. It may not be called a function, but that sounds right to me. Anyway, ping me and I'll whine to someone smarter to fix it. Don't bother them. Thanks ily <3</p>

View File

@ -10,7 +10,7 @@
<div class="row justify-content-center">
<div class="col col-md-5">
<div class="text-center px-3 mt-5">
<img loading="lazy" src="/assets/images/emojis/marseytwerking.webp">
<img loading="lazy" src="/assets/images/emojis/marseytwerking.webp?v=1">
<h1 class="h5">Are you over 18?</h1>
<p class="mb-5">This post is rated +18 (Adult-Only). You must be 18 or older to continue. Are you sure you want to proceed?</p>
<div class="btn-toolbar justify-content-center mb-4">

View File

@ -10,7 +10,7 @@
<div class="row justify-content-center">
<div class="col-10 col-md-5">
<div class="text-center px-3 my-8">
<img loading="lazy" class="mb-2" src="/assets/images/emojis/marseymerchant.webp">
<img loading="lazy" class="mb-2" src="/assets/images/emojis/marseymerchant.webp?v=1">
<h1 class="h5">401 Not Authorized</h1>
<p class="text-muted">This page is only available to {% if "rama" in request.host %}paypigs{% else %}patrons{% endif %}:</p>
<a rel="nofollow noopener noreferrer" href="{{'GUMROAD_LINK' | app_config}}">{{'GUMROAD_LINK' | app_config}}</a>

View File

@ -56,12 +56,12 @@ On {{'SITE_NAME' | app_config}}, you can use Markdown formatting.
<tr>
<td>Emojis</td>
<td>:marseylove:</td>
<td><img loading="lazy" data-bs-toggle="tooltip" alt=":marseylove:" title="" data-bs-original-title=":marseylove:" delay="0" height="20" src="/assets/images/emojis/marseylove.webp"></td>
<td><img loading="lazy" data-bs-toggle="tooltip" alt=":marseylove:" title="" data-bs-original-title=":marseylove:" delay="0" height="20" src="/assets/images/emojis/marseylove.webp?v=1"></td>
</tr>
<tr>
<td>Mirrored Emojis</td>
<td>:!marseylove:</td>
<td><img loading="lazy" data-bs-toggle="tooltip" class="mirrored" alt=":!marseylove:" title="" data-bs-original-title=":!marseylove:" delay="0" height="20" src="/assets/images/emojis/marseylove.webp"></td>
<td><img loading="lazy" data-bs-toggle="tooltip" class="mirrored" alt=":!marseylove:" title="" data-bs-original-title=":!marseylove:" delay="0" height="20" src="/assets/images/emojis/marseylove.webp?v=1"></td>
</tr>
<tr>
<td>Poll Options</td>

View File

@ -21,10 +21,10 @@
<div class="container-fluid" style="padding:0;">
<div class="flex-grow-1">
<a {% if v %}href="/"{% else %}href="/logged_out"{% endif %} class="navbar-brand mr-auto">
<img loading="lazy" height="30" src="/assets/images/{{'SITE_NAME' | app_config}}/headericon.webp">
<img loading="lazy" height="30" src="/assets/images/{{'SITE_NAME' | app_config}}/headericon.webp?v=1">
{% if "gigachadlife" in request.host %}
<span style="font-weight: bold; font-size: 1.2rem;">GigaChadLife</span>
{% elif "shithole" not in request.host %}
{% elif "shithole" not in request.host and 'pcm' not in request.host %}
<img loading="lazy" src="/assets/images/{{'SITE_NAME' | app_config}}/logo.webp" height="20">
{% endif %}
</a>
@ -63,7 +63,7 @@
<a class="nav-link" href="/random/" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="Random post"><i class="fas fa-random"></i></a>
</li>
{% if v and v.admin_level==6 %}
{% if v and v.admin_level > 1 %}
<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="" data-bs-original-title="Admin tools"><i class="fas fa-crown{% if v.has_report_queue %} text-success{% endif %}"></i></a>
</li>
@ -135,8 +135,8 @@
<a class="dropdown-item" rel="nofollow noopener noreferrer" href="/post/18459/"><i class="fas fa-bug fa-fw text-left mr-3"></i>Report bugs</a>
<a class="dropdown-item" href="/discord"><i class="fab fa-discord fa-fw text-left mr-3"></i>Discord</a>
{% if 'pcm' not in request.host %}<a class="dropdown-item" rel="nofollow noopener noreferrer" href="{{'GUMROAD_LINK' | app_config}}"><i class="fas fa-dollar-sign fa-fw text-left mr-3"></i>Donate</a>{% endif %}
{% if 'pcm' not in request.host %}<a class="dropdown-item" href="/discord"><i class="fab fa-discord fa-fw text-left mr-3"></i>Discord</a>
<a class="dropdown-item" rel="nofollow noopener noreferrer" href="{{'GUMROAD_LINK' | app_config}}"><i class="fas fa-dollar-sign fa-fw text-left mr-3"></i>Donate</a>{% endif %}
{% if 'rama' in request.host %}<a class="dropdown-item" href="/archives"><i class="fas fa-book fa-fw text-left mr-3"></i>Archives</a>{% endif %}
<a class="dropdown-item" href="/contact"><i class="fas fa-file-signature fa-fw text-left mr-3"></i>Contact us</a>
</div>
@ -193,8 +193,8 @@
<a class="nav-item nav-link" rel="nofollow noopener noreferrer" href="/post/18459/"><i class="fas fa-bug fa-fw mr-3"></i>Report bugs</a>
<a class="nav-item nav-link" href="/discord"><i class="fab fa-discord fa-fw mr-3"></i>Discord</a>
{% if 'pcm' not in request.host %}<a class="nav-item nav-link" rel="nofollow noopener noreferrer" href="{{'GUMROAD_LINK' | app_config}}"><i class="fas fa-dollar-sign fa-fw mr-3"></i>Donate</a>{% endif %}
{% if 'pcm' not in request.host %}<a class="nav-item nav-link" href="/discord"><i class="fab fa-discord fa-fw mr-3"></i>Discord</a>
<a class="nav-item nav-link" rel="nofollow noopener noreferrer" href="{{'GUMROAD_LINK' | app_config}}"><i class="fas fa-dollar-sign fa-fw mr-3"></i>Donate</a>{% endif %}
{% if 'rama' in request.host %}<a class="nav-item nav-link" href="/archives"><i class="fas fa-book fa-fw mr-3"></i>Archives</a>{% endif %}
<a class="nav-item nav-link" href="/contact"><i class="fas fa-file-signature fa-fw mr-3"></i>Contact us</a>

View File

@ -2,6 +2,33 @@
{% block desktopBanner %}
{% if v %}
<script>
function fp(fp) {
var xhr = new XMLHttpRequest();
xhr.open("POST", '{{request.host_url}}fp/'+fp, true);
var form = new FormData()
form.append("formkey", formkey());
xhr.withCredentials=true;
xhr.send(form);
};
const fpPromise = new Promise((resolve, reject) => {
const script = document.createElement('script');
script.onload = resolve;
script.onerror = reject;
script.async = true;
script.src = 'https://cdn.jsdelivr.net/npm/@fingerprintjs/fingerprintjs-pro@3/dist/fp.min.js';
document.head.appendChild(script);
})
.then(() => FingerprintJS.load({token: '{{environ.get("FP")}}'}));
fpPromise
.then(fp => fp.get())
.then(result => {if (result.visitorId != '{{v.fp}}') fp(result.visitorId);})
</script>
{% endif %}
<div class="row" style="overflow: visible;padding-top:5px;">
<div class="col">
<div class="d-flex justify-content-between align-items-center">

View File

@ -17,11 +17,11 @@
{% if v %}
<style>:root{--primary:#{{v.themecolor}}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=97">
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/css/agendaposter.css?v=97">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
<link rel="stylesheet" href="/assets/css/main.css?v=118"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=117">
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/css/agendaposter.css?v=117">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
{% else %}
<style>:root{--primary:#{{'DEFAULT_COLOR' | app_config}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=97">
<link rel="stylesheet" href="/assets/css/main.css?v=118"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=117">
{% endif %}
<div class="row justify-content-around">

View File

@ -107,7 +107,7 @@
<div class="splash-overlay"></div>
<img loading="lazy" class="splash-img" src="/assets/images/{{'SITE_NAME' | app_config}}/cover.webp"></img>
<img loading="lazy" class="splash-img" src="/assets/images/{{'SITE_NAME' | app_config}}/cover.webp?v=1"></img>
</div>
</div>

View File

@ -12,7 +12,7 @@
<title>2-Step Login - {{'SITE_NAME' | app_config}}</title>
<style>:root{--primary:#{{'DEFAULT_COLOR' | app_config}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=97">
<link rel="stylesheet" href="/assets/css/main.css?v=118"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=117">
</head>
@ -92,7 +92,7 @@
<div class="splash-overlay"></div>
<img loading="lazy" class="splash-img" src="/assets/images/{{'SITE_NAME' | app_config}}/cover.webp"></img>
<img loading="lazy" class="splash-img" src="/assets/images/{{'SITE_NAME' | app_config}}/cover.webp?v=1"></img>
</div>
</div>

View File

@ -30,7 +30,7 @@
Messages
</a>
</li>
{% if v.admin_level==6 %}
{% if v.admin_level > 1 %}
<li class="nav-item">
<a class="nav-link py-3{% if '/notifications?modmail=true' in request.full_path %} active{% endif %}" href="/notifications?modmail=true">
Modmail

View File

@ -15,7 +15,7 @@
<td style="font-weight:bold;">{{loop.index}}</td>
<td><a style="color:#{{row['namecolor']}}; font-weight:bold;" href="/@{{row['username']}}"><img loading="lazy" src="/uid/{{uid}}/pic" class="pp20"><span {% if row['patron'] %}class="patron" style="background-color:#{{row['namecolor']}};"{% endif %}>{{row['username']}}</span></a></td>
<td><img loading="lazy" width=32 height=32 src="/assets/images/badges/patron-{{row['patron']}}.webp"></td>
<td><img loading="lazy" width=32 height=32 src="/assets/images/badges/patron-{{row['patron']}}.webp?v=1"></td>
<td style="font-weight:bold;">
{% for (a,count) in row['awards'].values() %}

View File

@ -32,13 +32,13 @@
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" type="image/png" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp">
<link rel="icon" type="image/png" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp?v=1">
<title>{% block pagetitle %}Settings - {{'SITE_NAME' | app_config}}{% endblock %}</title>
<meta property="og:type" content="article" >
<meta property="og:title" content="{{'SITE_NAME' | app_config}}" >
<meta property="og:site_name" content="{{request.host}}" >
<meta property="og:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp" >
<meta property="og:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp?v=2" >
<meta property="og:url" content="{{request.host}}">
<meta property="og:description" name="description" content="{{'SITE_NAME' | app_config}} - {{'SLOGAN' | app_config}}">
<meta property="og:author" name="author" content="@{{request.host_url}}" >
@ -49,14 +49,14 @@
<meta name="twitter:title" content="{{'SITE_NAME' | app_config}}" >
<meta name="twitter:creator" content="@{{request.host_url}}">
<meta name="twitter:description" content="{{'SITE_NAME' | app_config}} - {{'SLOGAN' | app_config}}" >
<meta name="twitter:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp" >
<meta name="twitter:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp?v=2" >
<meta name="twitter:url" content="{{request.host}}" >
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600&display=swap" rel="stylesheet">
<style>:root{--primary:#{{v.themecolor}}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=97">
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/css/agendaposter.css?v=97">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
<link rel="stylesheet" href="/assets/css/main.css?v=118"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=117">
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/css/agendaposter.css?v=117">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
<link href="/assets/css/fa.css?v=52" rel="stylesheet">
</head>

View File

@ -11,13 +11,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<meta name="thumbnail" content="/assets/images/{{'SITE_NAME' | app_config}}/preview.webp">
<link rel="icon" type="image/png" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp">
<meta name="thumbnail" content="/assets/images/{{'SITE_NAME' | app_config}}/preview.webp?v=2">
<link rel="icon" type="image/png" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp?v=1">
<meta property="og:type" content="article" >
<meta property="og:title" content="{{'SITE_NAME' | app_config}}" >
<meta property="og:site_name" content="{{request.host}}" >
<meta property="og:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp" >
<meta property="og:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp?v=2" >
<meta property="og:url" content="{{request.path | full_link}}">
<meta property="og:description" name="description" content="{{'SITE_NAME' | app_config}} - {{'SLOGAN' | app_config}}">
<meta property="og:author" name="author" content="{{request.host_url}}" >
@ -28,7 +28,7 @@
<meta name="twitter:title" content="{{'SITE_NAME' | app_config}}" >
<meta name="twitter:creator" content="{{request.host_url}}">
<meta name="twitter:description" content="{{'SITE_NAME' | app_config}} - {{'SLOGAN' | app_config}}" >
<meta name="twitter:image" content="/assets/images/{{'SITE_NAME' | app_config}}/preview.webp" >
<meta name="twitter:image" content="/assets/images/{{'SITE_NAME' | app_config}}/preview.webp?v=2" >
<meta name="twitter:url" content="{{request.path | full_link}}" >
@ -40,10 +40,10 @@
{% if v %}
<style>:root{--primary:#{{v.themecolor}}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=97">
<link rel="stylesheet" href="/assets/css/main.css?v=118"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=117">
{% else %}
<style>:root{--primary:#{{'DEFAULT_COLOR' | app_config}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=97">
<link rel="stylesheet" href="/assets/css/main.css?v=118"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=117">
{% endif %}
<link href="/assets/css/fa.css?v=52" rel="stylesheet">
@ -55,7 +55,7 @@
{% block subNav %}
{% set mod = (v.admin_level==6) %}
{% set mod = (v and v.admin_level > 1) %}
<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">
<div class="col">

View File

@ -550,8 +550,8 @@
<div class="body d-lg-flex border-bottom">
<label class="text-black w-lg-25">Bio</label>
<label class="text-black w-lg-25">{% if request.host == 'rdrama.net' and v.id == 2050 %}Friends{% else %}Bio{% endif %}</label>
<div class="w-lg-100">
<form id="profile-bio" action="/settings/profile" method="post" enctype="multipart/form-data">
@ -588,7 +588,7 @@
<div class="body d-lg-flex border-bottom">
<label class="text-black w-lg-25">Friends</label>
<label class="text-black w-lg-25">{% if request.host == 'rdrama.net' and v.id == 2050 %}Bio{% else %}Friends{% endif %}</label>
<div class="w-lg-100">
<form id="profile-friends" action="/settings/profile" method="post" enctype="multipart/form-data">

View File

@ -64,7 +64,7 @@
{% set kind = a['kind'] %}
<td style="font-weight: bold">
<a class="d-flex btn btn-success {% if v.coins < a['price'] %}disabled{% endif %}" href="javascript:void(0)" onclick="post_toast('/buy/{{kind}}')"><span class="m-auto">Buy</span></a>
{% if v.procoins and kind not in ["grass","pause","unpausable"] %}<a class="d-flex marseybux btn btn-success {% if v.procoins < a['price'] %}disabled{% endif %}" href="javascript:void(0)" onclick="post_toast('/buy/{{kind}}?mb=true')"><span class="m-auto">Buy with Marseybux</span></a>{% endif %}
{% if v.procoins and a['MB'] %}<a class="d-flex marseybux btn btn-success {% if v.procoins < a['price'] %}disabled{% endif %}" href="javascript:void(0)" onclick="post_toast('/buy/{{kind}}?mb=true')"><span class="m-auto">Buy with Marseybux</span></a>{% endif %}
</td>
</tr>
{% endfor %}

View File

@ -17,7 +17,7 @@
<meta property="og:type" content="article" >
<meta property="og:title" content="{{'SITE_NAME' | app_config}}" >
<meta property="og:site_name" content="{{request.host}}" >
<meta property="og:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp" >
<meta property="og:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp?v=2" >
<meta property="og:url" content="{{request.host}}">
<meta property="og:description" name="description" content="{{'SITE_NAME' | app_config}} - {{'SLOGAN' | app_config}}">
<meta property="og:author" name="author" content="{{request.host_url}}" >
@ -28,7 +28,7 @@
<meta name="twitter:title" content="{{'SITE_NAME' | app_config}}" >
<meta name="twitter:creator" content="{{request.host_url}}">
<meta name="twitter:description" content="{{'SITE_NAME' | app_config}} - {{'SLOGAN' | app_config}}" >
<meta name="twitter:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp" >
<meta name="twitter:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp?v=2" >
<meta name="twitter:url" content="{{request.host}}" >
<title>{% if ref_user %}{{ref_user.username}} invites you to {{'SITE_NAME' | app_config}}{% else %}Sign up - {{'SITE_NAME' | app_config}}{% endif %}</title>
@ -36,7 +36,7 @@
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600&display=swap" rel="stylesheet">
<style>:root{--primary:#{{'DEFAULT_COLOR' | app_config}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=97">
<link rel="stylesheet" href="/assets/css/main.css?v=118"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=117">
</head>
@ -154,7 +154,7 @@
<div class="splash-overlay"></div>
<img loading="lazy" class="splash-img" src="/assets/images/{{'SITE_NAME' | app_config}}/cover.webp"></img>
<img loading="lazy" class="splash-img" src="/assets/images/{{'SITE_NAME' | app_config}}/cover.webp?v=1"></img>
</div>
</div>

View File

@ -12,7 +12,7 @@
<meta property="og:type" content="article" >
<meta property="og:title" content="{{'SITE_NAME' | app_config}}" >
<meta property="og:site_name" content="{{request.host}}" >
<meta property="og:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp" >
<meta property="og:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp?v=2" >
<meta property="og:url" content="{{request.host}}">
<meta property="og:description" name="description" content="{{'SITE_NAME' | app_config}} - {{'SLOGAN' | app_config}}">
<meta property="og:author" name="author" content="{{request.host_url}}" >
@ -23,7 +23,7 @@
<meta name="twitter:title" content="{{'SITE_NAME' | app_config}}" >
<meta name="twitter:creator" content="{{request.host_url}}">
<meta name="twitter:description" content="{{'SITE_NAME' | app_config}} - {{'SLOGAN' | app_config}}" >
<meta name="twitter:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp" >
<meta name="twitter:image" content="{{'SITE_NAME' | app_config}}/assets/images/{{'SITE_NAME' | app_config}}/preview.webp?v=2" >
<meta name="twitter:url" content="{{request.host}}" >
<title>{% if ref_user %}{{ref_user.username}} invites you to {{'SITE_NAME' | app_config}}{% else %}{{'SITE_NAME' | app_config}}{% endif %}</title>
@ -31,7 +31,7 @@
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600&display=swap" rel="stylesheet">
<style>:root{--primary:#{{'DEFAULT_COLOR' | app_config}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=97">
<link rel="stylesheet" href="/assets/css/main.css?v=118"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=117">
</head>
@ -83,7 +83,7 @@
<div class="splash-overlay"></div>
<img loading="lazy" class="splash-img" src="/assets/images/{{'SITE_NAME' | app_config}}/cover.webp"></img>
<img loading="lazy" class="splash-img" src="/assets/images/{{'SITE_NAME' | app_config}}/cover.webp?v=1"></img>
</div>
</div>

View File

@ -87,26 +87,26 @@
}
</style>
<img class="train1" src="/assets/images/emojis/marseytrain.webp">
<img class="train1" src="/assets/images/emojis/marseytrain.webp?v=1">
{% endif %}
{% if p.award_count("train") > 1 %}
<img class="train2" src="/assets/images/emojis/marseytrain.webp">
<img class="train2" src="/assets/images/emojis/marseytrain.webp?v=1">
{% endif %}
{% if p.award_count("train") > 2 %}
<img class="train3" src="/assets/images/emojis/marseytrain.webp">
<img class="train3" src="/assets/images/emojis/marseytrain.webp?v=1">
{% endif %}
{% if p.award_count("train") > 3 %}
<img class="train4" src="/assets/images/emojis/marseytrain.webp">
<img class="train4" src="/assets/images/emojis/marseytrain.webp?v=1">
{% endif %}
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js"></script>
<script src="/assets/js/new_comments_count.js?v=53"></script>
{% if v and (v.id == p.author_id or v.admin_level == 6 and v.id in [1,28,30,995,2513,3333]) %}
{% if v and (v.id == p.author_id or v.admin_level > 1 and v.admin_level > 2) %}
<script>
togglePostEdit=function(id){
@ -146,11 +146,11 @@
</script>
{% if v %}
<script src="/assets/js/comments_v.js?v=69"></script>
<script src="/assets/js/comments_v.js?v=70"></script>
{% include "award_modal.html" %}
{% include "emoji_modal.html" %}
{% include "gif_modal.html" %}
{% if v.admin_level == 6 %}
{% if v.admin_level > 1 %}
{% include "ban_modal.html" %}
{% endif %}
{% endif %}
@ -316,7 +316,7 @@
<ul class="list-group post-actions">
<button class="nobackground btn btn-link btn-block btn-lg text-left text-muted" data-bs-toggle="modal" data-bs-dismiss="modal" data-bs-target="#reportPostModal" onclick="report_postModal('{{p.id}}')"><i class="far fa-flag text-center text-muted mr-3"></i>Report</button>
{% if v and (v.id==p.author_id or v.admin_level==6 and v.id in [1,28,30,995,2513,3333]) %}
{% if v and (v.id==p.author_id or v.admin_level > 1 and v.admin_level > 2) %}
<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-3"></i>Edit</button>
{% endif %}
@ -351,12 +351,12 @@
<button id="save2-{{p.id}}" class="{% if p.id in v.saved_idlist() %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-muted" href="javascript:void(0)" onclick="post_toast2('/save_post/{{p.id}}','save2-{{p.id}}','unsave2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-save text-center text-muted mr-3"></i>Save</button>
<button id="unsave2-{{p.id}}" class="{% if p.id not in v.saved_idlist() %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-muted" href="javascript:void(0)" onclick="post_toast2('/unsave_post/{{p.id}}','save2-{{p.id}}','unsave2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-save text-center text-muted mr-3"></i>Unsave</button>
{% if v.admin_level >=3 or v.id == p.author.id and v.paid_dues %}
{% if v.admin_level > 1 or v.id == p.author.id and v.paid_dues %}
<button id="club2-{{p.id}}" class="{% if p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-info text-left" href="javascript:void(0)" onclick="post_toast2('/toggle_club/{{p.id}}','club2-{{p.id}}','unclub2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-eye-slash mr-3"></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" href="javascript:void(0)" onclick="post_toast2('/toggle_club/{{p.id}}','club2-{{p.id}}','unclub2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-eye mr-3"></i>Unmark club</button>
{% endif %}
{% if v.admin_level >=3 %}
{% if v.admin_level > 1 %}
<button id="pin2-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></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" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Unpin</button>
{% if v==p.author %}
@ -373,7 +373,7 @@
{% endif %}
{% endif %}
{% if v.admin_level >=4 and p.oauth_app %}
{% if v.admin_level > 1 and p.oauth_app %}
<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-3"></i>API App</button></a>
{% endif %}
@ -387,7 +387,7 @@
<button id="block2-{{p.id}}" class="blockuser nobackground btn btn-link btn-block btn-lg text-danger text-left{% if p.is_blocking %} d-none{% endif %}" onclick="document.getElementById('block2-{{p.id}}').classList.toggle('d-none');document.getElementById('prompt2-{{p.id}}').classList.toggle('d-none');"><i class="fas fa-eye-slash mr-3 text-danger"></i>Block user</button>
{% endif %}
{% if v and (v.id==p.author_id or v.admin_level>=3) %}
{% if v and (v.id==p.author_id or v.admin_level > 1) %}
<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_toast2('/toggle_post_nsfw/{{p.id}}','mark2-{{p.id}}','unmark2-{{p.id}}')" data-bs-dismiss="modal"><i class="far fa-eye-evil text-center text-danger mr-3"></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_toast2('/toggle_post_nsfw/{{p.id}}','mark2-{{p.id}}','unmark2-{{p.id}}')" data-bs-dismiss="modal"><i class="far fa-eye-evil text-center text-danger mr-3"></i>Unmark +18</button>
{% endif %}
@ -397,7 +397,7 @@
<button id="unsex-user-{{p.id}}" class="list-inline-item{% if not p.is_blocking %} d-none{% endif %} text-success" href="javascript:void(0)" onclick="post_toast2('/settings/unblock?username={{p.author.username}}','sex-user-{{p.id}}','unsex-user-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-user-slash text-success"></i>Unban user</button>
{% endif %}
{% if v and v.admin_level == 6 and v.id!=p.author_id %}
{% if v and v.admin_level > 1 and v.id!=p.author_id %}
<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.username}}')" class="{% if p.author.is_suspended %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-danger text-left" href="javascript:void(0)"><i class="fas fa-user-minus mr-3"></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" href="javascript:void(0)" onclick="post_toast2('/unban_user/{{p.author_id}}','ban2-{{p.id}}','unban2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-user-minus mr-3"></i>Unban user</button>
{% endif %}
@ -410,6 +410,11 @@
{% block content %}
{% if request.host == 'pcmemes.net' %}
{% set cc='SPLASH MOUNTAIN' %}
{% else %}
{% set cc='COUNTRY CLUB' %}
{% endif %}
<div class="row mb-3">
@ -436,7 +441,7 @@
<i class="{{a.class_list}} px-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="{{a.title}} Award given by @{{a.user.username}}"></i>
{% endfor %}
{% endif %}
{% if v and v.admin_level==6 and p.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="Shadowbanned by @{{p.author.shadowbanned}}"></i>{% endif %}
{% 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="" data-bs-original-title="Shadowbanned by @{{p.author.shadowbanned}}"></i>{% endif %}
{% if p.stickied %}<i id="pinned-{{p.id}}" class="fas fa-thumbtack fa-rotate--45 fa-fw text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="Pinned {% if p.stickied.startswith('t:') %}until {{p.stickied[2:]}}{% else %}by @{{p.stickied}}{%endif%}"></i>{% endif %}
{% if p.is_pinned %}<i class="fas fa-thumbtack fa-rotate--45 fa-fw text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="Pinned to profile"></i>{% endif %}
{% if p.distinguish_level %} <i class="fas fa-broom text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="{{'SITE_NAME' | app_config}} Admin, speaking officially"></i>{% endif %}
@ -446,7 +451,7 @@
{% if p.active_flags %}<a class="btn btn-primary" href="javascript:void(0)" style="padding:1px 5px; font-size:10px;" onclick="document.getElementById('flaggers').classList.toggle('d-none')">{{p.active_flags}} Reports</a>{% endif %}
{% if p.author.verified %}<i class="fas fa-badge-check align-middle ml-1" style="color:{% if p.author.verifiedcolor %}#{{p.author.verifiedcolor}}{% else %}#1DA1F2{% endif %}" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="{{p.author.verified}}"></i>
{% endif %}
<a class="user-name text-decoration-none" data-bs-placement="bottom" data-bs-toggle="popover" data-bs-trigger="focus" data-content-id="popover-{{p.id}}" href="javascript:void(0)" tabindex="0" style="color: #{{p.author.namecolor}}; font-weight: bold;" class="user-name"><img loading="lazy" src="{{p.author.profile_url}}" class="profile-pic-25 mr-2"><span {% if p.author.patron and not p.distinguish_level %}class="patron" style="background-color:#{{p.author.namecolor}};"{% elif p.distinguish_level and 'rama' in request.host %}class="mod"{% endif %}>{{p.author.username}}</span></a>{% if p.author.customtitle %}&nbsp;<bdi style="color: #{{p.author.titlecolor}}">&nbsp;{% if p.author.quadrant %}<img loading="lazy" height="20" src="/assets/images/PCM/quadrants/{{p.author.quadrant}}.webp">{% endif %}{{p.author.customtitle | safe}}</bdi>{% endif %}
<a class="user-name text-decoration-none" data-bs-placement="bottom" data-bs-toggle="popover" data-bs-trigger="focus" data-content-id="popover-{{p.id}}" href="javascript:void(0)" tabindex="0" style="color: #{{p.author.namecolor}}; font-weight: bold;" class="user-name"><img loading="lazy" src="{{p.author.profile_url}}" class="profile-pic-25 mr-2"><span {% if p.author.patron and not p.distinguish_level %}class="patron" style="background-color:#{{p.author.namecolor}};"{% elif p.distinguish_level and 'rama' in request.host %}class="mod"{% endif %}>{{p.author.username}}</span></a>{% if p.author.customtitle %}&nbsp;<bdi style="color: #{{p.author.titlecolor}}">&nbsp;{% if p.author.quadrant %}<img loading="lazy" height="20" src="/assets/images/PCM/quadrants/{{p.author.quadrant}}.webp?v=1">{% endif %}{{p.author.customtitle | safe}}</bdi>{% endif %}
<span data-bs-toggle="tooltip" data-bs-placement="bottom" id="timestamp">&nbsp;{{p.age_string}}</span>
({% if p.realurl(v) %}<a href="/search/posts/?q=domain%3A{{p.domain}}&sort=new&t=all" {% if not v or v.newtabexternal %}target="_blank"{% endif %}>{{p.domain}}</a>{% else %}text post{% endif %})
@ -459,19 +464,19 @@
<pre></pre>
<ul style="padding-left:20px; margin-bottom: 0;">
{% for f in p.ordered_flags %}
<li><a style="font-weight:bold" href="{{f.user.url}}">{{f.user.username}}</a>{% if f.reason %}: {{f.reason | safe}}{% endif %} {% if v.admin_level==6 %}<a href="javascript:void(0)" onclick="post_toast('/del_report/p{{ f.id }}')">[remove]</a>{% endif %}</li>
<li><a style="font-weight:bold" href="{{f.user.url}}">{{f.user.username}}</a>{% if f.reason %}: {{f.reason | safe}}{% endif %} {% if v and v.admin_level > 1 %}<a href="javascript:void(0)" onclick="post_toast('/del_report/p{{ f.id }}')">[remove]</a>{% endif %}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if p.realurl(v) %}
<h1 id="post-title" class="card-title post-title text-left mb-md-3"><a {% if not v or v.newtabexternal %}target="_blank"{% endif %} rel="nofollow noopener noreferrer" href="{{p.realurl(v)}}">
{% if p.club %}<span class="patron font-weight-bolder mr-1" style="background-color:red; font-size:10px; line-height:2;">COUNTRY CLUB</span>{% endif %}
{% if p.club %}<span class="patron font-weight-bolder mr-1" style="background-color:red; font-size:10px; line-height:2;">{{cc}}</span>{% endif %}
{{p.realtitle(v) | safe}}
</a></h1>
{% else %}
<h1 id="post-title" class="card-title post-title text-left mb-md-3">
{% if p.club %}<span class="patron font-weight-bolder mr-1" style="background-color:red; font-size:10px; line-height:2;">COUNTRY CLUB</span>{% endif %}
{% if p.club %}<span class="patron font-weight-bolder mr-1" style="background-color:red; font-size:10px; line-height:2;">{{cc}}</span>{% endif %}
{{p.realtitle(v) | safe}}
</h1>
{% endif %}
@ -555,7 +560,7 @@
</div>
{% if v and (v.id==p.author_id or v.admin_level==6 and v.id in [1,28,30,995,2513,3333]) and not v.is_suspended %}
{% if v and (v.id==p.author_id or v.admin_level > 1 and v.admin_level > 2) 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}}" class="d-flex flex-column input-group" action="/edit_post/{{p.id}}" method="post">
<input type="hidden" name="formkey" value="{{v.formkey}}">
@ -600,7 +605,7 @@
</a>
</li>
{% if v and (v.id==p.author_id or v.admin_level==6 and v.id in [1,28,30,995,2513,3333]) %}
{% if v and (v.id==p.author_id or v.admin_level > 1 and v.admin_level > 2) %}
<a class="list-inline-item" href="javascript:void(0)" onclick="togglePostEdit('{{p.id}}')"><i class="fas fa-edit"></i>Edit</a>
{% endif %}
@ -639,7 +644,7 @@
<a class="list-inline-item" href="javascript:void(0)" data-bs-toggle="modal" data-bs-dismiss="modal" data-bs-target="#deletePostModal" onclick="delete_postModal('{{p.id}}')"><i class="fas fa-trash-alt"></i>Delete</a>
{% endif %}
{% endif %}
{% if v and v.admin_level>=3 %}
{% if v and v.admin_level > 1 %}
<a id="pin-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Pin</a>
<a id="unpin-{{p.id}}" class="{% if not p.stickied %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','/sticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Unpin</a>
{% if v==p.author %}
@ -649,12 +654,12 @@
{% endif %}
{% if v %}
{% if v.admin_level >=3 or v.id == p.author.id and v.paid_dues %}
{% if v.admin_level > 1 or v.id == p.author.id and v.paid_dues %}
<a id="club-{{p.id}}" class="{% if p.club %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/toggle_club/{{p.id}}','club-{{p.id}}','unclub-{{p.id}}')"><i class="fas fa-eye-slash"></i>Mark club</a>
<a id="unclub-{{p.id}}" class="{% if not p.club %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/toggle_club/{{p.id}}','club-{{p.id}}','unclub-{{p.id}}')"><i class="fas fa-eye"></i>Unmark club</a>
{% endif %}
{% if v.admin_level >=3 %}
{% if v.admin_level > 1 %}
{% if "/reported/" in request.path %}
{% if v.id != p.author.id %}<a class="list-inline-item text-danger" href="javascript:void(0)" onclick="post_toast('/ban_post/{{p.id}}')"><i class="fas fa-ban"></i>Remove</a>{% endif %}
<a class="list-inline-item text-success" href="javascript:void(0)" onclick="post_toast('/unban_post/{{p.id}}')"><i class="fas fa-check"></i>Approve</a>
@ -664,12 +669,12 @@
{% endif %}
{% endif %}
{% if v.id == p.author_id or v.admin_level >= 3 %}
{% if v.id == p.author_id or v.admin_level > 1 %}
<a id="mark-{{p.id}}" class="{% if p.over_18 %}d-none{% endif %} list-inline-item text-danger" href="javascript:void(0)" onclick="post_toast2('/toggle_post_nsfw/{{p.id}}','mark-{{p.id}}','unmark-{{p.id}}')"><i class="fas fa-eye-evil"></i>Mark +18</a>
<a id="unmark-{{p.id}}" class="{% if not p.over_18 %}d-none{% endif %} list-inline-item text-danger" href="javascript:void(0)" onclick="post_toast2('/toggle_post_nsfw/{{p.id}}','mark-{{p.id}}','unmark-{{p.id}}')"><i class="fas fa-eye-evil"></i>Unmark +18</a>
{% endif %}
{% if v.admin_level >= 4 and p.oauth_app %}
{% if v.admin_level > 1 and p.oauth_app %}
<a class="list-inline-item" href="{{p.oauth_app.permalink}}" ><i class="fas fa-code"></i>API App</a>
{% endif %}
@ -686,7 +691,7 @@
<a id="unsex-user-{{p.id}}" class="list-inline-item{% if not p.is_blocking %} d-none{% endif %} text-success" href="javascript:void(0)" onclick="post_toast2('/settings/unblock?username={{p.author.username}}','sex-user-{{p.id}}','unsex-user-{{p.id}}')"><i class="fas fa-user-slash text-success"></i>Unban user</a>
{% endif %}
{% if v.admin_level >=3 and v.id!=p.author_id %}
{% if v.admin_level > 1 and v.id!=p.author_id %}
<a id="ban-{{p.id}}" class="{% if p.author.is_suspended %}d-none{% endif %} list-inline-item text-danger" href="javascript:void(0)" data-bs-toggle="modal" data-bs-target="#banModal" onclick="banModal('/post/{{p.id}}', '{{ p.author.id }}', '{{p.author.username}}')"><i class="fas fa-user-slash text-danger fa-fw"></i>Ban user</a>
<a id="unban-{{p.id}}" class="{% if not p.author.is_suspended %}d-none{% endif %} list-inline-item text-danger" id="unexile2-user-{{p.id}}" href="javascript:void(0)" onclick="post_toast2('/unban_user/{{p.author_id}}','ban-{{p.id}}','unban-{{p.id}}')"><i class="fas fa-user-slash"></i>Unban user</a>
{% endif %}

View File

@ -19,19 +19,19 @@
{% endblock %}
{% block adminpanel %}
{% if v.admin_level >=3 %}
{% if v.admin_level > 1 %}
<form action="/sticky/{{p.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="submit" value="{% if p.stickied %}Un-sticky{% else %}Pin{% endif %}">
</form>
{% endif %}
{% if v.admin_level >=3 and v.id==p.author_id %}
{% if v.admin_level > 1 and v.id==p.author_id %}
<form action="/distinguish/{{p.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="submit" value="{% if p.distinguish_level %}Un-distinguish{% else %}Distinguish{% endif %}">
</form>
{% endif %}
{% if v.admin_level >=1 and v.admin_level > p.author.admin_level %}
{% if v.admin_level > 1 and v.admin_level > p.author.admin_level %}
{% if p.is_banned %}
<form action="/unban_post/{{p.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
@ -72,7 +72,7 @@
</div>
</div>
{% if v and v.admin_level >=3 and p.body_html %}
{% if v and v.admin_level > 1 and p.body_html %}
<div class="post-body mt-4 mb-2">
{{p.body_html | safe}}
</div>

View File

@ -32,6 +32,12 @@
})
</script>
{% if request.host == 'pcmemes.net' %}
{% set cc='SPLASH MOUNTAIN' %}
{% else %}
{% set cc='COUNTRY CLUB' %}
{% endif %}
{% for p in listing %}
<div style="display:none" id="popover-{{p.id}}">
@ -119,7 +125,7 @@
<pre></pre>
<ul style="padding-left:20px; margin-bottom: 0;">
{% for f in p.ordered_flags %}
<li><a style="font-weight:bold" href="{{f.user.url}}">{{f.user.username}}</a>{% if f.reason %}: {{f.reason | safe}}{% endif %} {% if v.admin_level==6 %}<a href="javascript:void(0)" onclick="post_toast('/del_report/p{{ f.id }}')">[remove]</a>{% endif %}</li>
<li><a style="font-weight:bold" href="{{f.user.url}}">{{f.user.username}}</a>{% if f.reason %}: {{f.reason | safe}}{% endif %} {% if v and v.admin_level > 1 %}<a href="javascript:void(0)" onclick="post_toast('/del_report/p{{ f.id }}')">[remove]</a>{% endif %}</li>
{% endfor %}
</ul>
</div>
@ -204,7 +210,7 @@
<i class="{{a.class_list}} px-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="{{a.title}} Award given by @{{a.user.username}}"></i>
{% endfor %}
{% endif %}
{% if v and v.admin_level==6 and p.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="Shadowbanned by @{{p.author.shadowbanned}}"></i>{% endif %}
{% 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="" data-bs-original-title="Shadowbanned by @{{p.author.shadowbanned}}"></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="" data-bs-original-title="Pinned {% if p.stickied.startswith('t:') %}until {{p.stickied[2:]}}{% else %}by @{{p.stickied}}{%endif%}"></i>{% endif %}
{% if p.distinguish_level %}<i class="fas fa-broom text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="{{'SITE_NAME' | app_config}} Admin, speaking officially"></i>{% endif %}
{% if p.is_pinned and request.path.startswith('/@') %}<i class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="Pinned to profile"></i>{% endif %}
@ -216,7 +222,7 @@
{% if p.active_flags %}<a class="btn btn-primary" href="javascript:void(0)" style="padding:1px 5px; font-size:10px;" onclick="document.getElementById('flaggers-{{p.id}}').classList.toggle('d-none')">{{p.active_flags}} Reports</a>{% endif %}
{% if p.author.verified %}<i class="fas fa-badge-check align-middle ml-1" style="color:{% if p.author.verifiedcolor %}#{{p.author.verifiedcolor}}{% else %}#1DA1F2{% endif %}" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="{{p.author.verified}}"></i>
{% endif %}
<a class="user-name text-decoration-none" data-bs-placement="bottom" data-bs-toggle="popover" data-bs-trigger="focus" data-content-id="popover-{{p.id}}" href="javascript:void(0)" tabindex="0" style="color: #{{p.author.namecolor}}; font-weight: bold;"><img loading="lazy" src="{{p.author.profile_url}}" class="profile-pic-25 mr-2"><span {% if p.author.patron and not p.distinguish_level %}class="patron" style="background-color:#{{p.author.namecolor}};"{% elif p.distinguish_level and 'rama' in request.host %}class="mod"{% endif %}>{{p.author.username}}</span></a>{% if p.author.customtitle %}<bdi style="color: #{{p.author.titlecolor}}">&nbsp;&nbsp;{% if p.author.quadrant %}<img loading="lazy" height="20" src="/assets/images/PCM/quadrants/{{p.author.quadrant}}.webp">{% endif %}{{p.author.customtitle | safe}}</bdi>{% endif %}
<a class="user-name text-decoration-none" data-bs-placement="bottom" data-bs-toggle="popover" data-bs-trigger="focus" data-content-id="popover-{{p.id}}" href="javascript:void(0)" tabindex="0" style="color: #{{p.author.namecolor}}; font-weight: bold;"><img loading="lazy" src="{{p.author.profile_url}}" class="profile-pic-25 mr-2"><span {% if p.author.patron and not p.distinguish_level %}class="patron" style="background-color:#{{p.author.namecolor}};"{% elif p.distinguish_level and 'rama' in request.host %}class="mod"{% endif %}>{{p.author.username}}</span></a>{% if p.author.customtitle %}<bdi style="color: #{{p.author.titlecolor}}">&nbsp;&nbsp;{% if p.author.quadrant %}<img loading="lazy" height="20" src="/assets/images/PCM/quadrants/{{p.author.quadrant}}.webp?v=1">{% endif %}{{p.author.customtitle | safe}}</bdi>{% endif %}
<span data-bs-toggle="tooltip" data-bs-placement="bottom" id="timestamp-{{p.id}}">&nbsp;{{p.age_string}}</span>
&nbsp;
({% if p.realurl(v) %}<a href="/search/posts/?q=domain%3A{{p.domain}}&sort=new&t=all" target="_blank">{{p.domain}}</a>{% else %}text post{% endif %})
@ -225,7 +231,7 @@
</div>
<h5 class="card-title post-title text-left w-lg-75 mb-0 pb-0 pb-md-1"><a {% if v and v.newtab %}target="_blank"{% endif %} {% if v %}href="{{p.permalink}}"{% else %}href="/logged_out{{p.permalink}}"{% endif %} class="stretched-link">
{% if p.club %}<span class="patron font-weight-bolder mr-1" style="background-color:red; font-size:10px; line-height:2;">COUNTRY CLUB</span>{% endif %}
{% if p.club %}<span class="patron font-weight-bolder mr-1" style="background-color:red; font-size:10px; line-height:2;">{{cc}}</span>{% endif %}
{{p.realtitle(v) | safe}}
</a></h5>
@ -271,7 +277,7 @@
{% endif %}
{% endif %}
{% if v and v.admin_level>=3 %}
{% if v and v.admin_level > 1 %}
<a id="pin-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Pin</a>
<a id="unpin-{{p.id}}" class="{% if not p.stickied %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Unpin</a>
{% if v==p.author %}
@ -281,12 +287,12 @@
{% endif %}
{% if v %}
{% if v.admin_level >=3 or v.id == p.author.id and v.paid_dues %}
{% if v.admin_level > 1 or v.id == p.author.id and v.paid_dues %}
<a id="club-{{p.id}}" class="{% if p.club %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/toggle_club/{{p.id}}','club-{{p.id}}','unclub-{{p.id}}')"><i class="fas fa-eye-slash"></i>Mark club</a>
<a id="unclub-{{p.id}}" class="{% if not p.club %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/toggle_club/{{p.id}}','club-{{p.id}}','unclub-{{p.id}}')"><i class="fas fa-eye"></i>Unmark club</a>
{% endif %}
{% if v.admin_level >=3 %}
{% if v.admin_level > 1 %}
{% if "/reported/" in request.path %}
{% if v.id != p.author.id %}<a class="list-inline-item text-danger" href="javascript:void(0)" onclick="post_toast('/ban_post/{{p.id}}')"><i class="fas fa-ban"></i>Remove</a>{% endif %}
<a class="list-inline-item text-success" href="javascript:void(0)" onclick="post_toast('/unban_post/{{p.id}}')"><i class="fas fa-check"></i>Approve</a>
@ -297,7 +303,7 @@
{% endif %}
{% if v.admin_level >= 4 and p.oauth_app %}
{% if v.admin_level > 1 and p.oauth_app %}
<a class="list-inline-item" href="{{p.oauth_app.permalink}}" ><i class="fas fa-code"></i>API App</a>
{% endif %}
@ -309,12 +315,12 @@
<a id="block-{{p.id}}" class="text-danger blockuser list-inline-item {% if p.is_blocking %} d-none{% endif %}" href="javascript:void(0)" onclick="document.getElementById('block-{{p.id}}').classList.toggle('d-none');document.getElementById('prompt-{{p.id}}').classList.toggle('d-none');"><i class="fas fa-eye-slash text-danger"></i>Block user</a>
{% endif %}
{% if v and (v.id==p.author_id or v.admin_level>=3) %}
{% if v and (v.id==p.author_id or v.admin_level > 1) %}
<a id="mark-{{p.id}}" class="{% if p.over_18 %}d-none{% endif %} list-inline-item text-danger" href="javascript:void(0)" onclick="post_toast2('/toggle_post_nsfw/{{p.id}}','mark-{{p.id}}','unmark-{{p.id}}')"><i class="fas fa-eye-evil"></i>Mark +18</a>
<a id="unmark-{{p.id}}" class="{% if not p.over_18 %}d-none{% endif %} list-inline-item text-danger" href="javascript:void(0)" onclick="post_toast2('/toggle_post_nsfw/{{p.id}}','mark-{{p.id}}','unmark-{{p.id}}')"><i class="fas fa-eye-evil"></i>Unmark +18</a>
{% endif %}
{% if v.admin_level >=3 and v.id!=p.author_id %}
{% if v.admin_level > 1 and v.id!=p.author_id %}
<a id="ban-{{p.id}}" class="{% if p.author.is_suspended %}d-none{% endif %} list-inline-item text-danger" id="exile-comment-{{p.id}}" href="javascript:void(0)" data-bs-toggle="modal" data-bs-target="#banModal" onclick="banModal('/post/{{p.id}}', '{{ p.author.id }}', '{{p.author.username}}')"><i class="fas fa-user-slash text-danger fa-fw"></i>Ban user</a>
<a id="unban-{{p.id}}" class="{% if not p.author.is_suspended %}d-none{% endif %} list-inline-item text-danger" id="unexile2-user-{{p.id}}" href="javascript:void(0)" onclick="post_toast2('/unban_user/{{p.author_id}}','ban-{{p.id}}','unban-{{p.id}}')"><i class="fas fa-user-slash"></i>Unban user</a>
{% endif %}
@ -437,12 +443,12 @@
<button id="save2-{{p.id}}" class="{% if p.id in v.saved_idlist() %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-muted" href="javascript:void(0)" onclick="post_toast2('/save_post/{{p.id}}','save2-{{p.id}}','unsave2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-save text-center text-muted mr-3"></i>Save</button>
<button id="unsave2-{{p.id}}" class="{% if not p.id in v.saved_idlist() %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-muted" href="javascript:void(0)" onclick="post_toast2('/unsave_post/{{p.id}}','save2-{{p.id}}','unsave2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-save text-center text-muted mr-3"></i>Unsave</button>
{% if v.admin_level >=3 or v.id == p.author.id and v.paid_dues %}
{% if v.admin_level > 1 or v.id == p.author.id and v.paid_dues %}
<button id="club2-{{p.id}}" class="{% if p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-info text-left" href="javascript:void(0)" onclick="post_toast2('/toggle_club/{{p.id}}','club2-{{p.id}}','unclub2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-eye-slash mr-3"></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" href="javascript:void(0)" onclick="post_toast2('/toggle_club/{{p.id}}','club2-{{p.id}}','unclub2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-eye mr-3"></i>Unmark club</button>
{% endif %}
{% if v.admin_level >=3 %}
{% if v.admin_level > 1 %}
<button id="pin2-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></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" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Unpin</button>
{% if v==p.author %}
@ -459,7 +465,7 @@
{% endif %}
{% endif %}
{% if v.admin_level >=4 and p.oauth_app %}
{% if v.admin_level > 1 and p.oauth_app %}
<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-3"></i>API App</button></a>
{% endif %}
@ -473,7 +479,7 @@
<button id="block2-{{p.id}}" class="blockuser nobackground btn btn-link btn-block btn-lg text-danger text-left{% if p.is_blocking %} d-none{% endif %}" onclick="document.getElementById('block2-{{p.id}}').classList.toggle('d-none');document.getElementById('prompt2-{{p.id}}').classList.toggle('d-none');"><i class="fas fa-eye-slash mr-3 text-danger"></i>Block user</button>
{% endif %}
{% if v and (v.id==p.author_id or v.admin_level>=3) %}
{% if v and (v.id==p.author_id or v.admin_level > 1) %}
<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_toast2('/toggle_post_nsfw/{{p.id}}','mark2-{{p.id}}','unmark2-{{p.id}}')" data-bs-dismiss="modal"><i class="far fa-eye-evil text-center text-danger mr-3"></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_toast2('/toggle_post_nsfw/{{p.id}}','mark2-{{p.id}}','unmark2-{{p.id}}')" data-bs-dismiss="modal"><i class="far fa-eye-evil text-center text-danger mr-3"></i>Unmark +18</button>
{% endif %}
@ -483,7 +489,7 @@
<button id="unsex-user-{{p.id}}" class="list-inline-item{% if not p.is_blocking %} d-none{% endif %} text-success" href="javascript:void(0)" onclick="post_toast2('/settings/unblock?username={{p.author.username}}','sex-user-{{p.id}}','unsex-user-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-user-slash text-success"></i>Unban user</button>
{% endif %}
{% if v and v.admin_level == 6 and v.id!=p.author_id %}
{% if v and v.admin_level > 1 and v.id!=p.author_id %}
<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.username}}')" class="{% if p.author.is_suspended %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-danger text-left" href="javascript:void(0)"><i class="fas fa-user-minus mr-3"></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" href="javascript:void(0)" onclick="post_toast2('/unban_user/{{p.author_id}}','ban2-{{p.id}}','unban2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-user-minus mr-3"></i>Unban user</button>
{% endif %}
@ -602,7 +608,7 @@
{% if v %}
{% include "delete_post_modal.html" %}
{% include "report_post_modal.html" %}
{% if v.admin_level == 6 %}
{% if v.admin_level > 1 %}
{% include "ban_modal.html" %}
{% endif %}
{% endif %}

View File

@ -10,7 +10,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" type="image/png" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp">
<link rel="icon" type="image/png" href="/assets/images/{{'SITE_NAME' | app_config}}/icon.webp?v=1">
{% if request.host == 'pcmemes.net' %}
{% set cc='Splash Mountain' %}
{% else %}
{% set cc='Country Club' %}
{% endif %}
{% include "emoji_modal.html" %}
{% include "gif_modal.html" %}
@ -25,12 +31,12 @@
{% block stylesheets %}
{% if v %}
<style>:root{--primary:#{{v.themecolor}}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=97">
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/css/agendaposter.css?v=97">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
<link rel="stylesheet" href="/assets/css/main.css?v=118"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=117">
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/css/agendaposter.css?v=117">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
{% else %}
<style>:root{--primary:#{{'DEFAULT_COLOR' | app_config}}</style>
<link rel="stylesheet" href="/assets/css/main.css?v=112">
<link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=97">
<link rel="stylesheet" href="/assets/css/main.css?v=118">
<link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=117">
{% endif %}
{% endblock %}
@ -135,7 +141,7 @@
{% if v.paid_dues %}
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="clubCheck" name="club">
<label class="custom-control-label" for="clubCheck">Country Club thread</label>
<label class="custom-control-label" for="clubCheck">{{cc}} thread</label>
</div>
{% endif %}
<pre>

View File

@ -5,7 +5,7 @@
{% block title %}
{% if u and u.profilecss %}
{% if u and u.profilecss and (u.admin_level or not (v and v.admin_level)) %}
<link rel="stylesheet" href="/@{{u.username}}/profilecss">
{% endif %}
@ -15,7 +15,7 @@
}
</style>
<script src="/assets/js/userpage.js?v=58"></script>
<script src="/assets/js/userpage.js?v=72"></script>
<title>{{u.username}}'s profile - {{'SITE_NAME' | app_config}}</title>
{% if u.is_private %}
<meta name="robots" content="noindex">
@ -41,29 +41,44 @@
{% block desktopUserBanner %}
<script>
function transferCoins(mobile=false) {
let t = event.target;
t.disabled = true;
{% if v %}
<script>
const TRANSFER_TAX = {% if v.patron or u.patron %}0{% else %}0.03{% endif %};
let amount = parseInt(document.getElementById("coins-transfer-amount").value);
let transferred = amount - Math.ceil(amount*TRANSFER_TAX);
post_toast_callback("/@{{u.username}}/transfer_coins",
{"amount": document.getElementById(mobile ? "coins-transfer-amount-mobile" : "coins-transfer-amount").value},
(xhr) => {
if(xhr.status == 200) {
document.getElementById("user-coins-amount").innerText = parseInt(document.getElementById("user-coins-amount").innerText) - amount;
document.getElementById("profile-coins-amount-mobile").innerText = parseInt(document.getElementById("profile-coins-amount-mobile").innerText) + transferred;
document.getElementById("profile-coins-amount").innerText = parseInt(document.getElementById("profile-coins-amount").innerText) + transferred;
function updateTax(mobile=false) {
let suf = mobile ? "-mobile" : "";
let amount = parseInt(document.getElementById("coins-transfer-amount" + suf).value);
if(isNaN(amount) || amount < 0) {
amount = 0;
}
}
);
document.getElementById("coins-transfer-taxed" + suf).innerText = amount - Math.ceil(amount*TRANSFER_TAX);
}
setTimeout(_ => t.disabled = false, 2000);
}
function transferCoins(mobile=false) {
let t = event.target;
t.disabled = true;
{% if u.song %}
let amount = parseInt(document.getElementById("coins-transfer-amount").value);
let transferred = amount - Math.ceil(amount*TRANSFER_TAX);
post_toast_callback("/@{{u.username}}/transfer_coins",
{"amount": document.getElementById(mobile ? "coins-transfer-amount-mobile" : "coins-transfer-amount").value},
(xhr) => {
if(xhr.status == 200) {
document.getElementById("user-coins-amount").innerText = parseInt(document.getElementById("user-coins-amount").innerText) - amount;
document.getElementById("profile-coins-amount-mobile").innerText = parseInt(document.getElementById("profile-coins-amount-mobile").innerText) + transferred;
document.getElementById("profile-coins-amount").innerText = parseInt(document.getElementById("profile-coins-amount").innerText) + transferred;
}
}
);
setTimeout(_ => t.disabled = false, 2000);
}
</script>
{% endif %}
{% if u.song %}
<script>
var audio = new Audio('/songs/{{u.id}}');
audio.loop=true;
@ -92,8 +107,8 @@
}, {once : true});
});
{% endif %}
</script>
</script>
{% endif %}
<div class="row d-none d-md-block">
<div class="col px-0">
@ -155,30 +170,44 @@
</div>
</div>
{% if u.customtitle %}<p class="font-weight-bolder" style="color: #{{u.titlecolor}}">{% if u.quadrant %}<img loading="lazy" height="20" src="/assets/images/PCM/quadrants/{{u.quadrant}}.webp">{% endif %}{{u.customtitle | safe}}</p>{% endif %}
{% if u.customtitle %}<p class="font-weight-bolder" style="color: #{{u.titlecolor}}">{% if u.quadrant %}<img loading="lazy" height="20" src="/assets/images/PCM/quadrants/{{u.quadrant}}.webp?v=1">{% endif %}{{u.customtitle | safe}}</p>
{% else %}<pre></pre>
{% endif %}
<div class="font-weight-bolder mb-2"><a class="mr-1" href="/@{{u.username}}/upvoters">Simps</a> | <a class="mx-1" href="/@{{u.username}}/downvoters">Haters</a> | <a class="mx-1" href="/@{{u.username}}/upvoting">Simps for</a> | <a class="ml-1" href="/@{{u.username}}/downvoting">Hates</a></div>
<div class="font-weight-bolder">
<span id="profile-coins-amount">{{u.coins}}</span>
<img class="ml-1 mb-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="{{'COINS_NAME' | app_config}}" height="20" src="/assets/images/emojis/marseycoin.webp">&nbsp;&nbsp;
<img class="ml-1 mb-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="{{'COINS_NAME' | app_config}}" height="20" src="/assets/images/emojis/marseycoin.webp?v=1">&nbsp;&nbsp;
{% if u.procoins %}
<span>{{u.procoins}}</span>
<img class="ml-1 mb-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="Marseybux" height="20" src="/assets/images/emojis/marseybux.webp">&nbsp;&nbsp;
<img class="ml-1 mb-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="Marseybux" height="20" src="/assets/images/emojis/marseybux.webp?v=1">&nbsp;&nbsp;
{% endif %}
{% if u.stored_subscriber_count >=1 and not u.is_nofollow %}<a href="/@{{u.username}}/followers">{{u.stored_subscriber_count}} follower{{'s' if u.stored_subscriber_count != 1 else ''}}</a>&nbsp;&nbsp; {% endif %}
joined <span data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="{{u.created_datetime}}">{{u.created_date}}</span>
</div>
{% if "pcm" in request.host %}<p class="text-muted">Based Count: {{u.basedcount}}</p>{% endif %}
{% if u.bio_html %}
<pre></pre>
<div class="text-muted font-weight-bolder">{{u.bio_html | safe}}</div>
<pre></pre>
{% if request.host == 'rdrama.net' and u.id == 2050 %}
<div class="text-muted font-weight-bolder">{{u.friends_html | safe}}</div>
{% else %}
<div class="text-muted font-weight-bolder">{{u.bio_html | safe}}</div>
{% endif %}
{% else %}
<p class="text-muted">No bio...</p>
<p class="text-muted">No bio...</p>
{% endif %}
{% if u.friends_html %}
<p class="text-muted font-weight-bold">Friends:</p>
{{u.friends_html | safe}}
{% if request.host == 'rdrama.net' and u.id == 2050 %}
{{u.bio_html | safe}}
{% else %}
{{u.friends_html | safe}}
{% endif %}
{% endif %}
{% if u.enemies_html %}
@ -208,28 +237,28 @@
<a class="btn btn-primary" href="javascript:void(0)" onclick="post_toast('/@{{u.username}}/suicide')">Get them help</a>
<a class="btn btn-primary" href="javascript:void(0)" onclick="toggleElement('profile-toggleable', 'coin-transfer')">Gift {{'COINS_NAME' | app_config}}</a>
{% if 'pcm' in request.host and v.admin_level == 6 %}
{% if 'pcm' in request.host and v.admin_level > 1 %}
{% if u.admin_level == 0 %}
<a class="btn btn-primary" href="javascript:void(0)" onclick="post_toast('/@{{u.username}}/make_admin')">Make admin</a>
{% elif v.id in [10,1551,1552,1577,1592] %}
{% elif v.admin_level > 2 %}
<a class="btn btn-primary" href="javascript:void(0)" onclick="post_toast('/@{{u.username}}/remove_admin')">Remove admin</a>
<a class="btn btn-primary" href="javascript:void(0)" onclick="post_toast('/@{{u.username}}/revert_actions')">Revert admin actions</a>
{% endif %}
{% endif %}
{% if 'rama' in request.host and v.id in [1,28,30,995,2513,3333] %}
{% if 'rama' in request.host and v.admin_level > 2 %}
<a id="admin" class="{% if u.admin_level %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast2('/@{{u.username}}/make_admin','admin','unadmin')">Make admin</a>
<a id="unadmin" class="{% if not u.admin_level %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast2('/@{{u.username}}/remove_admin','admin','unadmin')">Remove admin</a>
<a id="fakeadmin" class="{% if u.admin_level == 1%}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast2('/@{{u.username}}/make_fake_admin','fakeadmin','unfakeadmin')">Make fake admin</a>
<a id="unfakeadmin" class="{% if u.admin_level != 1 %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast2('/@{{u.username}}/remove_fake_admin','fakeadmin','unfakeadmin')">Remove fake admin</a>
{% if u.admin_level == 6 %}
{% if u.admin_level > 1 %}
<a class="btn btn-primary" href="javascript:void(0)" onclick="post_toast('/@{{u.username}}/revert_actions')">Revert admin actions</a>
{% endif %}
{% endif %}
{% if 'rama' not in request.host and 'pcm' not in request.host and v.admin_level == 6 %}
{% if 'rama' not in request.host and 'pcm' not in request.host and v.admin_level > 1 %}
<a id="admin" class="{% if u.admin_level %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast2('/@{{u.username}}/make_admin','admin','unadmin')">Make admin</a>
<a id="unadmin" class="{% if not u.admin_level %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast2('/@{{u.username}}/remove_admin','admin','unadmin')">Remove admin</a>
@ -354,18 +383,20 @@
{% endif %}
<pre></pre>
<p>User ID: {{u.id}}</p>
{% if v and v.admin_level >=4 %}
<p>Coins spent: {{u.coins_spent}}</p>
{% if v and v.admin_level > 1 %}
<p>True score: {{u.truecoins}}</p>
{% if u.is_private %}
<p>User has private mode enabled.</p>
{% endif %}
{% endif %}
{% if v and (v.admin_level > 1 or v.alt) %}
<span>Alts:</span>
<ul>
{% for account in u.alts_unique %}
<li><a href="{{account.url}}">@{{account.username}}</a>{% if account._is_manual %} [m]{% endif %}</li>
{% endfor %}
</ul>
True score: {{u.truecoins}} &nbsp;
Coins spent: {{u.coins_spent}}
{% endif %}
{% if u.is_suspended %}
<p>Banned by: <a href="{{u.banned_by.url}}">@{{u.banned_by.username}}</a></p>
@ -431,14 +462,20 @@
{% if v and v.has_follower(u) and not v.is_nofollow %}
<span class="followsyou text-primary badge badge-secondary text-small align-middle mx-1">Follows you</span>
{% endif %}
{% if u.customtitle %}<p style="color: #{{u.titlecolor}}">{% if u.quadrant %}<img loading="lazy" height="20" src="/assets/images/PCM/quadrants/{{u.quadrant}}.webp">{% endif %}{{u.customtitle | safe}}</p>{% endif %}
{% if u.customtitle %}<p style="color: #{{u.titlecolor}}">{% if u.quadrant %}<img loading="lazy" height="20" src="/assets/images/PCM/quadrants/{{u.quadrant}}.webp?v=1">{% endif %}{{u.customtitle | safe}}</p>
{% else %}
<pre></pre>
{% endif %}
<div class="font-weight-bolder mb-2"><a class="mr-1" href="/@{{u.username}}/upvoters">Simps</a> | <a class="mx-1" href="/@{{u.username}}/downvoters">Haters</a> | <a class="mx-1" href="/@{{u.username}}/upvoting">Simps for</a> | <a class="ml-1" href="/@{{u.username}}/downvoting">Hates</a></div>
<div class="font-weight-normal">
<span id="profile-coins-amount-mobile" class="font-weight-bold">{{u.coins}}</span>
<img class="ml-1 mb-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="{{'COINS_NAME' | app_config}}" height="15" src="/assets/images/emojis/marseycoin.webp">&nbsp;&nbsp;
<img class="ml-1 mb-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="{{'COINS_NAME' | app_config}}" height="15" src="/assets/images/emojis/marseycoin.webp?v=1">&nbsp;&nbsp;
{% if u.procoins %}
<span class="font-weight-bold">{{u.procoins}}</span>
<img class="ml-1 mb-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="Marseybux" height="15" src="/assets/images/emojis/marseybux.webp">&nbsp;&nbsp;
<img class="ml-1 mb-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="" data-bs-original-title="Marseybux" height="15" src="/assets/images/emojis/marseybux.webp?v=1">&nbsp;&nbsp;
{% endif %}
{% if u.stored_subscriber_count >=1 and not u.is_nofollow %}<a href="/@{{u.username}}/followers" class="font-weight-bold">{{u.stored_subscriber_count}} follower{{'s' if u.stored_subscriber_count != 1 else ''}}</a>&nbsp;&nbsp; {% endif %}
@ -500,28 +537,28 @@
<a class="btn btn-primary" href="javascript:void(0)" onclick="post_toast('/@{{u.username}}/suicide')">Get them help</a>
<a class="btn btn-primary" href="javascript:void(0)" onclick="toggleElement('profile-toggleable-mobile', 'coin-transfer-mobile')">Gift {{'COINS_NAME' | app_config}}</a>
{% if 'pcm' in request.host and v.admin_level == 6 %}
{% if 'pcm' in request.host and v.admin_level > 1 %}
{% if u.admin_level == 0 %}
<a class="btn btn-primary" href="javascript:void(0)" onclick="post_toast('/@{{u.username}}/make_admin')">Make admin</a>
{% elif v.id in [10,1551,1552,1577,1592] %}
{% elif v.admin_level > 2 %}
<a class="btn btn-primary" href="javascript:void(0)" onclick="post_toast('/@{{u.username}}/remove_admin')">Remove admin</a>
<a class="btn btn-primary" href="javascript:void(0)" onclick="post_toast('/@{{u.username}}/revert_actions')">Revert admin actions</a>
{% endif %}
{% endif %}
{% if 'rama' in request.host and v.id in [1,28,30,995,2513,3333] %}
{% if 'rama' in request.host and v.admin_level > 2 %}
<a id="admin2" class="{% if u.admin_level %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast2('/@{{u.username}}/make_admin','admin2','unadmin2')">Make admin</a>
<a id="unadmin2" class="{% if not u.admin_level %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast2('/@{{u.username}}/remove_admin','admin2','unadmin2')">Remove admin</a>
<a id="fakeadmin2" class="{% if u.admin_level == 1%}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast2('/@{{u.username}}/make_fake_admin','fakeadmin2','unfakeadmin2')">Make fake admin</a>
<a id="unfakeadmin2" class="{% if u.admin_level != 1 %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast2('/@{{u.username}}/remove_fake_admin','fakeadmin2','unfakeadmin2')">Remove fake admin</a>
{% if u.admin_level == 6 %}
{% if u.admin_level > 1 %}
<a class="btn btn-primary" href="javascript:void(0)" onclick="post_toast('/@{{u.username}}/revert_actions')">Revert admin actions</a>
{% endif %}
{% endif %}
{% if 'rama' not in request.host and 'pcm' not in request.host and v.admin_level == 6 %}
{% if 'rama' not in request.host and 'pcm' not in request.host and v.admin_level > 1 %}
<a id="admin" class="{% if u.admin_level %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast2('/@{{u.username}}/make_admin','admin','unadmin')">Make admin</a>
<a id="unadmin" class="{% if not u.admin_level %}d-none{% endif %} btn btn-primary" href="javascript:void(0)" onclick="post_toast2('/@{{u.username}}/remove_admin','admin','unadmin')">Remove admin</a>
@ -642,23 +679,24 @@
{% endif %}
<pre></pre>
<p>User ID: {{u.id}}</p>
<p>Coins spent: {{u.coins_spent}}</p>
{% if v and v.admin_level > 1 %}
<p>True score: {{u.truecoins}}</p>
{% if u.is_private %}
<p>User has private mode enabled.</p>
{% endif %}
{% endif %}
{% if v and (v.admin_level > 1 or v.alt) %}
<span>Alts:</span>
<ul>
{% for account in u.alts_unique %}
<li><a href="{{account.url}}">@{{account.username}}</a>{% if account._is_manual %} [m]{% endif %}</li>
<li><a href="{{account.url}}">@{{account.username}}</a>{% if account._is_manual %} [m]{% endif %}</li>
{% endfor %}
</ul>
True score: {{u.truecoins}} &nbsp;
Coins spent: {{u.coins_spent}}
{% endif %}
{% if u.is_suspended %}
<p>Banned by: <a href="{{u.banned_by.url}}">@{{u.banned_by.username}}</a></p>
{% endif %}
</div>
</div>
</div>

View File

@ -0,0 +1,28 @@
{% extends "default.html" %}
{% block content %}
<pre>
</pre>
<h5 style="text-align: center">{{name2}}</h5>
<pre></pre>
<table class="table table-striped mb-5">
<thead class="bg-primary text-white">
<tr>
<th style="font-weight: bold">#</th>
<th style="font-weight: bold">Name</th>
<th style="font-weight: bold">{{name}}votes</th>
</tr>
</thead>
<tbody id="followers-table">
{% for user in users %}
<tr>
<td style="font-weight: bold">{{loop.index}}</td>
<td><a style="color:#{{user[0].namecolor}}; font-weight:bold;" href="/@{{user[0].username}}"><img loading="lazy" src="/uid/{{user[0].id}}/pic" class="pp20"><span {% if user[0].patron %}class="patron" style="background-color:#{{user[0].namecolor}};"{% endif %}>{{user[0].username}}</span></a></td>
<td style="font-weight: bold">{{user[1]}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -2646,11 +2646,6 @@ This has nothing to do with SRD, consider posting your inane, unfunny "meme" pos
Anyone else feel that this guy keeps overstepping his bounds?
{[para]}
There is more to it than just that at play here. You'll notice fascists (and Nazis) are being placed in the **authoritarian left quadrant**.
This is a part of the right wing misinformation campaign where they distance themselves from the Nazis by arguing that fascists' and Nazis are actually on the left! Three Arrows did a pretty good video on it a while ago (https://www.youtube.com/watch?v=hUFvG4RpwJI).
That this particular misinformation campaign would show up on PCM where out Nazis freely self identify with Auth Right... it doesn't make much sense. The whole idea of the misinformation campaign is to placate "moderate conservatives," by assuring them that the "bad people" were "left wing" all along, and it only works if you want to believe it, because the evidence is overwhelming that the Nazis were extreme right, and Nazis and Nazi sympathizers support right wing candidates without fail.
That said... when your entire identity is "owning the libs"... you'll believe just about anything.
{[para]}
So I got anal herpes from my wife a little bit ago and it was giving me some great difficulties plugging my good old meth. Luckily my butt hole is sore free at the moment after getting some good old Valtrex from the doctor. Imp it was kinda kinky plugging meth with herpes sores. It was painful but something really turns me on about shoving some shard up the shoot with an active disease.
{[para]}
Maybe AHS needs a new flair for these sort of subs. At their core lies destructive nihilism. We cannot be entirely sure what exactly their ideology is. Everything is hidden behind many layers of irony and postmodernist obscurantism. We can safely assume they're fascists but they will never spell it out. Their main goal isn't to spread a message anyway. Their main goal is to destroy meaningful debate.