rankingCalendar.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package core
  2. import (
  3. "fmt"
  4. "html/template"
  5. "net/http"
  6. "time"
  7. "codeberg.org/vnpower/pixivfe/v2/session"
  8. "github.com/gofiber/fiber/v2"
  9. "golang.org/x/net/html"
  10. )
  11. func get_weekday(n time.Weekday) int {
  12. switch n {
  13. case time.Sunday:
  14. return 1
  15. case time.Monday:
  16. return 2
  17. case time.Tuesday:
  18. return 3
  19. case time.Wednesday:
  20. return 4
  21. case time.Thursday:
  22. return 5
  23. case time.Friday:
  24. return 6
  25. case time.Saturday:
  26. return 7
  27. }
  28. return 0
  29. }
  30. // note(@iacore):
  31. // so the funny thing about Pixiv is that they will return this month's data for a request of a future date
  32. // is it a bug or a feature?
  33. func GetRankingCalendar(c *fiber.Ctx, mode string, year, month int) (template.HTML, error) {
  34. token := session.GetPixivToken(c)
  35. URL := GetRankingCalendarURL(mode, year, month)
  36. req, err := http.NewRequest("GET", URL, nil)
  37. if err != nil {
  38. return template.HTML(""), err
  39. }
  40. req = req.WithContext(c.Context())
  41. req.Header.Add("User-Agent", "Mozilla/5.0")
  42. req.Header.Add("Cookie", "PHPSESSID="+token)
  43. // req.AddCookie(&http.Cookie{
  44. // Name: "PHPSESSID",
  45. // Value: token,
  46. // })
  47. resp, err := http.DefaultClient.Do(req)
  48. if err != nil {
  49. return "", err
  50. }
  51. defer resp.Body.Close()
  52. // Use the html package to parse the response body from the request
  53. doc, err := html.Parse(resp.Body)
  54. if err != nil {
  55. return "", err
  56. }
  57. // Find and print all links on the web page
  58. var links []string
  59. var link func(*html.Node)
  60. link = func(n *html.Node) {
  61. if n.Type == html.ElementNode && n.Data == "img" {
  62. for _, a := range n.Attr {
  63. if a.Key == "data-src" {
  64. // adds a new link entry when the attribute matches
  65. links = append(links, session.ProxyImageUrlNoEscape(c, a.Val))
  66. }
  67. }
  68. }
  69. // traverses the HTML of the webpage from the first child node
  70. for c := n.FirstChild; c != nil; c = c.NextSibling {
  71. link(c)
  72. }
  73. }
  74. link(doc)
  75. // now := c.Context().Time()
  76. // yearNow := now.Year()
  77. // monthNow := now.Month()
  78. lastMonth := time.Date(year, time.Month(month), 0, 0, 0, 0, 0, time.UTC)
  79. thisMonth := time.Date(year, time.Month(month+1), 0, 0, 0, 0, 0, time.UTC)
  80. renderString := ""
  81. for i := 0; i < get_weekday(lastMonth.Weekday()); i++ {
  82. renderString += "<div class=\"calendar-node calendar-node-empty\"></div>"
  83. }
  84. for i := 0; i < thisMonth.Day(); i++ {
  85. date := fmt.Sprintf("%d%02d%02d", year, month, i+1)
  86. if len(links) > i {
  87. renderString += fmt.Sprintf(`<a href="/ranking?mode=%s&date=%s"><div class="calendar-node"><img src="%s" alt="Day %d" /><span>%d</span></div></a>`, mode, date, links[i], i+1, i+1)
  88. } else {
  89. renderString += fmt.Sprintf(`<div class="calendar-node"><span>%d</span></div>`, i+1)
  90. }
  91. }
  92. return template.HTML(renderString), nil
  93. }