diff --git a/.gitignore b/.gitignore index a0f7330b9..12edea75b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ __pycache__/ *$py.class chart.png video.mp4 +hostedimages/ # C extensions *.so diff --git a/files/helpers/images.py b/files/helpers/images.py index 027660cd2..9e84927f5 100644 --- a/files/helpers/images.py +++ b/files/helpers/images.py @@ -1,16 +1,10 @@ -import requests -from os import environ from PIL import Image as IImage, ImageSequence from files.classes.images import * from webptools import gifwebp -CATBOX_KEY = environ.get("CATBOX_KEY", "").strip() - -def upload_ibb(file=None, resize=False): +def process_image(filename=None, resize=False): - if file: file.save("image.webp") - - i = IImage.open("image.webp") + i = IImage.open(filename) if resize: size = 100, 100 @@ -26,13 +20,9 @@ def upload_ibb(file=None, resize=False): om = next(frames) om.info = i.info - om.save("image.webp", save_all=True, append_images=list(frames), loop=0) + om.save(filename, save_all=True, append_images=list(frames), loop=0) elif i.format.lower() != "webp": - if i.format.lower() == "gif": gifwebp(input_image="image.webp", output_image="image.webp", option="-q 80") - else: i.save("image.webp") + if i.format.lower() == "gif": gifwebp(input_image=filename, output_image=filename, option="-q 80") + else: i.save(filename) - - with open("image.webp", 'rb') as f: - req = requests.post('https://catbox.moe/user/api.php', data={'userhash':CATBOX_KEY, 'reqtype':'fileupload'}, files={'fileToUpload':f}).text - - if req.startswith('https://'): return req \ No newline at end of file + return filename \ No newline at end of file diff --git a/files/routes/comments.py b/files/routes/comments.py index 3bcd402ac..79d7cddfb 100644 --- a/files/routes/comments.py +++ b/files/routes/comments.py @@ -263,7 +263,9 @@ def api_comment(v): file=request.files["file"] if not file.content_type.startswith('image/'): return {"error": "That wasn't an image!"}, 400 - url = upload_ibb(file=file) + name = f'/hostedimages/{time.time()}{secrets.token_urlsafe(8)}' + file.save(name) + url = process_image(name) body = request.values.get("body") + f"\n![]({url})" body = re.sub('([^\n])\n([^\n])', r'\1\n\n\2', body) @@ -682,7 +684,9 @@ def edit_comment(cid, v): file=request.files["file"] if not file.content_type.startswith('image/'): return {"error": "That wasn't an image!"}, 400 - url = upload_ibb(file=file) + name = f'/hostedimages/{time.time()}{secrets.token_urlsafe(8)}' + file.save(name) + url = process_image(name) body += f"\n![]({url})" body_md = CustomRenderer().render(mistletoe.Document(body)) diff --git a/files/routes/giphy.py b/files/routes/giphy.py index bf460974c..81a4248de 100644 --- a/files/routes/giphy.py +++ b/files/routes/giphy.py @@ -7,8 +7,8 @@ from files.__main__ import app GIPHY_KEY = environ.get('GIPHY_KEY').rstrip() -@app.route("/giphy", methods=["GET"]) -@app.route("/giphy", methods=["GET"]) +@app.get("/giphy") +@app.get("/giphy") def giphy(path=None): searchTerm = request.values.get("searchTerm", "") diff --git a/files/routes/login.py b/files/routes/login.py index c74c5bbba..c59e4caf5 100644 --- a/files/routes/login.py +++ b/files/routes/login.py @@ -505,7 +505,7 @@ def post_reset(v): title="Password reset successful!", message="Login normally to access your account.") -@app.route("/lost_2fa") +@app.get("/lost_2fa") @auth_desired def lost_2fa(v): diff --git a/files/routes/posts.py b/files/routes/posts.py index ae38d62b4..86867537b 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -509,11 +509,13 @@ def thumbnail_thread(pid): db.close() return - with open("image.webp", "wb") as file: + name = f'/hostedimages/{time.time()}{secrets.token_urlsafe(8)}' + + with open(name, "wb") as file: for chunk in image_req.iter_content(1024): file.write(chunk) - post.thumburl = upload_ibb(resize=True) + post.thumburl = process_image(name, True) db.add(post) db.commit() db.close() @@ -833,7 +835,11 @@ def submit_post(v): body=request.values.get("body", "") ), 403 - if file.content_type.startswith('image/'): new_post.url = upload_ibb(file=file) + if file.content_type.startswith('image/'): + name = f'/hostedimages/{time.time()}{secrets.token_urlsafe(8)}' + file.save(name) + new_post.url = process_image(name) + elif file.content_type.startswith('video/'): file.save("video.mp4") with open("video.mp4", 'rb') as f: diff --git a/files/routes/settings.py b/files/routes/settings.py index d05a4c7a8..474ce6452 100644 --- a/files/routes/settings.py +++ b/files/routes/settings.py @@ -111,15 +111,12 @@ def settings_profile_post(v): if request.headers.get("Authorization"): return {"error": f"Image files only"}, 400 else: return render_template("settings_profile.html", v=v, error=f"Image files only."), 400 - url = upload_ibb(file=file) + name = f'/hostedimages/{time.time()}{secrets.token_urlsafe(8)}' + file.save(name) + url = process_image(name) bio += f"\n\n![]({url})" - # if bio == v.bio: - # return render_template("settings_profile.html", - # v=v, - # error="You didn't change anything") - bio_html = CustomRenderer().render(mistletoe.Document(bio)) bio_html = sanitize(bio_html) # Run safety filter @@ -509,11 +506,16 @@ def settings_images_profile(v): file = request.files["profile"] - file.save("image.webp") - highres = upload_ibb() + name = f'/hostedimages/{time.time()}{secrets.token_urlsafe(8)}' + file.save(name) + highres = process_image(name) + if not highres: abort(400) - imageurl = upload_ibb(resize=True) + name = f'/hostedimages/{time.time()}{secrets.token_urlsafe(8)}' + file.save(name) + imageurl = process_image(name, True) + if not imageurl: abort(400) v.highres = highres @@ -534,7 +536,10 @@ def settings_images_banner(v): if request.headers.get("cf-ipcountry") == "T1": return "Image uploads are not allowed through TOR.", 403 file = request.files["banner"] - imageurl = upload_ibb(file=file) + + name = f'/hostedimages/{time.time()}{secrets.token_urlsafe(8)}' + file.save(name) + imageurl = process_image(name) if imageurl: v.bannerurl = imageurl diff --git a/files/routes/static.py b/files/routes/static.py index 693a84d29..a6b8c0ba6 100644 --- a/files/routes/static.py +++ b/files/routes/static.py @@ -229,19 +229,19 @@ def submit_contact(v): g.db.commit() return render_template("contact.html", v=v, msg="Your message has been sent.") -@app.route('/archives') +@app.get('/archives') @limiter.exempt def archivesindex(): return redirect("/archives/index.html") -@app.route('/archives/') +@app.get('/archives/') @limiter.exempt def archives(path): resp = make_response(send_from_directory('/archives', path)) if request.path.endswith('.css'): resp.headers.add("Content-Type", "text/css") return resp -@app.route('/assets/') +@app.get('/assets/') @limiter.exempt def static_service(path): resp = make_response(send_from_directory('./assets', path)) @@ -251,6 +251,14 @@ def static_service(path): return resp +@app.get('/hostedimages/') +@limiter.exempt +def images(path): + resp = make_response(send_from_directory('./images', path)) + resp.headers.remove("Cache-Control") + resp.headers.add("Cache-Control", "public, max-age=2628000") + return resp + @app.get("/robots.txt") def robots_txt(): return send_file("./assets/robots.txt") @@ -308,7 +316,7 @@ def formatting(v): return render_template("formatting.html", v=v) -@app.route("/service-worker.js") +@app.get("/service-worker.js") def serviceworker(): with open("files/assets/js/service-worker.js", "r") as f: return Response(f.read(), mimetype='application/javascript') diff --git a/files/routes/users.py b/files/routes/users.py index b08e0361a..581de7a65 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -696,7 +696,7 @@ def remove_follow(username, v): return {"message": "Follower removed!"} -@app.route("/uid//pic/profile") +@app.get("/uid//pic/profile") @limiter.exempt def user_profile_uid(id): try: id = int(id)