Skip to content

Commit dc3100c

Browse files
feat: format
1 parent 832a422 commit dc3100c

File tree

18 files changed

+714
-477
lines changed

18 files changed

+714
-477
lines changed

src/commands/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from .show import show
21
from .profile import profile
2+
from .show import show
33

4-
__all__ = ["show", "profile"]
4+
__all__ = ["show", "profile"]

src/commands/daily.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
import typer
2-
from .edit import edit
2+
33
from ..server.api import get_daily_question
4+
from .edit import edit
5+
46

57
def daily(
68
lang: str = typer.Argument("py", help="Programming language to use."),
7-
editor: str = typer.Option("vim", '--editor', '-e', help="Code editor to use."),
8-
full: bool = typer.Option(False, "--full", "-f", help="Show full problem description"),
9-
save: bool = typer.Option(False, "--save", "-s", help="Save problem description to a file"),
9+
editor: str = typer.Option("vim", "--editor", "-e", help="Code editor to use."),
10+
full: bool = typer.Option(
11+
False, "--full", "-f", help="Show full problem description"
12+
),
13+
save: bool = typer.Option(
14+
False, "--save", "-s", help="Save problem description to a file"
15+
),
1016
no_editor: bool = typer.Option(False, "--no-editor", help="Skip opening editor"),
1117
):
1218
"""
@@ -17,25 +23,33 @@ def daily(
1723
"""
1824
from .show import show
1925

20-
if editor not in ['code', 'vim', 'nano']:
26+
if editor not in ["code", "vim", "nano"]:
2127
typer.echo(typer.style(f"❌ Unsupported editor: {editor}", fg=typer.colors.RED))
2228
raise typer.Exit(1)
2329

24-
typer.echo(typer.style("Fetching daily challenge...", fg=typer.colors.GREEN), nl=False)
30+
typer.echo(
31+
typer.style("Fetching daily challenge...", fg=typer.colors.GREEN), nl=False
32+
)
2533
try:
2634
result = get_daily_question()
27-
question = result['data']['activeDailyCodingChallengeQuestion']
35+
question = result["data"]["activeDailyCodingChallengeQuestion"]
2836
typer.echo("\r" + " " * 30 + "\r", nl=False)
2937

30-
show(problem=question['question']['titleSlug'], save=save, compact=not full)
38+
show(problem=question["question"]["titleSlug"], save=save, compact=not full)
3139
except Exception as e:
32-
typer.echo("\n" + typer.style(f"❌ Failed to fetch daily question: {str(e)}", fg=typer.colors.RED))
40+
typer.echo(
41+
"\n"
42+
+ typer.style(
43+
f"❌ Failed to fetch daily question: {str(e)}", fg=typer.colors.RED
44+
)
45+
)
3346
raise typer.Exit(1)
3447

35-
3648
if not no_editor and editor:
3749
try:
38-
edit(problem=question['question']['titleSlug'], lang=lang, editor=editor)
50+
edit(problem=question["question"]["titleSlug"], lang=lang, editor=editor)
3951
except Exception as e:
40-
typer.echo(typer.style(f"❌ Failed to open editor: {str(e)}", fg=typer.colors.RED))
41-
raise typer.Exit(1)
52+
typer.echo(
53+
typer.style(f"❌ Failed to open editor: {str(e)}", fg=typer.colors.RED)
54+
)
55+
raise typer.Exit(1)

src/commands/edit.py

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,43 @@
11
import typer
22

3-
from ..server.solution_manager import SolutionManager
43
from ..server.auth import Auth
54
from ..server.config import LANGUAGE_MAP
5+
from ..server.solution_manager import SolutionManager
66

77
solution_manager = SolutionManager(Auth().get_session())
88

9+
910
def edit(
10-
problem: str = typer.Argument(..., help="Problem name or id."),
11-
lang: str = typer.Argument("cpp", help="Programming language to use."),
12-
editor: str = typer.Option("vim", '-e', '--editor', help="Editor to use for code editing."),
11+
problem: str = typer.Argument(..., help="Problem name or id."),
12+
lang: str = typer.Argument("cpp", help="Programming language to use."),
13+
editor: str = typer.Option(
14+
"vim", "-e", "--editor", help="Editor to use for code editing."
15+
),
1316
):
14-
"""Solves a problem by passing lang param and open it with your code editor."""
15-
question_data = solution_manager.get_question_data(problem).get('data', {}).get('question')
16-
17-
if not question_data:
18-
typer.echo(f"Problem {problem} not found.")
19-
return
20-
21-
filename_prefix = question_data.get('questionFrontendId') or (
22-
problem if problem.isdigit() else question_data.get('questionId')
23-
)
24-
25-
def create_file_with_template(lang: str):
26-
filename = f"{filename_prefix}.{lang}"
27-
with open(filename, "w") as f:
28-
for snippet in question_data.get('codeSnippets', []):
29-
if snippet.get('langSlug').lower() == LANGUAGE_MAP.get(lang):
30-
f.write(snippet.get('code'))
31-
return
32-
typer.echo(f"No template found for language {lang}")
33-
34-
create_file_with_template(lang)
35-
36-
import subprocess
37-
subprocess.run([editor, f"{filename_prefix}.{lang}"])
17+
"""Solves a problem by passing lang param and open it with your code editor."""
18+
question_data = (
19+
solution_manager.get_question_data(problem).get("data", {}).get("question")
20+
)
21+
22+
if not question_data:
23+
typer.echo(f"Problem {problem} not found.")
24+
return
25+
26+
filename_prefix = question_data.get("questionFrontendId") or (
27+
problem if problem.isdigit() else question_data.get("questionId")
28+
)
29+
30+
def create_file_with_template(lang: str):
31+
filename = f"{filename_prefix}.{lang}"
32+
with open(filename, "w") as f:
33+
for snippet in question_data.get("codeSnippets", []):
34+
if snippet.get("langSlug").lower() == LANGUAGE_MAP.get(lang):
35+
f.write(snippet.get("code"))
36+
return
37+
typer.echo(f"No template found for language {lang}")
38+
39+
create_file_with_template(lang)
40+
41+
import subprocess
42+
43+
subprocess.run([editor, f"{filename_prefix}.{lang}"])

src/commands/list_problems.py

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,73 @@
1-
2-
from rich.spinner import Spinner
3-
from rich.live import Live
41
from typing import Optional
5-
from ..lib.ui import display_problem_list
6-
from ..server.auth import Auth
7-
from rich.progress import Progress, SpinnerColumn, TextColumn
82

93
import typer
4+
from rich.progress import Progress, SpinnerColumn, TextColumn
105

6+
from ..lib.ui import display_problem_list
117
from ..server.api import fetch_problem_list
8+
from ..server.auth import Auth
129

1310
status_map = {
14-
"attempted": "TRIED",
15-
"solved": "AC",
16-
"todo": "NOT_STARTED",
11+
"attempted": "TRIED",
12+
"solved": "AC",
13+
"todo": "NOT_STARTED",
1714
}
1815

1916
AuthManager = Auth()
2017

18+
2119
def list_problems(
22-
difficulty: Optional[str] = typer.Option(None, "--difficulty", "-d", help="Filter by difficulty (easy/medium/hard)"),
23-
status: Optional[str] = typer.Option(None, "--status", "-s", help="Filter by status (todo/attempted/solved)"),
24-
tag: Optional[str] = typer.Option(None, "--tag", "-t", help="Filter by tags (comma-separated)"),
25-
category_slug: Optional[str] = typer.Option("all-code-essentials", "--category-slug", "-c", help="Filter by category slug")
20+
difficulty: Optional[str] = typer.Option(
21+
None, "--difficulty", "-d", help="Filter by difficulty (easy/medium/hard)"
22+
),
23+
status: Optional[str] = typer.Option(
24+
None, "--status", "-s", help="Filter by status (todo/attempted/solved)"
25+
),
26+
tag: Optional[str] = typer.Option(
27+
None, "--tag", "-t", help="Filter by tags (comma-separated)"
28+
),
29+
category_slug: Optional[str] = typer.Option(
30+
"all-code-essentials", "--category-slug", "-c", help="Filter by category slug"
31+
),
2632
):
27-
"""List available LeetCode problems with optional filters."""
28-
if (difficulty is not None or status is not None or tag is not None):
29-
if not AuthManager.is_authenticated:
30-
typer.echo(typer.style("❌ Please login first to enable problem listing with filters", fg=typer.colors.RED))
31-
raise typer.Exit(1)
33+
"""List available LeetCode problems with optional filters."""
34+
if difficulty is not None or status is not None or tag is not None:
35+
if not AuthManager.is_authenticated:
36+
typer.echo(
37+
typer.style(
38+
"❌ Please login first to enable problem listing with filters",
39+
fg=typer.colors.RED,
40+
)
41+
)
42+
raise typer.Exit(1)
3243

33-
tags = tag.split(',') if tag else []
44+
tags = tag.split(",") if tag else []
3445

35-
with Progress(
46+
with Progress(
3647
SpinnerColumn(),
3748
TextColumn("[progress.description]{task.description}"),
3849
transient=True,
3950
) as progress:
40-
progress.add_task("Fetching problems...", total=1)
41-
42-
session = AuthManager.session_manager.load_session()
43-
if not session:
44-
typer.echo(typer.style("❌ No valid session found. Please login first.", fg=typer.colors.RED))
45-
raise typer.Exit(1)
46-
47-
data = fetch_problem_list(
48-
csrf_token=session["csrftoken"],
49-
session_id=session["session_token"],
50-
categorySlug=category_slug or "all-code-essentials",
51-
filters={
52-
"difficulty": difficulty,
53-
"status": status_map.get(status) if status is not None else None,
54-
"tags": tags
55-
}
56-
)
57-
display_problem_list(data)
51+
progress.add_task("Fetching problems...", total=1)
52+
53+
session = AuthManager.session_manager.load_session()
54+
if not session:
55+
typer.echo(
56+
typer.style(
57+
"❌ No valid session found. Please login first.",
58+
fg=typer.colors.RED,
59+
)
60+
)
61+
raise typer.Exit(1)
62+
63+
data = fetch_problem_list(
64+
csrf_token=session["csrftoken"],
65+
session_id=session["session_token"],
66+
categorySlug=category_slug or "all-code-essentials",
67+
filters={
68+
"difficulty": difficulty,
69+
"status": status_map.get(status) if status is not None else None,
70+
"tags": tags,
71+
},
72+
)
73+
display_problem_list(data)

src/commands/login.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
import typer
2+
23
from ..server.auth import Auth
34

45
auth_manager = Auth()
56

7+
68
def login():
79
"""Login to LeetCode"""
810
if auth_manager.is_authenticated:
911
saved_session = auth_manager.session_manager.load_session()
1012
if saved_session:
11-
typer.echo(typer.style(f"Already logged in as {saved_session['user_name']}!", fg=typer.colors.GREEN))
13+
typer.echo(
14+
typer.style(
15+
f"Already logged in as {saved_session['user_name']}!",
16+
fg=typer.colors.GREEN,
17+
)
18+
)
1219
return
1320

14-
instruction = f"""
21+
instruction = """
1522
📝 To get your login tokens:
1623
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1724
1️ Open LeetCode in your browser
@@ -28,25 +35,40 @@ def login():
2835
csrf_result = auth_manager.verify_csrf_token(csrf_token)
2936

3037
if not csrf_result["success"]:
31-
typer.echo(typer.style(f"\n✗ CSRF verification failed: {csrf_result['message']}", fg=typer.colors.RED))
38+
typer.echo(
39+
typer.style(
40+
f"\n✗ CSRF verification failed: {csrf_result['message']}",
41+
fg=typer.colors.RED,
42+
)
43+
)
3244
return
3345

3446
leetcode_session = typer.prompt("Please enter your LEETCODE_SESSION token")
3547
result = auth_manager.login_with_session(csrf_token, leetcode_session)
3648

3749
if result["success"]:
38-
typer.echo(typer.style(f"\n✓ Successfully logged in as {result['user_name']}!", fg=typer.colors.GREEN))
50+
typer.echo(
51+
typer.style(
52+
f"\n✓ Successfully logged in as {result['user_name']}!",
53+
fg=typer.colors.GREEN,
54+
)
55+
)
3956
break
4057
else:
41-
typer.echo(typer.style(f"\n✗ Login failed: {result['message']}", fg=typer.colors.RED))
58+
typer.echo(
59+
typer.style(
60+
f"\n✗ Login failed: {result['message']}", fg=typer.colors.RED
61+
)
62+
)
4263
if not typer.confirm("Do you want to try again?", abort=True):
4364
break
4465

66+
4567
def logout():
4668
"""Logout from LeetCode"""
4769
if not auth_manager.is_authenticated:
4870
typer.echo(typer.style("❌ You are not logged in", fg=typer.colors.RED))
4971
return
5072

5173
auth_manager.session_manager.clear_session()
52-
typer.echo(typer.style("✓ Successfully logged out", fg=typer.colors.GREEN))
74+
typer.echo(typer.style("✓ Successfully logged out", fg=typer.colors.GREEN))

src/commands/profile.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
from ..server.api import fetch_user_profile
1+
from rich.live import Live
22
from rich.spinner import Spinner
3+
34
from ..lib.ui import display_user_stats
4-
from rich.live import Live
5+
from ..server.api import fetch_user_profile
6+
57

68
def profile():
79
"""List all available LeetCode problems."""
8-
spinner = Spinner('dots')
10+
spinner = Spinner("dots")
911
with Live(spinner, refresh_per_second=10, transient=True) as live:
1012
live.console.print("[cyan]Fetching user profile...")
1113
data = fetch_user_profile()

0 commit comments

Comments
 (0)