add dm images

pull/93/head
Aevann 2023-01-23 11:58:38 +02:00
parent d34f836052
commit 8396126606
12 changed files with 85 additions and 18 deletions

View File

@ -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

View File

@ -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 = '<i class="fas fa-file"></i>';
document.getElementById(`filename-${id}`).innerHTML = '<i class="fas fa-file"></i>';
}
} else {
showToast(false, getMessageFromJsonData(false, data));

View File

@ -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,

View File

@ -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

View File

@ -13,6 +13,7 @@ _SETTINGS = {
"signups": True,
"login_required": False,
"under_siege": False,
"dm_images": True,
}
def get_setting(setting:str):

View File

@ -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)

View File

@ -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,

View File

@ -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,

View File

@ -35,6 +35,7 @@
<h4>Content</h4>
<ul>
<li><a href="/admin/dm_images">DM Images</a></li>
<li><a href="/log">Moderation Log</a></li>
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
<li><a href="/admin/image_posts">Image Posts</a></li>

View File

@ -522,12 +522,12 @@
<div class="comment-format" id="comment-format-bar-{{c.id}}">
<button type="button" data-nonce="{{g.nonce}}" data-onclick="loadEmojis('reply-form-body-{{c.id}}')" class="btn btn-secondary m-0 mt-3 mr-1" data-bs-toggle="modal" data-bs-target="#emojiModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add Emoji"><i class="fas fa-smile-beam"></i></button>
{% if c.sentto == MODMAIL_ID %}
<label class="btn btn-secondary m-0 mt-3" for="file-upload">
<div id="filename"><i class="fas fa-file"></i></div>
<input autocomplete="off" id="file-upload" accept="image/*, video/*, audio/*" type="file" name="file" multiple="multiple" {% if g.is_tor %}disabled{% endif %} data-nonce="{{g.nonce}}" data-onchange="changename('filename','file-upload')" hidden>
</label>
{% endif %}
{% set upload_disabled = g.is_tor or not get_setting('dm_images') %}
<label class="btn btn-secondary m-0 mt-3 {% if upload_disabled %}disabled{% endif %}" for="file-upload-{{c.id}}">
<div id="filename-{{c.id}}"><i class="fas fa-image"></i></div>
<input autocomplete="off" id="file-upload-{{c.id}}" accept="image/*" type="file" name="file" multiple="multiple" {% if upload_disabled %}disabled{% endif %} data-nonce="{{g.nonce}}" data-onchange="changename('filename-{{c.id}}','file-upload-{{c.id}}')" hidden>
</label>
</div>
<button type="button" data-nonce="{{g.nonce}}" data-onclick="remove_dialog()" class="btn btn-link text-muted ml-auto" data-toggleelement="reply-message-{{c.fullname}}" data-toggleattr="d-none">Cancel</button>

View File

@ -153,8 +153,17 @@
</div>
<form class="d-none toggleable" id="message" action="/@{{u.username}}/message" data-nonce="{{g.nonce}}" data-onsubmit="sendMessage(this)">
<input type="hidden" name="formkey" value="{{v|formkey}}">
<textarea autocomplete="off" id="input-message" form="message" name="message" rows="3" minlength="1" maxlength="10000" class="form-control b2 mt-1" data-preview="message-preview" data-nonce="{{g.nonce}}" data-oninput="markdown(this)" required></textarea>
<button type="button" class="btn btn-secondary format d-inline-block m-0 fas fa-smile-beam" data-nonce="{{g.nonce}}" data-onclick="loadEmojis('input-message')" data-bs-toggle="modal" data-bs-target="#emojiModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add Emoji"></button>
<textarea autocomplete="off" id="input-message" form="message" name="message" rows="3" minlength="1" maxlength="10000" class="form-control b2 mt-1" data-preview="message-preview" data-nonce="{{g.nonce}}" data-oninput="markdown(this)"></textarea>
<button type="button" class="btn btn-secondary format d-inline-block m-0 py-2 fas fa-smile-beam" data-nonce="{{g.nonce}}" data-onclick="loadEmojis('input-message')" data-bs-toggle="modal" data-bs-target="#emojiModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add Emoji"></button>
{% set upload_disabled = g.is_tor or not get_setting('dm_images') %}
<label class="btn btn-secondary m-0 py-1 px-2 {% if upload_disabled %}disabled{% endif %}" for="file-upload">
<div id="filename"><i class="fas fa-image"></i></div>
<input autocomplete="off" id="file-upload" accept="image/*" type="file" name="file" multiple="multiple" {% if upload_disabled %}disabled{% endif %} data-nonce="{{g.nonce}}" data-onchange="changename('filename','file-upload')" hidden>
</label>
&nbsp;
<input type="submit" data-nonce="{{g.nonce}}" data-onclick="disable(this);remove_dialog()" value="Submit" class="btn btn-primary">
</form>

View File

@ -38,6 +38,7 @@ pip3 install -r requirements.txt
mkdir /images
mkdir /chat_images
mkdir /dm_images
mkdir /songs
mkdir /videos
mkdir /audio