user.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package handler
  2. import (
  3. "errors"
  4. "fmt"
  5. "math"
  6. "sort"
  7. "strconv"
  8. "codeberg.org/vnpower/pixivfe/models"
  9. "github.com/goccy/go-json"
  10. )
  11. func (p *PixivClient) GetUserArtworksID(id string, category string, page int) (string, int, error) {
  12. URL := fmt.Sprintf(UserArtworksURL, id)
  13. response, err := p.PixivRequest(URL)
  14. if err != nil {
  15. return "", -1, err
  16. }
  17. var ids []int
  18. var idsString string
  19. var body struct {
  20. Illusts json.RawMessage `json:"illusts"`
  21. Mangas json.RawMessage `json:"manga"`
  22. }
  23. err = json.Unmarshal(response, &body)
  24. if err != nil {
  25. return "", -1, err
  26. }
  27. var illusts map[int]string
  28. var mangas map[int]string
  29. count := 0
  30. if err = json.Unmarshal(body.Illusts, &illusts); err != nil {
  31. illusts = make(map[int]string)
  32. }
  33. if err = json.Unmarshal(body.Mangas, &mangas); err != nil {
  34. mangas = make(map[int]string)
  35. }
  36. // Get the keys, because Pixiv only returns IDs (very evil)
  37. if category == "illustrations" || category == "artworks" {
  38. for k := range illusts {
  39. ids = append(ids, k)
  40. count++
  41. }
  42. }
  43. if category == "manga" || category == "artworks" {
  44. for k := range mangas {
  45. ids = append(ids, k)
  46. count++
  47. }
  48. }
  49. // Reverse sort the ids
  50. sort.Sort(sort.Reverse(sort.IntSlice(ids)))
  51. worksNumber := float64(count)
  52. worksPerPage := 30.0
  53. if page < 1 || float64(page) > math.Ceil(worksNumber/worksPerPage)+1.0 {
  54. return "", -1, errors.New("Page overflow")
  55. }
  56. start := (page - 1) * int(worksPerPage)
  57. end := int(min(float64(page)*worksPerPage, worksNumber)) // no overflow
  58. for _, k := range ids[start:end] {
  59. idsString += fmt.Sprintf("&ids[]=%d", k)
  60. }
  61. return idsString, count, nil
  62. }
  63. func (p *PixivClient) GetUserArtworks(id string, ids string) ([]models.IllustShort, error) {
  64. var works []models.IllustShort
  65. URL := fmt.Sprintf(UserArtworksFullURL, id, ids)
  66. response, err := p.PixivRequest(URL)
  67. if err != nil {
  68. return nil, err
  69. }
  70. var body struct {
  71. Illusts map[int]json.RawMessage `json:"works"`
  72. }
  73. err = json.Unmarshal(response, &body)
  74. if err != nil {
  75. return nil, err
  76. }
  77. for _, v := range body.Illusts {
  78. var illust models.IllustShort
  79. err = json.Unmarshal(v, &illust)
  80. if err != nil {
  81. return nil, err
  82. }
  83. works = append(works, illust)
  84. }
  85. return works, nil
  86. }
  87. func (p *PixivClient) GetUserBasicInformation(id string) (models.UserShort, error) {
  88. var user models.UserShort
  89. URL := fmt.Sprintf(UserBasicInformationURL, id)
  90. response, err := p.PixivRequest(URL)
  91. if err != nil {
  92. return user, err
  93. }
  94. err = json.Unmarshal([]byte(response), &user)
  95. if err != nil {
  96. return user, err
  97. }
  98. return user, nil
  99. }
  100. func (p *PixivClient) GetUserInformation(id string, category string, page int) (*models.User, error) {
  101. var user *models.User
  102. URL := fmt.Sprintf(UserInformationURL, id)
  103. response, err := p.PixivRequest(URL)
  104. if err != nil {
  105. return user, err
  106. }
  107. var body struct {
  108. *models.User
  109. Background map[string]interface{} `json:"background"`
  110. }
  111. // Basic user information
  112. err = json.Unmarshal([]byte(response), &body)
  113. if err != nil {
  114. return nil, err
  115. }
  116. user = body.User
  117. if category != "bookmarks" {
  118. // Artworks
  119. ids, count, err := p.GetUserArtworksID(id, category, page)
  120. if err != nil {
  121. return nil, err
  122. }
  123. works, _ := p.GetUserArtworks(id, ids)
  124. // IDK but the order got shuffled even though Pixiv sorted the IDs in the response
  125. sort.Slice(works[:], func(i, j int) bool {
  126. left, _ := strconv.Atoi(works[i].ID)
  127. right, _ := strconv.Atoi(works[j].ID)
  128. return left > right
  129. })
  130. user.Artworks = works
  131. // Artworks count
  132. user.ArtworksCount = count
  133. // Frequent tags
  134. user.FrequentTags, err = p.GetFrequentTags(ids)
  135. if err != nil {
  136. return nil, err
  137. }
  138. } else {
  139. // Bookmarks
  140. works, count, err := p.GetUserBookmarks(id, "show", page)
  141. if err != nil {
  142. return nil, err
  143. }
  144. user.Artworks = works
  145. // Public bookmarks count
  146. user.ArtworksCount = count
  147. // Parse social medias
  148. }
  149. user.ParseSocial()
  150. // Background image
  151. if body.Background != nil {
  152. user.BackgroundImage = body.Background["url"].(string)
  153. }
  154. return user, nil
  155. }
  156. func (p *PixivClient) GetUserBookmarks(id string, mode string, page int) ([]models.IllustShort, int, error) {
  157. page--
  158. URL := fmt.Sprintf(UserBookmarksURL, id, page*48, mode)
  159. response, err := p.PixivRequest(URL)
  160. if err != nil {
  161. return nil, -1, err
  162. }
  163. var body struct {
  164. Artworks []json.RawMessage `json:"works"`
  165. Total int `json:"total"`
  166. }
  167. err = json.Unmarshal([]byte(response), &body)
  168. if err != nil {
  169. return nil, -1, err
  170. }
  171. artworks := make([]models.IllustShort, len(body.Artworks))
  172. for index, value := range body.Artworks {
  173. var artwork models.IllustShort
  174. err = json.Unmarshal([]byte(value), &artwork)
  175. if err != nil {
  176. artworks[index] = models.IllustShort{
  177. ID: "#",
  178. Title: "Deleted or Private",
  179. Thumbnail: "https://s.pximg.net/common/images/limit_unknown_360.png",
  180. }
  181. continue
  182. }
  183. artworks[index] = artwork
  184. }
  185. return artworks, body.Total, nil
  186. }