From 8396126606794b0a0cc423bd9fc1047e5a6a24ac Mon Sep 17 00:00:00 2001 From: Aevann Date: Mon, 23 Jan 2023 11:58:38 +0200 Subject: [PATCH] add dm images --- Dockerfile | 1 + files/assets/js/comments_v.js | 6 ++-- files/helpers/config/const.py | 3 +- files/helpers/media.py | 46 ++++++++++++++++++++++++++- files/helpers/settings.py | 1 + files/routes/admin.py | 6 ++++ files/routes/jinja2.py | 4 +-- files/routes/users.py | 9 ++++-- files/templates/admin/admin_home.html | 1 + files/templates/comments.html | 12 +++---- files/templates/userpage/banner.html | 13 ++++++-- ubuntu_setup.sh | 1 + 12 files changed, 85 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1c65eca12..cbff4d459 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,6 +20,7 @@ RUN pip3 install -r /etc/requirements.txt RUN mkdir /images RUN mkdir /chat_images +RUN mkdir /dm_images RUN mkdir /songs RUN mkdir /videos RUN mkdir /audio diff --git a/files/assets/js/comments_v.js b/files/assets/js/comments_v.js index ec73d8064..a4780877d 100644 --- a/files/assets/js/comments_v.js +++ b/files/assets/js/comments_v.js @@ -119,7 +119,7 @@ function post_reply(id){ form.append('parent_id', id); form.append('body', document.getElementById('reply-form-body-'+id).value); try { - for (const e of document.getElementById('file-upload').files) + for (const e of document.getElementById(`file-upload-${id}`).files) form.append('file', e); } catch(e) {} @@ -144,10 +144,10 @@ function post_reply(id){ document.getElementById('reply-form-body-'+id).value = '' document.getElementById('message-reply-'+id).innerHTML = '' toggleReplyBox('reply-message-c_'+id) - const fileupload = document.getElementById('file-upload') + const fileupload = document.getElementById(`file-upload-${id}`) if (fileupload) { fileupload.value = null; - document.getElementById('filename').innerHTML = ''; + document.getElementById(`filename-${id}`).innerHTML = ''; } } else { showToast(false, getMessageFromJsonData(false, data)); diff --git a/files/helpers/config/const.py b/files/helpers/config/const.py index 77f204508..d95942cc5 100644 --- a/files/helpers/config/const.py +++ b/files/helpers/config/const.py @@ -465,7 +465,8 @@ PERMS = { # Minimum admin_level to perform action. 'SITE_CACHE_PURGE_CDN': 3, 'NOTIFICATIONS_FROM_SHADOWBANNED_USERS': 3, 'NOTIFICATIONS_MODMAIL': 3, - 'APPS_MODERATION': 3, + 'APPS_MODERATION': 3, + 'VIEW_DM_IMAGES': 3, 'POST_EDITING': 4, 'MODERATE_PENDING_SUBMITTED_ASSETS': 4, 'UPDATE_ASSETS': 4, diff --git a/files/helpers/media.py b/files/helpers/media.py index cf2347f36..094c3087b 100644 --- a/files/helpers/media.py +++ b/files/helpers/media.py @@ -1,12 +1,13 @@ import os import subprocess import time +import requests from shutil import copyfile from typing import Optional import gevent import imagehash -from flask import abort, g, has_request_context +from flask import abort, g, has_request_context, request from werkzeug.utils import secure_filename from PIL import Image from PIL import UnidentifiedImageError @@ -15,6 +16,7 @@ from sqlalchemy.orm.session import Session from files.classes.media import * from files.helpers.cloudflare import purge_files_in_cache +from files.helpers.settings import get_setting from .config.const import * @@ -216,3 +218,45 @@ def process_image(filename:str, v, resize=0, trim=False, uploader_id:Optional[in db.add(media) return filename + + +def process_dm_images(v): + if not request.files.get("file") or g.is_tor or not get_setting("dm_images"): + return '' + + body = '' + files = request.files.getlist('file')[:4] + for file in files: + if file.content_type.startswith('image/'): + filename = f'/dm_images/{time.time()}'.replace('.','') + '.webp' + file.save(filename) + + size = os.stat(filename).st_size + patron = bool(v.patron) + + 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, f"Max image/audio size is {MAX_IMAGE_AUDIO_SIZE_MB} MB ({MAX_IMAGE_AUDIO_SIZE_MB_PATRON} MB for paypigs)") + + with open(filename, 'rb') as f: + os.remove(filename) + try: + req = requests.request( + "POST", + "https://pomf2.lain.la/upload.php", + files={'files[]': f}, + timeout=20, + proxies=proxies + ).json() + except requests.Timeout: + abort(400, "Image upload timed out, please try again!") + + try: url = req['files'][0]['url'] + except: abort(400, req['description']) + + body += f'\n\n{url}\n\n' + + with open(f"{LOG_DIRECTORY}/dm_images.log", "a+", encoding="utf-8") as f: + f.write(body.strip() + '\n') + + return body diff --git a/files/helpers/settings.py b/files/helpers/settings.py index 207df0ddd..2b95dda66 100644 --- a/files/helpers/settings.py +++ b/files/helpers/settings.py @@ -13,6 +13,7 @@ _SETTINGS = { "signups": True, "login_required": False, "under_siege": False, + "dm_images": True, } def get_setting(setting:str): diff --git a/files/routes/admin.py b/files/routes/admin.py index a7bf2e531..d86ef882f 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -188,6 +188,12 @@ def loggedout_list(v): # return redirect(f"/@{olduser.username}") +@app.get('/admin/dm_images') +@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID) +@admin_level_required(PERMS['VIEW_DM_IMAGES']) +def dm_images(v): + with open(f"{LOG_DIRECTORY}/dm_images.log", "r", encoding="utf-8") as f: + return f.read() @app.get('/admin/edit_rules') @limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID) diff --git a/files/routes/jinja2.py b/files/routes/jinja2.py index 101673dca..7ccb01139 100644 --- a/files/routes/jinja2.py +++ b/files/routes/jinja2.py @@ -12,7 +12,7 @@ from files.classes.user import User from files.helpers.assetcache import assetcache_path from files.helpers.config.const import * from files.helpers.regex import * -from files.helpers.settings import get_settings +from files.helpers.settings import get_settings, get_setting from files.helpers.sorting_and_time import make_age_string from files.routes.routehelpers import get_alt_graph, get_formkey from files.__main__ import app, cache @@ -107,7 +107,7 @@ def inject_constants(): "HOLE_NAME":HOLE_NAME, "HOLE_STYLE_FLAIR":HOLE_STYLE_FLAIR, "HOLE_REQUIRED":HOLE_REQUIRED, "GUMROAD_LINK":GUMROAD_LINK, "DEFAULT_THEME":DEFAULT_THEME, "DESCRIPTION":DESCRIPTION, "has_sidebar":has_sidebar, "has_logo":has_logo, - "FP":FP, "patron":patron, + "FP":FP, "patron":patron, "get_setting": get_setting, "SIDEBAR_THREAD":SIDEBAR_THREAD, "BANNER_THREAD":BANNER_THREAD, "BADGE_THREAD":BADGE_THREAD, "SNAPPY_THREAD":SNAPPY_THREAD, "KOFI_TOKEN":KOFI_TOKEN, "KOFI_LINK":KOFI_LINK, diff --git a/files/routes/users.py b/files/routes/users.py index 576b4179b..776f79e5f 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -495,6 +495,9 @@ def message2(v:User, username:str): abort(403, f"@{user.username} is blocking you.") message = sanitize_raw_body(request.values.get("message"), False) + + message += process_dm_images(v) + if not message: abort(400, "Message is empty!") body_html = sanitize(message) @@ -545,7 +548,6 @@ def message2(v:User, username:str): @auth_required def messagereply(v:User): body = sanitize_raw_body(request.values.get("body"), False) - if not body and not request.files.get("file"): abort(400, "Message is empty!") id = request.values.get("parent_id") parent = get_comment(id, v=v) @@ -567,11 +569,12 @@ def messagereply(v:User): and hasattr(user, 'is_blocked') and user.is_blocked): abort(403, f"You're blocked by @{user.username}") - if parent.sentto == MODMAIL_ID: - body += process_files(request.files, v) + body += process_dm_images(v) body = body.strip() + if not body: abort(400, "Message is empty!") + body_html = sanitize(body) c = Comment(author_id=v.id, diff --git a/files/templates/admin/admin_home.html b/files/templates/admin/admin_home.html index f6c910c1c..6dc83011b 100644 --- a/files/templates/admin/admin_home.html +++ b/files/templates/admin/admin_home.html @@ -35,6 +35,7 @@

Content