feat(i18n): add English and Simplified Chinese

This commit is contained in:
eezd committed 2026-10-26 22:04:33 +08:00
1 parent 38c4c8b781
commit 1e9e0678ee
149 files changed
+5356 -1144

No files matched your search

+13 -13
View File
@@ -5,12 +5,12 @@ import (
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"io/fs"
"net/http"
"os"
"path/filepath"
"rawmark/internal/i18n"
"regexp"
"strings"
@@ -46,7 +46,7 @@ func (s *Server) openFont(id string) (*os.Root, fontInfo, error) {
err = json.Unmarshal(data, &info)
}
if err == nil && (info.ID != id || info.Name == "" || !validFontFormat(info.Format)) {
err = fmt.Errorf("字体安装信息无效")
err = i18n.New("invalid_font_installation_information_77cff8")
}
if err != nil {
dir.Close()
@@ -88,13 +88,13 @@ func (s *Server) listFonts(w http.ResponseWriter, r *http.Request) {
func (s *Server) importFont(w http.ResponseWriter, r *http.Request) {
r.Body = http.MaxBytesReader(w, r.Body, maxFontBytes+(1<<20))
if err := r.ParseMultipartForm(1 << 20); err != nil {
writeError(w, 400, "无法读取字体文件,单个文件上限 30 MB")
writeError(w, 400, message(w, "could_not_read_font_file_b7b543"))
return
}
defer r.MultipartForm.RemoveAll()
f, header, err := r.FormFile("file")
if err != nil {
writeError(w, 400, "请选择字体文件")
writeError(w, 400, message(w, "choose_a_font_file_4c95b9"))
return
}
defer f.Close()
@@ -105,23 +105,23 @@ func (s *Server) importFont(w http.ResponseWriter, r *http.Request) {
return
}
if len(data) > maxFontBytes {
writeError(w, 413, "字体文件超过 30 MB")
writeError(w, 413, message(w, "font_file_exceeds_mb_cc001c"))
return
}
magic := map[string]string{"ttf": "\x00\x01\x00\x00", "otf": "OTTO", "woff": "wOFF", "woff2": "wOF2"}
if !validFontFormat(format) || len(data) < 12 || string(data[:4]) != magic[format] {
writeError(w, 400, "请导入有效的 TTF、OTF、WOFF 或 WOFF2 字体文件")
writeError(w, 400, message(w, "import_a_valid_ttf_otf_b67fd3"))
return
}
if s.FontsDir == "" {
writeError(w, 503, "字体目录未配置")
writeError(w, 503, message(w, "font_directory_is_not_configured_73d32a"))
return
}
hash := sha256.Sum256(data)
id := "custom-" + hex.EncodeToString(hash[:])
info := fontInfo{id, strings.TrimSuffix(filepath.Base(header.Filename), filepath.Ext(header.Filename)), format}
if strings.TrimSpace(info.Name) == "" || len(info.Name) > 200 || strings.ContainsAny(info.Name, "\x00\r\n") {
writeError(w, 400, "字体文件名无效或过长")
writeError(w, 400, message(w, "font_filename_is_invalid_or_a3fd5e"))
return
}
s.settingsMu.Lock()
@@ -167,7 +167,7 @@ func (s *Server) fontFile(w http.ResponseWriter, r *http.Request) {
dir, info, err := s.openFont(r.PathValue("id"))
if errors.Is(err, fs.ErrNotExist) {
s.settingsMu.Unlock()
writeError(w, 404, "字体不存在")
writeError(w, 404, message(w, "font_not_found_4383e9"))
return
}
if err != nil {
@@ -186,7 +186,7 @@ func (s *Server) fontFile(w http.ResponseWriter, r *http.Request) {
stat, err := f.Stat()
if err != nil || !stat.Mode().IsRegular() {
if err == nil {
err = fmt.Errorf("字体必须为普通文件")
err = i18n.New("a_font_must_be_a_5b8b51")
}
internalError(w, r, err)
return
@@ -198,14 +198,14 @@ func (s *Server) fontFile(w http.ResponseWriter, r *http.Request) {
func (s *Server) deleteFont(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
if id == "maple" {
writeError(w, 400, "Maple 是默认字体,不可删除")
writeError(w, 400, message(w, "maple_is_the_default_font_a8a571"))
return
}
s.settingsMu.Lock()
defer s.settingsMu.Unlock()
dir, _, err := s.openFont(id)
if errors.Is(err, fs.ErrNotExist) {
writeError(w, 404, "字体不存在")
writeError(w, 404, message(w, "font_not_found_4383e9"))
return
}
if err != nil {
@@ -247,7 +247,7 @@ func (s *Server) deleteFont(w http.ResponseWriter, r *http.Request) {
}
s.hub.Broadcast(events.Event{Type: "settings"})
if err := root.RemoveAll(removed); err != nil {
internalError(w, r, fmt.Errorf("字体已停用,但文件清理失败:%w", err))
internalError(w, r, i18n.New("font_disabled_but_file_cleanup_d8b892", err))
return
}
writeJSON(w, 200, map[string]bool{"ok": true})