improve baicizhan query speed.

This commit is contained in:
St.Huang 2018-07-09 14:12:54 +08:00
parent 9fa0ae6aba
commit 4b2ddcd69a
2 changed files with 50 additions and 31 deletions

View File

@ -17,11 +17,25 @@ class Baicizhan(WebService):
def _get_from_api(self): def _get_from_api(self):
word = self.word.replace(' ', '_') word = self.word.replace(' ', '_')
url = u"http://mall.baicizhan.com/ws/search?w={}".format(word) url = u"http://mall.baicizhan.com/ws/search?w={}".format(word)
result = {
"accent": u"",
"img": u"",
"mean_cn": u"",
"st": u"",
"sttr": u"",
"tv": u"",
"word": u"",
"df": u'',
}
try: try:
html = self.get_response(url, timeout=5)#urllib2.urlopen(url, timeout=5).read() html = self.get_response(url, timeout=5)#urllib2.urlopen(url, timeout=5).read()
return self.cache_this(json.loads(html)) result.update(json.loads(html))
except: except:
return defaultdict(str) pass
return self.cache_this(result)
def _get_field(self, key, default=u''):
return self.cache_result(key) if self.cached(key) else self._get_from_api().get(key, default)
@export('PRON', 0) @export('PRON', 0)
def fld_phonetic(self): def fld_phonetic(self):
@ -29,7 +43,7 @@ class Baicizhan(WebService):
url = u'http://baicizhan.qiniucdn.com/word_audios/{}.mp3'.format(word) url = u'http://baicizhan.qiniucdn.com/word_audios/{}.mp3'.format(word)
audio_name = 'bcz_%s.mp3' % self.word audio_name = 'bcz_%s.mp3' % self.word
if self.bcz_download_mp3: if self.bcz_download_mp3:
if self.download(url, audio_name): if os.path.exists(audio_name) or self.download(url, audio_name, 5):
# urllib.urlretrieve(url, audio_name) # urllib.urlretrieve(url, audio_name)
with open(audio_name, 'rb') as f: with open(audio_name, 'rb') as f:
if f.read().strip() == '{"error":"Document not found"}': if f.read().strip() == '{"error":"Document not found"}':
@ -44,11 +58,8 @@ class Baicizhan(WebService):
else: else:
return url return url
def _get_field(self, key, default=u''):
return self.cache_result(key) if self.cached(key) else self._get_from_api().get(key, default)
@export('PHON', 1) @export('PHON', 1)
def fld_explains(self): def fld_phon(self):
return self._get_field('accent') return self._get_field('accent')
@export('IMAGE', 2) @export('IMAGE', 2)
@ -56,7 +67,7 @@ class Baicizhan(WebService):
url = self._get_field('img') url = self._get_field('img')
if url and self.bcz_download_img: if url and self.bcz_download_img:
filename = url[url.rindex('/') + 1:] filename = url[url.rindex('/') + 1:]
if self.download(url, filename): if os.path.exists(filename) or self.download(url, filename):
return self.get_anki_label(filename, 'img') return self.get_anki_label(filename, 'img')
#return self.get_anki_label(url, 'img') #return self.get_anki_label(url, 'img')
return '' return ''
@ -66,7 +77,7 @@ class Baicizhan(WebService):
url = self._get_field('df') url = self._get_field('df')
if url and self.bcz_download_img: if url and self.bcz_download_img:
filename = url[url.rindex('/') + 1:] filename = url[url.rindex('/') + 1:]
if self.download(url, filename): if os.path.exists(filename) or self.download(url, filename):
return self.get_anki_label(filename, 'img') return self.get_anki_label(filename, 'img')
#return self.get_anki_label(url, 'img') #return self.get_anki_label(url, 'img')
return '' return ''

View File

@ -32,6 +32,7 @@ import zlib
import random import random
from collections import defaultdict from collections import defaultdict
from functools import wraps from functools import wraps
from hashlib import md5
import cookielib import cookielib
from aqt import mw from aqt import mw
@ -261,7 +262,9 @@ class WebService(Service):
return '' return ''
@classmethod @classmethod
def download(cls, url, filename): def download(cls, url, filename, timeout=15):
import socket
socket.setdefaulttimeout(timeout)
try: try:
return urllib.urlretrieve(url, filename) return urllib.urlretrieve(url, filename)
except Exception as e: except Exception as e:
@ -401,21 +404,19 @@ class WebService(Service):
response_output.write(payload) response_output.write(payload)
# MdxBuilder instances map class _DictBuildWorker(QThread):
mdx_builders = defaultdict(dict)
mutex_builder = QMutex()
class DictBuilder(QThread):
"""Local Dictionary Builder""" """Local Dictionary Builder"""
def __init__(self, func): def __init__(self, func):
super(DictBuilder, self).__init__() super(_DictBuildWorker, self).__init__()
self.index = 0 self._builder = None
self.exit = False self._func = func
self.builder = None
self.func = func
def run(self): def run(self):
self.builder = self.func() self._builder = self._func()
@property
def builder(self):
return self._builder
class LocalService(Service): class LocalService(Service):
@ -428,18 +429,25 @@ class LocalService(Service):
self.dict_path = dict_path self.dict_path = dict_path
self.builder = None self.builder = None
self.missed_css = set() self.missed_css = set()
def get_builer(self, key, func): # MdxBuilder instances map
mutex_builder.lock() _mdx_builders = defaultdict(dict)
if not mdx_builders.has_key(key) or not mdx_builders[key]: _mutex_builder = QMutex()
worker = DictBuilder(func)
@staticmethod
def _get_builer(key, func=None):
LocalService._mutex_builder.lock()
key = md5(key).hexdigest()
if not func is None:
if not LocalService._mdx_builders.has_key(key) or not LocalService._mdx_builders[key]:
worker = _DictBuildWorker(func)
worker.start() worker.start()
while not worker.isFinished(): while not worker.isFinished():
mw.app.processEvents() mw.app.processEvents()
worker.wait(100) worker.wait(100)
mdx_builders[key] = worker.builder LocalService._mdx_builders[key] = worker.builder
mutex_builder.unlock() LocalService._mutex_builder.unlock()
return mdx_builders[key] return LocalService._mdx_builders[key]
@property @property
def support(self): def support(self):
@ -471,7 +479,7 @@ class MdxService(LocalService):
self.query_interval = 0.01 self.query_interval = 0.01
self.styles = [] self.styles = []
if self.support: if self.support:
self.builder = self.get_builer(dict_path, service_wrap(MdxBuilder, dict_path)) self.builder = self._get_builer(dict_path, service_wrap(MdxBuilder, dict_path))
@staticmethod @staticmethod
def check(dict_path): def check(dict_path):
@ -640,7 +648,7 @@ class StardictService(LocalService):
super(StardictService, self).__init__(dict_path) super(StardictService, self).__init__(dict_path)
self.query_interval = 0.05 self.query_interval = 0.05
if self.support: if self.support:
self.builder = self.get_builer( self.builder = self._get_builer(
dict_path, dict_path,
service_wrap(StardictBuilder, dict_path, in_memory=False) service_wrap(StardictBuilder, dict_path, in_memory=False)
) )