Skip to content

Commit d5daa90

Browse files
refactor:submission UI
1 parent 58c3cfe commit d5daa90

File tree

4 files changed

+151
-40
lines changed

4 files changed

+151
-40
lines changed

2529.cpp

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/commands/submit.py

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
from typing import Optional
55
from ..server.auth import Auth
66
from ..server.solution_manager import SolutionManager
7+
from ..lib.submission_ui import (
8+
display_auth_error, display_file_not_found_error, display_language_detection_message,
9+
display_language_detection_error, display_problem_not_found_error, display_submission_details,
10+
display_submission_canceled, create_submission_progress, display_submission_results,
11+
display_exception_error
12+
)
713

814
auth_manager = Auth()
915
solution_manager = SolutionManager(auth_manager.get_session())
@@ -36,57 +42,45 @@ def submit(
3642
Language is auto-detected from file extension if not specified.
3743
"""
3844
if not auth_manager.is_authenticated:
39-
typer.echo(typer.style("❌ Please login first using the login command", fg=typer.colors.RED))
40-
raise typer.Exit(1)
45+
display_auth_error()
4146

4247
if not file.exists():
43-
typer.echo(typer.style(f"❌ File not found: {file}", fg=typer.colors.RED))
44-
raise typer.Exit(1)
48+
display_file_not_found_error(file)
4549

4650
try:
4751
# Auto-detect language from file extension if not provided
4852
if not lang:
4953
extension = os.path.splitext(file)[1].lower()
5054
if extension in LANGUAGE_MAP:
5155
lang = LANGUAGE_MAP[extension]
52-
typer.echo(typer.style(f"🔍 Auto-detected language: {lang}", fg=typer.colors.BLUE))
56+
display_language_detection_message(lang)
5357
else:
54-
typer.echo(typer.style(f"❌ Could not detect language for {extension} files. Please specify with --lang", fg=typer.colors.RED))
55-
raise typer.Exit(1)
58+
display_language_detection_error(extension)
5659

5760
with open(file, 'r') as f:
5861
code = f.read()
5962

6063
# Confirm submission unless forced
6164
if not force:
62-
typer.echo(typer.style(f"Problem: {problem}", fg=typer.colors.BLUE))
63-
typer.echo(typer.style(f"Language: {lang}", fg=typer.colors.BLUE))
64-
typer.echo(typer.style(f"File: {file}", fg=typer.colors.BLUE))
65-
if not typer.confirm("Do you want to submit this solution?"):
66-
typer.echo(typer.style("Submission canceled", fg=typer.colors.YELLOW))
67-
raise typer.Exit(0)
65+
problem_name = solution_manager.get_question_data(problem).get('data', {}).get('question', {}).get('title')
6866

69-
typer.echo(typer.style("📤 Submitting solution...", fg=typer.colors.YELLOW))
70-
result = solution_manager.submit_solution(problem, code, lang)
67+
if not problem_name:
68+
display_problem_not_found_error(problem)
7169

72-
if result["success"]:
73-
status = result['status']
74-
status_color = (
75-
typer.colors.GREEN if status == "Accepted"
76-
else typer.colors.YELLOW if status == "Runtime Error" or status == "Time Limit Exceeded"
77-
else typer.colors.RED
78-
)
70+
if not display_submission_details(problem, problem_name, lang, file):
71+
display_submission_canceled()
7972

80-
typer.echo(typer.style(f"\n✨ Status: {status}", fg=status_color))
81-
typer.echo(f"⏱️ Runtime: {result['runtime']}")
82-
typer.echo(f"💾 Memory: {result['memory']}")
83-
typer.echo(f"✅ Passed: {result['passed_testcases']}/{result['total_testcases']} test cases")
73+
if not lang:
74+
display_language_detection_error("")
75+
return
76+
77+
with create_submission_progress() as progress:
78+
submit_task = progress.add_task("Submitting...", total=1)
79+
progress.update(submit_task, advance=0.5)
80+
result = solution_manager.submit_solution(problem, code, lang)
81+
progress.update(submit_task, advance=0.5)
8482

85-
if status != "Accepted":
86-
typer.echo(typer.style(f"\n❗ Error message: {result.get('error_message', 'No details available')}", fg=typer.colors.RED))
87-
else:
88-
typer.echo(typer.style(f"\n❌ Submission failed: {result['error']}", fg=typer.colors.RED))
83+
display_submission_results(result)
8984

9085
except Exception as e:
91-
typer.echo(typer.style(f"❌ Error: {str(e)}", fg=typer.colors.RED))
92-
raise typer.Exit(1)
86+
display_exception_error(e)

src/lib/submission_ui.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
from rich.console import Console
2+
from rich.panel import Panel
3+
from rich.table import Table
4+
from rich.progress import Progress, BarColumn, TextColumn
5+
from rich import box
6+
from rich.text import Text
7+
from rich.columns import Columns
8+
import typer
9+
10+
console = Console()
11+
12+
def display_auth_error():
13+
"""Display error message when not authenticated"""
14+
console.print(Panel("❌ Please login first using the login command",
15+
style="bold red", border_style="red"))
16+
raise typer.Exit(1)
17+
18+
def display_file_not_found_error(file):
19+
"""Display error message when file is not found"""
20+
console.print(Panel(f"❌ File not found: {file}", style="bold red", border_style="red"))
21+
raise typer.Exit(1)
22+
23+
def display_language_detection_message(lang):
24+
"""Display auto-detected language message"""
25+
console.print(f"🔍 Auto-detected language: [cyan]{lang}[/]")
26+
27+
def display_language_detection_error(extension):
28+
"""Display error message when language cannot be detected"""
29+
console.print(Panel(f"❌ Could not detect language for {extension} files. Please specify with --lang",
30+
style="bold red", border_style="red"))
31+
raise typer.Exit(1)
32+
33+
def display_problem_not_found_error(problem):
34+
"""Display error message when problem is not found"""
35+
console.print(Panel(f"❌ Problem not found: {problem}", style="bold red", border_style="red"))
36+
raise typer.Exit(1)
37+
38+
def display_submission_details(problem, problem_name, lang, file):
39+
"""Display submission details and confirmation prompt using a clean layout"""
40+
# Create formatted text lines instead of a nested table
41+
content = [
42+
f"[cyan]Problem:[/] {problem} - {problem_name}",
43+
f"[cyan]Language:[/] {lang}",
44+
f"[cyan]File:[/] {str(file)}"
45+
]
46+
47+
console.print(Panel(
48+
"\n".join(content),
49+
title="Submission Details",
50+
border_style="blue",
51+
box=box.ROUNDED
52+
))
53+
54+
return typer.confirm("Do you want to submit this solution?")
55+
56+
def display_submission_canceled():
57+
"""Display submission canceled message"""
58+
console.print("[yellow]Submission canceled[/]")
59+
raise typer.Exit(0)
60+
61+
def create_submission_progress():
62+
"""Create and return a submission progress context"""
63+
return Progress(
64+
TextColumn("[bold yellow]Submitting solution...", justify="right"),
65+
BarColumn(bar_width=40, style="yellow"),
66+
transient=True,
67+
)
68+
69+
def display_submission_results(result):
70+
"""Display submission results with a cleaner layout"""
71+
if result["success"]:
72+
status = result['status']
73+
74+
# Set colors based on status
75+
if status == "Accepted":
76+
status_style = "bold green"
77+
border_style = "green"
78+
emoji = "✅"
79+
elif status in ["Runtime Error", "Time Limit Exceeded"]:
80+
status_style = "bold yellow"
81+
border_style = "yellow"
82+
emoji = "⚠️"
83+
else:
84+
status_style = "bold red"
85+
border_style = "red"
86+
emoji = "❌"
87+
88+
# Get metrics
89+
runtime = result.get('runtime', 'N/A')
90+
memory = result.get('memory', 'N/A')
91+
passed = result.get('passed_testcases', 0)
92+
total = result.get('total_testcases', 0)
93+
test_case_str = f"{passed}/{total} ({passed/total*100:.1f}%)" if total > 0 else "N/A"
94+
95+
content = [
96+
f"[cyan]⏱️ Runtime:[/] {runtime}",
97+
f"[cyan]💾 Memory:[/] {memory}",
98+
f"[cyan]🧪 Test Cases:[/] {test_case_str}"
99+
]
100+
101+
title = f"{emoji} Submission Result: [{status_style}]{status}[/]"
102+
console.print(Panel(
103+
"\n".join(content),
104+
title=title,
105+
border_style=border_style,
106+
box=box.ROUNDED
107+
))
108+
109+
if status != "Accepted" and result.get('error_message'):
110+
error_msg = result.get('error_message', 'No details available')
111+
console.print(Panel(error_msg, title="Error Details", border_style="red"))
112+
else:
113+
error_panel = Panel(
114+
f"{result.get('error', 'Unknown error')}",
115+
title="❌ Submission Failed",
116+
border_style="red"
117+
)
118+
console.print(error_panel)
119+
120+
def display_exception_error(e):
121+
"""Display exception error message"""
122+
console.print(Panel(f"❌ Error: {str(e)}", style="bold red", border_style="red"))
123+
raise typer.Exit(1)

src/server/solution_manager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def submit_solution(self, title_slug: str, code: str, lang: str = "python3") ->
9999
if not question_data:
100100
return {"success": False, "error": "Question data not found"}
101101

102-
question_id = question_data['questionFrontendId']
102+
question_id = question_data['questionId']
103103
submit_url = f"{self.BASE_URL}/problems/{title_slug}/submit/"
104104

105105
csrf_token = self._get_csrf_token()
@@ -158,7 +158,7 @@ def test_solution(self, title_slug: str, code: str, lang: str = "python3", full:
158158
if not question_data:
159159
return {"success": False, "error": "Question data not found"}
160160

161-
question_id = question_data['questionFrontendId']
161+
question_id = question_data['questionId']
162162
test_cases = question_data['exampleTestcaseList']
163163

164164
endpoint = 'submit' if full else 'interpret_solution'

0 commit comments

Comments
 (0)