From ef6c72c0f2e0da97b94636cf175a858f2bfb496d Mon Sep 17 00:00:00 2001 From: VnPower Date: Fri, 16 Jun 2023 20:08:14 +0700 Subject: [PATCH] Feature: user's (public) bookmarks --- handler/artwork.go | 9 +++-- handler/constants.go | 1 + handler/user.go | 86 ++++++++++++++++++++++++++++++++---------- template/user.jet.html | 15 ++++++-- views/routes.go | 13 ++++--- 5 files changed, 91 insertions(+), 33 deletions(-) diff --git a/handler/artwork.go b/handler/artwork.go index 95e06e2..b7afd33 100644 --- a/handler/artwork.go +++ b/handler/artwork.go @@ -72,8 +72,7 @@ func (p *PixivClient) GetArtworkByID(id string) (*models.Illust, error) { illust.Images = images // Get recent artworks - var ids []int - idsString := "" + ids := make([]int, len(illust.Recent)) for k := range illust.Recent { ids = append(ids, k) @@ -81,8 +80,10 @@ func (p *PixivClient) GetArtworkByID(id string) (*models.Illust, error) { sort.Sort(sort.Reverse(sort.IntSlice(ids))) - count := len(ids) - for i := 0; i < 30 && i < count; i++ { + idsString := "" + count := Min(len(ids), 30) + + for i := 0; i < count; i++ { idsString += fmt.Sprintf("&ids[]=%d", ids[i]) } diff --git a/handler/constants.go b/handler/constants.go index 964e37f..697131b 100644 --- a/handler/constants.go +++ b/handler/constants.go @@ -15,5 +15,6 @@ const ( UserBasicInformationURL = "https://www.pixiv.net/ajax/user/%s" UserArtworksURL = "https://www.pixiv.net/ajax/user/%s/profile/all" UserArtworksFullURL = "https://www.pixiv.net/ajax/user/%s/profile/illusts?work_category=illustManga&is_first_page=0&lang=en%s" + UserBookmarksURL = "https://www.pixiv.net/ajax/user/%s/illusts/bookmarks?tag=&offset=%d&limit=48&rest=%s" FrequentTagsURL = "https://www.pixiv.net/ajax/tags/frequent/illust?%s" ) diff --git a/handler/user.go b/handler/user.go index a3f4da0..368fa17 100644 --- a/handler/user.go +++ b/handler/user.go @@ -126,11 +126,6 @@ func (p *PixivClient) GetUserBasicInformation(id string) (models.UserShort, erro func (p *PixivClient) GetUserInformation(id string, category string, page int) (*models.User, error) { var user *models.User - ids, count, err := p.GetUserArtworksID(id, category, page) - if err != nil { - return nil, err - } - URL := fmt.Sprintf(UserInformationURL, id) response, err := p.PixivRequest(URL) @@ -151,26 +146,77 @@ func (p *PixivClient) GetUserInformation(id string, category string, page int) ( user = body.User - // Artworks - works, _ := p.GetUserArtworks(id, ids) - // IDK but the order got shuffled even though Pixiv sorted the IDs in the response - sort.Slice(works[:], func(i, j int) bool { - left, _ := strconv.Atoi(works[i].ID) - right, _ := strconv.Atoi(works[j].ID) - return left > right - }) - user.Artworks = works + if category != "bookmarks" { + // Artworks + ids, count, err := p.GetUserArtworksID(id, category, page) + if err != nil { + return nil, err + } + works, _ := p.GetUserArtworks(id, ids) + // IDK but the order got shuffled even though Pixiv sorted the IDs in the response + sort.Slice(works[:], func(i, j int) bool { + left, _ := strconv.Atoi(works[i].ID) + right, _ := strconv.Atoi(works[j].ID) + return left > right + }) + user.Artworks = works + + // Artworks count + user.ArtworksCount = count + + // Frequent tags + user.FrequentTags, err = p.GetFrequentTags(ids) + } else { + // Bookmarks + works, count, err := p.GetUserBookmarks(id, "show", page) + if err != nil { + return nil, err + } + + user.Artworks = works + + // Public bookmarks count + user.ArtworksCount = count + } // Background image if body.Background != nil { user.BackgroundImage = body.Background["url"].(string) } - // Artworks count - user.ArtworksCount = count - - // Frequent tags - user.FrequentTags, err = p.GetFrequentTags(ids) - return user, nil } + +func (p *PixivClient) GetUserBookmarks(id string, mode string, page int) ([]models.IllustShort, int, error) { + page-- + URL := fmt.Sprintf(UserBookmarksURL, id, page*48, mode) + + response, err := p.PixivRequest(URL) + if err != nil { + return nil, -1, err + } + + var body struct { + Artworks []json.RawMessage `json:"works"` + Total int `json:"total"` + } + + err = json.Unmarshal([]byte(response), &body) + if err != nil { + return nil, -1, err + } + + artworks := make([]models.IllustShort, len(body.Artworks)) + + for index, value := range body.Artworks { + var artwork models.IllustShort + + err = json.Unmarshal([]byte(value), &artwork) + if err != nil { + continue + } + artworks[index] = artwork + } + + return artworks, body.Total, nil +} diff --git a/template/user.jet.html b/template/user.jet.html index 2436085..bbe80f5 100644 --- a/template/user.jet.html +++ b/template/user.jet.html @@ -33,6 +33,9 @@ Mangas + Bookmarks

Illustrations and Mangas

@@ -63,9 +66,13 @@ First Previous {{ else }} - First First + Previous @@ -78,12 +85,12 @@ Last {{ else }} Next Last diff --git a/views/routes.go b/views/routes.go index 63282d7..083001a 100644 --- a/views/routes.go +++ b/views/routes.go @@ -61,21 +61,24 @@ func user_page(c *fiber.Ctx) error { return err } category := c.Params("category", "artworks") - if !(category == "artworks" || category == "illustrations" || category == "manga") { - return errors.New("Invalid work category: only illustrations, manga and artworks are available") + if !(category == "artworks" || category == "illustrations" || category == "manga" || category == "bookmarks") { + return errors.New("Invalid work category: only illustrations, manga, artworks and bookmarks are available") } - page := c.Query("page", "1") + page := c.Query("page", "1") pageInt, _ := strconv.Atoi(page) + user, err := PC.GetUserInformation(id, category, pageInt) if err != nil { return err } - worksCount := user.ArtworksCount + var worksCount int + + worksCount = user.ArtworksCount pageLimit := math.Ceil(float64(worksCount)/30.0) + 1.0 - return c.Render("user", fiber.Map{"Title": user.Name, "User": user, "PageLimit": int(pageLimit), "Page": pageInt}) + return c.Render("user", fiber.Map{"Title": user.Name, "User": user, "Category": category, "PageLimit": int(pageLimit), "Page": pageInt}) } func ranking_page(c *fiber.Ctx) error {