forked from MarseyWorld/MarseyWorld
Orgies: Support Rumble and Twitch and Mobile Viewing (#169)
Hell yeah - Rumble.com, basically youtube for rightoids (so you can do more edgy streams) - Twitch - Mobile orgy support, it's pretty bad thoever - Button to switch back to normalchat for phonefags Co-authored-by: Chuck Sneed <sneed@formerlychucks.net> Reviewed-on: rDrama/rDrama#169 Co-authored-by: HeyMoon <heymoon@noreply.fsdfsd.net> Co-committed-by: HeyMoon <heymoon@noreply.fsdfsd.net>master
parent
e7e2b49c84
commit
abd91f81ac
|
@ -1,9 +1,27 @@
|
||||||
.orgy-top-container {
|
.orgy-top-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row nowrap;
|
|
||||||
justify-content: space-around;
|
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 {
|
.orgy-chat-window-item {
|
||||||
flex-grow: 2;
|
flex-grow: 2;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
|
@ -12,3 +30,8 @@
|
||||||
max-width: 550px;
|
max-width: 550px;
|
||||||
width: 550px;
|
width: 550px;
|
||||||
}
|
}
|
||||||
|
.rumble-player {
|
||||||
|
aspect-ratio: 16/9;
|
||||||
|
max-width: min(70vw,500px) !important;
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
|
|
@ -15,29 +15,52 @@ from files.helpers.config.const import *
|
||||||
from files.helpers.lazy import lazy
|
from files.helpers.lazy import lazy
|
||||||
from files.helpers.regex import *
|
from files.helpers.regex import *
|
||||||
from files.helpers.sorting_and_time import *
|
from files.helpers.sorting_and_time import *
|
||||||
|
from files.helpers.sanitize import normalize_url, get_youtube_id_and_t
|
||||||
|
|
||||||
class Orgy(Base):
|
class Orgy(Base):
|
||||||
__tablename__ = "orgies"
|
__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)
|
title = Column(String)
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**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):
|
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():
|
def get_orgy():
|
||||||
orgy = g.db.query(Orgy).one_or_none()
|
orgy = g.db.query(Orgy).one_or_none()
|
||||||
return orgy
|
return orgy
|
||||||
|
|
||||||
def create_orgy(youtube_id, title):
|
def create_orgy(link, title):
|
||||||
assert not get_orgy()
|
assert not get_orgy()
|
||||||
assert re.match(yt_id_regex, youtube_id)
|
normalized_link = normalize_url(link)
|
||||||
orgy = Orgy(title=title, youtube_id=youtube_id)
|
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.add(orgy)
|
||||||
g.db.flush()
|
g.db.flush()
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
|
@ -1265,6 +1265,11 @@ GIRL_NAMES = {
|
||||||
'Z': ['Zoe', 'Zoey', 'Zaria', 'Zoie']
|
'Z': ['Zoe', 'Zoey', 'Zaria', 'Zoie']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class OrgyTypes:
|
||||||
|
YOUTUBE = 1
|
||||||
|
RUMBLE = 2
|
||||||
|
TWITCH = 3
|
||||||
|
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from sqlalchemy.orm import scoped_session, sessionmaker
|
from sqlalchemy.orm import scoped_session, sessionmaker
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,10 @@ giphy_regex = re.compile('(https:\/\/media\.giphy\.com\/media\/[a-z0-9]+\/giphy)
|
||||||
youtube_regex = re.compile('(<p>[^<]*)(https:\/\/youtube\.com\/watch\?[\w\-.#&/=?@%+]{7,})', flags=re.I|re.A)
|
youtube_regex = re.compile('(<p>[^<]*)(https:\/\/youtube\.com\/watch\?[\w\-.#&/=?@%+]{7,})', flags=re.I|re.A)
|
||||||
yt_id_regex = re.compile('[\w\-]{5,20}', flags=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)
|
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)
|
css_url_regex = re.compile('url\(\s*[\'"]?(.*?)[\'"]?\s*\)', flags=re.I|re.A)
|
||||||
|
|
|
@ -300,14 +300,12 @@ def sanitize_settings_text(sanitized:Optional[str], max_length:Optional[int]=Non
|
||||||
if max_length: sanitized = sanitized[:max_length]
|
if max_length: sanitized = sanitized[:max_length]
|
||||||
return sanitized
|
return sanitized
|
||||||
|
|
||||||
|
def get_youtube_id_and_t(url):
|
||||||
def handle_youtube_links(url):
|
|
||||||
html = None
|
|
||||||
params = parse_qs(urlparse(url).query, keep_blank_values=True)
|
params = parse_qs(urlparse(url).query, keep_blank_values=True)
|
||||||
|
|
||||||
id = params.get('v')
|
id = params.get('v')
|
||||||
|
|
||||||
if not id: return None
|
if not id: return (None, None)
|
||||||
|
|
||||||
id = id[0]
|
id = id[0]
|
||||||
|
|
||||||
|
@ -319,6 +317,13 @@ def handle_youtube_links(url):
|
||||||
|
|
||||||
id = id.split('?')[0]
|
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 yt_id_regex.fullmatch(id):
|
||||||
if not t:
|
if not t:
|
||||||
t = params.get('t', params.get('start', [0]))[0]
|
t = params.get('t', params.get('start', [0]))[0]
|
||||||
|
|
|
@ -1917,13 +1917,13 @@ def orgy_control(v):
|
||||||
@app.post("/admin/start_orgy")
|
@app.post("/admin/start_orgy")
|
||||||
@admin_level_required(PERMS['ORGIES'])
|
@admin_level_required(PERMS['ORGIES'])
|
||||||
def start_orgy(v):
|
def start_orgy(v):
|
||||||
youtube_id = request.values.get("youtube_id")
|
link = request.values.get("link")
|
||||||
title = request.values.get("title")
|
title = request.values.get("title")
|
||||||
|
|
||||||
assert youtube_id
|
assert link
|
||||||
assert title
|
assert title
|
||||||
|
|
||||||
create_orgy(youtube_id, title)
|
create_orgy(link, title)
|
||||||
|
|
||||||
return redirect("/chat")
|
return redirect("/chat")
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ def chat(v):
|
||||||
abort(403, f"Need at least {TRUESCORE_CHAT_MINIMUM} truescore for access to chat!")
|
abort(403, f"Need at least {TRUESCORE_CHAT_MINIMUM} truescore for access to chat!")
|
||||||
orgy = get_orgy()
|
orgy = get_orgy()
|
||||||
if 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:
|
else:
|
||||||
return render_template("chat.html", v=v, messages=messages)
|
return render_template("chat.html", v=v, messages=messages)
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="d-lg-flex border-bottom">
|
<div class="d-lg-flex border-bottom">
|
||||||
<div class="title w-lg-25">
|
<div class="title w-lg-25">
|
||||||
<label for="youtube_id">Youtube ID</label>
|
<label for="link">Link</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="body w-lg-100">
|
<div class="body w-lg-100">
|
||||||
<input id="youtube_id" autocomplete="off" type="text" name="youtube_id" class="form-control">
|
<input id="link" autocomplete="off" type="text" name="link" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input hidden name="formkey" value="{{v|formkey}}">
|
<input hidden name="formkey" value="{{v|formkey}}">
|
||||||
|
|
|
@ -11,11 +11,22 @@
|
||||||
<div class="container pb-4">
|
<div class="container pb-4">
|
||||||
|
|
||||||
<div class="orgy-top-container">
|
<div class="orgy-top-container">
|
||||||
<div class="col text-left d-none d-lg-block pt-3 orgy-info-window-item">
|
<div class="col text-left pt-3 orgy-info-window-item">
|
||||||
<h2>{{orgy.title}}</h1>
|
<h2>{{orgy.title}}</h1>
|
||||||
<div>
|
<div>
|
||||||
<lite-youtube videoid="{{orgy.youtube_id}}" params="autoplay=1&modestbranding=1"/>
|
{% if orgy.is_youtube() %}
|
||||||
|
<lite-youtube videoid="{{orgy.data}}" params="autoplay=1&modestbranding=1"/>
|
||||||
|
{% elif orgy.is_rumble() %}
|
||||||
|
<iframe class="rumble rumble-player" width="100%" src="{{orgy.data}}" frameborder="0" allowfullscreen></iframe>
|
||||||
|
{% elif orgy.is_twitch() %}
|
||||||
|
<iframe
|
||||||
|
src="https://player.twitch.tv/?channel={{orgy.data}}&parent={{site}}"
|
||||||
|
class="rumble-player"
|
||||||
|
allowfullscreen>
|
||||||
|
</iframe>
|
||||||
|
{%endif%}
|
||||||
</div>
|
</div>
|
||||||
|
<a href="/old_chat" class="btn btn-primary ml-auto" value="Old Chat">Old Chat</a>
|
||||||
{{macros.chat_users_list()}}
|
{{macros.chat_users_list()}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
);
|
|
@ -2,5 +2,5 @@ add_header Referrer-Policy "same-origin";
|
||||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
|
||||||
add_header X-Frame-Options "deny";
|
add_header X-Frame-Options "deny";
|
||||||
add_header X-Content-Type-Options "nosniff";
|
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";
|
add_header Cross-Origin-Opener-Policy "same-origin";
|
||||||
|
|
|
@ -1133,6 +1133,15 @@ CREATE TABLE public.votes (
|
||||||
coins smallint DEFAULT 1 NOT NULL
|
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: -
|
-- Name: award_relationships id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
|
|
Loading…
Reference in New Issue