From c563af5a68cb365bb7b6ce2a94637413b42557ea Mon Sep 17 00:00:00 2001 From: "yakumo.izuru" Date: Thu, 19 Oct 2023 23:15:20 +0000 Subject: [PATCH] =?UTF-8?q?=E6=A7=8B=E6=88=90=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=81=AE=E3=82=B5=E3=83=9D=E3=83=BC=E3=83=88=E3=82=92?= =?UTF-8?q?=E6=9C=89=E5=8A=B9=E3=81=AB=E3=81=97=E3=80=81=E7=B5=84=E3=81=BF?= =?UTF-8?q?=E8=BE=BC=E3=81=BF=E3=81=AE=E9=9D=99=E7=9A=84=E3=83=AC=E3=83=B3?= =?UTF-8?q?=E3=83=80=E3=83=A9=E3=83=BC=E3=81=AE=E5=95=8F=E9=A1=8C=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E3=81=97=E3=81=BE=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Izuru Yakumo git-svn-id: file:///srv/svn/repo/mai/trunk@53 e410bdd4-646f-c54f-a7ce-fffcc4f439ae --- .gitignore | 1 - README.md | 14 +- cmd/simplytranslate/main.go | 257 ++++++++++++++++++++++++++++++++++++ engines/engine.go | 2 - example/simplytranslate.ini | 3 + go.mod | 7 +- go.sum | 15 +-- legal_notice.txt | 6 - 8 files changed, 280 insertions(+), 25 deletions(-) create mode 100644 cmd/simplytranslate/main.go create mode 100644 example/simplytranslate.ini delete mode 100644 legal_notice.txt diff --git a/.gitignore b/.gitignore index a65166b..e69de29 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +0,0 @@ -simplytranslate diff --git a/README.md b/README.md index 00a3d17..1f53297 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,14 @@ location / { proxy_set_header Host $host; proxy_pass http://localhost:5000; } -location /static { - alias /path/to/static/files; - autoindex off; -} ``` + +### Legal notice +SimplyTranslate does not host any content. All content shown on any SimplyTranslate instances is from [Google Translate](https://translate.google.com) and [Reverso](https://www.reverso.net/). + +SimplyTranslate is not affiliated with Google Translate nor Reverso that SimplyTranslate relays. + +Trademarks belong to their respective owners. +Google Translate is a trademark of Google LLC. Reverso is a trademark of Reverso. + +The creators and maintainers of this repository assume no liability for the accuracy and timeliness of any information provided above. Trademark owner information was researched to the best of the author's knowledge at the time of curation and may be outdated or incorrect. diff --git a/cmd/simplytranslate/main.go b/cmd/simplytranslate/main.go new file mode 100644 index 0000000..a8be7d5 --- /dev/null +++ b/cmd/simplytranslate/main.go @@ -0,0 +1,257 @@ +package main + +import ( + "bytes" + "net/http" + "net/url" + "time" + "flag" + + "git.chaotic.ninja/yakumo.izuru/simplytranslate/engines" + "github.com/gofiber/fiber/v2" + "github.com/gofiber/template/html/v2" + "gopkg.in/ini.v1" +) + +var conf struct { + listen string + staticpath string + tmplpath string +} +func readConf(file string) error { + cfg, err := ini.Load(file) + if err != nil { + return err + } + conf.listen = cfg.Section("").Key("listen").String() + conf.staticpath = cfg.Section("").Key("rootdir").String() + conf.tmplpath = cfg.Section("").Key("tmplpath").String() + + return nil +} +func main() { + var configfile string + flag.StringVar(&configfile, "f", "", "Configuration file") + flag.Parse() + + if configfile != "" { + readConf(configfile) + } + + conf.listen = "127.0.0.1:5000" + conf.staticpath = "./static" + conf.tmplpath = "./views" + + engine := html.New(conf.tmplpath, ".html") + engine.AddFunc("inc", func(i int) int { return i + 1 }) + + app := fiber.New(fiber.Config{ + Views: engine, + }) + + app.All("/", func(c *fiber.Ctx) error { + engine := c.Cookies("engine") + if c.Query("engine") != "" { + engine = c.Query("engine") + } + if _, ok := engines.Engines[engine]; !ok { + engine = "google" + } + targetLanguages, err := engines.Engines[engine].TargetLanguages() + if err != nil { + return c.SendStatus(500) + } + sourceLanguages, err := engines.Engines[engine].SourceLanguages() + if err != nil { + return c.SendStatus(500) + } + originalText := "" + translatedText := "" + from := "" + to := "" + ttsFrom := "" + ttsTo := "" + sourceLanguage := "" + + var translation engines.TranslationResult + if c.Method() == "POST" { + from = c.FormValue("from") + to = c.FormValue("to") + originalText = c.FormValue("text") + if result, err := engines.Engines[engine].Translate(originalText, from, to); err != nil { + return c.SendStatus(500) + } else { + translatedText = result.TranslatedText + translation = result + sourceLanguage = result.SourceLanguage + } + + ttsFromURL, _ := url.Parse("api/tts") + fromQuery := url.Values{} + fromQuery.Add("lang", from) + fromQuery.Add("text", originalText) + ttsFromURL.RawQuery = fromQuery.Encode() + ttsFrom = ttsFromURL.String() + + ttsToURL, _ := url.Parse("api/tts") + toQuery := url.Values{} + toQuery.Add("lang", to) + toQuery.Add("text", translatedText) + ttsToURL.RawQuery = toQuery.Encode() + ttsTo = ttsToURL.String() + + fromCookie := new(fiber.Cookie) + fromCookie.Name = "from" + fromCookie.Value = from + fromCookie.Expires = time.Now().Add(time.Hour * 24 * 365) + c.Cookie(fromCookie) + + toCookie := new(fiber.Cookie) + toCookie.Name = "to" + toCookie.Value = to + toCookie.Expires = time.Now().Add(time.Hour * 24 * 365) + c.Cookie(toCookie) + + engineCookie := new(fiber.Cookie) + engineCookie.Name = "engine" + engineCookie.Value = engine + engineCookie.Expires = time.Now().Add(time.Hour * 24 * 365) + c.Cookie(engineCookie) + } else if c.Method() == "GET" { + from = c.Cookies("from") + to = c.Cookies("to") + } else { + return c.SendStatus(400) + } + + if from == "" { + from = "auto" + } + + enginesNames := map[string]string{} + for k, v := range engines.Engines { + enginesNames[k] = v.DisplayName() + } + + return c.Render("index", fiber.Map{ + "Engine": engine, + "enginesNames": enginesNames, + "SourceLanguages": sourceLanguages, + "TargetLanguages": targetLanguages, + "OriginalText": originalText, + "Translation": translation, + "From": from, + "To": to, + "TtsFrom": ttsFrom, + "TtsTo": ttsTo, + "SourceLanguage": sourceLanguage, + }) + }) + + app.All("/api/translate", func(c *fiber.Ctx) error { + from := "" + to := "" + engine := "" + text := "" + if c.Method() == "GET" { + engine = c.Query("engine") + text = c.Query("text") + from = c.Query("from") + to = c.Query("to") + } else if c.Method() == "POST" { + engine = c.FormValue("engine") + text = c.FormValue("text") + from = c.FormValue("from") + to = c.FormValue("to") + } else { + return c.SendStatus(400) + } + if _, ok := engines.Engines[engine]; !ok || engine == "" { + engine = "google" + } + if to == "" { + return c.SendStatus(400) + } + if result, err := engines.Engines[engine].Translate(text, from, to); err != nil { + return c.SendStatus(500) + } else { + return c.JSON(result) + } + }) + + app.Get("/api/source_languages", func(c *fiber.Ctx) error { + engine := c.Query("engine") + if _, ok := engines.Engines[engine]; !ok || engine == "" { + engine = "google" + } + if result, err := engines.Engines[engine].SourceLanguages(); err != nil { + return c.SendStatus(500) + } else { + return c.JSON(result) + } + }) + + app.Get("/api/target_languages", func(c *fiber.Ctx) error { + engine := c.Query("engine") + if _, ok := engines.Engines[engine]; !ok || engine == "" { + engine = "google" + } + if result, err := engines.Engines[engine].TargetLanguages(); err != nil { + return c.SendStatus(500) + } else { + return c.JSON(result) + } + }) + + app.Get("/api/tts", func(c *fiber.Ctx) error { + engine := c.Query("engine") + if _, ok := engines.Engines[engine]; !ok || engine == "" { + engine = "google" + } + + text := c.Query("text") + if text == "" { + return c.SendStatus(400) + } + + lang := c.Query("lang") + + if url, err := engines.Engines[engine].Tts(text, lang); err != nil { + return c.SendStatus(500) + } else { + if response, err := http.Get(url); err != nil { + return c.SendStatus(500) + } else { + defer response.Body.Close() + var buf bytes.Buffer + response.Write(&buf) + c.Context().SetContentType("audio/mpeg") + return c.Send(buf.Bytes()) + } + } + }) + + app.Post("/switchlanguages", func(c *fiber.Ctx) error { + if c.Cookies("from") != "" { + fromCookie := new(fiber.Cookie) + fromCookie.Name = "from" + fromCookie.Value = c.Cookies("to") + fromCookie.Expires = time.Now().Add(24 * time.Hour * 365) + + toCookie := new(fiber.Cookie) + toCookie.Name = "to" + toCookie.Value = c.Cookies("from") + toCookie.Expires = time.Now().Add(24 * time.Hour * 365) + + c.Cookie(fromCookie) + c.Cookie(toCookie) + } + return c.Redirect("/") + }) + app.Static("/static", conf.staticpath, fiber.Static{ + Compress: true, + ByteRange: true, + Browse: true, + }) + app.Listen(conf.listen) +} diff --git a/engines/engine.go b/engines/engine.go index df3bc18..82f35aa 100644 --- a/engines/engine.go +++ b/engines/engine.go @@ -19,7 +19,5 @@ type Language map[string]string var Engines = map[string]Engine{ "google": &GoogleTranslate{}, - // "iciba": &ICIBA{}, - // "libre": &LibreTranslate{}, "reverso": &Reverso{}, } diff --git a/example/simplytranslate.ini b/example/simplytranslate.ini new file mode 100644 index 0000000..126cf95 --- /dev/null +++ b/example/simplytranslate.ini @@ -0,0 +1,3 @@ +listen = "127.0.0.1:5000" +rootdir = "/home/yakumo_izuru/Repos/simplytranslate/static" +tmplpath = "./views" diff --git a/go.mod b/go.mod index 85dec44..339b1c6 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,12 @@ -module git.chaotic.ninja/yakumo.izuru/simplytranslate-mod +module git.chaotic.ninja/yakumo.izuru/simplytranslate go 1.20 require ( - codeberg.org/SimpleWeb/SimplyTranslate/engines v0.0.0-20230920112526-526a2c0ed1dd github.com/PuerkitoBio/goquery v1.8.1 github.com/gofiber/fiber/v2 v2.49.2 github.com/gofiber/template/html/v2 v2.0.5 + gopkg.in/ini.v1 v1.67.0 ) require ( @@ -20,11 +20,10 @@ require ( github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/rivo/uniseg v0.2.0 // indirect + github.com/stretchr/testify v1.8.4 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.49.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect golang.org/x/net v0.8.0 // indirect golang.org/x/sys v0.12.0 // indirect ) - -replace codeberg.org/SimpleWeb/SimplyTranslate/engines v0.0.0 => ./engines diff --git a/go.sum b/go.sum index 70858b6..58d7beb 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,10 @@ -codeberg.org/SimpleWeb/SimplyTranslate/engines v0.0.0-20230920112526-526a2c0ed1dd h1:7of7Y4s8COfEcCqTIclI+EgObPRdhX/H4o2cXFGBymY= -codeberg.org/SimpleWeb/SimplyTranslate/engines v0.0.0-20230920112526-526a2c0ed1dd/go.mod h1:sEsqyflt+UgTVk1Z9hcwEexilsPOosOUPX6dlffsA1w= github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM= github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/gofiber/fiber/v2 v2.49.2 h1:ONEN3/Vc+dUCxxDgZZwpqvhISgHqb+bu+isBiEyKEQs= github.com/gofiber/fiber/v2 v2.49.2/go.mod h1:gNsKnyrmfEWFpJxQAV0qvW6l70K1dZGno12oLtukcts= github.com/gofiber/template v1.8.2 h1:PIv9s/7Uq6m+Fm2MDNd20pAFFKt5wWs7ZBd8iV9pWwk= @@ -25,8 +24,11 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.49.0 h1:9FdvCpmxB74LH4dPb7IJ1cOSsluR07XG3I1txXWwJpE= @@ -37,18 +39,15 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -63,15 +62,15 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/legal_notice.txt b/legal_notice.txt deleted file mode 100644 index 2040a34..0000000 --- a/legal_notice.txt +++ /dev/null @@ -1,6 +0,0 @@ -SimplyTranslate does not host any content. All content shown on any SimplyTranslate instances is from Google Translate, DeepL, ICIBA, Reverso and LibreTranslate. SimplyTranslate is not affiliated with Google Translate, DeepL, ICIBA, Reverso or LibreTranslate that SimplyTranslate relays. - -Trademarks belong to their respective owners. Google Translate is a trademark of Google LLC. DeepL is a trademark of DeepL SE. Reverso is a trademark of Reverso. LibreTranslate is a trademark of LibreTranslate. - -The creators of this repository assume no liability for the accuracy and timeliness of any information provided above. Trademark owner information was researched to the best of the author's knowledge at the time of curation and may be outdated or incorrect. -