forked from charlesmadere/CynanBotCommon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathenEsDictionary.py
120 lines (89 loc) · 4.57 KB
/
enEsDictionary.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
import locale
import urllib
from json.decoder import JSONDecodeError
from typing import List
import requests
from requests import ConnectionError, HTTPError, Timeout
from urllib3.exceptions import MaxRetryError, NewConnectionError
import CynanBotCommon.utils as utils
class EnEsDictionaryResult():
def __init__(self, definitions: List[str], word: str):
if not utils.hasItems(definitions):
raise ValueError(f'definitions argument is malformed: \"{definitions}\"')
elif not utils.isValidStr(word):
raise ValueError(f'word argument is malformed: \"{word}\"')
self.__definitions = definitions
self.__word = word
def getDefinitions(self) -> List[str]:
return self.__definitions
def getWord(self) -> str:
return self.__word
def toStr(self, delimiter: str = ', ') -> str:
if delimiter is None:
raise ValueError(f'delimiter argument is malformed: \"{delimiter}\"')
definitionsJoin = delimiter.join(self.__definitions)
return f'{self.__word} — {definitionsJoin}'
class EnEsDictionary():
def __init__(
self,
merriamWebsterApiKey: str,
definitionsMaxSize: int = 3
):
if not utils.isValidStr(merriamWebsterApiKey):
raise ValueError(f'merriamWebsterApiKey argument is malformed: \"{merriamWebsterApiKey}\"')
elif not utils.isValidNum(definitionsMaxSize) or definitionsMaxSize < 1:
raise ValueError(f'definitionsMaxSize argument is malformed: \"{definitionsMaxSize}\"')
self.__definitionsMaxSize = definitionsMaxSize
self.__merriamWebsterApiKey = merriamWebsterApiKey
def search(self, query: str) -> EnEsDictionaryResult:
if not utils.isValidStr(query):
raise ValueError(f'query argument is malformed: \"{query}\"')
query = query.strip()
print(f'Looking up \"{query}\"... ({utils.getNowTimeText()})')
encodedQuery = urllib.parse.quote(query)
requestUrl = 'https://www.dictionaryapi.com/api/v3/references/spanish/json/{}?key={}'.format(
encodedQuery, self.__merriamWebsterApiKey)
rawResponse = None
try:
rawResponse = requests.get(url = requestUrl, timeout = utils.getDefaultTimeout())
except (ConnectionError, HTTPError, MaxRetryError, NewConnectionError, Timeout) as e:
print(f'Exception occurred when attempting to search Merriam Webster for \"{query}\": {e}')
raise RuntimeError(f'Exception occurred when attempting to search Merriam Webster for \"{query}\": {e}')
jsonResponse = None
try:
jsonResponse = rawResponse.json()
except JSONDecodeError as e:
print(f'Exception occurred when attempting to decode Merriam Webster\'s response into JSON for \"{query}\": {e}')
raise RuntimeError(f'Exception occurred when attempting to decode Merriam Webster\'s response into JSON for \"{query}\": {e}')
if not utils.hasItems(jsonResponse):
print(f'jsonResponse for \"{query}\" has no definitions: {jsonResponse}')
raise ValueError(f'jsonResponse \"{query}\" has no definitions: {jsonResponse}')
definitions = list()
for entry in jsonResponse:
definition = None
if isinstance(entry, str):
definition = entry
elif not entry['meta'].get('offensive', True) and utils.hasItems(entry['shortdef']):
definition = entry['shortdef'][0]
definition = utils.cleanStr(definition)
if not utils.isValidStr(definition):
continue
index = 0
add = True
while (index < len(definitions) and add):
if definitions[index].lower() == definition.lower():
add = False
index = index + 1
if add:
number = locale.format_string("%d", len(definitions) + 1, grouping = True)
definitions.append(f'#{number} {definition}')
if len(definitions) >= self.__definitionsMaxSize:
# keep from adding tons of definitions
break
if not utils.hasItems(definitions):
print(f'Unable to find any viable definitions for \"{query}\"')
raise ValueError(f'Unable to find any viable definitions for \"{query}\"')
return EnEsDictionaryResult(
definitions = definitions,
word = query
)