forked from johnridesabike/WordRoom
/
define.py
135 lines (119 loc) · 4.54 KB
/
define.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python3
"""This module contains the functions used for retrieving word definitions.
Outside of this module, you'll usually just call the define() function.
"""
import console
import json
import re
from urllib.error import URLError
from config import CONFIG_FILE
WORDNIK_IS_LOADED = False
def check_wordnik_key():
"""Check if the WordNik API is reachable."""
global WORDNIK_API_KEY
global WORDNIK_IS_LOADED
global wn_api
try:
with open(CONFIG_FILE, 'r') as file:
WORDNIK_API_KEY = json.load(file).get('wordnik_api_key')
WORDNIK_IS_LOADED = bool(WORDNIK_API_KEY)
except FileNotFoundError:
WORDNIK_API_KEY = None
if WORDNIK_API_KEY:
try:
wn_api = WordApi(swagger.ApiClient(WORDNIK_API_KEY,
WORDNIK_API_URL))
except NameError:
WORDNIK_IS_LOADED = False
try:
from wordnik import swagger
from wordnik.WordApi import WordApi
WORDNIK_API_URL = 'https://api.wordnik.com/v4'
check_wordnik_key()
except ImportError:
WORDNIK_IS_LOADED = False
def define(word: str):
"""Return definition and metadata for a given word.
It's returned in the following dictionary format:
{'word' : 'word',
'definitions': [{'text': 'The first definition',
'partofspeech': 'noun'},
{'definition': 'The second definition',
'text': 'verb'}],
'attribution': 'Dictionary Source, Public Domain',
'attributionUrl' : 'https://creativecommons.org/publicdomain/zero/1.0/',
'suggestions': ['suggestion one', 'suggestion two'],
'messages' : ['error message one', 'error message two']
}
"""
if WORDNIK_IS_LOADED:
data = wordnik(word)
else:
data = opted(word)
m = ['WordRoom is using a limited offline dictionary.',
'''This app is a free personal project, so I don't share my online
API access. <a href="https://developer.wordnik.com/">You can get
your own from developer.wordnik.com</a>''',
'''<a href="wordroom://-change_key">Add an API key to WordRoom
here.</a>''']
if not data['definitions']:
data['messages'] += m
data['word'] = word
return data
def wordnik(word: str):
"""Return the WordNik definition of a word.
If can't connect to WordNik API, then return opted() instead.
"""
try:
console.show_activity()
defs = wn_api.getDefinitions(word, limit=5) or []
suggs = wn_api.getWord(word, includeSuggestions=True)
console.hide_activity()
suggestions = suggs.suggestions or []
definitions = [{'text': d.text,
'partOfSpeech': d.partOfSpeech} for d in defs]
if defs:
attribution = defs[0].attributionText
attribution_url = defs[0].attributionUrl
else:
attribution = ''
attribution_url = ''
data = {'definitions': definitions,
'attribution': attribution,
'attributionUrl': attribution_url,
'suggestions': suggestions,
'messages': []}
except URLError:
data = opted(word)
data['messages'].append('''WordRoom couldn't connect to WordNik.com to
retrieve online definitions.''')
return data
opted_cache = {}
def opted(word: str):
"""Return the OPTED definition of a word."""
messages = []
alpha = re.sub('[^a-zA-Z]', '', word)[:1].lower()
if not opted_cache.get(alpha) and alpha:
try:
with open('opted/' + alpha + '.json', 'r') as f:
opted_cache[alpha] = json.load(f)
except FileNotFoundError:
opted_cache[alpha] = {}
messages.append('''WordRoom couldn't load the offline dictionary.
If you're storing WordRoom in iCloud, check that
iOS downloaded all of its files.''')
if alpha:
definitions = opted_cache[alpha].get(word) or []
else: # if the input had no ascii letters
definitions = []
if len(definitions) > 0:
attr = 'from The Online Plain Text English Dictionary, Public Domain.'
attribution_url = 'http://www.mso.anu.edu.au/%7Eralph/OPTED/index.html'
else:
attr = ''
attribution_url = ''
return {'definitions': definitions,
'attribution': attr,
'attributionUrl': attribution_url,
'suggestions': [],
'messages': messages}