This commit is contained in:
St.Huang 2019-02-10 11:44:42 +08:00
parent ab9593074b
commit b07d343dc3
2 changed files with 91 additions and 90 deletions

View File

@ -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')

View File

@ -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):