From 7c040367fa6936fc358b33d079d48513fa25220d Mon Sep 17 00:00:00 2001 From: HeyMoon Date: Sun, 2 Jul 2023 23:55:37 +0000 Subject: [PATCH] Bring back orgies (watchparties), now controllable by admins, and generally better in all ways (#165) This PR adds orgies back into rdrama. Long ago, snakes made the original orgy code, and it was super fun. But he had to rush it out, and ended up making it a bit unsustainable, and had a couple questionable coding decisions, which meant that it had to be removed. Hey, the man literally did it in a few hours before the DB trial continued, lmao. Anyways, I took my own approach to it. I do not use iframes, i just just repurpose code from /chat window. Because I had that freedom, I also moved things around to make the user experience a bit better. I also added a title to give users some context about what's happening. Check it out ![image](/attachments/6719146c-4922-4d75-967d-8d424a09b198) Most importantly, this is all configurable from the site. Admins with the permission "ORGIES" will see this in their control panel ![image](/attachments/423d6046-a11d-4e84-bd2c-a2a641afd552) Nigga, idk where to put it, so I made my own category. If there is no orgy in progress, admins will see this: ![image](/attachments/7c64b9fa-cdf4-4986-a0c4-f2324878062e) Click the button, and, viola, the orgy begins. If there is an orgy in progress, the page will look like this: ![image](/attachments/b65be4b3-5db1-43cb-8857-7d3a8ea24ca7) Click the button, and the orgy stops. If an orgy is in progress, navigating to /chat will take the user to the orgy seemlessly. But what if they don't want to participate, liek some kind of spoilsport? Just navigate to /old_chat. That's just about it, it's really that simple. I have lots of ideas for the future, but I'll let that wait til later :). A few notes about implementation: - I moved some functionality out of /templates/chat.html and into /templates/util/macros.html. This is just so I could reference the code directly from my new template, /templates/orgy.html. - The orgy is stored as a single row in the new table "orgies". Okay, I know this is a little silly, but you know what they say: "if it's stupid and it works, it's not stupid". (tbf the oceangate ceo also said that) Co-authored-by: Chuck Sneed Reviewed-on: https://fsdfsd.net/rDrama/rDrama/pulls/165 Co-authored-by: HeyMoon Co-committed-by: HeyMoon --- files/assets/css/orgy.css | 14 +++ files/classes/orgy.py | 49 ++++++++++ files/helpers/config/const.py | 1 + files/routes/admin.py | 25 +++++ files/routes/chat.py | 14 +++ files/templates/admin/admin_home.html | 6 ++ files/templates/admin/orgy_control.html | 52 +++++++++++ files/templates/chat.html | 119 ++---------------------- files/templates/orgy.html | 46 +++++++++ files/templates/rules_rDrama.html | 9 +- files/templates/util/html_head.html | 1 + files/templates/util/macros.html | 117 +++++++++++++++++++++++ migrations/20230702-orgies.sql | 4 + nginx.conf | 4 + schema.sql | 7 ++ 15 files changed, 352 insertions(+), 116 deletions(-) create mode 100644 files/assets/css/orgy.css create mode 100644 files/classes/orgy.py create mode 100644 files/templates/admin/orgy_control.html create mode 100644 files/templates/orgy.html create mode 100644 migrations/20230702-orgies.sql diff --git a/files/assets/css/orgy.css b/files/assets/css/orgy.css new file mode 100644 index 000000000..f2d0bd40b --- /dev/null +++ b/files/assets/css/orgy.css @@ -0,0 +1,14 @@ +.orgy-top-container { + display: flex; + flex-flow: row nowrap; + justify-content: space-around; +} + +.orgy-chat-window-item { + flex-grow: 2; + width: fit-content; +} +.orgy-info-window-item { + max-width: 550px; + width: 550px; +} \ No newline at end of file diff --git a/files/classes/orgy.py b/files/classes/orgy.py new file mode 100644 index 000000000..83fa8d0b5 --- /dev/null +++ b/files/classes/orgy.py @@ -0,0 +1,49 @@ +import time +from math import floor +from random import randint +from urllib.parse import parse_qs, urlencode, urlparse +from flask import g + +from sqlalchemy import Column, ForeignKey +from sqlalchemy.dialects.postgresql import TSVECTOR +from sqlalchemy.orm import relationship, scoped_session +from sqlalchemy.schema import FetchedValue +from sqlalchemy.sql.sqltypes import * + +from files.classes import Base +from files.helpers.config.const import * +from files.helpers.lazy import lazy +from files.helpers.regex import * +from files.helpers.sorting_and_time import * + +class Orgy(Base): + __tablename__ = "orgies" + + youtube_id = Column(String, primary_key=True) + title = Column(String) + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + + def __repr__(self): + return f"<{self.__class__.__name__}(id={self.youtube_id}, title={self.title})>" + + +def get_orgy(): + orgy = g.db.query(Orgy).one_or_none() + return orgy + +def create_orgy(youtube_id, title): + assert not get_orgy() + assert re.match(yt_id_regex, youtube_id) + orgy = Orgy(title=title, youtube_id=youtube_id) + g.db.add(orgy) + g.db.flush() + g.db.commit() + +def end_orgy(): + assert get_orgy() + g.db.query(Orgy).delete() + g.db.flush() + g.db.commit() \ No newline at end of file diff --git a/files/helpers/config/const.py b/files/helpers/config/const.py index 2f0601ef8..9b4b915b7 100644 --- a/files/helpers/config/const.py +++ b/files/helpers/config/const.py @@ -518,6 +518,7 @@ PERMS = { # Minimum admin_level to perform action. 'LOTTERY_VIEW_PARTICIPANTS': 2, 'POST_COMMENT_INFINITE_PINGS': 2, 'IGNORE_1WEEk_EDITING_LIMIT': 2, + 'ORGIES': 2, 'ADMIN_REMOVE': 3, 'ADMIN_ACTIONS_REVERT': 3, diff --git a/files/routes/admin.py b/files/routes/admin.py index 7fb0b11ce..a3537a2b5 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -9,6 +9,7 @@ from psycopg2.errors import UniqueViolation from files.__main__ import app, cache, limiter from files.classes import * +from files.classes.orgy import * from files.helpers.actions import * from files.helpers.alerts import * from files.helpers.cloudflare import * @@ -1906,3 +1907,27 @@ def admin_reset_password(user_id, v): send_repeatable_notification(user.id, text) return {"message": f"@{user.username}'s password has been reset! The new password has been messaged to them!"} + +@app.get("/admin/orgy") +@admin_level_required(PERMS['ORGIES']) +def orgy_control(v): + return render_template("admin/orgy_control.html", v=v, orgy=get_orgy()) + +@app.post("/admin/start_orgy") +@admin_level_required(PERMS['ORGIES']) +def start_orgy(v): + youtube_id = request.values.get("youtube_id") + title = request.values.get("title") + + assert youtube_id + assert title + + create_orgy(youtube_id, title) + + return redirect("/chat") + +@app.post("/admin/stop_orgy") +@admin_level_required(PERMS['ORGIES']) +def stop_orgy(v): + end_orgy() + return redirect("/chat") \ No newline at end of file diff --git a/files/routes/chat.py b/files/routes/chat.py index 35e527337..5ecb6719e 100644 --- a/files/routes/chat.py +++ b/files/routes/chat.py @@ -13,6 +13,7 @@ from files.helpers.media import * from files.helpers.sanitize import * from files.helpers.alerts import push_notif from files.routes.wrappers import * +from files.classes.orgy import * from files.__main__ import app, cache, limiter @@ -33,6 +34,19 @@ messages = cache.get(f'messages') or {} @limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID) @is_not_permabanned def chat(v): + if not v.admin_level and TRUESCORE_CHAT_MINIMUM and v.truescore < TRUESCORE_CHAT_MINIMUM: + abort(403, f"Need at least {TRUESCORE_CHAT_MINIMUM} truescore for access to chat!") + orgy = get_orgy() + if orgy: + return render_template("orgy.html", v=v, messages=messages, orgy = orgy) + else: + return render_template("chat.html", v=v, messages=messages) + +@app.get("/old_chat") +@limiter.limit(DEFAULT_RATELIMIT) +@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID) +@is_not_permabanned +def old_chat(v): if not v.admin_level and TRUESCORE_CHAT_MINIMUM and v.truescore < TRUESCORE_CHAT_MINIMUM: abort(403, f"Need at least {TRUESCORE_CHAT_MINIMUM} truescore for access to chat!") return render_template("chat.html", v=v, messages=messages) diff --git a/files/templates/admin/admin_home.html b/files/templates/admin/admin_home.html index fb3e6d8a8..05ebeab71 100644 --- a/files/templates/admin/admin_home.html +++ b/files/templates/admin/admin_home.html @@ -98,6 +98,12 @@ {%- endif %} +{% if v.admin_level >= PERMS['ORGIES'] %} +

Misc

+ +{%- endif %}

Statistics

  • Content Stats
  • diff --git a/files/templates/admin/orgy_control.html b/files/templates/admin/orgy_control.html new file mode 100644 index 000000000..e45c0daa0 --- /dev/null +++ b/files/templates/admin/orgy_control.html @@ -0,0 +1,52 @@ +{% extends "default.html" %} + +{% block pagetitle %}Orgy Control Panel{% endblock %} + +{% block content %} +{% if msg %}{{macros.alert(msg, false)}}{% endif %} +
    +
    +
    +
    +

    Orgy Control Panel

    +
    +
    +
    +
    + {%if not orgy%} +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    + +
    +
    + {%else%} +
    + +
    + +
    +
    + {%endif%} +
    +
    +
    +
    +
    +{% endblock %} diff --git a/files/templates/chat.html b/files/templates/chat.html index 251fd80e9..6080990df 100644 --- a/files/templates/chat.html +++ b/files/templates/chat.html @@ -6,132 +6,27 @@ {% include "header.html" %} {% include "modals/expanded_image.html" %} {% include "modals/emoji.html" %} + {% include "util/macros.html" %} {% set vlink = '' %}
    - -
    - - - 0 - -
    - - {% macro chat_group_template(id, m) %} -
    -
    {% if m %}{{m['username']}}{% else %}NULL{% endif %}
    - {% if m %}{{m['time'] | timestamp}}{% else %}just now{% endif %} - - {% endmacro %} - - {% macro chat_line_template(id, m) %} - {% set quote_exists = m and m['quotes'] and messages.get(m['quotes']) %} - {% set mentioned = m and vlink in m['text_html'] or (quote_exists and messages[m['quotes']]['user_id'] == v.id) %} -
    -
    -
    - - -
    - - {% if m %} - {% if v.slurreplacer %} - {{m['text_censored'] | safe}} - {% else %} - {{m['text_html'] | safe}} - {% endif %} - {% endif %} - - {% if m %}{{m['text']}}{% endif %} - - {% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %} - - - {% endif %} -
    -
    -
    -
    - {% endmacro %} - + + {{ macros.chat_users_online() }}
    - {{chat_group_template()}} + {{macros.chat_group_template()}}
    - {{chat_line_template()}} + {{macros.chat_line_template()}}
    -
    -
    - {% set messages_list = messages.items()|list %} - {% for id, m in messages_list %} - {% set same = loop.index > 1 and m['user_id'] == messages_list[loop.index-2][1]['user_id'] %} - {% if not same %} - {% if loop.index > 1 %} -
    - {% endif %} - {{chat_group_template(id, m)}} - {% endif %} - {{chat_line_template(id, m)}} - {% endfor %} -
    -
    - -
    - - -
    -
    - - -
    - - - - - - - - - - - - -
    -
    + {{macros.chat_window(vlink)}}
    -
    -
    Users Online
    -
    -
    + {{macros.chat_users_list()}} diff --git a/files/templates/orgy.html b/files/templates/orgy.html new file mode 100644 index 000000000..f71a3d302 --- /dev/null +++ b/files/templates/orgy.html @@ -0,0 +1,46 @@ +{%- extends 'root.html' -%} +{% block pagetitle -%}Chat{%- endblock %} +{% block pagetype %}chat{% endblock %} +{% block body_attributes %}class="has_header"{% endblock %} +{% block body %} + {% include "header.html" %} + {% include "modals/expanded_image.html" %} + {% include "modals/emoji.html" %} + {% include "util/macros.html" %} + {% set vlink = '' %} +
    + +
    +
    +

    {{orgy.title}}

    +
    + +
    + {{macros.chat_users_list()}} +
    + +
    +
    + {{macros.chat_group_template()}} +
    +
    + +
    + {{macros.chat_line_template()}} +
    + {{macros.chat_users_online()}} + {{macros.chat_window(vlink)}} +
    + +
    + + + + + + + + + + +{% endblock %} diff --git a/files/templates/rules_rDrama.html b/files/templates/rules_rDrama.html index 7df594c41..264f37aef 100644 --- a/files/templates/rules_rDrama.html +++ b/files/templates/rules_rDrama.html @@ -1,6 +1,6 @@

    CURRENT EVENTS:

    -

    Bing Bing Wahoo Pet Contest

    Dramacoin prizes!
    -

    Independence Gay Grill-Off

    BADGE
    +

    Bing Bing Wahoo Pet Contest

    Dramacoin prizes!
    +

    Independence Gay Grill-Off

    BADGE



    @@ -10,7 +10,7 @@
    -

    𝐜𝐚𝐫𝐩 𝐰𝐨𝐳 𝐞𝐫𝐞

    \ No newline at end of file +

    𝐜𝐚𝐫𝐩 𝐰𝐨𝐳 𝐞𝐫𝐞

    +

    gaming!

    \ No newline at end of file diff --git a/files/templates/util/html_head.html b/files/templates/util/html_head.html index 9d444a789..60ea2089b 100644 --- a/files/templates/util/html_head.html +++ b/files/templates/util/html_head.html @@ -139,6 +139,7 @@ {% if request.path.endswith('/chat') %} + {% endif %} {% endmacro %} diff --git a/files/templates/util/macros.html b/files/templates/util/macros.html index 1ebb21174..e22b99c87 100644 --- a/files/templates/util/macros.html +++ b/files/templates/util/macros.html @@ -222,3 +222,120 @@ {% endif %} {% endmacro %} + +{% macro chat_users_online() %} +
    + + + 0 + +
    +{% endmacro %} + +{% macro chat_group_template(id, m) %} +
    +
    {% if m %}{{m['username']}}{% else %}NULL{% endif %}
    + {% if m %}{{m['time'] | timestamp}}{% else %}just now{% endif %} + +{% endmacro %} + +{% macro chat_line_template(id, m, vlink) %} + {% set quote_exists = m and m['quotes'] and messages.get(m['quotes']) %} + {% set mentioned = m and vlink in m['text_html'] or (quote_exists and messages[m['quotes']]['user_id'] == v.id) %} +
    +
    +
    + + +
    + + {% if m %} + {% if v.slurreplacer %} + {{m['text_censored'] | safe}} + {% else %} + {{m['text_html'] | safe}} + {% endif %} + {% endif %} + + {% if m %}{{m['text']}}{% endif %} + + {% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %} + + + {% endif %} +
    +
    +
    +
    +{% endmacro %} + +{% macro chat_window(vlink)%} +
    +
    + {% set messages_list = messages.items()|list %} + {% for id, m in messages_list %} + {% set same = loop.index > 1 and m['user_id'] == messages_list[loop.index-2][1]['user_id'] %} + {% if not same %} + {% if loop.index > 1 %} +
    + {% endif %} + {{chat_group_template(id, m)}} + {% endif %} + {{chat_line_template(id, m, vlink)}} + {% endfor %} +
    +
    + +
    + + +
    +
    + + +
    + + + + + + + + + + + + +
    + +{% endmacro %} + +{% macro chat_users_list() %} +
    +
    Users Online
    +
    +
    +{% endmacro %} \ No newline at end of file diff --git a/migrations/20230702-orgies.sql b/migrations/20230702-orgies.sql new file mode 100644 index 000000000..219c2a4cd --- /dev/null +++ b/migrations/20230702-orgies.sql @@ -0,0 +1,4 @@ +CREATE TABLE public.orgies ( + youtube_id character varying(12) NOT NULL, + title character varying(1000) NOT NULL +); \ No newline at end of file diff --git a/nginx.conf b/nginx.conf index 09b1591ab..d28d80e78 100644 --- a/nginx.conf +++ b/nginx.conf @@ -24,6 +24,10 @@ server { proxy_pass http://localhost:5001/chat; include includes/headers; } + location /old_chat { + proxy_pass http://localhost:5001/old_chat; + include includes/headers; + } location =/offline.html { alias /rDrama/files/assets/offline.html; include includes/headers; diff --git a/schema.sql b/schema.sql index fbff00c4b..63fe20b36 100644 --- a/schema.sql +++ b/schema.sql @@ -1126,6 +1126,13 @@ CREATE TABLE public.votes ( coins smallint DEFAULT 1 NOT NULL ); +-- +-- Name: orgies, Type: TABLE; Schema: public; Owner: - +-- +CREATE TABLE public.orgies ( + youtube_id character varying(12) NOT NULL, + title character varying(1000) NOT NULL +); -- -- Name: award_relationships id; Type: DEFAULT; Schema: public; Owner: -