diff --git a/kernel/api/icon.go b/kernel/api/icon.go new file mode 100644 index 000000000..c2d25b06b --- /dev/null +++ b/kernel/api/icon.go @@ -0,0 +1,453 @@ +// SiYuan - Refactor your thinking +// Copyright (c) 2020-present, b3log.org +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package api + +import ( + "fmt" + "math" + "net/http" + "regexp" + "strings" + "time" + + "github.com/gin-gonic/gin" + "github.com/siyuan-note/siyuan/kernel/util" +) + +type ColorScheme struct { + Primary string + Secondary string +} + +var colorSchemes = map[string]ColorScheme{ + "red": {"#DD2F45", "#F4BEC3"}, + "blue": {"#2bb7ff", "#0097e6"}, + "yellow": {"#feca57", "#ff9f43"}, + "green": {"#55efc4", "#19b37a"}, + "purple": {"#a55eea", "#8854d0"}, + "pink": {"#fd79a8", "#e05b8a"}, + "orange": {"#ff7f50", "#ff6348"}, + "grey": {"#576574", "#222f3e"}, +} + +func getColorScheme(color string) ColorScheme { + // 检查是否是预定义的颜色 + if scheme, ok := colorSchemes[strings.ToLower(color)]; ok { + return scheme + } + + // 如果不是预定义颜色,返回默认颜色 + return colorSchemes["red"] +} + +func getDynamicIcon(c *gin.Context) { + iconType := c.DefaultQuery("type", "1") + color := c.Query("color") // 不要预设默认值,不然type6返回星期就没法自动设置周末颜色了 + date := c.Query("date") + lang := c.DefaultQuery("lang", util.Lang) + content := c.Query("content") + weekdayType := c.DefaultQuery("weekdayType", "1") // 设置星期几的格式,zh_CH {1:周日,2:周天, 3:星期日,4:星期天,}, en_US {1: Mon, 2: MON,3: Monday, 4. MONDAY,} + + dateInfo := getDateInfo(date, lang, weekdayType) + var svg string + switch iconType { + case "1": + // Type 1: 显示年月日星期 + svg = generateTypeOneSVG(color, lang, dateInfo) + case "2": + // Type 2: 显示年月日 + svg = generateTypeTwoSVG(color, lang, dateInfo) + case "3": + // Type 3: 显示年月 + svg = generateTypeThreeSVG(color, lang, dateInfo) + case "4": + // Type 4: 仅显示年 + svg = generateTypeFourSVG(color, lang, dateInfo) + case "5": + // Type 5: 显示周数 + svg = generateTypeFiveSVG(color, lang, dateInfo) + case "6": + // Type 6: 仅显示星期 + svg = generateTypeSixSVG(color, lang, weekdayType, dateInfo) + case "7": + // Type 7: 倒数日 + svg = generateTypeSevenSVG(color, lang, dateInfo) + case "8": + // Type 8: 文字图标 + svg = generateTypeEightSVG(color, content) + default: + // 默认为Type 1 + svg = generateTypeOneSVG(color, lang, dateInfo) + } + + c.Header("Content-Type", "image/svg+xml") + c.Header("Cache-Control", "no-cache") + c.Header("Pragma", "no-cache") + c.String(http.StatusOK, svg) +} + +func getDateInfo(dateStr string, lang string, weekdayType string) map[string]interface{} { + // 设置默认值 + var date time.Time + var err error + if dateStr == "" { + date = time.Now() + } else { + date, err = time.Parse("2006-01-02", dateStr) + if err != nil { + date = time.Now() + } + } + // 获取年月日星期 + year := date.Year() + month := date.Format("Jan") + day := date.Day() + var weekdayStr string + var weekdays []string + + switch lang { + case "zh_CN": + month = date.Format("1月") + switch weekdayType { + case "1": + weekdays = []string{"周日", "周一", "周二", "周三", "周四", "周五", "周六"} + case "2": + weekdays = []string{"周天", "周一", "周二", "周三", "周四", "周五", "周六"} + case "3": + weekdays = []string{"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"} + case "4": + weekdays = []string{"星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"} + default: + weekdays = []string{"周日", "周一", "周二", "周三", "周四", "周五", "周六"} + } + weekdayStr = weekdays[date.Weekday()] + case "zh_CHT": + month = date.Format("1月") + switch weekdayType { + case "1": + weekdays = []string{"週日", "週一", "週二", "週三", "週四", "週五", "週六"} + case "2": + weekdays = []string{"週天", "週一", "週二", "週三", "週四", "週五", "週六"} + case "3": + weekdays = []string{"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"} + case "4": + weekdays = []string{"星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"} + default: + weekdays = []string{"週日", "週一", "週二", "週三", "週四", "週五", "週六"} + } + weekdayStr = weekdays[date.Weekday()] + + + default: + // 其他语言 + switch weekdayType { + case "1": + weekdayStr = date.Format("Mon") + case "2": + weekdayStr = date.Format("Mon") + weekdayStr = strings.ToUpper(weekdayStr) + case "3": + weekdayStr = date.Format("Monday") + case "4": + weekdayStr = date.Format("Monday") + weekdayStr = strings.ToUpper(weekdayStr) + default: + weekdayStr = date.Format("Mon") + } + } + // Calculate week number + _, weekNum := date.ISOWeek() + weekNumStr := fmt.Sprintf("%dW", weekNum) + + switch lang { + case "zh_CN": + weekNumStr = fmt.Sprintf("%d周", weekNum) + case "zh_CHT": + weekNumStr = fmt.Sprintf("%d週", weekNum) + } + // 判断是否是周末 + isWeekend := date.Weekday() == time.Saturday || date.Weekday() == time.Sunday + // Calculate days until today + today := time.Now() + today = time.Date(today.Year(), today.Month(), today.Day(), 0, 0, 0, 0, today.Location()) + date = time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location()) + countDown := int(math.Floor(date.Sub(today).Hours() / 24)) // 注意最大返回106751天,go的时间戳最大值 + + return map[string]interface{}{ + "year": year, + "month": month, + "day": day, + "date": fmt.Sprintf("%02d-%02d", date.Month(), date.Day()), + "weekday": weekdayStr, + "week": weekNumStr, + "countDown": countDown, + "isWeekend": isWeekend, + } +} + +// Type 1: 显示年月日星期 +func generateTypeOneSVG(color string, lang string, dateInfo map[string]interface{}) string { + colorScheme := getColorScheme(color) + + return fmt.Sprintf(` + + + + %s + %d + %s + %d + + `, colorScheme.Primary, dateInfo["month"], dateInfo["day"], dateInfo["weekday"], dateInfo["year"]) +} + +// Type 2: 显示年月日 +func generateTypeTwoSVG(color string, lang string, dateInfo map[string]interface{}) string { + colorScheme := getColorScheme(color) + + return fmt.Sprintf(` + + + + %s + %d + %d + + `, colorScheme.Primary, dateInfo["month"], dateInfo["day"], dateInfo["year"]) +} + +// Type 3: 显示年月 +func generateTypeThreeSVG(color string, lang string, dateInfo map[string]interface{}) string { + colorScheme := getColorScheme(color) + + return fmt.Sprintf(` + + + + + + + + + + + + %d + %s + + `, colorScheme.Primary, colorScheme.Secondary, dateInfo["year"], dateInfo["month"]) +} + +// Type 4: 仅显示年 +func generateTypeFourSVG(color string, lang string, dateInfo map[string]interface{}) string { + colorScheme := getColorScheme(color) + + return fmt.Sprintf(` + + + + + + + + + + + + %d + + `, colorScheme.Primary, colorScheme.Secondary, dateInfo["year"]) +} + +// Type 5:: 显示周数 +func generateTypeFiveSVG(color string, lang string, dateInfo map[string]interface{}) string { + colorScheme := getColorScheme(color) + + return fmt.Sprintf(` + + + + + + + + + + + + %d + %s + + `, colorScheme.Primary, colorScheme.Secondary, dateInfo["year"], dateInfo["week"]) +} + +// Type 6: 仅显示星期 +func generateTypeSixSVG(color string, lang string, weekdayType string, dateInfo map[string]interface{}) string { + + weekday := dateInfo["weekday"].(string) + isWeekend := dateInfo["isWeekend"].(bool) + + // 如果不设置颜色,周末默认使用蓝色,工作日默认使用红色 + var colorScheme ColorScheme + if color == "" { + if isWeekend { + colorScheme = colorSchemes["blue"] + } else { + colorScheme = colorSchemes["red"] + } + } else { + colorScheme = getColorScheme(color) + } + // 动态变化字体大小 + var fontSize float64 + switch lang{ + case "zh_CN", "zh_CHT": + fontSize = 460 / float64(len([]rune(weekday))) + default: + switch weekdayType { + case "1": + fontSize = 690 / float64(len([]rune(weekday))) + case "2": + fontSize = 600 / float64(len([]rune(weekday))) + case "3": + fontSize = 720 / float64(len([]rune(weekday))) + case "4": + fontSize = 630 / float64(len([]rune(weekday))) + default: + fontSize = 750 / float64(len([]rune(weekday))) + } + } + + return fmt.Sprintf(` + + + + + + + + + + + + %s + `, colorScheme.Primary, colorScheme.Secondary, colorScheme.Primary, fontSize, weekday) +} + +// Type7: 倒数日 +func generateTypeSevenSVG(color string, lang string, dateInfo map[string]interface{}) string { + colorScheme := getColorScheme(color) + + diffDays := dateInfo["countDown"].(int) + + var tipText, diffDaysText string + + // 设置输出字符 + if diffDays == 0 { + switch lang { + case "zh_CN": + tipText = "今天" + case "zh_CHT": + tipText = "今天" + default: + tipText = "Today" + } + diffDaysText = "--" + } else if diffDays > 0 { + switch lang { + case "zh_CN": + tipText = "还有" + case "zh_CHT": + tipText = "還有" + default: + tipText = "Left" + } + diffDaysText = fmt.Sprintf("%d", diffDays) + } else { + switch lang { + case "zh_CN": + tipText = "已过" + case "zh_CHT": + tipText = "已過" + default: + tipText = "Past" + } + diffDaysText = fmt.Sprintf("%d", int(math.Abs(float64(diffDays)))) + } + + dayStr := map[string]string{ + "zh_CN": "天", + "zh_CHT": "天", + "default": "days", + }[lang] + if dayStr == "" { + dayStr = "days" + } + + fontSize := 240.0 + if len(diffDaysText) >= 6 { + fontSize = 130 + } else if len(diffDaysText) == 5 { + fontSize = 140 + } else if len(diffDaysText) == 4 { + fontSize = 190 + } + return fmt.Sprintf(` + + + + %d + %s + %s + %s + %s + `, colorScheme.Primary, dateInfo["year"], dateInfo["date"], tipText, fontSize, diffDaysText, dayStr) +} + +// Type 8: 文字图标 +func generateTypeEightSVG(color, content string) string { + colorScheme := getColorScheme(color) + + isChinese := regexp.MustCompile(`[\p{Han}]`).MatchString(content) + + var fontSize float64 + switch { + case len([]rune(content)) == 1: + fontSize = 320 + case len([]rune(content)) == 2: + fontSize = 240 + case len([]rune(content)) == 3: + fontSize = 160 + case len([]rune(content)) == 4: + fontSize = 120 + case len([]rune(content)) == 5: + fontSize = 95 + default: + if isChinese { + fontSize = 480 / float64(len([]rune(content))) + } else { + fontSize = 750 / float64(len([]rune(content))) + } + } + + return fmt.Sprintf(` + + + %s + + `, colorScheme.Primary, fontSize, content) +} diff --git a/kernel/api/router.go b/kernel/api/router.go index a315d5293..1956e0757 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -33,7 +33,8 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/system/loginAuth", model.LoginAuth) ginServer.Handle("POST", "/api/system/logoutAuth", model.LogoutAuth) ginServer.Handle("GET", "/api/system/getCaptcha", model.GetCaptcha) - + ginServer.Handle("GET", "/api/icon/getDynamicIcon", getDynamicIcon) // 添加动态图标路由 + // 需要鉴权 ginServer.Handle("POST", "/api/system/getEmojiConf", model.CheckAuth, getEmojiConf)