diff --git a/files/__main__.py b/files/__main__.py index 891f364ce..4f18844d0 100644 --- a/files/__main__.py +++ b/files/__main__.py @@ -13,7 +13,7 @@ from sqlalchemy import * import gevent import redis import time -from sys import stdout +from sys import stdout, argv import faulthandler from json import loads @@ -116,4 +116,8 @@ def after_request(response): response.headers.add("X-Frame-Options", "deny") return response -from files.routes import * \ No newline at end of file +if "load_chat" in argv or app.config["SERVER_NAME"] == 'localhost': + from files.routes.chat import * + +if "load_chat" not in argv: + from files.routes import * \ No newline at end of file diff --git a/files/helpers/const.py b/files/helpers/const.py index 1e6601141..94321e6c5 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -724,7 +724,7 @@ def sub_matcher_upper(match): return SLURS[match.group(0).lower()].upper() def censor_slurs(body, logged_user): - if not logged_user or logged_user.slurreplacer: + if not logged_user or logged_user == 'chat' or logged_user.slurreplacer: body = slur_regex_upper.sub(sub_matcher_upper, body) body = slur_regex.sub(sub_matcher, body) return body diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index fa5d01e2a..5717d13a2 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -326,6 +326,10 @@ def sanitize(sanitized, noimages=False, alert=False, comment=False, edit=False): marsey.count += 1 g.db.add(marsey) + if '#fortune' in sanitized: + sanitized = sanitized.replace('#fortune', '') + sanitized += '\n\n
' + random.choice(FORTUNE_REPLIES) + '
' + signal.alarm(0) return sanitized diff --git a/files/routes/__init__.py b/files/routes/__init__.py index bcca8b043..e9121b46a 100644 --- a/files/routes/__init__.py +++ b/files/routes/__init__.py @@ -15,5 +15,4 @@ from .votes import * from .feeds import * from .awards import * from .giphy import * -from .subs import * -from .chat import * \ No newline at end of file +from .subs import * \ No newline at end of file diff --git a/files/routes/chat.py b/files/routes/chat.py index 772a31ed5..6cab14e24 100644 --- a/files/routes/chat.py +++ b/files/routes/chat.py @@ -1,90 +1,95 @@ +import time +from files.helpers.wrappers import auth_required +from files.helpers.sanitize import sanitize +from files.helpers.const import * +from datetime import datetime +from flask_socketio import SocketIO, emit +from files.__main__ import app, limiter, cache +from flask import render_template, make_response, send_from_directory import sys -from files.helpers.const import SITE, SITE_FULL - -if "load_chat" in sys.argv or SITE == 'localhost': - import time - from files.helpers.wrappers import auth_required - from files.helpers.sanitize import sanitize - from datetime import datetime - from flask_socketio import SocketIO, emit - from files.__main__ import app, limiter, cache - from flask import render_template, make_response, send_from_directory, abort - import sys - import atexit +import atexit +if SITE == 'localhost': + socketio = SocketIO(app, async_mode='gevent', cors_allowed_origins=[SITE_FULL], logger=True, engineio_logger=True, debug=True) +else: socketio = SocketIO(app, async_mode='gevent', cors_allowed_origins=[SITE_FULL]) - typing = [] - online = [] - messages = cache.get('chat') or [] + +typing = [] +online = [] +messages = cache.get('chat') or [] +total = cache.get('total') or 0 + +@app.get("/chat") +@auth_required +def chat( v): + return render_template("chat.html", v=v, messages=messages) - @app.get("/chat") - @auth_required - def chat( v): - return render_template("chat.html", v=v, messages=messages) +@app.get('/chat.js') +@limiter.exempt +def chatjs(): + resp = make_response(send_from_directory('assets', 'js/chat.js')) + return resp - @app.get('/chat.js') - @limiter.exempt - def chatjs(): - resp = make_response(send_from_directory('assets', 'js/chat.js')) - return resp +@socketio.on('speak') +@limiter.limit("3/second;10/minute") +@auth_required +def speak(data, v): + if v.is_banned: return '', 403 + global messages, total + text = data[:1000].strip() + if not text: return '', 403 + text_html = sanitize(text) + + data={ + "avatar": v.profile_url, + "username":v.username, + "namecolor":v.namecolor, + "text":text, + "text_html":text_html, + "text_censored":censor_slurs(text_html, 'chat') + } + + messages.append(data) + messages = messages[-20:] + total += 1 + emit('speak', data, broadcast=True) + return '', 204 + +@socketio.on('connect') +@auth_required +def connect(v): + if v.username not in online: + online.append(v.username) + emit("online", online, broadcast=True) + + emit('typing', typing) + return '', 204 + +@socketio.on('disconnect') +@auth_required +def disconnect(v): + if v.username in online: + online.remove(v.username) + emit("online", online, broadcast=True) + + if v.username in typing: typing.remove(v.username) + emit('typing', typing, broadcast=True) + return '', 204 + +@socketio.on('typing') +@auth_required +def typing_indicator(data, v): + + if data and v.username not in typing: typing.append(v.username) + elif not data and v.username in typing: typing.remove(v.username) + + emit('typing', typing, broadcast=True) + return '', 204 - @socketio.on('speak') - @limiter.limit("3/second;10/minute") - @auth_required - def speak(data, v): - if v.is_banned: abort(403) - global messages - text = data[:1000].strip() - if not text: abort(403) - - data={ - "avatar": v.profile_url, - "username":v.username, - "namecolor":v.namecolor, - "text":text, - "text_html":sanitize(text), - } - - messages.append(data) - messages = messages[-500:] - emit('speak', data, broadcast=True) - return '', 204 - - @socketio.on('connect') - @auth_required - def connect(v): - if v.username not in online: - online.append(v.username) - emit("online", online, broadcast=True) - - emit('typing', typing) - return '', 204 - - @socketio.on('disconnect') - @auth_required - def disconnect(v): - if v.username in online: - online.remove(v.username) - emit("online", online, broadcast=True) - - if v.username in typing: typing.remove(v.username) - emit('typing', typing, broadcast=True) - return '', 204 - - @socketio.on('typing') - @auth_required - def typing_indicator(data, v): - - if data and v.username not in typing: typing.append(v.username) - elif not data and v.username in typing: typing.remove(v.username) - - emit('typing', typing, broadcast=True) - return '', 204 - - - def close_running_threads(): - cache.set('chat', messages) - atexit.register(close_running_threads) \ No newline at end of file +def close_running_threads(): + cache.set('chat', messages) + cache.set('total', total) +atexit.register(close_running_threads) \ No newline at end of file diff --git a/files/routes/comments.py b/files/routes/comments.py index e9e726b05..ca7a823a1 100644 --- a/files/routes/comments.py +++ b/files/routes/comments.py @@ -335,10 +335,6 @@ def api_comment(v): if v.agendaposter and not v.marseyawarded and parent_post.id not in ADMIGGERS: body = torture_ap(body, v.username) - if '#fortune' in body: - body = body.replace('#fortune', '') - body += '\n\n' + random.choice(FORTUNE_REPLIES) + '
' - body_html = sanitize(body, comment=True) if v.marseyawarded and parent_post.id not in ADMIGGERS and marseyaward_body_regex.search(body_html): diff --git a/files/routes/posts.py b/files/routes/posts.py index fe7273596..0953e033e 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -1034,10 +1034,6 @@ def submit_post(v, sub=None): else: return error("Image/Video files only.") - if '#fortune' in body: - body = body.replace('#fortune', '') - body += '\n\n' + random.choice(FORTUNE_REPLIES) + '
' - body_html = sanitize(body) if v.marseyawarded and marseyaward_body_regex.search(body_html): diff --git a/files/templates/chat.html b/files/templates/chat.html index cd63ffe6b..676622eac 100644 --- a/files/templates/chat.html +++ b/files/templates/chat.html @@ -1,132 +1,165 @@ -{% extends "default.html" %} + + + + + + + + + + + + -{% block title %}