import ../../base import std/[re,httpclient,json,strutils,tables] # TODO: # Query available languages, maybe have selection panel # Maybe store last used so future translations are more fluent const LIBRETRANSLATE_URL = "https://libretranslate.pussthecat.org/" const HOME = "en" let LANG_RE = re"\w+>\w+" let DETECT_RE = re"\bd(etect)?\b" var current = @["de",HOME] var detected = {"detected":"0","confidence":"0","language":"en"}.toTable type Request = object source: string target: string q: string format: string proc main(messages: varargs[string] = @[]) proc newRequest(): Request = return Request(source:current[0], target:current[1], q: "", format: "text",) proc parseReq(req: string): Request = var langs = findAll(req,LANG_RE) var r = newRequest() let query = replace(req,LANG_RE,"") r.q = query if len(langs) > 0: let lang = langs[0] langs = lang.split(re">") current[0] = langs[0].toLowerAscii() current[1] = langs[1].toLowerAscii() r.source = current[0].toLowerAscii() r.target = current[1].toLowerAscii() if query == "": main() return r proc answerTranslate(response: string, req: Request) = let r = parseJson(response) try: let ans = r["translatedText"].getStr() main(ans) except: main("Error : " & r["error"].getStr()) proc goTranslate(req: string) = let r = parseReq(req) if r.q != "": var client = newHTTPClient() client.headers = newHttpHeaders({"Content-Type":"application/json"}) let body = %*r let response = client.request(LIBRETRANSLATE_URL & "translate", httpMethod = HttpPost, body = $body) if response.status != "": answerTranslate(response.body, r) proc flipCurrent() = current = @[current[1],current[0]] main() proc detectLanguage(str: string) = let term = replace(str,DETECT_RE,"") echo "detecting ", term if term != "": var client = newHTTPClient() client.headers = newHttpHeaders({"Content-Type":"application/json"}) let body = %*Request(q:term) let response = client.request(LIBRETRANSLATE_URL & "detect", httpMethod = HttpPost, body = $body) if response.status != "": let r = parseJson(response.body) echo r try: detected["confidence"] = $r[0]["confidence"].getFloat() detected["language"] = r[0]["language"].getStr() detected["detected"] = "1" current[0] = detected["language"] current[1] = HOME goTranslate(term) except: try: main("Error : " & r["error"].getStr()) except: main("Error Parsing Json") return proc main(messages:varargs[string] = @[]) = var info = newInfo("Translate") info.selected_bg = green var args: seq[string] = @[] for msg in messages: if msg != "": args.add(msg) args.add(current[0] & " > " & current[1]) if detected["detected"] == "1": args.add("detected language : " & detected["language"]) args.add("detected confidence : " & detected["confidence"]) detected["detected"] = "0" if len(messages) > 0: args.add("back") args.add("exit") let output = outputData(info,args) if output == "exit" or output == "": return elif output == "back": main() elif output == current[0] & " > " & current[1]: flipCurrent() elif re.startsWith(output,DETECT_RE): detectLanguage(output) elif output in messages: copyToClipboard(output) else: goTranslate(output) return if isMainModule: main()