refactor: re-organize gitignore

* chore(pylint): enable pylint rule and reorganize gitignore

* chore(pylint): fix pylint line-too-long pylint rule

* improv: fix formatting issues

* fix: fix pytest docstrings

* improv: remove trailing disabled pylint error

Co-authored-by: Daniel Kantor <git@daniel-kantor.com>
This commit is contained in:
Amine Louzar 2022-02-21 08:23:50 +01:00 committed by GitHub
parent 9c27cfa76d
commit 7d9d996176
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 146 additions and 71 deletions

94
.gitignore vendored
View File

@ -1,48 +1,78 @@
.DS_Store
# IDE
**/.DS_Store
**/.vscode
**/.idea/codeStyles/codeStyleConfig.xml
**/.idea/jsLinters/eslint.xml
**/.idea/LibreLingo.iml
**/.idea/misc.xml
**/.idea/modules.xml
**/.idea/codeStyles/Project.xml
**/.idea/inspectionProfiles/Project_Default.xml
**/.idea/vcs.xml
**/.idea/workspace.xml
**/.vim
# Dependencies
/node_modules/
**/node_modules/
/src/node_modules/@sapper/
.venv/
.env
/apps/*/poetry.lock
# Development
yarn-error.log
apps/web/cypress/screenshots/
.yarn
.yarnrc
*.pyc
/apps/librelingo_json_export/profile.png
profile.dat
# Static files
/apps/web/__sapper__/
/static/files
staticfiles/
apps/web/static/files/noto-*
# Cypress files
.nyc_output/
cypress-coverage/
jest-coverage/
cypress/videos
.venv/
/course_editor/db.sqlite3
*.pyc
.env
/db.sqlite3
/src/audios_to_fetch.csv
localData/
staticfiles/
git_stats/
/.idea/codeStyles/codeStyleConfig.xml
/.idea/jsLinters/eslint.xml
/.idea/LibreLingo.iml
/.idea/misc.xml
/.idea/modules.xml
/.idea/codeStyles/Project.xml
/.idea/inspectionProfiles/Project_Default.xml
/.idea/vcs.xml
/.idea/workspace.xml
apps/web/static/files/noto-*
**/cypress/videos
apps/web/cypress/screenshots/
apps/web/cypress/screenshots/**/__tkey-*.png
.vim
**/coverage/
# Build
apps/librelingo_tools/dist
**/dist/
*.tsbuildinfo
report.*.*.json
/coverage/
# Documentation
apps/docs/build/
report.*.*.json
*.tsbuildinfo
__sapper__
.yarn
.yarnrc
# Stats
git_stats/
# Data
/course_editor/db.sqlite3
/db.sqlite3
/src/audios_to_fetch.csv
/apps/librelingo_json_export/profile.png
localData/
# Courses
/apps/web/src/courses/*-*
/courses/*-*
profile.dat
/apps/librelingo_json_export/profile.png
/apps/*/poetry.lock
.vscode/

View File

@ -1,7 +1,9 @@
from pathlib import Path
import collections
from pathlib import Path
import click # type: ignore
from librelingo_yaml_loader import load_course
from librelingo_audios.update_audios import update_audios_for_course
Settings = collections.namedtuple(
@ -32,7 +34,8 @@ def ensure_output_directory(output_path, settings):
"--destructive/--non-destructive",
default=DEFAULT_SETTINGS.destructive,
show_default=True,
help="--destructive deletes existing audio and re-generates from scratch. --non-destructive performs an iterative update.",
help="--destructive deletes existing audio and re-generates from scratch."
"--non-destructive performs an iterative update.",
)
def _command(input_path: str, output_path: str, course_name: str, dry_run, destructive):
"""

View File

@ -1,12 +1,14 @@
from pathlib import Path
import subprocess
import json
import random
import subprocess
from pathlib import Path
from typing import Set, Union
from librelingo_audios.functions import list_required_audios
from librelingo_types.data_types import Course, PhraseIdentity
from librelingo_utils import audio_id
from librelingo_audios.functions import list_required_audios
def update_audios_for_course(
output_path: str, course_name: str, course: Course, settings
@ -106,11 +108,13 @@ def _generate_audio_with_tts(
if settings.dry_run:
print(
f"Would generate {destination_path} using {chosen_tts_settings.voice} {chosen_tts_settings.engine}"
f"Would generate {destination_path} "
f"using {chosen_tts_settings.voice} {chosen_tts_settings.engine}"
)
else:
print(
f"Generating {destination_path} using {chosen_tts_settings.voice} {chosen_tts_settings.engine}"
f"Generating {destination_path} "
f"using {chosen_tts_settings.voice} {chosen_tts_settings.engine}"
)
# This is where more more TTS providers would be added with an if statement.
# For now there is only Polly.

View File

@ -50,6 +50,7 @@ def terminal(tmp_path, capsys):
return SimpleNamespace(
assert_output_matches=assert_output_matches,
# pylint: disable=line-too-long
message=SimpleNamespace(
**{
"generating": lambda text: f"Generating {tmp_path / _mock_audio_file_for_text(text)} using Lupe standard",

View File

@ -1,7 +1,8 @@
"""
This package contains fake data for testing LibreLingo-related packages.
The fake data is returned using the types from [librelingo-types](https://pypi.org/project/librelingo-types/).
The fake data is returned using the types from
[librelingo-types](https://pypi.org/project/librelingo-types/).
## Usage
```python
@ -13,7 +14,8 @@ fakes.course2 # This is another Course() object
fakes.courseEmpty # This is an empty course
```
For the full list of fakes, use the autocomplete or check out the [this file](https://github.com/LibreLingo/LibreLingo/blob/main/apps/librelingo_fakes/librelingo_fakes/fakes.py).
# pylint: disable=line-too-long
For the full list of fakes, use the autocomplete or check out[this file](https://github.com/LibreLingo/LibreLingo/blob/main/apps/librelingo_fakes/librelingo_fakes/fakes.py).
### Customizing fakes
@ -29,20 +31,23 @@ fake_course = fakes.customize(fakes.course1, modules=[
"""
from pathlib import Path
import random
from collections import namedtuple
from librelingo_types import Course
from librelingo_types import Module
from librelingo_types import Skill
from librelingo_types import Phrase
from librelingo_types import Word
from librelingo_types import License
from librelingo_types import Language
from librelingo_types import DictionaryItem
from librelingo_types import Settings
from librelingo_types import AudioSettings
from librelingo_types import TextToSpeechSettings
from pathlib import Path
from librelingo_types import (
AudioSettings,
Course,
DictionaryItem,
Language,
License,
Module,
Phrase,
Settings,
Skill,
TextToSpeechSettings,
Word,
)
challenge1 = "challenge1"
challenge2 = "challenge2"

View File

@ -50,7 +50,8 @@ def _define_word(course: Course, word: Word, is_in_target_language):
else course.source_language.name
)
raise ValueError(
f'The {language_name} word "{word}" does not have a definition. Please add it to the mini-dictionary.'
f'The {language_name} word "{word}" does not have a definition.'
"Please add it to the mini-dictionary."
)

View File

@ -9,7 +9,8 @@ from librelingo_types import DictionaryItem
def test_definition_not_found():
word = str(fakes.fake_value())
pattern = re.escape(
f'The another language word "{word}" does not have a definition. Please add it to the mini-dictionary.'
f'The another language word "{word}" does not have a definition.'
"Please add it to the mini-dictionary."
)
with pytest.raises(ValueError, match=pattern):
assert _define_word(fakes.course1, word, is_in_target_language=False) is True

View File

@ -27,6 +27,7 @@ def test__get_course_data_return_value():
"languageName": "my language",
"languageCode": "de",
"specialCharacters": ["", "ß"],
# pylint: disable=line-too-long
"repositoryURL": "https://github.com/kantord/LibreLingo/tree/main/courses/spanish-from-english",
"license": {
"name": {

View File

@ -28,6 +28,7 @@ class TextToSpeechSettings(
pass
# pylint: disable=line-too-long
class AudioSettings(
namedtuple(
"AudioSettings",
@ -78,6 +79,7 @@ class HunspellSettings(
pass
# pylint: disable=line-too-long
class Settings(
namedtuple(
"Settings",
@ -154,6 +156,7 @@ class Language(namedtuple("Language", ["name", "code"])):
pass
# pylint: disable=line-too-long
class License(
namedtuple(
"License",
@ -244,6 +247,7 @@ class Skill(
pass
# pylint: disable=line-too-long
class Word(
namedtuple(
"Word",

View File

@ -26,7 +26,8 @@ def _validate_phrase_in_target_language(phrase, course):
for variant_subword in variant.split():
if not course.settings.hunspell.target_language.spell(variant_subword):
raise RuntimeError(
f'The {course.target_language.name} phrase "{variant}" is misspelled. The word "{variant_subword}" is unknown.'
f'The {course.target_language.name} phrase "{variant}" is misspelled.'
f'The word "{variant_subword}" is unknown.'
)
@ -35,7 +36,8 @@ def _validate_phrase_in_source_language(phrase, course):
for variant_subword in variant.split():
if not course.settings.hunspell.source_language.spell(variant_subword):
raise RuntimeError(
f'The {course.source_language.name} phrase "{variant}" is misspelled. The word "{variant_subword}" is unknown.'
f'The {course.source_language.name} phrase "{variant}" is misspelled.'
f'The word "{variant_subword}" is unknown.'
)

View File

@ -150,7 +150,9 @@ def _convert_word(raw_word) -> Word:
"""
Converts a YAML word definition into a Word() object
>>> _convert_word({'Images': ["abc"], 'Word': "cat", 'Synonyms': ["kitten"], 'Translation': "gato"})
>>> _convert_word(
... {'Images': ["abc"], 'Word': "cat", 'Synonyms': ["kitten"], 'Translation': "gato"}
... )
Word(in_target_language=['cat', 'kitten'], in_source_language=['gato'], pictures=['abc'])
"""
return Word(
@ -162,6 +164,7 @@ def _convert_word(raw_word) -> Word:
)
# pylint: disable=line-too-long
def _convert_words(raw_words: List[Word]) -> List[Word]:
"""
Converts each YAML word definition into Word() objects
@ -183,6 +186,7 @@ def _convert_words(raw_words: List[Word]) -> List[Word]:
return list(map(_convert_word, raw_words))
# pylint: disable=line-too-long
def _convert_phrase(raw_phrase) -> Phrase:
"""
Converts a YAML phrase definition into a Phrase() object

View File

@ -893,7 +893,8 @@ def test_load_skill_complains_about_misspelled_phrase_in_target_language(load_ya
),
)
expected_error = re.escape(
f'The {fake_course.target_language.name} phrase "{fake_phrase}" is misspelled. The word "{fake_word}" is unknown.'
f'The {fake_course.target_language.name} phrase "{fake_phrase}" is misspelled.'
f'The word "{fake_word}" is unknown.'
)
with pytest.raises(RuntimeError, match=expected_error):
_load_skill(random_path, fake_course)
@ -927,7 +928,8 @@ def test_load_skill_complains_about_misspelled_phrase_in_source_language(load_ya
),
)
expected_error = re.escape(
f'The {fake_course.source_language.name} phrase "{fake_phrase}" is misspelled. The word "{fake_word}" is unknown.'
f'The {fake_course.source_language.name} phrase "{fake_phrase}" is misspelled.'
f'The word "{fake_word}" is unknown.'
)
with pytest.raises(RuntimeError, match=expected_error):
_load_skill(random_path, fake_course)

View File

@ -78,7 +78,8 @@ def download_course(url, tempdir):
def generate_course(links, courses_data, reldir, outdir, tdir, course_dir):
logging.info("generate_course %s", course_dir)
# pylint complains of "Catching too general exception Exception (broad-except)"
# but I don't know what kind of exception can happen there, so for now let's not catch any exception.
# but I don't know what kind of exception can happen there,
# so for now let's not catch any exception.
# try:
docs_dir = os.path.join(outdir, tdir)
course = lili.load_course(course_dir)

View File

@ -27,7 +27,11 @@ def main():
for module in course.modules:
for skill in module.skills:
# Word(in_target_language=['el chapeo', 'el chapeyo'], in_source_language=['the hat'], pictures=['hat1', 'hat2', 'hat3'])
# Word(
# in_target_language=['el chapeo', 'el chapeyo'],
# in_source_language=['the hat'],
# pictures=['hat1', 'hat2', 'hat3']
# )
for word in skill.words:
collect(
"target_word", module, skill, search_word, word.in_target_language

View File

@ -97,7 +97,8 @@ def render(template_file, **args):
def export_main_html_page(course, count, html_dir):
branch = "main" # how can we know which is the default branch of a repository?
#'count', 'dictionary', 'index', 'license', 'modules', 'repository_url', 'settings', 'source_language', 'special_characters', 'target_language'
#'count', 'dictionary', 'index', 'license', 'modules', 'repository_url',
#'settings', 'source_language', 'special_characters', 'target_language'
# course.modules[0].skills[0].phrases
# from ptpython.repl import embed
# embed(globals(), locals())
@ -435,7 +436,11 @@ class Lili:
if picture in self.unused_images["regular"]:
self.unused_images["regular"].remove(picture)
# print(word.pictures)
# Word(in_target_language=['la mujer'], in_source_language=['the woman'], pictures=['woman1', 'woman2', 'woman3'])
# Word(
# in_target_language=['la mujer'],
# in_source_language=['the woman'],
# pictures=['woman1', 'woman2', 'woman3']
# )
def collect_ids_and_names(self, images, course):
for module in course.modules:
@ -444,11 +449,15 @@ class Lili:
self.check_images(module, skill)
if skill.id in self.skill_ids:
self.errors.append(
f"Duplicate id: {skill.id} in {module.title}/{skill.name} and in {self.skill_ids[skill.id]['module'].title}/{self.skill_ids[skill.id]['skill'].name}"
f"Duplicate id: {skill.id} in {module.title}/{skill.name}"
f"and in {self.skill_ids[skill.id]['module'].title}"
f"/{self.skill_ids[skill.id]['skill'].name}"
)
if skill.name in self.skill_names:
self.errors.append(
f"Duplicate name: {skill.name} in {module.title}/{skill.name} and in {self.skill_names[skill.name]['module'].title}/{self.skill_names[skill.name]['skill'].name}"
f"Duplicate name: {skill.name} in {module.title}/{skill.name} "
f"and in {self.skill_names[skill.name]['module'].title}/"
f"{self.skill_names[skill.name]['skill'].name}"
)
self.skill_ids[skill.id] = {
"module": module,

View File

@ -53,10 +53,14 @@ def main():
# #exit()
# for sentence in phrase.in_target_language:
# if found(search_word, [sentence]):
# phrases[sentence].append({"filename": skill.filename, "translations": phrase.in_source_language})
# phrases[sentence].append(
# {"filename": skill.filename, "translations": phrase.in_source_language}
# )
# for sentence in phrase.in_source_language:
# if found(search_word, [sentence]):
# phrases[sentence].append({"filename": skill.filename, "translations": phrase.in_target_language})
# phrases[sentence].append(
# {"filename": skill.filename, "translations": phrase.in_target_language}
# )
# for expression in sorted(translations.keys()):
# for filename in translations[expression]:

View File

@ -63,7 +63,8 @@ def main():
target, source, _ = collect_data(course)
_show_banner()
# Randomly select a word or a phrase, show it, ask the user to type the answer, verify the answer
# Randomly select a word or a phrase, show it
# ask the user to type the answer, verify the answer
challenges = {
"source_to_target_word": [0.1, lambda: guess_word(source_to_target_words)],

View File

@ -92,8 +92,6 @@ disable=raw-checker-failed,
too-many-public-methods, # TODO: enable
unspecified-encoding, # TODO: enable
missing-module-docstring, # TODO: enable
too-many-lines, # TODO: enable
line-too-long, # TODO: enable
import-outside-toplevel, # TODO: enable
global-statement, # TODO: enable
unnecessary-pass, # TODO: enable