localize community and user links, regex cleanup

This commit is contained in:
Ryan Stafford 2023-07-15 20:59:32 -04:00
parent 1dd8476fae
commit 2d8a3d2315
4 changed files with 79 additions and 21 deletions

View file

@ -11,7 +11,7 @@ reload:
serve: serve:
#python -m http.server --directory ./public 8081 &>/dev/null #python -m http.server --directory ./public 8081 &>/dev/null
watchexec -e go -r "go run . --addr 0.0.0.0:8008 -w" DEBUG=true watchexec -e go -r "go run . --addr 0.0.0.0:8008 -w"
style: style:
npm run watchcss > /dev/null 2>&1 npm run watchcss > /dev/null 2>&1

35
main.go
View file

@ -7,6 +7,7 @@ import (
"log" "log"
"net" "net"
"net/http" "net/http"
"os"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
"github.com/yuin/goldmark" "github.com/yuin/goldmark"
@ -64,6 +65,40 @@ func init() {
templates[name] = glob templates[name] = glob
} }
} }
if os.Getenv("DEBUG") != "" {
test()
}
}
func test() {
links := [][]string{
[]string{"https://lemmy.local/u/dude", "/lemmy.local/u/dude", "/u/dude"},
[]string{"https://lemmy.local/u/dude@lemmy.local", "/lemmy.local/u/dude", "/u/dude"},
[]string{"/u/dude", "/lemmy.local/u/dude", "/u/dude"},
[]string{"https://lemmy.world/c/dude", "/lemmy.local/c/dude@lemmy.world", "/c/dude@lemmy.world"},
[]string{"https://lemmy.world/u/dude", "/lemmy.local/u/dude@lemmy.world", "/u/dude@lemmy.world"},
[]string{"https://lemmy.world/u/dude@lemmy.world", "/lemmy.local/u/dude@lemmy.world", "/u/dude@lemmy.world"},
[]string{"https://lemmy.world/post/123", "/lemmy.world/post/123", "https://lemmy.world/post/123"},
[]string{"/post/123", "/lemmy.local/post/123", "/post/123"},
[]string{"/comment/123", "/lemmy.local/comment/123", "/comment/123"},
[]string{"https://lemmy.local/comment/123", "/lemmy.local/comment/123", "/comment/123"},
}
for _, url := range links {
output := LemmyLinkRewrite(`href="`+url[0]+`"`, "lemmy.local", "")
success := (output == (`href="` + url[1] + `"`))
if !success {
fmt.Println("\n!!!! Link rewrite failure !!!!")
fmt.Println(url)
fmt.Println(output)
fmt.Println("")
}
output = LemmyLinkRewrite(`href="`+url[0]+`"`, ".", "lemmy.local")
success = (output == (`href="` + url[2] + `"`))
if !success {
fmt.Println(success, url)
fmt.Println(output)
fmt.Println("")
}
}
} }
func middleware(n httprouter.Handle) httprouter.Handle { func middleware(n httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {

View file

@ -32,12 +32,12 @@ var funcMap = template.FuncMap{
} }
return host return host
}, },
"proxy": func(s string) string { "localize": func(s string) string {
u, err := url.Parse(s) u, err := url.Parse(s)
if err != nil { if err != nil {
return s return s
} }
return "/" + u.Host + u.Path return "." + u.Path + "@" + u.Host
}, },
"printer": func(n any) string { "printer": func(n any) string {
p := message.NewPrinter(language.English) p := message.NewPrinter(language.English)
@ -137,22 +137,11 @@ var funcMap = template.FuncMap{
fmt.Println(err) fmt.Println(err)
return template.HTML(body) return template.HTML(body)
} }
converted := buf.String() body = buf.String()
converted = strings.Replace(converted, `<img `, `<img loading="lazy" `, -1) body = strings.Replace(body, `<img `, `<img loading="lazy" `, -1)
re = regexp.MustCompile(`!([a-zA-Z0-9]+)@([a-zA-Z0-9\.\-]+)[ $]?`) body = LemmyLinkRewrite(body, host, os.Getenv("LEMMY_DOMAIN"))
converted = re.ReplaceAllString(converted, `<a href="https://$2/c/$1">!$1@$2</a> `) body = RegReplace(body, `::: spoiler (.*?)\n([\S\s]*?):::`, "<details><summary>$1</summary>$2</details>")
if os.Getenv("LEMMY_DOMAIN") == "" { return template.HTML(body)
re = regexp.MustCompile(`href="\/(c\/[a-zA-Z0-9\-]+|(post|comment)\/\d+)`)
converted = re.ReplaceAllString(converted, `href="https://`+host+`/$1`)
re := regexp.MustCompile(`href="https:\/\/([a-zA-Z0-9\.\-]+\/(c\/[a-zA-Z0-9]+|(post|comment)\/\d+))`)
converted = re.ReplaceAllString(converted, `href="/$1`)
} else {
re := regexp.MustCompile(`href="https:\/\/` + os.Getenv("LEMMY_DOMAIN") + `\/(c\/[a-zA-Z0-9]+|(post|comment)\/\d+)`)
converted = re.ReplaceAllString(converted, `href="/$1`)
}
re = regexp.MustCompile(`::: spoiler (.*?)\n([\S\s]*?):::`)
converted = re.ReplaceAllString(converted, "<details><summary>$1</summary>$2</details>")
return template.HTML(converted)
}, },
"rmmarkdown": func(body string) string { "rmmarkdown": func(body string) string {
var buf bytes.Buffer var buf bytes.Buffer
@ -173,6 +162,40 @@ var funcMap = template.FuncMap{
}, },
} }
func LemmyLinkRewrite(input string, host string, lemmy_domain string) (body string) {
body = input
// community bangs
body = RegReplace(body, `!([a-zA-Z0-9]+)@([a-zA-Z0-9\.\-]+)[ $]?`, `<a href="/c/$1">!$1@$2</a> `)
// localize community and user links
body = RegReplace(body, `href="https:\/\/([a-zA-Z0-9\.\-]+)\/((c|u)\/.*?)"`, `href="/$2@$1"`)
// remove extra instance tag
body = RegReplace(body, `href="\/((c|u)\/.*@.*?)@(.*?)"`, `href="/$1"`)
if lemmy_domain == "" {
// add domain to relative links
body = RegReplace(body, `href="\/(c\/[a-zA-Z0-9\-]+"|(post|comment)\/\d+"|(c|u)\/(.*?)")`, `href="/`+host+`/$1`)
// convert links to relative
body = RegReplace(body, `href="https:\/\/([a-zA-Z0-9\.\-]+\/(c\/[a-zA-Z0-9]+"|(post|comment)\/\d+"|u\/(.*?)"))`, `href="/$1`)
} else {
// convert local links to relative
body = RegReplace(body, `href="https:\/\/`+lemmy_domain+`\/(c\/[a-zA-Z0-9]+"|(post|comment)\/\d+"|u\/(.*?)")`, `href="/$1`)
body = RegReplace(body, `href="(.*)@`+lemmy_domain+`"`, `href="$1"`)
}
// remove redundant instance tag
re := regexp.MustCompile(`href="\/([a-zA-Z0-9\.\-]+)\/(c|u)\/(.*?)@(.*?)"`)
matches := re.FindAllStringSubmatch(body, -1)
for _, match := range matches {
if match[1] == match[4] {
body = strings.Replace(body, match[0], `href="/`+strings.Join(match[1:4], "/")+`"`, -1)
}
}
return body
}
func RegReplace(input string, match string, replace string) string {
re := regexp.MustCompile(match)
return re.ReplaceAllString(input, replace)
}
func Initialize(Host string, r *http.Request) (State, error) { func Initialize(Host string, r *http.Request) (State, error) {
state := State{ state := State{
Host: Host, Host: Host,

View file

@ -3,11 +3,11 @@
<input name="op" type="submit" value="{{ membership .Subscribed}}"> <input name="op" type="submit" value="{{ membership .Subscribed}}">
<input type="hidden" name="communityid" value ="{{.Community.ID}}"> <input type="hidden" name="communityid" value ="{{.Community.ID}}">
</form> </form>
<span class="title"><a href="{{proxy .Community.ActorID}}">c/{{fullcname .Community}}: {{.Community.Title}}</a></span> <span class="title"><a href="{{localize .Community.ActorID}}">c/{{fullcname .Community}}: {{.Community.Title}}</a></span>
<div class="details"> <div class="details">
{{ if .Community.Description.IsValid }} {{ if .Community.Description.IsValid }}
<div class="description"> <div class="description">
{{markdown "poop" .Community.Description.String}} {{markdown "" .Community.Description.String}}
</div> </div>
{{ end }} {{ end }}
<div class="gray"> <div class="gray">