fix #92
This commit is contained in:
parent
ab9593074b
commit
b07d343dc3
@ -1,4 +1,4 @@
|
||||
#-*- coding:utf-8 -*-
|
||||
# -*- coding:utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2018 sthoo <sth201807@gmail.com>
|
||||
#
|
||||
@ -17,29 +17,26 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
import io
|
||||
import shutil
|
||||
import unicodedata
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
from aqt.qt import *
|
||||
from aqt.utils import showInfo
|
||||
|
||||
from ..constants import Template
|
||||
from ..context import config
|
||||
from ..service import service_pool, QueryResult, copy_static_file
|
||||
from ..libs.snowballstemmer import stemmer
|
||||
from ..service import QueryResult, copy_static_file, service_pool
|
||||
from ..service.base import LocalService
|
||||
from ..utils import wrap_css
|
||||
from ..libs.snowballstemmer import stemmer
|
||||
|
||||
|
||||
__all__ = [
|
||||
'InvalidWordException', 'update_note_fields',
|
||||
'update_note_field', 'promot_choose_css', 'add_to_tmpl',
|
||||
'query_flds', 'inspect_note'
|
||||
'InvalidWordException', 'update_note_fields', 'update_note_field',
|
||||
'promot_choose_css', 'add_to_tmpl', 'query_flds', 'inspect_note'
|
||||
]
|
||||
|
||||
|
||||
@ -127,19 +124,14 @@ def promot_choose_css(missed_css):
|
||||
if not os.path.exists(filename) and not css['file'] in checked:
|
||||
checked.add(css['file'])
|
||||
showInfo(
|
||||
Template.miss_css.format(
|
||||
dict=css['title'],
|
||||
css=css['file']
|
||||
)
|
||||
)
|
||||
Template.miss_css.format(dict=css['title'], css=css['file']))
|
||||
try:
|
||||
filepath = css['dict_path'][:css['dict_path'].rindex(
|
||||
os.path.sep)+1]
|
||||
filepath = css['dict_path'][:css['dict_path'].rindex(os.path.
|
||||
sep) + 1]
|
||||
filepath = QFileDialog.getOpenFileName(
|
||||
directory=filepath,
|
||||
caption=u'Choose css file',
|
||||
filter=u'CSS (*.css)'
|
||||
)
|
||||
filter=u'CSS (*.css)')
|
||||
if filepath:
|
||||
shutil.copy(filepath, filename)
|
||||
wrap_css(filename)
|
||||
@ -161,15 +153,17 @@ def add_to_tmpl(note, **kwargs):
|
||||
if js and js.strip():
|
||||
addings = js.strip()
|
||||
if addings not in afmt:
|
||||
if not addings.startswith(u'<script') and not addings.endswith(u'/script>'):
|
||||
addings = u'\n<script type="text/javascript">\n{}\n</script>'.format(addings)
|
||||
if not addings.startswith(u'<script') and not addings.endswith(
|
||||
u'/script>'):
|
||||
addings = u'\n<script type="text/javascript">\n{}\n</script>'.format(
|
||||
addings)
|
||||
afmt += addings
|
||||
if jsfile:
|
||||
#new_jsfile = u'_' + \
|
||||
# jsfile if not jsfile.startswith(u'_') else jsfile
|
||||
#copy_static_file(jsfile, new_jsfile)
|
||||
#addings = u'\r\n<script src="{}"></script>'.format(new_jsfile)
|
||||
#afmt += addings
|
||||
# new_jsfile = u'_' + \
|
||||
# jsfile if not jsfile.startswith(u'_') else jsfile
|
||||
# copy_static_file(jsfile, new_jsfile)
|
||||
# addings = u'\r\n<script src="{}"></script>'.format(new_jsfile)
|
||||
# afmt += addings
|
||||
jsfile = jsfile if isinstance(jsfile, list) else [jsfile]
|
||||
for fn in jsfile:
|
||||
addings = '''
|
||||
@ -204,17 +198,17 @@ def query_flds(note, fileds=None):
|
||||
continue
|
||||
if i == len(note.fields):
|
||||
break
|
||||
#ignore field
|
||||
# ignore field
|
||||
ignore = each.get('ignore', False)
|
||||
if ignore:
|
||||
continue
|
||||
#skip valued
|
||||
# skip valued
|
||||
skip = each.get('skip_valued', False)
|
||||
if skip and len(note.fields[i]) != 0:
|
||||
continue
|
||||
#cloze
|
||||
# cloze
|
||||
cloze = each.get('cloze_word', False)
|
||||
#normal
|
||||
# normal
|
||||
dict_unique = each.get('dict_unique', '').strip()
|
||||
dict_fld_ord = each.get('dict_fld_ord', -1)
|
||||
fld_ord = each.get('fld_ord', -1)
|
||||
@ -227,9 +221,9 @@ def query_flds(note, fileds=None):
|
||||
services[dict_unique] = s
|
||||
if s and s.support:
|
||||
tasks.append({
|
||||
'k': dict_unique,
|
||||
'k': dict_unique,
|
||||
'w': word,
|
||||
'f': dict_fld_ord,
|
||||
'f': dict_fld_ord,
|
||||
'i': fld_ord,
|
||||
'cloze': cloze,
|
||||
})
|
||||
@ -237,17 +231,17 @@ def query_flds(note, fileds=None):
|
||||
success_num = 0
|
||||
result = defaultdict(QueryResult)
|
||||
for task in tasks:
|
||||
#try:
|
||||
service = services.get(task['k'], None)
|
||||
qr = service.active(task['f'], task['w'])
|
||||
if qr:
|
||||
if task['cloze']:
|
||||
qr['result'] = cloze_deletion(qr['result'], word)
|
||||
result.update({task['i']: qr})
|
||||
success_num += 1
|
||||
#except:
|
||||
# showInfo(_("NO_QUERY_WORD"))
|
||||
# pass
|
||||
try:
|
||||
service = services.get(task['k'], None)
|
||||
qr = service.active(task['f'], task['w'])
|
||||
if qr:
|
||||
if task['cloze']:
|
||||
qr['result'] = cloze_deletion(qr['result'], word)
|
||||
result.update({task['i']: qr})
|
||||
success_num += 1
|
||||
except Exception as e:
|
||||
print(_("NO_QUERY_WORD"), e)
|
||||
pass
|
||||
|
||||
missed_css = list()
|
||||
for service in services.values():
|
||||
@ -284,13 +278,15 @@ def cloze_deletion(text, cloze):
|
||||
continue
|
||||
word = text[s:e]
|
||||
if _stemmer.stemWord(word).lower() == term:
|
||||
l = len(cloze)
|
||||
ln = len(cloze)
|
||||
w = word
|
||||
if w[:l].lower() == cloze.lower():
|
||||
e = s + l
|
||||
w = word[:l]
|
||||
result = result[:s+offset] + (config.cloze_str % w) + result[e+offset:]
|
||||
offset += len(config.cloze_str)-2
|
||||
if w[:ln].lower() == cloze.lower():
|
||||
e = s + ln
|
||||
w = word[:ln]
|
||||
result = result[:s + offset] + (
|
||||
config.cloze_str % w) + result[e + offset:]
|
||||
offset += len(config.cloze_str) - 2
|
||||
return result
|
||||
|
||||
|
||||
_stemmer = stemmer('english')
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#-*- coding:utf-8 -*-
|
||||
# -*- coding:utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2018 sthoo <sth201807@gmail.com>
|
||||
#
|
||||
@ -19,6 +19,7 @@
|
||||
|
||||
import inspect
|
||||
import os
|
||||
import random
|
||||
# use ntpath module to ensure the windows-style (e.g. '\\LDOCE.css')
|
||||
# path can be processed on Unix platform.
|
||||
# However, anki version on mac platforms doesn't including this package?
|
||||
@ -27,32 +28,33 @@ import re
|
||||
import shutil
|
||||
import sqlite3
|
||||
import urllib
|
||||
import zlib
|
||||
from collections import defaultdict
|
||||
from functools import wraps
|
||||
from hashlib import md5, sha1
|
||||
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from aqt import mw
|
||||
from aqt.qt import QMutex, QThread
|
||||
|
||||
from ..context import config
|
||||
from ..lang import _cl
|
||||
from ..libs import MdxBuilder, StardictBuilder
|
||||
from ..utils import MapDict, wrap_css
|
||||
|
||||
try:
|
||||
import urllib2
|
||||
except:
|
||||
except Exception:
|
||||
import urllib.request as urllib2
|
||||
|
||||
import zlib
|
||||
import random
|
||||
from collections import defaultdict
|
||||
from functools import wraps
|
||||
from hashlib import md5
|
||||
from hashlib import sha1
|
||||
|
||||
try:
|
||||
from cookielib import CookieJar
|
||||
except:
|
||||
except Exception:
|
||||
from http.cookiejar import CookieJar
|
||||
|
||||
from aqt import mw
|
||||
from aqt.qt import QThread, QMutex
|
||||
from bs4 import BeautifulSoup
|
||||
from ..context import config
|
||||
from ..libs import MdxBuilder, StardictBuilder
|
||||
from ..utils import MapDict, wrap_css
|
||||
from ..lang import _cl
|
||||
|
||||
try:
|
||||
import threading as _threading
|
||||
@ -69,18 +71,14 @@ __all__ = [
|
||||
def get_hex_name(prefix, val, suffix):
|
||||
''' get sha1 hax name '''
|
||||
hex_digest = sha1(val.encode('utf-8')).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,
|
||||
])
|
||||
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):
|
||||
"""
|
||||
register the dict service with a labels, which will be shown in the dicts list.
|
||||
@ -120,6 +118,8 @@ def export(labels):
|
||||
export.EXPORT_INDEX += 1
|
||||
return _deco
|
||||
return _with
|
||||
|
||||
|
||||
export.EXPORT_INDEX = 0
|
||||
|
||||
|
||||
@ -181,8 +181,9 @@ def with_styles(**styles):
|
||||
return _deco
|
||||
return _with
|
||||
|
||||
# bs4 threading lock, overload protection
|
||||
_BS_LOCKS = [_threading.Lock(), _threading.Lock()]
|
||||
|
||||
_BS_LOCKS = [_threading.Lock(), _threading.Lock()] # bs4 threading lock, overload protection
|
||||
|
||||
|
||||
def parse_html(html):
|
||||
'''
|
||||
@ -238,6 +239,7 @@ class Service(object):
|
||||
@property
|
||||
def unique(self):
|
||||
return self._unique
|
||||
|
||||
@unique.setter
|
||||
def unique(self, value):
|
||||
self._unique = value
|
||||
@ -326,7 +328,7 @@ class WebService(Service):
|
||||
if response.info().get('Content-Encoding') == 'gzip':
|
||||
data = zlib.decompress(data, 16 + zlib.MAX_WBITS)
|
||||
return data
|
||||
except:
|
||||
except Exception:
|
||||
return u''
|
||||
|
||||
@classmethod
|
||||
@ -340,7 +342,7 @@ class WebService(Service):
|
||||
'(KHTML, like Gecko) Chrome/31.0.1623.0 Safari/537.36'
|
||||
}).content)
|
||||
return True
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
class TinyDownloadError(ValueError):
|
||||
@ -434,7 +436,7 @@ class WebService(Service):
|
||||
try:
|
||||
value_error.payload = response.read()
|
||||
response.close()
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
raise value_error
|
||||
|
||||
@ -475,7 +477,7 @@ class WebService(Service):
|
||||
f.write(payload)
|
||||
f.close()
|
||||
return True
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
@ -516,7 +518,7 @@ class LocalService(Service):
|
||||
def _get_builer(key, func=None):
|
||||
LocalService._mutex_builder.lock()
|
||||
key = md5(str(key).encode('utf-8')).hexdigest()
|
||||
if not func is None:
|
||||
if not(func is None):
|
||||
if not LocalService._mdx_builders[key]:
|
||||
worker = _DictBuildWorker(func)
|
||||
worker.start()
|
||||
@ -582,21 +584,22 @@ class MdxService(LocalService):
|
||||
jsfile = re.findall(r'<script .*?src=[\'\"](.+?)[\'\"]', html, re.DOTALL)
|
||||
return QueryResult(result=html, js=u'\n'.join(js), jsfile=jsfile)
|
||||
|
||||
|
||||
def _get_definition_mdx(self):
|
||||
"""according to the word return mdx dictionary page"""
|
||||
content = self.builder.mdx_lookup(self.word, ignorecase=config.ignore_mdx_wordcase)
|
||||
ignorecase = config.ignore_mdx_wordcase and (self.word != self.word.lower() or self.word != self.word.upper())
|
||||
content = self.builder.mdx_lookup(self.word, ignorecase=ignorecase)
|
||||
str_content = ""
|
||||
if len(content) > 0:
|
||||
for c in content:
|
||||
str_content += c.replace("\r\n","").replace("entry:/","")
|
||||
str_content += c.replace("\r\n", "").replace("entry:/", "")
|
||||
|
||||
return str_content
|
||||
|
||||
def _get_definition_mdd(self, word):
|
||||
"""according to the keyword(param word) return the media file contents"""
|
||||
word = word.replace('/', '\\')
|
||||
content = self.builder.mdd_lookup(word, ignorecase=config.ignore_mdx_wordcase)
|
||||
ignorecase = config.ignore_mdx_wordcase and (word != word.lower() or word != word.upper())
|
||||
content = self.builder.mdd_lookup(word, ignorecase=ignorecase)
|
||||
if len(content) > 0:
|
||||
return [content[0]]
|
||||
else:
|
||||
@ -620,7 +623,7 @@ class MdxService(LocalService):
|
||||
f.write(bytes_list[0])
|
||||
return savepath
|
||||
except sqlite3.OperationalError as e:
|
||||
#showInfo(str(e))
|
||||
print(e)
|
||||
pass
|
||||
return ''
|
||||
|
||||
@ -677,7 +680,7 @@ class MdxService(LocalService):
|
||||
# folder first, and it will also execute the wrap process to generate
|
||||
# the desired file.
|
||||
if not os.path.exists(cssfile):
|
||||
css_src = self.dict_path.replace(self._filename+u'.mdx', f)
|
||||
css_src = self.dict_path.replace(self._filename + u'.mdx', f)
|
||||
if os.path.exists(css_src):
|
||||
shutil.copy(css_src, cssfile)
|
||||
else:
|
||||
@ -700,17 +703,19 @@ class MdxService(LocalService):
|
||||
if os.path.exists(savepath):
|
||||
return savepath
|
||||
try:
|
||||
src_fn = self.dict_path.replace(self._filename+u'.mdx', basename)
|
||||
src_fn = self.dict_path.replace(self._filename + u'.mdx', basename)
|
||||
if os.path.exists(src_fn):
|
||||
shutil.copy(src_fn, savepath)
|
||||
return savepath
|
||||
else:
|
||||
bytes_list = self.builder.mdd_lookup(filepath_in_mdx, ignorecase=config.ignore_mdx_wordcase)
|
||||
ignorecase = config.ignore_mdx_wordcase and (filepath_in_mdx != filepath_in_mdx.lower() or filepath_in_mdx != filepath_in_mdx.upper())
|
||||
bytes_list = self.builder.mdd_lookup(filepath_in_mdx, ignorecase=ignorecase)
|
||||
if bytes_list:
|
||||
with open(savepath, 'wb') as f:
|
||||
f.write(bytes_list[0])
|
||||
return savepath
|
||||
except sqlite3.OperationalError as e:
|
||||
print('save default file error', e)
|
||||
pass
|
||||
|
||||
def save_media_files(self, data):
|
||||
@ -752,7 +757,7 @@ class StardictService(LocalService):
|
||||
dict_path,
|
||||
service_wrap(StardictBuilder, dict_path, in_memory=False)
|
||||
)
|
||||
#if self.builder:
|
||||
# if self.builder:
|
||||
# self.builder.get_header()
|
||||
|
||||
@staticmethod
|
||||
@ -772,7 +777,7 @@ class StardictService(LocalService):
|
||||
|
||||
@export([u'默认', u'Default'])
|
||||
def fld_whole(self):
|
||||
#self.builder.check_build()
|
||||
# self.builder.check_build()
|
||||
try:
|
||||
result = self.builder[self.word]
|
||||
result = result.strip().replace('\r\n', '<br />')\
|
||||
@ -788,7 +793,7 @@ class QueryResult(MapDict):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(QueryResult, self).__init__(*args, **kwargs)
|
||||
# avoid return None
|
||||
if self['result'] == None:
|
||||
if self['result'] is None:
|
||||
self['result'] = ""
|
||||
|
||||
def set_styles(self, **kwargs):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user