-
Notifications
You must be signed in to change notification settings - Fork 5
/
sitemap_group.go
137 lines (120 loc) · 2.95 KB
/
sitemap_group.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
package sitemap
import (
"compress/gzip"
"io"
"log"
"strconv"
"strings"
)
type File struct {
Name string
Content []byte
}
func (f *File) Write(w io.Writer) error {
zip, _ := gzip.NewWriterLevel(w, gzip.BestCompression)
defer zip.Close()
_, err := zip.Write(f.Content)
return err
}
type SitemapGroup struct {
name string
folder string
group_count int
urls []URL
isMobile bool
savedSitemaps []string
}
//Add a sitemap.URL to the group
func (s *SitemapGroup) Add(url URL) {
s.urls = append(s.urls, url)
}
//Clean Urls not yet added to the group
func (s *SitemapGroup) Clear() {
s.urls = nil
}
func (s *SitemapGroup) getSitemapName() string {
return s.name + "_" + strconv.Itoa(s.group_count) + ".xml.gz"
}
//Saves the sitemap from the sitemap.URLSet
func (s *SitemapGroup) Create(url_set URLSet) ([]File, error) {
var remnant []URL
xml, err := createSitemapXml(url_set, s.isMobile)
if err == ErrMaxFileSize {
//splits into two sitemaps recursively
newlimit := MAXURLSETSIZE / 2
firstSplit, err := s.Create(URLSet{URLs: url_set.URLs[newlimit:]})
if err != nil {
return nil, err
}
secondSplit, err := s.Create(URLSet{URLs: url_set.URLs[:newlimit]})
if err != nil {
return nil, err
}
return append(firstSplit, secondSplit...), nil
} else if err == ErrMaxUrlSetSize {
remnant = url_set.URLs[MAXURLSETSIZE:]
url_set.URLs = url_set.URLs[:MAXURLSETSIZE]
xml, err = createSitemapXml(url_set, s.isMobile)
}
if err != nil {
return nil, err
}
sitemap_name := s.getSitemapName()
files := []File{
{Name: sitemap_name, Content: xml},
}
s.savedSitemaps = append(s.savedSitemaps, sitemap_name)
s.group_count++
s.Clear()
// append remnant urls if exists
if len(remnant) > 0 {
s.urls = append(s.urls, remnant...)
}
return files, nil
}
//clean array of already generated sitemaps (not delete files)
func (s *SitemapGroup) ClearSavedSitemaps() {
s.savedSitemaps = []string{}
}
//returns the url of already generated sitemaps
func (s *SitemapGroup) URLs() []string {
return s.savedSitemaps
}
func (s *SitemapGroup) Files() chan File {
filesChannel := make(chan File)
go func() {
var partialGroup []URL
defer close(filesChannel)
for _, entry := range s.urls {
partialGroup = append(partialGroup, entry)
if len(partialGroup) == MAXURLSETSIZE {
groupFiles, err := s.Create(URLSet{URLs: partialGroup})
if err != nil {
continue
}
for _, file := range groupFiles {
filesChannel <- file
}
partialGroup = nil
}
}
// remaining files
if len(partialGroup) > 0 {
groupFiles, err := s.Create(URLSet{URLs: partialGroup})
if err != nil {
log.Println(err)
}
for _, file := range groupFiles {
filesChannel <- file
}
s.Clear()
}
}()
return filesChannel
}
//Configure name and folder of group
func (s *SitemapGroup) Configure(name string, isMobile bool) {
s.name = strings.Replace(name, ".xml.gz", "", 1)
s.group_count = 1
s.isMobile = isMobile
}