wordreference: fix various issues and format code
This commit is contained in:
parent
b76088ca77
commit
24d24ef233
|
@ -20,10 +20,12 @@ from shutil import which
|
||||||
import requests
|
import requests
|
||||||
from bs4 import BeautifulSoup, NavigableString
|
from bs4 import BeautifulSoup, NavigableString
|
||||||
|
|
||||||
|
|
||||||
class DummyColorama:
|
class DummyColorama:
|
||||||
def __getattr__(self, _):
|
def __getattr__(self, _):
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
HAS_COLORAMA = True
|
HAS_COLORAMA = True
|
||||||
Fore = None
|
Fore = None
|
||||||
Style = None
|
Style = None
|
||||||
|
@ -39,12 +41,14 @@ URL = "https://www.wordreference.com"
|
||||||
|
|
||||||
MeaningType = enum.Enum("MeaningType", "MAIN ADD COMPOUND")
|
MeaningType = enum.Enum("MeaningType", "MAIN ADD COMPOUND")
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
@dataclasses.dataclass
|
||||||
class Translation:
|
class Translation:
|
||||||
desc: str
|
desc: str
|
||||||
nature: str
|
nature: str
|
||||||
precision: str = ""
|
precision: str = ""
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
@dataclasses.dataclass
|
||||||
class Meaning:
|
class Meaning:
|
||||||
ident: str
|
ident: str
|
||||||
|
@ -55,6 +59,7 @@ class Meaning:
|
||||||
ex: list[str] = dataclasses.field(default_factory=list)
|
ex: list[str] = dataclasses.field(default_factory=list)
|
||||||
trans: list[Translation] = dataclasses.field(default_factory=list)
|
trans: list[Translation] = dataclasses.field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
ap = argparse.ArgumentParser()
|
ap = argparse.ArgumentParser()
|
||||||
ap.add_argument("lang", help="4-letter code, e.g. 'fren' or 'enfr'")
|
ap.add_argument("lang", help="4-letter code, e.g. 'fren' or 'enfr'")
|
||||||
|
@ -82,6 +87,7 @@ def main():
|
||||||
else:
|
else:
|
||||||
get_translations(lang, words)
|
get_translations(lang, words)
|
||||||
|
|
||||||
|
|
||||||
def get_translations(lang, words):
|
def get_translations(lang, words):
|
||||||
"""Get translations for these words."""
|
"""Get translations for these words."""
|
||||||
encoded_words = urllib.parse.quote(words)
|
encoded_words = urllib.parse.quote(words)
|
||||||
|
@ -116,8 +122,9 @@ def get_translations(lang, words):
|
||||||
for meaning in meanings:
|
for meaning in meanings:
|
||||||
print_meaning(meaning)
|
print_meaning(meaning)
|
||||||
|
|
||||||
|
|
||||||
def parse_rows(table, meanings, mtype):
|
def parse_rows(table, meanings, mtype):
|
||||||
"""Parse all meaningful rows of this table and store results in meanings."""
|
"""Parse all good rows of this table and store results in meanings."""
|
||||||
meaning = None
|
meaning = None
|
||||||
for row in table.find_all("tr"):
|
for row in table.find_all("tr"):
|
||||||
# Discard rows that aren't meanings.
|
# Discard rows that aren't meanings.
|
||||||
|
@ -126,21 +133,32 @@ def parse_rows(table, meanings, mtype):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# New meaning start with a row that has an ID.
|
# New meaning start with a row that has an ID.
|
||||||
new_meaning_row = False
|
is_new_meaning_row = False
|
||||||
if (meaning_id := row.get("id")):
|
if (meaning_id := row.get("id")):
|
||||||
if meaning:
|
if meaning:
|
||||||
meanings.append(meaning)
|
meanings.append(meaning)
|
||||||
meaning = Meaning(ident=meaning_id, mtype=mtype)
|
meaning = Meaning(ident=meaning_id, mtype=mtype)
|
||||||
new_meaning_row = True
|
is_new_meaning_row = True
|
||||||
|
|
||||||
cells = row.find_all("td")
|
cells = row.find_all("td")
|
||||||
|
|
||||||
# Rows with 3 cells are definitions or complementary meanings.
|
# Rows with 3 cells are definitions or complementary meanings.
|
||||||
if len(cells) == 3:
|
if len(cells) == 3:
|
||||||
|
parse_common_cells(cells, meaning, is_new_meaning_row)
|
||||||
|
# Rows with 2 cells are examples.
|
||||||
|
else:
|
||||||
|
parse_example_cells(cells, meaning)
|
||||||
|
|
||||||
|
if meaning:
|
||||||
|
meanings.append(meaning)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_common_cells(cells, meaning, is_new_meaning):
|
||||||
|
"""Parse common cells: meaning, definition, translations, etc."""
|
||||||
lcell, ccell, rcell = cells
|
lcell, ccell, rcell = cells
|
||||||
|
|
||||||
# For new meanings, use the left cell info.
|
# For new meanings, use the left cell info.
|
||||||
if new_meaning_row:
|
if is_new_meaning:
|
||||||
meaning.original = lcell.strong.text
|
meaning.original = lcell.strong.text
|
||||||
if (nature_elements := lcell.em.contents):
|
if (nature_elements := lcell.em.contents):
|
||||||
meaning.nature = nature_elements[0]
|
meaning.nature = nature_elements[0]
|
||||||
|
@ -152,10 +170,11 @@ def parse_rows(table, meanings, mtype):
|
||||||
trans_desc.append(content.strip())
|
trans_desc.append(content.strip())
|
||||||
elif "POS2" not in (content.get("class") or []):
|
elif "POS2" not in (content.get("class") or []):
|
||||||
trans_desc.append(content.text)
|
trans_desc.append(content.text)
|
||||||
translation = Translation(
|
nature = ""
|
||||||
desc=" ".join(trans_desc),
|
if (nature_content := rcell.contents[-1]):
|
||||||
nature=rcell.contents[-1].contents[0],
|
if len(nature_content):
|
||||||
)
|
nature = nature_content.contents[0]
|
||||||
|
translation = Translation(desc=" ".join(trans_desc), nature=nature)
|
||||||
|
|
||||||
# Center cell mixes original description and translation info…
|
# Center cell mixes original description and translation info…
|
||||||
for child in ccell.children:
|
for child in ccell.children:
|
||||||
|
@ -170,13 +189,11 @@ def parse_rows(table, meanings, mtype):
|
||||||
meaning.desc.append(text)
|
meaning.desc.append(text)
|
||||||
meaning.trans.append(translation)
|
meaning.trans.append(translation)
|
||||||
|
|
||||||
# Rows with 2 cells are examples.
|
|
||||||
else:
|
|
||||||
example_cell = cells[-1]
|
|
||||||
meaning.ex.append(example_cell.span.text)
|
|
||||||
|
|
||||||
if meaning:
|
def parse_example_cells(cells, meaning):
|
||||||
meanings.append(meaning)
|
"""Parse cells of an example line (pretty much just the last one)."""
|
||||||
|
meaning.ex.append(cells[-1].span.text)
|
||||||
|
|
||||||
|
|
||||||
def print_meaning(meaning):
|
def print_meaning(meaning):
|
||||||
"""Print a few formatted lines for this meaning."""
|
"""Print a few formatted lines for this meaning."""
|
||||||
|
@ -197,15 +214,20 @@ def print_meaning(meaning):
|
||||||
print(first_line)
|
print(first_line)
|
||||||
# Each translation is on its own line.
|
# Each translation is on its own line.
|
||||||
for trans in meaning.trans:
|
for trans in meaning.trans:
|
||||||
print(
|
trans_line = f"— {trans.desc}"
|
||||||
f"— {trans.desc} " +
|
if trans.nature:
|
||||||
f"{Style.DIM}({trans.nature}) {trans.precision}{Style.NORMAL}")
|
trans_line += f" {Style.DIM}({trans.nature}){Style.NORMAL}"
|
||||||
|
if trans.precision:
|
||||||
|
trans_line += f" {Style.DIM}{trans.precision}{Style.NORMAL}"
|
||||||
|
print(trans_line)
|
||||||
# Show examples on different, dimmed line.
|
# Show examples on different, dimmed line.
|
||||||
for example in meaning.ex:
|
for example in meaning.ex:
|
||||||
print(f" {Style.DIM}e.g. {example}{Style.NORMAL}")
|
print(f" {Style.DIM}e.g. {example}{Style.NORMAL}")
|
||||||
|
|
||||||
|
|
||||||
AUTOCOMP_URL = f"{URL}/2012/autocomplete/autocomplete.aspx"
|
AUTOCOMP_URL = f"{URL}/2012/autocomplete/autocomplete.aspx"
|
||||||
|
|
||||||
|
|
||||||
def get_suggestions(lang, words):
|
def get_suggestions(lang, words):
|
||||||
"""Show completion suggestions for these words."""
|
"""Show completion suggestions for these words."""
|
||||||
params = {"dict": lang, "query": words}
|
params = {"dict": lang, "query": words}
|
||||||
|
|
Loading…
Reference in a new issue