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/assets/js/chat.js b/files/assets/js/chat.js index 69a31f2a5..3e34a6333 100644 --- a/files/assets/js/chat.js +++ b/files/assets/js/chat.js @@ -7,6 +7,7 @@ const textbox = document.getElementById('input-text') const icon = document.getElementById('favicon') const vid = document.getElementById('vid').value const site_name = document.getElementById('site_name').value +const slurreplacer = document.getElementById('slurreplacer').value let notifs = 0; let scrolled_down = true; @@ -38,7 +39,10 @@ function flash(){ socket.on('speak', function(json) { let text = json['text'] - let text_html = json['text_html'] + let text_html + + if (slurreplacer == 'True') text_html = json['text_censored'] + else text_html = json['text_html'] if (text_html.includes(``)){ chatline.classList.add('chat-mention'); @@ -47,20 +51,30 @@ socket.on('speak', function(json) { chatline.classList.remove('chat-mention'); }; - notifs = notifs + 1; - if (notifs == 1) { - setTimeout(flash, 500); + scrolled_down = (box.scrollHeight - box.scrollTop <= window.innerHeight-109) + + let users = document.getElementsByClassName('userlink'); + let last_user = users[users.length-1].innerHTML; + + if (last_user == json['username']) { + document.getElementsByClassName('userlink')[0].classList.add('d-none') + document.getElementsByClassName('avatar')[0].classList.add('d-none') + document.getElementsByClassName('userlink')[0].href = '/@' + json['username'] + document.getElementsByClassName('userlink')[0].style.color = '#' + json['namecolor'] + document.getElementsByClassName('chat-line')[0].classList.remove('diff') + } + else { + document.getElementsByClassName('avatar')[0].src = json['avatar'] + document.getElementsByClassName('chat-line')[0].classList.add('diff') } - scrolled_down = (box.scrollHeight - box.scrollTop <= window.innerHeight-109) - document.getElementsByClassName('desktop-avatar')[0].src = json['avatar'] - document.getElementsByClassName('mobile-avatar')[0].src = json['avatar'] - document.getElementsByClassName('userlink')[0].href = '/@' + json['username'] document.getElementsByClassName('userlink')[0].innerHTML = json['username'] - document.getElementsByClassName('userlink')[0].style.color = '#' + json['namecolor'] document.getElementsByClassName('text')[0].innerHTML = text - document.getElementsByClassName('chat-message')[0].innerHTML = text_html - document.getElementById('chat-text').append(document.getElementsByClassName('chat-line')[0].cloneNode(true)) + document.getElementsByClassName('chat-message')[0].innerHTML = text_html.replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, '') + + let line = document.getElementsByClassName('chat-line')[0].cloneNode(true) + bs_trigger(line) + box.append(line) if (scrolled_down) box.scrollTo(0, box.scrollHeight) }) @@ -78,7 +92,7 @@ function send() { } function quote(t) { - textbox.style.height = '80px' + textbox.style.height = '50px' text = t.previousElementSibling.innerHTML.replace(/>/g, ">").replace(/\n/g, "\n>") textbox.value = '> ' + text + '\n\n@' + t.parentElement.previousElementSibling.innerHTML + ' ' textbox.focus() diff --git a/files/assets/js/comments+submission_listing.js b/files/assets/js/comments+submission_listing.js index a3f570e4c..46ddade22 100644 --- a/files/assets/js/comments+submission_listing.js +++ b/files/assets/js/comments+submission_listing.js @@ -10,33 +10,6 @@ function pinned_timestamp(id) { if (!pintooltip.includes('until')) el.setAttribute("data-bs-original-title", `${pintooltip} until ${time}`) } -function expandDesktopImage(image) { - document.getElementById("desktop-expanded-image").src = image.replace("200w_d.webp", "giphy.webp"); - document.getElementById("desktop-expanded-image-link").href = image; - document.getElementById("desktop-expanded-image-wrap-link").href=image; -}; - -function bs_trigger() { - let tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); - tooltipTriggerList.map(function(element){ - return bootstrap.Tooltip.getOrCreateInstance(element); - }); - - const popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]')); - popoverTriggerList.map(function(popoverTriggerEl) { - const popoverId = popoverTriggerEl.getAttribute('data-content-id'); - const contentEl = document.getElementById(popoverId); - if (contentEl) { - return bootstrap.Popover.getOrCreateInstance(popoverTriggerEl, { - content: contentEl.innerHTML, - html: true, - }); - } - }) -} - -bs_trigger() - function popclick(author) { setTimeout(() => { let popover = document.getElementsByClassName("popover") diff --git a/files/assets/js/comments_v.js b/files/assets/js/comments_v.js index 5db4a65fd..9c3648b78 100644 --- a/files/assets/js/comments_v.js +++ b/files/assets/js/comments_v.js @@ -162,7 +162,7 @@ function post_reply(id){ if (data && data["comment"]) { commentForm=document.getElementById('comment-form-space-'+id); commentForm.innerHTML = data["comment"].replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, '').replace('comment-collapse-desktop d-none d-md-block','d-none').replace('border-left: 2px solid','padding-left:0;border-left: 0px solid'); - bs_trigger(); + bs_trigger(commentForm); } else { if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"]; @@ -200,6 +200,7 @@ function comment_edit(id){ commentForm=document.getElementById('comment-text-'+id); commentForm.innerHTML = data["comment"].replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, '') document.getElementById('cancel-edit-'+id).click() + bs_trigger(commentForm); } else { if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"]; @@ -239,7 +240,7 @@ function post_comment(fullname){ if (data && data["comment"]) { commentForm=document.getElementById('comment-form-space-'+fullname); commentForm.innerHTML = data["comment"].replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, ''); - bs_trigger(); + bs_trigger(commentForm); } else { if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"]; diff --git a/files/assets/js/header.js b/files/assets/js/header.js index 377ea9e15..0d98f27d4 100644 --- a/files/assets/js/header.js +++ b/files/assets/js/header.js @@ -29,13 +29,35 @@ function formkey() { else return null; } -if (typeof bs_trigger === 'undefined') { - var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); + +function bs_trigger(e) { + let tooltipTriggerList = [].slice.call(e.querySelectorAll('[data-bs-toggle="tooltip"]')); tooltipTriggerList.map(function(element){ return bootstrap.Tooltip.getOrCreateInstance(element); }); + + const popoverTriggerList = [].slice.call(e.querySelectorAll('[data-bs-toggle="popover"]')); + popoverTriggerList.map(function(popoverTriggerEl) { + const popoverId = popoverTriggerEl.getAttribute('data-content-id'); + const contentEl = e.getElementById(popoverId); + if (contentEl) { + return bootstrap.Popover.getOrCreateInstance(popoverTriggerEl, { + content: contentEl.innerHTML, + html: true, + }); + } + }) } +bs_trigger(document) + + +function expandDesktopImage(image) { + document.getElementById("desktop-expanded-image").src = image.replace("200w_d.webp", "giphy.webp"); + document.getElementById("desktop-expanded-image-link").href = image; + document.getElementById("desktop-expanded-image-wrap-link").href=image; +}; + function post_toast(t, url, reload, data) { t.disabled = true; t.classList.add("disabled"); 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 %} Chat - -{% endblock %} -{% block content %} + + + + {% if v.css %} + + {% endif %} -
- - - 0 - -
+ + + + + + + {% include "header.html" %} + +
+
+
+ +
+ + + 0 +
-
-
-
-
-
-
- {% for m in messages %} - {% set text_html = m['text_html'] %} - {% set link = '' %} - -
-
-
- - + + - - - +
+
+ - - - + + + \ No newline at end of file diff --git a/files/templates/comments.html b/files/templates/comments.html index ed71cfd01..e7f3218bb 100644 --- a/files/templates/comments.html +++ b/files/templates/comments.html @@ -843,7 +843,7 @@ {% if v %} - + {% endif %} @@ -854,7 +854,7 @@ {% include "expanded_image_modal.html" %} - + + {% if v and not err %}
{{v.formkey}}
diff --git a/files/templates/submission.html b/files/templates/submission.html index 72436c357..2e03986c8 100644 --- a/files/templates/submission.html +++ b/files/templates/submission.html @@ -999,8 +999,9 @@ xhr.setRequestHeader('xhr', 'xhr'); xhr.onload=function(){ if (xhr.status==200) { - document.getElementById(`viewmore-${offset}`).innerHTML = xhr.response.replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, ''); - bs_trigger() + let e = document.getElementById(`viewmore-${offset}`); + e.innerHTML = xhr.response.replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, ''); + bs_trigger(e) comments = JSON.parse(localStorage.getItem("old-comment-counts")) || {} lastCount = comments['{{p.id}}'] diff --git a/files/templates/submission_listing.html b/files/templates/submission_listing.html index 0c6f2f8c3..106512a61 100644 --- a/files/templates/submission_listing.html +++ b/files/templates/submission_listing.html @@ -445,5 +445,5 @@ {% include "expanded_image_modal.html" %} - + \ No newline at end of file diff --git a/snappy_Drama.txt b/snappy_Drama.txt index aae420d70..3b4e810b5 100644 --- a/snappy_Drama.txt +++ b/snappy_Drama.txt @@ -3631,20 +3631,22 @@ I cannot think or comprehend of anything more cucked than having a daughter. Hon {[para]} watch this go nowhere in 2 weeks {[para]} -I would appreciate you removing my post from the site asap,and I won't sign up to your site just to have a 'word' I hate the fact I have to explain -myself inregards to my weight. But if it helps you take down my post. Here you go - I hate myself. Ive struggled with depression my entire life I was -bullied at school for being taller than most girls and not being stick thin (yet according to the bmi calculator I was healthy at 16-17) but to everyone I -was fat, and white and gross. I turned to self harm and eating as coping mechanisms. Even now at a bmi of 40 (yes I'm actively losing weight) I'm still -not the biggest person in the room. I'm guessing your admin thinks I have fat rolls dripping down me, breathing heavy and unable to leave my bed. -Sadly for him thats not the case. I do alot for my kids, I have to be active but I use to eat a crazy amount of sugary shit to just get through the day -because of my depression. Im ashamed of how I look, I can't stand to see myself in the mirror, let alone get on the scales every day. I almost lost my -veteran husband 3 years ago to a disease, I care for him 24/7. What I sub to in reddit are my outlets for my depression, for my loneliness. I have four -kids and my husband but I dont have friends no one to vent to about the hard shit. I design clothes for my "creepy" dolls as an outlet a way to stay -creative I use to make dresses and outfits for my daughters dolls when she was younger and I just continued it. I even use to draw furry art (hi gay -furry femboy) but I gave that up years ago. I honestly thought twox chromosome was a safe place for me to say stuff that made me happy, -everything I write is true however sad you think it is. I dont want to be made fun of its hard enough looking at myself everyday without a chorus of -people telling me exactly what my own thoughts are. Ive attempted suicide numerous times and its my kids that pull me through it. So please take it -down. I dont deserve to be shamed, im just a sad pathetic woman who cares about her kids and if she could end it without hurting anyone she +I would appreciate you removing my post from the site asap,and I won't sign up to your site just to have a 'word' I hate the fact I have to explain +myself inregards to my weight. But if it helps you take down my post. Here you go - I hate myself. Ive struggled with depression my entire life I was +bullied at school for being taller than most girls and not being stick thin (yet according to the bmi calculator I was healthy at 16-17) but to everyone I +was fat, and white and gross. I turned to self harm and eating as coping mechanisms. Even now at a bmi of 40 (yes I'm actively losing weight) I'm still +not the biggest person in the room. I'm guessing your admin thinks I have fat rolls dripping down me, breathing heavy and unable to leave my bed. +Sadly for him thats not the case. I do alot for my kids, I have to be active but I use to eat a crazy amount of sugary shit to just get through the day +because of my depression. Im ashamed of how I look, I can't stand to see myself in the mirror, let alone get on the scales every day. I almost lost my +veteran husband 3 years ago to a disease, I care for him 24/7. What I sub to in reddit are my outlets for my depression, for my loneliness. I have four +kids and my husband but I dont have friends no one to vent to about the hard shit. I design clothes for my "creepy" dolls as an outlet a way to stay +creative I use to make dresses and outfits for my daughters dolls when she was younger and I just continued it. I even use to draw furry art (hi gay +furry femboy) but I gave that up years ago. I honestly thought twox chromosome was a safe place for me to say stuff that made me happy, +everything I write is true however sad you think it is. I dont want to be made fun of its hard enough looking at myself everyday without a chorus of +people telling me exactly what my own thoughts are. Ive attempted suicide numerous times and its my kids that pull me through it. So please take it +down. I dont deserve to be shamed, im just a sad pathetic woman who cares about her kids and if she could end it without hurting anyone she would. {[para]} -My husband use to snore like a chainsaw then he got nose surgery and it was like white noise and then a cpap so nice and quiet. He farts so much and I HATE IT. He is so freaking proud of them, throws his leg in the air and pretends to kick start a bike while farting. Then he tries to crop dust me. Ive asked him to stop but Nada. Im am disgusted by it. We've both put on a lot of weight in the last few years and that doesn't repulse me but his hygiene and man funk do. \ No newline at end of file +My husband use to snore like a chainsaw then he got nose surgery and it was like white noise and then a cpap so nice and quiet. He farts so much and I HATE IT. He is so freaking proud of them, throws his leg in the air and pretends to kick start a bike while farting. Then he tries to crop dust me. Ive asked him to stop but Nada. Im am disgusted by it. We've both put on a lot of weight in the last few years and that doesn't repulse me but his hygiene and man funk do. +{[para]} +The only thing that is advanced from this thread is my stage 4 cancer from reading it. \ No newline at end of file