forked from MarseyWorld/MarseyWorld
Merge branch 'frost' of https://github.com/Aevann1/rDrama into frost
commit
466867afd1
|
@ -218,6 +218,7 @@ function post_toast(t, url, button1, button2, classname, extra_actions) {
|
|||
} else {
|
||||
document.getElementById('toast-post-error-text').innerText = "Error, please try again later."
|
||||
if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"];
|
||||
if (data && data["details"]) document.getElementById('toast-post-error-text').innerText = data["details"];
|
||||
bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show();
|
||||
}
|
||||
if (!isShopConfirm)
|
||||
|
|
|
@ -257,6 +257,73 @@ FEATURES = {
|
|||
'PATRON_ICONS': False,
|
||||
}
|
||||
|
||||
WERKZEUG_ERROR_DESCRIPTIONS = {
|
||||
400: "The browser (or proxy) sent a request that this server could not understand.",
|
||||
401: "The server could not verify that you are authorized to access the URL requested. You either supplied the wrong credentials (e.g. a bad password), or your browser doesn't understand how to supply the credentials required.",
|
||||
403: "You don't have the permission to access the requested resource. It is either read-protected or not readable by the server.",
|
||||
404: "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.",
|
||||
405: "The method is not allowed for the requested URL.",
|
||||
406: "The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.",
|
||||
409: "A conflict happened while processing the request. The resource might have been modified while the request was being processed.",
|
||||
413: "The data value transmitted exceeds the capacity limit.",
|
||||
414: "The length of the requested URL exceeds the capacity limit for this server. The request cannot be processed.",
|
||||
415: "The server does not support the media type transmitted in the request.",
|
||||
417: "The server could not meet the requirements of the Expect header",
|
||||
418: "This server is a teapot, not a coffee machine",
|
||||
429: "This user has exceeded an allotted request count. Try again later.",
|
||||
500: "The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.",
|
||||
}
|
||||
|
||||
ERROR_TITLES = {
|
||||
400: "Bad Request",
|
||||
401: "Unauthorized",
|
||||
403: "Forbidden",
|
||||
404: "Not Found",
|
||||
405: "Method Not Allowed",
|
||||
406: "Too Many Pings",
|
||||
409: "Conflict",
|
||||
413: "Max image/audio size is 8 MB (16 MB for paypigs)",
|
||||
414: "Max video size is 32 MB (64 MB for paypigs)",
|
||||
415: "Unsupported Media Type",
|
||||
417: "Image already exists!",
|
||||
418: "WEBM videos are not allowed",
|
||||
429: "Too Many Requests",
|
||||
500: "Internal Server Error",
|
||||
}
|
||||
|
||||
ERROR_MSGS = {
|
||||
400: "That request was bad and you should feel bad.",
|
||||
401: "What you're trying to do requires an account. I think. The original error message said something about a castle and I hated that.",
|
||||
403: "YOU AREN'T WELCOME HERE GO AWAY",
|
||||
404: "Someone typed something wrong and it was probably you, please do better.",
|
||||
405: "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",
|
||||
406: "Max limit is 5 for comments and 50 for posts",
|
||||
409: "There's a conflict between what you're trying to do and what you or someone else has done and because of that you can't do what you're trying to do. So maybe like... don't try and do that? Sorry not sorry",
|
||||
413: "Max image/audio size is 8 MB (16 MB for paypigs)",
|
||||
414: "Max video size is 32 MB (64 MB for paypigs)",
|
||||
415: "Please upload only Image, Video, or Audio files!",
|
||||
417: "Image already exists!",
|
||||
418: "Please convert your video to MP4 and re-upload it!",
|
||||
429: "go spam somewhere else nerd",
|
||||
500: "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",
|
||||
}
|
||||
|
||||
ERROR_MARSEYS = {
|
||||
400: "marseybrainlet",
|
||||
401: "marseydead",
|
||||
403: "marseytroll",
|
||||
404: "marseyconfused",
|
||||
405: "marseyretard",
|
||||
406: "marseyrage",
|
||||
409: "marseynoyou",
|
||||
413: "marseyretard",
|
||||
414: "marseychonker2",
|
||||
415: "marseydetective",
|
||||
418: "marseytea",
|
||||
429: "marseyrentfree",
|
||||
500: "marseycarp3",
|
||||
}
|
||||
|
||||
EMOJI_MARSEYS = True
|
||||
EMOJI_SRCS = ['files/assets/emojis.json']
|
||||
|
||||
|
@ -389,6 +456,8 @@ elif SITE == 'pcmemes.net':
|
|||
PIN_LIMIT = 10
|
||||
FEATURES['REPOST_DETECTION'] = False
|
||||
FEATURES['GAMBLING'] = False
|
||||
ERROR_MSGS[500] = "Hiiiii it's <b>nigger</b>! I think this error means that there's a <b>nigger</b> error. And I think that means something took too long to load so it decided to be a <b>nigger</b>. If you keep seeing this on the same page but not other pages, then something its probably a <b>niggerfaggot</b>. It may not be called a <b>nigger</b>, 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"
|
||||
ERROR_MARSEYS[500] = "wholesome"
|
||||
POST_RATE_LIMIT = '1/second;4/minute;20/hour;100/day'
|
||||
|
||||
HOLE_COST = 2000
|
||||
|
|
|
@ -196,7 +196,7 @@ def remove_admin(v, username):
|
|||
@admin_level_required(PERMS['POST_BETS_DISTRIBUTE'])
|
||||
def distribute(v, option_id):
|
||||
autojanny = get_account(AUTOJANNY_ID)
|
||||
if autojanny.coins == 0: return {"error": "@AutoJanny has 0 coins"}, 400
|
||||
if autojanny.coins == 0: abort(400, "@AutoJanny has 0 coins")
|
||||
|
||||
try: option_id = int(option_id)
|
||||
except: abort(400)
|
||||
|
@ -303,7 +303,7 @@ def revert_actions(v, username):
|
|||
def club_allow(v, username):
|
||||
u = get_user(username, v=v)
|
||||
|
||||
if u.admin_level >= v.admin_level: return {"error": "noob"}, 400
|
||||
if u.admin_level >= v.admin_level: abort(403, 'noob')
|
||||
|
||||
u.club_allowed = True
|
||||
g.db.add(u)
|
||||
|
@ -329,7 +329,7 @@ def club_allow(v, username):
|
|||
def club_ban(v, username):
|
||||
u = get_user(username, v=v)
|
||||
|
||||
if u.admin_level >= v.admin_level: return {"error": "noob"}, 400
|
||||
if u.admin_level >= v.admin_level: abort(403, 'noob')
|
||||
|
||||
u.club_allowed = False
|
||||
|
||||
|
@ -490,7 +490,7 @@ def purge_cache(v):
|
|||
g.db.add(ma)
|
||||
|
||||
if response == "<Response [200]>": return {"message": "Cache purged!"}
|
||||
return {"error": "Failed to purge cache."}, 400
|
||||
abort(400, 'Failed to purge cache.')
|
||||
|
||||
|
||||
@app.post("/admin/under_attack")
|
||||
|
@ -507,7 +507,7 @@ def under_attack(v):
|
|||
|
||||
response = str(requests.patch(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/settings/security_level', headers=CF_HEADERS, data='{"value":"high"}', timeout=5))
|
||||
if response == "<Response [200]>": return {"message": "Under attack mode disabled!"}
|
||||
return {"error": "Failed to disable under attack mode."}, 400
|
||||
abort(400, "Failed to disable under attack mode.")
|
||||
else:
|
||||
ma = ModAction(
|
||||
kind="enable_under_attack",
|
||||
|
@ -517,7 +517,7 @@ def under_attack(v):
|
|||
|
||||
response = str(requests.patch(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/settings/security_level', headers=CF_HEADERS, data='{"value":"under_attack"}', timeout=5))
|
||||
if response == "<Response [200]>": return {"message": "Under attack mode enabled!"}
|
||||
return {"error": "Failed to enable under attack mode."}, 400
|
||||
abort(400, "Failed to enable under attack mode.")
|
||||
|
||||
@app.get("/admin/badge_grant")
|
||||
@admin_level_required(PERMS['USER_BADGES'])
|
||||
|
@ -1158,7 +1158,7 @@ def approve_post(post_id, v):
|
|||
post = get_post(post_id)
|
||||
|
||||
if post.author.id == v.id and post.author.agendaposter and AGENDAPOSTER_PHRASE not in post.body.lower() and post.sub != 'chudrama':
|
||||
return {"error": "You can't bypass the chud award!"}, 400
|
||||
abort(400, "You can't bypass the chud award!")
|
||||
|
||||
if post.is_banned:
|
||||
ma=ModAction(
|
||||
|
@ -1223,7 +1223,7 @@ def sticky_post(post_id, v):
|
|||
if v.admin_level >= PERMS['BYPASS_PIN_LIMIT']:
|
||||
post.stickied = v.username
|
||||
post.stickied_utc = int(time.time()) + 3600
|
||||
else: return {"error": f"Can't exceed {PIN_LIMIT} pinned posts limit!"}, 403
|
||||
else: abort(403, f"Can't exceed {PIN_LIMIT} pinned posts limit!")
|
||||
else: post.stickied = v.username
|
||||
g.db.add(post)
|
||||
|
||||
|
@ -1246,7 +1246,7 @@ def unsticky_post(post_id, v):
|
|||
|
||||
post = get_post(post_id)
|
||||
if post.stickied:
|
||||
if post.stickied.endswith('(pin award)'): return {"error": "Can't unpin award pins!"}, 403
|
||||
if post.stickied.endswith('(pin award)'): abort(403, "Can't unpin award pins!")
|
||||
|
||||
post.stickied = None
|
||||
post.stickied_utc = None
|
||||
|
@ -1296,7 +1296,7 @@ def unsticky_comment(cid, v):
|
|||
comment = get_comment(cid, v=v)
|
||||
|
||||
if comment.stickied:
|
||||
if comment.stickied.endswith("(pin award)"): return {"error": "Can't unpin award pins!"}, 403
|
||||
if comment.stickied.endswith("(pin award)"): abort(403, "Can't unpin award pins!")
|
||||
|
||||
comment.stickied = None
|
||||
g.db.add(comment)
|
||||
|
@ -1344,7 +1344,7 @@ def approve_comment(c_id, v):
|
|||
if not comment: abort(404)
|
||||
|
||||
if comment.author.id == v.id and comment.author.agendaposter and AGENDAPOSTER_PHRASE not in comment.body.lower() and comment.post.sub != 'chudrama':
|
||||
return {"error": "You can't bypass the chud award!"}, 400
|
||||
abort(400, "You can't bypass the chud award!")
|
||||
|
||||
if comment.is_banned:
|
||||
ma=ModAction(
|
||||
|
|
|
@ -96,27 +96,27 @@ if SITE not in ('pcmemes.net', 'watchpeopledie.co'):
|
|||
@admin_level_required(PERMS['MODERATE_PENDING_SUBMITTED_MARSEYS'])
|
||||
def approve_marsey(v, name):
|
||||
if AEVANN_ID and v.id not in (AEVANN_ID, CARP_ID, SNAKES_ID):
|
||||
return {"error": "Only Carp can approve marseys!"}, 403
|
||||
abort(403, "Only Carp can approve marseys!")
|
||||
|
||||
name = name.lower().strip()
|
||||
|
||||
marsey = g.db.query(Marsey).filter_by(name=name).one_or_none()
|
||||
if not marsey:
|
||||
return {"error": f"This marsey '{name}' doesn't exist!"}, 404
|
||||
abort(404, f"This marsey '{name}' doesn't exist!")
|
||||
|
||||
tags = request.values.get('tags').lower().strip()
|
||||
if not tags:
|
||||
return {"error": "You need to include tags!"}, 400
|
||||
abort(400, "You need to include tags!")
|
||||
|
||||
new_name = request.values.get('name').lower().strip()
|
||||
if not new_name:
|
||||
return {"error": "You need to include name!"}, 400
|
||||
abort(400, "You need to include name!")
|
||||
|
||||
|
||||
if not marsey_regex.fullmatch(new_name):
|
||||
return {"error": "Invalid name!"}, 400
|
||||
abort(400, "Invalid name!")
|
||||
if not tags_regex.fullmatch(tags):
|
||||
return {"error": "Invalid tags!"}, 400
|
||||
abort(400, "Invalid tags!")
|
||||
|
||||
|
||||
marsey.name = new_name
|
||||
|
@ -168,10 +168,10 @@ if SITE not in ('pcmemes.net', 'watchpeopledie.co'):
|
|||
|
||||
marsey = g.db.query(Marsey).filter_by(name=name).one_or_none()
|
||||
if not marsey:
|
||||
return {"error": f"This marsey '{name}' doesn't exist!"}, 404
|
||||
abort(404, f"This marsey '{name}' doesn't exist!")
|
||||
|
||||
if v.id not in (marsey.submitter_id, AEVANN_ID, CARP_ID):
|
||||
return {"error": "Only Carp can remove marseys!"}, 403
|
||||
abort(403, "Only Carp can remove marseys!")
|
||||
|
||||
if v.id != marsey.submitter_id:
|
||||
msg = f"@{v.username} has rejected a marsey you submitted: `'{marsey.name}'`"
|
||||
|
@ -257,27 +257,20 @@ if SITE not in ('pcmemes.net', 'watchpeopledie.co'):
|
|||
@admin_level_required(PERMS['MODERATE_PENDING_SUBMITTED_HATS'])
|
||||
def approve_hat(v, name):
|
||||
if AEVANN_ID and v.id not in (AEVANN_ID, CARP_ID, SNAKES_ID):
|
||||
return {"error": "Only Carp can approve hats!"}, 403
|
||||
abort(403, "Only Carp can approve hats!")
|
||||
|
||||
name = name.strip()
|
||||
|
||||
hat = g.db.query(HatDef).filter_by(name=name).one_or_none()
|
||||
if not hat:
|
||||
return {"error": f"This hat '{name}' doesn't exist!"}, 404
|
||||
if not hat: abort(404, f"This hat '{name}' doesn't exist!")
|
||||
|
||||
description = request.values.get('description').strip()
|
||||
if not description:
|
||||
return {"error": "You need to include description!"}, 400
|
||||
if not description: abort(400, "You need to include a description!")
|
||||
|
||||
new_name = request.values.get('name').strip()
|
||||
if not new_name:
|
||||
return {"error": "You need to include name!"}, 400
|
||||
|
||||
if not hat_regex.fullmatch(new_name):
|
||||
return {"error": "Invalid name!"}, 400
|
||||
|
||||
if not description_regex.fullmatch(description):
|
||||
return {"error": "Invalid description!"}, 400
|
||||
if not new_name: abort(400, "You need to include a name!")
|
||||
if not hat_regex.fullmatch(new_name): abort(400, "Invalid name!")
|
||||
if not description_regex.fullmatch(description): abort(400, "Invalid description!")
|
||||
|
||||
hat.price = int(request.values.get('price'))
|
||||
hat.name = new_name
|
||||
|
@ -332,11 +325,9 @@ if SITE not in ('pcmemes.net', 'watchpeopledie.co'):
|
|||
name = name.strip()
|
||||
|
||||
hat = g.db.query(HatDef).filter_by(name=name).one_or_none()
|
||||
if not hat:
|
||||
return {"error": f"This hat '{name}' doesn't exist!"}, 404
|
||||
|
||||
if not hat: abort(404, f"This hat '{name}' doesn't exist!")
|
||||
if v.id not in (hat.submitter_id, AEVANN_ID, CARP_ID):
|
||||
return {"error": "Only Carp can remove hats!"}, 403
|
||||
abort(403, 'Only Carp can remove hats!')
|
||||
|
||||
if v.id != hat.submitter_id:
|
||||
msg = f"@{v.username} has rejected a hat you submitted: `'{hat.name}'`"
|
||||
|
|
|
@ -49,10 +49,10 @@ def buy(v, award):
|
|||
|
||||
|
||||
if award == 'benefactor' and not request.values.get("mb"):
|
||||
return {"error": "You can only buy the Benefactor award with marseybux."}, 403
|
||||
abort(403, "You can only buy the Benefactor award with marseybux.")
|
||||
|
||||
if award == 'ghost' and v.admin_level < PERMS['BUY_GHOST_AWARD']:
|
||||
return {"error": "Only admins can buy this award."}, 403
|
||||
abort(403, "Only admins can buy this award")
|
||||
|
||||
AWARDS = deepcopy(AWARDS2)
|
||||
|
||||
|
@ -67,15 +67,15 @@ def buy(v, award):
|
|||
|
||||
if request.values.get("mb"):
|
||||
if award == "grass":
|
||||
return {"error": "You can't buy the grass award with marseybux."}, 403
|
||||
abort(403, "You can't buy the grass award with marseybux.")
|
||||
|
||||
charged = v.charge_account('procoins', price)
|
||||
if not charged:
|
||||
return {"error": "Not enough marseybux."}, 400
|
||||
abort(400, "Not enough marseybux.")
|
||||
else:
|
||||
charged = v.charge_account('coins', price)
|
||||
if not charged:
|
||||
return {"error": "Not enough coins."}, 400
|
||||
abort(400, "Not enough coins.")
|
||||
|
||||
v.coins_spent += price
|
||||
if v.coins_spent >= 1000000:
|
||||
|
@ -129,8 +129,6 @@ def buy(v, award):
|
|||
@is_not_permabanned
|
||||
@feature_required('BADGES')
|
||||
def award_thing(v, thing_type, id):
|
||||
|
||||
|
||||
if thing_type == 'post': thing = get_post(id)
|
||||
else: thing = get_comment(id)
|
||||
|
||||
|
@ -142,8 +140,7 @@ def award_thing(v, thing_type, id):
|
|||
if v.house:
|
||||
AWARDS[v.house] = HOUSE_AWARDS[v.house]
|
||||
|
||||
if kind not in AWARDS:
|
||||
return {"error": "This award doesn't exist."}, 404
|
||||
if kind not in AWARDS: abort(404, "This award doesn't exist")
|
||||
|
||||
award = g.db.query(AwardRelationship).filter(
|
||||
AwardRelationship.kind == kind,
|
||||
|
@ -152,8 +149,7 @@ def award_thing(v, thing_type, id):
|
|||
AwardRelationship.comment_id == None
|
||||
).first()
|
||||
|
||||
if not award:
|
||||
return {"error": "You don't have that award."}, 404
|
||||
if not award: abort(404, "You don't have that award")
|
||||
|
||||
if thing_type == 'post': award.submission_id = thing.id
|
||||
else: award.comment_id = thing.id
|
||||
|
@ -167,13 +163,13 @@ def award_thing(v, thing_type, id):
|
|||
if author.shadowbanned: abort(404)
|
||||
|
||||
if SITE == 'rdrama.net' and author.id in (PIZZASHILL_ID, CARP_ID):
|
||||
return {"error": "This user is immune to awards."}, 403
|
||||
abort(403, "This user is immune to awards.")
|
||||
|
||||
if kind == "benefactor" and author.id == v.id:
|
||||
return {"error": "You can't use this award on yourself."}, 400
|
||||
abort(400, "You can't use this award on yourself.")
|
||||
|
||||
if kind == 'marsify' and author.marsify == 1:
|
||||
return {"error": "User is already permanently marsified!"}, 403
|
||||
abort(403, "User is already permanently marsified!")
|
||||
|
||||
if v.id != author.id:
|
||||
safe_username = "👻" if thing.ghost else f"@{author.username}"
|
||||
|
@ -254,7 +250,7 @@ def award_thing(v, thing_type, id):
|
|||
g.db.add(thing)
|
||||
elif kind == "agendaposter" and not (author.agendaposter and author.agendaposter == 0):
|
||||
if author.marseyawarded:
|
||||
return {"error": "This user is the under the effect of a conflicting award: Marsey award."}, 404
|
||||
abort(400, "This user is under the effect of a conflicting award: Marsey award.")
|
||||
|
||||
if author.agendaposter and time.time() < author.agendaposter: author.agendaposter += 86400
|
||||
else: author.agendaposter = int(time.time()) + 86400
|
||||
|
@ -284,13 +280,13 @@ def award_thing(v, thing_type, id):
|
|||
badge_grant(user=author, badge_id=98)
|
||||
elif kind == "pizzashill":
|
||||
if author.bird:
|
||||
return {"error": "This user is the under the effect of a conflicting award: Bird Site award."}, 404
|
||||
abort(400, "This user is under the effect of a conflicting award: Bird Site award.")
|
||||
if author.longpost: author.longpost += 86400
|
||||
else: author.longpost = int(time.time()) + 86400
|
||||
badge_grant(user=author, badge_id=97)
|
||||
elif kind == "bird":
|
||||
if author.longpost:
|
||||
return {"error": "This user is the under the effect of a conflicting award: Pizzashill award."}, 404
|
||||
abort(400, "This user is under the effect of a conflicting award: Pizzashill award.")
|
||||
if author.bird: author.bird += 86400
|
||||
else: author.bird = int(time.time()) + 86400
|
||||
badge_grant(user=author, badge_id=95)
|
||||
|
@ -317,7 +313,7 @@ def award_thing(v, thing_type, id):
|
|||
else: author.progressivestack = int(time.time()) + 21600
|
||||
badge_grant(user=author, badge_id=94)
|
||||
elif kind == "benefactor":
|
||||
if author.patron: return {"error": "This user is already a paypig!"}, 400
|
||||
if author.patron: abort(400, "This user is already a paypig!")
|
||||
author.patron = 1
|
||||
if author.patron_utc: author.patron_utc += 2629746
|
||||
else: author.patron_utc = int(time.time()) + 2629746
|
||||
|
|
|
@ -55,8 +55,8 @@ def casino_game_page(v, game):
|
|||
@auth_required
|
||||
@feature_required('GAMBLING')
|
||||
def casino_game_feed(v, game):
|
||||
if v.rehab:
|
||||
return {"error": "You are under Rehab award effect!"}, 400
|
||||
if v.rehab:
|
||||
abort(403, "You are under Rehab award effect!")
|
||||
elif game not in CASINO_GAME_KINDS:
|
||||
abort(404)
|
||||
|
||||
|
@ -83,27 +83,27 @@ def lottershe(v):
|
|||
@feature_required('GAMBLING')
|
||||
def pull_slots(v):
|
||||
if v.rehab:
|
||||
return {"error": "You are under Rehab award effect!"}, 400
|
||||
abort(403, "You are under Rehab award effect!")
|
||||
|
||||
try:
|
||||
wager = int(request.values.get("wager"))
|
||||
except:
|
||||
return {"error": "Invalid wager."}, 400
|
||||
abort(400, "Invalid wager.")
|
||||
|
||||
try:
|
||||
currency = request.values.get("currency")
|
||||
except:
|
||||
return {"error": "Invalid currency (expected 'coin' or 'marseybux')."}, 400
|
||||
abort(400, "Invalid currency (expected 'coin' or 'marseybux').")
|
||||
|
||||
if (currency == "coin" and wager > v.coins) or (currency == "marseybux" and wager > v.procoins):
|
||||
return {"error": f"Not enough {currency} to make that bet."}, 400
|
||||
abort(400, f"Not enough {currency} to make that bet")
|
||||
|
||||
success, game_state = casino_slot_pull(v, wager, currency)
|
||||
|
||||
if success:
|
||||
return {"game_state": game_state, "gambler": {"coins": v.coins, "procoins": v.procoins}}
|
||||
else:
|
||||
return {"error": f"Wager must be more than 5 {currency}."}, 400
|
||||
abort(400, f"Wager must be more than 5 {currency}")
|
||||
|
||||
|
||||
# 21
|
||||
|
@ -113,7 +113,7 @@ def pull_slots(v):
|
|||
@feature_required('GAMBLING')
|
||||
def blackjack_deal_to_player(v):
|
||||
if v.rehab:
|
||||
return {"error": "You are under Rehab award effect!"}, 400
|
||||
abort(403, "You are under Rehab award effect!")
|
||||
|
||||
try:
|
||||
wager = int(request.values.get("wager"))
|
||||
|
@ -124,7 +124,7 @@ def blackjack_deal_to_player(v):
|
|||
|
||||
return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
|
||||
except Exception as e:
|
||||
return {"error": str(e)}, 400
|
||||
abort(400, str(e))
|
||||
|
||||
|
||||
@app.post("/casino/twentyone/hit")
|
||||
|
@ -133,14 +133,14 @@ def blackjack_deal_to_player(v):
|
|||
@feature_required('GAMBLING')
|
||||
def blackjack_player_hit(v):
|
||||
if v.rehab:
|
||||
return {"error": "You are under Rehab award effect!"}, 400
|
||||
abort(403, "You are under Rehab award effect!")
|
||||
|
||||
try:
|
||||
state = dispatch_action(v, BlackjackAction.HIT)
|
||||
feed = get_game_feed('blackjack')
|
||||
return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
|
||||
except:
|
||||
return {"error": "Unable to hit."}, 400
|
||||
abort(400, "Unable to hit.")
|
||||
|
||||
|
||||
@app.post("/casino/twentyone/stay")
|
||||
|
@ -149,14 +149,14 @@ def blackjack_player_hit(v):
|
|||
@feature_required('GAMBLING')
|
||||
def blackjack_player_stay(v):
|
||||
if v.rehab:
|
||||
return {"error": "You are under Rehab award effect!"}, 400
|
||||
abort(403, "You are under Rehab award effect!")
|
||||
|
||||
try:
|
||||
state = dispatch_action(v, BlackjackAction.STAY)
|
||||
feed = get_game_feed('blackjack')
|
||||
return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
|
||||
except:
|
||||
return {"error": "Unable to stay."}, 400
|
||||
abort(400, "Unable to stay.")
|
||||
|
||||
|
||||
@app.post("/casino/twentyone/double-down")
|
||||
|
@ -165,14 +165,14 @@ def blackjack_player_stay(v):
|
|||
@feature_required('GAMBLING')
|
||||
def blackjack_player_doubled_down(v):
|
||||
if v.rehab:
|
||||
return {"error": "You are under Rehab award effect!"}, 400
|
||||
abort(403, "You are under Rehab award effect!")
|
||||
|
||||
try:
|
||||
state = dispatch_action(v, BlackjackAction.DOUBLE_DOWN)
|
||||
feed = get_game_feed('blackjack')
|
||||
return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
|
||||
except:
|
||||
return {"error": "Unable to double down."}, 400
|
||||
abort(400, "Unable to double down.")
|
||||
|
||||
|
||||
@app.post("/casino/twentyone/buy-insurance")
|
||||
|
@ -181,14 +181,14 @@ def blackjack_player_doubled_down(v):
|
|||
@feature_required('GAMBLING')
|
||||
def blackjack_player_bought_insurance(v):
|
||||
if v.rehab:
|
||||
return {"error": "You are under Rehab award effect!"}, 400
|
||||
abort(403, "You are under Rehab award effect!")
|
||||
|
||||
try:
|
||||
state = dispatch_action(v, BlackjackAction.BUY_INSURANCE)
|
||||
feed = get_game_feed('blackjack')
|
||||
return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}}
|
||||
except:
|
||||
return {"error": "Unable to buy insurance."}, 400
|
||||
abort(403, "Unable to buy insurance.")
|
||||
|
||||
# Roulette
|
||||
@app.get("/casino/roulette/bets")
|
||||
|
@ -197,7 +197,7 @@ def blackjack_player_bought_insurance(v):
|
|||
@feature_required('GAMBLING')
|
||||
def roulette_get_bets(v):
|
||||
if v.rehab:
|
||||
return {"error": "You are under Rehab award effect!"}, 400
|
||||
abort(403, "You are under Rehab award effect!")
|
||||
|
||||
bets = get_roulette_bets()
|
||||
|
||||
|
@ -210,7 +210,7 @@ def roulette_get_bets(v):
|
|||
@feature_required('GAMBLING')
|
||||
def roulette_player_placed_bet(v):
|
||||
if v.rehab:
|
||||
return {"error": "You are under Rehab award effect!"}, 400
|
||||
abort(403, "You are under Rehab award effect!")
|
||||
|
||||
try:
|
||||
bet = request.values.get("bet")
|
||||
|
@ -227,4 +227,4 @@ def roulette_player_placed_bet(v):
|
|||
|
||||
return {"success": True, "bets": bets, "gambler": {"coins": v.coins, "procoins": v.procoins}}
|
||||
except:
|
||||
return {"error": "Unable to place a bet."}, 400
|
||||
abort(400, "Unable to place a bet.")
|
||||
|
|
|
@ -56,7 +56,7 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None):
|
|||
post = get_post(pid, v=v)
|
||||
|
||||
if post.over_18 and not (v and v.over_18) and not session.get('over_18', 0) >= int(time.time()):
|
||||
if request.headers.get("Authorization"): return {"error": 'This content is not suitable for some users and situations.'}, 403
|
||||
if request.headers.get("Authorization"): abort(403, "This content is not suitable for some users and situations.")
|
||||
else: return render_template("errors/nsfw.html", v=v)
|
||||
|
||||
try: context = min(int(request.values.get("context", 0)), 8)
|
||||
|
@ -126,17 +126,17 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None):
|
|||
@limiter.limit("1/second;20/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
||||
@auth_required
|
||||
def comment(v):
|
||||
if v.is_suspended: return {"error": "You can't perform this action while banned."}, 403
|
||||
if v.is_suspended: abort(403, "You can't perform this action while banned.")
|
||||
|
||||
parent_submission = request.values.get("submission").strip()
|
||||
parent_fullname = request.values.get("parent_fullname").strip()
|
||||
|
||||
parent_post = get_post(parent_submission, v=v)
|
||||
sub = parent_post.sub
|
||||
if sub and v.exiled_from(sub): return {"error": f"You're exiled from /h/{sub}"}, 403
|
||||
if sub and v.exiled_from(sub): abort(403, f"You're exiled from /h/{sub}")
|
||||
|
||||
if sub in ('furry','vampire','racist','femboy') and not v.client and not v.house.lower().startswith(sub):
|
||||
return {"error": f"You need to be a member of House {sub.capitalize()} to comment in /h/{sub}"}, 400
|
||||
abort(403, f"You need to be a member of House {sub.capitalize()} to comment in /h/{sub}")
|
||||
|
||||
if parent_post.club and not (v and (v.paid_dues or v.id == parent_post.author_id)): abort(403)
|
||||
|
||||
|
@ -157,18 +157,17 @@ def comment(v):
|
|||
if not parent.can_see(v): abort(404)
|
||||
if parent.deleted_utc != 0: abort(404)
|
||||
|
||||
if level > COMMENT_MAX_DEPTH:
|
||||
return {"error": f"Max comment level is {COMMENT_MAX_DEPTH}"}, 400
|
||||
if level > COMMENT_MAX_DEPTH: abort(400, f"Max comment level is {COMMENT_MAX_DEPTH}")
|
||||
|
||||
body = sanitize_raw_body(request.values.get("body", ""), False)
|
||||
|
||||
if parent_post.id not in ADMIGGERS:
|
||||
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
|
||||
return {"error":"You have to type more than 280 characters!"}, 403
|
||||
abort(403, "You have to type more than 280 characters!")
|
||||
elif v.bird and len(body) > 140:
|
||||
return {"error":"You have to type less than 140 characters!"}, 403
|
||||
abort(403, "You have to type less than 140 characters!")
|
||||
|
||||
if not body and not request.files.get('file'): return {"error":"You need to actually write something!"}, 400
|
||||
if not body and not request.files.get('file'): abort(400, "You need to actually write something!")
|
||||
|
||||
options = []
|
||||
for i in poll_regex.finditer(body):
|
||||
|
@ -187,7 +186,7 @@ def comment(v):
|
|||
oldname = f'/images/{time.time()}'.replace('.','') + '.webp'
|
||||
file.save(oldname)
|
||||
image = process_image(oldname, patron=v.patron)
|
||||
if image == "": return {"error":"Image upload failed"}, 400
|
||||
if image == "": abort(400, "Image upload failed")
|
||||
if v.admin_level >= PERMS['SITE_SETTINGS_SIDEBARS_BANNERS_BADGES'] and level == 1:
|
||||
if parent_post.id == SIDEBAR_THREAD:
|
||||
li = sorted(os.listdir(f'files/assets/images/{SITE_NAME}/sidebar'),
|
||||
|
@ -210,7 +209,7 @@ def comment(v):
|
|||
name = badge_def["name"]
|
||||
|
||||
existing = g.db.query(BadgeDef).filter_by(name=name).one_or_none()
|
||||
if existing: return {"error": "A badge with this name already exists!"}, 403
|
||||
if existing: abort(403, "A badge with this name already exists!")
|
||||
|
||||
badge = BadgeDef(name=name, description=badge_def["description"])
|
||||
g.db.add(badge)
|
||||
|
@ -221,7 +220,7 @@ def comment(v):
|
|||
requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS,
|
||||
data=f'{{"files": ["https://{SITE}/assets/images/badges/{badge.id}.webp"]}}', timeout=5)
|
||||
except Exception as e:
|
||||
return {"error": str(e)}, 400
|
||||
abort(400, str(e))
|
||||
body += f"\n\n![]({image})"
|
||||
elif file.content_type.startswith('video/'):
|
||||
body += f"\n\n{process_video(file)}"
|
||||
|
@ -257,7 +256,7 @@ def comment(v):
|
|||
if existing: return {"error": f"You already made that comment: /comment/{existing.id}"}, 409
|
||||
|
||||
if parent.author.any_block_exists(v) and v.admin_level < PERMS['POST_COMMENT_MODERATION']:
|
||||
return {"error": "You can't reply to users who have blocked you or users that you have blocked."}, 403
|
||||
abort(403, "You can't reply to users who have blocked you or users that you have blocked.")
|
||||
|
||||
is_bot = v.id != BBBB_ID and (bool(request.headers.get("Authorization")) or (SITE == 'pcmemes.net' and v.id == SNAPPY_ID))
|
||||
|
||||
|
@ -297,7 +296,7 @@ def comment(v):
|
|||
g.db.add(ma)
|
||||
|
||||
g.db.commit()
|
||||
return {"error": "Too much spam!"}, 403
|
||||
abort(403, "Too much spam!")
|
||||
|
||||
if len(body_html) > COMMENT_BODY_HTML_LENGTH_LIMIT: abort(400)
|
||||
|
||||
|
@ -442,7 +441,7 @@ def comment(v):
|
|||
g.db.add(c)
|
||||
|
||||
if v.marseyawarded and parent_post.id not in ADMIGGERS and marseyaward_body_regex.search(body_html):
|
||||
return {"error":"You can only type marseys!"}, 403
|
||||
abort(403, "You can only type marseys!")
|
||||
|
||||
check_for_treasure(body, c)
|
||||
|
||||
|
@ -469,7 +468,7 @@ def edit_comment(cid, v):
|
|||
c = get_comment(cid, v=v)
|
||||
|
||||
if time.time() - c.created_utc > 7*24*60*60 and not (c.post and c.post.private):
|
||||
return {"error":"You can't edit comments older than 1 week!"}, 403
|
||||
abort(403, "You can't edit comments older than 1 week!")
|
||||
|
||||
if c.author_id != v.id: abort(403)
|
||||
if not c.post: abort(403)
|
||||
|
@ -477,13 +476,13 @@ def edit_comment(cid, v):
|
|||
body = sanitize_raw_body(request.values.get("body", ""), False)
|
||||
|
||||
if len(body) < 1 and not (request.files.get("file") and request.headers.get("cf-ipcountry") != "T1"):
|
||||
return {"error":"You have to actually type something!"}, 400
|
||||
abort(400, "You have to actually type something!")
|
||||
|
||||
if body != c.body or request.files.get("file") and request.headers.get("cf-ipcountry") != "T1":
|
||||
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
|
||||
return {"error":"You have to type more than 280 characters!"}, 403
|
||||
abort(403, "You have to type more than 280 characters!")
|
||||
elif v.bird and len(body) > 140:
|
||||
return {"error":"You have to type less than 140 characters!"}, 403
|
||||
abort(403, "You have to type less than 140 characters!")
|
||||
|
||||
for i in poll_regex.finditer(body):
|
||||
body = body.replace(i.group(0), "")
|
||||
|
@ -535,7 +534,7 @@ def edit_comment(cid, v):
|
|||
g.db.add(comment)
|
||||
|
||||
g.db.commit()
|
||||
return {"error": "Too much spam!"}, 403
|
||||
abort(403, "Too much spam!")
|
||||
|
||||
body += process_files()
|
||||
body = body.strip()[:COMMENT_BODY_LENGTH_LIMIT] # process_files potentially adds characters to the post
|
||||
|
@ -553,7 +552,7 @@ def edit_comment(cid, v):
|
|||
if len(body_html) > COMMENT_BODY_HTML_LENGTH_LIMIT: abort(400)
|
||||
|
||||
if v.marseyawarded and marseyaward_body_regex.search(body_html):
|
||||
return {"error":"You can only type marseys!"}, 403
|
||||
abort(403, "You can only type marseys!")
|
||||
|
||||
c.body = body
|
||||
c.body_html = body_html
|
||||
|
@ -568,7 +567,7 @@ def edit_comment(cid, v):
|
|||
g.db.add(notif)
|
||||
|
||||
if v.agendaposter and not v.marseyawarded and AGENDAPOSTER_PHRASE not in c.body.lower() and c.post.sub != 'chudrama':
|
||||
return {"error": f'You have to include "{AGENDAPOSTER_PHRASE}" in your comment!'}, 403
|
||||
abort(403, f'You have to include "{AGENDAPOSTER_PHRASE}" in your comment!')
|
||||
|
||||
|
||||
if int(time.time()) - c.created_utc > 60 * 3: c.edited_utc = int(time.time())
|
||||
|
@ -745,7 +744,6 @@ def diff_words(answer, guess):
|
|||
@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
||||
@auth_required
|
||||
def handle_wordle_action(cid, v):
|
||||
|
||||
comment = get_comment(cid)
|
||||
|
||||
if v.id != comment.author_id:
|
||||
|
@ -757,8 +755,7 @@ def handle_wordle_action(cid, v):
|
|||
try: guess = request.values.get("thing").strip().lower()
|
||||
except: abort(400)
|
||||
|
||||
if len(guess) != 5:
|
||||
return {"error": "Not a valid guess!"}, 400
|
||||
if len(guess) != 5: abort(400, "Not a valid guess!")
|
||||
|
||||
if status == "active":
|
||||
guesses += "".join(cg + WORDLE_COLOR_MAPPINGS[diff] for cg, diff in zip(guess, diff_words(answer, guess)))
|
||||
|
|
|
@ -8,15 +8,10 @@ import requests
|
|||
@app.get("/discord")
|
||||
@is_not_permabanned
|
||||
def join_discord(v):
|
||||
|
||||
if v.shadowbanned: return {"error": "Internal server error"}, 400
|
||||
|
||||
if v.shadowbanned: return {"error": "Internal Server Error"}, 500
|
||||
now=int(time.time())
|
||||
|
||||
state=generate_hash(f"{now}+{v.id}+discord")
|
||||
|
||||
state=f"{now}.{state}"
|
||||
|
||||
return redirect(f"https://discord.com/api/oauth2/authorize?client_id={DISCORD_CLIENT_ID}&redirect_uri=https%3A%2F%2F{SITE}%2Fdiscord_redirect&response_type=code&scope=identify%20guilds.join&state={state}")
|
||||
|
||||
|
||||
|
|
|
@ -4,17 +4,39 @@ from urllib.parse import quote, urlencode
|
|||
import time
|
||||
from files.__main__ import app, limiter
|
||||
|
||||
|
||||
# If you're adding an error, go here:
|
||||
# https://github.com/pallets/werkzeug/blob/main/src/werkzeug/exceptions.py
|
||||
# and copy the description for the error code you're adding and add it to
|
||||
# the constant WERKZEUG_ERROR_DESCRIPTIONS so that the default error message
|
||||
# doesn't show up on the message. Be exact or it won't work properly.
|
||||
|
||||
@app.errorhandler(400)
|
||||
def error_400(e):
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "400 Bad Request"}, 400
|
||||
else: return render_template('errors/400.html', err=True), 400
|
||||
@app.errorhandler(403)
|
||||
@app.errorhandler(404)
|
||||
@app.errorhandler(405)
|
||||
@app.errorhandler(406)
|
||||
@app.errorhandler(409)
|
||||
@app.errorhandler(413)
|
||||
@app.errorhandler(414)
|
||||
@app.errorhandler(415)
|
||||
@app.errorhandler(417)
|
||||
@app.errorhandler(418)
|
||||
@app.errorhandler(429)
|
||||
def error(e):
|
||||
title = ERROR_TITLES.get(e.code, str(e.code))
|
||||
msg = ERROR_MSGS.get(e.code, str(e.code))
|
||||
details = e.description
|
||||
|
||||
if WERKZEUG_ERROR_DESCRIPTIONS.get(e.code, None) == details:
|
||||
details = None
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"):
|
||||
return {"error": title, "code": e.code, "description": msg, "details": details}
|
||||
img = ERROR_MARSEYS.get(e.code, 'marseyl')
|
||||
return render_template('errors/error.html', err=True, title=title, msg=msg, details=details, img=img), e.code
|
||||
|
||||
@app.errorhandler(401)
|
||||
def error_401(e):
|
||||
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "401 Not Authorized"}, 401
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"): return error(e)
|
||||
else:
|
||||
path = request.path
|
||||
qs = urlencode(dict(request.values))
|
||||
|
@ -23,75 +45,10 @@ def error_401(e):
|
|||
if session.get("history"): return redirect(f"/login?redirect={argval}")
|
||||
else: return redirect(f"/signup?redirect={argval}")
|
||||
|
||||
@app.errorhandler(406)
|
||||
def error_406(e):
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"):
|
||||
return {"error": "Too many pings: max limit is 5 for comments and 50 for posts"}, 406
|
||||
else: return render_template('errors/406.html', err=True), 406
|
||||
|
||||
@app.errorhandler(403)
|
||||
def error_403(e):
|
||||
|
||||
description = e.description
|
||||
if description == "You don't have the permission to access the requested resource. It is either read-protected or not readable by the server.": description = ''
|
||||
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"):
|
||||
if not description: description = "403 Forbidden"
|
||||
return {"error": description}, 403
|
||||
else:
|
||||
if not description: description = "YOU AREN'T WELCOME HERE GO AWAY"
|
||||
return render_template('errors/403.html', description=description, err=True), 403
|
||||
|
||||
|
||||
@app.errorhandler(404)
|
||||
def error_404(e):
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "404 Not Found"}, 404
|
||||
else: return render_template('errors/404.html', err=True), 404
|
||||
|
||||
@app.errorhandler(405)
|
||||
def error_405(e):
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "405 Method Not Allowed"}, 405
|
||||
else: return render_template('errors/405.html', err=True), 405
|
||||
|
||||
@app.errorhandler(413)
|
||||
def error_413(e):
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"):
|
||||
return {"error": "Max image/audio size is 8 MB (16 MB for paypigs)"}, 413
|
||||
else: return render_template('errors/413.html', err=True), 413
|
||||
|
||||
@app.errorhandler(414)
|
||||
def error_414(e):
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"):
|
||||
return {"error": "Max video size is 32 MB (64 MB for paypigs)"}, 414
|
||||
else: return render_template('errors/414.html', err=True), 414
|
||||
|
||||
@app.errorhandler(415)
|
||||
def error_415(e):
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "Please upload only Image, Video, or Audio files!"}, 415
|
||||
else: return render_template('errors/415.html', err=True), 415
|
||||
|
||||
@app.errorhandler(417)
|
||||
def error_417(e):
|
||||
return {"error": "Image already exists!"}, 417
|
||||
|
||||
@app.errorhandler(418)
|
||||
def error_418(e):
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"):
|
||||
return {"error": "WEBM videos are not allowed, please convert your video to MP4 and re-upload it!"}, 418
|
||||
else: return render_template('errors/418.html', err=True), 418
|
||||
|
||||
@app.errorhandler(429)
|
||||
def error_429(e):
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "429 Too Many Requests"}, 429
|
||||
else: return render_template('errors/429.html', err=True), 429
|
||||
|
||||
|
||||
@app.errorhandler(500)
|
||||
def error_500(e):
|
||||
g.db.rollback()
|
||||
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "500 Internal Server Error"}, 500
|
||||
else: return render_template('errors/500.html', err=True), 500
|
||||
return error(e)
|
||||
|
||||
|
||||
@app.post("/allow_nsfw")
|
||||
|
|
|
@ -36,25 +36,23 @@ def hats(v):
|
|||
@feature_required('HATS')
|
||||
def buy_hat(v, hat_id):
|
||||
try: hat_id = int(hat_id)
|
||||
except: return {"error": "Hat not found!"}, 400
|
||||
except: abort(404, "Hat not found!")
|
||||
|
||||
hat = g.db.query(HatDef).filter_by(submitter_id=None, id=hat_id).one_or_none()
|
||||
if not hat: return {"error": "Hat not found!"}, 400
|
||||
if not hat: abort(404, "Hat not found!")
|
||||
|
||||
existing = g.db.query(Hat).filter_by(user_id=v.id, hat_id=hat.id).one_or_none()
|
||||
if existing: return {"error": "You already own this hat!"}, 400
|
||||
if existing: abort(400, "You already own this hat!")
|
||||
|
||||
if request.values.get("mb"):
|
||||
charged = v.charge_account('procoins', hat.price)
|
||||
if not charged:
|
||||
return {"error": "Not enough marseybux."}, 400
|
||||
if not charged: abort(400, "Not enough marseybux.")
|
||||
|
||||
hat.author.procoins += hat.price * 0.1
|
||||
currency = "marseybux"
|
||||
else:
|
||||
charged = v.charge_account('coins', hat.price)
|
||||
if not charged:
|
||||
return {"error": "Not enough coins."}, 400
|
||||
if not charged: abort(400, "Not enough coins.")
|
||||
|
||||
v.coins_spent_on_hats += hat.price
|
||||
hat.author.coins += hat.price * 0.1
|
||||
|
@ -86,10 +84,10 @@ def buy_hat(v, hat_id):
|
|||
@feature_required('HATS')
|
||||
def equip_hat(v, hat_id):
|
||||
try: hat_id = int(hat_id)
|
||||
except: return {"error": "Hat not found!"}, 400
|
||||
except: abort(404, "Hat not found!")
|
||||
|
||||
hat = g.db.query(Hat).filter_by(hat_id=hat_id, user_id=v.id).one_or_none()
|
||||
if not hat: return {"error": "You don't own this hat!"}, 400
|
||||
if not hat: abort(403, "You don't own this hat!")
|
||||
|
||||
hat.equipped = True
|
||||
g.db.add(hat)
|
||||
|
@ -101,10 +99,10 @@ def equip_hat(v, hat_id):
|
|||
@feature_required('HATS')
|
||||
def unequip_hat(v, hat_id):
|
||||
try: hat_id = int(hat_id)
|
||||
except: return {"error": "Hat not found!"}, 400
|
||||
except: abort(404, "Hat not found!")
|
||||
|
||||
hat = g.db.query(Hat).filter_by(hat_id=hat_id, user_id=v.id).one_or_none()
|
||||
if not hat: return {"error": "You don't own this hat!"}, 400
|
||||
if not hat: abort(403, "You don't own this hat!")
|
||||
|
||||
hat.equipped = False
|
||||
g.db.add(hat)
|
||||
|
|
|
@ -29,7 +29,7 @@ def lottery_start(v):
|
|||
@feature_required('GAMBLING')
|
||||
def lottery_buy(v):
|
||||
try: quantity = int(request.values.get("quantity"))
|
||||
except: return {"error": "Invalid ticket quantity."}, 400
|
||||
except: abort(400, "Invalid ticket quantity.")
|
||||
|
||||
success, message = purchase_lottery_tickets(v, quantity)
|
||||
lottery, participants = get_active_lottery_stats()
|
||||
|
|
|
@ -19,10 +19,10 @@ def vote_option(option_id, v):
|
|||
sub = option.post.sub
|
||||
|
||||
if sub in ('furry','vampire','racist','femboy') and not v.house.lower().startswith(sub):
|
||||
return {"error": f"You need to be a member of House {sub.capitalize()} to vote on polls in /h/{sub}"}, 400
|
||||
abort(403, f"You need to be a member of House {sub.capitalize()} to vote on polls in /h/{sub}")
|
||||
|
||||
if option.exclusive == 2:
|
||||
if v.coins < POLL_BET_COINS: return {"error": f"You don't have {POLL_BET_COINS} coins!"}, 400
|
||||
if v.coins < POLL_BET_COINS: abort(400, f"You don't have {POLL_BET_COINS} coins!")
|
||||
v.coins -= POLL_BET_COINS
|
||||
g.db.add(v)
|
||||
autojanny = get_account(AUTOJANNY_ID)
|
||||
|
@ -35,7 +35,7 @@ def vote_option(option_id, v):
|
|||
SubmissionOptionVote.submission_id==option.submission_id,
|
||||
SubmissionOption.exclusive==option.exclusive).one_or_none()
|
||||
if vote:
|
||||
if option.exclusive == 2: return {"error": "You already voted on this bet!"}, 400
|
||||
if option.exclusive == 2: abort(400, "You already voted on this bet!")
|
||||
g.db.delete(vote)
|
||||
|
||||
existing = g.db.query(SubmissionOptionVote).filter_by(option_id=option_id, user_id=v.id).one_or_none()
|
||||
|
@ -85,7 +85,7 @@ def vote_option_comment(option_id, v):
|
|||
sub = option.comment.post.sub
|
||||
|
||||
if sub in ('furry','vampire','racist','femboy') and not v.house.lower().startswith(sub):
|
||||
return {"error": f"You need to be a member of House {sub.capitalize()} to vote on polls in /h/{sub}"}, 400
|
||||
abort(403, f"You need to be a member of House {sub.capitalize()} to vote on polls in /h/{sub}")
|
||||
|
||||
if option.exclusive:
|
||||
vote = g.db.query(CommentOptionVote).join(CommentOption).filter(
|
||||
|
|
|
@ -414,26 +414,26 @@ def edit_post(pid, v):
|
|||
# Disable edits on things older than 1wk unless it's a draft or editor is a jannie
|
||||
if (time.time() - p.created_utc > 7*24*60*60 and not p.private
|
||||
and not v.admin_level >= PERMS['POST_EDITING']):
|
||||
return {"error": "You can't edit posts older than 1 week!"}, 403
|
||||
abort(403, "You can't edit posts older than 1 week!")
|
||||
|
||||
title = sanitize_raw_title(request.values.get("title", ""))
|
||||
body = sanitize_raw_body(request.values.get("body", ""), True)
|
||||
|
||||
if v.id == p.author_id:
|
||||
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
|
||||
return {"error":"You have to type more than 280 characters!"}, 403
|
||||
abort(403, "You have to type more than 280 characters!")
|
||||
elif v.bird and len(body) > 140:
|
||||
return {"error":"You have to type less than 140 characters!"}, 403
|
||||
abort(403, "You have to type less than 140 characters!")
|
||||
|
||||
if not title:
|
||||
return {"error": "Please enter a better title."}, 400
|
||||
abort(400, "Please enter a better title.")
|
||||
if title != p.title:
|
||||
torture = (v.agendaposter and not v.marseyawarded and p.sub != 'chudrama' and v.id == p.author_id)
|
||||
|
||||
title_html = filter_emojis_only(title, golden=False, torture=torture)
|
||||
|
||||
if v.id == p.author_id and v.marseyawarded and not marseyaward_title_regex.fullmatch(title_html):
|
||||
return {"error":"You can only type marseys!"}, 403
|
||||
abort(403, "You can only type marseys!")
|
||||
|
||||
p.title = title
|
||||
p.title_html = title_html
|
||||
|
@ -466,7 +466,7 @@ def edit_post(pid, v):
|
|||
body_html = sanitize(body, golden=False, limit_pings=100, showmore=False, torture=torture)
|
||||
|
||||
if v.id == p.author_id and v.marseyawarded and marseyaward_body_regex.search(body_html):
|
||||
return {"error":"You can only type marseys!"}, 403
|
||||
abort(403, "You can only type marseys!")
|
||||
|
||||
|
||||
p.body = body
|
||||
|
@ -477,12 +477,13 @@ def edit_post(pid, v):
|
|||
g.db.add(v)
|
||||
send_repeatable_notification(CARP_ID, p.permalink)
|
||||
|
||||
if len(body_html) > POST_BODY_HTML_LENGTH_LIMIT: return {"error":f"Submission body_html too long! (max {POST_BODY_HTML_LENGTH_LIMIT} characters)"}, 400
|
||||
if len(body_html) > POST_BODY_HTML_LENGTH_LIMIT:
|
||||
abort(400, f"Submission body_html too long! (max {POST_BODY_HTML_LENGTH_LIMIT} characters)")
|
||||
|
||||
p.body_html = body_html
|
||||
|
||||
if v.id == p.author_id and v.agendaposter and not v.marseyawarded and AGENDAPOSTER_PHRASE not in f'{p.body}{p.title}'.lower() and p.sub != 'chudrama':
|
||||
return {"error": f'You have to include "{AGENDAPOSTER_PHRASE}" in your post!'}, 403
|
||||
abort(403, f'You have to include "{AGENDAPOSTER_PHRASE}" in your post!')
|
||||
|
||||
|
||||
if not p.private and not p.ghost:
|
||||
|
@ -702,7 +703,7 @@ def submit_post(v, sub=None):
|
|||
body = sanitize_raw_body(request.values.get("body", ""), True)
|
||||
|
||||
def error(error):
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": error}, 400
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"): abort(400, error)
|
||||
|
||||
SUBS = [x[0] for x in g.db.query(Sub.name).order_by(Sub.name).all()]
|
||||
return render_template("submit.html", SUBS=SUBS, v=v, error=error, title=title, url=url, body=body), 400
|
||||
|
@ -1204,7 +1205,7 @@ def pin_post(post_id, v):
|
|||
|
||||
post = get_post(post_id)
|
||||
if post:
|
||||
if v.id != post.author_id: return {"error": "Only the post author's can do that!"}, 400
|
||||
if v.id != post.author_id: abort(400, "Only the post author's can do that!")
|
||||
post.is_pinned = not post.is_pinned
|
||||
g.db.add(post)
|
||||
|
||||
|
@ -1212,7 +1213,7 @@ def pin_post(post_id, v):
|
|||
|
||||
if post.is_pinned: return {"message": "Post pinned!"}
|
||||
else: return {"message": "Post unpinned!"}
|
||||
return {"error": "Post not found!"}, 400
|
||||
return abort(404, "Post not found!")
|
||||
|
||||
|
||||
extensions = (
|
||||
|
|
|
@ -21,14 +21,13 @@ def flag_post(pid, v):
|
|||
if not v.is_banned: v.ban_reason = 'Blackjack'
|
||||
send_repeatable_notification(CARP_ID, f"reports on {post.permalink}")
|
||||
|
||||
if v.is_muted:
|
||||
return {"error": "You are forbidden from making reports."}, 400
|
||||
if v.is_muted: abort(400, "You are forbidden from making reports.")
|
||||
|
||||
reason = reason[:100]
|
||||
|
||||
reason = filter_emojis_only(reason)
|
||||
|
||||
if len(reason) > 350: return {"error": "Too long."}, 400
|
||||
if len(reason) > 350: abort(400, "Too long.")
|
||||
|
||||
if reason.startswith('!') and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or post.sub and v.mods(post.sub)):
|
||||
post.flair = reason[1:]
|
||||
|
@ -58,16 +57,16 @@ def flag_post(pid, v):
|
|||
sub_to = g.db.get(Sub, sub_to)
|
||||
sub_to = sub_to.name if sub_to else None
|
||||
|
||||
if sub_from == sub_to: {"error": f"Post is already in /h/{sub_to}"}, 400
|
||||
if sub_from == sub_to: abort(400, f"Post is already in /h/{sub_to}")
|
||||
|
||||
if post.author.exiled_from(sub_to):
|
||||
return {"error": f"User is exiled from this {HOLE_NAME}!"}, 400
|
||||
abort(400, f"User is exiled from this {HOLE_NAME}!")
|
||||
|
||||
if sub_to in ('furry','vampire','racist','femboy') and not v.client and not post.author.house.lower().startswith(sub_to):
|
||||
if v.id == post.author_id:
|
||||
return {"error": f"You need to be a member of House {sub.capitalize()} to post in /h/{sub}"}, 403
|
||||
abort(403, f"You need to be a member of House {sub_to.capitalize()} to post in /h/{sub_to}")
|
||||
else:
|
||||
return {"error": f"@{post.author.username} needs to be a member of House {sub.capitalize()} for their post to be moved to /h/{sub}"}, 400
|
||||
abort(403, f"@{post.author.username} needs to be a member of House {sub_to.capitalize()} for their post to be moved to /h/{sub_to}")
|
||||
|
||||
post.sub = sub_to
|
||||
g.db.add(post)
|
||||
|
@ -103,8 +102,7 @@ def flag_post(pid, v):
|
|||
return {"message": f"Post moved to /h/{post.sub}"}
|
||||
else:
|
||||
existing = g.db.query(Flag.post_id).filter_by(user_id=v.id, post_id=post.id).one_or_none()
|
||||
if existing:
|
||||
return {"error": "You already reported this post!"}, 409
|
||||
if existing: abort(409, "You already reported this post!")
|
||||
flag = Flag(post_id=post.id, user_id=v.id, reason=reason)
|
||||
g.db.add(flag)
|
||||
|
||||
|
@ -121,8 +119,7 @@ def flag_comment(cid, v):
|
|||
comment = get_comment(cid)
|
||||
|
||||
existing = g.db.query(CommentFlag.comment_id).filter_by(user_id=v.id, comment_id=comment.id).one_or_none()
|
||||
if existing:
|
||||
return {"error": "You already reported this comment!"}, 409
|
||||
if existing: abort(409, "You already reported this comment!")
|
||||
|
||||
reason = request.values.get("reason", "").strip()
|
||||
|
||||
|
@ -135,7 +132,7 @@ def flag_comment(cid, v):
|
|||
|
||||
reason = filter_emojis_only(reason)
|
||||
|
||||
if len(reason) > 350: return {"error": "Too long."}, 400
|
||||
if len(reason) > 350: abort(400, "Too long.")
|
||||
|
||||
flag = CommentFlag(comment_id=comment.id, user_id=v.id, reason=reason)
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ def searchposts(v):
|
|||
author = get_user(criteria['author'], v=v, include_shadowbanned=False)
|
||||
if author.is_private and author.id != v.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye:
|
||||
if request.headers.get("Authorization"):
|
||||
return {"error": f"@{author.username}'s profile is private; You can't use the 'author' syntax on them"}, 400
|
||||
abort(403, f"@{author.username}'s profile is private; You can't use the 'author' syntax on them")
|
||||
return render_template("search.html",
|
||||
v=v,
|
||||
query=query,
|
||||
|
@ -193,7 +193,7 @@ def searchcomments(v):
|
|||
|
||||
if 'post' in criteria:
|
||||
try: post = int(criteria['post'])
|
||||
except: return {"error": f"Post with id {post} does not exist."}, 400
|
||||
except: abort(404, f"Post with id {post} does not exist.")
|
||||
comments = comments.filter(Comment.parent_submission == post)
|
||||
|
||||
|
||||
|
@ -202,7 +202,7 @@ def searchcomments(v):
|
|||
author = get_user(criteria['author'], v=v, include_shadowbanned=False)
|
||||
if author.is_private and author.id != v.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye:
|
||||
if request.headers.get("Authorization"):
|
||||
return {"error": f"@{author.username}'s profile is private; You can't use the 'author' syntax on them"}, 400
|
||||
abort(403, 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.")
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ def settings_profile_post(v):
|
|||
if theme:
|
||||
if theme in {"4chan","classic","classic_dark","coffee","dark","dramblr","light","midnight","transparent","tron","win98"}:
|
||||
if theme == "transparent" and not v.background:
|
||||
return {"error": "You need to set a background to use the transparent theme!"}, 400
|
||||
abort(400, "You need to set a background to use the transparent theme!")
|
||||
v.theme = theme
|
||||
if theme == "win98": v.themecolor = "30409f"
|
||||
updated = True
|
||||
|
@ -294,7 +294,7 @@ def settings_profile_post(v):
|
|||
return {"message": "Your settings have been updated."}
|
||||
|
||||
else:
|
||||
return {"error": "You didn't change anything."}, 400
|
||||
abort(400, "You didn't change anything.")
|
||||
|
||||
|
||||
@app.post("/settings/filters")
|
||||
|
@ -348,23 +348,23 @@ def themecolor(v):
|
|||
@auth_required
|
||||
def gumroad(v):
|
||||
if not (v.email and v.is_activated):
|
||||
return {"error": f"You must have a verified email to verify {patron} status and claim your rewards!"}, 400
|
||||
abort(400, f"You must have a verified email to verify {patron} status and claim your rewards!")
|
||||
|
||||
data = {'access_token': GUMROAD_TOKEN, 'email': v.email}
|
||||
response = requests.get('https://api.gumroad.com/v2/sales', data=data, timeout=5).json()["sales"]
|
||||
|
||||
if len(response) == 0: return {"error": "Email not found"}, 404
|
||||
if len(response) == 0: abort(404, "Email not found")
|
||||
|
||||
response = [x for x in response if x['variants_and_quantity']]
|
||||
response = response[0]
|
||||
tier = tiers[response["variants_and_quantity"]]
|
||||
if v.patron == tier: return {"error": f"{patron} rewards already claimed"}, 400
|
||||
if v.patron == tier: abort(400, f"{patron} rewards already claimed")
|
||||
|
||||
procoins = procoins_li[tier] - procoins_li[v.patron]
|
||||
if procoins < 0: return {"error": f"{patron} rewards already claimed"}, 400
|
||||
if procoins < 0: abort(400, f"{patron} rewards already claimed")
|
||||
|
||||
existing = g.db.query(User.id).filter(User.email == v.email, User.is_activated == True, User.patron >= tier).first()
|
||||
if existing: return {"error": f"{patron} rewards already claimed on another account"}, 400
|
||||
if existing: abort(400, f"{patron} rewards already claimed on another account")
|
||||
|
||||
v.patron = tier
|
||||
if v.discord_id: add_role(v, f"{tier}")
|
||||
|
@ -513,7 +513,7 @@ def settings_log_out_others(v):
|
|||
@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
||||
@auth_required
|
||||
def settings_images_profile(v):
|
||||
if request.headers.get("cf-ipcountry") == "T1": return {"error":"Image uploads are not allowed through TOR."}, 403
|
||||
if request.headers.get("cf-ipcountry") == "T1": abort(403, "Image uploads are not allowed through TOR.")
|
||||
|
||||
file = request.files["profile"]
|
||||
|
||||
|
@ -549,9 +549,7 @@ def settings_images_profile(v):
|
|||
@auth_required
|
||||
@feature_required('USERS_PROFILE_BANNER')
|
||||
def settings_images_banner(v):
|
||||
|
||||
|
||||
if request.headers.get("cf-ipcountry") == "T1": return {"error":"Image uploads are not allowed through TOR."}, 403
|
||||
if request.headers.get("cf-ipcountry") == "T1": abort(403, "Image uploads are not allowed through TOR.")
|
||||
|
||||
file = request.files["banner"]
|
||||
|
||||
|
@ -586,12 +584,12 @@ def settings_css_get(v):
|
|||
@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
||||
@auth_required
|
||||
def settings_css(v):
|
||||
if v.agendaposter: return {"error": "Agendapostered users can't edit css!"}, 400
|
||||
if v.agendaposter: abort(400, "Agendapostered users can't edit CSS!")
|
||||
|
||||
css = request.values.get("css").strip().replace('\\', '').strip()[:4000]
|
||||
|
||||
if '</style' in css.lower():
|
||||
return {"error": "Please message @Aevann if you get this error"}, 400
|
||||
abort(400, "Please message @Aevann if you get this error")
|
||||
|
||||
v.css = css
|
||||
g.db.add(v)
|
||||
|
@ -625,21 +623,16 @@ def settings_profilecss(v):
|
|||
def settings_block_user(v):
|
||||
user = get_user(request.values.get("username"), graceful=True)
|
||||
|
||||
if not user: return {"error": "This user doesn't exist."}, 404
|
||||
if not user: abort(404, "This user doesn't exist.")
|
||||
|
||||
if user.unblockable:
|
||||
if not v.shadowbanned:
|
||||
send_notification(user.id, f"@{v.username} has tried to block you and failed because of your unblockable status!")
|
||||
return {"error": "This user is unblockable."}, 403
|
||||
abort(403, "This user is unblockable.")
|
||||
|
||||
if user.id == v.id:
|
||||
return {"error": "You can't block yourself."}, 409
|
||||
|
||||
if v.has_blocked(user):
|
||||
return {"error": f"You have already blocked @{user.username}."}, 409
|
||||
|
||||
if user.id == AUTOJANNY_ID:
|
||||
return {"error": "You can't block this user."}, 409
|
||||
if user.id == v.id: abort(400, "You can't block yourself")
|
||||
if user.id == AUTOJANNY_ID: abort(403, "You can't block this user")
|
||||
if v.has_blocked(user): abort(409, f"You have already blocked @{user.username}")
|
||||
|
||||
new_block = UserBlock(user_id=v.id,
|
||||
target_id=user.id,
|
||||
|
@ -660,13 +653,9 @@ def settings_block_user(v):
|
|||
@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
||||
@auth_required
|
||||
def settings_unblock_user(v):
|
||||
|
||||
user = get_user(request.values.get("username"))
|
||||
|
||||
x = v.has_blocked(user)
|
||||
|
||||
if not x: abort(409)
|
||||
|
||||
if not x: abort(409, "You can't unblock someone you haven't blocked")
|
||||
g.db.delete(x)
|
||||
|
||||
if not v.shadowbanned and user.admin_level >= PERMS['USER_BLOCKS_VISIBLE']:
|
||||
|
|
|
@ -245,7 +245,7 @@ def add_mod(v, sub):
|
|||
user = get_user(user, v=v, include_shadowbanned=False)
|
||||
|
||||
if sub in ('furry','vampire','racist','femboy') and not v.client and not user.house.lower().startswith(sub):
|
||||
return {"error": f"@{user.username} needs to be a member of House {sub.capitalize()} to be added as a mod there!"}, 400
|
||||
abort(403, f"@{user.username} needs to be a member of House {sub.capitalize()} to be added as a mod there!")
|
||||
|
||||
existing = g.db.query(Mod).filter_by(user_id=user.id, sub=sub).one_or_none()
|
||||
|
||||
|
@ -470,7 +470,7 @@ def get_sub_css(sub):
|
|||
@limiter.limit("1/second;10/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
||||
@is_not_permabanned
|
||||
def sub_banner(v, sub):
|
||||
if request.headers.get("cf-ipcountry") == "T1": return {"error":"Image uploads are not allowed through TOR."}, 403
|
||||
if request.headers.get("cf-ipcountry") == "T1": abort(403, "Image uploads are not allowed through TOR.")
|
||||
|
||||
sub = get_sub_by_name(sub)
|
||||
if not v.mods(sub.name): abort(403)
|
||||
|
@ -503,7 +503,7 @@ def sub_banner(v, sub):
|
|||
@limiter.limit("1/second;10/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
||||
@is_not_permabanned
|
||||
def sub_sidebar(v, sub):
|
||||
if request.headers.get("cf-ipcountry") == "T1": return {"error":"Image uploads are not allowed through TOR."}, 403
|
||||
if request.headers.get("cf-ipcountry") == "T1": abort(403, "Image uploads are not allowed through TOR.")
|
||||
|
||||
sub = get_sub_by_name(sub)
|
||||
if not v.mods(sub.name): abort(403)
|
||||
|
@ -535,7 +535,7 @@ def sub_sidebar(v, sub):
|
|||
@limiter.limit("1/second;10/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
||||
@is_not_permabanned
|
||||
def sub_marsey(v, sub):
|
||||
if request.headers.get("cf-ipcountry") == "T1": return {"error":"Image uploads are not allowed through TOR."}, 403
|
||||
if request.headers.get("cf-ipcountry") == "T1": abort(403, "Image uploads are not allowed through TOR.")
|
||||
|
||||
sub = get_sub_by_name(sub)
|
||||
if not v.mods(sub.name): abort(403)
|
||||
|
|
|
@ -264,9 +264,9 @@ def transfer_coins(v, username):
|
|||
amount = int(amount) if amount.isdigit() else None
|
||||
reason = request.values.get("reason", "").strip()
|
||||
|
||||
if amount is None or amount <= 0: return {"error": "Invalid amount of coins."}, 400
|
||||
if v.coins < amount: return {"error": "You don't have enough coins."}, 400
|
||||
if amount < 100: return {"error": "You have to gift at least 100 coins."}, 400
|
||||
if amount is None or amount <= 0: abort(400, "Invalid amount of coins.")
|
||||
if v.coins < amount: abort(400, "You don't have enough coins.")
|
||||
if amount < 100: abort(400, "You have to gift at least 100 coins.")
|
||||
|
||||
if not v.patron and not receiver.patron and not v.alts_patron and not receiver.alts_patron: tax = math.ceil(amount*0.03)
|
||||
else: tax = 0
|
||||
|
@ -291,8 +291,7 @@ def transfer_coins(v, username):
|
|||
g.db.add(v)
|
||||
|
||||
return {"message": f"{amount-tax} coins have been transferred to @{receiver.username}"}, 200
|
||||
|
||||
return {"message": "You can't transfer coins to yourself!"}, 400
|
||||
abort(400, "You can't transfer coins to yourself!")
|
||||
|
||||
|
||||
@app.post("/@<username>/transfer_bux")
|
||||
|
@ -307,9 +306,9 @@ def transfer_bux(v, username):
|
|||
amount = int(amount) if amount.isdigit() else None
|
||||
reason = request.values.get("reason", "").strip()
|
||||
|
||||
if not amount or amount < 0: return {"error": "Invalid amount of marseybux."}, 400
|
||||
if v.procoins < amount: return {"error": "You don't have enough marseybux"}, 400
|
||||
if amount < 100: return {"error": "You have to gift at least 100 marseybux."}, 400
|
||||
if not amount or amount < 0: abort(400, "Invalid amount of marseybux.")
|
||||
if v.procoins < amount: abort(400, "You don't have enough marseybux")
|
||||
if amount < 100: abort(400, "You have to gift at least 100 marseybux.")
|
||||
|
||||
v.procoins -= amount
|
||||
|
||||
|
@ -331,7 +330,7 @@ def transfer_bux(v, username):
|
|||
g.db.add(v)
|
||||
return {"message": f"{amount} marseybux have been transferred to @{receiver.username}"}, 200
|
||||
|
||||
return {"message": "You can't transfer marseybux to yourself!"}, 400
|
||||
abort(400, "You can't transfer marseybux to yourslef!")
|
||||
|
||||
|
||||
@app.get("/leaderboard")
|
||||
|
@ -500,16 +499,16 @@ def message2(v, username):
|
|||
user = get_user(username, v=v, include_blocks=True, include_shadowbanned=False)
|
||||
|
||||
if hasattr(user, 'is_blocking') and user.is_blocking:
|
||||
return {"error": "You're blocking this user."}, 403
|
||||
abort(403, "You're blocking this user.")
|
||||
|
||||
if v.admin_level <= PERMS['MESSAGE_BLOCKED_USERS'] and hasattr(user, 'is_blocked') and user.is_blocked:
|
||||
return {"error": "This user is blocking you."}, 403
|
||||
abort(403, "This user is blocking you.")
|
||||
|
||||
message = request.values.get("message", "").strip()[:10000].strip()
|
||||
|
||||
if not message: return {"error": "Message is empty!"}, 400
|
||||
if not message: abort(400, "Message is empty!")
|
||||
|
||||
if 'linkedin.com' in message: return {"error": "This domain 'linkedin.com' is banned."}, 403
|
||||
if 'linkedin.com' in message: abort(403, "This domain 'linkedin.com' is banned.")
|
||||
|
||||
body_html = sanitize(message)
|
||||
|
||||
|
@ -519,7 +518,7 @@ def message2(v, username):
|
|||
Comment.body_html == body_html,
|
||||
).first()
|
||||
|
||||
if existing: return {"error": "Message already exists."}, 403
|
||||
if existing: abort(403, "Message already exists.")
|
||||
|
||||
c = Comment(author_id=v.id,
|
||||
parent_submission=None,
|
||||
|
@ -573,18 +572,18 @@ def messagereply(v):
|
|||
body = request.values.get("body", "").strip().replace('','')
|
||||
body = body.replace('\r\n', '\n')[:COMMENT_BODY_LENGTH_LIMIT]
|
||||
|
||||
if not body and not request.files.get("file"): return {"error": "Message is empty!"}, 400
|
||||
if not body and not request.files.get("file"): abort(400, "Message is empty!")
|
||||
|
||||
if 'linkedin.com' in body: return {"error": "this domain 'linkedin.com' is banned"}, 400
|
||||
if 'linkedin.com' in body: abort(400, "this domain 'linkedin.com' is banned")
|
||||
|
||||
id = int(request.values.get("parent_id"))
|
||||
parent = get_comment(id, v=v)
|
||||
user_id = parent.author.id
|
||||
|
||||
if v.is_suspended_permanently and parent.sentto != 2:
|
||||
return {"error": "You are permabanned and may not reply to messages."}, 400
|
||||
abort(400, "You are permabanned and may not reply to messages.")
|
||||
elif v.is_muted and parent.sentto == 2:
|
||||
return {"error": "You are forbidden from replying to modmail."}, 400
|
||||
abort(400, "You are forbidden from replying to modmail.")
|
||||
|
||||
if parent.sentto == 2: user_id = None
|
||||
elif v.id == user_id: user_id = parent.sentto
|
||||
|
@ -791,14 +790,14 @@ def u_username(username, v=None):
|
|||
|
||||
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)):
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr") or request.path.endswith(".json"):
|
||||
return {"error": "This userpage is private"}, 403
|
||||
abort(403, "This userpage is private")
|
||||
|
||||
return render_template("userpage_private.html", u=u, v=v)
|
||||
|
||||
|
||||
if v and hasattr(u, 'is_blocking') and u.is_blocking:
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr") or request.path.endswith(".json"):
|
||||
return {"error": f"You are blocking @{u.username}."}, 403
|
||||
abort(403, f"You are blocking @{u.username}.")
|
||||
|
||||
return render_template("userpage_blocking.html", u=u, v=v)
|
||||
|
||||
|
@ -877,12 +876,12 @@ def u_username_comments(username, v=None):
|
|||
|
||||
if u.is_private and (not v or (v.id != u.id and v.admin_level < PERMS['VIEW_PRIVATE_PROFILES'] and not v.eye)):
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr") or request.path.endswith(".json"):
|
||||
return {"error": "This userpage is private"}, 403
|
||||
abort(403, "This userpage is private")
|
||||
return render_template("userpage_private.html", u=u, v=v)
|
||||
|
||||
if v and hasattr(u, 'is_blocking') and u.is_blocking:
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr") or request.path.endswith(".json"):
|
||||
return {"error": f"You are blocking @{u.username}."}, 403
|
||||
abort(403, f"You are blocking @{u.username}.")
|
||||
return render_template("userpage_blocking.html", u=u, v=v)
|
||||
|
||||
try: page = max(int(request.values.get("page", "1")), 1)
|
||||
|
@ -933,9 +932,9 @@ def u_username_info(username, v=None):
|
|||
user=get_user(username, v=v, include_blocks=True, include_shadowbanned=False)
|
||||
|
||||
if hasattr(user, 'is_blocking') and user.is_blocking:
|
||||
return {"error": "You're blocking this user."}, 401
|
||||
abort(401, "You're blocking this user.")
|
||||
elif hasattr(user, 'is_blocked') and user.is_blocked:
|
||||
return {"error": "This user is blocking you."}, 403
|
||||
abort(403, "This user is blocking you.")
|
||||
|
||||
return user.json
|
||||
|
||||
|
@ -946,9 +945,9 @@ def u_user_id_info(id, v=None):
|
|||
user=get_account(id, v=v, include_blocks=True, include_shadowbanned=False)
|
||||
|
||||
if hasattr(user, 'is_blocking') and user.is_blocking:
|
||||
return {"error": "You're blocking this user."}, 401
|
||||
abort(403, "You're blocking this user.")
|
||||
elif hasattr(user, 'is_blocked') and user.is_blocked:
|
||||
return {"error": "This user is blocking you."}, 403
|
||||
abort(403, "This user is blocking you.")
|
||||
|
||||
return user.json
|
||||
|
||||
|
@ -961,10 +960,10 @@ def follow_user(username, v):
|
|||
target = get_user(username, v=v, include_shadowbanned=False)
|
||||
|
||||
if target.id==v.id:
|
||||
return {"error": "You can't follow yourself!"}, 400
|
||||
abort(400, "You can't follow yourself!")
|
||||
|
||||
if target.is_nofollow:
|
||||
return {"error": "This user has disallowed other users from following them!"}, 403
|
||||
abort(403, "This user has disallowed other users from following them!")
|
||||
|
||||
if g.db.query(Follow).filter_by(user_id=v.id, target_id=target.id).one_or_none():
|
||||
return {"message": f"@{target.username} has been followed!"}
|
||||
|
@ -993,7 +992,7 @@ def unfollow_user(username, v):
|
|||
if target.fish:
|
||||
if not v.shadowbanned:
|
||||
send_notification(target.id, f"@{v.username} has tried to unfollow you and failed because of your fish award!")
|
||||
return {"error": "You can't unfollow this user!"}, 400
|
||||
abort(400, "You can't unfollow this user!")
|
||||
|
||||
follow = g.db.query(Follow).filter_by(user_id=v.id, target_id=target.id).one_or_none()
|
||||
|
||||
|
@ -1223,15 +1222,15 @@ kofi_tiers={
|
|||
@auth_required
|
||||
def settings_kofi(v):
|
||||
if not (v.email and v.is_activated):
|
||||
return {"error": f"You must have a verified email to verify {patron} status and claim your rewards!"}, 400
|
||||
abort(400, f"You must have a verified email to verify {patron} status and claim your rewards!")
|
||||
|
||||
transaction = g.db.query(Transaction).filter_by(email=v.email).order_by(Transaction.created_utc.desc()).first()
|
||||
|
||||
if not transaction:
|
||||
return {"error": "Email not found"}, 404
|
||||
abort(404, "Email not found")
|
||||
|
||||
if transaction.claimed:
|
||||
return {"error": f"{patron} rewards already claimed"}, 400
|
||||
abort(400, f"{patron} rewards already claimed")
|
||||
|
||||
tier = kofi_tiers[transaction.amount]
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ def vote_info_get(v, link):
|
|||
@is_not_permabanned
|
||||
def vote_post(post_id, new, v):
|
||||
|
||||
if new == "-1" and DISABLE_DOWNVOTES: return {"error": "forbidden."}, 403
|
||||
if new == "-1" and DISABLE_DOWNVOTES: abort(403)
|
||||
|
||||
if new not in ["-1", "0", "1"]: abort(400)
|
||||
|
||||
|
@ -126,7 +126,7 @@ def vote_post(post_id, new, v):
|
|||
@is_not_permabanned
|
||||
def vote_comment(comment_id, new, v):
|
||||
|
||||
if new == "-1" and DISABLE_DOWNVOTES: return {"error": "forbidden."}, 403
|
||||
if new == "-1" and DISABLE_DOWNVOTES: abort(403, "forbidden.")
|
||||
|
||||
if new not in ["-1", "0", "1"]: abort(400)
|
||||
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>400 Bad Request</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}error-400{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10 col-md-5">
|
||||
<div class="text-center px-3 my-8">
|
||||
<img alt=":#marseybrainlet:" loading="lazy" src="/e/marseybrainlet.webp">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,24 +0,0 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>401 Not Authorized</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}error-401{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10 col-md-5">
|
||||
<div class="text-center px-3 my-8">
|
||||
|
||||
<img alt=":#marseydead:" loading="lazy" src="/e/marseydead.webp">
|
||||
<pre></pre>
|
||||
|
||||
<h1 class="h5">401 Not Authorized</h1>
|
||||
<p class="text-muted mb-5">What you're trying to do requires an account. I think. The original error message said something about a castle and I hated that.</p>
|
||||
<div><a href="/signup" class="btn btn-primary mb-2">Create an account</a></div>
|
||||
<div><a href="/login" class="text-muted text-small">Or sign in</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,21 +0,0 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>403 Forbidden</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}error-403{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10 col-md-5">
|
||||
<div class="text-center px-3 my-8">
|
||||
<img alt=":#marseytroll:" loading="lazy" src="/e/marseytroll.webp">
|
||||
<pre></pre>
|
||||
<h1 class="h5">403 Forbidden</h1>
|
||||
<p class="text-muted mb-5">{{description}}</p>
|
||||
<div><a href="/" class="btn btn-primary">Go to frontpage</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,21 +0,0 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>404 Page Not Found</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}error-404{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10 col-md-5">
|
||||
<div class="text-center px-3 my-8">
|
||||
<img alt=":#marseyconfused" loading="lazy" src="/e/marseyconfused.webp">
|
||||
<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>
|
||||
<div><a href="/" class="btn btn-primary">Go to frontpage</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,21 +0,0 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>405 Method Not Allowed</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}error-405{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10 col-md-5">
|
||||
<div class="text-center px-3 my-8">
|
||||
<img alt=":#marseyretard:" loading="lazy" src="/e/marseyretard.webp">
|
||||
<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>
|
||||
<div><a href="/" class="btn btn-primary">Go to frontpage</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,21 +0,0 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>Too many pings</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}Too many pings{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10 col-md-5">
|
||||
<div class="text-center px-3 my-8">
|
||||
<img alt=":#marseyrage" loading="lazy" src="/e/marseyrage.webp">
|
||||
<pre></pre>
|
||||
<h1 class="h5">Too many pings</h1>
|
||||
<p class="text-muted mb-5">Max limit is 5 for comments and 50 for posts</p>
|
||||
<div><a href="/" class="btn btn-primary">Go to frontpage</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,20 +0,0 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>Max image/audio size is 8 MB (16 MB for paypigs)</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}error-413{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10 col-md-5">
|
||||
<div class="text-center px-3 my-8">
|
||||
<img alt=":#marseyretard:" loading="lazy" src="/e/marseychonker2.webp">
|
||||
<pre></pre>
|
||||
<h1 class="h5">Max image/audio size is 8 MB (16 MB for paypigs)</h1>
|
||||
<div><a href="/" class="btn btn-primary">Go to frontpage</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,20 +0,0 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>Max video size is 32 MB (64 MB for paypigs)</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}error-414{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10 col-md-5">
|
||||
<div class="text-center px-3 my-8">
|
||||
<img alt=":#marseyretard:" loading="lazy" src="/e/marseychonker2.webp">
|
||||
<pre></pre>
|
||||
<h1 class="h5">Max video size is 32 MB (64 MB for paypigs)</h1>
|
||||
<div><a href="/" class="btn btn-primary">Go to frontpage</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,20 +0,0 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>415 Unsupported Media Type</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}error-415{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10 col-md-5">
|
||||
<div class="text-center px-3 my-8">
|
||||
<img alt=":#marseydetective:" loading="lazy" src="/e/marseydetective.webp">
|
||||
<pre></pre>
|
||||
<h1 class="h5">415 Unsupported Media Type</h1>
|
||||
<p class="text-muted mb-5">Please upload only Image, Video, or Audio files!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,20 +0,0 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>WEBM videos are not allowed</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}error-418{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10 col-md-5">
|
||||
<div class="text-center px-3 my-8">
|
||||
<img alt=":#marseytea:" loading="lazy" src="/e/marseytea.webp">
|
||||
<pre></pre>
|
||||
<h1 class="h5">WEBM videos are not allowed</h1>
|
||||
<div><a href="/" class="btn btn-primary">Please convert your video to MP4 and re-upload it!</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,20 +0,0 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>429 Too Many Requests</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}error-429{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10 col-md-5">
|
||||
<div class="text-center px-3 my-8">
|
||||
<img alt=":#marseyrentfree:" loading="lazy" src="/e/marseyrentfree.webp">
|
||||
<pre></pre>
|
||||
<h1 class="h5">429 Too Many Requests</h1>
|
||||
<p class="text-muted mb-5">go spam somewhere else nerd</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,31 +0,0 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>500 Internal Server Error</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}error-500{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10 col-md-5">
|
||||
<div class="text-center px-3 my-8">
|
||||
{% if SITE_NAME == 'PCM' %}
|
||||
<img alt="wholesome" loading="lazy" src="/i/wholesome.webp">
|
||||
{% else %}
|
||||
<img alt=":#marseycarp3:" loading="lazy" src="/e/marseycarp3.webp">
|
||||
{% endif %}
|
||||
<pre></pre>
|
||||
<h1 class="h5">500 Internal Server Error</h1>
|
||||
<p class="text-muted mb-5">
|
||||
{% if SITE_NAME == 'PCM' %}
|
||||
Hiiiii it's <b>nigger</b>! I think this error means that there's a <b>nigger</b> error. And I think that means something took too long to load so it decided to be a <b>nigger</b>. If you keep seeing this on the same page but not other pages, then something its probably a <b>niggerfaggot</b>. It may not be called a <b>nigger</b>, 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
|
||||
{% else %}
|
||||
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
|
||||
{% endif %}
|
||||
</p>
|
||||
<div><a href="/" class="btn btn-primary">Go to the frontpage</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -0,0 +1,26 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>{{code}} {{title}}</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}error-{{code}}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10 col-md-5">
|
||||
<div class="text-center px-3 my-8">
|
||||
{% if img -%}
|
||||
<img alt=":#{{img}}:" loading="lazy" src="/e/{{img}}.webp">
|
||||
{%- endif %}
|
||||
<pre></pre>
|
||||
<h1 class="h5">{{code}} {{title}}</h1>
|
||||
<p class="text-muted error-description">{{msg|safe}}</p>
|
||||
{% if details -%}
|
||||
<blockquote class="error-details mb-5">{{details|safe}}</blockquote>
|
||||
{%- endif %}
|
||||
<div><a href="/" class="btn btn-primary">Go to frontpage</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue