From b2cafe344864ff3c3bfb8df8220cc931282ffe26 Mon Sep 17 00:00:00 2001
From: JuanZoran <1430359574@qq.com>
Date: Sat, 18 Mar 2023 18:20:01 +0800
Subject: [PATCH] feat: add free backend iciba.lua and try to use template
 method for querying backend data

---
 lua/Trans/backend/iciba.lua  | 85 ++++++++++++++++++++++++++++++++++++
 lua/Trans/backend/youdao.lua | 72 +++++++++++++++---------------
 lua/Trans/core/translate.lua | 60 ++++++++++++++++++++++++-
 3 files changed, 181 insertions(+), 36 deletions(-)
 create mode 100644 lua/Trans/backend/iciba.lua

diff --git a/lua/Trans/backend/iciba.lua b/lua/Trans/backend/iciba.lua
new file mode 100644
index 0000000..3612c6a
--- /dev/null
+++ b/lua/Trans/backend/iciba.lua
@@ -0,0 +1,85 @@
+---@class iCiba: TransBackend
+---@field uri string api uri
+---@field salt string
+---@field app_id string
+---@field app_passwd string
+---@field disable boolean
+local M = {
+    uri  = 'https://dict-mobile.iciba.com/interface/index.php',
+    name = 'iciba',
+}
+
+---@class iCibaQuery
+---@field q string
+---@field from string
+---@field to string
+---@field appid string
+---@field salt string
+---@field sign string
+function M.get_content(data)
+    return {
+        word = data.str,
+        is_need_mean = '1',
+        m = 'getsuggest',
+        c = 'word',
+    }
+end
+
+---@overload fun(TransData): TransResult
+function M.query(data)
+    local handle = function(res)
+        local status, body = pcall(vim.json.decode, res.body)
+        vim.print(body)
+
+        if true and not status or not body or body.errorCode ~= "0" then
+            data.result.iciba = false
+            data[#data + 1] = res
+            return
+        end
+
+        -- if not body.isWord then
+        --     data.result.youdao = {
+        --         title = body.query,
+        --         [data.from == 'en' and 'translation' or 'definition'] = body.translation,
+        --     }
+        --     return
+        -- end
+
+        -- local tmp = {
+        --     title    = {
+        --         word     = body.query,
+        --         phonetic = body.basic.phonetic,
+        --     },
+        --     web      = body.web,
+        --     explains = body.basic.explains,
+        --     -- phrases                                               = body.phrases,
+        --     -- synonyms                                              = body.synonyms,
+        --     -- sentenceSample                                        = body.sentenceSample,
+
+
+        --     [data.from == 'en' and 'translation' or 'definition'] = body.translation,
+        -- }
+        -- data.result.iciba = tmp
+    end
+
+    require('Trans').curl.get(M.uri, {
+        query = M.get_content(data),
+        callback = handle,
+    })
+end
+
+-- {
+--   message = { {
+--       key = "测试",
+--       means = { {
+--           means = { "test", "testing", "checkout", "measurement " },
+--           part = ""
+--         } },
+--       paraphrase = "test;testing;measurement ;checkout",
+--       value = 0
+--     } },
+--   status = 1
+-- }
+
+
+return M
diff --git a/lua/Trans/backend/youdao.lua b/lua/Trans/backend/youdao.lua
index ed8d425..33e97fd 100644
--- a/lua/Trans/backend/youdao.lua
+++ b/lua/Trans/backend/youdao.lua
@@ -52,33 +52,41 @@ function M.get_content(data)
     }
 end
 
-local field = {
-    "phonetic",
-    'usPhonetic',
-    "ukPhonetic",
-    "text",           --	text	短语
-    "explain",        --	String Array	词义解释列表
-    "wordFormats",    --	Object Array	单词形式变化列表
-    "name",           --	String	形式名称,例如:复数
-    "phrase",         --	String	词组
-    "meaning",        --	String	含义
-    "synonyms",       --	JSONObject	近义词
-    "pos",            --	String	词性
-    "words",          --	String Array	近义词列表
-    "trans",          --	String	释义
-    "antonyms",       --	ObjectArray	反义词
-    "relatedWords",   --	JSONArray	相关词
-    "wordNet",        --	JSONObject	汉语词典网络释义
-    "phonetic",       --	String	发音
-    "meanings",       --	ObjectArray	释义
-    "meaning",        --	String	释义
-    "example",        --	array	示例
-    "sentenceSample", --	text	例句
-    "sentence",       --	text	例句
-    "sentenceBold",   --	text	将查询内容加粗的例句
-    "wfs",            --	text	单词形式变化
-    "exam_type",      --	text	考试类型
-}
+local function check_untracked_field(body)
+    local field = {
+        "phonetic",
+        'usPhonetic',
+        "ukPhonetic",
+        "text",       --	text	短语
+        "explain",    --	String Array	词义解释列表
+        "wordFormats", --	Object Array	单词形式变化列表
+        "name",       --	String	形式名称,例如:复数
+        "phrase",     --	String	词组
+        "meaning",    --	String	含义
+        "synonyms",   --	JSONObject	近义词
+        "pos",        --	String	词性
+        "words",      --	String Array	近义词列表
+        "trans",      --	String	释义
+        "antonyms",   --	ObjectArray	反义词
+        "relatedWords", --	JSONArray	相关词
+        "wordNet",    --	JSONObject	汉语词典网络释义
+        "phonetic",   --	String	发音
+        "meanings",   --	ObjectArray	释义
+        "meaning",    --	String	释义
+        "example",    --	array	示例
+        "sentenceSample", --	text	例句
+        "sentence",   --	text	例句
+        "sentenceBold", --	text	将查询内容加粗的例句
+        "wfs",        --	text	单词形式变化
+        "exam_type",  --	text	考试类型
+    }
+    for _, f in ipairs(field) do
+        if body[f] then
+            print(('%s found : %s'):format(f, vim.inspect(body[f])))
+        end
+    end
+end
+
 
 
 
@@ -126,14 +134,6 @@ function M.query(data)
     local handle = function(res)
         local status, body = pcall(vim.json.decode, res.body)
         -- vim.print(body)
-        if body then
-            for _, f in ipairs(field) do
-                if body[f] then
-                    print(('%s found : %s'):format(f, vim.inspect(body[f])))
-                end
-            end
-        end
-
         if not status or not body or body.errorCode ~= "0" then
             if not require('Trans').conf.debug then M.debug(body) end
             data.result.youdao = false
@@ -141,6 +141,8 @@ function M.query(data)
             return
         end
 
+        check_untracked_field(body)
+
         if not body.isWord then
             data.result.youdao = {
                 title = body.query,
diff --git a/lua/Trans/core/translate.lua b/lua/Trans/core/translate.lua
index b8f8ee0..422294d 100644
--- a/lua/Trans/core/translate.lua
+++ b/lua/Trans/core/translate.lua
@@ -13,6 +13,64 @@ local function init_opts(opts)
 end
 
 
+local function do_query(data, backend)
+    -- TODO : template method for online query
+    local name      = backend.name
+    local uri       = backend.uti
+    local method    = backend.method
+    local formatter = backend.formatter
+    local query     = backend.get_query(data)
+
+    local header
+    if backend.header then
+        if type(backend.header) == "function" then
+            header = backend.header(data)
+        else
+            header = backend.header
+        end
+    end
+
+    local function handle(output)
+        local status, body = pcall(vim.json.decode, output.body)
+        -- -- vim.print(body)
+        if not status or not body or body.errorCode ~= "0" then
+            if not Trans.conf.debug then backend.debug(body) end
+            data.result[name] = false
+            data[#data + 1] = output
+            return
+        end
+        -- check_untracked_field(body)
+        -- if not body.isWord then
+        --     data.result.youdao = {
+        --         title = body.query,
+        --         [data.from == 'en' and 'translation' or 'definition'] = body.translation,
+        --     }
+        --     return
+        -- end
+        -- local tmp = {
+        --     title    = {
+        --         word     = body.query,
+        --         phonetic = body.basic.phonetic,
+        --     },
+        --     web      = body.web,
+        --     explains = body.basic.explains,
+        --     -- phrases                                               = body.phrases,
+        --     -- synonyms                                              = body.synonyms,
+        --     -- sentenceSample                                        = body.sentenceSample,
+        --     [data.from == 'en' and 'translation' or 'definition'] = body.translation,
+        -- }
+        data.result[name] = formatter and formatter(output) or output
+    end
+
+    Trans.curl[method](uri, {
+        query = query,
+        callback = handle,
+        header = header,
+    })
+    -- Hook ?
+end
+
+
 ---@type table<string, fun(data: TransData): true | nil>
 local strategy = {
     fallback = function(data)
@@ -38,6 +96,7 @@ local strategy = {
 }
 
 
+
 -- HACK : Core process logic
 local function process(opts)
     opts = init_opts(opts)
@@ -55,7 +114,6 @@ local function process(opts)
     if strategy[Trans.conf.query](data) then
         Trans.cache[data.str] = data
         data.frontend:process(data)
-
     else
         data.frontend:fallback()
     end