Adapt to anki 2.1
This commit is contained in:
parent
0bf86b9885
commit
0e0cc52f0c
@ -33,6 +33,7 @@ import random
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
|
from hashlib import sha1
|
||||||
|
|
||||||
import cookielib
|
import cookielib
|
||||||
from aqt import mw
|
from aqt import mw
|
||||||
@ -50,11 +51,29 @@ except ImportError:
|
|||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'register', 'export', 'copy_static_file', 'with_styles', 'parse_html', 'service_wrap',
|
'register', 'export', 'copy_static_file', 'with_styles', 'parse_html', 'service_wrap', 'get_hex_name',
|
||||||
'Service', 'WebService', 'LocalService', 'MdxService', 'StardictService', 'QueryResult'
|
'Service', 'WebService', 'LocalService', 'MdxService', 'StardictService', 'QueryResult'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_hex_name(prefix, val, suffix):
|
||||||
|
''' get sha1 hax name '''
|
||||||
|
hex_digest = sha1(
|
||||||
|
val.encode('utf-8') if isinstance(val, unicode)
|
||||||
|
else val
|
||||||
|
).hexdigest().lower()
|
||||||
|
name = '.'.join([
|
||||||
|
'-'.join([
|
||||||
|
prefix, hex_digest[:8], hex_digest[8:16],
|
||||||
|
hex_digest[16:24], hex_digest[24:32], hex_digest[32:],
|
||||||
|
]),
|
||||||
|
suffix,
|
||||||
|
])
|
||||||
|
return name
|
||||||
|
|
||||||
|
def _is_method_or_func(object):
|
||||||
|
return inspect.isfunction(object) or inspect.ismethod(object)
|
||||||
|
|
||||||
def register(labels):
|
def register(labels):
|
||||||
"""
|
"""
|
||||||
register the dict service with a labels, which will be shown in the dicts list.
|
register the dict service with a labels, which will be shown in the dicts list.
|
||||||
@ -62,7 +81,7 @@ def register(labels):
|
|||||||
def _deco(cls):
|
def _deco(cls):
|
||||||
cls.__register_label__ = _cl(labels)
|
cls.__register_label__ = _cl(labels)
|
||||||
|
|
||||||
methods = inspect.getmembers(cls, predicate=inspect.ismethod)
|
methods = inspect.getmembers(cls, predicate=_is_method_or_func)
|
||||||
exports = []
|
exports = []
|
||||||
for method in methods:
|
for method in methods:
|
||||||
attrs = getattr(method[1], '__export_attrs__', None)
|
attrs = getattr(method[1], '__export_attrs__', None)
|
||||||
@ -198,10 +217,16 @@ class Service(object):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def cached(self, key):
|
def cached(self, key):
|
||||||
return (self.word in self.cache) and self.cache[self.word].has_key(key)
|
return (self.word in self.cache) and (key in self.cache[self.word])
|
||||||
|
|
||||||
def cache_result(self, key):
|
def cache_result(self, key):
|
||||||
return self.cache[self.word].get(key, u'')
|
return self.cache[self.word].get(key, u'')
|
||||||
|
|
||||||
|
def _get_from_api(self):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def _get_field(self, key, default=u''):
|
||||||
|
return self.cache_result(key) if self.cached(key) else self._get_from_api().get(key, default)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique(self):
|
def unique(self):
|
||||||
@ -210,6 +235,13 @@ class Service(object):
|
|||||||
@unique.setter
|
@unique.setter
|
||||||
def unique(self, value):
|
def unique(self, value):
|
||||||
self._unique = value
|
self._unique = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def quote_word(self):
|
||||||
|
return urllib2.quote(
|
||||||
|
self.word.encode('utf-8') if isinstance(self.word, unicode)
|
||||||
|
else self.word
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def support(self):
|
def support(self):
|
||||||
@ -269,8 +301,10 @@ class WebService(Service):
|
|||||||
return getattr(self, '__register_label__', self.unique)
|
return getattr(self, '__register_label__', self.unique)
|
||||||
|
|
||||||
def get_response(self, url, data=None, headers=None, timeout=10):
|
def get_response(self, url, data=None, headers=None, timeout=10):
|
||||||
default_headers = {'User-Agent': 'Anki WordQuery',
|
default_headers = {
|
||||||
'Accept-Encoding': 'gzip'}
|
'User-Agent': 'Mozilla/5.0',
|
||||||
|
'Accept-Encoding': 'gzip'
|
||||||
|
}
|
||||||
if headers:
|
if headers:
|
||||||
default_headers.update(headers)
|
default_headers.update(headers)
|
||||||
|
|
||||||
@ -282,7 +316,7 @@ class WebService(Service):
|
|||||||
data = zlib.decompress(data, 16 + zlib.MAX_WBITS)
|
data = zlib.decompress(data, 16 + zlib.MAX_WBITS)
|
||||||
return data
|
return data
|
||||||
except:
|
except:
|
||||||
return ''
|
return u''
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def download(cls, url, filename, timeout=15):
|
def download(cls, url, filename, timeout=15):
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
import re
|
import re
|
||||||
import FastWQ
|
import FastWQ
|
||||||
from ..base import MdxService, export, register, with_styles, parse_html
|
from ..base import *
|
||||||
|
|
||||||
PATH = FastWQ.LDOCE6_PATH
|
PATH = FastWQ.LDOCE6_PATH
|
||||||
|
|
||||||
@ -33,24 +33,11 @@ class Ldoce6(MdxService):
|
|||||||
|
|
||||||
def _fld_voice(self, html, voice):
|
def _fld_voice(self, html, voice):
|
||||||
"""获取发音字段"""
|
"""获取发音字段"""
|
||||||
from hashlib import sha1
|
|
||||||
for regexp in LANG_TO_REGEXPS[voice]:
|
for regexp in LANG_TO_REGEXPS[voice]:
|
||||||
match = regexp.search(html)
|
match = regexp.search(html)
|
||||||
if match:
|
if match:
|
||||||
val = '/' + match.group(1)
|
val = '/' + match.group(1)
|
||||||
hex_digest = sha1(
|
name = get_hex_name('mdx-'+self.unique.lower(), val, 'mp3')
|
||||||
val.encode('utf-8') if isinstance(val, unicode)
|
|
||||||
else val
|
|
||||||
).hexdigest().lower()
|
|
||||||
|
|
||||||
assert len(hex_digest) == 40, "unexpected output from hash library"
|
|
||||||
name = '.'.join([
|
|
||||||
'-'.join([
|
|
||||||
'mdx', self.unique.lower(), hex_digest[:8], hex_digest[8:16],
|
|
||||||
hex_digest[16:24], hex_digest[24:32], hex_digest[32:],
|
|
||||||
]),
|
|
||||||
'mp3',
|
|
||||||
])
|
|
||||||
name = self.save_file(val, name)
|
name = self.save_file(val, name)
|
||||||
if name:
|
if name:
|
||||||
return self.get_anki_label(name, 'audio')
|
return self.get_anki_label(name, 'audio')
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from ..base import WebService, export, register
|
from ..base import *
|
||||||
|
|
||||||
|
|
||||||
@register([u'百词斩', u'Baicizhan'])
|
@register([u'百词斩', u'Baicizhan'])
|
||||||
@ -15,8 +15,7 @@ class Baicizhan(WebService):
|
|||||||
super(Baicizhan, self).__init__()
|
super(Baicizhan, self).__init__()
|
||||||
|
|
||||||
def _get_from_api(self):
|
def _get_from_api(self):
|
||||||
word = self.word.replace(' ', '_')
|
url = u"http://mall.baicizhan.com/ws/search?w={}".format(self.quote_word)
|
||||||
url = u"http://mall.baicizhan.com/ws/search?w={}".format(word)
|
|
||||||
result = {
|
result = {
|
||||||
"accent": u"",
|
"accent": u"",
|
||||||
"img": u"",
|
"img": u"",
|
||||||
@ -33,18 +32,14 @@ class Baicizhan(WebService):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return self.cache_this(result)
|
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')
|
@export('PRON')
|
||||||
def fld_phonetic(self):
|
def fld_phonetic(self):
|
||||||
word = self.word.replace(' ', '_')
|
url = u'http://baicizhan.qiniucdn.com/word_audios/{}.mp3'.format(self.quote_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
|
||||||
|
audio_name = get_hex_name(self.unique.lower(), audio_name, 'mp3')
|
||||||
if self.bcz_download_mp3:
|
if self.bcz_download_mp3:
|
||||||
if os.path.exists(audio_name) or self.download(url, audio_name, 5):
|
if os.path.exists(audio_name) or self.download(url, audio_name, 5):
|
||||||
# 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"}':
|
||||||
res = ''
|
res = ''
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
from hashlib import sha1
|
import os
|
||||||
from ..base import WebService, export, register, with_styles, parse_html
|
from ..base import *
|
||||||
|
|
||||||
baidu_download_mp3 = True
|
baidu_download_mp3 = True
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ class Baidu_Chinese(WebService):
|
|||||||
super(Baidu_Chinese, self).__init__()
|
super(Baidu_Chinese, self).__init__()
|
||||||
|
|
||||||
def _get_content(self):
|
def _get_content(self):
|
||||||
url = u"http://dict.baidu.com/s?wd={}#basicmean".format(self.word)
|
url = u"http://dict.baidu.com/s?wd={}#basicmean".format(self.quote_word)
|
||||||
html = self.get_response(url, timeout=10)
|
html = self.get_response(url, timeout=10)
|
||||||
soup = parse_html(html)
|
soup = parse_html(html)
|
||||||
result = {
|
result = {
|
||||||
@ -72,26 +72,14 @@ class Baidu_Chinese(WebService):
|
|||||||
audio_url = self._get_field('audio_url')
|
audio_url = self._get_field('audio_url')
|
||||||
if baidu_download_mp3 and audio_url:
|
if baidu_download_mp3 and audio_url:
|
||||||
filename = u'_baidu_chinese_{}_.mp3'.format(self.word)
|
filename = u'_baidu_chinese_{}_.mp3'.format(self.word)
|
||||||
hex_digest = sha1(
|
filename = get_hex_name(self.unique.lower(), filename, 'mp3')
|
||||||
self.word.encode('utf-8') if isinstance(self.word, unicode)
|
|
||||||
else self.word
|
|
||||||
).hexdigest().lower()
|
|
||||||
assert len(hex_digest) == 40, "unexpected output from hash library"
|
|
||||||
filename = '.'.join([
|
|
||||||
'-'.join([
|
|
||||||
self.unique.lower(
|
|
||||||
), hex_digest[:8], hex_digest[8:16],
|
|
||||||
hex_digest[16:24], hex_digest[24:32], hex_digest[32:],
|
|
||||||
]),
|
|
||||||
'mp3',
|
|
||||||
])
|
|
||||||
try:
|
try:
|
||||||
self.net_download(
|
if os.path.exists(filename) or self.net_download(
|
||||||
filename,
|
filename,
|
||||||
audio_url,
|
audio_url,
|
||||||
require=dict(mime='audio/mp3', size=512),
|
require=dict(mime='audio/mp3', size=512)
|
||||||
)
|
):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return ''
|
return ''
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
import re
|
import re
|
||||||
from ..base import WebService, export, register, with_styles, parse_html
|
import os
|
||||||
|
from ..base import *
|
||||||
|
|
||||||
bing_download_mp3 = True
|
bing_download_mp3 = True
|
||||||
|
|
||||||
@ -10,9 +11,8 @@ class Bing(WebService):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Bing, self).__init__()
|
super(Bing, self).__init__()
|
||||||
|
|
||||||
def _get_content(self):
|
def _get_from_api(self):
|
||||||
word = self.word.replace(' ', '_')
|
data = self.get_response(u"http://cn.bing.com/dict/search?q={}&mkt=zh-cn".format(self.quote_word))
|
||||||
data = self.get_response(u"http://cn.bing.com/dict/search?q={}&mkt=zh-cn".format(word))
|
|
||||||
soup = parse_html(data)
|
soup = parse_html(data)
|
||||||
result = {
|
result = {
|
||||||
'pronunciation': {'AmE': '', 'BrE': '', 'AmEmp3': '', 'BrEmp3': ''},
|
'pronunciation': {'AmE': '', 'BrE': '', 'AmEmp3': '', 'BrEmp3': ''},
|
||||||
@ -66,9 +66,6 @@ class Bing(WebService):
|
|||||||
|
|
||||||
return self.cache_this(result)
|
return self.cache_this(result)
|
||||||
|
|
||||||
def _get_field(self, key, default=u''):
|
|
||||||
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
|
|
||||||
|
|
||||||
@with_styles(css='.pos{font-weight:bold;margin-right:4px;}', need_wrap_css=True, wrap_class='bing')
|
@with_styles(css='.pos{font-weight:bold;margin-right:4px;}', need_wrap_css=True, wrap_class='bing')
|
||||||
def _css(self, val):
|
def _css(self, val):
|
||||||
return val
|
return val
|
||||||
@ -86,8 +83,8 @@ class Bing(WebService):
|
|||||||
def _fld_mp3(self, fld):
|
def _fld_mp3(self, fld):
|
||||||
audio_url = self._get_field('pronunciation')[fld]
|
audio_url = self._get_field('pronunciation')[fld]
|
||||||
if bing_download_mp3 and audio_url:
|
if bing_download_mp3 and audio_url:
|
||||||
filename = u'bing_' + u''.join(re.findall(r'\w*\.mp3', audio_url))
|
filename = get_hex_name('bing', audio_url, 'mp3')
|
||||||
if filename and self.net_download(filename, audio_url):
|
if os.path.exists(filename) or self.net_download(filename, audio_url):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
from ..base import WebService, export, register, with_styles
|
import os
|
||||||
|
from ..base import *
|
||||||
|
|
||||||
bing_download_mp3 = True
|
bing_download_mp3 = True
|
||||||
|
|
||||||
@ -11,7 +12,7 @@ class BingXtk(WebService):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(BingXtk, self).__init__()
|
super(BingXtk, self).__init__()
|
||||||
|
|
||||||
def _get_content(self):
|
def _get_from_api(self):
|
||||||
result = {
|
result = {
|
||||||
'pronunciation': {'AmE': '', 'BrE': '', 'AmEmp3': '', 'BrEmp3': ''},
|
'pronunciation': {'AmE': '', 'BrE': '', 'AmEmp3': '', 'BrEmp3': ''},
|
||||||
'def': '',
|
'def': '',
|
||||||
@ -21,17 +22,13 @@ 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(' ', '_').encode('utf-8')
|
url = u'http://xtk.azurewebsites.net/BingDictService.aspx?Word={}'.format(self.quote_word)
|
||||||
url = u'http://xtk.azurewebsites.net/BingDictService.aspx?Word={}'.format(word)
|
|
||||||
try:
|
try:
|
||||||
result.update(json.loads(self.get_response(url, headers=headers, timeout=10)))
|
result.update(json.loads(self.get_response(url, headers=headers, timeout=10)))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return self.cache_this(result)
|
return self.cache_this(result)
|
||||||
|
|
||||||
def _get_field(self, key, default=u''):
|
|
||||||
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
|
|
||||||
|
|
||||||
@export('AME_PHON')
|
@export('AME_PHON')
|
||||||
def fld_phonetic_us(self):
|
def fld_phonetic_us(self):
|
||||||
seg = self._get_field('pronunciation')
|
seg = self._get_field('pronunciation')
|
||||||
@ -45,8 +42,8 @@ class BingXtk(WebService):
|
|||||||
def _fld_mp3(self, fld):
|
def _fld_mp3(self, fld):
|
||||||
audio_url = self._get_field('pronunciation')[fld]
|
audio_url = self._get_field('pronunciation')[fld]
|
||||||
if bing_download_mp3 and audio_url:
|
if bing_download_mp3 and audio_url:
|
||||||
filename = u'bing_' + u''.join(re.findall(r'\w*\.mp3', audio_url))
|
filename = get_hex_name('bing', audio_url, 'mp3')
|
||||||
if filename and self.net_download(filename, audio_url):
|
if os.path.exists(filename) or self.net_download(filename, audio_url):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
from hashlib import sha1
|
import os
|
||||||
from ..base import WebService, export, register, with_styles, parse_html
|
from ..base import *
|
||||||
|
|
||||||
cambridge_download_mp3 = True
|
cambridge_download_mp3 = True
|
||||||
|
|
||||||
@ -10,9 +10,8 @@ class Cambridge(WebService):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Cambridge, self).__init__()
|
super(Cambridge, self).__init__()
|
||||||
|
|
||||||
def _get_content(self):
|
def _get_from_api(self):
|
||||||
word = self.word.replace(' ', '_')
|
data = self.get_response(u"https://dictionary.cambridge.org/dictionary/english/{}".format(self.quote_word))
|
||||||
data = self.get_response(u"https://dictionary.cambridge.org/dictionary/english/{}".format(word))
|
|
||||||
soup = parse_html(data)
|
soup = parse_html(data)
|
||||||
result = {
|
result = {
|
||||||
'pronunciation': {'AmE': '', 'BrE': '', 'AmEmp3': '', 'BrEmp3': ''},
|
'pronunciation': {'AmE': '', 'BrE': '', 'AmEmp3': '', 'BrEmp3': ''},
|
||||||
@ -29,7 +28,8 @@ class Cambridge(WebService):
|
|||||||
tags = header.find_all('span', class_='pron-info')
|
tags = header.find_all('span', class_='pron-info')
|
||||||
if tags:
|
if tags:
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
reg = str(tag.find('span', class_='region').get_text()).decode('utf-8')
|
r = tag.find('span', class_='region')
|
||||||
|
reg = str(r.get_text()).decode('utf-8') if r else u''
|
||||||
pn = 'AmE' if reg=='us' else 'BrE'
|
pn = 'AmE' if reg=='us' else 'BrE'
|
||||||
p = tag.find('span', class_='pron')
|
p = tag.find('span', class_='pron')
|
||||||
result['pronunciation'][pn] = str(p.get_text()).decode('utf-8') if p else u''
|
result['pronunciation'][pn] = str(p.get_text()).decode('utf-8') if p else u''
|
||||||
@ -58,9 +58,6 @@ class Cambridge(WebService):
|
|||||||
result['def'] = u'<ul>' + u''.join(s for s in l) + u'</ul>'
|
result['def'] = u'<ul>' + u''.join(s for s in l) + u'</ul>'
|
||||||
|
|
||||||
return self.cache_this(result)
|
return self.cache_this(result)
|
||||||
|
|
||||||
def _get_field(self, key, default=u''):
|
|
||||||
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
|
|
||||||
|
|
||||||
@with_styles(need_wrap_css=True, cssfile='_cambridge.css')
|
@with_styles(need_wrap_css=True, cssfile='_cambridge.css')
|
||||||
def _css(self, val):
|
def _css(self, val):
|
||||||
@ -79,22 +76,8 @@ class Cambridge(WebService):
|
|||||||
def _fld_mp3(self, fld):
|
def _fld_mp3(self, fld):
|
||||||
audio_url = self._get_field('pronunciation')[fld]
|
audio_url = self._get_field('pronunciation')[fld]
|
||||||
if cambridge_download_mp3 and audio_url:
|
if cambridge_download_mp3 and audio_url:
|
||||||
filename = u'_cambridge_{}_.mp3'.format(self.word)
|
filename = get_hex_name(self.unique.lower(), audio_url, 'mp3')
|
||||||
hex_digest = sha1(
|
if os.path.exists(filename) or self.net_download(filename, audio_url):
|
||||||
self.word.encode('utf-8') if isinstance(self.word, unicode)
|
|
||||||
else self.word
|
|
||||||
).hexdigest().lower()
|
|
||||||
assert len(hex_digest) == 40, "unexpected output from hash library"
|
|
||||||
filename = '.'.join([
|
|
||||||
'-'.join([
|
|
||||||
self.unique.lower(
|
|
||||||
), hex_digest[:8], hex_digest[8:16],
|
|
||||||
hex_digest[16:24], hex_digest[24:32], hex_digest[32:],
|
|
||||||
]),
|
|
||||||
'mp3',
|
|
||||||
])
|
|
||||||
|
|
||||||
if filename and self.net_download(filename, audio_url):
|
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|||||||
@ -1,32 +1,25 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
import re
|
import re
|
||||||
import urllib
|
|
||||||
import urllib2
|
import urllib2
|
||||||
|
import os
|
||||||
from aqt.utils import showInfo
|
from ..base import *
|
||||||
from BeautifulSoup import BeautifulSoup
|
|
||||||
from ..base import WebService, export, register, with_styles
|
|
||||||
|
|
||||||
# Anki buit-in BeautifulSoup is bs3 not bs4
|
|
||||||
|
|
||||||
|
|
||||||
css = ''
|
css = ''
|
||||||
|
|
||||||
|
|
||||||
@register(u'西语助手')
|
@register(u'西语助手')
|
||||||
class Esdict(WebService):
|
class Esdict(WebService):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Esdict, self).__init__()
|
super(Esdict, self).__init__()
|
||||||
|
|
||||||
def _get_content(self):
|
def _get_from_api(self):
|
||||||
url = 'https://www.esdict.cn/mdicts/es/{word}'.format(
|
url = 'https://www.esdict.cn/mdicts/es/{}'.format(self.quote_word)
|
||||||
word=urllib.quote(self.word.encode('utf-8')))
|
|
||||||
try:
|
try:
|
||||||
result = {}
|
result = {}
|
||||||
html = urllib2.urlopen(url, timeout=5).read()
|
html = self.get_response(url, timeout=5)
|
||||||
soup = BeautifulSoup(html)
|
soup = parse_html(html)
|
||||||
|
|
||||||
def _get_from_element(dict, key, soup, tag, id=None, class_=None):
|
def _get_from_element(dict, key, soup, tag, id=None, class_=None):
|
||||||
baseURL = 'https://www.esdict.cn/'
|
baseURL = 'https://www.esdict.cn/'
|
||||||
@ -62,21 +55,15 @@ class Esdict(WebService):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def _get_field(self, key, default=u''):
|
|
||||||
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
|
|
||||||
|
|
||||||
@export(u'真人发音')
|
@export(u'真人发音')
|
||||||
def fld_sound(self):
|
def fld_sound(self):
|
||||||
# base64.b64encode('bonjour') == 'Ym9uam91cg=='
|
|
||||||
# https://api.frdic.com/api/v2/speech/speakweb?langid=fr&txt=QYNYm9uam91cg%3d%3d
|
|
||||||
url = 'https://api.frdic.com/api/v2/speech/speakweb?langid=es&txt=QYN{word}'.format(
|
url = 'https://api.frdic.com/api/v2/speech/speakweb?langid=es&txt=QYN{word}'.format(
|
||||||
word=urllib.quote(base64.b64encode(self.word.encode('utf-8'))))
|
word=urllib2.quote(base64.b64encode(self.word.encode('utf-8')))
|
||||||
audio_name = u'esdict_{word}.mp3'.format(word=self.word)
|
)
|
||||||
try:
|
filename = get_hex_name(self.unique.lower(), url, 'mp3')
|
||||||
urllib.urlretrieve(url, audio_name)
|
if os.path.exists(filename) or self.net_download(filename, url):
|
||||||
return self.get_anki_label(audio_name, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
except Exception as e:
|
return ''
|
||||||
return ''
|
|
||||||
|
|
||||||
@export(u'音标')
|
@export(u'音标')
|
||||||
def fld_phonetic(self):
|
def fld_phonetic(self):
|
||||||
|
|||||||
@ -1,36 +1,28 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
import base64
|
import base64
|
||||||
import re
|
import re
|
||||||
import urllib
|
|
||||||
import urllib2
|
import urllib2
|
||||||
|
import os
|
||||||
from aqt.utils import showInfo
|
from ..base import *
|
||||||
from BeautifulSoup import BeautifulSoup
|
|
||||||
|
|
||||||
from ..base import WebService, export, with_styles, register
|
|
||||||
|
|
||||||
# Anki buit-in BeautifulSoup is bs3 not bs4
|
|
||||||
|
|
||||||
|
|
||||||
css = ''
|
css = ''
|
||||||
|
|
||||||
|
|
||||||
@register(u'法语助手')
|
@register(u'法语助手')
|
||||||
class Frdic(WebService):
|
class Frdic(WebService):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Frdic, self).__init__()
|
super(Frdic, self).__init__()
|
||||||
|
|
||||||
def _get_content(self):
|
def _get_from_api(self):
|
||||||
url = 'https://frdic.com/mdicts/fr/{word}'.format(
|
url = 'http://www.frdic.com/dicts/fr/{}'.format(self.quote_word)
|
||||||
word=urllib.quote(self.word.encode('utf-8')))
|
|
||||||
try:
|
try:
|
||||||
result = {}
|
result = {}
|
||||||
html = urllib2.urlopen(url, timeout=5).read()
|
html = self.get_response(url, timeout=5)
|
||||||
soup = BeautifulSoup(html)
|
soup = parse_html(html)
|
||||||
|
|
||||||
def _get_from_element(dict, key, soup, tag, id=None, class_=None):
|
def _get_from_element(dict, key, soup, tag, id=None, class_=None):
|
||||||
baseURL = 'https://frdic.com/'
|
baseURL = 'http://www.frdic.com/'
|
||||||
# element = soup.find(tag, id=id, class_=class_) # bs4
|
# element = soup.find(tag, id=id, class_=class_) # bs4
|
||||||
if id:
|
if id:
|
||||||
element = soup.find(tag, {"id": id})
|
element = soup.find(tag, {"id": id})
|
||||||
@ -49,9 +41,9 @@ class Frdic(WebService):
|
|||||||
result, 'phonitic', soup, 'span', class_='Phonitic')
|
result, 'phonitic', soup, 'span', class_='Phonitic')
|
||||||
# '<div id='FCChild' class='expDiv'>'
|
# '<div id='FCChild' class='expDiv'>'
|
||||||
result = _get_from_element(
|
result = _get_from_element(
|
||||||
result, 'fccf', soup, 'div', id='FCChild') # 法汉-汉法词典
|
result, 'fccf', soup, 'div', id='ExpFCChild') # 法汉-汉法词典
|
||||||
result = _get_from_element(
|
result = _get_from_element(
|
||||||
result, 'example', soup, 'div', id='LJChild') # 法语例句库
|
result, 'example', soup, 'div', id='TingLijuChild') # 法语例句库
|
||||||
result = _get_from_element(
|
result = _get_from_element(
|
||||||
result, 'syn', soup, 'div', id='SYNChild') # 近义、反义、派生词典
|
result, 'syn', soup, 'div', id='SYNChild') # 近义、反义、派生词典
|
||||||
result = _get_from_element(
|
result = _get_from_element(
|
||||||
@ -65,19 +57,14 @@ class Frdic(WebService):
|
|||||||
|
|
||||||
@export(u'真人发音')
|
@export(u'真人发音')
|
||||||
def fld_sound(self):
|
def fld_sound(self):
|
||||||
# base64.b64encode('bonjour') == 'Ym9uam91cg=='
|
|
||||||
# https://api.frdic.com/api/v2/speech/speakweb?langid=fr&txt=QYNYm9uam91cg%3d%3d
|
|
||||||
url = 'https://api.frdic.com/api/v2/speech/speakweb?langid=fr&txt=QYN{word}'.format(
|
url = 'https://api.frdic.com/api/v2/speech/speakweb?langid=fr&txt=QYN{word}'.format(
|
||||||
word=urllib.quote(base64.b64encode(self.word.encode('utf-8'))))
|
word=urllib2.quote(base64.b64encode(self.word.encode('utf-8')))
|
||||||
audio_name = u'frdic_{word}.mp3'.format(word=self.word)
|
)
|
||||||
try:
|
filename = u'frdic_{word}.mp3'.format(word=self.word)
|
||||||
urllib.urlretrieve(url, audio_name)
|
filename = get_hex_name(self.unique.lower(), filename, 'mp3')
|
||||||
return self.get_anki_label(audio_name, 'audio')
|
if os.path.exists(filename) or self.net_download(filename, url):
|
||||||
except Exception as e:
|
return self.get_anki_label(filename, 'audio')
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def _get_field(self, key, default=u''):
|
|
||||||
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
|
|
||||||
|
|
||||||
@export(u'音标')
|
@export(u'音标')
|
||||||
def fld_phonetic(self):
|
def fld_phonetic(self):
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import urllib2
|
|
||||||
import json
|
import json
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from aqt.utils import showInfo, showText
|
from aqt.utils import showInfo, showText
|
||||||
|
|
||||||
from ..base import WebService, export, with_styles, register
|
from ..base import *
|
||||||
from ...utils import ignore_exception
|
from ...utils import ignore_exception
|
||||||
|
|
||||||
iciba_download_mp3 = True
|
iciba_download_mp3 = True
|
||||||
@ -18,16 +17,19 @@ class ICIBA(WebService):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(ICIBA, self).__init__()
|
super(ICIBA, self).__init__()
|
||||||
|
|
||||||
def _get_content(self):
|
def _get_from_api(self):
|
||||||
resp = defaultdict(str)
|
resp = defaultdict(str)
|
||||||
headers = {
|
headers = {
|
||||||
'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': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
|
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
|
||||||
'Accept': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01'}
|
'Accept': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01'}
|
||||||
# try:
|
# try:
|
||||||
request = urllib2.Request(
|
html = self.get_response(
|
||||||
'http://www.iciba.com/index.php?a=getWordMean&c=search&word=' + self.word.encode('utf-8'), headers=headers)
|
'http://www.iciba.com/index.php?a=getWordMean&c=search&word=' + self.quote_word,
|
||||||
resp = json.loads(urllib2.urlopen(request).read())
|
headers=headers,
|
||||||
|
timeout=5
|
||||||
|
)
|
||||||
|
resp = json.loads(html)
|
||||||
# self.cache_this(resp['baesInfo']['symbols'][0])
|
# self.cache_this(resp['baesInfo']['symbols'][0])
|
||||||
# self.cache_this(resp['sentence'])
|
# self.cache_this(resp['sentence'])
|
||||||
# showText(str(self.cache[self.word]))
|
# showText(str(self.cache[self.word]))
|
||||||
@ -36,9 +38,6 @@ class ICIBA(WebService):
|
|||||||
# except Exception as e:
|
# except Exception as e:
|
||||||
# return resp
|
# return resp
|
||||||
|
|
||||||
def _get_field(self, key, default=u''):
|
|
||||||
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
|
|
||||||
|
|
||||||
@ignore_exception
|
@ignore_exception
|
||||||
@export(u'美式音标')
|
@export(u'美式音标')
|
||||||
def fld_phonetic_us(self):
|
def fld_phonetic_us(self):
|
||||||
@ -130,12 +129,11 @@ class ICIBA(WebService):
|
|||||||
@ignore_exception
|
@ignore_exception
|
||||||
@export(u'英文例句')
|
@export(u'英文例句')
|
||||||
def fld_st(self):
|
def fld_st(self):
|
||||||
sentences = ''
|
sentences = ''
|
||||||
segs = self._get_field('sentence')
|
segs = self._get_field('sentence')
|
||||||
for i, seg in enumerate(segs):
|
for i, seg in enumerate(segs):
|
||||||
sentences = u"""{}""".format(seg['Network_en'])
|
sentences = u"""{}""".format(seg['Network_en'])
|
||||||
break
|
break
|
||||||
|
|
||||||
return sentences
|
return sentences
|
||||||
|
|
||||||
@ignore_exception
|
@ignore_exception
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
|
|
||||||
from hashlib import sha1
|
import os
|
||||||
from ..base import WebService, export, register, with_styles, parse_html
|
from ..base import *
|
||||||
from ...libs.bs4 import Tag
|
from ...libs.bs4 import Tag
|
||||||
|
|
||||||
|
|
||||||
@ -14,11 +14,8 @@ class Longman(WebService):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Longman, self).__init__()
|
super(Longman, self).__init__()
|
||||||
|
|
||||||
def _get_field(self, key, default=u''):
|
def _get_from_api(self):
|
||||||
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
|
url = 'https://www.ldoceonline.com/dictionary/{}'.format(self.quote_word)
|
||||||
|
|
||||||
def _get_content(self):
|
|
||||||
url = 'https://www.ldoceonline.com/dictionary/{}'.format(self.word)
|
|
||||||
data = self.get_response(url)
|
data = self.get_response(url)
|
||||||
soup = parse_html(data)
|
soup = parse_html(data)
|
||||||
# Top Container
|
# Top Container
|
||||||
@ -116,21 +113,8 @@ class Longman(WebService):
|
|||||||
def _fld_mp3(self, fld):
|
def _fld_mp3(self, fld):
|
||||||
audio_url = self._get_field(fld)
|
audio_url = self._get_field(fld)
|
||||||
if longman_download_mp3 and audio_url:
|
if longman_download_mp3 and audio_url:
|
||||||
filename = u'_longman_{}_.mp3'.format(self.word)
|
filename = get_hex_name(self.unique.lower(), audio_url, 'mp3')
|
||||||
hex_digest = sha1(
|
if os.path.exists(filename) or self.net_download(filename, audio_url):
|
||||||
self.word.encode('utf-8') if isinstance(self.word, unicode)
|
|
||||||
else self.word
|
|
||||||
).hexdigest().lower()
|
|
||||||
assert len(hex_digest) == 40, "unexpected output from hash library"
|
|
||||||
filename = '.'.join([
|
|
||||||
'-'.join([
|
|
||||||
self.unique.lower(
|
|
||||||
), hex_digest[:8], hex_digest[8:16],
|
|
||||||
hex_digest[16:24], hex_digest[24:32], hex_digest[32:],
|
|
||||||
]),
|
|
||||||
'mp3',
|
|
||||||
])
|
|
||||||
if self.net_download(filename, audio_url):
|
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
|
|
||||||
from ..base import WebService, export, register, with_styles, parse_html
|
from ..base import *
|
||||||
|
|
||||||
|
|
||||||
@register(u'海词迷你词典')
|
@register(u'海词迷你词典')
|
||||||
@ -9,8 +9,8 @@ class MiniDict(WebService):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(MiniDict, self).__init__()
|
super(MiniDict, self).__init__()
|
||||||
|
|
||||||
def _get_content(self):
|
def _get_from_api(self):
|
||||||
data = self.get_response(u"http://apii.dict.cn/mini.php?q={}".format(self.word))
|
data = self.get_response(u"http://apii.dict.cn/mini.php?q={}".format(self.quote_word))
|
||||||
soup = parse_html(data)
|
soup = parse_html(data)
|
||||||
result = {
|
result = {
|
||||||
'expressions': u'',
|
'expressions': u'',
|
||||||
@ -45,9 +45,6 @@ class MiniDict(WebService):
|
|||||||
|
|
||||||
return self.cache_this(result)
|
return self.cache_this(result)
|
||||||
|
|
||||||
def _get_field(self, key, default=u''):
|
|
||||||
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
|
|
||||||
|
|
||||||
@export(u'音标')
|
@export(u'音标')
|
||||||
def fld_phonetic(self):
|
def fld_phonetic(self):
|
||||||
return self._get_field('phonetic')
|
return self._get_field('phonetic')
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
|
|
||||||
import urllib2
|
import urllib2
|
||||||
from urllib2 import quote
|
|
||||||
import json
|
import json
|
||||||
from aqt.utils import showInfo
|
from ..base import *
|
||||||
from ..base import WebService, export, register, with_styles
|
|
||||||
|
|
||||||
|
|
||||||
@register("Oxford")
|
@register(u"Oxford")
|
||||||
class Oxford(WebService):
|
class Oxford(WebService):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -19,7 +18,7 @@ class Oxford(WebService):
|
|||||||
app_key = "bb36fd6a1259e5baf8df6110a2f7fc8f"
|
app_key = "bb36fd6a1259e5baf8df6110a2f7fc8f"
|
||||||
headers = {"app_id": app_id, "app_key": app_key}
|
headers = {"app_id": app_id, "app_key": app_key}
|
||||||
|
|
||||||
word_id = quote(word.lower().replace(" ", "_"))
|
word_id = urllib2.quote(word.lower().replace(" ", "_"))
|
||||||
url = baseurl + "/entries/" + lang + "/" + word_id
|
url = baseurl + "/entries/" + lang + "/" + word_id
|
||||||
url = urllib2.Request(url, headers=headers)
|
url = urllib2.Request(url, headers=headers)
|
||||||
response = json.loads(urllib2.urlopen(url).read())
|
response = json.loads(urllib2.urlopen(url).read())
|
||||||
|
|||||||
@ -1,14 +1,9 @@
|
|||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
#from warnings import filterwarnings
|
#from warnings import filterwarnings
|
||||||
|
|
||||||
|
from ..base import *
|
||||||
from ...libs.bs4 import Tag
|
from ...libs.bs4 import Tag
|
||||||
from ..base import WebService, export, register, with_styles, parse_html
|
|
||||||
|
|
||||||
#filterwarnings('ignore')
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
#reload(sys)
|
|
||||||
#sys.setdefaultencoding('utf8')
|
|
||||||
|
|
||||||
@register([u'牛津学习词典', u'Oxford Learner'])
|
@register([u'牛津学习词典', u'Oxford Learner'])
|
||||||
class OxfordLearning(WebService):
|
class OxfordLearning(WebService):
|
||||||
@ -36,7 +31,7 @@ class OxfordLearning(WebService):
|
|||||||
|
|
||||||
def _get_single_dict(self, single_dict):
|
def _get_single_dict(self, single_dict):
|
||||||
if not (self.cached(single_dict) and self.cache_result(single_dict)):
|
if not (self.cached(single_dict) and self.cache_result(single_dict)):
|
||||||
web_word = self.query(self.word)
|
web_word = self.query(self.quote_word)
|
||||||
if web_word:
|
if web_word:
|
||||||
self.cache_this(
|
self.cache_this(
|
||||||
{
|
{
|
||||||
|
|||||||
@ -21,12 +21,10 @@ import os
|
|||||||
# import ntpath
|
# import ntpath
|
||||||
import re
|
import re
|
||||||
import urllib
|
import urllib
|
||||||
import urllib2
|
|
||||||
import urlparse
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from aqt.utils import showInfo, showText
|
from aqt.utils import showInfo, showText
|
||||||
from ..base import QueryResult, WebService, export, register, with_styles
|
from ..base import *
|
||||||
|
|
||||||
|
|
||||||
@register('MDX_SERVER')
|
@register('MDX_SERVER')
|
||||||
@ -41,8 +39,8 @@ class RemoteMdx(WebService):
|
|||||||
self.url = dict_path + \
|
self.url = dict_path + \
|
||||||
'/' if not dict_path.endswith('/') else dict_path
|
'/' if not dict_path.endswith('/') else dict_path
|
||||||
try:
|
try:
|
||||||
req = urllib2.urlopen(self.url + word)
|
html = self.get_response(self.url + word)
|
||||||
result, js = self.adapt_to_anki(req.read())
|
result, js = self.adapt_to_anki(html)
|
||||||
return QueryResult(result=result, js=js)
|
return QueryResult(result=result, js=js)
|
||||||
except:
|
except:
|
||||||
return QueryResult.default()
|
return QueryResult.default()
|
||||||
@ -54,12 +52,12 @@ class RemoteMdx(WebService):
|
|||||||
for each in diff:
|
for each in diff:
|
||||||
basename = os.path.basename(each.replace('\\', os.path.sep))
|
basename = os.path.basename(each.replace('\\', os.path.sep))
|
||||||
saved_basename = '_' + basename
|
saved_basename = '_' + basename
|
||||||
abs_url = urlparse.urljoin(self.url, each)
|
abs_url = urllib.parse.urljoin(self.url, each)
|
||||||
if basename.endswith('.css') or basename.endswith('.js'):
|
if basename.endswith('.css') or basename.endswith('.js'):
|
||||||
styles.append(saved_basename)
|
styles.append(saved_basename)
|
||||||
if not os.path.exists(saved_basename):
|
if not os.path.exists(saved_basename):
|
||||||
try:
|
try:
|
||||||
urllib.urlretrieve(abs_url, saved_basename)
|
self.download(abs_url, saved_basename)
|
||||||
except:
|
except:
|
||||||
errors.append(each)
|
errors.append(each)
|
||||||
return errors, styles
|
return errors, styles
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
# -*- coding:utf-8 -*-
|
# -*- coding:utf-8 -*-
|
||||||
import os
|
import os
|
||||||
from hashlib import sha1
|
from ..base import *
|
||||||
from ..base import WebService, export, register, with_styles, parse_html
|
|
||||||
|
|
||||||
yahoo_download_mp3 = True
|
yahoo_download_mp3 = True
|
||||||
|
|
||||||
@ -12,9 +11,9 @@ class Yahoo_Dict(WebService):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Yahoo_Dict, self).__init__()
|
super(Yahoo_Dict, self).__init__()
|
||||||
|
|
||||||
def _get_content(self):
|
def _get_from_api(self):
|
||||||
url = u"https://tw.dictionary.search.yahoo.com/search?p={}".format(
|
url = u"https://tw.dictionary.search.yahoo.com/search?p={}".format(
|
||||||
self.word)
|
self.quote_word)
|
||||||
html = self.get_response(url, timeout=10)
|
html = self.get_response(url, timeout=10)
|
||||||
soup = parse_html(html)
|
soup = parse_html(html)
|
||||||
result = {
|
result = {
|
||||||
@ -51,9 +50,6 @@ class Yahoo_Dict(WebService):
|
|||||||
|
|
||||||
return self.cache_this(result)
|
return self.cache_this(result)
|
||||||
|
|
||||||
def _get_field(self, key, default=u''):
|
|
||||||
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
|
|
||||||
|
|
||||||
@with_styles(need_wrap_css=True, cssfile='_yahoo.css')
|
@with_styles(need_wrap_css=True, cssfile='_yahoo.css')
|
||||||
def _css(self, val):
|
def _css(self, val):
|
||||||
return val
|
return val
|
||||||
@ -66,20 +62,7 @@ class Yahoo_Dict(WebService):
|
|||||||
def fld_pron(self):
|
def fld_pron(self):
|
||||||
audio_url = self._get_field('audio_url')
|
audio_url = self._get_field('audio_url')
|
||||||
if yahoo_download_mp3 and audio_url:
|
if yahoo_download_mp3 and audio_url:
|
||||||
filename = u'_yahoo_dict_{}_.mp3'.format(self.word)
|
filename = get_hex_name(self.unique.lower(), audio_url, 'mp3')
|
||||||
hex_digest = sha1(
|
|
||||||
self.word.encode('utf-8') if isinstance(self.word, unicode)
|
|
||||||
else self.word
|
|
||||||
).hexdigest().lower()
|
|
||||||
assert len(hex_digest) == 40, "unexpected output from hash library"
|
|
||||||
filename = '.'.join([
|
|
||||||
'-'.join([
|
|
||||||
self.unique.lower(
|
|
||||||
), hex_digest[:8], hex_digest[8:16],
|
|
||||||
hex_digest[16:24], hex_digest[24:32], hex_digest[32:],
|
|
||||||
]),
|
|
||||||
'mp3',
|
|
||||||
])
|
|
||||||
if os.path.exists(filename) or self.download(audio_url, filename, 5):
|
if os.path.exists(filename) or self.download(audio_url, filename, 5):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
import re
|
|
||||||
import urllib2
|
|
||||||
import xml.etree.ElementTree
|
|
||||||
|
|
||||||
from aqt.utils import showInfo
|
import os
|
||||||
from ..base import WebService, export, register, with_styles
|
import xml.etree.ElementTree
|
||||||
|
from ..base import *
|
||||||
|
|
||||||
js = '''
|
js = '''
|
||||||
var initVoice = function () {
|
var initVoice = function () {
|
||||||
@ -38,7 +36,7 @@ class Youdao(WebService):
|
|||||||
'&doctype=xml&xmlVersion=3.2'
|
'&doctype=xml&xmlVersion=3.2'
|
||||||
'&dogVersion=1.0&vendor=unknown'
|
'&dogVersion=1.0&vendor=unknown'
|
||||||
'&appVer=3.1.17.4208'
|
'&appVer=3.1.17.4208'
|
||||||
'&le={0}&q={1}').format(lang, self.word)
|
'&le={0}&q={1}').format(lang, self.quote_word)
|
||||||
result ={
|
result ={
|
||||||
'phonetic': '',
|
'phonetic': '',
|
||||||
'explains':'',
|
'explains':'',
|
||||||
@ -66,9 +64,6 @@ class Youdao(WebService):
|
|||||||
pass
|
pass
|
||||||
return self.cache_this(result)
|
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(u'音标')
|
@export(u'音标')
|
||||||
def fld_phonetic(self):
|
def fld_phonetic(self):
|
||||||
return self._get_field('phonetic')
|
return self._get_field('phonetic')
|
||||||
@ -80,12 +75,12 @@ class Youdao(WebService):
|
|||||||
@with_styles(cssfile='_youdao.css', js=js, need_wrap_css=True, wrap_class='youdao')
|
@with_styles(cssfile='_youdao.css', js=js, need_wrap_css=True, wrap_class='youdao')
|
||||||
def _get_singledict(self, single_dict, lang='eng'):
|
def _get_singledict(self, single_dict, lang='eng'):
|
||||||
url = u"http://m.youdao.com/singledict?q={0}&dict={1}&le={2}&more=false".format(
|
url = u"http://m.youdao.com/singledict?q={0}&dict={1}&le={2}&more=false".format(
|
||||||
self.word,
|
self.quote_word,
|
||||||
single_dict,
|
single_dict,
|
||||||
lang
|
lang
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
result = urllib2.urlopen(url, timeout=5).read()
|
result = self.get_response(url, timeout=5)
|
||||||
return (u'<div id="{0}_contentWrp" class="content-wrp dict-container">'
|
return (u'<div id="{0}_contentWrp" class="content-wrp dict-container">'
|
||||||
'<div id="{0}" class="trans-container {0} ">{1}</div>'
|
'<div id="{0}" class="trans-container {0} ">{1}</div>'
|
||||||
'</div>'
|
'</div>'
|
||||||
@ -100,19 +95,19 @@ class Youdao(WebService):
|
|||||||
|
|
||||||
@export(u'英式发音')
|
@export(u'英式发音')
|
||||||
def fld_british_audio(self):
|
def fld_british_audio(self):
|
||||||
audio_url = u'http://dict.youdao.com/dictvoice?audio={}&type=1'.format(self.word)
|
audio_url = u'http://dict.youdao.com/dictvoice?audio={}&type=1'.format(self.quote_word)
|
||||||
if youdao_download_mp3:
|
if youdao_download_mp3:
|
||||||
filename = u'_youdao_{}_uk.mp3'.format(self.word)
|
filename = get_hex_name(self.unique.lower(), audio_url, 'mp3')
|
||||||
if self.download(audio_url, filename):
|
if os.path.exists(filename) or self.download(audio_url, filename):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
return audio_url
|
return audio_url
|
||||||
|
|
||||||
@export(u'美式发音')
|
@export(u'美式发音')
|
||||||
def fld_american_audio(self):
|
def fld_american_audio(self):
|
||||||
audio_url = u'http://dict.youdao.com/dictvoice?audio={}&type=2'.format(self.word)
|
audio_url = u'http://dict.youdao.com/dictvoice?audio={}&type=2'.format(self.quote_word)
|
||||||
if youdao_download_mp3:
|
if youdao_download_mp3:
|
||||||
filename = u'_youdao_{}_us.mp3'.format(self.word)
|
filename = get_hex_name(self.unique.lower(), audio_url, 'mp3')
|
||||||
if self.download(audio_url, filename):
|
if os.path.exists(filename) or self.download(audio_url, filename):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
return audio_url
|
return audio_url
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
import re
|
|
||||||
import urllib2
|
|
||||||
import xml.etree.ElementTree
|
|
||||||
|
|
||||||
from aqt.utils import showInfo
|
import xml.etree.ElementTree
|
||||||
from ..base import WebService, export, register, with_styles
|
from ..base import *
|
||||||
|
|
||||||
|
|
||||||
@register([u'有道词典-法语', u'Youdao-French'])
|
@register([u'有道词典-法语', u'Youdao-French'])
|
||||||
@ -19,7 +16,7 @@ class Youdaofr(WebService):
|
|||||||
'&doctype=xml&xmlVersion=3.2'
|
'&doctype=xml&xmlVersion=3.2'
|
||||||
'&dogVersion=1.0&vendor=unknown'
|
'&dogVersion=1.0&vendor=unknown'
|
||||||
'&appVer=3.1.17.4208'
|
'&appVer=3.1.17.4208'
|
||||||
'&le={0}&q={1}').format(lang, self.word)
|
'&le={0}&q={1}').format(lang, self.quote_word)
|
||||||
result ={
|
result ={
|
||||||
'phonetic': '',
|
'phonetic': '',
|
||||||
'explains':'',
|
'explains':'',
|
||||||
@ -44,10 +41,10 @@ class Youdaofr(WebService):
|
|||||||
@with_styles(cssfile='_youdao.css', need_wrap_css=True, wrap_class='youdao')
|
@with_styles(cssfile='_youdao.css', need_wrap_css=True, wrap_class='youdao')
|
||||||
def _get_singledict(self, single_dict, lang='fr'):
|
def _get_singledict(self, single_dict, lang='fr'):
|
||||||
url = u"http://m.youdao.com/singledict?q={0}&dict={1}&le={2}&more=false".format(
|
url = u"http://m.youdao.com/singledict?q={0}&dict={1}&le={2}&more=false".format(
|
||||||
self.word, single_dict, lang
|
self.quote_word, single_dict, lang
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
html = urllib2.urlopen(url, timeout=5).read()
|
html = self.get_response(url, timeout=5)
|
||||||
return (u'<div id="{0}_contentWrp" class="content-wrp dict-container">'
|
return (u'<div id="{0}_contentWrp" class="content-wrp dict-container">'
|
||||||
'<div id="{1}" class="trans-container {2} ">{3}</div>'
|
'<div id="{1}" class="trans-container {2} ">{3}</div>'
|
||||||
'</div>'
|
'</div>'
|
||||||
@ -57,7 +54,7 @@ class Youdaofr(WebService):
|
|||||||
single_dict,
|
single_dict,
|
||||||
single_dict,
|
single_dict,
|
||||||
single_dict,
|
single_dict,
|
||||||
html
|
html.decode('utf-8')
|
||||||
)
|
)
|
||||||
except:
|
except:
|
||||||
return ''
|
return ''
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
import re
|
|
||||||
import urllib2
|
|
||||||
import xml.etree.ElementTree
|
|
||||||
|
|
||||||
from aqt.utils import showInfo
|
import xml.etree.ElementTree
|
||||||
from ..base import WebService, export, register, with_styles
|
from ..base import *
|
||||||
|
|
||||||
|
|
||||||
@register([u'有道词典-韩语', u'Youdao-Korean'])
|
@register([u'有道词典-韩语', u'Youdao-Korean'])
|
||||||
@ -19,10 +16,10 @@ class Youdaoko(WebService):
|
|||||||
'&doctype=xml&xmlVersion=3.2'
|
'&doctype=xml&xmlVersion=3.2'
|
||||||
'&dogVersion=1.0&vendor=unknown'
|
'&dogVersion=1.0&vendor=unknown'
|
||||||
'&appVer=3.1.17.4208'
|
'&appVer=3.1.17.4208'
|
||||||
'&le={0}&q={1}').format(lang, self.word)
|
'&le={0}&q={1}').format(lang, self.quote_word)
|
||||||
result ={
|
result ={
|
||||||
'phonetic': '',
|
'phonetic': u'',
|
||||||
'explains':'',
|
'explains': u'',
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
html = self.get_response(url, timeout=5)
|
html = self.get_response(url, timeout=5)
|
||||||
@ -44,10 +41,10 @@ class Youdaoko(WebService):
|
|||||||
@with_styles(cssfile='_youdao.css', need_wrap_css=True, wrap_class='youdao')
|
@with_styles(cssfile='_youdao.css', need_wrap_css=True, wrap_class='youdao')
|
||||||
def _get_singledict(self, single_dict, lang='ko'):
|
def _get_singledict(self, single_dict, lang='ko'):
|
||||||
url = u"http://m.youdao.com/singledict?q={0}&dict={1}&le={2}&more=false".format(
|
url = u"http://m.youdao.com/singledict?q={0}&dict={1}&le={2}&more=false".format(
|
||||||
self.word, single_dict, lang
|
self.quote_word, single_dict, lang
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
html = urllib2.urlopen(url, timeout=5).read()
|
html = self.get_response(url, timeout=5)
|
||||||
return (u'<div id="{0}_contentWrp" class="content-wrp dict-container">'
|
return (u'<div id="{0}_contentWrp" class="content-wrp dict-container">'
|
||||||
'<div id="{1}" class="trans-container {2} ">{3}</div>'
|
'<div id="{1}" class="trans-container {2} ">{3}</div>'
|
||||||
'</div>'
|
'</div>'
|
||||||
|
|||||||
@ -305,8 +305,10 @@ class WebService(Service):
|
|||||||
return getattr(self, '__register_label__', self.unique)
|
return getattr(self, '__register_label__', self.unique)
|
||||||
|
|
||||||
def get_response(self, url, data=None, headers=None, timeout=10):
|
def get_response(self, url, data=None, headers=None, timeout=10):
|
||||||
default_headers = {'User-Agent': 'Anki WordQuery',
|
default_headers = {
|
||||||
'Accept-Encoding': 'gzip'}
|
'User-Agent': 'Mozilla/5.0',
|
||||||
|
'Accept-Encoding': 'gzip'
|
||||||
|
}
|
||||||
if headers:
|
if headers:
|
||||||
default_headers.update(headers)
|
default_headers.update(headers)
|
||||||
|
|
||||||
|
|||||||
@ -83,8 +83,7 @@ class Bing(WebService):
|
|||||||
def _fld_mp3(self, fld):
|
def _fld_mp3(self, fld):
|
||||||
audio_url = self._get_field('pronunciation')[fld]
|
audio_url = self._get_field('pronunciation')[fld]
|
||||||
if bing_download_mp3 and audio_url:
|
if bing_download_mp3 and audio_url:
|
||||||
filename = u'bing_' + u''.join(re.findall(r'\w*\.mp3', audio_url))
|
filename = get_hex_name('bing', audio_url, 'mp3')
|
||||||
filename = get_hex_name('bing', filename, 'mp3')
|
|
||||||
if os.path.exists(filename) or self.net_download(filename, audio_url):
|
if os.path.exists(filename) or self.net_download(filename, audio_url):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
return ''
|
return ''
|
||||||
|
|||||||
@ -42,8 +42,7 @@ class BingXtk(WebService):
|
|||||||
def _fld_mp3(self, fld):
|
def _fld_mp3(self, fld):
|
||||||
audio_url = self._get_field('pronunciation')[fld]
|
audio_url = self._get_field('pronunciation')[fld]
|
||||||
if bing_download_mp3 and audio_url:
|
if bing_download_mp3 and audio_url:
|
||||||
filename = u'bing_' + u''.join(re.findall(r'\w*\.mp3', audio_url))
|
filename = get_hex_name('bing', audio_url, 'mp3')
|
||||||
filename = get_hex_name('bing', filename, 'mp3')
|
|
||||||
if os.path.exists(filename) or self.net_download(filename, audio_url):
|
if os.path.exists(filename) or self.net_download(filename, audio_url):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
return ''
|
return ''
|
||||||
|
|||||||
@ -76,8 +76,7 @@ class Cambridge(WebService):
|
|||||||
def _fld_mp3(self, fld):
|
def _fld_mp3(self, fld):
|
||||||
audio_url = self._get_field('pronunciation')[fld]
|
audio_url = self._get_field('pronunciation')[fld]
|
||||||
if cambridge_download_mp3 and audio_url:
|
if cambridge_download_mp3 and audio_url:
|
||||||
filename = u'_cambridge_{}_.mp3'.format(self.word)
|
filename = get_hex_name(self.unique.lower(), audio_url, 'mp3')
|
||||||
filename = get_hex_name(self.unique.lower(), filename, 'mp3')
|
|
||||||
if os.path.exists(filename) or self.net_download(filename, audio_url):
|
if os.path.exists(filename) or self.net_download(filename, audio_url):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
return ''
|
return ''
|
||||||
|
|||||||
@ -60,8 +60,7 @@ class Esdict(WebService):
|
|||||||
url = 'https://api.frdic.com/api/v2/speech/speakweb?langid=es&txt=QYN{word}'.format(
|
url = 'https://api.frdic.com/api/v2/speech/speakweb?langid=es&txt=QYN{word}'.format(
|
||||||
word=urllib2.quote(base64.b64encode(self.word.encode('utf-8')))
|
word=urllib2.quote(base64.b64encode(self.word.encode('utf-8')))
|
||||||
)
|
)
|
||||||
filename = u'esdict_{word}.mp3'.format(word=self.word)
|
filename = get_hex_name(self.unique.lower(), url, 'mp3')
|
||||||
filename = get_hex_name(self.unique.lower(), filename, 'mp3')
|
|
||||||
if os.path.exists(filename) or self.net_download(filename, url):
|
if os.path.exists(filename) or self.net_download(filename, url):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
return ''
|
return ''
|
||||||
|
|||||||
@ -113,8 +113,7 @@ class Longman(WebService):
|
|||||||
def _fld_mp3(self, fld):
|
def _fld_mp3(self, fld):
|
||||||
audio_url = self._get_field(fld)
|
audio_url = self._get_field(fld)
|
||||||
if longman_download_mp3 and audio_url:
|
if longman_download_mp3 and audio_url:
|
||||||
filename = u'_longman_{}_.mp3'.format(self.word)
|
filename = get_hex_name(self.unique.lower(), audio_url, 'mp3')
|
||||||
filename = get_hex_name(self.unique.lower(), filename, 'mp3')
|
|
||||||
if os.path.exists(filename) or self.net_download(filename, audio_url):
|
if os.path.exists(filename) or self.net_download(filename, audio_url):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
return ''
|
return ''
|
||||||
|
|||||||
@ -11,7 +11,7 @@ class Yahoo_Dict(WebService):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Yahoo_Dict, self).__init__()
|
super(Yahoo_Dict, self).__init__()
|
||||||
|
|
||||||
def _get_content(self):
|
def _get_from_api(self):
|
||||||
url = u"https://tw.dictionary.search.yahoo.com/search?p={}".format(
|
url = u"https://tw.dictionary.search.yahoo.com/search?p={}".format(
|
||||||
self.quote_word)
|
self.quote_word)
|
||||||
html = self.get_response(url, timeout=10)
|
html = self.get_response(url, timeout=10)
|
||||||
@ -50,9 +50,6 @@ class Yahoo_Dict(WebService):
|
|||||||
|
|
||||||
return self.cache_this(result)
|
return self.cache_this(result)
|
||||||
|
|
||||||
def _get_field(self, key, default=u''):
|
|
||||||
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
|
|
||||||
|
|
||||||
@with_styles(need_wrap_css=True, cssfile='_yahoo.css')
|
@with_styles(need_wrap_css=True, cssfile='_yahoo.css')
|
||||||
def _css(self, val):
|
def _css(self, val):
|
||||||
return val
|
return val
|
||||||
@ -65,8 +62,7 @@ class Yahoo_Dict(WebService):
|
|||||||
def fld_pron(self):
|
def fld_pron(self):
|
||||||
audio_url = self._get_field('audio_url')
|
audio_url = self._get_field('audio_url')
|
||||||
if yahoo_download_mp3 and audio_url:
|
if yahoo_download_mp3 and audio_url:
|
||||||
filename = u'_yahoo_dict_{}_.mp3'.format(self.word)
|
filename = get_hex_name(self.unique.lower(), audio_url, 'mp3')
|
||||||
filename = get_hex_name(self.unique.lower(), filename, 'mp3')
|
|
||||||
if os.path.exists(filename) or self.download(audio_url, filename, 5):
|
if os.path.exists(filename) or self.download(audio_url, filename, 5):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
|
|
||||||
|
|||||||
@ -97,7 +97,7 @@ class Youdao(WebService):
|
|||||||
def fld_british_audio(self):
|
def fld_british_audio(self):
|
||||||
audio_url = u'http://dict.youdao.com/dictvoice?audio={}&type=1'.format(self.quote_word)
|
audio_url = u'http://dict.youdao.com/dictvoice?audio={}&type=1'.format(self.quote_word)
|
||||||
if youdao_download_mp3:
|
if youdao_download_mp3:
|
||||||
filename = u'_youdao_{}_uk.mp3'.format(self.word)
|
filename = get_hex_name(self.unique.lower(), audio_url, 'mp3')
|
||||||
if os.path.exists(filename) or self.download(audio_url, filename):
|
if os.path.exists(filename) or self.download(audio_url, filename):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
return audio_url
|
return audio_url
|
||||||
@ -106,7 +106,7 @@ class Youdao(WebService):
|
|||||||
def fld_american_audio(self):
|
def fld_american_audio(self):
|
||||||
audio_url = u'http://dict.youdao.com/dictvoice?audio={}&type=2'.format(self.quote_word)
|
audio_url = u'http://dict.youdao.com/dictvoice?audio={}&type=2'.format(self.quote_word)
|
||||||
if youdao_download_mp3:
|
if youdao_download_mp3:
|
||||||
filename = u'_youdao_{}_us.mp3'.format(self.word)
|
filename = get_hex_name(self.unique.lower(), audio_url, 'mp3')
|
||||||
if os.path.exists(filename) or self.download(audio_url, filename):
|
if os.path.exists(filename) or self.download(audio_url, filename):
|
||||||
return self.get_anki_label(filename, 'audio')
|
return self.get_anki_label(filename, 'audio')
|
||||||
return audio_url
|
return audio_url
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user