-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathsitemap.go
161 lines (147 loc) · 3.37 KB
/
sitemap.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package gositemap
import (
"bytes"
"compress/gzip"
"encoding/xml"
"errors"
"io/ioutil"
"os"
"path"
"strings"
)
var (
TooMuchLinksError = errors.New("单个sitemap文件过多")
)
type urlSet struct {
*base
XMLName xml.Name `xml:"http://www.sitemaps.org/schemas/sitemap/0.9 urlset"`
XMLNSVideo string `xml:"xmlns:video,attr,omitempty"`
XMLNSImage string `xml:"xmlns:image,attr,omitempty"`
XMLNSNews string `xml:"xmlns:news,attr,omitempty"`
Token []xml.Token
}
type sitemap struct {
*urlSet
*options
}
func NewSiteMap() *sitemap {
return &sitemap{
options: NewOptions(),
urlSet: &urlSet{
base: &base{},
},
}
}
func (s *sitemap) AppendUrl(url *url) {
if !strings.HasPrefix(url.Loc, "http") {
url.Loc = strings.TrimRight(s.defaultHost, "/") + strings.TrimLeft(url.Loc, "/")
}
s.setNs(url.xmlns)
s.Token = append(s.Token, url)
}
func (s *sitemap) ToXml() ([]byte, error) {
if ImageXmlNS&s.xmlns == ImageXmlNS {
s.urlSet.XMLNSImage = "http://www.google.com/schemas/sitemap-image/1.1"
}
if VideoXmlNS&s.xmlns == VideoXmlNS {
s.urlSet.XMLNSVideo = "http://www.google.com/schemas/sitemap-video/1.1"
}
if NewsXmlNS&s.xmlns == NewsXmlNS {
s.urlSet.XMLNSNews = "http://www.google.com/schemas/sitemap-news/0.9"
}
if len(s.urlSet.Token) > s.options.maxLinks {
return nil, TooMuchLinksError
}
var (
data []byte
err error
buf bytes.Buffer
)
if s.options.pretty {
buf.Write([]byte(xml.Header))
data, err = xml.MarshalIndent(s, "", " ")
} else {
buf.Write([]byte(strings.Trim(xml.Header, "\n")))
data, err = xml.Marshal(s)
}
if err != nil {
return nil, err
}
buf.Write(data)
return buf.Bytes(), nil
}
// filename 生成sitemap文件名
func (s *sitemap) Storage() (filename string, err error) {
var (
data []byte
)
data, err = s.ToXml()
if err != nil {
return
}
if err = os.MkdirAll(s.publicPath, 0755); err != nil {
return
}
if s.compress {
basename := strings.TrimRight(s.filename, path.Ext(s.filename))
filename = basename + ".xml.gz"
if fd, err := os.OpenFile(path.Join(s.publicPath, filename), os.O_WRONLY|os.O_CREATE, 0666); err != nil {
return "", err
} else {
gw := gzip.NewWriter(fd)
if _, err := gw.Write(data); err != nil {
return "", err
}
_ = fd.Close()
_ = gw.Close()
return filename, nil
}
} else {
return s.filename, ioutil.WriteFile(path.Join(s.publicPath, s.filename), data, 0666)
}
}
type Map struct {
XMLName xml.Name `xml:"sitemap"`
Loc string `xml:"loc"`
}
type siteMapIndex struct {
XMLName xml.Name `xml:"http://www.sitemaps.org/schemas/sitemap/0.9 sitemapindex"`
SiteMap []Map
}
func NewSiteMapIndex() *siteMapIndex {
return &siteMapIndex{
SiteMap: make([]Map, 0),
}
}
func (s *siteMapIndex) Append(loc string) {
m := Map{
Loc: loc,
}
s.SiteMap = append(s.SiteMap, m)
}
func (s *siteMapIndex) ToXml() ([]byte, error) {
var (
data []byte
err error
buf bytes.Buffer
)
buf.Write([]byte(xml.Header))
data, err = xml.MarshalIndent(s, "", " ")
if err != nil {
return nil, err
}
buf.Write(data)
return buf.Bytes(), nil
}
func (s *siteMapIndex) Storage(filepath string) (filename string, err error) {
if path.Ext(filepath) != ".xml" {
return "", errors.New("建议以.xml作为文件扩展名")
}
var data []byte
if data, err = s.ToXml(); err != nil {
return
}
err = ioutil.WriteFile(filepath, data, 0666)
filename = path.Base(filepath)
return
}