package template import ( "fmt" "math" "math/rand" "net/url" "regexp" "strings" "time" "codeberg.org/vnpower/pixivfe/v2/core" ) type HTML = core.HTML func GetRandomColor() string { // Some color shade I stole colors := []string{ // Green "#C8847E", "#C8A87E", "#C8B87E", "#C8C67E", "#C7C87E", "#C2C87E", "#BDC87E", "#82C87E", "#82C87E", "#7EC8AF", "#7EAEC8", "#7EA6C8", "#7E99C8", "#7E87C8", "#897EC8", "#967EC8", "#AE7EC8", "#B57EC8", "#C87EA5", } // Randomly choose one and return return colors[rand.Intn(len(colors))] } func ParseEmojis(s string) HTML { emojiList := map[string]string{ "normal": "101", "surprise": "102", "serious": "103", "heaven": "104", "happy": "105", "excited": "106", "sing": "107", "cry": "108", "normal2": "201", "shame2": "202", "love2": "203", "interesting2": "204", "blush2": "205", "fire2": "206", "angry2": "207", "shine2": "208", "panic2": "209", "normal3": "301", "satisfaction3": "302", "surprise3": "303", "smile3": "304", "shock3": "305", "gaze3": "306", "wink3": "307", "happy3": "308", "excited3": "309", "love3": "310", "normal4": "401", "surprise4": "402", "serious4": "403", "love4": "404", "shine4": "405", "sweat4": "406", "shame4": "407", "sleep4": "408", "heart": "501", "teardrop": "502", "star": "503", } regex := regexp.MustCompile(`\(([^)]+)\)`) parsedString := regex.ReplaceAllStringFunc(s, func(s string) string { s = s[1 : len(s)-1] // Get the string inside id := emojiList[s] return fmt.Sprintf(`(%s)`, id, s) }) return HTML(parsedString) } func ParsePixivRedirect(s string) HTML { regex := regexp.MustCompile(`\/jump\.php\?(http[^"]+)`) parsedString := regex.ReplaceAllStringFunc(s, func(s string) string { s = s[10:] return s }) escaped, err := url.QueryUnescape(parsedString) if err != nil { return HTML(s) } return HTML(escaped) } func EscapeString(s string) string { escaped := url.QueryEscape(s) return escaped } func ParseTime(date time.Time) string { return date.Format("2006-01-02 15:04") } func ParseTimeCustomFormat(date time.Time, format string) string { return date.Format(format) } func CreatePaginator(base, ending string, current_page, max_page int) HTML { pageUrl := func(page int) string { return fmt.Sprintf(`%s%d%s`, base, page, ending) } const ( peek = 5 // this can be changed freely limit = peek*2 + 1 // tied to the algorithm below, do not change ) hasMaxPage := max_page != -1 count := 0 pages := "" pages += `
` { // "jump to page"
hidden_section := "" urlParsed, err := url.Parse(base) if err != nil { panic(err) } for k, vs := range urlParsed.Query() { if k == "page" { continue } for _, v := range vs { hidden_section += fmt.Sprintf(``, k, v) } } max_section := "" if hasMaxPage { max_section = fmt.Sprintf(`max="%d"`, max_page) } pages += fmt.Sprintf(`%s
`, pageUrl(current_page), hidden_section, current_page, 1, max_section) pages += `
` } { // previous,first (two buttons) pages += `` { pages += fmt.Sprintf(`«`, pageUrl(1)) pages += fmt.Sprintf(``, pageUrl(max(1, current_page-1))) } pages += `` // page number buttons for i := current_page - peek; (i <= max_page || max_page == -1) && count < limit; i++ { if i < 1 { continue } if i == current_page { pages += fmt.Sprintf(`%d`, pageUrl(i), i) } else { pages += fmt.Sprintf(`%d`, pageUrl(i), i) } count++ } // next,last (two buttons) pages += `` if hasMaxPage { pages += fmt.Sprintf(``, pageUrl(min(max_page, current_page+1))) pages += fmt.Sprintf(`»`, pageUrl(max_page)) } else { pages += fmt.Sprintf(``, pageUrl(current_page+1)) pages += fmt.Sprintf(`»`, pageUrl(max_page)) } pages += `` } pages += `
` return HTML(pages) } func GetNovelGenre(s string) string { switch s { case "1": return "Romance" case "2": return "Isekai fantasy" case "3": return "Contemporary fantasy" case "4": return "Mystery" case "5": return "Horror" case "6": return "Sci-fi" case "7": return "Literature" case "8": return "Drama" case "9": return "Historical pieces" case "10": return "BL (yaoi)" case "11": return "Yuri" case "12": return "For kids" case "13": return "Poetry" case "14": return "Essays/non-fiction" case "15": return "Screenplays/scripts" case "16": return "Reviews/opinion pieces" case "17": return "Other" } return fmt.Sprintf("(Unknown Genre %s)", s) } func SwitchButtonAttributes(baseURL, selection, currentSelection string) string { var cur string = "false" if selection == currentSelection { cur = "true" } return fmt.Sprintf(`href=%s%s class=switch-button selected=%s`, baseURL, selection, cur) } func GetTemplateFunctions() map[string]any { return map[string]any{ "parseEmojis": func(s string) HTML { return ParseEmojis(s) }, "parsePixivRedirect": func(s string) HTML { return ParsePixivRedirect(s) }, "escapeString": func(s string) string { return EscapeString(s) }, "randomColor": func() string { return GetRandomColor() }, "isEmpty": func(s string) bool { return len(s) < 1 }, "isEmphasize": func(s string) bool { switch s { case "R-18", "R-18G": return true } return false }, "reformatDate": func(s string) string { if len(s) != 8 { return s } return fmt.Sprintf("%s-%s-%s", s[4:], s[2:4], s[:2]) }, "parseTime": func(date time.Time) string { return ParseTime(date) }, "parseTimeCustomFormat": func(date time.Time, format string) string { return ParseTimeCustomFormat(date, format) }, "createPaginator": func(base, ending string, current_page, max_page int) HTML { return CreatePaginator(base, ending, current_page, max_page) }, "joinArtworkIds": func(artworks []core.ArtworkBrief) string { ids := []string{} for _, art := range artworks { ids = append(ids, art.ID) } return strings.Join(ids, ",") }, "stripEmbed": func(s string) string { // this is stupid return s[:len(s)-6] }, "renderNovel": func(s string) HTML { s = strings.ReplaceAll(s, "\n", "
") s = strings.ReplaceAll(s, "[newpage]", "Insert page separator here.") return HTML(s) }, "novelGenre": GetNovelGenre, "floor": func(i float64) int { return int(math.Floor(i)) }, "unfinishedQuery": UnfinishedQuery, "replaceQuery": ReplaceQuery, // "AttrGen": SwitchButtonAttributes, } }