Feature: basic ranking calendar #20
This commit is contained in:
parent
af2c360e5c
commit
eae2ddbf12
3
go.mod
3
go.mod
|
@ -27,5 +27,6 @@ require (
|
|||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.47.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/net v0.14.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
)
|
||||
|
|
4
go.sum
4
go.sum
|
@ -61,6 +61,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -79,6 +81,8 @@ golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
|||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||
|
|
|
@ -2,12 +2,36 @@ package handler
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"pixivfe/models"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
func get_weekday(n time.Weekday) int {
|
||||
switch n {
|
||||
case time.Sunday:
|
||||
return 1
|
||||
case time.Monday:
|
||||
return 2
|
||||
case time.Tuesday:
|
||||
return 3
|
||||
case time.Wednesday:
|
||||
return 4
|
||||
case time.Thursday:
|
||||
return 5
|
||||
case time.Friday:
|
||||
return 6
|
||||
case time.Saturday:
|
||||
return 7
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (p *PixivClient) GetNewestArtworks(worktype string, r18 string) ([]models.IllustShort, error) {
|
||||
var newWorks []models.IllustShort
|
||||
lastID := "0"
|
||||
|
@ -138,3 +162,57 @@ func (p *PixivClient) GetDiscoveryArtwork(mode string, count int) ([]models.Illu
|
|||
|
||||
return artworks, nil
|
||||
}
|
||||
|
||||
func (p *PixivClient) GetRankingLog(mode string, date string, image_proxy string) (template.HTML, error) {
|
||||
resp, err := http.Get("https://www.pixiv.net/ranking_log.php?mode=daily&date=202308")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Use the html package to parse the response body from the request
|
||||
doc, err := html.Parse(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Find and print all links on the web page
|
||||
var links []string
|
||||
var link func(*html.Node)
|
||||
link = func(n *html.Node) {
|
||||
if n.Type == html.ElementNode && n.Data == "img" {
|
||||
for _, a := range n.Attr {
|
||||
if a.Key == "data-src" {
|
||||
// adds a new link entry when the attribute matches
|
||||
links = append(links, models.ProxyImage(a.Val, image_proxy))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// traverses the HTML of the webpage from the first child node
|
||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
||||
link(c)
|
||||
}
|
||||
}
|
||||
link(doc)
|
||||
|
||||
now := time.Now()
|
||||
year := now.Year()
|
||||
month := now.Month()
|
||||
lastMonth := time.Date(year, month, 0, 0, 0, 0, 0, time.UTC)
|
||||
thisMonth := time.Date(year, month+1, 0, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
renderString := ""
|
||||
for i := 0; i <= get_weekday(lastMonth.Weekday()); i++ {
|
||||
renderString += "<div class=\"calendar-node\"></div>"
|
||||
}
|
||||
for i := 0; i < thisMonth.Day(); i++ {
|
||||
date := fmt.Sprintf("%d%02d%02d", year, month, i+1)
|
||||
if len(links) > i {
|
||||
renderString += fmt.Sprintf(`<a href="/ranking?mode=%s&date=%s"><div class="calendar-node" style="background-image: url(%s)"><span>%d</span></div></a>`, mode, date, links[i], i+1)
|
||||
} else {
|
||||
renderString += fmt.Sprintf(`<div class="calendar-node"><span>%d</span></div>`, i+1)
|
||||
}
|
||||
}
|
||||
return template.HTML(renderString), nil
|
||||
}
|
||||
|
|
|
@ -434,6 +434,47 @@ body {
|
|||
font-weight: normal;
|
||||
}
|
||||
|
||||
#calendar {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.calendar-weeks,
|
||||
.calendar-board {
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.calendar-weeks div {
|
||||
width: 128px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.calendar-node {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
border-radius: 8px;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-color: #24283b;
|
||||
position: relative;
|
||||
}
|
||||
.calendar-node span {
|
||||
font-size: small;
|
||||
color: #c0caf5;
|
||||
background-color: rgba(26, 27, 38, 0.6);
|
||||
position: absolute;
|
||||
top: 0.3rem;
|
||||
left: 0.3rem;
|
||||
padding: 0.05rem 0.3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.switcher {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
|
|
@ -516,6 +516,48 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
#calendar {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.calendar-weeks,
|
||||
.calendar-board {
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.calendar-weeks div {
|
||||
width: 128px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.calendar-node {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
border-radius: 8px;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-color: $bg-alt;
|
||||
position: relative;
|
||||
|
||||
span {
|
||||
font-size: small;
|
||||
color: $fg;
|
||||
background-color: $bg-alt-dimmed;
|
||||
position: absolute;
|
||||
top: 0.3rem;
|
||||
left: 0.3rem;
|
||||
padding: 0.05rem 0.3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.switcher {
|
||||
border-radius: 10px;
|
||||
|
||||
|
|
24
template/pages/ranking_log.jet.html
Normal file
24
template/pages/ranking_log.jet.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
<div class="container">
|
||||
<h2>Ranking calendar</h2>
|
||||
<!-- <div class="switcher">
|
||||
{{ url := "/discovery?mode=" }}
|
||||
<span class="switch-title">Filter</span>
|
||||
<a href="{{url}}all" class="switch-button">All</a>
|
||||
<a href="{{url}}safe" class="switch-button">Safe</a>
|
||||
<a href="{{url}}r18" class="switch-button">R-18</a>
|
||||
</div> -->
|
||||
<div id="calendar">
|
||||
<div class="calendar-weeks">
|
||||
<div>Sun</div>
|
||||
<div>Mon</div>
|
||||
<div>Tue</div>
|
||||
<div>Wed</div>
|
||||
<div>Thu</div>
|
||||
<div>Fri</div>
|
||||
<div>Sat</div>
|
||||
</div>
|
||||
<div class="calendar-board">
|
||||
{{ raw: Render }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -231,6 +231,23 @@ func discovery_page(c *fiber.Ctx) error {
|
|||
return c.Render("pages/discovery", fiber.Map{"Title": "Discovery", "Artworks": artworks})
|
||||
}
|
||||
|
||||
func ranking_log_page(c *fiber.Ctx) error {
|
||||
image_proxy := get_session_value(c, "image-proxy")
|
||||
if image_proxy == nil {
|
||||
image_proxy = &configs.ProxyServer
|
||||
}
|
||||
|
||||
mode := c.Query("mode", "daily")
|
||||
date := c.Query("date", "")
|
||||
|
||||
render, err := PC.GetRankingLog(mode, date, *image_proxy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Render("pages/ranking_log", fiber.Map{"Title": "Ranking calendar", "Render": render})
|
||||
}
|
||||
|
||||
func following_works_page(c *fiber.Ctx) error {
|
||||
image_proxy := get_session_value(c, "image-proxy")
|
||||
if image_proxy == nil {
|
||||
|
|
|
@ -39,12 +39,14 @@ func SetupRoutes(r *fiber.App) {
|
|||
PC = NewPixivClient(5000)
|
||||
PC.SetSessionID(configs.Token)
|
||||
PC.SetUserAgent(configs.UserAgent)
|
||||
PC.AddHeader("Accept-Language", "en-US,en;q=0.5")
|
||||
|
||||
r.Get("/", index_page)
|
||||
r.Get("artworks/:id/", artwork_page)
|
||||
r.Get("users/:id/:category?", user_page)
|
||||
r.Get("newest", newest_artworks_page)
|
||||
r.Get("ranking", ranking_page)
|
||||
r.Get("ranking_log", ranking_log_page)
|
||||
r.Get("tags/:name", search_page)
|
||||
r.Get("discovery", discovery_page)
|
||||
|
||||
|
|
Loading…
Reference in a new issue