- Detect social media bots (Facebook, Twitter, Discord, etc.) - Render OG meta tags with file name, size, and owner info - Auto-redirect to share page after preview is renderedpull/3227/head
parent
47218607ff
commit
99d1c05339
@ -0,0 +1,77 @@
|
||||
package share
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
)
|
||||
|
||||
// ShareOGData contains data for rendering Open Graph HTML page
|
||||
type ShareOGData struct {
|
||||
SiteName string
|
||||
FileName string
|
||||
FileSize string
|
||||
OwnerName string
|
||||
ShareURL string
|
||||
ThumbnailURL string
|
||||
RedirectURL string
|
||||
}
|
||||
|
||||
const ogHTMLTemplate = `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta property="og:title" content="{{.FileName}}">
|
||||
<meta property="og:description" content="{{.FileSize}}{{if .OwnerName}} · {{.OwnerName}}{{end}}">
|
||||
<meta property="og:image" content="{{.ThumbnailURL}}">
|
||||
<meta property="og:url" content="{{.ShareURL}}">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:site_name" content="{{.SiteName}}">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:title" content="{{.FileName}}">
|
||||
<meta name="twitter:description" content="{{.FileSize}}{{if .OwnerName}} · {{.OwnerName}}{{end}}">
|
||||
<meta name="twitter:image" content="{{.ThumbnailURL}}">
|
||||
<title>{{.FileName}} - {{.SiteName}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>window.location.href = "{{.RedirectURL}}";</script>
|
||||
<noscript>
|
||||
<p><a href="{{.RedirectURL}}">{{.FileName}}</a></p>
|
||||
</noscript>
|
||||
</body>
|
||||
</html>`
|
||||
|
||||
var ogTemplate = template.Must(template.New("og").Parse(ogHTMLTemplate))
|
||||
|
||||
// RenderOGHTML renders the Open Graph HTML page
|
||||
func RenderOGHTML(data *ShareOGData) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
if err := ogTemplate.Execute(&buf, data); err != nil {
|
||||
return "", fmt.Errorf("failed to render OG template: %w", err)
|
||||
}
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// FormatFileSize formats file size to human readable format
|
||||
func FormatFileSize(size int64) string {
|
||||
const (
|
||||
B = 1
|
||||
KB = 1024 * B
|
||||
MB = 1024 * KB
|
||||
GB = 1024 * MB
|
||||
TB = 1024 * GB
|
||||
)
|
||||
|
||||
switch {
|
||||
case size >= TB:
|
||||
return fmt.Sprintf("%.2f TB", float64(size)/TB)
|
||||
case size >= GB:
|
||||
return fmt.Sprintf("%.2f GB", float64(size)/GB)
|
||||
case size >= MB:
|
||||
return fmt.Sprintf("%.2f MB", float64(size)/MB)
|
||||
case size >= KB:
|
||||
return fmt.Sprintf("%.2f KB", float64(size)/KB)
|
||||
default:
|
||||
return fmt.Sprintf("%d B", size)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue