diff --git a/core/rankingCalendar.go b/core/rankingCalendar.go
index a69b1ec..c44c875 100644
--- a/core/rankingCalendar.go
+++ b/core/rankingCalendar.go
@@ -12,6 +12,8 @@ import (
"codeberg.org/vnpower/pixivfe/v2/server/session"
)
+// get_weekday converts a time.Weekday to an integer representation.
+// Sunday is 1, Monday is 2, and so on. This is used for calendar calculations.
func get_weekday(n time.Weekday) int {
switch n {
case time.Sunday:
@@ -32,66 +34,81 @@ func get_weekday(n time.Weekday) int {
return 0
}
+// selector_img is a pre-compiled CSS selector for finding
tags in HTML.
var selector_img = cascadia.MustCompile("img")
-// note(@iacore):
-// so the funny thing about Pixiv is that they will return this month's data for a request of a future date
-// is it a bug or a feature?
+// GetRankingCalendar retrieves and processes the ranking calendar data from Pixiv.
+// It returns an HTML string representation of the calendar and any error encountered.
+//
+// iacore: so the funny thing about Pixiv is that they will return this month's data for a request of a future date. is it a bug or a feature?
func GetRankingCalendar(r *http.Request, mode string, year, month int) (HTML, error) {
+ // Retrieve the user token from the session
token := session.GetUserToken(r)
URL := GetRankingCalendarURL(mode, year, month)
+ // Make an API request to Pixiv
resp, err := API_GET(r.Context(), URL, token)
if err != nil {
return "", err
}
- // Use the html package to parse the response body from the request
+ // Parse the HTML response
doc, err := html.Parse(strings.NewReader(resp.Body))
if err != nil {
return "", err
}
- // Find and print all links on the web page
+ // Extract image links from the parsed HTML
var links []string
for _, node := range cascadia.QueryAll(doc, selector_img) {
for _, attr := range node.Attr {
if attr.Key == "data-src" {
- // adds a new link entry when the attribute matches
+ // Proxy the image URL to avoid direct requests to Pixiv
links = append(links, session.ProxyImageUrlNoEscape(r, attr.Val))
}
}
}
- // now := r.Context().Time()
- // yearNow := now.Year()
- // monthNow := now.Month()
+ // Calculate the last day of the previous month and the current month
lastMonth := time.Date(year, time.Month(month), 0, 0, 0, 0, 0, time.UTC)
thisMonth := time.Date(year, time.Month(month+1), 0, 0, 0, 0, 0, time.UTC)
+ // Generate the HTML for the calendar
renderString := "
"
dayCount := 0
+
+ // Add empty cells for days before the 1st of the month
for i := 0; i < get_weekday(lastMonth.Weekday()); i++ {
renderString += ` | `
dayCount++
}
+
+ // Add cells for each day of the month
for i := 0; i < thisMonth.Day(); i++ {
+ // Start a new row if necessary
if dayCount == 7 {
renderString += "
"
dayCount = 0
}
+
+ // Format the date string
date := fmt.Sprintf("%d%02d%02d", year, month, i+1)
+
+ // Add a cell with an image link if available, otherwise just the day number
if len(links) > i {
- renderString += fmt.Sprintf(` %d | `, mode, date, links[i], i+1, i+1)
+ renderString += fmt.Sprintf(` %d | `, mode, date, links[i], i+1, i+1)
} else {
renderString += fmt.Sprintf(`%d | `, i+1)
}
dayCount++
}
+
+ // Add empty cells to complete the last row if necessary
for dayCount < 7 {
renderString += ` | `
dayCount++
}
+
renderString += "
"
return HTML(renderString), nil
}
diff --git a/server/routes/rankingCalendar.go b/server/routes/rankingCalendar.go
index 4e514c3..b4e7220 100644
--- a/server/routes/rankingCalendar.go
+++ b/server/routes/rankingCalendar.go
@@ -11,14 +11,17 @@ import (
"codeberg.org/vnpower/pixivfe/v2/server/utils"
)
+// DateWrap is a struct that encapsulates date-related information for easier handling in templates.
type DateWrap struct {
- Link string
+ Link string // URL-friendly date string
Year int
Month int
- MonthPadded string
- MonthLiteral string
+ MonthPadded string // Two-digit representation of the month
+ MonthLiteral string // Full name of the month
}
+// parseDate converts a time.Time value into a DateWrap struct.
+// This function is used to prepare date information for display and navigation.
func parseDate(t time.Time) DateWrap {
var d DateWrap
@@ -35,10 +38,12 @@ func parseDate(t time.Time) DateWrap {
return d
}
+// RankingCalendarPicker handles the form submission for selecting a ranking calendar.
+// It redirects to the RankingCalendarPage with the appropriate query parameters.
func RankingCalendarPicker(w http.ResponseWriter, r *http.Request) error {
mode := r.FormValue("mode")
if mode == "" {
- mode = "daily"
+ mode = "daily" // Default to daily mode if not specified
}
date := r.FormValue("date")
@@ -48,6 +53,8 @@ func RankingCalendarPicker(w http.ResponseWriter, r *http.Request) error {
})
}
+// RankingCalendarPage generates and renders the ranking calendar page.
+// It handles date parsing, retrieves the calendar data, and prepares the context for template rendering.
func RankingCalendarPage(w http.ResponseWriter, r *http.Request) error {
mode := GetQueryParam(r, "mode", "daily")
date := GetQueryParam(r, "date", "")
@@ -55,7 +62,7 @@ func RankingCalendarPage(w http.ResponseWriter, r *http.Request) error {
var year int
var month int
- // If the user supplied a date
+ // Parse the date from the query parameter if provided
if len(date) == 10 {
var err error
year, err = strconv.Atoi(date[:4])
@@ -67,19 +74,31 @@ func RankingCalendarPage(w http.ResponseWriter, r *http.Request) error {
return err
}
} else {
+ // Use current date if no date is provided
now := time.Now()
year = now.Year()
month = int(now.Month())
}
+ // Calculate dates for navigation
realDate := time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.UTC)
monthBefore := realDate.AddDate(0, -1, 0)
monthAfter := realDate.AddDate(0, 1, 0)
+ // Retrieve the ranking calendar HTML
render, err := core.GetRankingCalendar(r, mode, year, month)
if err != nil {
return err
}
- return RenderHTML(w, r, Data_rankingCalendar{Title: "Ranking calendar", Render: render, Mode: mode, Year: year, MonthBefore: parseDate(monthBefore), MonthAfter: parseDate(monthAfter), ThisMonth: parseDate(realDate)})
+ // Prepare and render the template with the calendar data
+ return RenderHTML(w, r, Data_rankingCalendar{
+ Title: "Ranking calendar",
+ Render: render,
+ Mode: mode,
+ Year: year,
+ MonthBefore: parseDate(monthBefore),
+ MonthAfter: parseDate(monthAfter),
+ ThisMonth: parseDate(realDate),
+ })
}