diff --git a/go.mod b/go.mod index 289a76f..9106f87 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( github.com/antchfx/htmlquery v1.3.0 // indirect github.com/antchfx/xmlquery v1.3.17 // indirect github.com/antchfx/xpath v1.2.4 // indirect + github.com/carlmjohnson/requests v0.23.4 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect diff --git a/go.sum b/go.sum index ea4f802..9de8083 100644 --- a/go.sum +++ b/go.sum @@ -86,6 +86,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/carlmjohnson/requests v0.23.4 h1:AxcvapfB9RPXLSyvAHk9YJoodQ43ZjzNHj6Ft3tQGdg= +github.com/carlmjohnson/requests v0.23.4/go.mod h1:Qzp6tW4DQyainPP+tGwiJTzwxvElTIKm0B191TgTtOA= github.com/cbroglie/mustache v1.4.0/go.mod h1:SS1FTIghy0sjse4DUVGV1k/40B1qE1XkD9DtDsHo9iM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/pages/api.go b/pages/api.go new file mode 100644 index 0000000..814105b --- /dev/null +++ b/pages/api.go @@ -0,0 +1,62 @@ +package pages + +import ( + "codeberg.org/aryak/simplytranslate/utils" + "github.com/gofiber/fiber/v2" +) + +func HandleSourceLanguages(c *fiber.Ctx) error { + engine := c.Query("engine") + if engine == "" { + return c.SendStatus(fiber.StatusBadRequest) + } + var data []utils.List + if engine == "google" { + data = utils.LangListGoogle("sl") + } else if engine == "libre" { + data = utils.LangListLibreTranslate("sl") + } else if engine == "reverso" { + data = utils.LangListReverso("sl") + } else if engine == "deepl" { + data = utils.LangListDeepl("sl") + } + return c.JSON(data) +} +func HandleTargetLanguages(c *fiber.Ctx) error { + engine := c.Query("engine") + if engine == "" { + return c.SendStatus(fiber.StatusBadRequest) + } + var data []utils.List + if engine == "google" { + data = utils.LangListGoogle("tl") + } else if engine == "libre" { + data = utils.LangListLibreTranslate("sl") + } else if engine == "reverso" { + data = utils.LangListReverso("tl") + } else if engine == "deepl" { + data = utils.LangListDeepl("tl") + } + return c.JSON(data) +} +func HandleTTS(c *fiber.Ctx) error { + engine := c.Query("engine") + lang := c.Query("lang") + text := c.Query("text") + // Why does go not have an andor statement :( + if engine == "" { + return c.SendStatus(fiber.StatusBadRequest) + } else if text == "" { + return c.SendStatus(fiber.StatusBadRequest) + } else if lang == "" { + return c.SendStatus(fiber.StatusBadRequest) + } + var data string + if engine == "google" { + data = utils.TTSGoogle(lang, text) + } else if engine == "reverso" { + data = utils.TTSReverso(lang, text) + } + c.Set("Content-Type", "audio/mpeg") + return c.Send([]byte(data)) +} diff --git a/serve/serve.go b/serve/serve.go index 1d23945..8a2b872 100644 --- a/serve/serve.go +++ b/serve/serve.go @@ -49,7 +49,6 @@ func Serve(port string) { err = ctx.Status(code).Render("error", fiber.Map{ "error": err, "link": link, - "branch": utils.Branch, }) if err != nil { return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error") @@ -76,7 +75,6 @@ func Serve(port string) { // LimitReached: func(c *fiber.Ctx) error { // return c.Status(429).Render("ratelimit_gt", fiber.Map{ // "Title": "Rate limit exceeded", - // "branch": utils.Branch, // }) // }, //}) @@ -99,6 +97,10 @@ func Serve(port string) { }) app.Get("/", pages.HandleIndex) + //app.Get("/api/translate", pages.HandleTranslateApi) + app.Get("/api/source_languages", pages.HandleSourceLanguages) + app.Get("/api/target_languages", pages.HandleTargetLanguages) + app.Get("/api/tts", pages.HandleTTS) app.Static("/css", "./public/css", staticConfig) app.Static("/robots.txt", "./public/robots.txt", staticConfig) app.Static("/favicon.ico", "./public/assets/favicon.ico", staticConfig) diff --git a/utils/langlist.go b/utils/langlist.go index 9519a38..55e19d3 100644 --- a/utils/langlist.go +++ b/utils/langlist.go @@ -94,8 +94,8 @@ func LangListReverso(listType string) []List { Name: "Greek", }, List{ - Id: "Hebrew", - Name: "heb", + Id: "heb", + Name: "Hebrew", }, List{ Id: "hin", diff --git a/utils/tts.go b/utils/tts.go new file mode 100644 index 0000000..5df3d11 --- /dev/null +++ b/utils/tts.go @@ -0,0 +1,142 @@ +package utils + +import ( + "github.com/carlmjohnson/requests" + "os" + "context" + "encoding/base64" +) + +type ReversoTTS struct { + Id string + Voice string +} + +func TTSGoogle(lang string, query string) string { + params := "?tl="+lang+"&q="+query+"&client=tw-ob" + var file string + url := "https://translate.google.com/translate_tts"+params + err := requests. + URL(url). + ToString(&file). + Fetch(context.Background()) + if err != nil { + file = "" + } + return file +} +func TTSReverso(lang string, query string) string { + var TTSData = []ReversoTTS{ + // http://voice.reverso.net/RestPronunciation.svc/v1/output=json/GetAvailableVoices with randomized deduplication + ReversoTTS{ + Id: "ar", + Voice: "Mehdi22k", + }, + ReversoTTS{ + Id: "zh", + Voice: "Lulu22k", + }, + ReversoTTS{ + Id: "cz", + Voice: "Eliska22k", + }, + ReversoTTS{ + Id: "dk", + Voice: "Mette22k", + }, + ReversoTTS{ + Id: "nl", + Voice: "Daan22k", + }, + ReversoTTS{ + Id: "en", + Voice: "Will22k", + }, + ReversoTTS{ + Id: "fr", + Voice: "Margaux22k", + }, + ReversoTTS{ + Id: "de", + Voice: "Andreas22k", + }, + ReversoTTS{ + Id: "gr", + Voice: "Dimitris22k", + }, + ReversoTTS{ + Id: "heb", + Voice: "he-IL-Asaf", + }, + ReversoTTS{ + Id: "it", + Voice: "Chiara22k", + }, + ReversoTTS{ + Id: "jp", + Voice: "Sakura22k", + }, + ReversoTTS{ + Id: "kr", + Voice: "Minji22k", + }, + ReversoTTS{ + Id: "pl", + Voice: "Monika22k", + }, + ReversoTTS{ + Id: "pt", + Voice: "Celia22k", + }, + ReversoTTS{ + Id: "ro", + Voice: "ro-RO-Andrei", + }, + ReversoTTS{ + Id: "ru", + Voice: "Alyona22k", + }, + ReversoTTS{ + Id: "es", + Voice: "Antonio22k", + }, + ReversoTTS{ + Id: "se", + Voice: "Erik22k", + }, + ReversoTTS{ + Id: "tr", + Voice: "Ipek22k", + }, + } + // https://voice.reverso.net/RestPronunciation.svc/v1/output=json/GetVoiceStream/voiceName=Lulu22k?voiceSpeed=80&inputText=6K%20V6aqM Base64 input text + text := base64.StdEncoding.EncodeToString([]byte(query)) + var voice string + for _, s := range TTSData { + if s.Id == lang { + voice = s.Voice + break + } + } + + params := "voiceName="+voice+"?voiceSpeed=80&inputText="+text + + var file string + + url := "https://voice.reverso.net/RestPronunciation.svc/v1/output=json/GetVoiceStream/"+params + + UserAgent, ok := os.LookupEnv("SIMPLYTRANSLATE_USER_AGENT") + if !ok { + UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36" + } + + err := requests. + URL(url). + ToString(&file). + UserAgent(UserAgent). + Fetch(context.Background()) + if err != nil { + file = "" + } + return file +}