diff --git a/files/assets/js/award_modal.js b/files/assets/js/award_modal.js index 1351a35e21..86e0bea0a9 100644 --- a/files/assets/js/award_modal.js +++ b/files/assets/js/award_modal.js @@ -157,7 +157,7 @@ function buy() { try {data = JSON.parse(xhr[0].response)} catch(e) {console.error(e)} success = xhr[0].status >= 200 && xhr[0].status < 300; - showToast(success, getMessageFromJsonData(success, data), true); + showToast(success, getMessageFromJsonData(success, data)); if (success) { if (kind != "lootbox") { diff --git a/files/assets/js/bottom.js b/files/assets/js/bottom.js index 985f3d6191..c42800604c 100644 --- a/files/assets/js/bottom.js +++ b/files/assets/js/bottom.js @@ -93,10 +93,6 @@ async function handleSettingSwitch(event) { // toggle the input back if the request doesn't go through input.checked = !input.checked; } - let oldToast = bootstrap.Toast.getOrCreateInstance( - document.getElementById('toast-post-' + (res.ok ? 'error': 'success')) - ); // intentionally reversed here: this is the old toast - oldToast.hide(); showToast(res.ok, message); input.disabled = false; input.classList.remove("disabled"); diff --git a/files/assets/js/core.js b/files/assets/js/core.js index fa97c2c7d6..a7c31a5f18 100644 --- a/files/assets/js/core.js +++ b/files/assets/js/core.js @@ -11,15 +11,13 @@ function getMessageFromJsonData(success, json) { return message; } -function showToast(success, message, isToastTwo=false) { +function showToast(success, message) { + const oldToast = bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-' + (success ? 'error': 'success'))); // intentionally reversed here: this is the old toast + oldToast.hide(); let element = success ? "toast-post-success" : "toast-post-error"; let textElement = element + "-text"; - if (isToastTwo) { - element = element + "2"; - textElement = textElement + "2"; - } if (!message) { - message = success ? "Success" : "Error, please try again later"; + message = success ? "Action successful!" : "Error, please try again later"; } document.getElementById(textElement).innerText = message; bootstrap.Toast.getOrCreateInstance(document.getElementById(element)).show(); @@ -43,18 +41,20 @@ function postToast(t, url, data, extraActionsOnSuccess, method="POST") { } const xhr = createXhrWithFormKey(url, method, form); xhr[0].onload = function() { - t.disabled = false; - t.classList.remove("disabled"); + const success = xhr[0].status >= 200 && xhr[0].status < 300; + + if (!(extraActionsOnSuccess == reload && success)) { + t.disabled = false; + t.classList.remove("disabled"); + } + let result let message; - let success = xhr[0].status >= 200 && xhr[0].status < 300; if (typeof result == "string") { message = result; } else { message = getMessageFromJsonData(success, JSON.parse(xhr[0].response)); } - let oldToast = bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-' + (success ? 'error': 'success'))); // intentionally reversed here: this is the old toast - oldToast.hide(); showToast(success, message); if (success && extraActionsOnSuccess) result = extraActionsOnSuccess(xhr[0]); return success; @@ -63,13 +63,7 @@ function postToast(t, url, data, extraActionsOnSuccess, method="POST") { } function postToastReload(t, url, method="POST") { - postToast(t, url, - { - }, - () => { - location.reload() - } - , method); + postToast(t, url, {}, reload, method); } function postToastSwitch(t, url, button1, button2, cls, extraActionsOnSuccess, method="POST") { @@ -280,10 +274,14 @@ function prepare_to_pause(audio) { }); } +function reload() { + location.reload(); +} + function sendFormXHR(form, extraActionsOnSuccess) { - const submit_btn = form.querySelector('[type="submit"]') - submit_btn.disabled = true; - submit_btn.classList.add("disabled"); + const t = form.querySelector('[type="submit"]') + t.disabled = true; + t.classList.add("disabled"); const xhr = new XMLHttpRequest(); @@ -296,24 +294,18 @@ function sendFormXHR(form, extraActionsOnSuccess) { xhr.setRequestHeader('xhr', 'xhr'); xhr.onload = function() { - if (xhr.status >= 200 && xhr.status < 300) { - let data = JSON.parse(xhr.response); - showToast(true, getMessageFromJsonData(true, data)); - if (extraActionsOnSuccess) extraActionsOnSuccess(xhr); - } else { - document.getElementById('toast-post-error-text').innerText = "Error, please try again later." - try { - let data=JSON.parse(xhr.response); - bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show(); - document.getElementById('toast-post-error-text').innerText = data["error"]; - if (data && data["details"]) document.getElementById('toast-post-error-text').innerText = data["details"]; - } catch(e) { - bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-success')).hide(); - bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show(); - } + const success = xhr.status >= 200 && xhr.status < 300; + + if (!(extraActionsOnSuccess == reload && success)) { + t.disabled = false; + t.classList.remove("disabled"); } - submit_btn.disabled = false; - submit_btn.classList.remove("disabled"); + + if (xhr.status != 204) { + const data = JSON.parse(xhr.response); + showToast(success, getMessageFromJsonData(success, data)); + } + if (success && extraActionsOnSuccess) extraActionsOnSuccess(xhr); }; xhr.send(formData); @@ -331,11 +323,7 @@ function sendFormXHRSwitch(form) { } function sendFormXHRReload(form) { - sendFormXHR(form, - () => { - location.reload(); - } - ) + sendFormXHR(form, reload) } let sortAscending = {}; diff --git a/files/assets/js/submit.js b/files/assets/js/submit.js index 2c7585ab12..298500c176 100644 --- a/files/assets/js/submit.js +++ b/files/assets/js/submit.js @@ -178,8 +178,9 @@ function submit(form) { xhr.onload = function() { upload_prog.classList.add("d-none") + const success = xhr.status >= 200 && xhr.status < 300 - if (xhr.status >= 200 && xhr.status < 300) { + if (success) { const res = JSON.parse(xhr.response) const post_id = res['post_id']; @@ -200,16 +201,8 @@ function submit(form) { location.href = "/post/" + post_id } else { submitButton.disabled = false; - document.getElementById('toast-post-error-text').innerText = "Error, please try again later." - try { - let data=JSON.parse(xhr.response); - bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show(); - document.getElementById('toast-post-error-text').innerText = data["error"]; - if (data && data["details"]) document.getElementById('toast-post-error-text').innerText = data["details"]; - } catch(e) { - bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-success')).hide(); - bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show(); - } + const data = JSON.parse(xhr.response); + showToast(success, getMessageFromJsonData(success, data)); } }; diff --git a/files/helpers/get.py b/files/helpers/get.py index 7231729d2d..07170f0bb1 100644 --- a/files/helpers/get.py +++ b/files/helpers/get.py @@ -363,12 +363,6 @@ def get_error(): else: return None -def get_msg(): - if request.referrer and request.referrer.split('?')[0] == request.base_url: - return request.values.get("msg") - else: - return None - def get_page(): try: return max(int(request.values.get("page", 1)), 1) except: return 1 diff --git a/files/routes/admin.py b/files/routes/admin.py index 8c401adf30..9fa9210df9 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -90,12 +90,12 @@ def edit_rules_post(v): with open(f'files/templates/rules_{SITE_NAME}.html', 'w+', encoding="utf-8") as f: f.write(rules) - # ma = ModAction( - # kind="edit_rules", - # user_id=v.id, - # ) - # g.db.add(ma) - return render_template('admin/edit_rules.html', v=v, rules=rules, msg='Rules edited successfully!') + ma = ModAction( + kind="edit_rules", + user_id=v.id, + ) + g.db.add(ma) + return {"message": "Rules edited successfully!"} @app.post("/@/make_admin") @limiter.limit('1/second', scope=rpath) @@ -472,16 +472,12 @@ def badge_grant_post(v): usernames = request.values.get("usernames", "").strip() if not usernames: - error = "You must enter usernames!" - if v.client: abort(400, error) - return render_template("admin/badge_admin.html", v=v, badge_types=badges, grant=True, error=error) + abort(400, "You must enter usernames!") for username in usernames.split(): user = get_user(username, graceful=True) if not user: - error = "User not found!" - if v.client: abort(400, error) - return render_template("admin/badge_admin.html", v=v, badge_types=badges, grant=True, error=error) + abort(400, "User not found!") try: badge_id = int(request.values.get("badge_id")) except: abort(400) @@ -532,10 +528,7 @@ def badge_grant_post(v): ) g.db.add(ma) - - msg = "Badge granted to users successfully!" - if v.client: return {"message": msg} - return render_template("admin/badge_admin.html", v=v, badge_types=badges, grant=True, msg=msg) + return {"message": "Badge granted to users successfully!"} @app.post("/admin/badge_remove") @feature_required('BADGES') @@ -549,14 +542,12 @@ def badge_remove_post(v): usernames = request.values.get("usernames", "").strip() if not usernames: - error = "You must enter usernames!" - if v.client: abort(400, error) - return render_template("admin/badge_admin.html", v=v, badge_types=badges, grant=False, error=error) + abort(400, "You must enter usernames!") for username in usernames.split(): user = get_user(username, graceful=True) if not user: - return render_template("admin/badge_admin.html", v=v, badge_types=badges, grant=False, error="User not found!") + abort(400, "User not found!") try: badge_id = int(request.values.get("badge_id")) except: abort(400) @@ -580,10 +571,7 @@ def badge_remove_post(v): g.db.add(ma) g.db.delete(badge) - - msg = "Badge removed from users successfully!" - if v.client: return {"message": msg} - return render_template("admin/badge_admin.html", v=v, badge_types=badges, grant=False, msg=msg) + return {"message": "Badge removed from users successfully!"} @app.get("/admin/alt_votes") @@ -1702,8 +1690,7 @@ def admin_distinguish_comment(c_id, v): def admin_banned_domains(v): banned_domains = g.db.query(BannedDomain) \ .order_by(BannedDomain.reason).all() - return render_template("admin/banned_domains.html", v=v, - banned_domains=banned_domains) + return render_template("admin/banned_domains.html", v=v, banned_domains=banned_domains) @app.post("/admin/ban_domain") @limiter.limit('1/second', scope=rpath) @@ -1736,7 +1723,7 @@ def ban_domain(v): ) g.db.add(ma) - return redirect("/admin/banned_domains/") + return {"message": "Domain banned successfully!"} @app.post("/admin/unban_domain/") @@ -1898,10 +1885,10 @@ def delete_media_post(v): url = request.values.get("url") if not url: - return render_template("admin/delete_media.html", v=v, url=url, error="No url provided!") + abort(400, "No url provided!") if not image_link_regex.fullmatch(url) and not video_link_regex.fullmatch(url): - return render_template("admin/delete_media.html", v=v, url=url, error="Invalid url!") + abort(400, "Invalid url!") path = url.split(SITE)[1] @@ -1909,7 +1896,7 @@ def delete_media_post(v): path = '/videos' + path if not os.path.isfile(path): - return render_template("admin/delete_media.html", v=v, url=url, error="File not found on the server!") + abort(400, "File not found on the server!") os.remove(path) @@ -1921,7 +1908,7 @@ def delete_media_post(v): g.db.add(ma) purge_files_in_cache(url) - return render_template("admin/delete_media.html", v=v, msg="Media deleted successfully!") + return {"message": "Media deleted successfully!"} @app.post("/admin/reset_password/") @limiter.limit('1/second', scope=rpath) @@ -1964,10 +1951,10 @@ def start_orgy(v): create_orgy(link, title) - return redirect("/chat") + return {"message": "Orgy started successfully!"} @app.post("/admin/stop_orgy") @admin_level_required(PERMS['ORGIES']) def stop_orgy(v): end_orgy() - return redirect("/chat") + return {"message": "Orgy stopped successfully!"} diff --git a/files/routes/asset_submissions.py b/files/routes/asset_submissions.py index 733c83bcc0..d442494fe0 100644 --- a/files/routes/asset_submissions.py +++ b/files/routes/asset_submissions.py @@ -34,7 +34,7 @@ def submit_emojis(v): emoji.author = g.db.query(User.username).filter_by(id=emoji.author_id).one()[0] emoji.submitter = g.db.query(User.username).filter_by(id=emoji.submitter_id).one()[0] - return render_template("submit_emojis.html", v=v, emojis=emojis, msg=get_msg()) + return render_template("submit_emojis.html", v=v, emojis=emojis) @app.post("/submit/emojis") @@ -50,46 +50,37 @@ def submit_emoji(v): username = request.values.get('author', '').lower().strip() kind = request.values.get('kind', '').strip() - def error(error): - if v.admin_level >= PERMS['VIEW_PENDING_SUBMITTED_EMOJIS']: emojis = g.db.query(Emoji).filter(Emoji.submitter_id != None) - else: emojis = g.db.query(Emoji).filter(Emoji.submitter_id == v.id) - emojis = emojis.order_by(Emoji.created_utc.desc()).all() - for emoji in emojis: - emoji.author = g.db.query(User.username).filter_by(id=emoji.author_id).one()[0] - emoji.submitter = g.db.query(User.username).filter_by(id=emoji.submitter_id).one()[0] - return render_template("submit_emojis.html", v=v, emojis=emojis, error=error, name=name, kind=kind, tags=tags, username=username), 400 - if kind not in EMOJI_KINDS: - return error("Invalid emoji kind!") + abort(400, "Invalid emoji kind!") if kind in {"Platy", "Wolf", "Tay", "Carp", "Capy"} and not name.startswith(kind.lower()): - return error(f'The name of this emoji should start with the word "{kind.lower()}"') + abort(400, f'The name of this emoji should start with the word "{kind.lower()}"') if kind == "Marsey" and not name.startswith("marsey") and not name.startswith("marcus"): - return error('The name of this emoji should start with the word "Marsey" or "Marcus"') + abort(400, 'The name of this emoji should start with the word "Marsey" or "Marcus"') if kind == "Marsey Flags" and not name.startswith("marseyflag"): - return error('The name of this emoji should start with the word "marseyflag"') + abort(400, 'The name of this emoji should start with the word "marseyflag"') if g.is_tor: - return error("Image uploads are not allowed through TOR!") + abort(400, "Image uploads are not allowed through TOR!") if not file or not file.content_type.startswith('image/'): - return error("You need to submit an image!") + abort(400, "You need to submit an image!") if not emoji_name_regex.fullmatch(name): - return error("Invalid name!") + abort(400, "Invalid name!") existing = g.db.query(Emoji.name).filter_by(name=name).one_or_none() if existing: - return error("Someone already submitted an emoji with this name!") + abort(400, "Someone already submitted an emoji with this name!") if not tags_regex.fullmatch(tags): - return error("Invalid tags!") + abort(400, "Invalid tags!") author = get_user(username, v=v, graceful=True) if not author: - return error(f"A user with the name '{username}' was not found!") + abort(400, f"A user with the name '{username}' was not found!") highquality = f'/asset_submissions/emojis/{name}' file.save(highquality) @@ -101,7 +92,8 @@ def submit_emoji(v): emoji = Emoji(name=name, kind=kind, author_id=author.id, tags=tags, count=0, submitter_id=v.id) g.db.add(emoji) - return redirect(f"/submit/emojis?msg='{name}' submitted successfully!") + return {"message": f"'{name}' submitted successfully!"} + def verify_permissions_and_get_asset(cls, asset_type, v, name, make_lower=False): if cls not in ASSET_TYPES: raise Exception("not a valid asset type") @@ -272,7 +264,7 @@ def submit_hats(v): else: hats = g.db.query(HatDef).filter(HatDef.submitter_id == v.id) hats = hats.order_by(HatDef.created_utc.desc()).all() - return render_template("submit_hats.html", v=v, hats=hats, msg=get_msg()) + return render_template("submit_hats.html", v=v, hats=hats) @app.post("/submit/hats") @@ -286,32 +278,26 @@ def submit_hat(v): description = request.values.get('description', '').strip() username = request.values.get('author', '').strip() - def error(error): - if v.admin_level >= PERMS['VIEW_PENDING_SUBMITTED_HATS']: hats = g.db.query(HatDef).filter(HatDef.submitter_id != None) - else: hats = g.db.query(HatDef).filter(HatDef.submitter_id == v.id) - hats = hats.order_by(HatDef.created_utc.desc()).all() - return render_template("submit_hats.html", v=v, hats=hats, error=error, name=name, description=description, username=username), 400 - if g.is_tor: - return error("Image uploads are not allowed through TOR!") + abort(400, "Image uploads are not allowed through TOR!") file = request.files["image"] if not file or not file.content_type.startswith('image/'): - return error("You need to submit an image!") + abort(400, "You need to submit an image!") if not hat_regex.fullmatch(name): - return error("Invalid name!") + abort(400, "Invalid name!") existing = g.db.query(HatDef.name).filter_by(name=name).one_or_none() if existing: - return error("A hat with this name already exists!") + abort(400, "A hat with this name already exists!") if not description_regex.fullmatch(description): - return error("Invalid description!") + abort(400, "Invalid description!") author = get_user(username, v=v, graceful=True) if not author: - return error(f"A user with the name '{username}' was not found!") + abort(400, f"A user with the name '{username}' was not found!") highquality = f'/asset_submissions/hats/{name}' file.save(highquality) @@ -319,7 +305,7 @@ def submit_hat(v): with Image.open(highquality) as i: if i.width > 100 or i.height > 130: os.remove(highquality) - return error("Images must be 100x130") + abort(400, "Images must be 100x130") if len(list(Iterator(i))) > 1: price = 1000 else: price = 500 @@ -331,7 +317,7 @@ def submit_hat(v): hat = HatDef(name=name, author_id=author.id, description=description, price=price, submitter_id=v.id) g.db.add(hat) - return redirect(f"/submit/hats?msg='{name}' submitted successfully!") + return {"message": f"'{name}' submitted successfully!"} @app.post("/admin/approve/hat/") @@ -434,20 +420,17 @@ def update_emoji(v): tags = request.values.get('tags', '').lower().strip() kind = request.values.get('kind', '').strip() - def error(error): - return render_template("admin/update_assets.html", v=v, error=error, name=name, tags=tags, kind=kind, type="Emoji") - existing = g.db.get(Emoji, name) if not existing: - return error("An emoji with this name doesn't exist!") + abort(400, "An emoji with this name doesn't exist!") updated = False if file: if g.is_tor: - return error("Image uploads are not allowed through TOR!") + abort(400, "Image uploads are not allowed through TOR!") if not file.content_type.startswith('image/'): - return error("You need to submit an image!") + abort(400, "You need to submit an image!") for x in IMAGE_FORMATS: if path.isfile(f'/asset_submissions/emojis/original/{name}.{x}'): @@ -480,7 +463,7 @@ def update_emoji(v): updated = True if not updated: - return error("You need to actually update something!") + abort(400, "You need to actually update something!") g.db.add(existing) @@ -494,7 +477,7 @@ def update_emoji(v): cache.delete("emojis") cache.delete(f"emoji_list_{existing.kind}") - return render_template("admin/update_assets.html", v=v, msg=f"'{name}' updated successfully!", name=name, tags=tags, kind=kind, type="Emoji") + return {"message": f"'{name}' updated successfully!"} @app.get("/admin/update/hats") @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400) @@ -514,21 +497,18 @@ def update_hat(v): file = request.files["image"] name = request.values.get('name', '').strip() - def error(error): - return render_template("admin/update_assets.html", v=v, error=error, type="Hat") - if g.is_tor: - return error("Image uploads are not allowed through TOR!") + abort(400, "Image uploads are not allowed through TOR!") if not file or not file.content_type.startswith('image/'): - return error("You need to submit an image!") + abort(400, "You need to submit an image!") if not hat_regex.fullmatch(name): - return error("Invalid name!") + abort(400, "Invalid name!") existing = g.db.query(HatDef.name).filter_by(name=name).one_or_none() if not existing: - return error("A hat with this name doesn't exist!") + abort(400, "A hat with this name doesn't exist!") highquality = f"/asset_submissions/hats/{name}" file.save(highquality) @@ -536,7 +516,7 @@ def update_hat(v): with Image.open(highquality) as i: if i.width > 100 or i.height > 130: os.remove(highquality) - return error("Images must be 100x130") + abort(400, "Images must be 100x130") format = i.format.lower() new_path = f'/asset_submissions/hats/original/{name}.{format}' @@ -557,4 +537,4 @@ def update_hat(v): _note=f'{name}' ) g.db.add(ma) - return render_template("admin/update_assets.html", v=v, msg=f"'{name}' updated successfully!", type="Hat") + return {"message": f"'{name}' updated successfully!"} diff --git a/files/routes/errors.py b/files/routes/errors.py index cca37fe818..f1c6dd4a3e 100644 --- a/files/routes/errors.py +++ b/files/routes/errors.py @@ -67,5 +67,4 @@ def error_500(e): def allow_nsfw(): session["over_18_cookies"] = int(time.time()) + 3600 redir = request.values.get("redir", "/") - if is_site_url(redir): return redirect(redir) - return redirect('/') + return '', 204 diff --git a/files/routes/groups.py b/files/routes/groups.py index bc5d7e3eb5..a5695f09ab 100644 --- a/files/routes/groups.py +++ b/files/routes/groups.py @@ -13,7 +13,7 @@ from files.__main__ import app, limiter @auth_required def ping_groups(v): groups = g.db.query(Group).order_by(Group.created_utc).all() - return render_template('groups.html', v=v, groups=groups, cost=GROUP_COST, msg=get_msg(), error=get_error()) + return render_template('groups.html', v=v, groups=groups, cost=GROUP_COST) @app.post("/create_group") @limiter.limit('1/second', scope=rpath) @@ -27,16 +27,16 @@ def create_group(v): name = name.strip().lower() if name.startswith('slots') or name.startswith('remindme'): - return redirect(f"/ping_groups?error=You can't make a group with that name!") + abort(400, "You can't make a group with that name!") if not valid_sub_regex.fullmatch(name): - return redirect(f"/ping_groups?error=Name does not match the required format!") + abort(400, "Name does not match the required format!") if name in {'everyone', 'jannies', 'followers'} or g.db.get(Group, name): - return redirect(f"/ping_groups?error=This group already exists!") + abort(400, "This group already exists!") if not v.charge_account('combined', GROUP_COST)[0]: - return redirect(f"/ping_groups?error=You don't have enough coins or marseybux!") + abort(403, "You don't have enough coins or marseybux!") g.db.add(v) if v.shadowbanned: abort(500) @@ -56,7 +56,7 @@ def create_group(v): for admin in admins: send_repeatable_notification(admin, f":!marseyparty: !{group} has been created by @{v.username} :marseyparty:") - return redirect(f'/ping_groups?msg=!{group} created successfully!') + return {"message": f"!{group} created successfully!"} @app.post("/!/apply") @limiter.limit('1/second', scope=rpath) diff --git a/files/routes/jinja2.py b/files/routes/jinja2.py index 67813e8b94..01bbb02c43 100644 --- a/files/routes/jinja2.py +++ b/files/routes/jinja2.py @@ -111,8 +111,7 @@ def inject_constants(): "BADGE_THREAD":BADGE_THREAD, "SNAPPY_THREAD":SNAPPY_THREAD, "CHANGELOG_THREAD":CHANGELOG_THREAD, "approved_embed_hosts":approved_embed_hosts, "POST_BODY_LENGTH_LIMIT":POST_BODY_LENGTH_LIMIT, "SITE_SETTINGS":get_settings(), "EMAIL":EMAIL, "max": max, "min": min, "user_can_see":User.can_see, - "TELEGRAM_ID":TELEGRAM_ID, "EMAIL_REGEX_PATTERN":EMAIL_REGEX_PATTERN, - "TRUESCORE_DONATE_MINIMUM":TRUESCORE_DONATE_MINIMUM, "PROGSTACK_ID":PROGSTACK_ID, + "TELEGRAM_ID":TELEGRAM_ID, "TRUESCORE_DONATE_MINIMUM":TRUESCORE_DONATE_MINIMUM, "PROGSTACK_ID":PROGSTACK_ID, "DONATE_LINK":DONATE_LINK, "DONATE_SERVICE":DONATE_SERVICE, "HOUSE_JOIN_COST":HOUSE_JOIN_COST, "HOUSE_SWITCH_COST":HOUSE_SWITCH_COST, "IMAGE_FORMATS":','.join(IMAGE_FORMATS), "PAGE_SIZES":PAGE_SIZES, "THEMES":THEMES, "COMMENT_SORTS":COMMENT_SORTS, "SORTS":SORTS, diff --git a/files/routes/login.py b/files/routes/login.py index 75c8d4dcb1..a64fc9d6b5 100644 --- a/files/routes/login.py +++ b/files/routes/login.py @@ -77,13 +77,13 @@ def login_post(v): try: if now - int(request.values.get("time")) > 600: - return redirect('/login') + return render_template("login/login.html", failed=True, redirect=redir) except: abort(400) formhash = request.values.get("hash") if not validate_hash(f"{account.id}+{request.values.get('time')}+2fachallenge", formhash): - return redirect("/login") + return render_template("login/login.html", failed=True, redirect=redir) if not account.validate_2fa(request.values.get("2fa_token", "").strip()): hash = generate_hash(f"{account.id}+{now}+2fachallenge") diff --git a/files/routes/oauth.py b/files/routes/oauth.py index 0ba6d537ff..963c527fff 100644 --- a/files/routes/oauth.py +++ b/files/routes/oauth.py @@ -95,7 +95,7 @@ def request_api_keys(v): push_notif(admin_ids, 'New notification', body, f'{SITE_FULL}/comment/{new_comment.id}?read=true#context') - return redirect('/settings/apps') + return {"message": "API keys requested successfully!"} @app.post("/delete_app/") @@ -145,8 +145,7 @@ def edit_oauth_app(v, aid): g.db.add(app) - - return redirect('/settings/apps') + return {"message": "App edited successfully!"} @app.post("/admin/app/approve/") diff --git a/files/routes/settings.py b/files/routes/settings.py index 4c6240471d..01bff28a91 100644 --- a/files/routes/settings.py +++ b/files/routes/settings.py @@ -38,7 +38,7 @@ def settings(v): @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID) @auth_required def settings_personal(v): - return render_template("settings/personal.html", v=v, error=get_error(), msg=get_msg()) + return render_template("settings/personal.html", v=v, error=get_error()) @app.delete('/settings/background') @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400) @@ -110,7 +110,7 @@ def settings_personal_post(v): request_flag = int(time.time()) setattr(v, column_name, request_flag) if badge_id: badge_grant(v, badge_id) - return render_template("settings/personal.html", v=v, msg=f"You have set the {friendly_name} permanently! Enjoy your new badge!") + return {"message": f"You have set the {friendly_name} permanently! Enjoy your new badge!"} elif current_value != request_flag: setattr(v, column_name, request_flag) return True @@ -199,25 +199,25 @@ def settings_personal_post(v): v.bio = None v.bio_html = None g.db.add(v) - return render_template("settings/personal.html", v=v, msg="Your bio has been updated!") + return {"message": "Your bio has been updated."} elif not updated and request.values.get("sig") == "": v.sig = None v.sig_html = None g.db.add(v) - return render_template("settings/personal.html", v=v, msg="Your sig has been updated!") + return {"message": "Your sig has been updated."} elif not updated and request.values.get("friends") == "": v.friends = None v.friends_html = None g.db.add(v) - return render_template("settings/personal.html", v=v, msg="Your friends list has been updated!") + return {"message": "Your friends list has been updated."} elif not updated and request.values.get("enemies") == "": v.enemies = None v.enemies_html = None g.db.add(v) - return render_template("settings/personal.html", v=v, msg="Your enemies list has been updated!") + return {"message": "Your enemies list has been updated."} elif not updated and request.values.get("sig"): if not v.patron: @@ -226,16 +226,12 @@ def settings_personal_post(v): sig = request.values.get("sig")[:200].replace('\n','').replace('\r','') sig_html = sanitize(sig, blackjack="signature") if len(sig_html) > 1000: - return render_template("settings/personal.html", - v=v, - error="Your sig is too long") + abort(400, "Your sig is too long") v.sig = sig[:200] v.sig_html=sig_html g.db.add(v) - return render_template("settings/personal.html", - v=v, - msg="Your sig has been updated.") + return {"message": "Your sig has been updated."} elif not updated and FEATURES['USERS_PROFILE_BODYTEXT'] and request.values.get("friends"): friends = request.values.get("friends")[:BIO_FRIENDS_ENEMIES_LENGTH_LIMIT] @@ -243,9 +239,7 @@ def settings_personal_post(v): friends_html = sanitize(friends, blackjack="friends") if len(friends_html) > BIO_FRIENDS_ENEMIES_HTML_LENGTH_LIMIT: - return render_template("settings/personal.html", - v=v, - error="Your friends list is too long") + abort(400, "Your friends list is too long") friends = friends[:BIO_FRIENDS_ENEMIES_LENGTH_LIMIT] @@ -262,9 +256,7 @@ def settings_personal_post(v): v.friends = friends v.friends_html=friends_html g.db.add(v) - return render_template("settings/personal.html", - v=v, - msg="Your friends list has been updated.") + return {"message": "Your friends list has been updated."} elif not updated and FEATURES['USERS_PROFILE_BODYTEXT'] and request.values.get("enemies"): @@ -273,9 +265,7 @@ def settings_personal_post(v): enemies_html = sanitize(enemies, blackjack="enemies") if len(enemies_html) > BIO_FRIENDS_ENEMIES_HTML_LENGTH_LIMIT: - return render_template("settings/personal.html", - v=v, - error="Your enemies list is too long") + abort(400, "Your enemies list is too long") enemies = enemies[:BIO_FRIENDS_ENEMIES_LENGTH_LIMIT] @@ -292,9 +282,7 @@ def settings_personal_post(v): v.enemies = enemies v.enemies_html=enemies_html g.db.add(v) - return render_template("settings/personal.html", - v=v, - msg="Your enemies list has been updated.") + return {"message": "Your enemies list has been updated."} elif not updated and FEATURES['USERS_PROFILE_BODYTEXT'] and \ @@ -305,17 +293,13 @@ def settings_personal_post(v): bio_html = sanitize(bio, blackjack="bio") if len(bio_html) > BIO_FRIENDS_ENEMIES_HTML_LENGTH_LIMIT: - return render_template("settings/personal.html", - v=v, - error="Your bio is too long") + abort(400, "Your bio is too long") v.bio = bio[:BIO_FRIENDS_ENEMIES_LENGTH_LIMIT] v.bio_html=bio_html g.db.add(v) - return render_template("settings/personal.html", - v=v, - msg="Your bio has been updated.") + return {"message": "Your bio has been updated."} frontsize = request.values.get("frontsize") @@ -375,14 +359,15 @@ def filters(v): filters=request.values.get("filters")[:1000].strip() if filters == v.custom_filter_list: - return redirect("/settings/advanced?error=You didn't change anything!") + abort(400, "You didn't change anything!") v.custom_filter_list=filters g.db.add(v) - return redirect("/settings/advanced?msg=Your custom filters have been updated!") + return {"message": "Your custom filters have been updated!"} -def set_color(v, attr, color): +def set_color(v, attr): + color = request.values.get(attr) current = getattr(v, attr) color = color.strip().lower() if color else None if color: @@ -402,7 +387,7 @@ def set_color(v, attr, color): @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID) @auth_required def namecolor(v): - return set_color(v, "namecolor", request.values.get("namecolor")) + return set_color(v, "namecolor") @app.post("/settings/themecolor") @limiter.limit('1/second', scope=rpath) @@ -411,7 +396,7 @@ def namecolor(v): @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID) @auth_required def themecolor(v): - return set_color(v, "themecolor", request.values.get("themecolor")) + return set_color(v, "themecolor") @app.post("/settings/titlecolor") @limiter.limit('1/second', scope=rpath) @@ -420,7 +405,7 @@ def themecolor(v): @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID) @auth_required def titlecolor(v): - return set_color(v, "titlecolor", request.values.get("titlecolor")) + return set_color(v, "titlecolor") @app.post("/settings/verifiedcolor") @limiter.limit('1/second', scope=rpath) @@ -430,7 +415,7 @@ def titlecolor(v): @auth_required def verifiedcolor(v): if not v.verified: abort(403, "You don't have a checkmark to edit its color!") - return set_color(v, "verifiedcolor", request.values.get("verifiedcolor")) + return set_color(v, "verifiedcolor") @app.post("/settings/security") @limiter.limit('1/second', scope=rpath) @@ -441,18 +426,18 @@ def verifiedcolor(v): def settings_security_post(v): if request.values.get("new_password"): if request.values.get("new_password") != request.values.get("cnf_password"): - return render_template("settings/security.html", v=v, error="Passwords do not match!") + abort(400, "Passwords do not match!") if not valid_password_regex.fullmatch(request.values.get("new_password")): - return render_template("settings/security.html", v=v, error="Password must be between 8 and 100 characters!") + abort(400, "Password must be between 8 and 100 characters!") if not v.verifyPass(request.values.get("old_password")): - return render_template("settings/security.html", v=v, error="Incorrect password") + abort(400, "Incorrect password") v.passhash = hash_password(request.values.get("new_password")) g.db.add(v) - return render_template("settings/security.html", v=v, msg="Your password has been changed!") + return {"message": "Your password has been changed successfully!"} if request.values.get("new_email"): if not v.verifyPass(request.values.get('password')): @@ -483,29 +468,29 @@ def settings_security_post(v): if request.values.get("2fa_token"): if not v.verifyPass(request.values.get('password')): - return render_template("settings/security.html", v=v, error="Invalid password!") + abort(400, "Invalid password!") secret = request.values.get("2fa_secret") x = pyotp.TOTP(secret) if not x.verify(request.values.get("2fa_token"), valid_window=1): - return render_template("settings/security.html", v=v, error="Invalid token!") + abort(400, "Invalid token!") v.mfa_secret = secret g.db.add(v) - return render_template("settings/security.html", v=v, msg="Two-factor authentication enabled!") + return {"message": "Two-factor authentication enabled!"} if request.values.get("2fa_remove"): if not v.verifyPass(request.values.get('password')): - return render_template("settings/security.html", v=v, error="Invalid password!") + abort(400, "Invalid password!") token = request.values.get("2fa_remove") if not token or not v.validate_2fa(token): - return render_template("settings/security.html", v=v, error="Invalid token!") + abort(400, "Invalid token!") v.mfa_secret = None g.db.add(v) - return render_template("settings/security.html", v=v, msg="Two-factor authentication disabled!") + return {"message": "Two-factor authentication disabled!"} @app.post("/settings/log_out_all_others") @limiter.limit('1/second', scope=rpath) @@ -516,13 +501,13 @@ def settings_security_post(v): def settings_log_out_others(v): submitted_password = request.values.get("password", "").strip() if not v.verifyPass(submitted_password): - return redirect("/settings/security?error=Incorrect password!") + abort(400, "Incorrect password!") v.login_nonce += 1 session["login_nonce"] = v.login_nonce g.db.add(v) - return redirect("/settings/security?msg=All other devices have been logged out!") + return {"message": "All other devices have been logged out!"} @app.post("/settings/images/profile") @@ -619,7 +604,7 @@ def settings_images_profile_background(v): @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID) @auth_required def settings_css_get(v): - return render_template("settings/css.html", v=v, msg=get_msg(), profilecss=v.profilecss) + return render_template("settings/css.html", v=v, profilecss=v.profilecss) @app.post("/settings/css") @limiter.limit('1/second', scope=rpath) @@ -628,12 +613,12 @@ def settings_css_get(v): @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID) @auth_required def settings_css(v): - if v.chud: abort(400, "Chuded users can't edit CSS!") + if v.chud: + abort(400, "Chudded users can't edit CSS!") css = request.values.get("css", v.css).strip().replace('\\', '')[:CSS_LENGTH_LIMIT].strip() v.css = css g.db.add(v) - - return render_template("settings/css.html", v=v, msg="Custom CSS successfully updated!", profilecss=v.profilecss) + return {"message": "Custom CSS successfully updated!"} @app.post("/settings/profilecss") @limiter.limit('1/second', scope=rpath) @@ -645,10 +630,10 @@ def settings_profilecss(v): profilecss = request.values.get("profilecss", v.profilecss).replace('\\', '')[:CSS_LENGTH_LIMIT].strip() valid, error = validate_css(profilecss) if not valid: - return render_template("settings/css.html", error=error, v=v, profilecss=profilecss) + abort(400, error) v.profilecss = profilecss g.db.add(v) - return redirect("/settings/css?msg=Profile CSS successfully updated!") + return {"message": "Profile CSS successfully updated!"} @app.get("/settings/security") @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400) @@ -659,8 +644,6 @@ def settings_security(v): v=v, mfa_secret=pyotp.random_base32() if not v.mfa_secret else None, now=int(time.time()), - error=get_error(), - msg=get_msg() ) @app.get("/settings/blocks") @@ -726,7 +709,7 @@ def settings_apps(v): @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID) @auth_required def settings_advanced_get(v): - return render_template("settings/advanced.html", v=v, msg=get_msg(), error=get_error()) + return render_template("settings/advanced.html", v=v) @app.post("/settings/name_change") @limiter.limit('1/second', scope=rpath) @@ -745,9 +728,7 @@ def settings_name_change(v): new_name=request.values.get("name").strip() if new_name==v.username: - return render_template("settings/personal.html", - v=v, - error="You didn't change anything") + abort(400, "You didn't change anything") if v.patron: used_regex = valid_username_patron_regex @@ -755,9 +736,7 @@ def settings_name_change(v): used_regex = valid_username_regex if not used_regex.fullmatch(new_name): - return render_template("settings/personal.html", - v=v, - error="This isn't a valid username.") + abort(400, "This isn't a valid username.") search_name = new_name.replace('\\', '').replace('_','\_').replace('%','') @@ -770,15 +749,13 @@ def settings_name_change(v): ).one_or_none() if x and x.id != v.id: - return render_template("settings/personal.html", - v=v, - error=f"Username `{new_name}` is already in use.") + abort(400, f"Username `{new_name}` is already in use.") v.username = new_name v.name_changed_utc = int(time.time()) g.db.add(v) - return redirect("/settings/personal?msg=Name successfully changed!") + return {"message": "Name successfully changed!"} @app.post("/settings/song_change_mp3") @feature_required('USERS_PROFILE_SONG') @@ -904,13 +881,13 @@ def process_settings_plaintext(value, current, length): value = request.values.get(value, "").strip() if not value: - return redirect("/settings/personal?error=You didn't enter anything!") + abort(400, "You didn't enter anything!") if len(value) > 100: - return redirect("/settings/personal?error=The value you entered exceeds the character limit (100 characters)") + abort(400, "The value you entered exceeds the character limit (100 characters)") if value == current: - return redirect("/settings/personal?error=You didn't change anything!") + abort(400, "You didn't change anything!") return value @@ -924,21 +901,19 @@ def process_settings_plaintext(value, current, length): def settings_title_change(v): if v.flairchanged: abort(403) - processed = process_settings_plaintext("title", v.customtitleplain, 100) - if not isinstance(processed, str): - return processed + customtitleplain = process_settings_plaintext("title", v.customtitleplain, 100) - customtitle = filter_emojis_only(processed) + customtitle = filter_emojis_only(customtitleplain) customtitle = censor_slurs(customtitle, None) if len(customtitle) > 1000: - return redirect("/settings/personal?error=Flair too long!") + abort(400, "Flair too long!") - v.customtitleplain = processed + v.customtitleplain = customtitleplain v.customtitle = customtitle g.db.add(v) - return redirect("/settings/personal?msg=Flair successfully updated!") + return {"message": "Flair successfully updated!"} @app.post("/settings/pronouns_change") @@ -949,13 +924,10 @@ def settings_title_change(v): @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID) @auth_required def settings_pronouns_change(v): - processed = process_settings_plaintext("pronouns", v.pronouns, 15) - if not isinstance(processed, str): - return processed + pronouns = process_settings_plaintext("pronouns", v.pronouns, 15) - pronouns = processed if not pronouns_regex.fullmatch(pronouns): - return redirect("/settings/personal?error=The pronouns you entered don't match the required format!") + abort(400, "The pronouns you entered don't match the required format!") bare_pronouns = pronouns.lower().replace('/', '') if 'nig' in bare_pronouns: pronouns = 'BI/POC' @@ -964,7 +936,7 @@ def settings_pronouns_change(v): v.pronouns = pronouns g.db.add(v) - return redirect("/settings/personal?msg=Pronouns successfully updated!") + return {"message": "Pronouns successfully updated!"} @app.post("/settings/checkmark_text") @@ -977,10 +949,6 @@ def settings_checkmark_text(v): if not v.verified: abort(403, "You don't have a checkmark to edit its hover text!") - processed = process_settings_plaintext("checkmark-text", v.verified, 100) - if not isinstance(processed, str): - return processed - - v.verified = processed + v.verified = process_settings_plaintext("checkmark-text", v.verified, 100) g.db.add(v) - return redirect("/settings/personal?msg=Checkmark Text successfully updated!") + return {"message": "Checkmark Text successfully updated!"} diff --git a/files/routes/static.py b/files/routes/static.py index 4e83781187..d7c09bf0ba 100644 --- a/files/routes/static.py +++ b/files/routes/static.py @@ -260,7 +260,7 @@ def api(v): @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400) @auth_desired def contact(v): - return render_template("contact.html", v=v, msg=get_msg()) + return render_template("contact.html", v=v) @app.post("/contact") @limiter.limit('1/second', scope=rpath) @@ -304,7 +304,7 @@ def submit_contact(v): push_notif(admin_ids, f'New modmail from @{new_comment.author_name}', new_comment.body, f'{SITE_FULL}/notifications/modmail') - return redirect("/contact?msg=Your message has been sent to the admins!") + return {"message": "Your message has been sent to the admins!"} patron_badges = (22,23,24,25,26,27,28,257,258,259,260,261) diff --git a/files/routes/subs.py b/files/routes/subs.py index e71722cbb2..5fc6c64924 100644 --- a/files/routes/subs.py +++ b/files/routes/subs.py @@ -87,7 +87,7 @@ def unexile(v, sub, uid): u = get_account(uid) if not v.mods(sub): abort(403) - if v.shadowbanned: return redirect(f'/h/{sub}/exilees') + if v.shadowbanned: abort(403) if u.exiler_username(sub): exile = g.db.query(Exile).filter_by(user_id=u.id, sub=sub).one_or_none() @@ -103,11 +103,7 @@ def unexile(v, sub, uid): ) g.db.add(ma) - if g.is_api_or_xhr: - return {"message": f"@{u.username} has been unexiled from /h/{sub} successfully!"} - - - return redirect(f'/h/{sub}/exilees') + return {"message": f"@{u.username} has been unexiled from /h/{sub} successfully!"} @app.post("/h//block") @limiter.limit('1/second', scope=rpath) @@ -275,7 +271,7 @@ def add_mod(v, sub): if SITE_NAME == 'WPD': abort(403) sub = get_sub_by_name(sub).name if not v.mods(sub): abort(403) - if v.shadowbanned: return redirect(f'/h/{sub}/mods') + if v.shadowbanned: abort(400) user = request.values.get('user') @@ -303,7 +299,7 @@ def add_mod(v, sub): ) g.db.add(ma) - return redirect(f'/h/{sub}/mods') + return {"message": "Mod added successfully!"} @app.post("/h//remove_mod") @limiter.limit('1/second', scope=rpath) @@ -356,7 +352,7 @@ def create_sub(v): if not v.can_create_hole: abort(403) - return render_template("sub/create_hole.html", v=v, cost=HOLE_COST, error=get_error()) + return render_template("sub/create_hole.html", v=v, cost=HOLE_COST) @app.post("/create_hole") @limiter.limit('1/second', scope=rpath) @@ -373,15 +369,15 @@ def create_sub2(v): name = name.strip().lower() if not valid_sub_regex.fullmatch(name): - return redirect(f"/create_hole?error=Name does not match the required format!") + abort(400, "Name does not match the required format!") if not v.charge_account('combined', HOLE_COST)[0]: - return redirect(f"/create_hole?error=You don't have enough coins or marseybux!") + abort(400, "You don't have enough coins or marseybux!") sub = get_sub_by_name(name, graceful=True) if sub: - return redirect(f"/create_hole?error=/h/{sub} already exists!") + abort(400, f"/h/{sub} already exists!") g.db.add(v) if v.shadowbanned: abort(500) @@ -396,7 +392,7 @@ def create_sub2(v): for admin in admins: send_repeatable_notification(admin, f":!marseyparty: /h/{sub} has been created by @{v.username} :marseyparty:") - return redirect(f'/h/{sub}') + return {"message": f"/h/{sub} created successfully!"} @app.post("/kick/") @limiter.limit('1/second', scope=rpath) @@ -452,13 +448,13 @@ def sub_settings(v, sub): def post_sub_sidebar(v, sub): sub = get_sub_by_name(sub) if not v.mods(sub.name): abort(403) - if v.shadowbanned: return redirect(f'/h/{sub}/settings') + if v.shadowbanned: abort(400) sub.sidebar = request.values.get('sidebar', '')[:10000].strip() sidebar_html = sanitize(sub.sidebar, blackjack=f"/h/{sub} sidebar") if len(sidebar_html) > 20000: - return render_template('sub/settings.html', v=v, sidebar=sub.sidebar, sub=sub, error="Sidebar is too big!", css=sub.css) + abort(400, "Sidebar is too big! (max 20000 characters)") sub.sidebar_html = sidebar_html g.db.add(sub) @@ -470,7 +466,7 @@ def post_sub_sidebar(v, sub): ) g.db.add(ma) - return render_template('sub/settings.html', v=v, sidebar=sub.sidebar, sub=sub, msg='CSS changed successfully!', css=sub.css) + return {"message": "Sidebar changed successfully!"} @app.post('/h//css') @@ -485,15 +481,14 @@ def post_sub_css(v, sub): if not sub: abort(404) if not v.mods(sub.name): abort(403) - if v.shadowbanned: return redirect(f'/h/{sub}/settings') + if v.shadowbanned: abort(400) if len(css) > 6000: - error = "CSS is too long (max 6000 characters)" - return render_template('sub/settings.html', v=v, sidebar=sub.sidebar, sub=sub, error=error, css=css) + abort(400, "CSS is too long (max 6000 characters)") valid, error = validate_css(css) if not valid: - return render_template('sub/settings.html', v=v, sidebar=sub.sidebar, sub=sub, error=error, css=css) + abort(400, error) sub.css = css g.db.add(sub) @@ -505,7 +500,7 @@ def post_sub_css(v, sub): ) g.db.add(ma) - return render_template('sub/settings.html', v=v, sidebar=sub.sidebar, sub=sub, msg='CSS changed successfully!', css=sub.css) + return {"message": "CSS changed successfully!"} @app.get("/h//css") @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400) diff --git a/files/routes/users.py b/files/routes/users.py index 7840a37366..aea0731982 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -1374,9 +1374,7 @@ def toggle_pins(sub, sort): pins = session.get(f'{sub}_{sort}', default) session[f'{sub}_{sort}'] = not pins - if is_site_url(request.referrer): - return redirect(request.referrer) - return redirect('/') + return {"message": "Pins toggled successfully!"} @app.get("/badge_owners/") diff --git a/files/templates/admin/app.html b/files/templates/admin/app.html index 0ce6669cc3..34ea611c4e 100644 --- a/files/templates/admin/app.html +++ b/files/templates/admin/app.html @@ -63,17 +63,4 @@ -
-
- Action successful! -
-
-
-
- Error, please try again later. -
-
- - - {% endblock %} diff --git a/files/templates/admin/apps.html b/files/templates/admin/apps.html index 7de1483c84..f027a4f278 100644 --- a/files/templates/admin/apps.html +++ b/files/templates/admin/apps.html @@ -51,17 +51,4 @@ -
-
- Action successful! -
-
-
-
- Error, please try again later. -
-
- - - {% endblock %} diff --git a/files/templates/admin/badge_admin.html b/files/templates/admin/badge_admin.html index dfd23e660b..df2e322d27 100644 --- a/files/templates/admin/badge_admin.html +++ b/files/templates/admin/badge_admin.html @@ -5,12 +5,9 @@ -{% if error %}{{macros.alert(error, true)}}{% endif %} -{% if msg %}{{macros.alert(msg, false)}}{% endif %} - {% set form_action = "/admin/badge_grant" if grant else "/admin/badge_remove" %} -
+
diff --git a/files/templates/admin/banned_domains.html b/files/templates/admin/banned_domains.html index 294eaed6ab..924c266ddd 100644 --- a/files/templates/admin/banned_domains.html +++ b/files/templates/admin/banned_domains.html @@ -29,7 +29,7 @@
- + diff --git a/files/templates/admin/delete_media.html b/files/templates/admin/delete_media.html index 12fd91800c..966ed81d59 100644 --- a/files/templates/admin/delete_media.html +++ b/files/templates/admin/delete_media.html @@ -3,9 +3,7 @@ {% block pagetitle %}Delete Media{% endblock %} {% block content %} -{% if error %}{{macros.alert(error, true)}}{% endif %} -{% if msg %}{{macros.alert(msg, false)}}{% endif %} - +
diff --git a/files/templates/admin/edit_rules.html b/files/templates/admin/edit_rules.html index d7225362dc..1c9f3a3339 100644 --- a/files/templates/admin/edit_rules.html +++ b/files/templates/admin/edit_rules.html @@ -3,7 +3,6 @@ {% block pagetitle %}Edit {{SITE_NAME}}'s rules{% endblock %} {% block content %} -{% if msg %}{{macros.alert(msg, false)}}{% endif %}
@@ -13,7 +12,7 @@
- + diff --git a/files/templates/admin/orgy_control.html b/files/templates/admin/orgy_control.html index 006644079f..27b31ae84d 100644 --- a/files/templates/admin/orgy_control.html +++ b/files/templates/admin/orgy_control.html @@ -3,7 +3,6 @@ {% block pagetitle %}Orgy Control Panel{% endblock %} {% block content %} -{% if msg %}{{macros.alert(msg, false)}}{% endif %}
@@ -14,7 +13,7 @@
{%if not orgy%} - +
@@ -37,7 +36,7 @@
{%else%} -
+
diff --git a/files/templates/admin/update_assets.html b/files/templates/admin/update_assets.html index b540d8e655..da431ab487 100644 --- a/files/templates/admin/update_assets.html +++ b/files/templates/admin/update_assets.html @@ -2,15 +2,12 @@ {% block pagetitle %}Update {{type}}{% endblock %} {% block pagetype %}message{% endblock %} {% block content %} - {% if error %}{{macros.alert(error, true)}}{% endif %} - {% if msg %}{{macros.alert(msg, false)}}{% endif %} -

Update {{type}}

- + diff --git a/files/templates/chat.html b/files/templates/chat.html index f0c348668b..8e03c9f421 100644 --- a/files/templates/chat.html +++ b/files/templates/chat.html @@ -28,17 +28,6 @@ {{macros.chat_users_list()}}
- -
-
- Action successful! -
-
-
-
- Error, please try again later. -
-
diff --git a/files/templates/comments.html b/files/templates/comments.html index 0b9db4971b..c9247000b9 100644 --- a/files/templates/comments.html +++ b/files/templates/comments.html @@ -24,35 +24,30 @@ {% endif %} {% if c.is_blocking and not c.ghost or (c.is_banned or c.deleted_utc) and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']) and not (v and v.id==c.author_id) %} -
- - -
-
- -
- - {% if render_replies %} -
- {% if level<9 or request.path.startswith('/notifications') %} - {% for reply in replies %} - {{single_comment(reply, level=level+1)}} - {% endfor %} - {% elif replies %} - - More comments - {% endif %} + +
+
+
- {% endif %} + {% if render_replies %} +
+ {% if level<9 or request.path.startswith('/notifications') %} + {% for reply in replies %} + {{single_comment(reply, level=level+1)}} + {% endfor %} + {% elif replies %} + + More comments + {% endif %} +
+ {% endif %} +
-
- - {% else %} {% set score=c.score %} diff --git a/files/templates/contact.html b/files/templates/contact.html index 9f0be1bfbb..4502b41209 100644 --- a/files/templates/contact.html +++ b/files/templates/contact.html @@ -1,10 +1,9 @@ {% extends "default.html" %} {% block pagetitle %}Contact{% endblock %} {% block content %} - {% if msg %}{{macros.alert(msg, false)}}{% endif %}

Contact {{SITE_NAME}} Admins

{% if v %} - + diff --git a/files/templates/default.html b/files/templates/default.html index bf78217343..ee9f1e86c5 100644 --- a/files/templates/default.html +++ b/files/templates/default.html @@ -100,16 +100,6 @@ Link copied to clipboard
-
-
- Action successful! -
-
-
-
- Error, please try again later. -
-
diff --git a/files/templates/errors/nsfw.html b/files/templates/errors/nsfw.html index d114f30b2c..0a4cd002ee 100644 --- a/files/templates/errors/nsfw.html +++ b/files/templates/errors/nsfw.html @@ -9,15 +9,13 @@
Are you over 18?

This post is rated +18 (Adult-Only). You must be 18 or older to continue. Are you sure you want to proceed?

-
diff --git a/files/templates/groups.html b/files/templates/groups.html index 480edf01d4..aff8376201 100644 --- a/files/templates/groups.html +++ b/files/templates/groups.html @@ -1,8 +1,6 @@ {% extends "default.html" %} {% block pagetitle %}Ping Groups{% endblock %} {% block content %} -{% if error %}{{macros.alert(error, true)}}{% endif %} -{% if msg %}{{macros.alert(msg, false)}}{% endif %}

Ping Groups

@@ -43,7 +41,7 @@

Create Ping Group

-
+
@@ -54,11 +52,6 @@ 3-25 characters, including letters, numbers, _ , and -
- -
-
- Action successful! -
-
-
-
- Error, please try again later. -
-
diff --git a/files/templates/root.html b/files/templates/root.html index 40fed76366..c1acfb69ad 100644 --- a/files/templates/root.html +++ b/files/templates/root.html @@ -1,6 +1,5 @@ {% set root_scope = namespace() %} {% block template_config %} - {% set root_scope.js = true %} {% set root_scope.include_user_css = true %} {% set root_scope.include_seo = true %} {% set root_scope.include_cf_2fa_verify = false %} @@ -21,7 +20,7 @@ {% block title %}{% block pagetitle %}if you see this pls report it as a bug <3{% endblock %} - {{SITE_NAME}}{% endblock %} {{html_head.page_meta(self.pagetitle() or none)}} - {{html_head.javascript() if root_scope.js}} + {{html_head.javascript()}} {{html_head.stylesheets(root_scope.include_user_css)}} {{html_head.seo() if root_scope.include_seo}} {{html_head.cf_2fa_verify() if root_scope.include_2fa_verify}} @@ -45,5 +44,15 @@ {% endif %} +
+
+ Action successful! +
+
+
+
+ Error, please try again later. +
+
diff --git a/files/templates/settings.html b/files/templates/settings.html index 9ff99dd8a0..e490b1d4eb 100644 --- a/files/templates/settings.html +++ b/files/templates/settings.html @@ -50,16 +50,6 @@
{% endblock %} -
-
- Action successful! -
-
-
-
- Error, please try again later. -
-
{% block onload %}{% endblock %} {% endblock %} diff --git a/files/templates/settings/advanced.html b/files/templates/settings/advanced.html index ac7cd89f25..c8cd4ffc4f 100644 --- a/files/templates/settings/advanced.html +++ b/files/templates/settings/advanced.html @@ -140,7 +140,7 @@
-
+ Hides matching posts from the frontpage and collapses matching comments. {% if show_extras %} diff --git a/files/templates/settings/css.html b/files/templates/settings/css.html index a5357b341f..fbda8e2eff 100644 --- a/files/templates/settings/css.html +++ b/files/templates/settings/css.html @@ -9,7 +9,7 @@

Edit your custom CSS for the site

- + Limit of {{CSS_LENGTH_LIMIT}} characters @@ -27,7 +27,7 @@

Edit your profile CSS

- + Limit of {{CSS_LENGTH_LIMIT}} characters diff --git a/files/templates/settings/personal.html b/files/templates/settings/personal.html index 8f35fa1544..4c6842e9de 100644 --- a/files/templates/settings/personal.html +++ b/files/templates/settings/personal.html @@ -16,10 +16,8 @@

You're a {{TIER_TO_NAME[v.patron] if v.patron else "freeloader"}}!

{% if v.patron %} Thanks ily! <3{% endif %} - {% if not v.patron and v.truescore >= TRUESCORE_DONATE_MINIMUM %} -

To stop freeloading, first verify your email, support us on {{DONATE_SERVICE}} with the same email, and click "Claim {{patron}} Rewards"

- {% elif not v.patron %} -

To stop freeloading, you can donate via crypto. Please let us know first beforehand by sending us a modmail. Thanks!

+ {% if not v.patron %} +

To stop freeloading, support us here

{% endif %}
@@ -186,7 +184,7 @@

Your original username will always stay reserved for you: {{v.original_username}}

- + {% if v.patron %}1{% else %}3{% endif %}-25 characters, including letters, numbers, _ , and - @@ -332,7 +330,7 @@ {% if FEATURES['USERS_PERMANENT_WORD_FILTERS'] -%}