From c7f77de72aefa4a23b22201363c53a0c050e2aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Fern=C3=A1ndez?= Date: Thu, 27 Aug 2020 21:41:16 +0200 Subject: [PATCH] refactor thirdparty app integration (#6513) * refactor thirdparty app integration * Fix fora package name --- frontend/device/android/device.lua | 57 +++++++++--------- frontend/device/android/dictionaries.lua | 20 ------- frontend/device/sdl/device.lua | 64 ++++++++++----------- frontend/device/sdl/dictionaries.lua | 20 ------- frontend/device/thirdparty.lua | 73 ++++++++++++++++++++++++ 5 files changed, 131 insertions(+), 103 deletions(-) delete mode 100644 frontend/device/android/dictionaries.lua delete mode 100644 frontend/device/sdl/dictionaries.lua create mode 100644 frontend/device/thirdparty.lua diff --git a/frontend/device/android/device.lua b/frontend/device/android/device.lua index b4206ad7e..4ee0be266 100644 --- a/frontend/device/android/device.lua +++ b/frontend/device/android/device.lua @@ -46,22 +46,25 @@ local function getCodename() return codename end -local EXTERNAL_DICTS_AVAILABILITY_CHECKED = false -local EXTERNAL_DICTS = require("device/android/dictionaries") -local external_dict_when_back_callback = nil - -local function getExternalDicts() - if not EXTERNAL_DICTS_AVAILABILITY_CHECKED then - EXTERNAL_DICTS_AVAILABILITY_CHECKED = true - for i, v in ipairs(EXTERNAL_DICTS) do - local package = v[4] - if android.isPackageEnabled(package) then - v[3] = true - end - end - end - return EXTERNAL_DICTS -end +-- thirdparty app support +local external = require("device/thirdparty"):new{ + dicts = { + { "Aard2", "Aard2", false, "itkach.aard2", "aard2" }, + { "Alpus", "Alpus", false, "com.ngcomputing.fora.android", "search" }, + { "ColorDict", "ColorDict", false, "com.socialnmobile.colordict", "colordict" }, + { "Eudic", "Eudic", false, "com.eusoft.eudic", "send" }, + { "Fora", "Fora Dict", false, "com.ngc.fora", "search" }, + { "ForaPro", "Fora Pro", false, "com.ngc.fora.android", "search" }, + { "GoldenFree", "GoldenDict Free", false, "mobi.goldendict.android.free", "send" }, + { "GoldenPro", "GoldenDict Pro", false, "mobi.goldendict.android", "send" }, + { "Kiwix", "Kiwix", false, "org.kiwix.kiwixmobile", "text" }, + { "Mdict", "Mdict", false, "cn.mdict", "send" }, + { "QuickDic", "QuickDic", false, "de.reimardoeffinger.quickdic", "quickdic" }, + }, + check = function(self, app) + return android.isPackageEnabled(app) + end, +} local Device = Generic:new{ isAndroid = yes, @@ -93,18 +96,13 @@ local Device = Generic:new{ doShareText = function(text) android.sendText(text) end, canExternalDictLookup = yes, - getExternalDictLookupList = getExternalDicts, + getExternalDictLookupList = function() return external.dicts end, doExternalDictLookup = function (self, text, method, callback) - external_dict_when_back_callback = callback - local package, action = nil - for i, v in ipairs(getExternalDicts()) do - if v[1] == method then - package = v[4] - action = v[5] - break - end + external.when_back_callback = callback + local _, app, action = external:checkMethod("dict", method) + if app and action then + android.dictLookup(text, app, action) end - android.dictLookup(text, package, action) end, @@ -151,10 +149,9 @@ function Device:init() end -- to-do: keyboard connected, disconnected elseif ev.code == C.APP_CMD_RESUME then - EXTERNAL_DICTS_AVAILABILITY_CHECKED = false - if external_dict_when_back_callback then - external_dict_when_back_callback() - external_dict_when_back_callback = nil + if external.when_back_callback then + external.when_back_callback() + external.when_back_callback = nil end local new_file = android.getIntent() if new_file ~= nil and lfs.attributes(new_file, "mode") == "file" then diff --git a/frontend/device/android/dictionaries.lua b/frontend/device/android/dictionaries.lua deleted file mode 100644 index ce02b797f..000000000 --- a/frontend/device/android/dictionaries.lua +++ /dev/null @@ -1,20 +0,0 @@ -local user_path = require("datastorage"):getDataDir() .. "/dictionaries.lua" -local ok, dicts = pcall(dofile, user_path) - -if ok then - return dicts -else - return { - -- tested dictionary applications - { "Aard2", "Aard2", false, "itkach.aard2", "aard2" }, - { "Alpus", "Alpus", false, "com.ngcomputing.fora.android", "search" }, - { "ColorDict", "ColorDict", false, "com.socialnmobile.colordict", "colordict" }, - { "Eudic", "Eudic", false, "com.eusoft.eudic", "send" }, - { "Fora", "Fora Dict", false, "com.ngc.fora", "search" }, - { "GoldenFree", "GoldenDict Free", false, "mobi.goldendict.android.free", "send" }, - { "GoldenPro", "GoldenDict Pro", false, "mobi.goldendict.android", "send" }, - { "Kiwix", "Kiwix", false, "org.kiwix.kiwixmobile", "text" }, - { "Mdict", "Mdict", false, "cn.mdict", "send" }, - { "QuickDic", "QuickDic", false, "de.reimardoeffinger.quickdic", "quickdic" }, - } -end diff --git a/frontend/device/sdl/device.lua b/frontend/device/sdl/device.lua index 6a1fa6f7a..dd45ffc41 100644 --- a/frontend/device/sdl/device.lua +++ b/frontend/device/sdl/device.lua @@ -20,6 +20,17 @@ local function runCommand(command) return os.execute(env..command) == 0 end +local function getDesktopDicts() + local t = { + { "Goldendict", "Goldendict", false, "goldendict" }, + } + -- apple dict is always present in osx + if jit.os == "OSX" then + table.insert(t, 1, { "Apple", "AppleDict", false, "dict://" }) + end + return t +end + local function getLinkOpener() if jit.os == "Linux" and isCommand("xdg-open") then return true, "xdg-open" @@ -29,25 +40,16 @@ local function getLinkOpener() return false end -local EXTERNAL_DICTS_AVAILABILITY_CHECKED = false -local EXTERNAL_DICTS = require("device/sdl/dictionaries") -local external_dict_when_back_callback = nil - -local function getExternalDicts() - if not EXTERNAL_DICTS_AVAILABILITY_CHECKED then - EXTERNAL_DICTS_AVAILABILITY_CHECKED = true - for i, v in ipairs(EXTERNAL_DICTS) do - local tool = v[4] - if tool then - if (isUrl(tool) and getLinkOpener()) or isCommand(tool) then - v[3] = true - end - end +-- thirdparty app support +local external = require("device/thirdparty"):new{ + dicts = getDesktopDicts(), + check = function(self, app) + if (isUrl(app) and getLinkOpener()) or isCommand(app) then + return true end - end - return EXTERNAL_DICTS -end - + return false + end, +} local Device = Generic:new{ model = "SDL", @@ -70,24 +72,20 @@ local Device = Generic:new{ return runCommand(tool .. " '" .. link .. "'") end, canExternalDictLookup = yes, - getExternalDictLookupList = getExternalDicts, + getExternalDictLookupList = function() return external.dicts end, doExternalDictLookup = function(self, text, method, callback) - external_dict_when_back_callback = callback - local tool, ok = nil - for i, v in ipairs(getExternalDicts()) do - if v[1] == method then - tool = v[4] - break + external.when_back_callback = callback + local ok, app = external:checkMethod("dict", method) + if app then + if isUrl(app) and getLinkOpener() then + ok = self:openLink(app..text) + elseif isCommand(app) then + ok = runCommand(app .. " " .. text .. " &") end end - if isUrl(tool) and getLinkOpener() then - ok = self:openLink(tool..text) - elseif isCommand(tool) then - ok = runCommand(tool .. " " .. text .. " &") - end - if ok and external_dict_when_back_callback then - external_dict_when_back_callback() - external_dict_when_back_callback = nil + if ok and external.when_back_callback then + external.when_back_callback() + external.when_back_callback = nil end end, window = G_reader_settings:readSetting("sdl_window") or {}, diff --git a/frontend/device/sdl/dictionaries.lua b/frontend/device/sdl/dictionaries.lua deleted file mode 100644 index d240d6842..000000000 --- a/frontend/device/sdl/dictionaries.lua +++ /dev/null @@ -1,20 +0,0 @@ -local user_path = require("datastorage"):getDataDir() .. "/dictionaries.lua" -local ok, dicts = pcall(dofile, user_path) - -local t = {} - -table.insert(t, 1, { "Goldendict", "Goldendict", false, "goldendict" }) - -if jit.os == "OSX" then - table.insert(t, 1, { "Apple", "AppleDict", false, "dict://" }) -end - -if ok then - -- append user dictionaries to the bottom of the menu - for k, v in pairs(dicts) do - table.insert(t, #t + 1, v) - end -end - -return t - diff --git a/frontend/device/thirdparty.lua b/frontend/device/thirdparty.lua new file mode 100644 index 000000000..0736ed90c --- /dev/null +++ b/frontend/device/thirdparty.lua @@ -0,0 +1,73 @@ +-- module for integration with thirdparty applications +local logger = require("logger") + +local roles = { + "dict", + "translator", +} + +local M = {} + +function M:new(o) + -- platform specific function to check availability of apps at runtime. + if not o.check or type(o.check) ~= "function" then + o.check = function(app) return false end + end + setmetatable(o, self) + self.__index = self + + -- one-time availability check + for _, role in pairs(roles) do + -- user override, if available + local user_file = role == "dict" and "dictionaries.lua" or role .. "s.lua" + local user = require("datastorage"):getDataDir() .. "/" .. user_file + local ok, user_dicts = pcall(dofile, user) + if ok then + o[role.."s"] = user_dicts + o.is_user_list = true + else + local t = o[role.."s"] + for i, value in ipairs(t or {}) do + local app = value[4] + if o:check(app) then + value[3] = true + end + end + if t then + self[role.."s"] = t + end + end + end + logger.info(o:dump()) + return o +end + +function M:checkMethod(role, method) + local tool, action = nil + for i, v in ipairs(self[role.."s"] or {}) do + if v[1] == method then + tool = v[4] + action = v[5] + break + end + end + if not tool and not action then + return false + else + return true, tool, action + end +end + +function M:dump() + local str = (self.is_user_list and "user" or "platform") .. " thirdparty apps\n" + for i, role in ipairs(roles) do + local apps = self[role.."s"] + for index, _ in ipairs(apps or {}) do + str = str .. string.format("-> %s (%s), role: %s, available: %s\n", + apps[index][1], apps[index][4], role, tostring(apps[index][3])) + end + end + return str +end + +return M