In order to make startSdcv usable for plugins that might need to do
dictionary lookups in order to work, it is necessary to split out the
core of startSdcv into another method which returns the raw data from
sdcv.
In addition, in order to make it possible to amortise the cost of each
lookup (which could be fairly expensive) make it possible to pass
multiple words to rawSdcv at the same time. Sdcv supports passing
multiple words as arguments (which it then looks up in order and returns
a separate JSON array per line for each word) so we just need to tweak
the return style accordingly.
All of the deduplication and dummy results handling remains in startSdcv
because plugins might strongly depend on whether sdcv returned actual
results.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
-- Allow for two sdcv calls : one in the classic data/dict, and
-- another one in data/dict_ext if it exists
-- We could put in data/dict_ext dictionaries with a great number of words
@ -725,14 +724,7 @@ function ReaderDictionary:startSdcv(word, dict_names, fuzzy_search)
end
-- early exit if no dictionaries
ifdictDirsEmpty(dict_dirs)then
final_results={
{
dict="",
word=word,
definition=_([[No dictionaries installed. Please search for "Dictionary support" in the KOReader Wiki to get more information about installing new dictionaries.]]),
}
}
returnfinal_results
returnfalse,nil
end
locallookup_cancelled=false
for_,dict_dirinipairs(dict_dirs)do
@ -751,7 +743,10 @@ function ReaderDictionary:startSdcv(word, dict_names, fuzzy_search)
end
end
table.insert(args,"--")-- prevent word starting with a "-" to be interpreted as a sdcv option
table.insert(args,word)
-- XXX: This requires <https://github.com/Dushistov/sdcv/pull/77> in
-- order to function properly (otherwise the first failure will
-- cause sdcv to exit).
util.arrayAppend(args,words)
localcmd=util.shell_escape(args)
-- cmd = "sleep 7 ; " .. cmd -- uncomment to simulate long lookup time
@ -773,30 +768,70 @@ function ReaderDictionary:startSdcv(word, dict_names, fuzzy_search)
-- definition found, sdcv will output some message on stderr, and
definition=_([[No dictionaries installed. Please search for "Dictionary support" in the KOReader Wiki to get more information about installing new dictionaries.]]),
}
}
else-- flatten any possible results
localflat_results={}
localseen_results={}
-- Flatten the array, removing any duplicates we may have gotten (sdcv
-- may do multiple queries, in fixed mode then in fuzzy mode, and the
-- LanguageSupport plugin may have returned multiple equivalent
-- results).
localh
for_,term_resultsinipairs(results)do
for_,rinipairs(term_results)do
h=r.dict..r.word..r.definition
ifseen_results[h]==nilthen
table.insert(flat_results,r)
seen_results[h]=true
end
else
logger.warn("JSON data cannot be decoded",results)
end
end
results=flat_results
end
if#final_results==0then
if#results ==0then-- no results found
-- dummy results
final_results={
results ={
{
dict=_("Not available"),
word=word,
@ -809,10 +844,9 @@ function ReaderDictionary:startSdcv(word, dict_names, fuzzy_search)
iflookup_cancelledthen
-- Also put this as a k/v into the results array: when using dict_ext,
-- we may get results from the 1st lookup, and have interrupted the 2nd.