1
0
Fork 0
mirror of https://github.com/miniflux/v2.git synced 2025-07-07 16:48:36 +00:00

Add the possibility to define rewrite rules for each feed

This commit is contained in:
Frédéric Guillot 2017-12-11 22:16:32 -08:00
parent 87ccad5c7f
commit 33445e5b68
29 changed files with 214 additions and 72 deletions

View file

@ -0,0 +1,40 @@
// Copyright 2017 Frédéric Guillot. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.
package rewrite
import (
"regexp"
"strings"
"github.com/PuerkitoBio/goquery"
)
var (
youtubeRegex = regexp.MustCompile(`youtube\.com/watch\?v=(.*)`)
)
func addImageTitle(entryURL, entryContent string) string {
doc, err := goquery.NewDocumentFromReader(strings.NewReader(entryContent))
if err != nil {
return entryContent
}
imgTag := doc.Find("img").First()
if titleAttr, found := imgTag.Attr("title"); found {
return entryContent + `<blockquote cite="` + entryURL + `">` + titleAttr + "</blockquote>"
}
return entryContent
}
func addYoutubeVideo(entryURL, entryContent string) string {
matches := youtubeRegex.FindStringSubmatch(entryURL)
if len(matches) == 2 {
video := `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/` + matches[1] + `" allowfullscreen></iframe>`
return video + "<p>" + entryContent + "</p>"
}
return entryContent
}

View file

@ -5,44 +5,39 @@
package rewrite
import (
"regexp"
"strings"
"github.com/PuerkitoBio/goquery"
"github.com/miniflux/miniflux2/url"
)
var rewriteRules = []func(string, string) string{
func(url, content string) string {
re := regexp.MustCompile(`youtube\.com/watch\?v=(.*)`)
matches := re.FindStringSubmatch(url)
if len(matches) == 2 {
video := `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/` + matches[1] + `" allowfullscreen></iframe>`
return video + "<p>" + content + "</p>"
}
return content
},
func(url, content string) string {
if strings.HasPrefix(url, "https://xkcd.com") {
doc, err := goquery.NewDocumentFromReader(strings.NewReader(content))
if err != nil {
return content
}
imgTag := doc.Find("img").First()
if titleAttr, found := imgTag.Attr("title"); found {
return content + `<blockquote cite="` + url + `">` + titleAttr + "</blockquote>"
}
}
return content
},
}
// Rewriter modify item contents with a set of rewriting rules.
func Rewriter(url, content string) string {
for _, rewriteRule := range rewriteRules {
content = rewriteRule(url, content)
func Rewriter(entryURL, entryContent, customRewriteRules string) string {
rulesList := getPredefinedRewriteRules(entryURL)
if customRewriteRules != "" {
rulesList = customRewriteRules
}
return content
rules := strings.Split(rulesList, ",")
for _, rule := range rules {
switch strings.TrimSpace(rule) {
case "add_image_title":
entryContent = addImageTitle(entryURL, entryContent)
case "add_youtube_video":
entryContent = addYoutubeVideo(entryURL, entryContent)
}
}
return entryContent
}
func getPredefinedRewriteRules(entryURL string) string {
urlDomain := url.Domain(entryURL)
for domain, rules := range predefinedRules {
if strings.Contains(urlDomain, domain) {
return rules
}
}
return ""
}

View file

@ -7,7 +7,7 @@ package rewrite
import "testing"
func TestRewriteWithNoMatchingRule(t *testing.T) {
output := Rewriter("https://example.org/article", `Some text.`)
output := Rewriter("https://example.org/article", `Some text.`, ``)
expected := `Some text.`
if expected != output {
@ -16,7 +16,7 @@ func TestRewriteWithNoMatchingRule(t *testing.T) {
}
func TestRewriteWithYoutubeLink(t *testing.T) {
output := Rewriter("https://www.youtube.com/watch?v=1234", `Video Description`)
output := Rewriter("https://www.youtube.com/watch?v=1234", `Video Description`, ``)
expected := `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/1234" allowfullscreen></iframe><p>Video Description</p>`
if expected != output {
@ -24,11 +24,37 @@ func TestRewriteWithYoutubeLink(t *testing.T) {
}
}
func TestRewriteWithInexistingCustomRule(t *testing.T) {
output := Rewriter("https://www.youtube.com/watch?v=1234", `Video Description`, `some rule`)
expected := `Video Description`
if expected != output {
t.Errorf(`Not expected output: got "%s" instead of "%s"`, output, expected)
}
}
func TestRewriteWithXkcdLink(t *testing.T) {
description := `<img src="https://imgs.xkcd.com/comics/thermostat.png" title="Your problem is so terrible, I worry that, if I help you, I risk drawing the attention of whatever god of technology inflicted it on you." alt="Your problem is so terrible, I worry that, if I help you, I risk drawing the attention of whatever god of technology inflicted it on you." />`
output := Rewriter("https://xkcd.com/1912/", description)
output := Rewriter("https://xkcd.com/1912/", description, ``)
expected := description + `<blockquote cite="https://xkcd.com/1912/">Your problem is so terrible, I worry that, if I help you, I risk drawing the attention of whatever god of technology inflicted it on you.</blockquote>`
if expected != output {
t.Errorf(`Not expected output: got "%s" instead of "%s"`, output, expected)
}
}
func TestRewriteWithXkcdLinkAndNoImage(t *testing.T) {
description := "test"
output := Rewriter("https://xkcd.com/1912/", description, ``)
expected := description
if expected != output {
t.Errorf(`Not expected output: got "%s" instead of "%s"`, output, expected)
}
}
func TestRewriteWithXkcdAndNoImage(t *testing.T) {
description := "test"
output := Rewriter("https://xkcd.com/1912/", description, ``)
expected := description
if expected != output {
t.Errorf(`Not expected output: got "%s" instead of "%s"`, output, expected)
}
}

30
reader/rewrite/rules.go Normal file
View file

@ -0,0 +1,30 @@
// Copyright 2017 Frédéric Guillot. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.
package rewrite
// List of predefined rewrite rules (alphabetically sorted)
// Available rules: "add_image_title", "add_youtube_video"
// domain => rule name
var predefinedRules = map[string]string{
"abstrusegoose.com": "add_image_title",
"amazingsuperpowers.com": "add_image_title",
"cowbirdsinlove.com": "add_image_title",
"drawingboardcomic.com": "add_image_title",
"exocomics.com": "add_image_title",
"happletea.com": "add_image_title",
"imogenquest.net": "add_image_title",
"lukesurl.com": "add_image_title",
"mercworks.net": "add_image_title",
"mrlovenstein.com": "add_image_title",
"nedroid.com": "add_image_title",
"oglaf.com": "add_image_title",
"optipess.com": "add_image_title",
"peebleslab.com": "add_image_title",
"sentfromthemoon.com": "add_image_title",
"thedoghousediaries.com": "add_image_title",
"treelobsters.com": "add_image_title",
"youtube.com": "add_youtube_video",
"xkcd.com": "add_image_title",
}