diff --git a/run.py b/run.py index 93dee37..08b5ed3 100755 --- a/run.py +++ b/run.py @@ -45,6 +45,7 @@ class Language(Enum): - Kotlin: kt - Lua: lua """ + PYTHON = "py" C = "c" CPP = "cpp" @@ -107,11 +108,11 @@ class Language(Enum): Language.KOTLIN: "kt.jar", Language.LUA: "lua.luac", }[self] - + @property def executable_command(self): """ - 각 언어에 대한 실행 명령어. + 각 언어에 대한 실행 명령어. """ return { Language.PYTHON: ["python", f"{BUILD_DIR}/{self.build_executable}"], @@ -173,6 +174,7 @@ def natural_sort_key(s: str): """Natural sort key: splits string into text/number chunks for proper ordering.""" return [int(c) if c.isdigit() else c.lower() for c in re.split(r"(\d+)", s)] + def parse_range_string(range_str: str) -> list[int]: """ 범위 문자열을 정수 리스트로 변환. @@ -334,7 +336,9 @@ def _guess_image_mime(src_url: str, content_type: str | None) -> str: return ext_to_mime.get(ext, "image/png") -def _download_image_for_offline(problem_id: str, src_url: str, seq: int, force: bool) -> str | None: +def _download_image_for_offline( + problem_id: str, src_url: str, seq: int, force: bool +) -> str | None: req = urllib.request.Request( src_url, headers={ @@ -387,7 +391,9 @@ def _localize_images_in_html(problem_id: str, html_fragment: str, force: bool) - return f"{prefix}{quote}{local_src}{quote}" counter["i"] += 1 - local_src = _download_image_for_offline(problem_id, abs_url, counter["i"], force=force) + local_src = _download_image_for_offline( + problem_id, abs_url, counter["i"], force=force + ) if not local_src: return m.group(0) @@ -455,7 +461,9 @@ def _render_math_expressions(html_fragment: str) -> str: return m.group(0) temp = re.sub(r"\$\$(.+?)\$\$", repl_block, temp, flags=re.DOTALL) - temp = re.sub(r"(? st blocks.append( "\n".join( [ - "
", + '
', f"

{fallback_label}

", f"{localized_content}", "
", @@ -503,7 +511,10 @@ def make_offline_problem_html(problem_id: str, raw_html: str, force: bool) -> st ) ) - for sample_type, sample_label in (("sampleinput", "예제 입력"), ("sampleoutput", "예제 출력")): + for sample_type, sample_label in ( + ("sampleinput", "예제 입력"), + ("sampleoutput", "예제 출력"), + ): sample_pattern = rf"]*id=\"{sample_type}(\d+)\"[^>]*>(.*?)" sample_matches = list( re.finditer(sample_pattern, raw_html, flags=re.DOTALL | re.IGNORECASE) @@ -540,7 +551,7 @@ def make_offline_problem_html(problem_id: str, raw_html: str, force: bool) -> st blocks.append( "\n".join( [ - "
", + '
', f"

{h2}

", pre_html, "
", @@ -550,7 +561,7 @@ def make_offline_problem_html(problem_id: str, raw_html: str, force: bool) -> st if not blocks: body_fallback = ( - "
" + '
' "

원본 페이지

" "

문제 본문 파싱에 실패하여 원본 HTML을 포함합니다.

" f"
{escape(raw_html[:100000])}
" @@ -979,11 +990,15 @@ def export(from_: str, completed: bool, copy: bool): if completed: s_is_completed = True - dest_path: str = f"{STORAGE_DIR}/{s_loc}/{from_language.value}{'/completed' if s_is_completed else ''}/{s_file}.{from_language.value}" + dest_path: str = ( + f"{STORAGE_DIR}/{s_loc}/{from_language.value}{'/completed' if s_is_completed else ''}/{s_file}.{from_language.value}" + ) source_path: str = ( f"{SRC_SPACE_DIR}/src-{from_language.value}/src/main.{from_language.value}" ) + os.makedirs(os.path.dirname(dest_path), exist_ok=True) + with open(source_path, "rb") as f_src, open(dest_path, "wb") as f_dst: f_dst.write(f_src.read()) @@ -1367,7 +1382,6 @@ def fetchprob(target: str, force: bool): ) - cli.add_command(run) cli.add_command(load) cli.add_command(init)