From 381dd54e457fd613f43de42e99422581a7002fbe Mon Sep 17 00:00:00 2001 From: VnPower Date: Fri, 19 May 2023 22:05:55 +0700 Subject: [PATCH] Feature: random pagination for user's page --- handler/pixiv.go | 66 +++++++++++++++++++++++++++++++---------- main.go | 7 +++++ models/models.go | 7 +++++ template/artwork.html | 2 +- template/css/style.css | 8 +++++ template/css/style.scss | 9 ++++++ template/user.html | 19 +++++++++++- views/routes.go | 22 ++++++++++---- 8 files changed, 117 insertions(+), 23 deletions(-) diff --git a/handler/pixiv.go b/handler/pixiv.go index ca03164..098973e 100644 --- a/handler/pixiv.go +++ b/handler/pixiv.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io/ioutil" + "math" "net/http" "pixivfe/models" "regexp" @@ -197,7 +198,7 @@ func (p *PixivClient) GetArtworkByID(id string) (*models.Illust, error) { return illust.Illust, nil } -func (p *PixivClient) GetUserArtworksID(id string) (*string, error) { +func (p *PixivClient) GetUserArtworksID(id string, page int) (*string, error) { s, _ := p.TextRequest(fmt.Sprintf(UserArtworksURL, id)) var pr models.PixivResponse @@ -226,19 +227,51 @@ func (p *PixivClient) GetUserArtworksID(id string) (*string, error) { // Reverse sort the ids sort.Sort(sort.Reverse(sort.IntSlice(ids))) - i := 0 - for _, k := range ids { - if i < 30 { - idsString += fmt.Sprintf("&ids[]=%d", k) - } else { - break - } - i++ + worksNumber := float64(len(ids)) + worksPerPage := 30.0 + + if page < 1 || float64(page) > math.Ceil(worksNumber/worksPerPage)+1.0 { + return nil, errors.New("Page overflow") + } + + start := (page - 1) * int(worksPerPage) + end := int(math.Min(float64(page)*worksPerPage, worksNumber)) // no overflow + + for _, k := range ids[start:end] { + idsString += fmt.Sprintf("&ids[]=%d", k) } return &idsString, nil } +func (p *PixivClient) GetUserArtworksCount(id string) (int, error) { + s, _ := p.TextRequest(fmt.Sprintf(UserArtworksURL, id)) + + var pr models.PixivResponse + + err := json.Unmarshal([]byte(s), &pr) + + if err != nil { + return -1, errors.New(fmt.Sprintf("Failed to extract data from JSON response from server. %s", err)) + } + if pr.Error { + return -1, errors.New(pr.Message) + } + + var count int + var body struct { + Illusts map[int]string `json:"illusts"` + } + err = json.Unmarshal(pr.Body, &body) + + // Get the keys, because Pixiv only returns IDs (very evil) + for range body.Illusts { + count++ + } + + return count, nil +} + func (p *PixivClient) GetRelatedArtworks(id string) ([]models.IllustShort, error) { url := fmt.Sprintf(ArtworkRelatedURL, id) @@ -263,8 +296,8 @@ func (p *PixivClient) GetRelatedArtworks(id string) ([]models.IllustShort, error return body.Illusts, nil } -func (p *PixivClient) GetUserArtworks(id string) ([]models.IllustShort, error) { - ids, err := p.GetUserArtworksID(id) +func (p *PixivClient) GetUserArtworks(id string, page int) ([]models.IllustShort, error) { + ids, err := p.GetUserArtworksID(id, page) if err != nil { return nil, err } @@ -300,12 +333,12 @@ func (p *PixivClient) GetUserArtworks(id string) ([]models.IllustShort, error) { return works, nil } -func (p *PixivClient) GetUserInformation(id string) (*models.User, error) { - s, _ := p.TextRequest(fmt.Sprintf(UserInformationURL, id)) - +func (p *PixivClient) GetUserInformation(id string, page int) (*models.User, error) { var user *models.User var pr models.PixivResponse + s, _ := p.TextRequest(fmt.Sprintf(UserInformationURL, id)) + err := json.Unmarshal([]byte(s), &pr) if err != nil { @@ -326,7 +359,7 @@ func (p *PixivClient) GetUserInformation(id string) (*models.User, error) { user = body.User // Artworks - works, _ := p.GetUserArtworks(id) + works, _ := p.GetUserArtworks(id, page) user.Artworks = works // Avatar @@ -337,5 +370,8 @@ func (p *PixivClient) GetUserInformation(id string) (*models.User, error) { user.BackgroundImage = ProxyImage(body.Background["url"]) } + // Artworks count + // user.ArtworksCount, _ = p.GetUserArtworksCount(id) + return user, nil } diff --git a/main.go b/main.go index ad408f7..c6808b7 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,13 @@ func setupRouter() *gin.Engine { // For rankings to increment a number by 1 return n + 1 }, + "add": func(a int, b int) int { + return a + b + }, + + "dec": func(n int) int { + return n - 1 + }, "isEmpty": func(s string) bool { return len(s) < 1 diff --git a/models/models.go b/models/models.go index f0c8693..f1b5e87 100644 --- a/models/models.go +++ b/models/models.go @@ -7,6 +7,12 @@ import ( "encoding/json" ) +type PaginationData struct { + PreviousPage int + CurrentPage int + NextPage int +} + type PixivResponse struct { Error bool Message string @@ -117,4 +123,5 @@ type User struct { MyPixiv int `json:"mypixivCount"` Comment string `json:"comment"` Artworks []IllustShort `json:"artworks"` + ArtworksCount int } diff --git a/template/artwork.html b/template/artwork.html index 5decda5..9631d50 100644 --- a/template/artwork.html +++ b/template/artwork.html @@ -34,7 +34,7 @@ alt="{{ $parent.Artist.Name }}" class="artwork-artist-avatar border-rounded" /> {{ $parent.Artist.Name }}
- {{ range $parent.Recent }} + {{ range $parent.Artist.Artworks }}
{{ template "thumbnail-dt.html" . }}
diff --git a/template/css/style.css b/template/css/style.css index e023bb1..e8533b5 100644 --- a/template/css/style.css +++ b/template/css/style.css @@ -255,4 +255,12 @@ body { border-radius: 50%; } +.pagination { + width: 100%; + text-align: center; +} +.pagination .disabled { + pointer-events: none; +} + /*# sourceMappingURL=style.css.map */ diff --git a/template/css/style.scss b/template/css/style.scss index d872444..fb0d73a 100644 --- a/template/css/style.scss +++ b/template/css/style.scss @@ -298,3 +298,12 @@ body { } } } + +.pagination { + width: 100%; + text-align: center; + + .disabled { + pointer-events: none; + } +} diff --git a/template/user.html b/template/user.html index 55aba5d..fb06007 100644 --- a/template/user.html +++ b/template/user.html @@ -17,7 +17,24 @@

Illustrations and Mangas

- {{ template "small-tn.html" .Recent }} + {{ template "small-tn.html" .User.Artworks }} +
+ {{ template "footer.html" }} diff --git a/views/routes.go b/views/routes.go index 2d88481..a3bfa47 100644 --- a/views/routes.go +++ b/views/routes.go @@ -1,9 +1,11 @@ package views import ( + "math" "net/http" "pixivfe/configs" "pixivfe/handler" + "strconv" "time" "github.com/gin-gonic/gin" @@ -15,13 +17,11 @@ func artwork_page(c *gin.Context) { id := c.Param("id") illust, _ := PC.GetArtworkByID(id) related, _ := PC.GetRelatedArtworks(id) - recent_by_artist, _ := PC.GetUserArtworks(illust.UserID) - artist_info, _ := PC.GetUserInformation(illust.UserID) + artist_info, _ := PC.GetUserInformation(illust.UserID, 1) c.HTML(http.StatusOK, "artwork.html", gin.H{ "Illust": illust, "Related": related, - "Recent": recent_by_artist, "Artist": artist_info, }) } @@ -41,9 +41,19 @@ func artwork_page(c *gin.Context) { func user_page(c *gin.Context) { id := c.Param("id") - user, _ := PC.GetUserInformation(id) - recent, _ := PC.GetUserArtworks(id) - c.HTML(http.StatusOK, "user.html", gin.H{"User": user, "Recent": recent}) + page, ok := c.GetQuery("page") + + if !ok { + page = "1" + } + + pageInt, _ := strconv.Atoi(page) + user, _ := PC.GetUserInformation(id, pageInt) + + worksCount, _ := PC.GetUserArtworksCount(id) + pageLimit := math.Ceil(float64(worksCount)/30) + 1.0 + + c.HTML(http.StatusOK, "user.html", gin.H{"User": user, "PageLimit": int(pageLimit), "Page": pageInt}) } func NewPixivClient(timeout int) *models.PixivClient {