Skip to content

Commit 0e0cc52

Browse files
committed
Adapt to anki 2.1
1 parent 0bf86b9 commit 0e0cc52

27 files changed

+176
-285
lines changed

addons/fastwq/service/base.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
from collections import defaultdict
3434
from functools import wraps
3535
from hashlib import md5
36+
from hashlib import sha1
3637

3738
import cookielib
3839
from aqt import mw
@@ -50,19 +51,37 @@
5051

5152

5253
__all__ = [
53-
'register', 'export', 'copy_static_file', 'with_styles', 'parse_html', 'service_wrap',
54+
'register', 'export', 'copy_static_file', 'with_styles', 'parse_html', 'service_wrap', 'get_hex_name',
5455
'Service', 'WebService', 'LocalService', 'MdxService', 'StardictService', 'QueryResult'
5556
]
5657

5758

59+
def get_hex_name(prefix, val, suffix):
60+
''' get sha1 hax name '''
61+
hex_digest = sha1(
62+
val.encode('utf-8') if isinstance(val, unicode)
63+
else val
64+
).hexdigest().lower()
65+
name = '.'.join([
66+
'-'.join([
67+
prefix, hex_digest[:8], hex_digest[8:16],
68+
hex_digest[16:24], hex_digest[24:32], hex_digest[32:],
69+
]),
70+
suffix,
71+
])
72+
return name
73+
74+
def _is_method_or_func(object):
75+
return inspect.isfunction(object) or inspect.ismethod(object)
76+
5877
def register(labels):
5978
"""
6079
register the dict service with a labels, which will be shown in the dicts list.
6180
"""
6281
def _deco(cls):
6382
cls.__register_label__ = _cl(labels)
6483

65-
methods = inspect.getmembers(cls, predicate=inspect.ismethod)
84+
methods = inspect.getmembers(cls, predicate=_is_method_or_func)
6685
exports = []
6786
for method in methods:
6887
attrs = getattr(method[1], '__export_attrs__', None)
@@ -198,10 +217,16 @@ def cache_this(self, result):
198217
return result
199218

200219
def cached(self, key):
201-
return (self.word in self.cache) and self.cache[self.word].has_key(key)
220+
return (self.word in self.cache) and (key in self.cache[self.word])
202221

203222
def cache_result(self, key):
204223
return self.cache[self.word].get(key, u'')
224+
225+
def _get_from_api(self):
226+
return {}
227+
228+
def _get_field(self, key, default=u''):
229+
return self.cache_result(key) if self.cached(key) else self._get_from_api().get(key, default)
205230

206231
@property
207232
def unique(self):
@@ -210,6 +235,13 @@ def unique(self):
210235
@unique.setter
211236
def unique(self, value):
212237
self._unique = value
238+
239+
@property
240+
def quote_word(self):
241+
return urllib2.quote(
242+
self.word.encode('utf-8') if isinstance(self.word, unicode)
243+
else self.word
244+
)
213245

214246
@property
215247
def support(self):
@@ -269,8 +301,10 @@ def title(self):
269301
return getattr(self, '__register_label__', self.unique)
270302

271303
def get_response(self, url, data=None, headers=None, timeout=10):
272-
default_headers = {'User-Agent': 'Anki WordQuery',
273-
'Accept-Encoding': 'gzip'}
304+
default_headers = {
305+
'User-Agent': 'Mozilla/5.0',
306+
'Accept-Encoding': 'gzip'
307+
}
274308
if headers:
275309
default_headers.update(headers)
276310

@@ -282,7 +316,7 @@ def get_response(self, url, data=None, headers=None, timeout=10):
282316
data = zlib.decompress(data, 16 + zlib.MAX_WBITS)
283317
return data
284318
except:
285-
return ''
319+
return u''
286320

287321
@classmethod
288322
def download(cls, url, filename, timeout=15):

addons/fastwq/service/dict/LDOCE6.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#-*- coding:utf-8 -*-
22
import re
33
import FastWQ
4-
from ..base import MdxService, export, register, with_styles, parse_html
4+
from ..base import *
55

66
PATH = FastWQ.LDOCE6_PATH
77

@@ -33,24 +33,11 @@ def fld_phonetic(self):
3333

3434
def _fld_voice(self, html, voice):
3535
"""获取发音字段"""
36-
from hashlib import sha1
3736
for regexp in LANG_TO_REGEXPS[voice]:
3837
match = regexp.search(html)
3938
if match:
4039
val = '/' + match.group(1)
41-
hex_digest = sha1(
42-
val.encode('utf-8') if isinstance(val, unicode)
43-
else val
44-
).hexdigest().lower()
45-
46-
assert len(hex_digest) == 40, "unexpected output from hash library"
47-
name = '.'.join([
48-
'-'.join([
49-
'mdx', self.unique.lower(), hex_digest[:8], hex_digest[8:16],
50-
hex_digest[16:24], hex_digest[24:32], hex_digest[32:],
51-
]),
52-
'mp3',
53-
])
40+
name = get_hex_name('mdx-'+self.unique.lower(), val, 'mp3')
5441
name = self.save_file(val, name)
5542
if name:
5643
return self.get_anki_label(name, 'audio')

addons/fastwq/service/dict/baicizhan.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import json
33
import os
44
from collections import defaultdict
5-
from ..base import WebService, export, register
5+
from ..base import *
66

77

88
@register([u'百词斩', u'Baicizhan'])
@@ -15,8 +15,7 @@ def __init__(self):
1515
super(Baicizhan, self).__init__()
1616

1717
def _get_from_api(self):
18-
word = self.word.replace(' ', '_')
19-
url = u"http://mall.baicizhan.com/ws/search?w={}".format(word)
18+
url = u"http://mall.baicizhan.com/ws/search?w={}".format(self.quote_word)
2019
result = {
2120
"accent": u"",
2221
"img": u"",
@@ -33,18 +32,14 @@ def _get_from_api(self):
3332
except:
3433
pass
3534
return self.cache_this(result)
36-
37-
def _get_field(self, key, default=u''):
38-
return self.cache_result(key) if self.cached(key) else self._get_from_api().get(key, default)
3935

4036
@export('PRON')
4137
def fld_phonetic(self):
42-
word = self.word.replace(' ', '_')
43-
url = u'http://baicizhan.qiniucdn.com/word_audios/{}.mp3'.format(word)
38+
url = u'http://baicizhan.qiniucdn.com/word_audios/{}.mp3'.format(self.quote_word)
4439
audio_name = 'bcz_%s.mp3' % self.word
40+
audio_name = get_hex_name(self.unique.lower(), audio_name, 'mp3')
4541
if self.bcz_download_mp3:
4642
if os.path.exists(audio_name) or self.download(url, audio_name, 5):
47-
# urllib.urlretrieve(url, audio_name)
4843
with open(audio_name, 'rb') as f:
4944
if f.read().strip() == '{"error":"Document not found"}':
5045
res = ''

addons/fastwq/service/dict/baidu_chinese.py

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#-*- coding:utf-8 -*-
2-
from hashlib import sha1
3-
from ..base import WebService, export, register, with_styles, parse_html
2+
import os
3+
from ..base import *
44

55
baidu_download_mp3 = True
66

@@ -11,7 +11,7 @@ def __init__(self):
1111
super(Baidu_Chinese, self).__init__()
1212

1313
def _get_content(self):
14-
url = u"http://dict.baidu.com/s?wd={}#basicmean".format(self.word)
14+
url = u"http://dict.baidu.com/s?wd={}#basicmean".format(self.quote_word)
1515
html = self.get_response(url, timeout=10)
1616
soup = parse_html(html)
1717
result = {
@@ -72,26 +72,14 @@ def fld_pron(self):
7272
audio_url = self._get_field('audio_url')
7373
if baidu_download_mp3 and audio_url:
7474
filename = u'_baidu_chinese_{}_.mp3'.format(self.word)
75-
hex_digest = sha1(
76-
self.word.encode('utf-8') if isinstance(self.word, unicode)
77-
else self.word
78-
).hexdigest().lower()
79-
assert len(hex_digest) == 40, "unexpected output from hash library"
80-
filename = '.'.join([
81-
'-'.join([
82-
self.unique.lower(
83-
), hex_digest[:8], hex_digest[8:16],
84-
hex_digest[16:24], hex_digest[24:32], hex_digest[32:],
85-
]),
86-
'mp3',
87-
])
75+
filename = get_hex_name(self.unique.lower(), filename, 'mp3')
8876
try:
89-
self.net_download(
77+
if os.path.exists(filename) or self.net_download(
9078
filename,
9179
audio_url,
92-
require=dict(mime='audio/mp3', size=512),
93-
)
94-
return self.get_anki_label(filename, 'audio')
80+
require=dict(mime='audio/mp3', size=512)
81+
):
82+
return self.get_anki_label(filename, 'audio')
9583
except:
9684
pass
9785
return ''

addons/fastwq/service/dict/bing.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#-*- coding:utf-8 -*-
22
import re
3-
from ..base import WebService, export, register, with_styles, parse_html
3+
import os
4+
from ..base import *
45

56
bing_download_mp3 = True
67

@@ -10,9 +11,8 @@ class Bing(WebService):
1011
def __init__(self):
1112
super(Bing, self).__init__()
1213

13-
def _get_content(self):
14-
word = self.word.replace(' ', '_')
15-
data = self.get_response(u"http://cn.bing.com/dict/search?q={}&mkt=zh-cn".format(word))
14+
def _get_from_api(self):
15+
data = self.get_response(u"http://cn.bing.com/dict/search?q={}&mkt=zh-cn".format(self.quote_word))
1616
soup = parse_html(data)
1717
result = {
1818
'pronunciation': {'AmE': '', 'BrE': '', 'AmEmp3': '', 'BrEmp3': ''},
@@ -66,9 +66,6 @@ def _get_content(self):
6666

6767
return self.cache_this(result)
6868

69-
def _get_field(self, key, default=u''):
70-
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
71-
7269
@with_styles(css='.pos{font-weight:bold;margin-right:4px;}', need_wrap_css=True, wrap_class='bing')
7370
def _css(self, val):
7471
return val
@@ -86,8 +83,8 @@ def fld_phonetic_uk(self):
8683
def _fld_mp3(self, fld):
8784
audio_url = self._get_field('pronunciation')[fld]
8885
if bing_download_mp3 and audio_url:
89-
filename = u'bing_' + u''.join(re.findall(r'\w*\.mp3', audio_url))
90-
if filename and self.net_download(filename, audio_url):
86+
filename = get_hex_name('bing', audio_url, 'mp3')
87+
if os.path.exists(filename) or self.net_download(filename, audio_url):
9188
return self.get_anki_label(filename, 'audio')
9289
return ''
9390

addons/fastwq/service/dict/bing3tp.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#-*- coding:utf-8 -*-
22
import json
33
import re
4-
from ..base import WebService, export, register, with_styles
4+
import os
5+
from ..base import *
56

67
bing_download_mp3 = True
78

@@ -11,7 +12,7 @@ class BingXtk(WebService):
1112
def __init__(self):
1213
super(BingXtk, self).__init__()
1314

14-
def _get_content(self):
15+
def _get_from_api(self):
1516
result = {
1617
'pronunciation': {'AmE': '', 'BrE': '', 'AmEmp3': '', 'BrEmp3': ''},
1718
'def': '',
@@ -21,17 +22,13 @@ def _get_content(self):
2122
'Accept-Language': 'en-US,zh-CN;q=0.8,zh;q=0.6,en;q=0.4',
2223
'User-Agent': 'WordQuery Addon (Anki)',
2324
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'}
24-
word = self.word.replace(' ', '_').encode('utf-8')
25-
url = u'http://xtk.azurewebsites.net/BingDictService.aspx?Word={}'.format(word)
25+
url = u'http://xtk.azurewebsites.net/BingDictService.aspx?Word={}'.format(self.quote_word)
2626
try:
2727
result.update(json.loads(self.get_response(url, headers=headers, timeout=10)))
2828
except:
2929
pass
3030
return self.cache_this(result)
3131

32-
def _get_field(self, key, default=u''):
33-
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
34-
3532
@export('AME_PHON')
3633
def fld_phonetic_us(self):
3734
seg = self._get_field('pronunciation')
@@ -45,8 +42,8 @@ def fld_phonetic_uk(self):
4542
def _fld_mp3(self, fld):
4643
audio_url = self._get_field('pronunciation')[fld]
4744
if bing_download_mp3 and audio_url:
48-
filename = u'bing_' + u''.join(re.findall(r'\w*\.mp3', audio_url))
49-
if filename and self.net_download(filename, audio_url):
45+
filename = get_hex_name('bing', audio_url, 'mp3')
46+
if os.path.exists(filename) or self.net_download(filename, audio_url):
5047
return self.get_anki_label(filename, 'audio')
5148
return ''
5249

addons/fastwq/service/dict/cambridge.py

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#-*- coding:utf-8 -*-
2-
from hashlib import sha1
3-
from ..base import WebService, export, register, with_styles, parse_html
2+
import os
3+
from ..base import *
44

55
cambridge_download_mp3 = True
66

@@ -10,9 +10,8 @@ class Cambridge(WebService):
1010
def __init__(self):
1111
super(Cambridge, self).__init__()
1212

13-
def _get_content(self):
14-
word = self.word.replace(' ', '_')
15-
data = self.get_response(u"https://dictionary.cambridge.org/dictionary/english/{}".format(word))
13+
def _get_from_api(self):
14+
data = self.get_response(u"https://dictionary.cambridge.org/dictionary/english/{}".format(self.quote_word))
1615
soup = parse_html(data)
1716
result = {
1817
'pronunciation': {'AmE': '', 'BrE': '', 'AmEmp3': '', 'BrEmp3': ''},
@@ -29,7 +28,8 @@ def _get_content(self):
2928
tags = header.find_all('span', class_='pron-info')
3029
if tags:
3130
for tag in tags:
32-
reg = str(tag.find('span', class_='region').get_text()).decode('utf-8')
31+
r = tag.find('span', class_='region')
32+
reg = str(r.get_text()).decode('utf-8') if r else u''
3333
pn = 'AmE' if reg=='us' else 'BrE'
3434
p = tag.find('span', class_='pron')
3535
result['pronunciation'][pn] = str(p.get_text()).decode('utf-8') if p else u''
@@ -58,9 +58,6 @@ def _get_content(self):
5858
result['def'] = u'<ul>' + u''.join(s for s in l) + u'</ul>'
5959

6060
return self.cache_this(result)
61-
62-
def _get_field(self, key, default=u''):
63-
return self.cache_result(key) if self.cached(key) else self._get_content().get(key, default)
6461

6562
@with_styles(need_wrap_css=True, cssfile='_cambridge.css')
6663
def _css(self, val):
@@ -79,22 +76,8 @@ def fld_phonetic_uk(self):
7976
def _fld_mp3(self, fld):
8077
audio_url = self._get_field('pronunciation')[fld]
8178
if cambridge_download_mp3 and audio_url:
82-
filename = u'_cambridge_{}_.mp3'.format(self.word)
83-
hex_digest = sha1(
84-
self.word.encode('utf-8') if isinstance(self.word, unicode)
85-
else self.word
86-
).hexdigest().lower()
87-
assert len(hex_digest) == 40, "unexpected output from hash library"
88-
filename = '.'.join([
89-
'-'.join([
90-
self.unique.lower(
91-
), hex_digest[:8], hex_digest[8:16],
92-
hex_digest[16:24], hex_digest[24:32], hex_digest[32:],
93-
]),
94-
'mp3',
95-
])
96-
97-
if filename and self.net_download(filename, audio_url):
79+
filename = get_hex_name(self.unique.lower(), audio_url, 'mp3')
80+
if os.path.exists(filename) or self.net_download(filename, audio_url):
9881
return self.get_anki_label(filename, 'audio')
9982
return ''
10083

0 commit comments

Comments
 (0)