added image support

This commit is contained in:
iou1name 2018-06-25 15:52:10 -04:00
parent 96363c55b2
commit 2386d54c3d
7 changed files with 72 additions and 14 deletions

View File

@ -4,7 +4,7 @@ By popular demand, I'm building a better anonkun. It doesn't do much right now t
## Requirements ## Requirements
Python 3.6+ Python 3.6+
MariaDB 10.2+ MariaDB 10.2+
Python packages: `flask flask_socketio flask-paranoid passlib argon2_cffi bleach flask-session` Python packages: `flask flask_socketio flask-paranoid passlib argon2_cffi bleach flask-session requests python-magic`
## Install ## Install
``` ```

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" """
Simple file host using Flask. A Flask-based questing platform.
""" """
import os import os
import time import time

View File

@ -9,6 +9,7 @@ from flask import session
from flask_socketio import SocketIO, emit, join_room from flask_socketio import SocketIO, emit, join_room
import database as db import database as db
import tools
socketio = SocketIO() socketio = SocketIO()
@ -43,6 +44,7 @@ def message(data):
line = '<span class="greenText">' + line + '</span>' line = '<span class="greenText">' + line + '</span>'
lines.append(line) lines.append(line)
message = "<br />".join(lines) message = "<br />".join(lines)
message = tools.handle_img(message)
data["message"] = message data["message"] = message
db.log_chat_message(data) db.log_chat_message(data)
@ -64,6 +66,7 @@ def new_post(data):
post = data["post"] post = data["post"]
post = bleach.clean(post.strip()) post = bleach.clean(post.strip())
post = post.replace("\n", "<br />") post = post.replace("\n", "<br />")
message = tools.handle_img(message)
data["post"] = [post] data["post"] = [post]
db.insert_quest_post(room, post, int(time.time())) db.insert_quest_post(room, post, int(time.time()))
@ -84,6 +87,7 @@ def update_post(data):
post = data["post"] post = data["post"]
post = post.strip().replace("<br>", "<br />") post = post.strip().replace("<br>", "<br />")
message = tools.handle_img(message)
data["post"] = post data["post"] = post
post_id = data["post_id"] post_id = data["post_id"]

View File

@ -1,3 +1,8 @@
img {
max-width:100%;
max-height:100%;
}
.header { .header {
display: initial; display: initial;
position: fixed; position: fixed;
@ -60,6 +65,11 @@
flex: 1; flex: 1;
} }
.message {
width: 100%;
word-wrap: break-word;
}
#messageTextDiv { #messageTextDiv {
padding-bottom: 10px; padding-bottom: 10px;
width: 100%; width: 100%;

View File

@ -9,6 +9,7 @@
if ( document.readyState !== 'complete' ) return; if ( document.readyState !== 'complete' ) return;
clearInterval( tid ); clearInterval( tid );
document.getElementById('chatWindow').scrollTop = document.getElementById('chatWindow').scrollHeight;
socket = io.connect('https://' + document.domain + ':' + location.port); socket = io.connect('https://' + document.domain + ':' + location.port);
socket.on('connect', function() { socket.on('connect', function() {
socket.emit('joined', {room: {{ room_id }}}); socket.emit('joined', {room: {{ room_id }}});

52
tools.py Normal file
View File

@ -0,0 +1,52 @@
#!/usr/bin/env python3
"""
Miscellaneous tools and help functions.
"""
import os
import re
import hashlib
import magic
import requests
IMG_DIR = "/usr/local/www/html/img"
def sanitize_title(canon_title):
"""
Sanitizes the given canonical title for a quest and returns a
url-friendly version.
"""
ident_title = canon_title.lower().replace(" ", "-")
ident_title = urllib.parse.quote(ident_title)
return ident_title
def handle_img(post):
"""
Handles [img] tags within a quest post appropriately.
"""
urls = re.findall(r"\[img\](.*?)\[/img\]", post)
for url in urls:
try:
res = requests.get(url)
res.raise_for_status()
mime = magic.from_buffer(res.content, mime=True)
assert mime in ["image/jpeg", "image/png","image/gif","video/webm"]
h = hashlib.sha256()
h.update(res.content)
fname = h.hexdigest()
fname += "." + mime.partition("/")[2]
with open(os.path.join(IMG_DIR, fname), "wb") as file:
for chunk in res.iter_content(100000):
file.write(chunk)
alt_text = os.path.basename(url)
img_tag = f'<img src="/img/{fname}" alt="{alt_text}" />'
except requests.exceptions:
img_tag = "INVALID_IMG_URL"
except assertion:
img_tag = "INVALID_IMG_MIME_TYPE"
except:
img_tag = "UNKNOWN_ERROR"
post = post.replace("[img]" + url + "[/img]", img_tag)
return post

View File

@ -12,6 +12,7 @@ from flask import session, request, abort, redirect, url_for, render_template
from flask import Blueprint from flask import Blueprint
import database as db import database as db
import tools
views = Blueprint("views", __name__) views = Blueprint("views", __name__)
@ -41,16 +42,6 @@ def login_required(url=None):
return actual_decorator return actual_decorator
def sanitize_title(canon_title):
"""
Sanitizes the given canonical title for a quest and returns a
url-friendly version.
"""
ident_title = canon_title.lower().replace(" ", "-")
ident_title = urllib.parse.quote(ident_title)
return ident_title
@views.route("/quest/<path:quest_title>") @views.route("/quest/<path:quest_title>")
def quest(quest_title): def quest(quest_title):
""" """
@ -99,7 +90,7 @@ def create_quest():
canon_title = request.form.get("quest_title") canon_title = request.form.get("quest_title")
quest_body = request.form.get("quest_body") quest_body = request.form.get("quest_body")
ident_title = sanitize_title(canon_title) ident_title = tools.sanitize_title(canon_title)
quest_body = bleach.clean(quest_body.strip()) quest_body = bleach.clean(quest_body.strip())
quest_body = quest_body.replace("\n", "<br />") quest_body = quest_body.replace("\n", "<br />")