diff --git a/src/eatlocal/__main__.py b/src/eatlocal/__main__.py index b537eec..08358dd 100644 --- a/src/eatlocal/__main__.py +++ b/src/eatlocal/__main__.py @@ -71,10 +71,16 @@ def download( is_flag=True, help="Overwrite bite directory with a fresh version.", ), + level: str | None = typer.Option( + None, + "--level", + "-l", + help="Filter bites by difficulty level.", + ), ) -> None: """Download and extract bite code from pybitesplatform.com.""" config = load_config(EATLOCAL_HOME / ".env") - bite = choose_bite(clear) + bite = choose_bite(clear, level=level) with Status("Downloading bite..."): bite.platform_content = download_bite(bite, config) if bite.platform_content is None: diff --git a/src/eatlocal/eatlocal.py b/src/eatlocal/eatlocal.py index e7d8717..0d2008e 100644 --- a/src/eatlocal/eatlocal.py +++ b/src/eatlocal/eatlocal.py @@ -7,6 +7,7 @@ from datetime import timedelta from os import environ, makedirs from pathlib import Path +from typing import FrozenSet import install_playwright import requests @@ -42,6 +43,10 @@ CACHE_DB_LOCATION, backend="sqlite", expire_after=timedelta(days=30) ) +VALID_LEVELS: FrozenSet[str] = frozenset( + ["newbie", "intro", "beginner", "intermediate", "advanced"] +) + @dataclass class Bite: @@ -286,8 +291,8 @@ def choose_local_bite(config: dict) -> Bite: return Bite(bite, bites[bite]) -def choose_bite(clear: bool = False) -> Bite: - """Choose which bite will be downloaded. +def choose_bite(clear: bool = False, *, level: str | None = None) -> Bite: + """Choose which level of bite will be downloaded. Returns: A Bite object. @@ -307,7 +312,26 @@ def choose_bite(clear: bool = False) -> Bite: style=ConsoleStyle.SUGGESTION.value, ) sys.exit() - bites = {bite["title"]: bite["slug"] for bite in r.json()} + if level is not None: + # Filter bites by level (case-insensitive) + if level.lower() not in VALID_LEVELS: + console.print( + f":warning: Invalid level: {level}.", + style=ConsoleStyle.WARNING.value, + ) + console.print( + f"Valid levels are: {', '.join(VALID_LEVELS)}.", + style=ConsoleStyle.SUGGESTION.value, + ) + sys.exit() + bites = { + bite["title"]: bite["slug"] + for bite in r.json() + if bite["level"].lower() == level.lower() + } + else: + # Display bites of all levels. + bites = {bite["title"]: bite["slug"] for bite in r.json()} bite_to_download = iterfzf(bites, multi=False) if bite_to_download is None: sys.exit()