108 lines
2.4 KiB
Go
108 lines
2.4 KiB
Go
package gositemap
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"fmt"
|
|
"math"
|
|
"path"
|
|
)
|
|
|
|
type ChangeFrequency string
|
|
|
|
const (
|
|
Always ChangeFrequency = "always"
|
|
Hourly ChangeFrequency = "hourly"
|
|
Daily ChangeFrequency = "daily"
|
|
Weekly ChangeFrequency = "weekly"
|
|
Monthly ChangeFrequency = "monthly"
|
|
Yearly ChangeFrequency = "yearly"
|
|
Never ChangeFrequency = "never"
|
|
)
|
|
|
|
func (f ChangeFrequency) String() string {
|
|
return string(f)
|
|
}
|
|
|
|
type urlSetXML struct {
|
|
XMLName xml.Name `xml:"http://www.sitemaps.org/schemas/sitemap/0.9 urlset"`
|
|
URLs []*urlXML `xml:"url"`
|
|
}
|
|
|
|
type urlXML struct {
|
|
Loc string `xml:"loc"`
|
|
LastMod *string `xml:"lastmod,omitempty"`
|
|
ChangeFreq *ChangeFrequency `xml:"changefreq,omitempty"`
|
|
Priority *float64 `xml:"priority,omitempty"`
|
|
}
|
|
|
|
type siteMapIndexXML struct {
|
|
XMLName xml.Name `xml:"http://www.sitemaps.org/schemas/sitemap/0.9 sitemapindex"`
|
|
SiteMaps []*sitemapXML `xml:"sitemap"`
|
|
}
|
|
|
|
type sitemapXML struct {
|
|
Loc string `xml:"loc"`
|
|
LastMod *string `xml:"lastmod,omitempty"`
|
|
}
|
|
|
|
type SiteMap struct {
|
|
urls []*urlXML
|
|
BaseURL string
|
|
MaxURLPerSiteMap int
|
|
}
|
|
|
|
func (m *SiteMap) AddURL(url string, lastMod *string, freq *ChangeFrequency, prio *float64) {
|
|
m.urls = append(m.urls, &urlXML{
|
|
Loc: fmt.Sprintf("https://%s", path.Join(m.BaseURL, url)),
|
|
LastMod: lastMod,
|
|
ChangeFreq: freq,
|
|
Priority: prio,
|
|
})
|
|
}
|
|
|
|
func prefixXML(content []byte) []byte {
|
|
return append([]byte(xml.Header), content...)
|
|
}
|
|
|
|
func (m *SiteMap) SiteMapIndex() ([]byte, error) {
|
|
nSiteMaps := int(math.Floor(float64(len(m.urls))/float64(m.MaxURLPerSiteMap) + 1))
|
|
index := &siteMapIndexXML{}
|
|
|
|
for i := 0; i < nSiteMaps; i++ {
|
|
index.SiteMaps = append(index.SiteMaps, &sitemapXML{
|
|
Loc: fmt.Sprintf("https://%s/sitemap/%d", m.BaseURL, i),
|
|
})
|
|
}
|
|
|
|
res, err := xml.Marshal(index)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return prefixXML(res), nil
|
|
}
|
|
|
|
func (m *SiteMap) SiteMap(id int) ([]byte, error) {
|
|
if m.MaxURLPerSiteMap*(id) >= len(m.urls) {
|
|
return nil, nil
|
|
}
|
|
|
|
siteMap := &urlSetXML{}
|
|
|
|
var urls []*urlXML
|
|
if m.MaxURLPerSiteMap*(id+1) >= len(m.urls) {
|
|
urls = m.urls[m.MaxURLPerSiteMap*id:]
|
|
} else {
|
|
urls = m.urls[m.MaxURLPerSiteMap*id : m.MaxURLPerSiteMap*(id+1)]
|
|
}
|
|
|
|
siteMap.URLs = append(siteMap.URLs, urls...)
|
|
|
|
res, err := xml.Marshal(siteMap)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return prefixXML(res), nil
|
|
}
|