Review record RC-025 (Go, autonomous mode, not independent). Task: MIL-003#1 Task: MIL-003#2 Task: MIL-003#3 Task: MIL-003#4 Task: MIL-003#5
78 lines
2.6 KiB
Python
78 lines
2.6 KiB
Python
"""Entry point and composition root of the flash card program.
|
|
|
|
@file app.py
|
|
@brief Creates the window, its view model and view, and runs the main loop.
|
|
"""
|
|
|
|
import argparse
|
|
import logging
|
|
import random
|
|
import tkinter as tk
|
|
from collections.abc import Sequence
|
|
from pathlib import Path
|
|
from typing import NoReturn
|
|
|
|
from flash_card.application.use_cases.open_study_session import open_study_session
|
|
from flash_card.constants import DEFAULT_DATA_DIR, VOCABULARY_FILE_NAME
|
|
from flash_card.domain.errors.vocabulary_errors import VocabularyError
|
|
from flash_card.infrastructure.persistence.csv_vocabulary_repository import (
|
|
CsvVocabularyRepository,
|
|
)
|
|
from flash_card.presentation.features.flash_card.flash_card_view import FlashCardView
|
|
from flash_card.presentation.features.flash_card.flash_card_view_model import (
|
|
FlashCardViewModel,
|
|
)
|
|
|
|
## @brief Logger of the entry point.
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
def create_application(
|
|
data_dir: Path | None = None,
|
|
) -> tuple[tk.Tk, FlashCardView]:
|
|
"""Create the root window and the flash card view.
|
|
|
|
@param data_dir Folder of the data files, or None for the default folder.
|
|
@return The root window and the view built on it.
|
|
@throws VocabularyError When the word list cannot be loaded.
|
|
"""
|
|
folder = DEFAULT_DATA_DIR if data_dir is None else data_dir
|
|
repository = CsvVocabularyRepository(folder / VOCABULARY_FILE_NAME)
|
|
session = open_study_session(repository, random.choice)
|
|
view_model = FlashCardViewModel(session)
|
|
root = tk.Tk()
|
|
view = FlashCardView(root, view_model)
|
|
return root, view
|
|
|
|
|
|
def main(argv: Sequence[str] | None = None) -> int:
|
|
"""Run the program and return its exit code.
|
|
|
|
@param argv Command line arguments, or None for those of the process.
|
|
@return The exit code, 0 on success and 1 when the word list is unusable.
|
|
"""
|
|
parser = argparse.ArgumentParser(description="Flash card program.")
|
|
parser.add_argument(
|
|
"--data-dir",
|
|
type=Path,
|
|
default=DEFAULT_DATA_DIR,
|
|
help="folder of the data files",
|
|
)
|
|
args = parser.parse_args(argv)
|
|
try:
|
|
root, _view = create_application(args.data_dir)
|
|
except VocabularyError as error:
|
|
_logger.error("%s", error)
|
|
return 1
|
|
root.mainloop()
|
|
return 0
|
|
|
|
|
|
def run() -> NoReturn:
|
|
"""Run the program and exit the interpreter with its exit code.
|
|
|
|
@return Never returns; the function always raises SystemExit.
|
|
@throws SystemExit Always, with the exit code of main.
|
|
"""
|
|
raise SystemExit(main())
|