diff --git a/internal/reader/rewrite/rewrite_functions.go b/internal/reader/rewrite/rewrite_functions.go
index e128a22a..3290d60b 100644
--- a/internal/reader/rewrite/rewrite_functions.go
+++ b/internal/reader/rewrite/rewrite_functions.go
@@ -21,10 +21,11 @@ import (
)
var (
- youtubeRegex = regexp.MustCompile(`youtube\.com/watch\?v=(.*)$`)
- youtubeIdRegex = regexp.MustCompile(`youtube_id"?\s*[:=]\s*"([a-zA-Z0-9_-]{11})"`)
- invidioRegex = regexp.MustCompile(`https?://(.*)/watch\?v=(.*)`)
- textLinkRegex = regexp.MustCompile(`(?mi)(\bhttps?:\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])`)
+ youtubeVideoRegex = regexp.MustCompile(`youtube\.com/watch\?v=(.*)$`)
+ youtubeShortRegex = regexp.MustCompile(`youtube\.com/shorts/([a-zA-Z0-9_-]{11})$`)
+ youtubeIdRegex = regexp.MustCompile(`youtube_id"?\s*[:=]\s*"([a-zA-Z0-9_-]{11})"`)
+ invidioRegex = regexp.MustCompile(`https?://(.*)/watch\?v=(.*)`)
+ textLinkRegex = regexp.MustCompile(`(?mi)(\bhttps?:\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])`)
)
// titlelize returns a copy of the string s with all Unicode letters that begin words
@@ -259,22 +260,34 @@ func useNoScriptImages(entryContent string) string {
return output
}
-func addYoutubeVideo(entryURL, entryContent string) string {
- matches := youtubeRegex.FindStringSubmatch(entryURL)
+func getYoutubVideoIDFromURL(entryURL string) string {
+ matches := youtubeVideoRegex.FindStringSubmatch(entryURL)
+
+ if len(matches) != 2 {
+ matches = youtubeShortRegex.FindStringSubmatch(entryURL)
+ }
if len(matches) == 2 {
- video := ``
- return video + `
` + entryContent
+ return matches[1]
+ }
+ return ""
+}
+
+func addVideoPlayerIframe(absoluteVideoURL, entryContent string) string {
+ video := ``
+ return video + `
` + entryContent
+}
+
+func addYoutubeVideoRewriteRule(entryURL, entryContent string) string {
+ if videoURL := getYoutubVideoIDFromURL(entryURL); videoURL != "" {
+ return addVideoPlayerIframe(config.Opts.YouTubeEmbedUrlOverride()+videoURL, entryContent)
}
return entryContent
}
func addYoutubeVideoUsingInvidiousPlayer(entryURL, entryContent string) string {
- matches := youtubeRegex.FindStringSubmatch(entryURL)
-
- if len(matches) == 2 {
- video := ``
- return video + `
` + entryContent
+ if videoURL := getYoutubVideoIDFromURL(entryURL); videoURL != "" {
+ return addVideoPlayerIframe(`https://`+config.Opts.InvidiousInstance()+`/embed/`+videoURL, entryContent)
}
return entryContent
}
diff --git a/internal/reader/rewrite/rewriter.go b/internal/reader/rewrite/rewriter.go
index 50284bc9..d22adf8e 100644
--- a/internal/reader/rewrite/rewriter.go
+++ b/internal/reader/rewrite/rewriter.go
@@ -29,7 +29,7 @@ func (rule rule) applyRule(entryURL string, entry *model.Entry) {
case "add_dynamic_iframe":
entry.Content = addDynamicIframe(entry.Content)
case "add_youtube_video":
- entry.Content = addYoutubeVideo(entryURL, entry.Content)
+ entry.Content = addYoutubeVideoRewriteRule(entryURL, entry.Content)
case "add_invidious_video":
entry.Content = addInvidiousVideo(entryURL, entry.Content)
case "add_youtube_video_using_invidious_player":
diff --git a/internal/reader/rewrite/rewriter_test.go b/internal/reader/rewrite/rewriter_test.go
index 4d9ba582..b0b7564d 100644
--- a/internal/reader/rewrite/rewriter_test.go
+++ b/internal/reader/rewrite/rewriter_test.go
@@ -66,7 +66,7 @@ func TestRewriteWithNoMatchingRule(t *testing.T) {
}
}
-func TestRewriteWithYoutubeLink(t *testing.T) {
+func TestRewriteYoutubeVideoLink(t *testing.T) {
config.Opts = config.NewOptions()
controlEntry := &model.Entry{
@@ -86,7 +86,47 @@ func TestRewriteWithYoutubeLink(t *testing.T) {
}
}
-func TestRewriteWithYoutubeLinkAndCustomEmbedURL(t *testing.T) {
+func TestRewriteYoutubeShortLink(t *testing.T) {
+ config.Opts = config.NewOptions()
+
+ controlEntry := &model.Entry{
+ URL: "https://www.youtube.com/shorts/1LUWKWZkPjo",
+ Title: `A title`,
+ Content: `
Video Description`,
+ }
+ testEntry := &model.Entry{
+ URL: "https://www.youtube.com/shorts/1LUWKWZkPjo",
+ Title: `A title`,
+ Content: `Video Description`,
+ }
+ ApplyContentRewriteRules(testEntry, ``)
+
+ if !reflect.DeepEqual(testEntry, controlEntry) {
+ t.Errorf(`Not expected output: got "%+v" instead of "%+v"`, testEntry, controlEntry)
+ }
+}
+
+func TestRewriteIncorrectYoutubeLink(t *testing.T) {
+ config.Opts = config.NewOptions()
+
+ controlEntry := &model.Entry{
+ URL: "https://www.youtube.com/some-page",
+ Title: `A title`,
+ Content: `Video Description`,
+ }
+ testEntry := &model.Entry{
+ URL: "https://www.youtube.com/some-page",
+ Title: `A title`,
+ Content: `Video Description`,
+ }
+ ApplyContentRewriteRules(testEntry, ``)
+
+ if !reflect.DeepEqual(testEntry, controlEntry) {
+ t.Errorf(`Not expected output: got "%+v" instead of "%+v"`, testEntry, controlEntry)
+ }
+}
+
+func TestRewriteYoutubeLinkAndCustomEmbedURL(t *testing.T) {
os.Clearenv()
os.Setenv("YOUTUBE_EMBED_URL_OVERRIDE", "https://invidious.custom/embed/")
@@ -115,6 +155,46 @@ func TestRewriteWithYoutubeLinkAndCustomEmbedURL(t *testing.T) {
}
}
+func TestRewriteYoutubeVideoLinkUsingInvidious(t *testing.T) {
+ config.Opts = config.NewOptions()
+ controlEntry := &model.Entry{
+ URL: "https://www.youtube.com/watch?v=1234",
+ Title: `A title`,
+ Content: `
Video Description`,
+ }
+ testEntry := &model.Entry{
+ URL: "https://www.youtube.com/watch?v=1234",
+ Title: `A title`,
+ Content: `Video Description`,
+ }
+
+ ApplyContentRewriteRules(testEntry, `add_youtube_video_using_invidious_player`)
+
+ if !reflect.DeepEqual(testEntry, controlEntry) {
+ t.Errorf(`Not expected output: got "%+v" instead of "%+v"`, testEntry, controlEntry)
+ }
+}
+
+func TestRewriteYoutubeShortLinkUsingInvidious(t *testing.T) {
+ config.Opts = config.NewOptions()
+ controlEntry := &model.Entry{
+ URL: "https://www.youtube.com/shorts/1LUWKWZkPjo",
+ Title: `A title`,
+ Content: `
Video Description`,
+ }
+ testEntry := &model.Entry{
+ URL: "https://www.youtube.com/shorts/1LUWKWZkPjo",
+ Title: `A title`,
+ Content: `Video Description`,
+ }
+
+ ApplyContentRewriteRules(testEntry, `add_youtube_video_using_invidious_player`)
+
+ if !reflect.DeepEqual(testEntry, controlEntry) {
+ t.Errorf(`Not expected output: got "%+v" instead of "%+v"`, testEntry, controlEntry)
+ }
+}
+
func TestRewriteWithInexistingCustomRule(t *testing.T) {
controlEntry := &model.Entry{
URL: "https://www.youtube.com/watch?v=1234",