Fix ui bug; Suport Multiple language for Service;

This commit is contained in:
St.Huang 2018-07-06 20:56:20 +08:00
parent 4aee5365ba
commit f95f8e9f6e
10 changed files with 145 additions and 119 deletions

View File

@ -51,7 +51,7 @@ class Config(object):
data['%s_last' % self.pmname] = data.get('last_model', self.last_model_id) data['%s_last' % self.pmname] = data.get('last_model', self.last_model_id)
self.data.update(data) self.data.update(data)
with open(self.path, 'wb') as f: with open(self.path, 'wb') as f:
json.dump(self.data, f) json.dump(self.data, f, indent=4, sort_keys=True)
f.close() f.close()
def read(self): def read(self):

View File

@ -18,46 +18,64 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from anki.lang import currentLang from anki.lang import currentLang
trans = {
'CHECK_FILENAME_LABEL': {'zh_CN': u'使用文件名作为标签', 'en': u'Use filename as dict label', 'fr': r"Utiliser le nom de fichier en tant qu'étiquette de dico"},
'EXPORT_MEDIA': {'zh_CN': u'导出媒体文件', 'en': u'Export media files', 'fr': u'Exporter les fichiers multimédias'},
'DICTS_FOLDERS': {'zh_CN': u'字典文件夹', 'en': u'Dict folders', 'fr': u'Dossiers dico'},
'CHOOSE_NOTE_TYPES': {'zh_CN': u'选择笔记类型', 'en': u'Choose note types', 'fr': u'Choisir le type de note '},
'CURRENT_NOTE_TYPE': {'zh_CN': u'当前类型', 'en': u'Current type', 'fr': u'Type utilisé en cours'},
'MDX_SERVER': {'zh_CN': u'MDX服务器', 'en': u'MDX server', 'fr': u'serveur MDX'},
'USE_DICTIONARY': {'zh_CN': u'使用字典', 'en': u'Use dict', 'fr': u'Utilisé un dico'},
'UPDATED': {'zh_CN': u'更新', 'en': u'Updated', 'fr': u'Mettre à jour'},
'CARDS': {'zh_CN': u'卡片', 'en': u'Cards', 'fr': u'Cartes'},
'FAILURE': {'zh_CN': u'失败', 'en': u'Failure', 'fr': u'Échec'},
'SUCCESS': {'zh_CN': u'成功', 'en': u'Success', 'fr': u'Succès'},
'QUERIED': {'zh_CN': u'查询', 'en': u'Queried', 'fr': u'Quêté'},
'FIELDS': {'zh_CN': u'字段', 'en': u'Fields', 'fr': u'Champs'},
'WORDS': {'zh_CN': u'单词', 'en': u'Words', 'fr': u'Mots'},
'NOT_DICT_FIELD': {'zh_CN': u'不是字典字段', 'en': u'Not dict field', 'fr': u'Pas un champ de dico'},
'NOTE_TYPE_FIELDS': {'zh_CN': u'<b>笔记字段</b>', 'en': u'<b>Note fields</b>', 'fr': u'<b>Champ de note</b>'},
'DICTS': {'zh_CN': u'<b>字典</b>', 'en': u'<b>Dict</b>', 'fr': u'<b>Dico</b>'},
'DICT_FIELDS': {'zh_CN': u'<b>字典字段</b>', 'en': u'<b>Dict fields</b>', 'fr': u'<b>Champ de dico</b>'},
'RADIOS_DESC': {'zh_CN': u'<b>单选框选中为待查询单词字段</b>', 'en': u'<b>Word field needs to be selected.</b>', 'fr': u'<b>Champ de mot doit d\'être sélectionné. </b>'},
'NO_QUERY_WORD': {'zh_CN': u'查询字段无单词', 'en': u'No word is found in the query field', 'fr': u'Aucun est trouvé dans le champ'},
'CSS_NOT_FOUND': {'zh_CN': u'没有找到CSS文件请手动选择', 'en': u'No valid css stylesheets found, please choose the file', 'fr': u'Aucun fichier de style CSS est valide, veuillez choisir le fichier'},
'ABOUT': {'zh_CN': u'关于', 'en': u'About', 'fr': u'À propos'},
'REPOSITORY': {'zh_CN': u'项目地址', 'en': u'Project homepage', 'fr': u'Accueil du projet'},
'FEEDBACK': {'zh_CN': u'反馈', 'en': u'Feedback', 'fr': u'Retourner de l\'information'},
'VERSION': {'zh_CN': u'版本', 'en': u'Version', 'fr': u'Version'},
'LATEST_VERSION': {'zh_CN': u'无更新版本.', 'en': u'No update version.', 'fr': u'Pas de mise à jour.'},
'ABNORMAL_VERSION': {'zh_CN': u'当前版本异常.', 'en': u'The current version is abnormal.', 'fr': u'La version actuelle est anormale.'},
'CHECK_FAILURE': {'zh_CN': u'版本检查失败.', 'en': u'Version check failure.', 'fr': u'Erreur de vérifier la version.'},
'NEW_VERSION': {'zh_CN': u'检查到新版本:', 'en': u'New version:', 'fr': u'Nouvelle version:'},
'UPDATE': {'zh_CN': u'更新', 'en': u'Update', 'fr': u'Mise à jour'},
'FORCE_UPDATE': {'zh_CN': u'强制更新字段', 'en': u'Force update'},
'SETTINGS': {'zh_CN': u'参数', 'en': u'Settings'},
'THREAD_NUMBER': {'zh_CN': u'线程数', 'en': u'Thread'},
}
__all__ = ['_', '_cl', '_sl']
#Language Define, [Key, zh_CN, en]
arr = [
['CHECK_FILENAME_LABEL', u'使用文件名作为标签', u'Use filename as dict label'],
['EXPORT_MEDIA', u'导出媒体文件', u'Export media files'],
['DICTS_FOLDERS', u'字典文件夹', u'Dict folders'],
['CHOOSE_NOTE_TYPES', u'选择笔记类型', u'Choose note types'],
['CURRENT_NOTE_TYPE', u'当前类型', u'Current type'],
['MDX_SERVER', u'MDX服务器', u'MDX server'],
['USE_DICTIONARY', u'使用字典', u'Use dict'],
['UPDATED', u'更新', u'Updated'],
['CARDS', u'卡片', u'Cards'],
['FAILURE', u'失败', u'Failure'],
['SUCCESS', u'成功', u'Success'],
['QUERIED', u'查询', u'Queried'],
['FIELDS', u'字段', u'Fields'],
['WORDS', u'单词', u'Words'],
['NOT_DICT_FIELD', u'忽略', u'Ignore'], #不是字典字段
['NOTE_TYPE_FIELDS', u'<b>笔记字段</b>', u'<b>Note fields</b>'],
['DICTS', u'<b>字典</b>', u'<b>Dict</b>'],
['DICT_FIELDS', u'<b>字典字段</b>', u'<b>Dict fields</b>'],
['RADIOS_DESC', u'<b>单选框选中为待查询单词字段</b>', u'<b>Word field needs to be selected.</b>'],
['NO_QUERY_WORD', u'查询字段无单词', u'No word is found in the query field'],
['CSS_NOT_FOUND', u'没有找到CSS文件请手动选择', u'No valid css stylesheets found, please choose the file'],
['ABOUT', u'关于', u'About'],
['REPOSITORY', u'项目地址', u'Project homepage'],
['FEEDBACK', u'反馈', u'Feedback'],
['VERSION', u'版本', u'Version'],
['LATEST_VERSION', u'已经是最新版本.', u'It\'s the lastest version.'],
['ABNORMAL_VERSION', u'当前版本异常.', u'The current version is abnormal.'],
['CHECK_FAILURE', u'版本检查失败.', u'Version check failure.'],
['NEW_VERSION', u'检查到新版本:', u'New version:'],
['UPDATE', u'更新', u'Update'],
['FORCE_UPDATE', u'强制更新字段', u'Force update'],
['SETTINGS', u'参数', u'Settings'],
['THREAD_NUMBER', u'线程数', u'Thread'],
['BRE_PRON', u'英式发音', u'British Pronunciation'],
['AME_PRON', u'美式发音', u'American Pronunciation'],
['PRON', u'发音', u'Pronunciation'],
['EXAMPLE', u'例句', u'Example'],
['TRANS', u'翻译', u'Translation'],
['DEF', u'释义', u'Definition'],
['PHON', u'音标', u'Phonetic'],
['BRE_PHON', u'英式音标', u'British Phonetic'],
['AME_PHON', u'美式音标', u'American Phonetic'],
['IMAGE', u'图片', u'Image'],
]
trans = {item[0]: {'zh_CN': item[1], 'en': item[2]} for item in arr}
def _(key, lang=currentLang): def _(key, lang=currentLang):
if lang != 'zh_CN' and lang != 'en' and lang != 'fr': if lang != 'zh_CN' and lang != 'en':
lang = 'en' # fallback lang = 'en'
def disp(s): def disp(s):
return s.lower().capitalize() return s.lower().capitalize()
@ -67,5 +85,13 @@ def _(key, lang=currentLang):
return trans[key][lang] return trans[key][lang]
def _cl(labels, lang=currentLang):
if isinstance(labels, basestring):
return _(labels)
if lang != 'zh_CN' and lang != 'en':
lang = 'en'
return labels[0] if lang == 'zh_CN' else labels[1]
def _sl(key): def _sl(key):
return trans[key].values() return trans[key].values()

View File

@ -52,12 +52,12 @@ class ProgressWindow(object):
self._msg_count['fails_number'] self._msg_count['fails_number']
) )
if words_number or fields_number: if words_number or fields_number:
number_info += _('QUERIED') + '<br>' + 45 * '-' number_info += _('QUERIED') + u'<br>' + 45 * u'-'
number_info += u'<br>{0}: {1}{2}'.format( number_info += u'<br>{0}: {1} {2}'.format(
_('SUCCESS'), words_number, _('WORDS')) _('SUCCESS'), words_number, _('WORDS'))
number_info += u'<br>{0}: {1}{2}'.format( number_info += u'<br>{0}: {1} {2}'.format(
_('UPDATE'), fields_number, _('FIELDS')) _('UPDATE'), fields_number, _('FIELDS'))
number_info += u'<br>{0}: {1}{2}'.format( number_info += u'<br>{0}: {1} {2}'.format(
_('FAILURE'), fails_number, _('WORDS')) _('FAILURE'), fails_number, _('WORDS'))
self._update(label=number_info, value=words_number) self._update(label=number_info, value=words_number)

View File

@ -12,7 +12,7 @@ MAPPINGS = [
LANG_TO_REGEXPS = {lang: regexps for lang, regexps in MAPPINGS} LANG_TO_REGEXPS = {lang: regexps for lang, regexps in MAPPINGS}
@register(u'本地词典-LDOCE6') @register([u'本地词典-LDOCE6', u'MDX-LDOCE6'])
class Ldoce6(MdxService): class Ldoce6(MdxService):
def __init__(self): def __init__(self):
@ -26,7 +26,7 @@ class Ldoce6(MdxService):
def title(self): def title(self):
return self.__register_label__ return self.__register_label__
@export(u'音标', 1) @export('PHON', 1)
def fld_phonetic(self): def fld_phonetic(self):
html = self.get_html() html = self.get_html()
m = re.search(r'<span class="pron">(.*?)</span>', html) m = re.search(r'<span class="pron">(.*?)</span>', html)
@ -59,15 +59,15 @@ class Ldoce6(MdxService):
return self.get_anki_label(name, 'audio') return self.get_anki_label(name, 'audio')
return '' return ''
@export(u'英式发音', 2) @export('BRE_PRON', 2)
def fld_voicebre(self): def fld_voicebre(self):
return self._fld_voice(self.get_html(), 'br') return self._fld_voice(self.get_html(), 'br')
@export(u'美式发音', 3) @export('AME_PRON', 3)
def fld_voiceame(self): def fld_voiceame(self):
return self._fld_voice(self.get_html(), 'us') return self._fld_voice(self.get_html(), 'us')
@export(u'例句', 4) @export('EXAMPLE', 4)
def fld_sentence(self): def fld_sentence(self):
m = re.findall(r'<span class="example"\s*.*>\s*.*<\/span>', self.get_html()) m = re.findall(r'<span class="example"\s*.*>\s*.*<\/span>', self.get_html())
if m: if m:
@ -84,7 +84,7 @@ class Ldoce6(MdxService):
return self._css(my_str) return self._css(my_str)
return '' return ''
@export(u'释义', 5) @export('DEF', 5)
def fld_definate(self): def fld_definate(self):
m = m = re.findall(r'<span class="def"\s*.*>\s*.*<\/span>', self.get_html()) m = m = re.findall(r'<span class="def"\s*.*>\s*.*<\/span>', self.get_html())
if m: if m:

View File

@ -1,24 +1,16 @@
#-*- coding:utf-8 -*- #-*- coding:utf-8 -*-
import json import json
import os import os
import re
import urllib
import urllib2
import xml.etree.ElementTree
from collections import defaultdict from collections import defaultdict
from aqt.utils import showInfo
from .base import WebService, export, register from .base import WebService, export, register
from ..utils import ignore_exception
bcz_download_mp3 = True
bcz_download_img = True
@register(u'百词斩') @register([u'百词斩', u'Baicizhan'])
class Baicizhan(WebService): class Baicizhan(WebService):
bcz_download_mp3 = True
bcz_download_img = True
def __init__(self): def __init__(self):
super(Baicizhan, self).__init__() super(Baicizhan, self).__init__()
@ -26,18 +18,17 @@ class Baicizhan(WebService):
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)
try: try:
html = 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)) return self.cache_this(json.loads(html))
except: except:
return defaultdict(str) return defaultdict(str)
# @ignore_exception @export('PRON', 0)
@export(u'发音', 0)
def fld_phonetic(self): def fld_phonetic(self):
word = self.word.replace(' ', '_') word = self.word.replace(' ', '_')
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 bcz_download_mp3: if self.bcz_download_mp3:
if self.download(url, audio_name): if self.download(url, audio_name):
# urllib.urlretrieve(url, audio_name) # urllib.urlretrieve(url, audio_name)
with open(audio_name, 'rb') as f: with open(audio_name, 'rb') as f:
@ -56,43 +47,43 @@ class Baicizhan(WebService):
def _get_field(self, key, default=u''): def _get_field(self, key, default=u''):
return self.cache_result(key) if self.cached(key) else self._get_from_api().get(key, default) return self.cache_result(key) if self.cached(key) else self._get_from_api().get(key, default)
@export(u'音标', 1) @export('PHON', 1)
def fld_explains(self): def fld_explains(self):
return self._get_field('accent') return self._get_field('accent')
@export(u'图片', 2) @export('IMAGE', 2)
def fld_img(self): def fld_img(self):
url = self._get_field('img') url = self._get_field('img')
if url and 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 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 ''
@export(u'象形', 3) @export([u'象形', u'Pictogram'], 3)
def fld_df(self): def fld_df(self):
url = self._get_field('df') url = self._get_field('df')
if url and 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 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 ''
@export(u'中文释义', 6) @export(u'DEF', 6)
def fld_mean(self): def fld_mean(self):
return self._get_field('mean_cn') return self._get_field('mean_cn')
@export(u'英文例句', 4) @export(u'EXAMPLE', 4)
def fld_st(self): def fld_st(self):
return self._get_field('st') return self._get_field('st')
@export(u'例句翻译', 5) @export('TRANS', 5)
def fld_sttr(self): def fld_sttr(self):
return self._get_field('sttr') return self._get_field('sttr')
@export(u'单词tv', 7) @export([u'单词tv', u'TV'], 7)
def fld_tv_url(self): def fld_tv_url(self):
video = self._get_field('tv') video = self._get_field('tv')
if video: if video:

View File

@ -38,6 +38,7 @@ from ..context import config
from ..libs import MdxBuilder, StardictBuilder from ..libs import MdxBuilder, StardictBuilder
from ..utils import MapDict, wrap_css from ..utils import MapDict, wrap_css
from ..libs.bs4 import BeautifulSoup from ..libs.bs4 import BeautifulSoup
from ..lang import _cl
try: try:
import threading as _threading import threading as _threading
@ -45,22 +46,26 @@ except ImportError:
import dummy_threading as _threading import dummy_threading as _threading
def register(label): def register(labels):
"""register the dict service with a label, which will be shown in the dicts list.""" """
register the dict service with a labels, which will be shown in the dicts list.
"""
def _deco(cls): def _deco(cls):
cls.__register_label__ = label cls.__register_label__ = _cl(labels)
return cls return cls
return _deco return _deco
def export(label, index): def export(labels, index):
"""export dict field function with a label, which will be shown in the fields list.""" """
export dict field function with a labels, which will be shown in the fields list.
"""
def _with(fld_func): def _with(fld_func):
@wraps(fld_func) @wraps(fld_func)
def _deco(cls, *args, **kwargs): def _deco(cls, *args, **kwargs):
res = fld_func(cls, *args, **kwargs) res = fld_func(cls, *args, **kwargs)
return QueryResult(result=res) if not isinstance(res, QueryResult) else res return QueryResult(result=res) if not isinstance(res, QueryResult) else res
_deco.__export_attrs__ = (label, index) _deco.__export_attrs__ = (_cl(labels), index)
return _deco return _deco
return _with return _with
@ -123,12 +128,12 @@ def with_styles(**styles):
return _deco return _deco
return _with return _with
# BS4资源锁防止程序卡死 # bs4 threading lock, overload protection
BS_LOCKS = [_threading.Lock(), _threading.Lock()] BS_LOCKS = [_threading.Lock(), _threading.Lock()]
def parseHtml(html): def parseHtml(html):
''' '''
使用BS4解析html use bs4 lib parse HTML, run only 2 BS at the same time
''' '''
lock = BS_LOCKS[random.randrange(0, len(BS_LOCKS) - 1, 1)] lock = BS_LOCKS[random.randrange(0, len(BS_LOCKS) - 1, 1)]
lock.acquire() lock.acquire()
@ -138,7 +143,9 @@ def parseHtml(html):
class Service(object): class Service(object):
'''service base class''' '''
Dictionary Service Abstract Class
'''
def __init__(self): def __init__(self):
self.cache = defaultdict(defaultdict) self.cache = defaultdict(defaultdict)
@ -207,7 +214,9 @@ class Service(object):
class WebService(Service): class WebService(Service):
'''web service class''' """
Web Dictionary Service
"""
def __init__(self): def __init__(self):
super(WebService, self).__init__() super(WebService, self).__init__()
@ -250,7 +259,7 @@ class WebService(Service):
class LocalService(Service): class LocalService(Service):
""" """
本地词典 Local Dictionary Service
""" """
def __init__(self, dict_path): def __init__(self, dict_path):
@ -275,12 +284,12 @@ class LocalService(Service):
def _filename(self): def _filename(self):
return os.path.splitext(os.path.basename(self.dict_path))[0] return os.path.splitext(os.path.basename(self.dict_path))[0]
# mdx字典实例集 # MdxBuilder instances map
mdx_builders = defaultdict(dict) mdx_builders = defaultdict(dict)
class MdxService(LocalService): class MdxService(LocalService):
""" """
Mdx本地词典 MDX Local Dictionary Service
""" """
def __init__(self, dict_path): def __init__(self, dict_path):
@ -304,14 +313,14 @@ class MdxService(LocalService):
else: else:
return self.builder['_title'] return self.builder['_title']
@export(u"default", 0) @export([u'默认', u'Default'], 0)
def fld_whole(self): def fld_whole(self):
html = self.get_html() html = self.get_html()
js = re.findall(r'<script.*?>.*?</script>', html, re.DOTALL) js = re.findall(r'<script.*?>.*?</script>', html, re.DOTALL)
return QueryResult(result=html, js=u'\n'.join(js)) return QueryResult(result=html, js=u'\n'.join(js))
def _get_definition_mdx(self): def _get_definition_mdx(self):
"""根据关键字得到MDX词典的解释""" """according to the word return mdx dictionary page"""
content = self.builder.mdx_lookup(self.word) content = self.builder.mdx_lookup(self.word)
str_content = "" str_content = ""
if len(content) > 0: if len(content) > 0:
@ -321,7 +330,7 @@ class MdxService(LocalService):
return str_content return str_content
def _get_definition_mdd(self, word): def _get_definition_mdd(self, word):
"""根据关键字得到MDX词典的媒体""" """according to the keyword(param word) return the media file contents"""
word = word.replace('/', '\\') word = word.replace('/', '\\')
content = self.builder.mdd_lookup(word) content = self.builder.mdd_lookup(word)
if len(content) > 0: if len(content) > 0:
@ -330,7 +339,7 @@ class MdxService(LocalService):
return [] return []
def get_html(self): def get_html(self):
"""取得self.word对应的html页面""" """get self.word's html page from MDX"""
if not self.html_cache[self.word]: if not self.html_cache[self.word]:
html = self._get_definition_mdx() html = self._get_definition_mdx()
if html: if html:
@ -338,7 +347,7 @@ class MdxService(LocalService):
return self.html_cache[self.word] return self.html_cache[self.word]
def save_file(self, filepath_in_mdx, savepath): def save_file(self, filepath_in_mdx, savepath):
"""从mmd中取出filepath_in_mdx媒体文件并保存到savepath""" """according to filepath_in_mdx to get media file and save it to savepath"""
try: try:
bytes_list = self._get_definition_mdd(filepath_in_mdx) bytes_list = self._get_definition_mdd(filepath_in_mdx)
if bytes_list: if bytes_list:
@ -372,7 +381,7 @@ class StardictService(LocalService):
else: else:
return self.builder.ifo.bookname.decode('utf-8') return self.builder.ifo.bookname.decode('utf-8')
@export(u"default", 0) @export([u'默认', u'Default'], 0)
def fld_whole(self): def fld_whole(self):
#self.builder.check_build() #self.builder.check_build()
try: try:

View File

@ -5,7 +5,7 @@ from aqt.utils import showInfo, showText
from .base import WebService, export, register, with_styles, parseHtml from .base import WebService, export, register, with_styles, parseHtml
@register(u'Bing') @register([u'必应', u'Bing'])
class Bing(WebService): class Bing(WebService):
def __init__(self): def __init__(self):
@ -40,15 +40,15 @@ class Bing(WebService):
def _get_field(self, key, default=u''): def _get_field(self, key, default=u''):
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default) return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
@export(u'美式音标', 1) @export('AME_PHON', 1)
def fld_phonetic_us(self): def fld_phonetic_us(self):
return self._get_field('phonitic_us') return self._get_field('phonitic_us')
@export(u'英式音标', 2) @export('BRE_PHON', 2)
def fld_phonetic_uk(self): def fld_phonetic_uk(self):
return self._get_field('phonitic_uk') return self._get_field('phonitic_uk')
@export(u'词语时态', 3) @export([u'词语时态', u'Participle'], 3)
def fld_participle(self): def fld_participle(self):
return self._get_field('participle') return self._get_field('participle')
@ -56,7 +56,7 @@ class Bing(WebService):
def _css(self, val): def _css(self, val):
return val return val
@export(u'释义', 4) @export('DEF', 4)
def fld_definition(self): def fld_definition(self):
val = self._get_field('def') val = self._get_field('def')
if val == None or val == '': if val == None or val == '':

View File

@ -1,9 +1,5 @@
#-*- coding:utf-8 -*- #-*- coding:utf-8 -*-
import json import json
import re
import urllib2
from aqt.utils import showInfo, showText
from .base import WebService, export, register, with_styles from .base import WebService, export, register, with_styles
bing_download_mp3 = True bing_download_mp3 = True
@ -21,13 +17,15 @@ class BingXtk(WebService):
'Accept-Language': 'en-US,zh-CN;q=0.8,zh;q=0.6,en;q=0.4', 'Accept-Language': 'en-US,zh-CN;q=0.8,zh;q=0.6,en;q=0.4',
'User-Agent': 'WordQuery Addon (Anki)', 'User-Agent': 'WordQuery Addon (Anki)',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'} 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'}
word = self.word.replace(' ', '_')
url = u'http://xtk.azurewebsites.net/BingDictService.aspx?Word={}'.format(word.encode('utf-8'))
try: try:
word = self.word.replace(' ', '_') #request = urllib2.Request(u'http://xtk.azurewebsites.net/BingDictService.aspx?Word=' +\
request = urllib2.Request(u'http://xtk.azurewebsites.net/BingDictService.aspx?Word=' +\ # word.encode('utf-8'), headers=headers)
word.encode('utf-8'), headers=headers) #resp = json.loads(urllib2.urlopen(request).read())
resp = json.loads(urllib2.urlopen(request).read()) resp = json.loads(self.get_response(url, headers=headers, timeout=10))
return self.cache_this(resp) return self.cache_this(resp)
except Exception as e: except:
return resp return resp
def _get_field(self, key, default=u''): def _get_field(self, key, default=u''):
@ -41,17 +39,17 @@ class BingXtk(WebService):
subfield = default subfield = default
return subfield return subfield
@export(u'美式音标', 1) @export('AME_PHON', 1)
def fld_phonetic_us(self): def fld_phonetic_us(self):
seg = self._get_field('pronunciation') seg = self._get_field('pronunciation')
return self._get_subfield(seg, 'AmE') return self._get_subfield(seg, 'AmE')
@export(u'英式音标', 2) @export('BRE_PHON', 2)
def fld_phonetic_uk(self): def fld_phonetic_uk(self):
seg = self._get_field('pronunciation') seg = self._get_field('pronunciation')
return self._get_subfield(seg, 'BrE') return self._get_subfield(seg, 'BrE')
@export(u'美式发音', 3) @export('AME_PRON', 3)
def fld_mp3_us(self): def fld_mp3_us(self):
seg = audio_url = self._get_field('pronunciation') seg = audio_url = self._get_field('pronunciation')
audio_url = self._get_subfield(seg, 'AmEmp3') audio_url = self._get_subfield(seg, 'AmEmp3')
@ -61,7 +59,7 @@ class BingXtk(WebService):
return self.get_anki_label(filename, 'audio') return self.get_anki_label(filename, 'audio')
return audio_url return audio_url
@export(u'英式发音', 4) @export('BRE_PRON', 4)
def fld_mp3_uk(self): def fld_mp3_uk(self):
seg = self._get_field('pronunciation') seg = self._get_field('pronunciation')
audio_url = self._get_subfield(seg, 'BrEmp3') audio_url = self._get_subfield(seg, 'BrEmp3')
@ -75,15 +73,16 @@ class BingXtk(WebService):
def _css(self, val): def _css(self, val):
return val return val
@export(u'释义', 5) @export('DEF', 5)
def fld_definition(self): def fld_definition(self):
segs = self._get_field('defs') segs = self._get_field('defs')
if isinstance(segs, list) and len(segs) > 0: if isinstance(segs, list) and len(segs) > 0:
val = u'<br>'.join([u'<span class="pos"><b>{0}</b> </span><span class="def"><span>{1}</span></span>'.format(seg['pos'], seg['def']) for seg in segs]) val = u'<br>'.join([u'''<span class="pos"><b>{0}</b></span>
<span class="def">{1}</span>'''.format(seg['pos'], seg['def']) for seg in segs])
return self._css(val) return self._css(val)
return '' return ''
@export(u'例句', 6) @export('EXAMPLE', 6)
# @with_styles(cssfile='_bing2.css', need_wrap_css=True, wrap_class=u'bing') # @with_styles(cssfile='_bing2.css', need_wrap_css=True, wrap_class=u'bing')
def fld_samples(self): def fld_samples(self):
max_numbers = 10 max_numbers = 10
@ -92,11 +91,9 @@ class BingXtk(WebService):
for i, seg in enumerate(segs): for i, seg in enumerate(segs):
sentences = sentences +\ sentences = sentences +\
u"""<li><div class="se_li1"> u"""<li><div class="se_li1">
<div class="se_li1">
<div class="sen_en">{0}</div> <div class="sen_en">{0}</div>
<div class="sen_cn">{1}</div> <div class="sen_cn">{1}</div>
</div> </div></li>""".format(seg['eng'], seg['chn'])#, i + 1)
</div></li>""".format(seg['eng'], seg['chn'], i + 1)
if i == 9: if i == 9:
break break
return u"""<div class="se_div"> return u"""<div class="se_div">

View File

@ -39,6 +39,8 @@ class ServicePool(object):
return self.manager.get_service(unique) return self.manager.get_service(unique)
def put(self, service): def put(self, service):
if service is None:
return
unique = service.unique unique = service.unique
queue = self.pools.get(unique, None) queue = self.pools.get(unique, None)
if queue == None: if queue == None:

View File

@ -309,6 +309,7 @@ class OptionsDialog(QDialog):
self.setLayout(self.main_layout) self.setLayout(self.main_layout)
self.resize(widget_size.dialog_width, self.resize(widget_size.dialog_width,
(i + 1) * widget_size.map_max_height + widget_size.dialog_height_margin) (i + 1) * widget_size.map_max_height + widget_size.dialog_height_margin)
self.save()
def show_models(self): def show_models(self):
edit = QPushButton(anki.lang._("Manage"), edit = QPushButton(anki.lang._("Manage"),
@ -384,13 +385,13 @@ class OptionsDialog(QDialog):
unique = dict_combo_itemdata unique = dict_combo_itemdata
service = service_pool.get(unique) service = service_pool.get(unique)
# problem # problem
field_combo.setEditText(u'')
if service and service.support and service.fields: if service and service.support and service.fields:
for each in service.fields: for each in service.fields:
field_combo.addItem(each) field_combo.addItem(each)
if each == field_text: if each == field_text:
field_combo.setEditText(field_text) field_combo.setEditText(field_text)
field_combo.setEnabled(service != None and service.support)
field_combo.setEnabled(service.support)
service_pool.put(service) service_pool.put(service)
def radio_btn_checked(self): def radio_btn_checked(self):