Simplify opengraph tag generation

This commit is contained in:
2024-09-09 14:48:10 +02:00
parent 51afa2615c
commit 9bf31b1eb1
4 changed files with 103 additions and 130 deletions

View File

@@ -22,7 +22,6 @@
<link rel="apple-touch-icon" sizes="152x152" href="/res/img/pixeldrain_152.png" /> <link rel="apple-touch-icon" sizes="152x152" href="/res/img/pixeldrain_152.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/res/img/pixeldrain_180.png" /> <link rel="apple-touch-icon" sizes="180x180" href="/res/img/pixeldrain_180.png" />
<link rel="shortcut icon" sizes="196x196" href="/res/img/pixeldrain_196.png" /> <link rel="shortcut icon" sizes="196x196" href="/res/img/pixeldrain_196.png" />
<meta name="theme-color" content="#220735"/>
<script> <script>
window.api_endpoint = '{{.APIEndpoint}}'; window.api_endpoint = '{{.APIEndpoint}}';

View File

@@ -91,7 +91,7 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
return return
} }
templateData.OGData = wc.metadataFromFile(files[0].FileInfo) templateData.OGData = wc.metadataFromFile(r, files[0].FileInfo)
var vd = fileViewerData{ var vd = fileViewerData{
CaptchaKey: wc.captchaKey(), CaptchaKey: wc.captchaKey(),
@@ -168,7 +168,7 @@ func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request,
} }
templateData.Title = fmt.Sprintf("%s ~ pixeldrain", list.Title) templateData.Title = fmt.Sprintf("%s ~ pixeldrain", list.Title)
templateData.OGData = wc.metadataFromList(list) templateData.OGData = wc.metadataFromList(r, list)
var vd = fileViewerData{ var vd = fileViewerData{
Type: "list", Type: "list",
CaptchaKey: wc.captchaSiteKey, CaptchaKey: wc.captchaSiteKey,

View File

@@ -3,17 +3,13 @@ package webcontroller
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"net/url"
"strings" "strings"
"fornaxian.tech/log" "fornaxian.tech/log"
"fornaxian.tech/pixeldrain_api_client/pixelapi"
"fornaxian.tech/util" "fornaxian.tech/util"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
) )
const defaultThemeColour = "#220735"
func (wc *WebController) serveDirectory(w http.ResponseWriter, r *http.Request, p httprouter.Params) { func (wc *WebController) serveDirectory(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
var err error var err error
var td = wc.newTemplateData(w, r) var td = wc.newTemplateData(w, r)
@@ -46,91 +42,9 @@ func (wc *WebController) serveDirectory(w http.ResponseWriter, r *http.Request,
td.Title = fmt.Sprintf("%s ~ pixeldrain", node.Path[node.BaseIndex].Name) td.Title = fmt.Sprintf("%s ~ pixeldrain", node.Path[node.BaseIndex].Name)
td.Other = node td.Other = node
td.OGData = wc.metadataFromFilesystem(node) td.OGData = wc.metadataFromFilesystem(r, node)
err = wc.templates.Get().ExecuteTemplate(w, "filesystem", td) err = wc.templates.Get().ExecuteTemplate(w, "filesystem", td)
if err != nil && !util.IsNetError(err) { if err != nil && !util.IsNetError(err) {
log.Error("Error executing template filesystem: %s", err) log.Error("Error executing template filesystem: %s", err)
} }
} }
func urlEncodePath(path string) string {
var split = strings.Split(path, "/")
for i := range split {
split[i] = url.PathEscape(split[i])
}
return strings.Join(split, "/")
}
func findThemeColour(f pixelapi.FilesystemPath) string {
// We walk the patch backward because lower entries can override the
// properties of higher entries
for i := len(f.Path) - 1; i >= 0; i-- {
if f.Path[i].Properties["branding_enabled"] != "true" &&
f.Path[i].Properties["brand_highlight_color"] != "" {
return f.Path[i].Properties["brand_highlight_color"]
}
}
return defaultThemeColour
}
func (wc *WebController) metadataFromFilesystem(f pixelapi.FilesystemPath) (og ogData) {
var (
base = f.Path[f.BaseIndex]
name = base.Name
filetype = base.FileType
filepath = urlEncodePath(base.Path)
pageurl = wc.config.WebsiteAddress + "/d" + filepath
fileurl = wc.config.WebsiteAddress + "/api/filesystem" + filepath
thumbnailurl = wc.config.WebsiteAddress + "/api/filesystem" + filepath + "?thumbnail"
)
og.addProp("og:title", name)
og.addProp("og:site_name", "pixeldrain")
og.addProp("og:description", "This file has been shared with you on pixeldrain")
og.addProp("og:url", pageurl)
og.addProp("description", "This file has been shared with you on pixeldrain")
og.addName("description", "This file has been shared with you on pixeldrain")
og.addName("keywords", "pixeldrain,shared,sharing,upload,file,free")
og.addName("twitter:title", name)
og.addName("twitter:site", "@Fornax96")
og.addName("twitter:domain", "pixeldrain.com")
og.addName("theme-color", findThemeColour(f))
if strings.HasPrefix(filetype, "image") {
og.addProp("og:type", "article")
og.addProp("og:image", fileurl)
og.addProp("og:image:url", fileurl)
og.addProp("og:image:secure_url", fileurl)
og.addProp("og:image:type", filetype)
og.addName("twitter:card", "summary_large_image")
og.addName("twitter:image", fileurl)
og.addLink("image_src", fileurl)
} else if strings.HasPrefix(filetype, "video") {
og.addProp("og:type", "video.other")
og.addProp("og:image", thumbnailurl)
og.addProp("og:video", fileurl)
og.addProp("og:video:url", fileurl)
og.addProp("og:video:secure_url", fileurl)
og.addProp("og:video:type", filetype)
og.addName("twitter:card", "player")
og.addName("twitter:image", thumbnailurl)
og.addName("twitter:player", fileurl)
og.addName("twitter:player:stream", fileurl)
og.addName("twitter:player:stream:content_type", filetype)
og.addLink("image_src", thumbnailurl)
} else if strings.HasPrefix(filetype, "audio") {
og.addProp("og:type", "music.song")
og.addProp("og:image", thumbnailurl)
og.addProp("og:audio", fileurl)
og.addProp("og:audio:secure_url", fileurl)
og.addProp("og:audio:type", filetype)
og.addLink("image_src", thumbnailurl)
} else {
og.addProp("og:type", "website")
og.addProp("og:image", thumbnailurl)
og.addLink("image_src", thumbnailurl)
}
return og
}

View File

@@ -1,11 +1,15 @@
package webcontroller package webcontroller
import ( import (
"net/http"
"net/url"
"strings" "strings"
"fornaxian.tech/pixeldrain_api_client/pixelapi" "fornaxian.tech/pixeldrain_api_client/pixelapi"
) )
const defaultThemeColour = "#220735"
type ogData struct { type ogData struct {
MetaPropRules []ogProp MetaPropRules []ogProp
MetaNameRules []ogProp MetaNameRules []ogProp
@@ -21,72 +25,128 @@ func (og *ogData) addProp(k, v string) { og.MetaPropRules = append(og.MetaPropRu
func (og *ogData) addName(k, v string) { og.MetaNameRules = append(og.MetaNameRules, ogProp{k, v}) } func (og *ogData) addName(k, v string) { og.MetaNameRules = append(og.MetaNameRules, ogProp{k, v}) }
func (og *ogData) addLink(k, v string) { og.LinkRules = append(og.LinkRules, ogProp{k, v}) } func (og *ogData) addLink(k, v string) { og.LinkRules = append(og.LinkRules, ogProp{k, v}) }
func (wc *WebController) metadataFromFile(f pixelapi.FileInfo) (og ogData) { func generateOGData(name, filetype, pageurl, fileurl, thumbnailurl, themecolour string) (og ogData) {
og.addProp("og:title", f.Name) og.addProp("og:title", name)
og.addProp("og:site_name", "pixeldrain") og.addProp("og:site_name", "pixeldrain")
og.addProp("og:description", "This file has been shared with you on pixeldrain") og.addProp("og:description", "This file has been shared with you on pixeldrain")
og.addProp("og:url", wc.config.WebsiteAddress+"/u/"+f.ID) og.addProp("og:url", pageurl)
og.addProp("description", "This file has been shared with you on pixeldrain") og.addProp("description", "This file has been shared with you on pixeldrain")
og.addName("description", "This file has been shared with you on pixeldrain") og.addName("description", "This file has been shared with you on pixeldrain")
og.addName("keywords", "pixeldrain,shared,sharing,upload,file,free") og.addName("keywords", "pixeldrain,shared,sharing,upload,file,free")
og.addName("twitter:title", f.Name) og.addName("twitter:title", name)
og.addName("twitter:site", "@Fornax96") og.addName("twitter:site", "@Fornax96")
og.addName("twitter:domain", "pixeldrain.com") og.addName("twitter:domain", "pixeldrain.com")
og.addName("theme-color", themecolour)
if strings.HasPrefix(f.MimeType, "image") { if strings.HasPrefix(filetype, "image") {
og.addProp("og:type", "article") og.addProp("og:type", "article")
og.addProp("og:image", wc.config.WebsiteAddress+"/api/file/"+f.ID) og.addProp("og:image", fileurl)
og.addProp("og:image:url", wc.config.WebsiteAddress+"/api/file/"+f.ID) og.addProp("og:image:url", fileurl)
og.addProp("og:image:secure_url", wc.config.WebsiteAddress+"/api/file/"+f.ID) og.addProp("og:image:secure_url", fileurl)
og.addProp("og:image:type", f.MimeType) og.addProp("og:image:type", filetype)
og.addName("twitter:card", "summary_large_image") og.addName("twitter:card", "summary_large_image")
og.addName("twitter:image", wc.config.WebsiteAddress+"/api/file/"+f.ID) og.addName("twitter:image", fileurl)
og.addLink("image_src", wc.config.WebsiteAddress+"/api/file/"+f.ID) og.addLink("image_src", fileurl)
} else if strings.HasPrefix(f.MimeType, "video") { } else if strings.HasPrefix(filetype, "video") {
og.addProp("og:type", "video.other") og.addProp("og:type", "video.other")
og.addProp("og:image", wc.config.WebsiteAddress+"/api/file/"+f.ID+"/thumbnail") og.addProp("og:image", thumbnailurl)
og.addProp("og:video", wc.config.WebsiteAddress+"/api/file/"+f.ID) og.addProp("og:video", fileurl)
og.addProp("og:video:url", wc.config.WebsiteAddress+"/api/file/"+f.ID) og.addProp("og:video:url", fileurl)
og.addProp("og:video:secure_url", wc.config.WebsiteAddress+"/api/file/"+f.ID) og.addProp("og:video:secure_url", fileurl)
og.addProp("og:video:type", f.MimeType) og.addProp("og:video:type", filetype)
og.addName("twitter:card", "player") og.addName("twitter:card", "player")
og.addName("twitter:image", wc.config.WebsiteAddress+"/api/file/"+f.ID+"/thumbnail") og.addName("twitter:image", thumbnailurl)
og.addName("twitter:player", wc.config.WebsiteAddress+"/api/file/"+f.ID) og.addName("twitter:player", fileurl)
og.addName("twitter:player:stream", wc.config.WebsiteAddress+"/api/file/"+f.ID) og.addName("twitter:player:stream", fileurl)
og.addName("twitter:player:stream:content_type", f.MimeType) og.addName("twitter:player:stream:content_type", filetype)
og.addLink("image_src", wc.config.WebsiteAddress+"/api/file/"+f.ID+"/thumbnail") og.addLink("image_src", thumbnailurl)
} else if strings.HasPrefix(f.MimeType, "audio") { } else if strings.HasPrefix(filetype, "audio") {
og.addProp("og:type", "music.song") og.addProp("og:type", "music.song")
og.addProp("og:image", wc.config.WebsiteAddress+"/api/file/"+f.ID+"/thumbnail") og.addProp("og:image", thumbnailurl)
og.addProp("og:audio", wc.config.WebsiteAddress+"/api/file/"+f.ID) og.addProp("og:audio", fileurl)
og.addProp("og:audio:secure_url", wc.config.WebsiteAddress+"/api/file/"+f.ID) og.addProp("og:audio:secure_url", fileurl)
og.addProp("og:audio:type", f.MimeType) og.addProp("og:audio:type", filetype)
og.addLink("image_src", wc.config.WebsiteAddress+"/api/file/"+f.ID+"/thumbnail") og.addLink("image_src", thumbnailurl)
} else { } else {
og.addProp("og:type", "website") og.addProp("og:type", "website")
og.addProp("og:image", wc.config.WebsiteAddress+"/api/file/"+f.ID+"/thumbnail") og.addProp("og:image", thumbnailurl)
og.addLink("image_src", wc.config.WebsiteAddress+"/api/file/"+f.ID+"/thumbnail") og.addLink("image_src", thumbnailurl)
} }
return og return og
} }
func (wc *WebController) metadataFromList(l pixelapi.ListInfo) (og ogData) {
func getRequestAddress(r *http.Request) (addr string) {
if r.TLS == nil {
return "http://" + r.Header.Get("Host")
} else {
return "https://" + r.Header.Get("Host")
}
}
func (wc *WebController) metadataFromFile(r *http.Request, f pixelapi.FileInfo) ogData {
var addr = getRequestAddress(r)
return generateOGData(
f.Name,
f.MimeType,
addr+"/u/"+f.ID,
addr+"/api/file/"+f.ID,
addr+"/api/file/"+f.ID+"/thumbnail",
defaultThemeColour,
)
}
func (wc *WebController) metadataFromList(r *http.Request, l pixelapi.ListInfo) ogData {
var addr = getRequestAddress(r)
if l.FileCount > 0 {
return generateOGData(
l.Title,
l.Files[0].MimeType,
addr+"/l/"+l.ID,
addr+"/api/file/"+l.Files[0].ID,
addr+"/api/file/"+l.Files[0].ID+"/thumbnail",
defaultThemeColour,
)
}
var og = ogData{}
og.addProp("og:type", "website") og.addProp("og:type", "website")
og.addProp("og:title", l.Title) og.addProp("og:title", l.Title)
og.addProp("og:site_name", "pixeldrain") og.addProp("og:site_name", "pixeldrain")
og.addProp("og:description", "A collection of files on pixeldrain") og.addProp("og:description", "A collection of files on pixeldrain")
og.addProp("description", "A collection of files on pixeldrain") og.addProp("description", "A collection of files on pixeldrain")
og.addName("description", "A collection of files on pixeldrain") og.addName("description", "A collection of files on pixeldrain")
og.addProp("og:url", wc.config.WebsiteAddress+"/l/"+l.ID) og.addProp("og:url", addr+"/l/"+l.ID)
og.addName("twitter:title", l.Title) og.addName("twitter:title", l.Title)
og.addName("twitter:site", "@Fornax96")
og.addName("twitter:domain", "pixeldrain.com")
if l.FileCount > 0 {
og.addProp("og:image", wc.config.WebsiteAddress+"/api/file/"+l.Files[0].ID+"/thumbnail")
og.addProp("og:image:url", wc.config.WebsiteAddress+"/api/file/"+l.Files[0].ID+"/thumbnail")
og.addName("twitter:image", wc.config.WebsiteAddress+"/api/file/"+l.Files[0].ID+"/thumbnail")
og.addLink("image_src", wc.config.WebsiteAddress+"/api/file/"+l.Files[0].ID+"/thumbnail")
}
return og return og
} }
func (wc *WebController) metadataFromFilesystem(r *http.Request, f pixelapi.FilesystemPath) (og ogData) {
var addr = getRequestAddress(r)
var base = &f.Path[f.BaseIndex]
// Encode the file path
var split = strings.Split(base.Path, "/")
for i := range split {
split[i] = url.PathEscape(split[i])
}
var filepath = strings.Join(split, "/")
// Get the theme colour
var colour = defaultThemeColour
for _, node := range f.Path {
if node.Properties["branding_enabled"] == "true" &&
node.Properties["brand_highlight_color"] != "" {
colour = node.Properties["brand_highlight_color"]
}
}
return generateOGData(
base.Name,
base.FileType,
addr+"/d"+filepath,
addr+"/api/filesystem"+filepath,
addr+"/api/filesystem"+filepath+"?thumbnail",
colour,
)
}