diff --git a/files/assets/css/orgy.css b/files/assets/css/orgy.css index 8c40ea6fb..ab33aaa00 100644 --- a/files/assets/css/orgy.css +++ b/files/assets/css/orgy.css @@ -1,9 +1,27 @@ .orgy-top-container { display: flex; - flex-flow: row nowrap; justify-content: space-around; } +@media all and (max-width: 900px) { + .orgy-top-container { + flex-flow: column wrap; + } + .orgy-info-window-item { + max-height: 20% !important; + height: 20% !important; + } + .orgy-chat-window-item { + max-height: 80% !important; + height: 80% !important; + } +} +@media all and (min-width: 900px) { + .orgy-top-container { + flex-flow: row nowrap; + } +} + .orgy-chat-window-item { flex-grow: 2; width: fit-content; @@ -12,3 +30,8 @@ max-width: 550px; width: 550px; } +.rumble-player { + aspect-ratio: 16/9; + max-width: min(70vw,500px) !important; + width: 500px; +} diff --git a/files/classes/orgy.py b/files/classes/orgy.py index 7b9d50990..7a7674142 100644 --- a/files/classes/orgy.py +++ b/files/classes/orgy.py @@ -15,29 +15,52 @@ from files.helpers.config.const import * from files.helpers.lazy import lazy from files.helpers.regex import * from files.helpers.sorting_and_time import * +from files.helpers.sanitize import normalize_url, get_youtube_id_and_t class Orgy(Base): __tablename__ = "orgies" - youtube_id = Column(String, primary_key=True) + id = Column(Integer, primary_key = True) + type = Column(Integer, primary_key = True) + data = Column(String) title = Column(String) def __init__(self, **kwargs): super().__init__(**kwargs) + def is_youtube(self): + return self.type == OrgyTypes.YOUTUBE + def is_rumble(self): + return self.type == OrgyTypes.RUMBLE + def is_twitch(self): + return self.type == OrgyTypes.TWITCH def __repr__(self): - return f"<{self.__class__.__name__}(id={self.youtube_id}, title={self.title})>" + return f"<{self.__class__.__name__}(id={self.id}, type={self.type}, data={self.data} title={self.title})>" def get_orgy(): orgy = g.db.query(Orgy).one_or_none() return orgy -def create_orgy(youtube_id, title): +def create_orgy(link, title): assert not get_orgy() - assert re.match(yt_id_regex, youtube_id) - orgy = Orgy(title=title, youtube_id=youtube_id) + normalized_link = normalize_url(link) + data = None + orgy_type = -1 + if re.match(bare_youtube_regex, normalized_link): + orgy_type = OrgyTypes.YOUTUBE + data, _ = get_youtube_id_and_t(normalized_link) + elif re.match(rumble_regex, normalized_link): + orgy_type = OrgyTypes.RUMBLE + data = normalized_link + elif re.match(twitch_regex, normalized_link): + orgy_type = OrgyTypes.TWITCH + data = re.search(twitch_regex, normalized_link).group(3) + else: + assert False + + orgy = Orgy(title=title, id=0, type = orgy_type, data = data) g.db.add(orgy) g.db.flush() g.db.commit() diff --git a/files/helpers/config/const.py b/files/helpers/config/const.py index ee3c6ebb5..0e97e7612 100644 --- a/files/helpers/config/const.py +++ b/files/helpers/config/const.py @@ -1265,6 +1265,11 @@ GIRL_NAMES = { 'Z': ['Zoe', 'Zoey', 'Zaria', 'Zoie'] } +class OrgyTypes: + YOUTUBE = 1 + RUMBLE = 2 + TWITCH = 3 + from sqlalchemy import * from sqlalchemy.orm import scoped_session, sessionmaker diff --git a/files/helpers/regex.py b/files/helpers/regex.py index dcc947663..e8024b198 100644 --- a/files/helpers/regex.py +++ b/files/helpers/regex.py @@ -126,6 +126,10 @@ giphy_regex = re.compile('(https:\/\/media\.giphy\.com\/media\/[a-z0-9]+\/giphy) youtube_regex = re.compile('(

[^<]*)(https:\/\/youtube\.com\/watch\?[\w\-.#&/=?@%+]{7,})', flags=re.I|re.A) yt_id_regex = re.compile('[\w\-]{5,20}', flags=re.A) +rumble_regex = re.compile('https://rumble\.com/embed/([a-zA-Z0-9]*)/\?pub=([a-zA-Z0-9]*)',flags=re.I|re.A) +bare_youtube_regex = re.compile('https:\/\/youtube\.com\/watch\?([\w\-.#&/=?@%+]{7,})',flags=re.I|re.A) +twitch_regex = re.compile('(https:\/\/)?(www\.)?twitch.tv/(.*)',flags=re.I|re.A) + link_fix_regex = re.compile("(\[.*?\]\()(?!http|\/)(.*?\))" + NOT_IN_CODE_OR_LINKS, flags=re.A) css_url_regex = re.compile('url\(\s*[\'"]?(.*?)[\'"]?\s*\)', flags=re.I|re.A) diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index d617bdb1b..d0bf58d94 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -300,14 +300,12 @@ def sanitize_settings_text(sanitized:Optional[str], max_length:Optional[int]=Non if max_length: sanitized = sanitized[:max_length] return sanitized - -def handle_youtube_links(url): - html = None +def get_youtube_id_and_t(url): params = parse_qs(urlparse(url).query, keep_blank_values=True) id = params.get('v') - if not id: return None + if not id: return (None, None) id = id[0] @@ -318,7 +316,14 @@ def handle_youtube_links(url): t = split[1] id = id.split('?')[0] + + return (id, t) +def handle_youtube_links(url): + params = parse_qs(urlparse(url).query, keep_blank_values=True) + html = None + id, t = get_youtube_id_and_t(url) + if not id: return None if yt_id_regex.fullmatch(id): if not t: t = params.get('t', params.get('start', [0]))[0] diff --git a/files/routes/admin.py b/files/routes/admin.py index 8d37e8967..343763ac9 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -1917,13 +1917,13 @@ def orgy_control(v): @app.post("/admin/start_orgy") @admin_level_required(PERMS['ORGIES']) def start_orgy(v): - youtube_id = request.values.get("youtube_id") + link = request.values.get("link") title = request.values.get("title") - assert youtube_id + assert link assert title - create_orgy(youtube_id, title) + create_orgy(link, title) return redirect("/chat") diff --git a/files/routes/chat.py b/files/routes/chat.py index 5ecb6719e..b15e0cfe6 100644 --- a/files/routes/chat.py +++ b/files/routes/chat.py @@ -38,7 +38,7 @@ def chat(v): 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) + return render_template("orgy.html", v=v, messages=messages, orgy = orgy, site = SITE) else: return render_template("chat.html", v=v, messages=messages) diff --git a/files/templates/admin/orgy_control.html b/files/templates/admin/orgy_control.html index e45c0daa0..123085c70 100644 --- a/files/templates/admin/orgy_control.html +++ b/files/templates/admin/orgy_control.html @@ -25,10 +25,10 @@

- +
- +
diff --git a/files/templates/orgy.html b/files/templates/orgy.html index 2047f8dc7..9d6c6251d 100644 --- a/files/templates/orgy.html +++ b/files/templates/orgy.html @@ -11,11 +11,22 @@
-
+

{{orgy.title}}

- + {% if orgy.is_youtube() %} + + {% elif orgy.is_rumble() %} + + {% elif orgy.is_twitch() %} + + {%endif%}
+ Old Chat {{macros.chat_users_list()}}
diff --git a/migrations/20230709-orgy-rumble.sql b/migrations/20230709-orgy-rumble.sql new file mode 100644 index 000000000..0b054f933 --- /dev/null +++ b/migrations/20230709-orgy-rumble.sql @@ -0,0 +1,7 @@ +DROP TABLE orgies; --Don't worry: Orgies should only have between 0 and 1 rows... +CREATE TABLE public.orgies ( + id integer NOT NULL, + type integer NOT NULL, + data character varying(200) NOT NULL, + title character varying(1000) NOT NULL +); diff --git a/nginx-headers.conf b/nginx-headers.conf index bca41f6b0..95699ea61 100644 --- a/nginx-headers.conf +++ b/nginx-headers.conf @@ -2,5 +2,5 @@ add_header Referrer-Policy "same-origin"; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; add_header X-Frame-Options "deny"; add_header X-Content-Type-Options "nosniff"; -add_header Content-Security-Policy "default-src 'none'; frame-ancestors 'none'; form-action 'self'; manifest-src 'self'; worker-src 'self'; base-uri 'self'; font-src 'self'; style-src-elem 'self'; style-src-attr 'unsafe-inline'; style-src 'self' 'unsafe-inline'; script-src-elem 'self' challenges.cloudflare.com; script-src-attr 'none'; script-src 'self' challenges.cloudflare.com; media-src 'self' https:; img-src 'self' https: data:; frame-src challenges.cloudflare.com www.youtube-nocookie.com platform.twitter.com; connect-src 'self' tls-use1.fpapi.io api.fpjs.io;"; +add_header Content-Security-Policy "default-src 'none'; frame-ancestors 'none'; form-action 'self'; manifest-src 'self'; worker-src 'self'; base-uri 'self'; font-src 'self'; style-src-elem 'self'; style-src-attr 'unsafe-inline'; style-src 'self' 'unsafe-inline'; script-src-elem 'self' challenges.cloudflare.com; script-src-attr 'none'; script-src 'self' challenges.cloudflare.com; media-src 'self' https:; img-src 'self' https: data:; frame-src challenges.cloudflare.com www.youtube-nocookie.com platform.twitter.com rumble.com player.twitch.tv; connect-src 'self' tls-use1.fpapi.io api.fpjs.io;"; add_header Cross-Origin-Opener-Policy "same-origin"; diff --git a/schema.sql b/schema.sql index d87128608..b83059566 100644 --- a/schema.sql +++ b/schema.sql @@ -1133,6 +1133,15 @@ CREATE TABLE public.votes ( coins smallint DEFAULT 1 NOT NULL ); +-- +-- Name: orgies, Type: TABLE; Schema: public; Owner: - +-- +CREATE TABLE public.orgies ( + id integer NOT NULL, + type integer NOT NULL, + data character varying(200) NOT NULL, + title character varying(1000) NOT NULL +); -- -- Name: award_relationships id; Type: DEFAULT; Schema: public; Owner: -