forked from MarseyWorld/MarseyWorld
master
parent
c9098526ed
commit
3ab53cad82
|
@ -20,9 +20,7 @@ def post_embed(id, v):
|
||||||
|
|
||||||
p = get_post(id, v, graceful=True)
|
p = get_post(id, v, graceful=True)
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("submission_listing.html", listing=[p], v=v)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}submission_listing.html", listing=[p], v=v)
|
|
||||||
|
|
||||||
@app.context_processor
|
@app.context_processor
|
||||||
def inject_constants():
|
def inject_constants():
|
||||||
|
|
|
@ -60,9 +60,7 @@ def activate(v):
|
||||||
token = request.values.get("token", "").strip()
|
token = request.values.get("token", "").strip()
|
||||||
|
|
||||||
if int(time.time()) - timestamp > 3600:
|
if int(time.time()) - timestamp > 3600:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("message.html", v=v, title="Verification link expired.",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}message.html", v=v, title="Verification link expired.",
|
|
||||||
message="That link has expired. Visit your settings to send yourself another verification email."), 410
|
message="That link has expired. Visit your settings to send yourself another verification email."), 410
|
||||||
|
|
||||||
if not validate_hash(f"{email}+{id}+{timestamp}", token):
|
if not validate_hash(f"{email}+{id}+{timestamp}", token):
|
||||||
|
@ -73,10 +71,7 @@ def activate(v):
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if user.is_activated and user.email == email:
|
if user.is_activated and user.email == email:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("message_success.html", v=v, title="Email already verified.", message="Email already verified."), 404
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}message_success.html", v=v,
|
|
||||||
title="Email already verified.", message="Email already verified."), 404
|
|
||||||
|
|
||||||
user.email = email
|
user.email = email
|
||||||
user.is_activated = True
|
user.is_activated = True
|
||||||
|
@ -90,6 +85,4 @@ def activate(v):
|
||||||
g.db.add(user)
|
g.db.add(user)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("message_success.html", v=v, title="Email verified.", message=f"Your email {email} has been verified. Thank you.")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}message_success.html", v=v, title="Email verified.", message=f"Your email {email} has been verified. Thank you.")
|
|
||||||
|
|
|
@ -264,9 +264,7 @@ def post_sidebar(v):
|
||||||
def shadowbanned(v):
|
def shadowbanned(v):
|
||||||
if not (v and v.admin_level > 1): 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).order_by(User.shadowbanned).all()]
|
users = [x for x in g.db.query(User).filter(User.shadowbanned != None).order_by(User.shadowbanned).all()]
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("shadowbanned.html", v=v, users=users)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}shadowbanned.html", v=v, users=users)
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/admin/image_posts")
|
@app.get("/admin/image_posts")
|
||||||
|
@ -284,9 +282,7 @@ def image_posts_listing(v):
|
||||||
next_exists = (len(posts) > 25)
|
next_exists = (len(posts) > 25)
|
||||||
posts = get_posts(posts[:25], v=v)
|
posts = get_posts(posts[:25], v=v)
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("admin/image_posts.html", v=v, listing=posts, next_exists=next_exists, page=page, sort="new")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}admin/image_posts.html", v=v, listing=posts, next_exists=next_exists, page=page, sort="new")
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/admin/reported/posts")
|
@app.get("/admin/reported/posts")
|
||||||
|
@ -306,9 +302,7 @@ def reported_posts(v):
|
||||||
|
|
||||||
listing = get_posts(listing, v=v)
|
listing = get_posts(listing, v=v)
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("admin/reported_posts.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}admin/reported_posts.html",
|
|
||||||
next_exists=next_exists, listing=listing, page=page, v=v)
|
next_exists=next_exists, listing=listing, page=page, v=v)
|
||||||
|
|
||||||
|
|
||||||
|
@ -330,9 +324,7 @@ def reported_comments(v):
|
||||||
|
|
||||||
listing = get_comments(listing, v=v)
|
listing = get_comments(listing, v=v)
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("admin/reported_comments.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}admin/reported_comments.html",
|
|
||||||
next_exists=next_exists,
|
next_exists=next_exists,
|
||||||
listing=listing,
|
listing=listing,
|
||||||
page=page,
|
page=page,
|
||||||
|
@ -346,11 +338,7 @@ def admin_home(v):
|
||||||
with open('disable_signups', 'r') as f: x = f.read()
|
with open('disable_signups', 'r') as f: x = f.read()
|
||||||
with open('under_attack', 'r') as f: x2 = f.read()
|
with open('under_attack', 'r') as f: x2 = f.read()
|
||||||
|
|
||||||
if not v or v.oldsite: return render_template("admin/admin_home.html", v=v, x=x, x2=x2)
|
return render_template("admin/admin_home.html", v=v, x=x, x2=x2)
|
||||||
|
|
||||||
actions = g.db.query(ModAction).order_by(ModAction.id.desc()).limit(10).all()
|
|
||||||
|
|
||||||
return render_template("CHRISTMAS/admin/admin_home.html", actions=actions, v=v, x=x, x2=x2)
|
|
||||||
|
|
||||||
@app.post("/admin/disable_signups")
|
@app.post("/admin/disable_signups")
|
||||||
@admin_level_required(3)
|
@admin_level_required(3)
|
||||||
|
@ -420,28 +408,23 @@ def under_attack(v):
|
||||||
@app.get("/admin/badge_grant")
|
@app.get("/admin/badge_grant")
|
||||||
@admin_level_required(2)
|
@admin_level_required(2)
|
||||||
def badge_grant_get(v):
|
def badge_grant_get(v):
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
return render_template(f"{template}admin/badge_grant.html", v=v, badge_types=BADGES)
|
return render_template("admin/badge_grant.html", v=v, badge_types=BADGES)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/admin/badge_grant")
|
@app.post("/admin/badge_grant")
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
@admin_level_required(2)
|
@admin_level_required(2)
|
||||||
def badge_grant_post(v):
|
def badge_grant_post(v):
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
user = get_user(request.values.get("username").strip(), graceful=True)
|
user = get_user(request.values.get("username").strip(), graceful=True)
|
||||||
if not user:
|
if not user:
|
||||||
return render_template(f"{template}admin/badge_grant.html", v=v, badge_types=BADGES, error="User not found.")
|
return render_template("admin/badge_grant.html", v=v, badge_types=BADGES, error="User not found.")
|
||||||
|
|
||||||
try: badge_id = int(request.values.get("badge_id"))
|
try: badge_id = int(request.values.get("badge_id"))
|
||||||
except: abort(400)
|
except: abort(400)
|
||||||
|
|
||||||
if user.has_badge(badge_id):
|
if user.has_badge(badge_id):
|
||||||
return render_template(f"{template}admin/badge_grant.html", v=v, badge_types=BADGES, error="User already has that badge.")
|
return render_template("admin/badge_grant.html", v=v, badge_types=BADGES, error="User already has that badge.")
|
||||||
|
|
||||||
new_badge = Badge(badge_id=badge_id, user_id=user.id)
|
new_badge = Badge(badge_id=badge_id, user_id=user.id)
|
||||||
|
|
||||||
|
@ -458,29 +441,23 @@ def badge_grant_post(v):
|
||||||
send_notification(user.id, text)
|
send_notification(user.id, text)
|
||||||
|
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
return render_template(f"{template}admin/badge_grant.html", v=v, badge_types=BADGES, msg="Badge granted!")
|
return render_template("admin/badge_grant.html", v=v, badge_types=BADGES, msg="Badge granted!")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/admin/badge_remove")
|
@app.get("/admin/badge_remove")
|
||||||
@admin_level_required(2)
|
@admin_level_required(2)
|
||||||
def badge_remove_get(v):
|
def badge_remove_get(v):
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("admin/badge_remove.html", v=v, badge_types=BADGES)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
return render_template(f"{template}admin/badge_remove.html", v=v, badge_types=BADGES)
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/admin/badge_remove")
|
@app.post("/admin/badge_remove")
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
@admin_level_required(2)
|
@admin_level_required(2)
|
||||||
def badge_remove_post(v):
|
def badge_remove_post(v):
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
user = get_user(request.values.get("username").strip(), graceful=True)
|
user = get_user(request.values.get("username").strip(), graceful=True)
|
||||||
if not user:
|
if not user:
|
||||||
return render_template(f"{template}admin/badge_remove.html", v=v, badge_types=BADGES, error="User not found.")
|
return render_template("admin/badge_remove.html", v=v, badge_types=BADGES, error="User not found.")
|
||||||
|
|
||||||
try: badge_id = int(request.values.get("badge_id"))
|
try: badge_id = int(request.values.get("badge_id"))
|
||||||
except: abort(400)
|
except: abort(400)
|
||||||
|
@ -490,7 +467,7 @@ def badge_remove_post(v):
|
||||||
g.db.delete(badge)
|
g.db.delete(badge)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
||||||
return render_template(f"{template}admin/badge_remove.html", v=v, badge_types=BADGES, msg="Badge removed!")
|
return render_template("admin/badge_remove.html", v=v, badge_types=BADGES, msg="Badge removed!")
|
||||||
|
|
||||||
|
|
||||||
@app.get("/admin/users")
|
@app.get("/admin/users")
|
||||||
|
@ -508,9 +485,7 @@ def users_list(v):
|
||||||
next_exists = (len(users) > 25)
|
next_exists = (len(users) > 25)
|
||||||
users = users[:25]
|
users = users[:25]
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("admin/new_users.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}admin/new_users.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
users=users,
|
users=users,
|
||||||
next_exists=next_exists,
|
next_exists=next_exists,
|
||||||
|
@ -522,9 +497,7 @@ def users_list(v):
|
||||||
def alt_votes_get(v):
|
def alt_votes_get(v):
|
||||||
|
|
||||||
if not request.values.get("u1") or not request.values.get("u2"):
|
if not request.values.get("u1") or not request.values.get("u2"):
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("admin/alt_votes.html", v=v)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}admin/alt_votes.html", v=v)
|
|
||||||
|
|
||||||
u1 = request.values.get("u1")
|
u1 = request.values.get("u1")
|
||||||
u2 = request.values.get("u2")
|
u2 = request.values.get("u2")
|
||||||
|
@ -620,9 +593,7 @@ def alt_votes_get(v):
|
||||||
data['u2_only_comment_downs'] // len(
|
data['u2_only_comment_downs'] // len(
|
||||||
u2_comment_downs) if u2_comment_downs else 0
|
u2_comment_downs) if u2_comment_downs else 0
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("admin/alt_votes.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}admin/alt_votes.html",
|
|
||||||
u1=u1,
|
u1=u1,
|
||||||
u2=u2,
|
u2=u2,
|
||||||
v=v,
|
v=v,
|
||||||
|
@ -666,9 +637,7 @@ def admin_removed(v):
|
||||||
|
|
||||||
posts = get_posts(ids, v=v)
|
posts = get_posts(ids, v=v)
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("admin/removed_posts.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}admin/removed_posts.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
listing=posts,
|
listing=posts,
|
||||||
page=page,
|
page=page,
|
||||||
|
@ -692,9 +661,7 @@ def admin_removed_comments(v):
|
||||||
|
|
||||||
comments = get_comments(ids, v=v)
|
comments = get_comments(ids, v=v)
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("admin/removed_comments.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}admin/removed_comments.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
listing=comments,
|
listing=comments,
|
||||||
page=page,
|
page=page,
|
||||||
|
@ -1242,9 +1209,7 @@ def admin_dump_cache(v):
|
||||||
def admin_banned_domains(v):
|
def admin_banned_domains(v):
|
||||||
|
|
||||||
banned_domains = g.db.query(BannedDomain).all()
|
banned_domains = g.db.query(BannedDomain).all()
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("admin/banned_domains.html", v=v, banned_domains=banned_domains)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}admin/banned_domains.html", v=v, banned_domains=banned_domains)
|
|
||||||
|
|
||||||
@app.post("/admin/banned_domains")
|
@app.post("/admin/banned_domains")
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
|
|
|
@ -77,9 +77,7 @@ def shop(v):
|
||||||
val["price"] = int(val["price"]*discount)
|
val["price"] = int(val["price"]*discount)
|
||||||
|
|
||||||
sales = g.db.query(Vote.id).count() + g.db.query(CommentVote.id).count() - g.db.query(func.sum(User.coins)).scalar()
|
sales = g.db.query(Vote.id).count() + g.db.query(CommentVote.id).count() - g.db.query(func.sum(User.coins)).scalar()
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("shop.html", awards=list(AWARDS.values()), v=v, sales=sales)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}shop.html", awards=list(AWARDS.values()), v=v, sales=sales)
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/buy/<award>")
|
@app.post("/buy/<award>")
|
||||||
|
@ -548,20 +546,16 @@ def award_comment(cid, v):
|
||||||
@app.get("/admin/awards")
|
@app.get("/admin/awards")
|
||||||
@admin_level_required(2)
|
@admin_level_required(2)
|
||||||
def admin_userawards_get(v):
|
def admin_userawards_get(v):
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
if v.admin_level != 3:
|
if v.admin_level != 3:
|
||||||
return render_template(f"{template}admin/awards.html", awards=list(AWARDS3.values()), v=v)
|
return render_template("admin/awards.html", awards=list(AWARDS3.values()), v=v)
|
||||||
|
|
||||||
return render_template(f"{template}admin/awards.html", awards=list(AWARDS.values()), v=v)
|
return render_template("admin/awards.html", awards=list(AWARDS.values()), v=v)
|
||||||
|
|
||||||
@app.post("/admin/awards")
|
@app.post("/admin/awards")
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
@admin_level_required(2)
|
@admin_level_required(2)
|
||||||
def admin_userawards_post(v):
|
def admin_userawards_post(v):
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
try: u = request.values.get("username").strip()
|
try: u = request.values.get("username").strip()
|
||||||
except: abort(404)
|
except: abort(404)
|
||||||
|
@ -616,5 +610,5 @@ def admin_userawards_post(v):
|
||||||
|
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
||||||
if v.admin_level != 3: return render_template(f"{template}admin/awards.html", awards=list(AWARDS3.values()), v=v)
|
if v.admin_level != 3: return render_template("admin/awards.html", awards=list(AWARDS3.values()), v=v)
|
||||||
return render_template(f"{template}admin/awards.html", awards=list(AWARDS.values()), v=v)
|
return render_template("admin/awards.html", awards=list(AWARDS.values()), v=v)
|
|
@ -97,9 +97,7 @@ def discord_redirect(v):
|
||||||
requests.delete(url, headers=headers, timeout=5)
|
requests.delete(url, headers=headers, timeout=5)
|
||||||
|
|
||||||
if g.db.query(User).filter(User.id!=v.id, User.discord_id==x["id"]).one_or_none():
|
if g.db.query(User).filter(User.id!=v.id, User.discord_id==x["id"]).one_or_none():
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("message.html", title="Discord account already linked.", error="That Discord account is already in use by another user.", v=v)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}message.html", title="Discord account already linked.", error="That Discord account is already in use by another user.", v=v)
|
|
||||||
|
|
||||||
v.discord_id=x["id"]
|
v.discord_id=x["id"]
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
|
|
|
@ -106,9 +106,7 @@ def notifications(v):
|
||||||
|
|
||||||
if request.headers.get("Authorization"): return {"data":[x.json for x in listing]}
|
if request.headers.get("Authorization"): return {"data":[x.json for x in listing]}
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("notifications.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}notifications.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
notifications=listing,
|
notifications=listing,
|
||||||
next_exists=next_exists,
|
next_exists=next_exists,
|
||||||
|
@ -206,9 +204,7 @@ def front_all(v):
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
||||||
if request.headers.get("Authorization"): return {"data": [x.json for x in posts], "next_exists": next_exists}
|
if request.headers.get("Authorization"): return {"data": [x.json for x in posts], "next_exists": next_exists}
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("home.html", v=v, listing=posts, next_exists=next_exists, sort=sort, t=t, page=page)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}home.html", v=v, listing=posts, next_exists=next_exists, sort=sort, t=t, page=page)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -328,9 +324,7 @@ def changelog(v):
|
||||||
posts = get_posts(ids, v=v)
|
posts = get_posts(ids, v=v)
|
||||||
|
|
||||||
if request.headers.get("Authorization"): return {"data": [x.json for x in posts], "next_exists": next_exists}
|
if request.headers.get("Authorization"): return {"data": [x.json for x in posts], "next_exists": next_exists}
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("changelog.html", v=v, listing=posts, next_exists=next_exists, sort=sort, t=t, page=page)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}changelog.html", v=v, listing=posts, next_exists=next_exists, sort=sort, t=t, page=page)
|
|
||||||
|
|
||||||
|
|
||||||
@cache.memoize(timeout=86400)
|
@cache.memoize(timeout=86400)
|
||||||
|
@ -472,6 +466,4 @@ def all_comments(v):
|
||||||
idlist = idlist[:25]
|
idlist = idlist[:25]
|
||||||
|
|
||||||
if request.headers.get("Authorization"): return {"data": [x.json for x in comments]}
|
if request.headers.get("Authorization"): return {"data": [x.json for x in comments]}
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("home_comments.html", v=v, sort=sort, t=t, page=page, comments=comments, standalone=True, next_exists=next_exists)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}home_comments.html", v=v, sort=sort, t=t, page=page, comments=comments, standalone=True, next_exists=next_exists)
|
|
|
@ -16,9 +16,7 @@ def login_get(v):
|
||||||
if v:
|
if v:
|
||||||
return redirect(redir)
|
return redirect(redir)
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("login.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}login.html",
|
|
||||||
failed=False,
|
failed=False,
|
||||||
redirect=redir)
|
redirect=redir)
|
||||||
|
|
||||||
|
@ -91,19 +89,19 @@ def login_post():
|
||||||
|
|
||||||
if not account:
|
if not account:
|
||||||
time.sleep(random.uniform(0, 2))
|
time.sleep(random.uniform(0, 2))
|
||||||
return render_template(f"{template}login.html", failed=True)
|
return render_template("login.html", failed=True)
|
||||||
|
|
||||||
|
|
||||||
if request.values.get("password"):
|
if request.values.get("password"):
|
||||||
|
|
||||||
if not account.verifyPass(request.values.get("password")):
|
if not account.verifyPass(request.values.get("password")):
|
||||||
time.sleep(random.uniform(0, 2))
|
time.sleep(random.uniform(0, 2))
|
||||||
return render_template(f"{template}login.html", failed=True)
|
return render_template("login.html", failed=True)
|
||||||
|
|
||||||
if account.mfa_secret:
|
if account.mfa_secret:
|
||||||
now = int(time.time())
|
now = int(time.time())
|
||||||
hash = generate_hash(f"{account.id}+{now}+2fachallenge")
|
hash = generate_hash(f"{account.id}+{now}+2fachallenge")
|
||||||
return render_template(f"{template}login_2fa.html",
|
return render_template("login_2fa.html",
|
||||||
v=account,
|
v=account,
|
||||||
time=now,
|
time=now,
|
||||||
hash=hash,
|
hash=hash,
|
||||||
|
@ -123,7 +121,7 @@ def login_post():
|
||||||
|
|
||||||
if not account.validate_2fa(request.values.get("2fa_token", "").strip()):
|
if not account.validate_2fa(request.values.get("2fa_token", "").strip()):
|
||||||
hash = generate_hash(f"{account.id}+{time}+2fachallenge")
|
hash = generate_hash(f"{account.id}+{time}+2fachallenge")
|
||||||
return render_template(f"{template}login_2fa.html",
|
return render_template("login_2fa.html",
|
||||||
v=account,
|
v=account,
|
||||||
time=now,
|
time=now,
|
||||||
hash=hash,
|
hash=hash,
|
||||||
|
@ -428,9 +426,7 @@ def post_reset(v):
|
||||||
now = int(time.time())
|
now = int(time.time())
|
||||||
|
|
||||||
if now - timestamp > 600:
|
if now - timestamp > 600:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("message.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}message.html",
|
|
||||||
title="Password reset expired",
|
title="Password reset expired",
|
||||||
error="That password reset form has expired.")
|
error="That password reset form has expired.")
|
||||||
|
|
||||||
|
@ -442,9 +438,7 @@ def post_reset(v):
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not password == confirm_password:
|
if not password == confirm_password:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("reset_password.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}reset_password.html",
|
|
||||||
v=user,
|
v=user,
|
||||||
token=token,
|
token=token,
|
||||||
time=timestamp,
|
time=timestamp,
|
||||||
|
@ -455,9 +449,7 @@ def post_reset(v):
|
||||||
|
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("message_success.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}message_success.html",
|
|
||||||
title="Password reset successful!",
|
title="Password reset successful!",
|
||||||
message="Login normally to access your account.")
|
message="Login normally to access your account.")
|
||||||
|
|
||||||
|
|
|
@ -87,9 +87,7 @@ def publish(pid, v):
|
||||||
@app.get("/submit")
|
@app.get("/submit")
|
||||||
@auth_required
|
@auth_required
|
||||||
def submit_get(v):
|
def submit_get(v):
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("submit.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}submit.html",
|
|
||||||
v=v)
|
v=v)
|
||||||
|
|
||||||
@app.get("/post/<pid>")
|
@app.get("/post/<pid>")
|
||||||
|
@ -98,9 +96,6 @@ def submit_get(v):
|
||||||
@app.get("/logged_out/post/<pid>/<anything>")
|
@app.get("/logged_out/post/<pid>/<anything>")
|
||||||
@auth_desired
|
@auth_desired
|
||||||
def post_id(pid, anything=None, v=None):
|
def post_id(pid, anything=None, v=None):
|
||||||
if not v or v.oldsite: template2 = ''
|
|
||||||
else: template2 = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
if not v and not request.path.startswith('/logged_out') and not request.headers.get("Authorization"): return redirect(f"/logged_out{request.full_path}")
|
if not v and not request.path.startswith('/logged_out') and not request.headers.get("Authorization"): return redirect(f"/logged_out{request.full_path}")
|
||||||
|
|
||||||
if v and request.path.startswith('/logged_out'): v = None
|
if v and request.path.startswith('/logged_out'): v = None
|
||||||
|
@ -337,9 +332,7 @@ def viewmore(v, pid, sort, offset):
|
||||||
if len(comments) == len(comments2): offset = None
|
if len(comments) == len(comments2): offset = None
|
||||||
comments = comments2
|
comments = comments2
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("comments.html", v=v, comments=comments, render_replies=True, pid=pid, sort=sort, offset=offset)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}comments.html", v=v, comments=comments, render_replies=True, pid=pid, sort=sort, offset=offset)
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/morecomments/<cid>")
|
@app.post("/morecomments/<cid>")
|
||||||
|
@ -388,9 +381,7 @@ def morecomments(v, cid):
|
||||||
c = g.db.query(Comment).filter_by(id=cid).one_or_none()
|
c = g.db.query(Comment).filter_by(id=cid).one_or_none()
|
||||||
comments = c.replies
|
comments = c.replies
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("comments.html", v=v, comments=comments, render_replies=True)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}comments.html", v=v, comments=comments, render_replies=True)
|
|
||||||
|
|
||||||
@app.post("/edit_post/<pid>")
|
@app.post("/edit_post/<pid>")
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
|
@ -700,8 +691,6 @@ def submit_post(v):
|
||||||
if request.content_length > 8 * 1024 * 1024: return {"error": "Max file size is 8 MB."}, 413
|
if request.content_length > 8 * 1024 * 1024: return {"error": "Max file size is 8 MB."}, 413
|
||||||
elif request.content_length > 4 * 1024 * 1024: return {"error": "Max file size is 4 MB."}, 413
|
elif request.content_length > 4 * 1024 * 1024: return {"error": "Max file size is 4 MB."}, 413
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
title = request.values.get("title", "").strip()[:500].replace('','')
|
title = request.values.get("title", "").strip()[:500].replace('','')
|
||||||
|
|
||||||
|
@ -766,9 +755,7 @@ def submit_post(v):
|
||||||
domain_obj = get_domain(domain)
|
domain_obj = get_domain(domain)
|
||||||
if domain_obj:
|
if domain_obj:
|
||||||
if request.headers.get("Authorization"): return {"error":domain_obj.reason}, 400
|
if request.headers.get("Authorization"): return {"error":domain_obj.reason}, 400
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("submit.html", v=v, error=domain_obj.reason, title=title, url=url, body=request.values.get("body", "")), 400
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}submit.html", v=v, error=domain_obj.reason, title=title, url=url, body=request.values.get("body", "")), 400
|
|
||||||
elif "twitter.com" == domain:
|
elif "twitter.com" == domain:
|
||||||
try: embed = requests.get("https://publish.twitter.com/oembed", timeout=5, params={"url":url, "omit_script":"t"}).json()["html"]
|
try: embed = requests.get("https://publish.twitter.com/oembed", timeout=5, params={"url":url, "omit_script":"t"}).json()["html"]
|
||||||
except: embed = None
|
except: embed = None
|
||||||
|
@ -790,15 +777,11 @@ def submit_post(v):
|
||||||
|
|
||||||
if not url and not request.values.get("body") and not request.files.get("file", None):
|
if not url and not request.values.get("body") and not request.files.get("file", None):
|
||||||
if request.headers.get("Authorization"): return {"error": "`url` or `body` parameter required."}, 400
|
if request.headers.get("Authorization"): return {"error": "`url` or `body` parameter required."}, 400
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("submit.html", v=v, error="Please enter a url or some text.", title=title, url=url, body=request.values.get("body", "")), 400
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}submit.html", v=v, error="Please enter a url or some text.", title=title, url=url, body=request.values.get("body", "")), 400
|
|
||||||
|
|
||||||
if not title:
|
if not title:
|
||||||
if request.headers.get("Authorization"): return {"error": "Please enter a better title"}, 400
|
if request.headers.get("Authorization"): return {"error": "Please enter a better title"}, 400
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("submit.html", v=v, error="Please enter a better title.", title=title, url=url, body=request.values.get("body", "")), 400
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}submit.html", v=v, error="Please enter a better title.", title=title, url=url, body=request.values.get("body", "")), 400
|
|
||||||
|
|
||||||
|
|
||||||
elif len(title) > 500:
|
elif len(title) > 500:
|
||||||
|
@ -872,16 +855,12 @@ def submit_post(v):
|
||||||
if len(str(body)) > 10000:
|
if len(str(body)) > 10000:
|
||||||
|
|
||||||
if request.headers.get("Authorization"): return {"error":"10000 character limit for text body."}, 400
|
if request.headers.get("Authorization"): return {"error":"10000 character limit for text body."}, 400
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("submit.html", v=v, error="10000 character limit for text body.", title=title, url=url, body=request.values.get("body", "")), 400
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}submit.html", v=v, error="10000 character limit for text body.", title=title, url=url, body=request.values.get("body", "")), 400
|
|
||||||
|
|
||||||
if len(url) > 2048:
|
if len(url) > 2048:
|
||||||
|
|
||||||
if request.headers.get("Authorization"): return {"error":"2048 character limit for URLs."}, 400
|
if request.headers.get("Authorization"): return {"error":"2048 character limit for URLs."}, 400
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("submit.html", v=v, error="2048 character limit for URLs.", title=title, url=url,body=request.values.get("body", "")), 400
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}submit.html", v=v, error="2048 character limit for URLs.", title=title, url=url,body=request.values.get("body", "")), 400
|
|
||||||
|
|
||||||
for i in re.finditer('^(https:\/\/.*\.(png|jpg|jpeg|gif|webp|PNG|JPG|JPEG|GIF|WEBP|9999))', body, re.MULTILINE):
|
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)})')
|
if "wikipedia" not in i.group(1): body = body.replace(i.group(1), f'![]({i.group(1)})')
|
||||||
|
@ -914,9 +893,7 @@ def submit_post(v):
|
||||||
body += f"\n\n{url}"
|
body += f"\n\n{url}"
|
||||||
else:
|
else:
|
||||||
if request.headers.get("Authorization"): return {"error": "Image/Video files only"}, 400
|
if request.headers.get("Authorization"): return {"error": "Image/Video files only"}, 400
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("submit.html", v=v, error=f"Image/Video files only."), 400
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}submit.html", v=v, error=f"Image/Video files only."), 400
|
|
||||||
|
|
||||||
body_html = sanitize(body)
|
body_html = sanitize(body)
|
||||||
|
|
||||||
|
@ -935,9 +912,7 @@ def submit_post(v):
|
||||||
reason = f"Remove the {ban.domain} link from your post and try again."
|
reason = f"Remove the {ban.domain} link from your post and try again."
|
||||||
if ban.reason: reason += f" {ban.reason}"
|
if ban.reason: reason += f" {ban.reason}"
|
||||||
if request.headers.get("Authorization"): return {"error": reason}, 403
|
if request.headers.get("Authorization"): return {"error": reason}, 403
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("submit.html", v=v, error=reason, title=title, url=url, body=request.values.get("body", "")), 403
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}submit.html", v=v, error=reason, title=title, url=url, body=request.values.get("body", "")), 403
|
|
||||||
|
|
||||||
if v.club_allowed == False: club = False
|
if v.club_allowed == False: club = False
|
||||||
else: club = bool(request.values.get("club",""))
|
else: club = bool(request.values.get("club",""))
|
||||||
|
@ -1011,7 +986,7 @@ def submit_post(v):
|
||||||
new_post.url = url
|
new_post.url = url
|
||||||
else:
|
else:
|
||||||
if request.headers.get("Authorization"): return {"error": "File type not allowed"}, 400
|
if request.headers.get("Authorization"): return {"error": "File type not allowed"}, 400
|
||||||
return render_template(f"{template}submit.html", v=v, error="File type not allowed.", title=title, body=request.values.get("body", "")), 400
|
return render_template("submit.html", v=v, error="File type not allowed.", title=title, body=request.values.get("body", "")), 400
|
||||||
|
|
||||||
|
|
||||||
if not new_post.thumburl and new_post.url:
|
if not new_post.thumburl and new_post.url:
|
||||||
|
|
|
@ -35,8 +35,6 @@ def searchparse(text):
|
||||||
@app.get("/search/posts")
|
@app.get("/search/posts")
|
||||||
@auth_required
|
@auth_required
|
||||||
def searchposts(v):
|
def searchposts(v):
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
query = request.values.get("q", '').strip()
|
query = request.values.get("q", '').strip()
|
||||||
|
|
||||||
|
@ -71,7 +69,7 @@ def searchposts(v):
|
||||||
if author.is_private and author.id != v.id and v.admin_level < 2 and not v.eye:
|
if author.is_private and author.id != v.id and v.admin_level < 2 and not v.eye:
|
||||||
if request.headers.get("Authorization"):
|
if request.headers.get("Authorization"):
|
||||||
return {"error": f"@{author.username}'s profile is private; You can't use the 'author' syntax on them"}
|
return {"error": f"@{author.username}'s profile is private; You can't use the 'author' syntax on them"}
|
||||||
return render_template(f"{template}search.html",
|
return render_template("search.html",
|
||||||
v=v,
|
v=v,
|
||||||
query=query,
|
query=query,
|
||||||
total=0,
|
total=0,
|
||||||
|
@ -181,7 +179,7 @@ def searchposts(v):
|
||||||
|
|
||||||
if request.headers.get("Authorization"): return {"total":total, "data":[x.json for x in posts]}
|
if request.headers.get("Authorization"): return {"total":total, "data":[x.json for x in posts]}
|
||||||
|
|
||||||
return render_template(f"{template}search.html",
|
return render_template("search.html",
|
||||||
v=v,
|
v=v,
|
||||||
query=query,
|
query=query,
|
||||||
total=total,
|
total=total,
|
||||||
|
@ -198,8 +196,6 @@ def searchposts(v):
|
||||||
@auth_required
|
@auth_required
|
||||||
def searchcomments(v):
|
def searchcomments(v):
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
query = request.values.get("q", '').strip()
|
query = request.values.get("q", '').strip()
|
||||||
|
|
||||||
|
@ -220,7 +216,7 @@ def searchcomments(v):
|
||||||
if request.headers.get("Authorization"):
|
if request.headers.get("Authorization"):
|
||||||
return {"error": f"@{author.username}'s profile is private; You can't use the 'author' syntax on them"}
|
return {"error": f"@{author.username}'s profile is private; You can't use the 'author' syntax on them"}
|
||||||
|
|
||||||
return render_template(f"{template}search_comments.html", v=v, query=query, total=0, page=page, comments=[], sort=sort, t=t, next_exists=False, error=f"@{author.username}'s profile is private; You can't use the 'author' syntax on them.")
|
return render_template("search_comments.html", v=v, query=query, total=0, page=page, comments=[], sort=sort, t=t, next_exists=False, error=f"@{author.username}'s profile is private; You can't use the 'author' syntax on them.")
|
||||||
|
|
||||||
else: comments = comments.filter(Comment.author_id == author.id)
|
else: comments = comments.filter(Comment.author_id == author.id)
|
||||||
|
|
||||||
|
@ -275,14 +271,12 @@ def searchcomments(v):
|
||||||
comments = get_comments(ids, v=v)
|
comments = get_comments(ids, v=v)
|
||||||
|
|
||||||
if request.headers.get("Authorization"): return {"total":total, "data":[x.json for x in comments]}
|
if request.headers.get("Authorization"): return {"total":total, "data":[x.json for x in comments]}
|
||||||
return render_template(f"{template}search_comments.html", v=v, query=query, total=total, page=page, comments=comments, sort=sort, t=t, next_exists=next_exists)
|
return render_template("search_comments.html", v=v, query=query, total=total, page=page, comments=comments, sort=sort, t=t, next_exists=next_exists)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/search/users")
|
@app.get("/search/users")
|
||||||
@auth_required
|
@auth_required
|
||||||
def searchusers(v):
|
def searchusers(v):
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
query = request.values.get("q", '').strip()
|
query = request.values.get("q", '').strip()
|
||||||
|
|
||||||
|
@ -304,4 +298,4 @@ def searchusers(v):
|
||||||
users=users[:25]
|
users=users[:25]
|
||||||
|
|
||||||
if request.headers.get("Authorization"): return {"data": [x.json for x in users]}
|
if request.headers.get("Authorization"): return {"data": [x.json for x in users]}
|
||||||
return render_template(f"{template}search_users.html", v=v, query=query, total=total, page=page, users=users, sort=sort, t=t, next_exists=next_exists)
|
return render_template("search_users.html", v=v, query=query, total=total, page=page, users=users, sort=sort, t=t, next_exists=next_exists)
|
|
@ -50,8 +50,6 @@ def settings_profile_post(v):
|
||||||
if request.content_length > 8 * 1024 * 1024: return {"error":"Max file size is 8 MB."}, 413
|
if request.content_length > 8 * 1024 * 1024: return {"error":"Max file size is 8 MB."}, 413
|
||||||
elif request.content_length > 4 * 1024 * 1024: return {"error":"Max file size is 4 MB."}, 413
|
elif request.content_length > 4 * 1024 * 1024: return {"error":"Max file size is 4 MB."}, 413
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
updated = False
|
updated = False
|
||||||
|
|
||||||
|
@ -128,36 +126,28 @@ def settings_profile_post(v):
|
||||||
v.bio_html = None
|
v.bio_html = None
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html", v=v, msg="Your bio has been updated.")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html", v=v, msg="Your bio has been updated.")
|
|
||||||
|
|
||||||
elif request.values.get("sig") == "":
|
elif request.values.get("sig") == "":
|
||||||
v.sig = None
|
v.sig = None
|
||||||
v.sig_html = None
|
v.sig_html = None
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html", v=v, msg="Your sig has been updated.")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html", v=v, msg="Your sig has been updated.")
|
|
||||||
|
|
||||||
elif request.values.get("friends") == "":
|
elif request.values.get("friends") == "":
|
||||||
v.friends = None
|
v.friends = None
|
||||||
v.friends_html = None
|
v.friends_html = None
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html", v=v, msg="Your friends list has been updated.")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html", v=v, msg="Your friends list has been updated.")
|
|
||||||
|
|
||||||
elif request.values.get("enemies") == "":
|
elif request.values.get("enemies") == "":
|
||||||
v.enemies = None
|
v.enemies = None
|
||||||
v.enemies_html = None
|
v.enemies_html = None
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html", v=v, msg="Your enemies list has been updated.")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html", v=v, msg="Your enemies list has been updated.")
|
|
||||||
|
|
||||||
elif (v.patron or v.id == MOOSE_ID) and request.values.get("sig"):
|
elif (v.patron or v.id == MOOSE_ID) and request.values.get("sig"):
|
||||||
sig = request.values.get("sig")[:200]
|
sig = request.values.get("sig")[:200]
|
||||||
|
@ -178,9 +168,7 @@ def settings_profile_post(v):
|
||||||
return {"error": reason}, 401
|
return {"error": reason}, 401
|
||||||
|
|
||||||
if len(sig_html) > 1000:
|
if len(sig_html) > 1000:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
error="Your sig is too long")
|
error="Your sig is too long")
|
||||||
|
|
||||||
|
@ -188,9 +176,7 @@ def settings_profile_post(v):
|
||||||
v.sig_html=sig_html
|
v.sig_html=sig_html
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
msg="Your sig has been updated.")
|
msg="Your sig has been updated.")
|
||||||
|
|
||||||
|
@ -213,9 +199,7 @@ def settings_profile_post(v):
|
||||||
return {"error": reason}, 401
|
return {"error": reason}, 401
|
||||||
|
|
||||||
if len(friends_html) > 2000:
|
if len(friends_html) > 2000:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
error="Your friends list is too long")
|
error="Your friends list is too long")
|
||||||
|
|
||||||
|
@ -231,9 +215,7 @@ def settings_profile_post(v):
|
||||||
v.friends_html=friends_html
|
v.friends_html=friends_html
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
msg="Your friends list has been updated.")
|
msg="Your friends list has been updated.")
|
||||||
|
|
||||||
|
@ -254,9 +236,7 @@ def settings_profile_post(v):
|
||||||
return {"error": reason}, 401
|
return {"error": reason}, 401
|
||||||
|
|
||||||
if len(enemies_html) > 2000:
|
if len(enemies_html) > 2000:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
error="Your enemies list is too long")
|
error="Your enemies list is too long")
|
||||||
|
|
||||||
|
@ -272,9 +252,7 @@ def settings_profile_post(v):
|
||||||
v.enemies_html=enemies_html
|
v.enemies_html=enemies_html
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
msg="Your enemies list has been updated.")
|
msg="Your enemies list has been updated.")
|
||||||
|
|
||||||
|
@ -301,17 +279,13 @@ def settings_profile_post(v):
|
||||||
bio += f"\n\n{url}"
|
bio += f"\n\n{url}"
|
||||||
else:
|
else:
|
||||||
if request.headers.get("Authorization"): return {"error": "Image/Video files only"}, 400
|
if request.headers.get("Authorization"): return {"error": "Image/Video files only"}, 400
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html", v=v, error="Image/Video files only."), 400
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html", v=v, error="Image/Video files only."), 400
|
|
||||||
|
|
||||||
bio_html = sanitize(bio)
|
bio_html = sanitize(bio)
|
||||||
bans = filter_comment_html(bio_html)
|
bans = filter_comment_html(bio_html)
|
||||||
|
|
||||||
if len(bio_html) > 10000:
|
if len(bio_html) > 10000:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
error="Your bio is too long")
|
error="Your bio is too long")
|
||||||
|
|
||||||
|
@ -329,7 +303,7 @@ def settings_profile_post(v):
|
||||||
v.bio_html=bio_html
|
v.bio_html=bio_html
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
return render_template(f"{template}settings_profile.html",
|
return render_template("settings_profile.html",
|
||||||
v=v,
|
v=v,
|
||||||
msg="Your bio has been updated.")
|
msg="Your bio has been updated.")
|
||||||
|
|
||||||
|
@ -428,16 +402,12 @@ def filters(v):
|
||||||
filters=request.values.get("filters")[:1000].strip()
|
filters=request.values.get("filters")[:1000].strip()
|
||||||
|
|
||||||
if filters == v.custom_filter_list:
|
if filters == v.custom_filter_list:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_filters.html", v=v, error="You didn't change anything")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_filters.html", v=v, error="You didn't change anything")
|
|
||||||
|
|
||||||
v.custom_filter_list=filters
|
v.custom_filter_list=filters
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_filters.html", v=v, msg="Your custom filters have been updated.")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_filters.html", v=v, msg="Your custom filters have been updated.")
|
|
||||||
|
|
||||||
@app.post("/changelogsub")
|
@app.post("/changelogsub")
|
||||||
@auth_required
|
@auth_required
|
||||||
|
@ -455,12 +425,10 @@ def changelogsub(v):
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
@auth_required
|
@auth_required
|
||||||
def namecolor(v):
|
def namecolor(v):
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
color = str(request.values.get("color", "")).strip()
|
color = str(request.values.get("color", "")).strip()
|
||||||
if color.startswith('#'): color = color[1:]
|
if color.startswith('#'): color = color[1:]
|
||||||
if len(color) != 6: return render_template(f"{template}settings_security.html", v=v, error="Invalid color code")
|
if len(color) != 6: return render_template("settings_security.html", v=v, error="Invalid color code")
|
||||||
v.namecolor = color
|
v.namecolor = color
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
@ -470,12 +438,10 @@ def namecolor(v):
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
@auth_required
|
@auth_required
|
||||||
def themecolor(v):
|
def themecolor(v):
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
themecolor = str(request.values.get("themecolor", "")).strip()
|
themecolor = str(request.values.get("themecolor", "")).strip()
|
||||||
if themecolor.startswith('#'): themecolor = themecolor[1:]
|
if themecolor.startswith('#'): themecolor = themecolor[1:]
|
||||||
if len(themecolor) != 6: return render_template(f"{template}settings_security.html", v=v, error="Invalid color code")
|
if len(themecolor) != 6: return render_template("settings_security.html", v=v, error="Invalid color code")
|
||||||
v.themecolor = themecolor
|
v.themecolor = themecolor
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
@ -537,12 +503,10 @@ def gumroad(v):
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
@auth_required
|
@auth_required
|
||||||
def titlecolor(v):
|
def titlecolor(v):
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
titlecolor = str(request.values.get("titlecolor", "")).strip()
|
titlecolor = str(request.values.get("titlecolor", "")).strip()
|
||||||
if titlecolor.startswith('#'): titlecolor = titlecolor[1:]
|
if titlecolor.startswith('#'): titlecolor = titlecolor[1:]
|
||||||
if len(titlecolor) != 6: return render_template(f"{template}settings_profile.html", v=v, error="Invalid color code")
|
if len(titlecolor) != 6: return render_template("settings_profile.html", v=v, error="Invalid color code")
|
||||||
v.titlecolor = titlecolor
|
v.titlecolor = titlecolor
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
@ -552,12 +516,9 @@ def titlecolor(v):
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
@auth_required
|
@auth_required
|
||||||
def verifiedcolor(v):
|
def verifiedcolor(v):
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
verifiedcolor = str(request.values.get("verifiedcolor", "")).strip()
|
verifiedcolor = str(request.values.get("verifiedcolor", "")).strip()
|
||||||
if verifiedcolor.startswith('#'): verifiedcolor = verifiedcolor[1:]
|
if verifiedcolor.startswith('#'): verifiedcolor = verifiedcolor[1:]
|
||||||
if len(verifiedcolor) != 6: return render_template(f"{template}settings_profile.html", v=v, error="Invalid color code")
|
if len(verifiedcolor) != 6: return render_template("settings_profile.html", v=v, error="Invalid color code")
|
||||||
v.verifiedcolor = verifiedcolor
|
v.verifiedcolor = verifiedcolor
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
@ -654,9 +615,7 @@ def settings_log_out_others(v):
|
||||||
submitted_password = request.values.get("password", "").strip()
|
submitted_password = request.values.get("password", "").strip()
|
||||||
|
|
||||||
if not v.verifyPass(submitted_password):
|
if not v.verifyPass(submitted_password):
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_security.html", v=v, error="Incorrect Password"), 401
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_security.html", v=v, error="Incorrect Password"), 401
|
|
||||||
|
|
||||||
v.login_nonce += 1
|
v.login_nonce += 1
|
||||||
|
|
||||||
|
@ -666,9 +625,7 @@ def settings_log_out_others(v):
|
||||||
|
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_security.html", v=v, msg="All other devices have been logged out")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_security.html", v=v, msg="All other devices have been logged out")
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/settings/images/profile")
|
@app.post("/settings/images/profile")
|
||||||
|
@ -703,9 +660,7 @@ def settings_images_profile(v):
|
||||||
|
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html", v=v, msg="Profile picture successfully updated.")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html", v=v, msg="Profile picture successfully updated.")
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/settings/images/banner")
|
@app.post("/settings/images/banner")
|
||||||
|
@ -730,9 +685,7 @@ def settings_images_banner(v):
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html", v=v, msg="Banner successfully updated.")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html", v=v, msg="Banner successfully updated.")
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/settings/delete/profile")
|
@app.post("/settings/delete/profile")
|
||||||
|
@ -745,9 +698,7 @@ def settings_delete_profile(v):
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html", v=v,
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html", v=v,
|
|
||||||
msg="Profile picture successfully removed.")
|
msg="Profile picture successfully removed.")
|
||||||
|
|
||||||
@app.post("/settings/delete/banner")
|
@app.post("/settings/delete/banner")
|
||||||
|
@ -760,26 +711,20 @@ def settings_delete_banner(v):
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html", v=v, msg="Banner successfully removed.")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html", v=v, msg="Banner successfully removed.")
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/settings/blocks")
|
@app.get("/settings/blocks")
|
||||||
@auth_required
|
@auth_required
|
||||||
def settings_blockedpage(v):
|
def settings_blockedpage(v):
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_blocks.html", v=v)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_blocks.html", v=v)
|
|
||||||
|
|
||||||
@app.get("/settings/css")
|
@app.get("/settings/css")
|
||||||
@auth_required
|
@auth_required
|
||||||
def settings_css_get(v):
|
def settings_css_get(v):
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_css.html", v=v)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_css.html", v=v)
|
|
||||||
|
|
||||||
@app.post("/settings/css")
|
@app.post("/settings/css")
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
|
@ -792,18 +737,14 @@ def settings_css(v):
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_css.html", v=v)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_css.html", v=v)
|
|
||||||
|
|
||||||
@app.get("/settings/profilecss")
|
@app.get("/settings/profilecss")
|
||||||
@auth_required
|
@auth_required
|
||||||
def settings_profilecss_get(v):
|
def settings_profilecss_get(v):
|
||||||
|
|
||||||
if v.truecoins < 1000 and not v.patron and v.admin_level == 0 : return f"You must have +1000 {COINS_NAME} or be a paypig 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 paypig to set profile css."
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profilecss.html", v=v)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profilecss.html", v=v)
|
|
||||||
|
|
||||||
@app.post("/settings/profilecss")
|
@app.post("/settings/profilecss")
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
|
@ -815,9 +756,7 @@ def settings_profilecss(v):
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profilecss.html", v=v)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profilecss.html", v=v)
|
|
||||||
|
|
||||||
@app.post("/settings/block")
|
@app.post("/settings/block")
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
|
@ -879,9 +818,7 @@ def settings_unblock_user(v):
|
||||||
@auth_required
|
@auth_required
|
||||||
def settings_apps(v):
|
def settings_apps(v):
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_apps.html", v=v)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_apps.html", v=v)
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/settings/remove_discord")
|
@app.post("/settings/remove_discord")
|
||||||
|
@ -902,9 +839,7 @@ def settings_remove_discord(v):
|
||||||
@auth_required
|
@auth_required
|
||||||
def settings_content_get(v):
|
def settings_content_get(v):
|
||||||
|
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_filters.html", v=v)
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_filters.html", v=v)
|
|
||||||
|
|
||||||
@app.post("/settings/name_change")
|
@app.post("/settings/name_change")
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
|
@ -914,16 +849,12 @@ def settings_name_change(v):
|
||||||
new_name=request.values.get("name").strip()
|
new_name=request.values.get("name").strip()
|
||||||
|
|
||||||
if new_name==v.username:
|
if new_name==v.username:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
error="You didn't change anything")
|
error="You didn't change anything")
|
||||||
|
|
||||||
if not re.match(valid_username_regex, new_name):
|
if not re.match(valid_username_regex, new_name):
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
error="This isn't a valid username.")
|
error="This isn't a valid username.")
|
||||||
|
|
||||||
|
@ -937,9 +868,7 @@ def settings_name_change(v):
|
||||||
).one_or_none()
|
).one_or_none()
|
||||||
|
|
||||||
if x and x.id != v.id:
|
if x and x.id != v.id:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
error=f"Username `{new_name}` is already in use.")
|
error=f"Username `{new_name}` is already in use.")
|
||||||
|
|
||||||
|
@ -975,9 +904,7 @@ def settings_song_change(v):
|
||||||
elif song.startswith("https://youtu.be/"):
|
elif song.startswith("https://youtu.be/"):
|
||||||
id = song.split("https://youtu.be/")[1]
|
id = song.split("https://youtu.be/")[1]
|
||||||
else:
|
else:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html", v=v, error="Not a youtube link.")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html", v=v, error="Not a youtube link.")
|
|
||||||
|
|
||||||
if "?" in id: id = id.split("?")[0]
|
if "?" in id: id = id.split("?")[0]
|
||||||
if "&" in id: id = id.split("&")[0]
|
if "&" in id: id = id.split("&")[0]
|
||||||
|
@ -992,21 +919,15 @@ def settings_song_change(v):
|
||||||
req = requests.get(f"https://www.googleapis.com/youtube/v3/videos?id={id}&key={YOUTUBE_KEY}&part=contentDetails", timeout=5).json()
|
req = requests.get(f"https://www.googleapis.com/youtube/v3/videos?id={id}&key={YOUTUBE_KEY}&part=contentDetails", timeout=5).json()
|
||||||
duration = req['items'][0]['contentDetails']['duration']
|
duration = req['items'][0]['contentDetails']['duration']
|
||||||
if duration == 'P0D':
|
if duration == 'P0D':
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html", v=v, error="Can't use a live youtube video!")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html", v=v, error="Can't use a live youtube video!")
|
|
||||||
|
|
||||||
if "H" in duration:
|
if "H" in duration:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html", v=v, error="Duration of the video must not exceed 10 minutes.")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html", v=v, error="Duration of the video must not exceed 10 minutes.")
|
|
||||||
|
|
||||||
if "M" in duration:
|
if "M" in duration:
|
||||||
duration = int(duration.split("PT")[1].split("M")[0])
|
duration = int(duration.split("PT")[1].split("M")[0])
|
||||||
if duration > 10:
|
if duration > 10:
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html", v=v, error="Duration of the video must not exceed 10 minutes.")
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html", v=v, error="Duration of the video must not exceed 10 minutes.")
|
|
||||||
|
|
||||||
|
|
||||||
if v.song and path.isfile(f"/songs/{v.song}.mp3") and g.db.query(User.id).filter_by(song=v.song).count() == 1:
|
if v.song and path.isfile(f"/songs/{v.song}.mp3") and g.db.query(User.id).filter_by(song=v.song).count() == 1:
|
||||||
|
@ -1026,9 +947,7 @@ def settings_song_change(v):
|
||||||
try: ydl.download([f"https://youtube.com/watch?v={id}"])
|
try: ydl.download([f"https://youtube.com/watch?v={id}"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
if not v or v.oldsite: template = ''
|
return render_template("settings_profile.html",
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
return render_template(f"{template}settings_profile.html",
|
|
||||||
v=v,
|
v=v,
|
||||||
error="Age-restricted videos aren't allowed.")
|
error="Age-restricted videos aren't allowed.")
|
||||||
|
|
||||||
|
@ -1048,14 +967,12 @@ def settings_song_change(v):
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
@auth_required
|
@auth_required
|
||||||
def settings_title_change(v):
|
def settings_title_change(v):
|
||||||
if not v or v.oldsite: template = ''
|
|
||||||
else: template = 'CHRISTMAS/'
|
|
||||||
|
|
||||||
if v.flairchanged: abort(403)
|
if v.flairchanged: abort(403)
|
||||||
|
|
||||||
new_name=request.values.get("title").strip()[:100].replace("𒐪","")
|
new_name=request.values.get("title").strip()[:100].replace("𒐪","")
|
||||||
|
|
||||||
if new_name==v.customtitle: return render_template(f"{template}settings_profile.html", v=v, error="You didn't change anything")
|
if new_name==v.customtitle: return render_template("settings_profile.html", v=v, error="You didn't change anything")
|
||||||
|
|
||||||
v.customtitleplain = new_name
|
v.customtitleplain = new_name
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue