diff --git a/lib/words.py b/lib/words.py new file mode 100644 index 0000000..623290e --- /dev/null +++ b/lib/words.py @@ -0,0 +1,144 @@ +import json +import requests + +from PyQt6.QtSql import QSqlQuery +from typing import Type, Self, Dict, Any, Optional + +from lib import query_error + +API = "https://api.dictionaryapi.dev/api/v2/entries/en/{word}" +MWAPI = "https://www.dictionaryapi.com/api/v3/references/collegiate/json/{word}?key=51d9df34-ee13-489e-8656-478c215e846c" + +class Word: + _instance = None + _words: Dict[str,str] = {} + _current: Optional[Dict[str,Any]] = None + + def __new__(cls: Type[Self], word:str ) -> Self: + if cls._instance: + return cls._instance + cls._instance = super(Word, cls).__new__(cls) + return cls._instance + + def __init__(self, word: str) -> None: + print(f"Word == {word}") + # + # Have we already retrieved this word? + # + try: + self._current = json.loads(self._words[word]) + return + except KeyError: + pass + query = QSqlQuery() + query.prepare("SELECT * FROM words " + "WHERE word = :word") + query.bindValue(":word", word) + if not query.exec(): + query_error(query) + if query.next(): + self._words[word] = query.value("definition") + self._current = json.loads(self._words[word]) + return + response = requests.get(MWAPI.format(word=word)) + if response.status_code != 200: + self._current = None + return + data = json.loads(response.content.decode("utf-8")) + # + # XXX - The first entry should be the correct entry. There could be more + # if there is a "hom" entry, then that will be appended to meta.id + # word = "lady", hom=1, meta.id = "lady:1"; + # + print(response.content.decode('utf-8')) + self._words[word] = json.dumps(data[0]) + self._current = data[0] + query.prepare("INSERT INTO words " + "(word, definition) " + "VALUES (:word, :definition)") + query.bindValue(":word", word) + query.bindValue(":definition", self._words[word]) + if not query.exec(): + query_error(query) + return + def get_html(self) -> str|None: + if not self._current: + return None + if "meta" in self._current.keys(): + return self.mw_html() + else: + return self.apidictionary_html() + + def mw_html(self) -> str: + + def sound_url(prs:Dict[str,Any]) -> str|None: + base = 'https://media.merriam-webster.com/audio/prons/en/us/ogg' + if 'sound' not in prs.keys(): + return None + audio = prs['sound']['audio'] + if audio.startswith('bix'): + url = base + '/bix/' + elif audio.startswith('gg'): + url = base + '/gg/' + elif audio[0] not in "abcdefghijklmnopqrstuvwxyz": + url = base + '/number/' + else: + url = base + '/' + audio[0] + '/' + url += audio + '.ogg' + return url + + def parse_sn(sn:str, old:str) -> str: + return sn + + assert self._current is not None + word = self._current['hwi']['hw'] + label = self._current['fl'] + html = f"