forked from rDrama/rDrama
Merge branch 'master' into patch-5
commit
cc052ea75d
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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",
|
||||
},
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
||||
|
|
|
@ -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)
|
||||
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.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
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -28,8 +28,8 @@ def check_for_alts(current_id):
|
|||
|
||||
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])
|
||||
)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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]
|
||||
|
@ -587,8 +603,6 @@ def submit_post(v):
|
|||
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:
|
||||
v.marseyawarded = None
|
||||
|
@ -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
|
||||
|
|
|
@ -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'):
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ''
|
|
@ -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)
|
||||
|
|
|
@ -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 %}
|
|
@ -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>
|
||||
|
|
|
@ -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"> </div>
|
||||
<div class="text-muted"> </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>
|
|
@ -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 %} <bdi style="color: #{{c.author.titlecolor}}"> {% 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 %} <bdi style="color: #{{c.author.titlecolor}}"> {% 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 %}
|
||||
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() %}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -551,7 +551,7 @@
|
|||
|
||||
<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">
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 %} <bdi style="color: #{{p.author.titlecolor}}"> {% 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 %} <bdi style="color: #{{p.author.titlecolor}}"> {% 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.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 %}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}}"> {% 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}}"> {% 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}}"> {{p.age_string}}</span>
|
||||
|
||||
({% 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 %}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
<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">
|
||||
|
||||
{% 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">
|
||||
<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">
|
||||
{% 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> {% 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}}
|
||||
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">
|
||||
<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">
|
||||
|
||||
{% 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">
|
||||
<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">
|
||||
{% 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> {% 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}}
|
||||
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>
|
||||
|
|
|
@ -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 %}
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue