sitemap.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package service
  2. import (
  3. "context"
  4. "encoding/json"
  5. "io/ioutil"
  6. "net/http"
  7. "strconv"
  8. "strings"
  9. "sync"
  10. "time"
  11. "go-common/library/log"
  12. )
  13. type urlNode struct {
  14. id int64
  15. next *urlNode
  16. }
  17. const (
  18. _sitemapSize = 20000
  19. _sitemapInterval = int64(60)
  20. )
  21. func (s *Service) sitemapproc() {
  22. if s.urlListHead == nil {
  23. s.initURLList(context.TODO())
  24. }
  25. var interval = s.c.Sitemap.Interval
  26. if interval == 0 {
  27. interval = _sitemapInterval
  28. }
  29. for {
  30. if s.lastURLNode == nil || s.lastURLNode != s.urlListHead {
  31. s.updateXML()
  32. }
  33. time.Sleep(time.Second * time.Duration(interval))
  34. }
  35. }
  36. // add new url.
  37. func (s *Service) addURLNode(c context.Context, id int64) {
  38. go s.pushShenma(c, id)
  39. if s.urlListHead == nil {
  40. s.initURLList(c)
  41. }
  42. if _, ok := s.sitemapMap[id]; ok {
  43. return
  44. }
  45. var (
  46. mutex sync.Mutex
  47. empty struct{}
  48. )
  49. mutex.Lock()
  50. node := &urlNode{id: id}
  51. s.urlListTail.next = node
  52. s.urlListTail = node
  53. oldID := s.urlListHead.id
  54. delete(s.sitemapMap, oldID)
  55. s.sitemapMap[id] = empty
  56. s.urlListHead = s.urlListHead.next
  57. mutex.Unlock()
  58. }
  59. func (s *Service) initURLList(c context.Context) {
  60. var (
  61. ids []int64
  62. err error
  63. size = s.c.Sitemap.Size
  64. head, tail *urlNode
  65. empty struct{}
  66. mutex sync.Mutex
  67. )
  68. if size == 0 {
  69. size = _sitemapSize
  70. }
  71. if ids, err = s.dao.LastModIDs(c, size); err != nil {
  72. log.Error("s.initURLList error(%+v) size(%d)", err, size)
  73. return
  74. }
  75. for i := len(ids); i > 0; i-- {
  76. id := ids[i-1]
  77. node := &urlNode{id: id}
  78. if head == nil {
  79. head = node
  80. tail = node
  81. s.sitemapMap[id] = empty
  82. continue
  83. }
  84. tail.next = node
  85. tail = node
  86. s.sitemapMap[id] = empty
  87. }
  88. if head != nil && tail != nil {
  89. mutex.Lock()
  90. s.urlListHead = head
  91. s.urlListTail = tail
  92. mutex.Unlock()
  93. }
  94. }
  95. func (s *Service) updateXML() {
  96. var (
  97. node = s.urlListHead
  98. xml = ""
  99. mutex sync.Mutex
  100. )
  101. for node != nil {
  102. xml = `<url><loc>http://www.bilibili.com/read/cv` + strconv.FormatInt(node.id, 10) + `/</loc><lastmod>` + time.Now().Format("2006-01-02") + `</lastmod><changefreq>always</changefreq></url>` + xml
  103. node = node.next
  104. }
  105. xml = `<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.google.com/schemas/sitemap/0.84">` + xml + `</urlset>`
  106. mutex.Lock()
  107. s.sitemapXML = xml
  108. s.lastURLNode = s.urlListHead
  109. mutex.Unlock()
  110. }
  111. // SitemapXML .
  112. func (s *Service) SitemapXML(c context.Context) (string, string) {
  113. return s.sitemapXML, strconv.Itoa(len(s.sitemapXML))
  114. }
  115. func (s *Service) pushShenma(c context.Context, id int64) {
  116. url := `http://data.zhanzhang.sm.cn/push?site=www.bilibili.com&user_name=zjdxgxy@163.com&resource_name=mip_add&token=TI_a1e0216ad1a64b63e9bbadfc7579f131`
  117. urlNode := "www.bilibili.com/read/mobile/" + strconv.FormatInt(id, 10)
  118. resp, err := http.Post(url, "text/plain", strings.NewReader(urlNode))
  119. if err != nil {
  120. log.Error("s.pushShenma post error(%+v)", err)
  121. return
  122. }
  123. defer resp.Body.Close()
  124. body, err := ioutil.ReadAll(resp.Body)
  125. if err != nil {
  126. log.Error("s.pushShenma ReadAll error(%+v)", err)
  127. return
  128. }
  129. var data struct {
  130. ReturnCode int `json:"returnCode"`
  131. ErrMsg string `json:"errMsg"`
  132. }
  133. if err = json.Unmarshal(body, &data); err != nil {
  134. log.Error("s.pushShenma json unmarshal error(%+v)", err)
  135. return
  136. }
  137. if data.ReturnCode == 200 {
  138. log.Info("s.pushShenma success, url(%s)", urlNode)
  139. } else {
  140. log.Error("s.pushShenma success, errMsg(%s), url(%s)", data.ErrMsg, urlNode)
  141. }
  142. return
  143. }