Edit Book: When showing suggestions for mis-spelled words, also show suggestions from the active user created word lists

This commit is contained in:
Kovid Goyal 2015-07-22 21:59:48 +05:30
parent 313b2096c7
commit 9b96964e3d

View File

@ -6,11 +6,13 @@ from __future__ import (unicode_literals, division, absolute_import,
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
import os, glob, shutil, re import os, glob, shutil, re, sys
from collections import namedtuple from collections import namedtuple, defaultdict
from operator import attrgetter from operator import attrgetter
from itertools import chain from itertools import chain
from functools import partial
from calibre import prints
from calibre.constants import plugins, config_dir from calibre.constants import plugins, config_dir
from calibre.spell import parse_lang_code from calibre.spell import parse_lang_code
from calibre.utils.config import JSONConfig from calibre.utils.config import JSONConfig
@ -164,6 +166,7 @@ class Dictionaries(object):
self.dictionaries = {} self.dictionaries = {}
self.word_cache = {} self.word_cache = {}
self.ignored_words = set() self.ignored_words = set()
self.added_user_words = {}
try: try:
self.default_locale = parse_lang_code(get_lang()) self.default_locale = parse_lang_code(get_lang())
except ValueError: except ValueError:
@ -186,6 +189,14 @@ class Dictionaries(object):
ans = get_dictionary(locale) ans = get_dictionary(locale)
if ans is not None: if ans is not None:
ans = load_dictionary(ans) ans = load_dictionary(ans)
for ud in self.active_user_dictionaries:
for word, langcode in ud.words:
if langcode == locale.langcode:
try:
ans.obj.add(word)
except Exception:
# not critical since all it means is that the word wont show up in suggestions
prints('Failed to add the word %r to the dictionary for %s' % (word, locale), file=sys.stderr)
self.dictionaries[locale] = ans self.dictionaries[locale] = ans
return ans return ans
@ -227,6 +238,18 @@ class Dictionaries(object):
def save_user_dictionaries(self): def save_user_dictionaries(self):
dprefs['user_dictionaries'] = [d.serialize() for d in self.all_user_dictionaries] dprefs['user_dictionaries'] = [d.serialize() for d in self.all_user_dictionaries]
def add_user_words(self, words, langcode):
for d in self.dictionaries.itervalues():
if d.primary_locale.langcode == langcode:
for word in words:
d.obj.add(word)
def remove_user_words(self, words, langcode):
for d in self.dictionaries.itervalues():
if d.primary_locale.langcode == langcode:
for word in words:
d.obj.remove(word)
def add_to_user_dictionary(self, name, word, locale): def add_to_user_dictionary(self, name, word, locale):
ud = self.user_dictionary(name) ud = self.user_dictionary(name)
if ud is None: if ud is None:
@ -234,8 +257,10 @@ class Dictionaries(object):
wl = len(ud.words) wl = len(ud.words)
if isinstance(word, (set, frozenset)): if isinstance(word, (set, frozenset)):
ud.words |= word ud.words |= word
self.add_user_words(word, locale.langcode)
else: else:
ud.words.add((word, locale.langcode)) ud.words.add((word, locale.langcode))
self.add_user_words((word,), locale.langcode)
if len(ud.words) > wl: if len(ud.words) > wl:
self.save_user_dictionaries() self.save_user_dictionaries()
try: try:
@ -255,21 +280,26 @@ class Dictionaries(object):
if changed: if changed:
self.word_cache.pop((word, locale), None) self.word_cache.pop((word, locale), None)
self.save_user_dictionaries() self.save_user_dictionaries()
self.remove_user_words((word,), locale.langcode)
return changed return changed
def remove_from_user_dictionary(self, name, words): def remove_from_user_dictionary(self, name, words):
changed = False changed = False
removals = defaultdict(set)
keys = [(w, l.langcode) for w, l in words] keys = [(w, l.langcode) for w, l in words]
for d in self.all_user_dictionaries: for d in self.all_user_dictionaries:
if d.name == name: if d.name == name:
for key in keys: for key in keys:
if key in d.words: if key in d.words:
d.words.discard(key) d.words.discard(key)
removals[key[1]].add(key[0])
changed = True changed = True
if changed: if changed:
for key in words: for key in words:
self.word_cache.pop(key, None) self.word_cache.pop(key, None)
self.save_user_dictionaries() for langcode, words in removals.iteritems():
self.remove_user_words(words, langcode)
self.save_user_dictionaries()
return changed return changed
def word_in_user_dictionary(self, word, locale): def word_in_user_dictionary(self, word, locale):
@ -366,9 +396,15 @@ class Dictionaries(object):
return ans return ans
if __name__ == '__main__': def test_dictionaries():
dictionaries = Dictionaries() dictionaries = Dictionaries()
dictionaries.initialize() dictionaries.initialize()
print (dictionaries.recognized('recognized', parse_lang_code('en'))) eng = parse_lang_code('en')
print (dictionaries.suggestions('ade-quately', parse_lang_code('en'))) rec = partial(dictionaries.recognized, locale=eng)
print (dictionaries.suggestions('magic.wand', parse_lang_code('en'))) sg = partial(dictionaries.suggestions, locale=eng)
assert rec('recognized')
assert 'adequately' in sg('ade-quately')
assert 'magic. Wand' in sg('magic.wand')
if __name__ == '__main__':
test_dictionaries()