add comments to rankingCalendar.go files

This commit is contained in:
perennial
2024-10-01 19:12:36 +10:00
parent 73dadd913f
commit 4ac909f1a7
2 changed files with 52 additions and 16 deletions
+27 -10
View File
@@ -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 <img> 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 := "<tr>"
dayCount := 0
// Add empty cells for days before the 1st of the month
for i := 0; i < get_weekday(lastMonth.Weekday()); i++ {
renderString += `<td class="calendar-node calendar-node-empty"></td>`
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 += "</tr><tr>"
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(`<td class="calendar-node"><a href="/ranking?mode=%s&date=%s" class="d-block position-relative"><img src="%s" alt="Day %d" class="img-fluid" /><span class="position-absolute bottom-0 end-0 bg-white px-2 rounded-pill">%d</span></a></td>`, mode, date, links[i], i+1, i+1)
renderString += fmt.Sprintf(`<td class="calendar-node"><a href="/ranking?mode=%s&date=%s" class="d-block position-relative"><img src="%s" alt="Day %d" class="img-fluid" /><span class="position-absolute bottom-0 end-0 bg-body-tertiary px-2 rounded-pill">%d</span></a></td>`, mode, date, links[i], i+1, i+1)
} else {
renderString += fmt.Sprintf(`<td class="calendar-node"><span class="d-block text-center">%d</span></td>`, i+1)
}
dayCount++
}
// Add empty cells to complete the last row if necessary
for dayCount < 7 {
renderString += `<td class="calendar-node calendar-node-empty"></td>`
dayCount++
}
renderString += "</tr>"
return HTML(renderString), nil
}
+25 -6
View File
@@ -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),
})
}