fix: better backend configuration file parser

This commit is contained in:
JuanZoran 2023-03-12 15:18:27 +08:00
parent ded28b68bc
commit 5a36ffad1c
10 changed files with 161 additions and 197 deletions

View File

@ -1,25 +1,20 @@
local M = {} local M = {
uri = 'https://fanyi-api.baidu.com/api/trans/vip/translate',
salt = tostring(math.random(bit.lshift(1, 15))),
}
local Trans = require('Trans') local Trans = require('Trans')
local baidu = Trans.conf.keys.baidu
local app_id = baidu.app_id
local app_passwd = baidu.app_passwd
local salt = tostring(math.random(bit.lshift(1, 15)))
local uri = 'https://fanyi-api.baidu.com/api/trans/vip/translate'
function M.get_content(data) function M.get_content(data)
local tmp = app_id .. data.str .. salt .. app_passwd local tmp = M.app_id .. data.str .. M.salt .. M.app_passwd
local sign = Trans.util.md5.sumhexa(tmp) local sign = Trans.util.md5.sumhexa(tmp)
return { return {
q = data.str, q = data.str,
from = data.from, from = data.from,
to = data.to, to = data.to,
appid = app_id, appid = M.app_id,
salt = salt, salt = M.salt,
sign = sign, sign = sign,
} }
end end
@ -33,7 +28,11 @@ end
function M.query(data) function M.query(data)
data.engine = 'baidu' if M.disable then
data.result.baidu = false
return
end
local handle = function(res) local handle = function(res)
local status, body = pcall(vim.json.decode, res.body) local status, body = pcall(vim.json.decode, res.body)
@ -41,7 +40,7 @@ function M.query(data)
local result = body.trans_result local result = body.trans_result
if result then if result then
-- TEST :whether multi result -- TEST :whether multi result
assert(#result == 1, 'multi result :' .. vim.inspect(result)) assert(#result == 1)
result = result[1] result = result[1]
data.result.baidu = { data.result.baidu = {
title = result.src, title = result.src,
@ -56,7 +55,7 @@ function M.query(data)
end end
Trans.wrapper.curl.get(uri, { Trans.wrapper.curl.get(M.uri, {
query = M.get_content(data), query = M.get_content(data),
callback = handle, callback = handle,
}) })

View File

@ -1,4 +1,4 @@
local M = { no_wait = true } local M = { no_wait = true, }
local db = require 'sqlite.db' local db = require 'sqlite.db'
vim.api.nvim_create_autocmd('VimLeavePre', { vim.api.nvim_create_autocmd('VimLeavePre', {
@ -13,7 +13,6 @@ vim.api.nvim_create_autocmd('VimLeavePre', {
function M.query(data) function M.query(data)
if data.is_word == false or data.from == 'zh' then return end if data.is_word == false or data.from == 'zh' then return end
data.path = data.path or require('Trans').conf.dir .. '/ultimate.db' data.path = data.path or require('Trans').conf.dir .. '/ultimate.db'
data.engine = 'offline' data.engine = 'offline'
data.formatter = data.formatter or M.formatter data.formatter = data.formatter or M.formatter

View File

@ -0,0 +1,32 @@
local Trans = require('Trans')
local M = Trans.metatable('backend')
--- INFO :Parse online engine keys config file
local path = Trans.conf.dir .. '/Trans.json'
local file = io.open(path, "r")
if file then
local content = file:read("*a")
local status, result = pcall(vim.json.decode, content)
file:close()
if not status then
error('Unable to parse json file: ' .. path .. '\n' .. result)
end
local default_opts = vim.deepcopy(Trans.conf.backend)
for name, private_opts in pairs(result or {}) do
local opts = vim.tbl_extend('keep', Trans.conf.backend[name] or {}, default_opts, private_opts)
local backend = M[name]
for k, v in pairs(opts) do
if not backend[k] then
backend[k] = v
end
end
end
end
return M

View File

@ -3,7 +3,7 @@ local Trans = require('Trans')
local function set_strategy_opts(conf) local function set_strategy_opts(conf)
local define = Trans.define local define = Trans.define
local all_modes = define.modes local all_modes = define.modes
local all_backends = vim.tbl_keys(conf.keys) local all_backends = define.backends
local function parse_backend(backend) local function parse_backend(backend)
if type(backend) == 'string' then if type(backend) == 'string' then
@ -62,6 +62,26 @@ local function set_frontend_opts(conf)
end end
local function define_keymaps(conf)
local set = vim.keymap.set
local opts = { silent = true, expr = true }
for _, name in ipairs(Trans.define.frontends) do
for action, key in pairs(conf.frontend[name].keymap) do
set('n', key, function()
local frontend = Trans.frontend[name]
if frontend.is_available() then
frontend.actions[action]()
else
return key
end
end, opts)
end
end
end
local function define_highlights(conf) local function define_highlights(conf)
local set_hl = vim.api.nvim_set_hl local set_hl = vim.api.nvim_set_hl
@ -80,5 +100,6 @@ return function(opts)
set_strategy_opts(conf) set_strategy_opts(conf)
set_frontend_opts(conf) set_frontend_opts(conf)
define_keymaps(conf)
define_highlights(conf) define_highlights(conf)
end end

View File

@ -1,7 +1,6 @@
local Trans = require('Trans') local Trans = require('Trans')
local util = Trans.util local util = Trans.util
vim.pretty_print(Trans.conf)
local function new_data(opts) local function new_data(opts)
opts = opts or {} opts = opts or {}
local mode = opts.method or ({ local mode = opts.method or ({
@ -28,37 +27,41 @@ local function new_data(opts)
data.from = 'zh' data.from = 'zh'
data.to = 'en' data.to = 'en'
end end
-- TODO : Check if the str is a word
data.is_word = true
return data return data
end end
local function set_result(data) local function set_result(data)
-- local t_backend = require('Trans').backend local backend_list = data.backend
-- for _, name in rdata.backend do local backends = Trans.backend
-- local backend = t_backend[name]
-- backend.query(data)
-- if backend.no_wait then
-- end
-- end
-- Trans.backend.baidu.query(data) local frontend = Trans.frontend[data.frontend]
-- local thread = coroutine.running()
-- local resume = function()
-- coroutine.resume(thread)
-- end
-- local time = 0 local function do_query(name)
-- while data.result == nil do local backend = backends[name]
-- vim.defer_fn(resume, 400) if backend.no_wait then
-- time = time + 1 backend.query(data)
-- print('waiting' .. ('.'):rep(time)) if type(data.result[name]) == 'table' then
-- coroutine.yield() return
-- end end
-- vim.pretty_print(data) else
backend.query(data)
frontend.wait(data.result, name, backend.timeout)
end
end
for _, name in ipairs(backend_list) do
do_query(name)
end
end end
local function render_window() local function render_window(data)
-- TODO
print('begin to render window')
end end
-- HACK : Core process logic -- HACK : Core process logic
@ -71,7 +74,7 @@ local function process(opts)
set_result(data) set_result(data)
if data.result == false then return end if data.result == false then return end
render_window() render_window(data)
end end
return coroutine.wrap(process) return coroutine.wrap(process)

View File

@ -36,18 +36,16 @@ end
---@param mode string 'n' | 'v' | 'i' ---@param mode string 'n' | 'v' | 'i'
---@return string ---@return string
function M.get_str(mode) function M.get_str(mode)
return ({ if mode == 'n' or mode == 'normal' then
normal = function() return fn.expand('<cword>')
return fn.expand('<cword>') elseif mode == 'v' or mode == 'visual' then
end, api.nvim_input('<ESC>')
visual = function() return M.get_select()
api.nvim_input('<ESC>') elseif mode == 'input' then
return M.get_select() return fn.expand('<cword>')
end, else
input = function() error('Unsupported mode' .. mode)
return fn.input('请输入需要查询的单词:') end
end,
})[mode]()
end end
function M.is_English(str) function M.is_English(str)

View File

@ -1,16 +1,67 @@
local M = {} local M = {}
local api = vim.api local api = vim.api
local conf = require('Trans').conf
function M.process(data)
function M.init()
print('TODO: init hover window')
end end
function M.wait(tbl, key, timeout)
local thread = coroutine.running()
local function pause(ms)
vim.defer_fn(function()
coroutine.resume(thread)
end, ms)
coroutine.yield()
end
local error_message = 'Faild'
local times = 0
local interval = math.floor(timeout / #error_message)
while tbl[key] == nil do
print(('waitting' .. (' '):rep(times)))
pause(interval)
end
if tbl[key] == false then
print('TODO: show error message: ' .. error_message)
else
vim.pretty_print(tbl[key])
end
end
function M.process(data)
print('TODO: process data')
end
function M.is_available()
return true
end
M.actions = {
play = function()
print('TODO: play')
end,
pageup = function()
print('TODO: pageup')
end,
pagedown = function()
print('TODO: pagedown')
end,
pin = function()
print('TODO: pin')
end,
close = function()
print('TODO: close')
end,
toggle_entry = function()
print('TODO: toggle_entry')
end,
}
return M return M
-- local api = vim.api
-- local conf = require('Trans').conf
-- local hover = conf.hover -- local hover = conf.hover
-- local error_msg = conf.icon.notfound .. ' 没有找到相关的翻译' -- local error_msg = conf.icon.notfound .. ' 没有找到相关的翻译'

View File

@ -19,7 +19,6 @@ local M = metatable('core')
M.metatable = metatable M.metatable = metatable
M.style = metatable("style") M.style = metatable("style")
M.wrapper = metatable("wrapper") M.wrapper = metatable("wrapper")
M.backend = metatable("backend")
M.frontend = metatable("frontend") M.frontend = metatable("frontend")

View File

@ -1,109 +0,0 @@
--- TODO :wrapper for curl
local curl = {}
---Send a GET request
---@param opts table
curl.GET = function(opts)
local uri = opts.uri
local headers = opts.headers or {}
local callback = opts.callback
-- INFO :Init Curl command with {s}ilent and {G}et
local cmd = { 'curl', '-Gs' }
-- INFO :Add headers
for k, v in pairs(headers) do
cmd[#cmd + 1] = ([[-H '%s: %s']]):format(k, v)
end
-- INFO :Add arguments
local info = {}
for k, v in pairs(opts.arguments) do
info[#info + 1] = ('%s=%s'):format(k, v)
end
cmd[#cmd + 1] = ([['%s?%s']]):format(uri, table.concat(info, '&'))
-- write a function to get the output
local outpus = {}
vim.fn.jobstart(table.concat(cmd, ' '), {
stdin = 'null',
on_stdout = function(_, stdout)
local str = table.concat(stdout)
if str ~= '' then
end
end,
on_exit = function()
callback(output)
end,
})
-- local output = ''
-- local option = {
-- stdin = 'null',
-- on_stdout = function(_, stdout)
-- local str = table.concat(stdout)
-- if str ~= '' then
-- output = output .. str
-- end
-- end,
-- on_exit = function()
-- callback(output)
-- end,
-- }
-- vim.fn.jobstart(table.concat(cmd, ' '), option)
end
curl.POST = function(opts)
vim.validate {
uri = { uri, 's' },
opts = { opts, 't' }
}
local callback = opts.callback
local cmd = { 'curl', '-s', ('"%s"'):format(uri) }
local size = 3
local function insert(...)
for _, v in ipairs { ... } do
size = size + 1
cmd[size] = v
end
end
local s = '"%s=%s"'
if opts.headers then
for k, v in pairs(opts.headers) do
insert('-H', s:format(k, v))
end
end
for k, v in pairs(opts.data) do
insert('-d', s:format(k, v))
end
local output = ''
local option = {
stdin = 'null',
on_stdout = function(_, stdout)
local str = table.concat(stdout)
if str ~= '' then
output = output .. str
end
end,
on_exit = function()
callback(output)
end,
}
vim.fn.jobstart(table.concat(cmd, ' '), option)
end
return curl

View File

@ -31,32 +31,3 @@ command('TransPlay', function()
str:play() str:play()
end end
end, { desc = ' 自动发音' }) end, { desc = ' 自动发音' })
--- INFO :Parse online engine keys config file
local function parse_engine_file()
local path = Trans.conf.dir .. '/Trans.json'
local file = io.open(path, "r")
if file then
local content = file:read("*a")
local status, result = pcall(vim.json.decode, content)
file:close()
assert(status, 'Unable to parse json file: ' .. path)
return result
end
end
local result = parse_engine_file()
if result then
for name, opts in pairs(result) do
if not opts.enable then
result[name] = nil
end
end
Trans.conf.keys = result
else
Trans.conf.keys = {}
end