diff --git a/files/assets/images/rDrama/sidebar/821.webp b/files/assets/images/rDrama/sidebar/821.webp new file mode 100644 index 000000000..fe13d57b1 Binary files /dev/null and b/files/assets/images/rDrama/sidebar/821.webp differ diff --git a/files/assets/js/award_modal.js b/files/assets/js/award_modal.js index a597d0a21..48c2307d1 100644 --- a/files/assets/js/award_modal.js +++ b/files/assets/js/award_modal.js @@ -157,6 +157,7 @@ function buy(mb) { } else { document.getElementById('toast-post-error-text').innerText = "Error, please try again later." if (data && data["error"]) document.getElementById('toast-post-error-text2').innerText = data["error"]; + if (data && data["details"]) document.getElementById('toast-post-error-text2').innerText = data["details"]; bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error2')).show(); } }; diff --git a/files/assets/js/ban_modal.js b/files/assets/js/ban_modal.js index 6be925fff..fbc49a1e5 100644 --- a/files/assets/js/ban_modal.js +++ b/files/assets/js/ban_modal.js @@ -21,6 +21,7 @@ function banModal(link, id, name) { } 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(); } }; diff --git a/files/assets/js/comments_admin.js b/files/assets/js/comments_admin.js index 4de331e8b..230463842 100644 --- a/files/assets/js/comments_admin.js +++ b/files/assets/js/comments_admin.js @@ -91,6 +91,7 @@ function adminMuteUser(userId, muteStatus, buttonId) { } 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(); } }; diff --git a/files/assets/js/comments_v.js b/files/assets/js/comments_v.js index 6daf15851..d0b2ebeb7 100644 --- a/files/assets/js/comments_v.js +++ b/files/assets/js/comments_v.js @@ -46,6 +46,7 @@ function report_commentModal(id, author) { } 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(); } }; @@ -121,6 +122,7 @@ function delete_commentModal(id) { } 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(); } }; @@ -169,6 +171,7 @@ function post_reply(id){ else { if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"]; else document.getElementById('toast-post-error-text').innerText = "Error, please try again later." + if (data && data["details"]) document.getElementById('toast-post-error-text').innerText = data["details"]; bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show(); } setTimeout(() => { @@ -212,6 +215,7 @@ function comment_edit(id){ else { if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"]; else document.getElementById('toast-post-error-text').innerText = "Error, please try again later." + if (data && data["details"]) document.getElementById('toast-post-error-text').innerText = data["details"]; bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show(); } setTimeout(() => { @@ -271,6 +275,7 @@ function post_comment(fullname, hide){ else { if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"]; else document.getElementById('toast-post-error-text').innerText = "Error, please try again later." + if (data && data["details"]) document.getElementById('toast-post-error-text').innerText = data["details"]; bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show(); setTimeout(() => { btn.disabled = false; @@ -360,6 +365,7 @@ function handle_action(type, cid, thing) { else { if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"]; else document.getElementById('toast-post-error-text').innerText = "Error, please try again later." + if (data && data["details"]) document.getElementById('toast-post-error-text').innerText = data["details"]; bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show(); } setTimeout(() => { diff --git a/files/assets/js/delete_post_modal.js b/files/assets/js/delete_post_modal.js index 4d6d7ee26..5b7b9c006 100644 --- a/files/assets/js/delete_post_modal.js +++ b/files/assets/js/delete_post_modal.js @@ -20,6 +20,7 @@ function delete_postModal(id) { } 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(); } }; diff --git a/files/assets/js/report_post_modal.js b/files/assets/js/report_post_modal.js index 555599e74..18958f1d4 100644 --- a/files/assets/js/report_post_modal.js +++ b/files/assets/js/report_post_modal.js @@ -45,6 +45,7 @@ function report_postModal(id) { } 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(); } }; diff --git a/files/assets/js/userpage_v.js b/files/assets/js/userpage_v.js index 13623ce92..02aa3bf99 100644 --- a/files/assets/js/userpage_v.js +++ b/files/assets/js/userpage_v.js @@ -120,6 +120,7 @@ function submitFormAjax(e) { var myToast = bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')); myToast.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) { var myToast = bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-success')); myToast.hide(); diff --git a/files/classes/comment.py b/files/classes/comment.py index a4303f370..ee4de4724 100644 --- a/files/classes/comment.py +++ b/files/classes/comment.py @@ -10,6 +10,7 @@ from files.classes.votes import CommentVote from files.helpers.const import * from files.helpers.regex import * from files.helpers.lazy import lazy +from files.helpers.sorting_and_time import * from .flags import CommentFlag from .votes import CommentVote from .saves import CommentSaveRelationship @@ -17,31 +18,6 @@ from random import randint from math import floor -def sort_objects(sort, objects, Class, v): - if not (v and v.can_see_shadowbanned): - objects = objects.join(Class.author).filter(User.shadowbanned == None) - - if sort == 'hot': - ti = int(time.time()) + 3600 - if SITE_NAME == 'rDrama': metric = Class.realupvotes - else: metric = Class.upvotes - Class.downvotes - if Class.__name__ == "Submission": metric += Class.comment_count/5 - return objects.order_by(-1000000*(metric + 1)/(func.power(((ti - Class.created_utc)/1000), 1.23)), Class.created_utc.desc()) - elif sort == "bump" and Class.__name__ == "Submission": - return objects.filter(Class.comment_count > 1).order_by(Class.bump_utc.desc(), Class.created_utc.desc()) - elif sort == "comments" and Class.__name__ == "Submission": - return objects.order_by(Class.comment_count.desc(), Class.created_utc.desc()) - elif sort == "new": - return objects.order_by(Class.created_utc.desc()) - elif sort == "old": - return objects.order_by(Class.created_utc) - elif sort == "controversial": - return objects.order_by((Class.upvotes+1)/(Class.downvotes+1) + (Class.downvotes+1)/(Class.upvotes+1), Class.downvotes.desc(), Class.created_utc.desc()) - elif sort == "bottom": - return objects.order_by(Class.upvotes - Class.downvotes, Class.created_utc.desc()) - else: - return objects.order_by(Class.downvotes - Class.upvotes, Class.created_utc.desc()) - def normalize_urls_runtime(body, v): if not v: return body @@ -238,7 +214,8 @@ class Comment(Base): if not self.parent_submission: sort='old' - return sort_objects(sort, replies, Comment, v) + return sort_objects(sort, replies, Comment, + include_shadowbanned=(not (v and v.can_see_shadowbanned))) @property diff --git a/files/classes/user.py b/files/classes/user.py index 33415d3ec..96c984004 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -7,7 +7,6 @@ from files.helpers.media import * from files.helpers.const import * from files.classes.casino_game import Casino_Game from files.helpers.sorting_and_time import * -from files.classes.comment import sort_objects from .alts import Alt from .saves import * from .notifications import Notification @@ -479,7 +478,8 @@ class User(Base): posts = apply_time_filter(t, posts, Submission) - posts = sort_objects(sort, posts, Submission, v) + posts = sort_objects(sort, posts, Submission, + include_shadowbanned=(not (v and v.can_see_shadowbanned))) posts = posts.offset(25 * (page - 1)).limit(26).all() diff --git a/files/helpers/const.py b/files/helpers/const.py index 4ac20673d..d002df3e5 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -282,11 +282,9 @@ ERROR_TITLES = { 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)", + 413: "Payload Too Large", 415: "Unsupported Media Type", - 417: "Image already exists!", - 418: "WEBM videos are not allowed", + 418: "I'm a teapot", 429: "Too Many Requests", 500: "Internal Server Error", } @@ -299,11 +297,9 @@ ERROR_MSGS = { 405: "idk how anyone gets this error but if you see this, remember to follow @carpathianflorist
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)", + 413: "That's a heckin' chonker of a file! Please make it smaller or maybe like upload it somewhere else idk", 415: "Please upload only Image, Video, or Audio files!", - 417: "Image already exists!", - 418: "Please convert your video to MP4 and re-upload it!", + 418: "this really shouldn't happen now that we autoconvert webm files but if it does there's a cool teapot marsey so there's that", 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 but not other pages, 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", } @@ -316,8 +312,7 @@ ERROR_MARSEYS = { 405: "marseyretard", 406: "marseyrage", 409: "marseynoyou", - 413: "marseyretard", - 414: "marseychonker2", + 413: "marseychonker2", 415: "marseydetective", 418: "marseytea", 429: "marseyrentfree", @@ -396,8 +391,8 @@ SIGNUP_FOLLOW_ID = 0 NOTIFICATION_THREAD = 1 MAX_IMAGE_SIZE_BANNER_RESIZED_MB = 1 -MAX_IMAGE_SIZE_MB = 8 -MAX_IMAGE_SIZE_MB_PATRON = 16 +MAX_IMAGE_AUDIO_SIZE_MB = 8 +MAX_IMAGE_AUDIO_SIZE_MB_PATRON = 16 MAX_VIDEO_SIZE_MB = 32 MAX_VIDEO_SIZE_MB_PATRON = 64 diff --git a/files/helpers/media.py b/files/helpers/media.py index cabc4324d..133e75c27 100644 --- a/files/helpers/media.py +++ b/files/helpers/media.py @@ -43,9 +43,9 @@ def process_audio(file): file.save(name) size = os.stat(name).st_size - if size > MAX_IMAGE_SIZE_MB_PATRON * 1024 * 1024 or not g.v.patron and size > MAX_IMAGE_SIZE_MB * 1024 * 1024: + if size > MAX_IMAGE_AUDIO_SIZE_MB_PATRON * 1024 * 1024 or not g.v.patron and size > MAX_IMAGE_AUDIO_SIZE_MB * 1024 * 1024: os.remove(name) - abort(413) + abort(413, f"Max image/audio size is {MAX_IMAGE_AUDIO_SIZE_MB} MB ({MAX_IMAGE_AUDIO_SIZE_MB_PATRON} MB for paypigs)") media = g.db.query(Media).filter_by(filename=name, kind='audio').one_or_none() if media: g.db.delete(media) @@ -92,7 +92,7 @@ def process_video(file): size = os.stat(old).st_size if SITE_NAME != 'WPD' and (size > MAX_VIDEO_SIZE_MB * 1024 * 1024 or not g.v.patron and size > MAX_VIDEO_SIZE_MB_PATRON * 1024 * 1024): os.remove(old) - abort(414) + abort(413, f"Max video size is {MAX_VIDEO_SIZE_MB} MB ({MAX_VIDEO_SIZE_MB_PATRON} MB for paypigs)") extension = file.filename.split('.')[-1].lower() if extension not in ['avi', 'mp4', 'webm', 'm4v', 'mov', 'mkv']: @@ -125,9 +125,9 @@ def process_video(file): def process_image(filename=None, resize=0, trim=False, uploader=None, patron=False, db=None): size = os.stat(filename).st_size - if size > MAX_IMAGE_SIZE_MB_PATRON * 1024 * 1024 or not patron and size > MAX_IMAGE_SIZE_MB * 1024 * 1024: + if size > MAX_IMAGE_AUDIO_SIZE_MB_PATRON * 1024 * 1024 or not patron and size > MAX_IMAGE_AUDIO_SIZE_MB * 1024 * 1024: os.remove(filename) - abort(413) + abort(413, f"Max image/audio size is {MAX_IMAGE_AUDIO_SIZE_MB} MB ({MAX_IMAGE_AUDIO_SIZE_MB_PATRON} MB for paypigs)") i = Image.open(filename) @@ -156,7 +156,7 @@ def process_image(filename=None, resize=0, trim=False, uploader=None, patron=Fal if resize in (300,400,1200): if os.stat(filename).st_size > MAX_IMAGE_SIZE_BANNER_RESIZED_MB * 1024 * 1024: os.remove(filename) - abort(413) + abort(413, f"Max size for banners, sidebars, and badges is {MAX_IMAGE_SIZE_BANNER_RESIZED_MB}") if resize == 1200: path = f'files/assets/images/{SITE_NAME}/banners' @@ -182,7 +182,7 @@ def process_image(filename=None, resize=0, trim=False, uploader=None, patron=Fal i_hash = str(imagehash.phash(i)) if i_hash in hashes.keys(): os.remove(filename) - abort(417) + abort(409, "Image already exists!") db = db or g.db diff --git a/files/helpers/sorting_and_time.py b/files/helpers/sorting_and_time.py index 4d7a4e9b0..0dc6691e3 100644 --- a/files/helpers/sorting_and_time.py +++ b/files/helpers/sorting_and_time.py @@ -1,10 +1,8 @@ import time -from files.classes.comment import Comment -from files.classes.submission import Submission from files.helpers.const import * from sqlalchemy.sql import func -def apply_time_filter(t, objects, Class): +def apply_time_filter(t, objects, cls): now = int(time.time()) if t == 'hour': cutoff = now - 3600 @@ -19,4 +17,30 @@ def apply_time_filter(t, objects, Class): else: cutoff = 0 - return objects.filter(Class.created_utc >= cutoff) + return objects.filter(cls.created_utc >= cutoff) + +def sort_objects(sort, objects, cls, include_shadowbanned=False): + if not include_shadowbanned: + cls_user = cls.__mapper__.relationships['author'].entity.entity + objects = objects.join(cls.author).filter(cls_user.shadowbanned == None) + + if sort == 'hot': + ti = int(time.time()) + 3600 + if SITE_NAME == 'rDrama': metric = cls.realupvotes + else: metric = cls.upvotes - cls.downvotes + if cls.__name__ == "Submission": metric += cls.comment_count/5 + return objects.order_by(-1000000*(metric + 1)/(func.power(((ti - cls.created_utc)/1000), 1.23)), cls.created_utc.desc()) + elif sort == "bump" and cls.__name__ == "Submission": + return objects.filter(cls.comment_count > 1).order_by(cls.bump_utc.desc(), cls.created_utc.desc()) + elif sort == "comments" and cls.__name__ == "Submission": + return objects.order_by(cls.comment_count.desc(), cls.created_utc.desc()) + elif sort == "new": + return objects.order_by(cls.created_utc.desc()) + elif sort == "old": + return objects.order_by(cls.created_utc) + elif sort == "controversial": + return objects.order_by((cls.upvotes+1)/(cls.downvotes+1) + (cls.downvotes+1)/(cls.upvotes+1), cls.downvotes.desc(), cls.created_utc.desc()) + elif sort == "bottom": + return objects.order_by(cls.upvotes - cls.downvotes, cls.created_utc.desc()) + else: + return objects.order_by(cls.downvotes - cls.upvotes, cls.created_utc.desc()) diff --git a/files/routes/errors.py b/files/routes/errors.py index fe311bb6c..db6c80c1d 100644 --- a/files/routes/errors.py +++ b/files/routes/errors.py @@ -17,9 +17,7 @@ from files.__main__ import app, limiter @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): @@ -30,7 +28,7 @@ def error(e): 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} + return {"error": title, "code": e.code, "description": msg, "details": details}, e.code 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 @@ -47,8 +45,6 @@ def error_401(e): @app.errorhandler(500) def error_500(e): - if not g: print("500: not g") - if not g.db: print("500: not g.db") g.db.rollback() return error(e) diff --git a/files/routes/front.py b/files/routes/front.py index 0405dfb08..e200142de 100644 --- a/files/routes/front.py +++ b/files/routes/front.py @@ -3,7 +3,6 @@ from files.helpers.get import * from files.helpers.discord import * from files.helpers.const import * from files.helpers.sorting_and_time import * -from files.classes.comment import sort_objects from files.__main__ import app, cache, limiter from files.classes.submission import Submission from files.helpers.awards import award_timers @@ -116,7 +115,8 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, ccmode="false" if not (v and v.shadowbanned): posts = posts.join(Submission.author).filter(User.shadowbanned == None) - posts = sort_objects(sort, posts, Submission, v) + posts = sort_objects(sort, posts, Submission, + include_shadowbanned=(not (v and v.can_see_shadowbanned))) if v: size = v.frontsize or 0 else: size = 25 @@ -236,7 +236,8 @@ def comment_idlist(page=1, v=None, nsfw=False, sort="new", t="all", gt=0, lt=0, if not gt and not lt: comments = apply_time_filter(t, comments, Comment) - comments = sort_objects(sort, comments, Comment, v) + comments = sort_objects(sort, comments, Comment, + include_shadowbanned=(not (v and v.can_see_shadowbanned))) comments = comments.offset(25 * (page - 1)).limit(26).all() return [x[0] for x in comments] diff --git a/files/routes/posts.py b/files/routes/posts.py index ff4b9a699..7b474197c 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -11,7 +11,6 @@ from files.helpers.slots import * from files.helpers.get import * from files.helpers.actions import * from files.helpers.sorting_and_time import * -from files.classes.comment import sort_objects from files.classes import * from flask import * from io import BytesIO @@ -197,7 +196,8 @@ def post_id(pid, anything=None, v=None, sub=None): comments = comments.filter(Comment.level == 1, Comment.stickied == None) - comments = sort_objects(sort, comments, Comment, v) + comments = sort_objects(sort, comments, Comment, + include_shadowbanned=(not (v and v.can_see_shadowbanned))) comments = [c[0] for c in comments.all()] else: @@ -205,7 +205,8 @@ def post_id(pid, anything=None, v=None, sub=None): comments = g.db.query(Comment).join(Comment.author).filter(User.shadowbanned == None, Comment.parent_submission == post.id, Comment.level == 1, Comment.stickied == None) - comments = sort_objects(sort, comments, Comment, v) + comments = sort_objects(sort, comments, Comment, + include_shadowbanned=(not (v and v.can_see_shadowbanned))) comments = comments.all() @@ -317,13 +318,15 @@ def viewmore(v, pid, sort, offset): comments = comments.filter(Comment.level == 1) - comments = sort_objects(sort, comments, Comment, v) + comments = sort_objects(sort, comments, Comment, + include_shadowbanned=(not (v and v.can_see_shadowbanned))) comments = [c[0] for c in comments.all()] else: comments = g.db.query(Comment).join(Comment.author).filter(User.shadowbanned == None, Comment.parent_submission == pid, Comment.level == 1, Comment.stickied == None, Comment.id.notin_(ids)) - comments = sort_objects(sort, comments, Comment, v) + comments = sort_objects(sort, comments, Comment, + include_shadowbanned=(not (v and v.can_see_shadowbanned))) comments = comments.offset(offset).all() diff --git a/files/routes/search.py b/files/routes/search.py index 49163eee3..715ef768e 100644 --- a/files/routes/search.py +++ b/files/routes/search.py @@ -5,7 +5,6 @@ from flask import * from files.__main__ import app from files.helpers.regex import * from files.helpers.sorting_and_time import * -from files.classes.comment import sort_objects import time from calendar import timegm @@ -146,7 +145,8 @@ def searchposts(v): posts = apply_time_filter(t, posts, Submission) - posts = sort_objects(sort, posts, Submission, v) + posts = sort_objects(sort, posts, Submission, + include_shadowbanned=(not (v and v.can_see_shadowbanned))) total = posts.count() @@ -249,7 +249,8 @@ def searchcomments(v): except: abort(400) comments = comments.filter(Comment.created_utc < before) - comments = sort_objects(sort, comments, Comment, v) + comments = sort_objects(sort, comments, Comment, + include_shadowbanned=(not (v and v.can_see_shadowbanned))) total = comments.count() diff --git a/files/routes/users.py b/files/routes/users.py index 25968707f..cf96a5eb5 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -8,7 +8,6 @@ from files.helpers.alerts import * from files.helpers.sanitize import * from files.helpers.const import * from files.helpers.sorting_and_time import * -from files.classes.comment import sort_objects from files.mail import * from flask import * from files.__main__ import app, limiter, db_session @@ -910,7 +909,8 @@ def u_username_comments(username, v=None): comments = apply_time_filter(t, comments, Comment) - comments = sort_objects(sort, comments, Comment, v) + comments = sort_objects(sort, comments, Comment, + include_shadowbanned=(not (v and v.can_see_shadowbanned))) comments = comments.offset(25 * (page - 1)).limit(26).all() ids = [x.id for x in comments]