Add Youtube embeds
This will embed a youtube video inline on the page. Hopefully it works! Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -345,6 +345,27 @@ $(window).on("load", () => {
|
||||
$(e.target).attr("src", thumbUrl);
|
||||
}
|
||||
});
|
||||
|
||||
$(".youtube_embed_link").on("click", (e) => {
|
||||
e.preventDefault();
|
||||
let fullEnt = $(e.target).parents(".youtube_embed");
|
||||
let frame = fullEnt.find(".youtube_embed_frame");
|
||||
if (frame.length) {
|
||||
frame.remove();
|
||||
} else {
|
||||
let hash = $(e.target).attr("data-yt-hash");
|
||||
let embed = $("<span>")
|
||||
.attr("class", "youtube_embed_frame")
|
||||
.append("<br/>")
|
||||
.append(
|
||||
$("<iframe>")
|
||||
.attr("src", "https://www.youtube.com/embed/" + hash)
|
||||
.attr("frameborder", "0")
|
||||
.attr("allow", "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture")
|
||||
);
|
||||
fullEnt.find(".youtube_embed_container").append(embed);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Load event that actually does stuff
|
||||
|
||||
@@ -169,6 +169,9 @@ th {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
/* Youtube embeds */
|
||||
|
||||
|
||||
/* Spoilers */
|
||||
|
||||
.spoiler {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import re
|
||||
from typing import Match, Pattern
|
||||
from django import template
|
||||
from board.models import Post
|
||||
|
||||
@@ -6,6 +7,9 @@ from board.models import Post
|
||||
REPLY_START_RE = re.compile(r"^>>\d+")
|
||||
REPLY_RE = re.compile(r">>\d+")
|
||||
QUOTE_RE = re.compile(r">.+$")
|
||||
YOUTUBE_RE = re.compile(
|
||||
r"https?://(((www\.)?youtube\.com/watch\?v=)|(youtu\.be/(watch\?v=)?))(?P<yt_hash>[a-zA-Z0-9_\-]{11})"
|
||||
)
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@@ -19,9 +23,12 @@ def htmlspecialchars(t: str):
|
||||
|
||||
|
||||
class ReplyBuilder:
|
||||
def __init__(self, text: str, parse_spoilers: bool = False):
|
||||
def __init__(
|
||||
self, text: str, parse_spoilers: bool = False, parse_youtube: bool = True
|
||||
):
|
||||
self.text = text
|
||||
self.parse_spoilers = parse_spoilers
|
||||
self.parse_youtube = parse_youtube
|
||||
self.index = 0
|
||||
self.final = ""
|
||||
|
||||
@@ -46,8 +53,12 @@ class ReplyBuilder:
|
||||
def adv(self, n=1):
|
||||
self.index += n
|
||||
|
||||
def matches(self, prefix: str) -> bool:
|
||||
return self.remain[: len(prefix)] == prefix
|
||||
def matches(self, prefix: str | Pattern) -> bool | Match:
|
||||
if isinstance(prefix, str):
|
||||
return self.remain.startswith(prefix)
|
||||
else:
|
||||
mat = prefix.match(self.remain)
|
||||
return mat or False
|
||||
|
||||
def build(self) -> str:
|
||||
while self.c:
|
||||
@@ -60,6 +71,12 @@ class ReplyBuilder:
|
||||
self.adv(9)
|
||||
elif self.parse_spoilers and self.matches("[spoiler]"):
|
||||
self.do_spoiler()
|
||||
elif self.parse_youtube and (mat := self.matches(YOUTUBE_RE)):
|
||||
assert isinstance(mat, Match)
|
||||
url = mat[0]
|
||||
yt_hash = mat["yt_hash"]
|
||||
self.final += f'<span class="youtube_embed"><span class="youtube_embed_container">{url} [<a class="youtube_embed_link" data-yt-hash="{yt_hash}" href="{url}">Embed</a>]</span></span>'
|
||||
self.adv(len(url))
|
||||
else:
|
||||
self.final += self.c
|
||||
self.adv()
|
||||
|
||||
@@ -103,3 +103,15 @@ what happened to the 1 2 3 4 5 6 7 8 9
|
||||
for input, output in expected:
|
||||
rb = ReplyBuilder(input.strip(), parse_spoilers=True)
|
||||
self.assertEquals(rb.build(), output)
|
||||
|
||||
def test_youtube_embed(self):
|
||||
expected = [
|
||||
(
|
||||
"https://www.youtube.com/watch?v=O_3_-UrhZH0",
|
||||
'<span class="youtube_embed"><span class="youtube_embed_container">https://www.youtube.com/watch?v=O_3_-UrhZH0 [<a class="youtube_embed_link" data-yt-hash="O_3_-UrhZH0" href="https://www.youtube.com/watch?v=O_3_-UrhZH0">Embed</a>]</span></span>',
|
||||
),
|
||||
]
|
||||
|
||||
for input, output in expected:
|
||||
rb = ReplyBuilder(input.strip())
|
||||
self.assertEquals(rb.build(), output)
|
||||
|
||||
Reference in New Issue
Block a user