mirror of https://github.com/koreader/koreader
commit
63b6d25f72
@ -0,0 +1,63 @@
|
|||||||
|
local ReaderDictionary = require("apps/reader/modules/readerdictionary")
|
||||||
|
local EventListener = require("ui/widget/eventlistener")
|
||||||
|
local NetworkMgr = require("ui/networkmgr")
|
||||||
|
local Translator = require("ui/translator")
|
||||||
|
local Wikipedia = require("ui/wikipedia")
|
||||||
|
local UIManager = require("ui/uimanager")
|
||||||
|
local Geom = require("ui/geometry")
|
||||||
|
local Screen = require("ui/screen")
|
||||||
|
local JSON = require("JSON")
|
||||||
|
local DEBUG = require("dbg")
|
||||||
|
local _ = require("gettext")
|
||||||
|
|
||||||
|
-- Wikipedia as a special dictionary
|
||||||
|
local ReaderWikipedia = ReaderDictionary:new{
|
||||||
|
-- identify itself
|
||||||
|
wiki = true,
|
||||||
|
no_page = _("No wiki page found."),
|
||||||
|
}
|
||||||
|
|
||||||
|
function ReaderWikipedia:onLookupWikipedia(word, box)
|
||||||
|
-- detect language of the text
|
||||||
|
local ok, lang = pcall(Translator.detect, Translator, word)
|
||||||
|
-- prompt users to turn on Wifi if network is unreachable
|
||||||
|
if not ok and lang and lang:find("Network is unreachable") then
|
||||||
|
NetworkMgr:promptWifiOn()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- convert "zh-CN" and "zh-TW" to "zh"
|
||||||
|
lang = lang:match("(.*)-") or lang
|
||||||
|
-- strip punctuation characters around selected word
|
||||||
|
word = string.gsub(word, "^%p+", '')
|
||||||
|
word = string.gsub(word, "%p+$", '')
|
||||||
|
-- seems lower case phrase has higher hit rate
|
||||||
|
word = string.lower(word)
|
||||||
|
local results = {}
|
||||||
|
local ok, pages = pcall(Wikipedia.wikintro, Wikipedia, word, lang)
|
||||||
|
if ok and pages then
|
||||||
|
for pageid, page in pairs(pages) do
|
||||||
|
local result = {
|
||||||
|
dict = _("Wikipedia"),
|
||||||
|
word = page.title,
|
||||||
|
definition = page.extract or self.no_page,
|
||||||
|
}
|
||||||
|
table.insert(results, result)
|
||||||
|
end
|
||||||
|
DEBUG("lookup result:", word, results)
|
||||||
|
self:showDict(word, results, box)
|
||||||
|
else
|
||||||
|
DEBUG("error:", pages)
|
||||||
|
-- dummy results
|
||||||
|
results = {
|
||||||
|
{
|
||||||
|
dict = _("Wikipedia"),
|
||||||
|
word = word,
|
||||||
|
definition = self.no_page,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG("dummy result table:", word, results)
|
||||||
|
self:showDict(word, results, box)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ReaderWikipedia
|
@ -0,0 +1,87 @@
|
|||||||
|
local socket = require('socket')
|
||||||
|
local url = require('socket.url')
|
||||||
|
local http = require('socket.http')
|
||||||
|
local https = require('ssl.https')
|
||||||
|
local ltn12 = require('ltn12')
|
||||||
|
local JSON = require("JSON")
|
||||||
|
local DEBUG = require("dbg")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
-- Translate text using Google Translate.
|
||||||
|
-- http://translate.google.com/translate_a/t?client=z&ie=UTF-8&oe=UTF-8&hl=en&tl=en&text=hello
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local Translator = {
|
||||||
|
trans_servers = {
|
||||||
|
"http://translate.google.cn",
|
||||||
|
"http://translate.google.com",
|
||||||
|
},
|
||||||
|
trans_path = "/translate_a/t",
|
||||||
|
trans_params = {
|
||||||
|
client = "z", -- client z returns normal JSON result
|
||||||
|
ie = "UTF-8",
|
||||||
|
oe = "UTF-8",
|
||||||
|
hl = "en",
|
||||||
|
tl = "en",
|
||||||
|
sl = nil, -- we don't specify source languagae to detect language
|
||||||
|
},
|
||||||
|
default_lang = "en",
|
||||||
|
}
|
||||||
|
|
||||||
|
function Translator:getTransServer()
|
||||||
|
return G_reader_settings:readSetting("trans_server") or self.trans_servers[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
-- return decoded JSON table from translate server
|
||||||
|
--]]
|
||||||
|
function Translator:loadPage(target_lang, source_lang, text)
|
||||||
|
local request, sink = {}, {}
|
||||||
|
local query = ""
|
||||||
|
self.trans_params.tl = target_lang
|
||||||
|
self.trans_params.sl = source_lang
|
||||||
|
for k,v in pairs(self.trans_params) do
|
||||||
|
query = query .. k .. '=' .. v .. '&'
|
||||||
|
end
|
||||||
|
local parsed = url.parse(self:getTransServer())
|
||||||
|
parsed.path = self.trans_path
|
||||||
|
parsed.query = query .. "text=" .. url.escape(text)
|
||||||
|
|
||||||
|
-- HTTP request
|
||||||
|
request['url'] = url.build(parsed)
|
||||||
|
request['method'] = 'GET'
|
||||||
|
request['sink'] = ltn12.sink.table(sink)
|
||||||
|
DEBUG("request", request)
|
||||||
|
http.TIMEOUT, https.TIMEOUT = 10, 10
|
||||||
|
local httpRequest = parsed.scheme == 'http' and http.request or https.request
|
||||||
|
local code, headers, status = socket.skip(1, httpRequest(request))
|
||||||
|
|
||||||
|
-- raise error message when network is unavailable
|
||||||
|
if headers == nil then
|
||||||
|
error("Network is unreachable")
|
||||||
|
end
|
||||||
|
|
||||||
|
local content = table.concat(sink)
|
||||||
|
if content ~= "" then
|
||||||
|
local ok, result = pcall(JSON.decode, JSON, content)
|
||||||
|
if ok and result then
|
||||||
|
--DEBUG("translate result", result)
|
||||||
|
return result
|
||||||
|
else
|
||||||
|
DEBUG("error:", result)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Translator:detect(text)
|
||||||
|
local result = self:loadPage("en", nil, text)
|
||||||
|
if result then
|
||||||
|
local src_lang = result.src
|
||||||
|
DEBUG("detected language:", src_lang)
|
||||||
|
return src_lang
|
||||||
|
else
|
||||||
|
return self.default_lang
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Translator
|
@ -0,0 +1,84 @@
|
|||||||
|
local socket = require('socket')
|
||||||
|
local url = require('socket.url')
|
||||||
|
local http = require('socket.http')
|
||||||
|
local https = require('ssl.https')
|
||||||
|
local ltn12 = require('ltn12')
|
||||||
|
local JSON = require("JSON")
|
||||||
|
local DEBUG = require("dbg")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
-- Query wikipedia using Wikimedia Web API.
|
||||||
|
-- http://en.wikipedia.org/w/api.php?action=query&prop=extracts&format=json&exintro=&explaintext=&redirects=&titles=hello
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local Wikipedia = {
|
||||||
|
wiki_server = "http://%s.wikipedia.org",
|
||||||
|
wiki_path = "/w/api.php",
|
||||||
|
wiki_params = {
|
||||||
|
action = "query",
|
||||||
|
prop = "extracts",
|
||||||
|
format = "json",
|
||||||
|
exintro = "",
|
||||||
|
explaintext = "",
|
||||||
|
redirects = "",
|
||||||
|
},
|
||||||
|
default_lang = "en",
|
||||||
|
}
|
||||||
|
|
||||||
|
function Wikipedia:getWikiServer(lang)
|
||||||
|
return string.format(self.wiki_server, lang or self.default_lang)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
-- return decoded JSON table from Wikipedia
|
||||||
|
--]]
|
||||||
|
function Wikipedia:loadPage(text, lang, intro, plain)
|
||||||
|
local request, sink = {}, {}
|
||||||
|
local query = ""
|
||||||
|
self.wiki_params.exintro = intro and "" or nil
|
||||||
|
self.wiki_params.explaintext = plain and "" or nil
|
||||||
|
for k,v in pairs(self.wiki_params) do
|
||||||
|
query = query .. k .. '=' .. v .. '&'
|
||||||
|
end
|
||||||
|
local parsed = url.parse(self:getWikiServer(lang))
|
||||||
|
parsed.path = self.wiki_path
|
||||||
|
parsed.query = query .. "titles=" .. url.escape(text)
|
||||||
|
|
||||||
|
-- HTTP request
|
||||||
|
request['url'] = url.build(parsed)
|
||||||
|
request['method'] = 'GET'
|
||||||
|
request['sink'] = ltn12.sink.table(sink)
|
||||||
|
DEBUG("request", request)
|
||||||
|
http.TIMEOUT, https.TIMEOUT = 10, 10
|
||||||
|
local httpRequest = parsed.scheme == 'http' and http.request or https.request
|
||||||
|
local code, headers, status = socket.skip(1, httpRequest(request))
|
||||||
|
|
||||||
|
-- raise error message when network is unavailable
|
||||||
|
if headers == nil then
|
||||||
|
error("Network is unreachable")
|
||||||
|
end
|
||||||
|
|
||||||
|
local content = table.concat(sink)
|
||||||
|
if content ~= "" then
|
||||||
|
local ok, result = pcall(JSON.decode, JSON, content)
|
||||||
|
if ok and result then
|
||||||
|
DEBUG("wiki result", result)
|
||||||
|
return result
|
||||||
|
else
|
||||||
|
DEBUG("error:", result)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- extract intro passage in wiki page
|
||||||
|
function Wikipedia:wikintro(text, lang)
|
||||||
|
local result = self:loadPage(text, lang, true, true)
|
||||||
|
if result then
|
||||||
|
local query = result.query
|
||||||
|
if query then
|
||||||
|
return query.pages
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Wikipedia
|
@ -1 +1 @@
|
|||||||
Subproject commit 48e46a9b01eb31888cb818b3f402045025f05069
|
Subproject commit 1075c61f74888d0ab291c8a3d0ed55d9dde8457b
|
Loading…
Reference in New Issue