diff --git a/go.mod b/go.mod index 2e75901..10fd149 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,10 @@ module github.com/yiwen-ai/yiwen-static -go 1.20 +go 1.21 require ( github.com/BurntSushi/toml v1.3.2 - github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible + github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible github.com/teambition/gear v1.27.3 ) @@ -12,7 +12,7 @@ require ( github.com/go-http-utils/cookie v1.3.1 // indirect github.com/go-http-utils/negotiator v1.0.0 // indirect github.com/teambition/trie-mux v1.5.2 // indirect - golang.org/x/net v0.14.0 // indirect - golang.org/x/text v0.12.0 // indirect + golang.org/x/net v0.15.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect ) diff --git a/go.sum b/go.sum index 5d43a00..0440512 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8 github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible h1:6JF1bjhT0WN2srEmijfOFtVWwV91KZ6dJY1/JbdtGrI= github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible h1:Sg/2xHwDrioHpxTN6WMiwbXTpUEinBpHsN7mG21Rc2k= +github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0= @@ -21,8 +23,12 @@ github.com/teambition/trie-mux v1.5.2 h1:ALTagFwKZXkn1vfSRlODlmoZg+NMeWAm4dyBPQI github.com/teambition/trie-mux v1.5.2/go.mod h1:0Woh4KOHSN9bkJ66eWmLs8ltrEKw+fnZbFaHFfbMrtc= golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/src/app/app.go b/src/app/app.go index b4f177b..0e4b3f3 100644 --- a/src/app/app.go +++ b/src/app/app.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "net/http" + "net/url" "strings" "time" @@ -64,7 +65,10 @@ func (gs Groups) lookupFile(path string) (string, []byte) { return "", nil } +const Wechat_UA = "MicroMessenger/" + func (gs Groups) Serve(ctx *gear.Context) error { + logging.SetTo(ctx, "host", ctx.Host) if ctx.Method != http.MethodGet && ctx.Method != http.MethodHead { status := 200 if ctx.Method != http.MethodOptions { @@ -75,9 +79,30 @@ func (gs Groups) Serve(ctx *gear.Context) error { return ctx.End(status) } + isWechat := strings.Contains(ctx.GetHeader(gear.HeaderUserAgent), Wechat_UA) + // https://www.yiwen.pub/pub/ck1sasaglcahc6fks810?language=zho&by=ke82hfgs3ni + if ctx.Host == "www.yiwen.pub" && !isWechat { + next := &url.URL{ + Scheme: "https", + Host: "www.yiwen.ai", + Path: ctx.Path, + RawQuery: ctx.Req.URL.RawQuery, + } + return ctx.Redirect(next.String()) + } + name, file := gs.lookupFile(ctx.Path) if name != "" { - handleCookie(ctx) + if name == "index.html" { + lang := handleContext(ctx) + app := "web" + if isWechat { + app = "wechat" + } + + html := fmt.Sprintf(``, lang, app) + file = bytes.Replace(file, []byte(""), []byte(html), 1) + } http.ServeContent(ctx.Res, ctx.Req, name, startTime, bytes.NewReader(file)) } @@ -132,12 +157,30 @@ func GetVersion() map[string]string { } } -func handleCookie(ctx *gear.Context) { +func handleContext(ctx *gear.Context) (lang string) { logging.SetTo(ctx, "referer", ctx.GetHeader(gear.HeaderReferer)) // user preferred language - if cookie, _ := ctx.Req.Cookie("lang"); cookie != nil { - logging.SetTo(ctx, "lang", cookie.Value) + lang = ctx.Query("language") + if lang == "" { + lang = ctx.Query("lang") + } + if lang == "" { + lang = ctx.GetHeader("x-language") } + if lang == "" { + if c, _ := ctx.Req.Cookie("lang"); c != nil { + lang = c.Value + } else if locale := ctx.AcceptLanguage(); locale != "" { + if i := strings.IndexAny(locale, "-_"); i > 0 { + locale = locale[:i] + } + lang = locale + } + } + + lang = Lang639_3(lang) + logging.SetTo(ctx, "lang", lang) + // user preferred currency if cookie, _ := ctx.Req.Cookie("ccy"); cookie != nil { logging.SetTo(ctx, "ccy", cookie.Value) @@ -146,10 +189,8 @@ func handleCookie(ctx *gear.Context) { // 用户推荐人 if cookie, _ := ctx.Req.Cookie("by"); cookie != nil { logging.SetTo(ctx, "by", cookie.Value) - return - } - // 如果 url 中包含用户推荐人,则设置到 cookie - if by := ctx.Query("by"); len(by) > 0 && len(by) <= 20 { + } else if by := ctx.Query("by"); len(by) > 0 && len(by) <= 20 { + // 如果 url 中包含用户推荐人,则设置到 cookie logging.SetTo(ctx, "by", by) http.SetCookie(ctx.Res, &http.Cookie{ Name: "by", @@ -161,6 +202,7 @@ func handleCookie(ctx *gear.Context) { Domain: conf.Config.Cookie.Domain, SameSite: http.SameSiteLaxMode, }) - return } + + return } diff --git a/src/app/languages.go b/src/app/languages.go new file mode 100644 index 0000000..7385773 --- /dev/null +++ b/src/app/languages.go @@ -0,0 +1,28 @@ +package app + +import ( + "encoding/json" + "strings" +) + +var Languages [][]string + +func init() { + if err := json.Unmarshal([]byte(languages), &Languages); err != nil { + panic(err) + } +} + +func Lang639_3(lang string) string { + lang = strings.ToLower(lang) + + for _, vv := range Languages { + if vv[0] == lang || vv[1] == lang || strings.ToLower(vv[2]) == lang || strings.ToLower(vv[3]) == lang { + return vv[1] + } + } + + return "" +} + +var languages = `[["ab","abk","Abkhazian","аҧсуа бызшәа\u200e (Aṗsua byzšwa), аҧсшәа\u200e (Aṗsšwa)"],["aa","aar","Afar","Qafar"],["af","afr","Afrikaans","Afrikaans"],["ak","aka","Akan","Akan"],["sq","sqi","Albanian","shqip"],["am","amh","Amharic","አማርኛ"],["ar","ara","Arabic","العربية"],["an","arg","Aragonese","Aragonés"],["hy","hye","Armenian","հայերեն"],["as","asm","Assamese","অসমীয়া"],["av","ava","Avaric","авар мацӏ\u200e (Awar mac̣), магӏарул мацӏ\u200e (Maʿarul mac̣)"],["az","aze","Azerbaijani","azərbaycan"],["bm","bam","Bambara","bamanakan"],["ba","bak","Bashkir","башҡорт теле\u200e (Başķort tele), башҡортса\u200e (Başķortsa)"],["eu","eus","Basque","euskara"],["be","bel","Belarusian","беларуская"],["bn","ben","Bengali","বাংলা"],["bi","bis","Bislama","Bislama"],["bs","bos","Bosnian","bosanski"],["br","bre","Breton","brezhoneg"],["bg","bul","Bulgarian","български"],["my","mya","Burmese","မြန်မာ"],["ca","cat","Catalan","català"],["ch","cha","Chamorro","Chamorru"],["ce","che","Chechen","нохчийн"],["zh","zho","Chinese","中文"],["cu","chu","Church Slavic","церковнослове́нскїй"],["cv","chv","Chuvash","Чӑвашла"],["kw","cor","Cornish","kernewek"],["co","cos","Corsican","Corsu"],["hr","hrv","Croatian","hrvatski"],["cs","ces","Czech","čeština"],["da","dan","Danish","dansk"],["dv","div","Dhivehi","ދިވެހިބަސް"],["nl","nld","Dutch","Nederlands"],["dz","dzo","Dzongkha","རྫོང་ཁ"],["en","eng","English","English"],["eo","epo","Esperanto","esperanto"],["et","est","Estonian","eesti"],["ee","ewe","Ewe","Eʋegbe"],["fo","fao","Faroese","føroyskt"],["fi","fin","Finnish","suomi"],["fr","fra","French","français"],["ff","ful","Fulah","Pulaar"],["gl","glg","Galician","galego"],["lg","lug","Ganda","Luganda"],["ka","kat","Georgian","ქართული"],["de","deu","German","Deutsch"],["gu","guj","Gujarati","ગુજરાતી"],["ht","hat","Haitian","Ayisyen, Kreyòl"],["ha","hau","Hausa","Hausa"],["he","heb","Hebrew","עברית"],["hi","hin","Hindi","हिन्दी"],["hu","hun","Hungarian","magyar"],["is","isl","Icelandic","íslenska"],["ig","ibo","Igbo","Igbo"],["id","ind","Indonesian","Indonesia"],["ia","ina","Interlingua","interlingua"],["iu","iku","Inuktitut","ᐃᓄᒃᑎᑐᑦ"],["ga","gle","Irish","Gaeilge"],["it","ita","Italian","italiano"],["ja","jpn","Japanese","日本語"],["jv","jav","Javanese","Basa Jawa"],["kl","kal","Kalaallisut","kalaallisut"],["kn","kan","Kannada","ಕನ್ನಡ"],["ks","kas","Kashmiri","کٲشُر"],["kk","kaz","Kazakh","қазақ тілі"],["km","khm","Khmer","ខ្មែរ"],["ki","kik","Kikuyu","Gikuyu"],["rw","kin","Kinyarwanda","Kinyarwanda"],["ky","kir","Kirghiz","кыргызча"],["ko","kor","Korean","한국어"],["kj","kua","Kuanyama","Oshikwanyama"],["ku","kur","Kurdish","kurdî"],["lo","lao","Lao","ລາວ"],["lv","lav","Latvian","latviešu"],["li","lim","Limburgan","Limbourgeois, Limburgs"],["ln","lin","Lingala","lingála"],["lt","lit","Lithuanian","lietuvių"],["lu","lub","Luba-Katanga","Tshiluba"],["lb","ltz","Luxembourgish","Lëtzebuergesch"],["mk","mkd","Macedonian","македонски"],["mg","mlg","Malagasy","Malagasy"],["ms","msa","Malay","Melayu"],["ml","mal","Malayalam","മലയാളം"],["mt","mlt","Maltese","Malti"],["gv","glv","Manx","Gaelg"],["mi","mri","Maori","te reo Maori"],["mr","mar","Marathi","मराठी"],["el","ell","Modern Greek","Ελληνικά"],["mn","mon","Mongolian","монгол"],["nv","nav","Navajo","Diné"],["ne","nep","Nepali","नेपाली"],["nd","nde","North Ndebele","isiNdebele"],["se","sme","Northern Sami","davvisámegiella"],["no","nor","Norwegian","Norsk"],["nn","nno","Norwegian Nynorsk","nynorsk"],["ny","nya","Nyanja","Chichewa, chiCheŵa\u200e (Chichewa), chiNyanja"],["oc","oci","Occitan","occitan"],["or","ori","Oriya","ଓଡ଼ିଆ"],["om","orm","Oromo","Oromoo"],["os","oss","Ossetian","ирон"],["pa","pan","Panjabi","ਪੰਜਾਬੀ"],["fa","fas","Persian","فارسی"],["pl","pol","Polish","polski"],["pt","por","Portuguese","português"],["ps","pus","Pushto","پښتو"],["qu","que","Quechua","Runasimi"],["ro","ron","Romanian","română"],["rm","roh","Romansh","rumantsch"],["rn","run","Rundi","Ikirundi"],["ru","rus","Russian","русский"],["sm","smo","Samoan","Gagana Samoa"],["sg","sag","Sango","Sängö"],["sa","san","Sanskrit","संस्कृत भाषा"],["gd","gla","Scottish Gaelic","Gàidhlig"],["sr","srp","Serbian","српски"],["sn","sna","Shona","chiShona"],["ii","iii","Sichuan Yi","ꆈꌠꉙ"],["sd","snd","Sindhi","سنڌي"],["si","sin","Sinhala","සිංහල"],["sk","slk","Slovak","slovenčina"],["sl","slv","Slovenian","slovenščina"],["so","som","Somali","Soomaali"],["nr","nbl","South Ndebele","isiNdebele"],["st","sot","Southern Sotho","Sesotho"],["es","spa","Spanish","español"],["su","sun","Sundanese","Sunda"],["sw","swa","Swahili","Kiswahili"],["ss","ssw","Swati","siSwati"],["sv","swe","Swedish","svenska"],["tl","tgl","Tagalog","Tagalog"],["ty","tah","Tahitian","Reo Tahiti"],["tg","tgk","Tajik","тоҷикӣ"],["ta","tam","Tamil","தமிழ்"],["tt","tat","Tatar","татар"],["te","tel","Telugu","తెలుగు"],["th","tha","Thai","ไทย"],["bo","bod","Tibetan","བོད་སྐད་"],["ti","tir","Tigrinya","ትግርኛ"],["to","ton","Tonga","lea fakatonga"],["ts","tso","Tsonga","Xitsonga"],["tn","tsn","Tswana","Setswana"],["tr","tur","Turkish","Türkçe"],["tk","tuk","Turkmen","Türkmen dili"],["ug","uig","Uighur","ئۇيغۇرچە"],["uk","ukr","Ukrainian","українська"],["ur","urd","Urdu","اردو"],["uz","uzb","Uzbek","o‘zbek"],["ve","ven","Venda","Tshivenḓa"],["vi","vie","Vietnamese","Tiếng Việt"],["cy","cym","Welsh","Cymraeg"],["fy","fry","Western Frisian","Frysk"],["wo","wol","Wolof","Wolof"],["xh","xho","Xhosa","isiXhosa"],["yi","yid","Yiddish","ייִדיש"],["yo","yor","Yoruba","Èdè Yorùbá"],["zu","zul","Zulu","isiZulu"]]`