Skip to content

Commit

Permalink
writer file
Browse files Browse the repository at this point in the history
  • Loading branch information
ikeikeikeike committed Nov 7, 2015
1 parent 3ce7022 commit 2dbf51a
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 58 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ _testmain.go
/Gemfile.lock /Gemfile.lock
/public/ /public/
/requirements.txt /requirements.txt
/tmp
9 changes: 5 additions & 4 deletions stm/adapter_file.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -22,16 +22,17 @@ func (adp *FileAdapter) Write(loc *Location, data []byte) {
if err != nil { if err != nil {
_ = os.MkdirAll(dir, 0755) _ = os.MkdirAll(dir, 0755)
} else if !fi.IsDir() { } else if !fi.IsDir() {
log.Fatal("%s should be a directory", dir) log.Fatalf("%s should be a directory", dir)
} }


file, _ := os.Open(loc.Path()) file, _ := os.OpenFile(loc.Path(), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
fi, err = file.Stat() fi, err = file.Stat()
if err != nil { if err != nil {
log.Fatal("%s file not exists", loc.Path()) log.Fatalf("%s file not exists", loc.Path())
} else if !fi.Mode().IsRegular() { } else if !fi.Mode().IsRegular() {
log.Fatal("%s should be a filename", loc.Path()) log.Fatalf("%s should be a filename", loc.Path())
} }
defer file.Close()


if gzipPtn.MatchString(loc.Path()) { if gzipPtn.MatchString(loc.Path()) {
adp.gzip(file, data) adp.gzip(file, data)
Expand Down
4 changes: 2 additions & 2 deletions stm/builder.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type Builder interface {
// AddWithErr(url interface{}) (Builder, error) // AddWithErr(url interface{}) (Builder, error)
// location() *Location // location() *Location


finalize() Finalize()
write() Write()
run() run()
} }
125 changes: 89 additions & 36 deletions stm/builder_file.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2,31 +2,63 @@ package stm


import "log" import "log"


type builderFileError struct {
error
full bool
finalized bool
}

func (e *builderFileError) FullError() bool {
return e.full
}

func (e *builderFileError) FinalizedError() bool {
return e.finalized
}

func NewBuilderFile(loc *Location) *BuilderFile { func NewBuilderFile(loc *Location) *BuilderFile {
return &BuilderFile{ b := &BuilderFile{
xmlContent: make([]byte, 50000, 52428800), // Number of URLs = 50,000 File size ( uncompressed ) = 50MB build: make(chan sitemapURL),
build: make(chan sitemapURL), loc: loc,
loc: loc,
} }
b.clear()
return b
} }


type BuilderFile struct { type BuilderFile struct {
xmlContent []byte // We can use this later content []byte
build chan sitemapURL build chan sitemapURL
loc *Location loc *Location
frozen bool
linkcnt int
newscnt int
written bool
reservedName string


urls []interface{} // XXX: For debug urls []interface{} // XXX: For debug
} }


func (b *BuilderFile) Add(url interface{}) BuilderError { func (b *BuilderFile) Add(url interface{}) BuilderError {
smu, err := NewSitemapURL(url) smu, err := NewSitemapURL(url)
if err != nil { if err != nil {
// panic(fmt.Sprintf("[F] Sitemap: %s", err)) log.Fatalln("[F] Sitemap: %s", err)
log.Println("[F] Sitemap: ", err)
return &builderFileError{err, true, false}
} }


b.xmlContent = append(b.xmlContent, smu.Xml()...) // TODO: Sitemap xml have limit length bytes := smu.Xml()

if b.isFinalized() {
return &builderFileError{error: err, finalized: true}
} else if !b.isFileCanFit(bytes) {
return &builderFileError{error: err, full: true}
}

// TODO: News sitemap xml
// if smu.isNews() {
// b.newscnt += 1
// }

b.content = append(b.content, bytes...) // TODO: Sitemap xml have limit length
b.linkcnt += 1
// b.build <- smu; b.urls = append(b.urls, url) // XXX: For debug // b.build <- smu; b.urls = append(b.urls, url) // XXX: For debug
return nil return nil
} }
Expand All @@ -36,49 +68,70 @@ func (b *BuilderFile) Add(url interface{}) BuilderError {
// if err != nil { // if err != nil {
// log.Println("[E] Sitemap: ", err) // log.Println("[E] Sitemap: ", err)
// } // }
// b.xmlContent += smu.Xml() // TODO: Sitemap xml have limit length // b.content += smu.Xml() // TODO: Sitemap xml have limit length
// // b.build <- smu; b.urls = append(b.urls, url) // XXX: For debug // // b.build <- smu; b.urls = append(b.urls, url) // XXX: For debug
// return b, nil // return b, nil
// } // }


func (b *BuilderFile) Content() []byte { func (b *BuilderFile) Content() []byte {
return b.xmlContent return b.content
}

func (b *BuilderFile) Finalize() {
b.frozen = true
}

func (b *BuilderFile) isFinalized() bool {
return b.frozen
}

func (b *BuilderFile) isWritten() bool {
return b.written
}

func (b *BuilderFile) isFileCanFit(bytes []byte) bool {
r := len(append(b.content, bytes...)) < MaxSitemapFilesize
r = r && b.linkcnt < MaxSitemapLinks
return r && b.newscnt < MaxSitemapNews
} }


// func (b *BuilderFile) location() *Location { // func (b *BuilderFile) location() *Location {
// return b.loc // return b.loc
// } // }


func (b *BuilderFile) finalize() {} func (b *BuilderFile) setReverseName() {
func (b *BuilderFile) write() { if b.reservedName == "" {
b.reservedName = b.loc.ReserveName()
}
}

func (b *BuilderFile) clear() {
b.content = make([]byte, MaxSitemapLinks, MaxSitemapFilesize)
}

func (b *BuilderFile) Write() {
if b.isWritten() {
log.Fatalln("[F] Sitemap already written!")
}

if !b.isFinalized() {
b.Finalize()
}

b.setReverseName()

// TODO: header and footer
b.loc.Write(b.content, b.linkcnt) // @location.write(@xml_wrapper_start + @xml_content + @xml_wrapper_end, link_count)


// raise SitemapGenerator::SitemapError.new("Sitemap already written!") if written? b.clear() // @xml_content = @xml_wrapper_start = @xml_wrapper_end = ''
// finalize! unless finalized? b.written = true
// reserve_name
// @location.write(@xml_wrapper_start + @xml_content + @xml_wrapper_end, link_count)
// @xml_content = @xml_wrapper_start = @xml_wrapper_end = ''
// @written = true
} }


func (b *BuilderFile) run() { func (b *BuilderFile) run() {
for { for {
select { select {
case smu := <-b.build: case smu := <-b.build:
b.xmlContent = append(b.xmlContent, smu.Xml()...) // TODO: Sitemap xml have limit length b.content = append(b.content, smu.Xml()...) // TODO: Sitemap xml have limit length
} }
} }
} }

type builderFileError struct {
error
isFull bool
isFinalized bool
}

func (e *builderFileError) FullError() bool {
return e.isFull
}

func (e *builderFileError) FinalizedError() bool {
return e.isFinalized
}
33 changes: 24 additions & 9 deletions stm/builder_indexfile.go
Original file line number Original file line Diff line number Diff line change
@@ -1,27 +1,42 @@
package stm package stm


import "github.com/k0kubun/pp"

func NewBuilderIndexfile(loc *Location) *BuilderIndexfile { func NewBuilderIndexfile(loc *Location) *BuilderIndexfile {
return &BuilderIndexfile{ return &BuilderIndexfile{
loc: loc, loc: loc,
} }
} }


type BuilderIndexfile struct { type BuilderIndexfile struct {
loc *Location loc *Location
linkCount int linkcnt int
bldrLinkCount int totalcnt int
} }


func (b *BuilderIndexfile) Add(link interface{}) BuilderError { func (b *BuilderIndexfile) Add(link interface{}) BuilderError {
bldr := link.(Builder) bldr := link.(*BuilderFile)
bldr.write()
b.totalcnt += bldr.linkcnt

if !bldr.isFinalized() {
bldr.Finalize()
}

// TODO: first sitemap
// if b.linkcnt == 0 { }

bldr.Write()
return nil return nil
} }


// func (b *BuilderIndexfile) AddWithErr(url interface{}) (Builder, error) { // func (b *BuilderIndexfile) AddWithErr(url interface{}) (Builder, error) {
// return b, nil // return b, nil
// } // }


func (b *BuilderIndexfile) finalize() {} func (b *BuilderIndexfile) Finalize() {}
func (b *BuilderIndexfile) write() {} func (b *BuilderIndexfile) Write() {
func (b *BuilderIndexfile) run() {} pp.Println("write indexfile")
}

func (b *BuilderIndexfile) run() {}
2 changes: 1 addition & 1 deletion stm/builder_url.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (su *sitemapURL) Xml() []byte {
} }


buf := &bytes.Buffer{} buf := &bytes.Buffer{}
doc.Indent(2) // doc.Indent(2)
doc.WriteTo(buf) doc.WriteTo(buf)


return buf.Bytes() return buf.Bytes()
Expand Down
21 changes: 21 additions & 0 deletions stm/consts.go
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,21 @@
// General sitemap guidelines: https://support.google.com/webmasters/answer/183668
// Number of URLs = 50,000
// File size ( uncompressed ) = 50MB
package stm

const (
MaxSitemapFiles = 50000 // max sitemap links per index file
MaxSitemapLinks = 50000 // max links per sitemap
MaxSitemapImages = 1000 // max images per url
MaxSitemapNews = 1000 // max news sitemap per index_file
MaxSitemapFilesize = 10485760 // bytes
)

const (
SchemaGeo = "http://www.google.com/geo/schemas/sitemap/1.0"
SchemaImage = "http://www.google.com/schemas/sitemap-image/1.1"
SchemaMobile = "http://www.google.com/schemas/sitemap-mobile/1.0"
SchemaNews = "http://www.google.com/schemas/sitemap-news/0.9"
SchemaPagemap = "http://www.google.com/schemas/sitemap-pagemap/1.0"
SchemaVideo = "http://www.google.com/schemas/sitemap-video/1.1"
)
4 changes: 2 additions & 2 deletions stm/location.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func NewLocation(opts *Options) *Location {
} }


type Location struct { type Location struct {
adp Adapter // adp Adapter
opts *Options opts *Options
} }


Expand Down Expand Up @@ -109,7 +109,7 @@ func (loc *Location) IsVerbose() bool {
} }


func (loc *Location) Write(data []byte, linkCount int) { func (loc *Location) Write(data []byte, linkCount int) {
loc.adp.Write(loc, data) loc.opts.adp.Write(loc, data)
if loc.IsVerbose() { if loc.IsVerbose() {
pp.Println(loc.Summary(linkCount)) pp.Println(loc.Summary(linkCount))
} }
Expand Down
12 changes: 8 additions & 4 deletions stm/sitemap.go
Original file line number Original file line Diff line number Diff line change
@@ -1,8 +1,12 @@
package stm package stm


import "runtime" import (
"log"
"runtime"
)


func NewSitemap() *Sitemap { func NewSitemap() *Sitemap {
log.SetFlags(log.LstdFlags | log.Llongfile)
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())


sm := &Sitemap{ sm := &Sitemap{
Expand Down Expand Up @@ -61,11 +65,11 @@ func (sm *Sitemap) finalize() {
} }


func (sm *Sitemap) finalizeFile() { func (sm *Sitemap) finalizeFile() {
sm.bldr.finalize() sm.bldr.Finalize()
sm.bldrs.Add(sm.bldr) sm.bldrs.Add(sm.bldr)
} }


func (sm *Sitemap) finalizeIndexfile() { func (sm *Sitemap) finalizeIndexfile() {
sm.bldrs.finalize() sm.bldrs.Finalize()
sm.bldrs.write() sm.bldrs.Write()
} }

0 comments on commit 2dbf51a

Please sign in to comment.