|
| 1 | +import importlib |
| 2 | +from typing import Optional |
| 3 | + |
1 | 4 | import typer |
2 | 5 |
|
3 | | -from src.commands.daily import daily |
4 | | -from src.commands.edit import edit |
5 | | -from src.commands.list_problems import list_problems |
6 | | -from src.commands.login import login, logout |
7 | | -from src.commands.profile import profile |
8 | | -from src.commands.show import show |
9 | | -from src.commands.solution import solutions |
10 | | -from src.commands.submit import submit |
11 | | -from src.commands.test import test |
12 | | - |
13 | | -app = typer.Typer() |
14 | | - |
15 | | -app.command(name="show")(show) |
16 | | -app.command(name="list")(list_problems) |
17 | | -app.command(name="daily")(daily) |
18 | | -app.command(name="profile")(profile) |
19 | | -app.command(name="login")(login) |
20 | | -app.command(name="logout")(logout) |
21 | | -app.command(name="submit")(submit) |
22 | | -app.command(name="test")(test) |
23 | | -app.command(name="edit")(edit) |
24 | | -app.command(name="solutions")(solutions) |
| 6 | +app = typer.Typer( |
| 7 | + help="A sleek command-line tool for LeetCode - solve, test, and submit problems directly from your terminal." |
| 8 | +) |
25 | 9 |
|
26 | | -if __name__ == "__main__": |
| 10 | + |
| 11 | +def import_and_call(module_path, function_name, *args, **kwargs): |
| 12 | + """Import a module and call a function from it with given args.""" |
| 13 | + module = importlib.import_module(module_path) |
| 14 | + func = getattr(module, function_name) |
| 15 | + return func(*args, **kwargs) |
| 16 | + |
| 17 | + |
| 18 | +@app.command(name="login") |
| 19 | +def login(): |
| 20 | + """Login to LeetCode account.""" |
| 21 | + return import_and_call("src.commands.login", "login") |
| 22 | + |
| 23 | + |
| 24 | +@app.command(name="logout") |
| 25 | +def logout(): |
| 26 | + """Logout from LeetCode.""" |
| 27 | + return import_and_call("src.commands.login", "logout") |
| 28 | + |
| 29 | + |
| 30 | +@app.command(name="profile") |
| 31 | +def profile(): |
| 32 | + """Display LeetCode profile.""" |
| 33 | + return import_and_call("src.commands.profile", "profile") |
| 34 | + |
| 35 | + |
| 36 | +@app.command(name="daily") |
| 37 | +def daily( |
| 38 | + lang: Optional[str] = typer.Argument(None, help="Programming language"), |
| 39 | + editor: Optional[str] = typer.Option( |
| 40 | + None, "--editor", "-e", help="Preferred editor" |
| 41 | + ), |
| 42 | + full: bool = typer.Option(False, "--full", "-f", help="Show full description"), |
| 43 | + save: bool = typer.Option(False, "--save", "-s", help="Save to file"), |
| 44 | + no_editor: bool = typer.Option(False, "--no-editor", help="Skip editor"), |
| 45 | +): |
| 46 | + """Show today's challenge.""" |
| 47 | + return import_and_call( |
| 48 | + "src.commands.daily", |
| 49 | + "daily", |
| 50 | + lang=lang, |
| 51 | + editor=editor, |
| 52 | + full=full, |
| 53 | + save=save, |
| 54 | + no_editor=no_editor, |
| 55 | + ) |
| 56 | + |
| 57 | + |
| 58 | +@app.command(name="list") |
| 59 | +def list_problems( |
| 60 | + difficulty: Optional[str] = typer.Option( |
| 61 | + None, "--difficulty", "-d", help="Difficulty level" |
| 62 | + ), |
| 63 | + status: Optional[str] = typer.Option(None, "--status", "-s", help="Problem status"), |
| 64 | + tag: Optional[str] = typer.Option(None, "--tag", "-t", help="Problem tag"), |
| 65 | + category_slug: Optional[str] = typer.Option( |
| 66 | + None, "--category-slug", "-c", help="Category" |
| 67 | + ), |
| 68 | + page: int = typer.Option(1, help="Page number"), |
| 69 | +): |
| 70 | + """List available problems.""" |
| 71 | + return import_and_call( |
| 72 | + "src.commands.list_problems", |
| 73 | + "list_problems", |
| 74 | + difficulty=difficulty, |
| 75 | + status=status, |
| 76 | + tag=tag, |
| 77 | + category_slug=category_slug, |
| 78 | + page=page, |
| 79 | + ) |
| 80 | + |
| 81 | + |
| 82 | +@app.command(name="show") |
| 83 | +def show( |
| 84 | + problem_id: str = typer.Argument(..., help="Problem Name/Number"), |
| 85 | + compact: bool = typer.Option(False, "--compact", "-c", help="Compact layout"), |
| 86 | +): |
| 87 | + """Display problem details.""" |
| 88 | + return import_and_call("src.commands.show", "show", problem_id, compact=compact) |
| 89 | + |
| 90 | + |
| 91 | +@app.command(name="test") |
| 92 | +def test( |
| 93 | + problem_id: str = typer.Argument(..., help="Problem Name/Number"), |
| 94 | + file_path: str = typer.Argument(..., help="Solution file path"), |
| 95 | +): |
| 96 | + """Test your solution.""" |
| 97 | + return import_and_call("src.commands.test", "test", problem_id, file_path) |
| 98 | + |
| 99 | + |
| 100 | +@app.command(name="submit") |
| 101 | +def submit( |
| 102 | + problem_id: str = typer.Argument(..., help="Problem Name/Number"), |
| 103 | + file_path: str = typer.Argument(..., help="Solution file path"), |
| 104 | + lang: Optional[str] = typer.Option(None, "--lang", help="Programming language"), |
| 105 | + force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation"), |
| 106 | +): |
| 107 | + """Submit your solution.""" |
| 108 | + return import_and_call( |
| 109 | + "src.commands.submit", "submit", problem_id, file_path, lang=lang, force=force |
| 110 | + ) |
| 111 | + |
| 112 | + |
| 113 | +@app.command(name="edit") |
| 114 | +def edit( |
| 115 | + problem_id: str = typer.Argument(..., help="Problem Name/Number"), |
| 116 | + lang: str = typer.Argument(..., help="Programming language"), |
| 117 | + editor: Optional[str] = typer.Option( |
| 118 | + None, "--editor", "-e", help="Preferred editor" |
| 119 | + ), |
| 120 | +): |
| 121 | + """Edit solution in editor.""" |
| 122 | + return import_and_call("src.commands.edit", "edit", problem_id, lang, editor=editor) |
| 123 | + |
| 124 | + |
| 125 | +@app.command(name="solutions") |
| 126 | +def solutions( |
| 127 | + problem_id: str = typer.Argument(..., help="Problem Name/Number"), |
| 128 | + best: bool = typer.Option(False, "--best", "-b", help="Show best solutions"), |
| 129 | +): |
| 130 | + """View problem solutions.""" |
| 131 | + return import_and_call("src.commands.solution", "solutions", problem_id, best=best) |
| 132 | + |
| 133 | + |
| 134 | +def main(): |
| 135 | + """Entry point for the CLI.""" |
27 | 136 | app() |
| 137 | + |
| 138 | + |
| 139 | +if __name__ == "__main__": |
| 140 | + main() |
0 commit comments