135 lines
3.1 KiB
Go
135 lines
3.1 KiB
Go
package dhsitemap
|
|
|
|
import (
|
|
"context"
|
|
"encoding/xml"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
"videoweb/app/service/configser"
|
|
"videoweb/pub/common/log"
|
|
"videoweb/pub/common/utils"
|
|
)
|
|
|
|
const (
|
|
outputDir = "../h5/templates/page/sitemaps"
|
|
filename = "dhsitemap.xml"
|
|
|
|
// 与主站 sitemap 一致:浏览器用 XSLT 把 loc 渲成可点击链接
|
|
stylesheetURLSet = `<?xml-stylesheet type="text/xsl" href="/static/sitemap.xsl"?>` + "\n"
|
|
)
|
|
|
|
var generateMu sync.Mutex
|
|
|
|
type urlSet struct {
|
|
XMLName xml.Name `xml:"urlset"`
|
|
Xmlns string `xml:"xmlns,attr"`
|
|
URLs []urlEntry `xml:"url"`
|
|
}
|
|
|
|
type urlEntry struct {
|
|
Loc string `xml:"loc"`
|
|
LastMod string `xml:"lastmod"`
|
|
}
|
|
|
|
// GenerateDHSitemap 生成导航站 sitemap,域名取自系统配置 newUrlAddr。
|
|
func GenerateDHSitemap() {
|
|
generateMu.Lock()
|
|
defer generateMu.Unlock()
|
|
|
|
ctx := context.Background()
|
|
config, serr := configser.GetSystemConfig(ctx)
|
|
if serr != nil {
|
|
log.Error("GenerateDHSitemap GetSystemConfig", log.Any("err", serr))
|
|
return
|
|
}
|
|
if config == nil {
|
|
log.Error("GenerateDHSitemap GetSystemConfig config is nil")
|
|
return
|
|
}
|
|
|
|
urls := collectDHURLs(config.NewUrlAddr, config.NewUrlAddr1, config.NewUrlAddr2)
|
|
if len(urls) == 0 {
|
|
log.Warn("GenerateDHSitemap: no newUrlAddr configured, skip")
|
|
return
|
|
}
|
|
|
|
today := time.Now().Format("2006-01-02")
|
|
entries := make([]urlEntry, 0, len(urls))
|
|
for _, u := range urls {
|
|
entries = append(entries, urlEntry{
|
|
Loc: u,
|
|
LastMod: today,
|
|
})
|
|
}
|
|
|
|
doc := urlSet{
|
|
Xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9",
|
|
URLs: entries,
|
|
}
|
|
|
|
if err := writeFile(doc); err != nil {
|
|
log.Error("GenerateDHSitemap write", log.Any("err", err))
|
|
return
|
|
}
|
|
|
|
src := filepath.Join(outputDir, filename+".tmp")
|
|
dst := filepath.Join(outputDir, filename)
|
|
if err := os.Rename(src, dst); err != nil {
|
|
log.Error("GenerateDHSitemap rename", log.Any("err", err))
|
|
os.Remove(src)
|
|
return
|
|
}
|
|
|
|
log.Info("GenerateDHSitemap done", log.Any("urls", len(entries)))
|
|
}
|
|
|
|
func collectDHURLs(addrs ...string) []string {
|
|
seen := make(map[string]struct{}, len(addrs))
|
|
urls := make([]string, 0, len(addrs))
|
|
for _, addr := range addrs {
|
|
addr = strings.TrimSpace(addr)
|
|
if addr == "" {
|
|
continue
|
|
}
|
|
loc := utils.JoinUrlPath(addr, "/")
|
|
if _, ok := seen[loc]; ok {
|
|
continue
|
|
}
|
|
seen[loc] = struct{}{}
|
|
urls = append(urls, loc)
|
|
}
|
|
return urls
|
|
}
|
|
|
|
func writeFile(doc urlSet) error {
|
|
if err := os.MkdirAll(outputDir, 0755); err != nil {
|
|
return fmt.Errorf("mkdir %s: %w", outputDir, err)
|
|
}
|
|
path := filepath.Join(outputDir, filename+".tmp")
|
|
file, err := os.Create(path)
|
|
if err != nil {
|
|
return fmt.Errorf("create %s: %w", filename, err)
|
|
}
|
|
defer file.Close()
|
|
|
|
if _, err := file.WriteString(xml.Header); err != nil {
|
|
return fmt.Errorf("write header: %w", err)
|
|
}
|
|
if _, err := file.WriteString(stylesheetURLSet); err != nil {
|
|
return fmt.Errorf("write stylesheet: %w", err)
|
|
}
|
|
encoder := xml.NewEncoder(file)
|
|
encoder.Indent("", " ")
|
|
if err := encoder.Encode(doc); err != nil {
|
|
return fmt.Errorf("encode: %w", err)
|
|
}
|
|
if err := encoder.Flush(); err != nil {
|
|
return fmt.Errorf("flush: %w", err)
|
|
}
|
|
return file.Sync()
|
|
}
|