refactoring stage 6
- enhance state command - enhance init
This commit is contained in:
138
run.py
138
run.py
@@ -305,6 +305,15 @@ class StateManager:
|
||||
def reload(self) -> None:
|
||||
self._state = None
|
||||
|
||||
def set_completed(self, lang: Language, is_completed: bool) -> None:
|
||||
state = self._load()
|
||||
if lang.value not in state.get("space", {}):
|
||||
raise ValueError(f"No space found for language: {lang}")
|
||||
if not state["space"].get(lang.value):
|
||||
raise ValueError(f"No space found for language: {lang}")
|
||||
state["space"][lang.value]["is_completed"] = is_completed
|
||||
self._state = state
|
||||
|
||||
|
||||
class StorageManager:
|
||||
_instance: "StorageManager | None" = None
|
||||
@@ -376,6 +385,16 @@ class StorageManager:
|
||||
with open(file_path, "rb") as f:
|
||||
return f.read()
|
||||
|
||||
def remove_file(self, location: str, lang: Language, filename: str) -> None:
|
||||
path = self.check_get_file(location, lang, filename)
|
||||
if path is None:
|
||||
raise FileNotFoundError(
|
||||
f"File not found in storage: {location}/{filename}.{lang.value}"
|
||||
)
|
||||
file_path = f"{path}/{filename}"
|
||||
if os.path.isfile(file_path):
|
||||
os.remove(file_path)
|
||||
|
||||
def mark_completed(self, location: str, lang: Language, filename: str) -> None:
|
||||
uncompleted_file = (
|
||||
STORAGE_DIR / location / lang.value / f"{filename}.{lang.value}"
|
||||
@@ -629,6 +648,7 @@ def load(target: str, force: bool):
|
||||
f_dst.write(f_src.read())
|
||||
StateManager().remove_space(lang)
|
||||
StateManager().add_space(lang, prob, loc, False)
|
||||
StorageManager().remove_file(loc, lang, prob)
|
||||
click.secho(
|
||||
f"Loaded '{prob}.{lang.value}' from location '{loc}' to src-space.",
|
||||
fg="cyan",
|
||||
@@ -705,38 +725,65 @@ def export(from_: tuple[str, ...], all_: bool, force: bool):
|
||||
_export_sub_command(l)
|
||||
|
||||
|
||||
@click.command(name="state")
|
||||
@click.group(name="state")
|
||||
def state():
|
||||
try:
|
||||
with open(STATE_PATH, "r", encoding="utf-8") as f_state:
|
||||
state = yaml.safe_load(f_state)
|
||||
except FileNotFoundError as e:
|
||||
raise click.ClickException(e)
|
||||
except yaml.YAMLError as e:
|
||||
raise click.ClickException(e)
|
||||
"""State management commands"""
|
||||
pass
|
||||
|
||||
if "space" not in state:
|
||||
raise click.ClickException("state.yml is wrong")
|
||||
elif not state["space"]:
|
||||
click.secho("state.space has no member", fg="yellow", bold=True)
|
||||
state["space"] = {}
|
||||
|
||||
active = sum(1 for v in state["space"].values() if v)
|
||||
total = len(state["space"])
|
||||
click.secho(f"Space: {active}/{total} active", fg="cyan", bold=True)
|
||||
click.echo()
|
||||
|
||||
for k, v in state["space"].items():
|
||||
click.secho(f" {k}/", fg="yellow")
|
||||
if not v:
|
||||
click.echo(f" {click.style('—', fg='bright_black')} empty")
|
||||
else:
|
||||
status = (
|
||||
@state.command(name="show")
|
||||
def state_show():
|
||||
"""Show current space state"""
|
||||
click.secho("Current Space State:", fg="cyan", bold=True)
|
||||
for lang in Language.languages():
|
||||
space = (
|
||||
StateManager().get_space(lang) if StateManager().check_space(lang) else None
|
||||
)
|
||||
if space:
|
||||
status_symbol = (
|
||||
click.style("✓", fg="green")
|
||||
if v["is_completed"]
|
||||
if space.get("is_completed")
|
||||
else click.style("○", fg="white")
|
||||
)
|
||||
click.echo(f" {status} {v['file']}.{k} @ {v['location']}")
|
||||
click.echo(
|
||||
f"{status_symbol} {lang.value}: {space['file']} (Location: {space['location']})"
|
||||
)
|
||||
else:
|
||||
click.echo(f"{click.style('○', fg='white')} {lang.value}: No file loaded")
|
||||
|
||||
|
||||
@state.command(name="complete")
|
||||
@click.argument("lang", type=str)
|
||||
def state_complete(lang: str):
|
||||
"""Mark language space as completed"""
|
||||
lang_obj = Language.convert_name(lang)
|
||||
if lang_obj is Language.UNDEFINED:
|
||||
raise click.ClickException(f"Unknown language: {lang}")
|
||||
|
||||
state_manager = StateManager()
|
||||
try:
|
||||
state_manager.set_completed(lang_obj, True)
|
||||
state_manager.save()
|
||||
except ValueError as e:
|
||||
raise click.ClickException(str(e))
|
||||
click.secho(f"Language '{lang}' marked as completed.", fg="green")
|
||||
|
||||
|
||||
@state.command(name="uncomplete")
|
||||
@click.argument("lang", type=str)
|
||||
def state_uncomplete(lang: str):
|
||||
"""Mark language space as not completed"""
|
||||
lang_obj = Language.convert_name(lang)
|
||||
if lang_obj is Language.UNDEFINED:
|
||||
raise click.ClickException(f"Unknown language: {lang}")
|
||||
|
||||
state_manager = StateManager()
|
||||
try:
|
||||
state_manager.set_completed(lang_obj, False)
|
||||
state_manager.save()
|
||||
except ValueError as e:
|
||||
raise click.ClickException(str(e))
|
||||
click.secho(f"Language '{lang}' marked as not completed.", fg="green")
|
||||
|
||||
|
||||
@click.command(name="init")
|
||||
@@ -746,36 +793,20 @@ def init(count: int):
|
||||
init testcases with initial count and state.yml and config.yml
|
||||
"""
|
||||
if count < 1:
|
||||
raise click.UsageError("var count should be greater than 1.")
|
||||
raise click.UsageError("count should be greater than 0")
|
||||
|
||||
if not os.path.exists("./" + TC_DIR):
|
||||
os.mkdir(TC_DIR)
|
||||
TC_DIR.mkdir(exist_ok=True)
|
||||
for i in range(1, count + 1):
|
||||
default_in_path = "./" + TC_DIR + f"/{i}.in"
|
||||
default_out_path = "./" + TC_DIR + f"/{i}.out"
|
||||
if not os.path.exists(default_in_path):
|
||||
with open(default_in_path, "w", encoding="utf-8") as _:
|
||||
pass
|
||||
if not os.path.exists(default_out_path):
|
||||
with open(default_out_path, "w", encoding="utf-8") as _:
|
||||
pass
|
||||
|
||||
click.echo(f"1. Testcases was made with count {count} successfully!")
|
||||
|
||||
if not os.path.isfile("./state.yml"):
|
||||
click.echo("2-1. state.yml does not exist, creating...")
|
||||
with open("state.yml", "w", encoding="utf-8") as f:
|
||||
f.write("space:\n")
|
||||
click.echo("2-1. state.yml is created successfully!")
|
||||
(TC_DIR / f"{i}.in").touch()
|
||||
(TC_DIR / f"{i}.out").touch()
|
||||
click.secho(f"1. Testcases created with count {count}", fg="cyan")
|
||||
click.secho("2. Checking state.yml...", fg="cyan")
|
||||
if not STATE_PATH.is_file():
|
||||
click.secho("2. state.yml does not exist, creating...", fg="yellow")
|
||||
STATE_PATH.write_text("space:\n", encoding="utf-8")
|
||||
click.secho("2. state.yml created", fg="cyan")
|
||||
else:
|
||||
click.echo("2-1. state.yml exists")
|
||||
if not os.path.isfile("./config.yml"):
|
||||
click.echo("2-2. config.yml does not exist, creating...")
|
||||
with open("config.yml", "w", encoding="utf-8") as f:
|
||||
f.write("space:\n")
|
||||
click.echo("2-2. config.yml is created successfully!")
|
||||
else:
|
||||
click.echo("2-2. config.yml exists")
|
||||
click.secho("2. state.yml exists", fg="green")
|
||||
|
||||
|
||||
@click.command(name="show")
|
||||
@@ -797,7 +828,6 @@ def show(filter: str | None, completed: bool, show_all: bool):
|
||||
"""
|
||||
Show all stored problems in storage directory.
|
||||
|
||||
\b
|
||||
FILTER format (optional):
|
||||
location e.g. zeta
|
||||
location/lang e.g. zeta/rs
|
||||
|
||||
Reference in New Issue
Block a user