Skip to content

Commit

Permalink
refactor : parse.pyをクラスで整理した。それにともない依存しているdownload, generate, open, m…
Browse files Browse the repository at this point in the history
…arkdown, problemなど広範囲の修正を行なった
  • Loading branch information
yuta6 committed Sep 4, 2024
1 parent ae586d5 commit bfef2f1
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 163 deletions.
55 changes: 25 additions & 30 deletions atcdr/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@
from rich.prompt import Prompt

from atcdr.util.filetype import FILE_EXTENSIONS, Lang
from atcdr.util.parse import (
get_title_from_html,
make_problem_markdown,
repair_html,
title_to_filename,
)
from atcdr.util.parse import ProblemHTML
from atcdr.util.problem import Contest, Diff, Problem
from atcdr.util.session import load_session

Expand All @@ -22,15 +17,15 @@ class Downloader:
def __init__(self) -> None:
self.session = load_session()

def get(self, problem: Problem) -> str:
def get(self, problem: Problem) -> ProblemHTML:
session = self.session
retry_attempts = 3
retry_wait = 1 # 1 second

for _ in range(retry_attempts):
response = session.get(problem.url)
if response.status_code == 200:
return response.text
return ProblemHTML(response.text)
elif response.status_code == 429:
print(
f'[bold yellow][Error {response.status_code}][/bold yellow] 再試行します。{problem}'
Expand All @@ -55,13 +50,7 @@ def get(self, problem: Problem) -> str:
f'[bold red][Error {response.status_code}][/bold red] {problem}に対応するHTMLファイルを取得できませんでした。'
)
break
return ''


def save_file(file_path: str, html: str) -> None:
with open(file_path, 'w', encoding='utf-8') as file:
file.write(html)
print(f'[bold green][+][/bold green] ファイルを保存しました :{file_path}')
return ProblemHTML('')


def mkdir(path: str) -> None:
Expand All @@ -88,32 +77,38 @@ def gene_path_on_num(base: str, problem: Problem) -> str:
)


def title_to_filename(title: str) -> str:
title = re.sub(r'[\\/*?:"<>| !@#$%^&()+=\[\]{};,\']', '', title)
title = re.sub(r'.*?-', '', title)
return title


def generate_problem_directory(
base_path: str, problems: List[Problem], gene_path: Callable[[str, Problem], str]
) -> None:
downloader = Downloader()
for problem in problems:
dir_path = gene_path(base_path, problem)
mkdir(dir_path)
problem_content = downloader.get(problem)
if not problem_content:
print(f'[bold red][Error][/] {problem}の保存に失敗しました')
return
problem_content.repair_me()

html = downloader.get(problem)
if not html:
continue

title = get_title_from_html(html)
if not title:
print('[bold red][Error][/bold red] タイトルが取得できませんでした')
title = f'{problem}'

title = problem_content.title or problem.label
title = title_to_filename(title)

mkdir(dir_path)
repaired_html = repair_html(html)

html_path = os.path.join(dir_path, title + FILE_EXTENSIONS[Lang.HTML])
save_file(html_path, repaired_html)
md = make_problem_markdown(html, 'ja')
with open(html_path, 'w', encoding='utf-8') as file:
file.write(problem_content.html)
print(f'[bold green][+][/bold green] ファイルを保存しました :{html_path}')

md = problem_content.make_problem_markdown('ja')
md_path = os.path.join(dir_path, title + FILE_EXTENSIONS[Lang.MARKDOWN])
save_file(md_path, md)
with open(md_path, 'w', encoding='utf-8') as file:
file.write(md)
print(f'[bold green][+][/bold green] ファイルを保存しました :{md_path}')


def parse_range(match: re.Match) -> List[int]:
Expand Down
14 changes: 7 additions & 7 deletions atcdr/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
LabeledTestCaseResult,
ResultStatus,
TestInformation,
create_testcases_from_html,
judge_code_from,
)
from atcdr.util.execute import execute_files
Expand All @@ -22,7 +21,7 @@
str2lang,
)
from atcdr.util.gpt import ChatGPT, set_api_key
from atcdr.util.parse import make_problem_markdown
from atcdr.util.parse import ProblemHTML


def get_code_from_gpt_output(output: str) -> str:
Expand Down Expand Up @@ -65,7 +64,7 @@ def generate_code(file: Filename, lang: Lang) -> None:
console = Console()
with open(file, 'r') as f:
html_content = f.read()
md = make_problem_markdown(html_content, 'en')
md = ProblemHTML(html_content).make_problem_markdown('en')

if set_api_key() is None:
return
Expand Down Expand Up @@ -96,7 +95,7 @@ def generate_template(file: Filename, lang: Lang) -> None:
console = Console()
with open(file, 'r') as f:
html_content = f.read()
md = make_problem_markdown(html_content, 'en')
md = ProblemHTML(html_content).make_problem_markdown('en')

if set_api_key() is None:
return
Expand Down Expand Up @@ -131,9 +130,10 @@ def generate_template(file: Filename, lang: Lang) -> None:
def solve_problem(file: Filename, lang: Lang) -> None:
console = Console()
with open(file, 'r') as f:
html_content = f.read()
md = make_problem_markdown(html_content, 'en')
labeled_cases = create_testcases_from_html(html_content)
html = ProblemHTML(f.read())

md = html.make_problem_markdown('en')
labeled_cases = html.load_labeled_testcase()

if set_api_key() is None:
return
Expand Down
6 changes: 3 additions & 3 deletions atcdr/markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@

from atcdr.util.execute import execute_files
from atcdr.util.filetype import FILE_EXTENSIONS, Lang
from atcdr.util.parse import make_problem_markdown
from atcdr.util.parse import ProblemHTML


def save_markdown(html_path: str, lang: str) -> None:
console = Console()
with open(html_path, 'r', encoding='utf-8') as f:
html = f.read()
md = make_problem_markdown(html, lang)
html = ProblemHTML(f.read())
md = html.make_problem_markdown(lang)
file_without_ext = os.path.splitext(html_path)[0]
md_path = file_without_ext + FILE_EXTENSIONS[Lang.MARKDOWN]

Expand Down
4 changes: 2 additions & 2 deletions atcdr/open.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from atcdr.util.filetype import Lang
from atcdr.util.execute import execute_files
from atcdr.util.parse import find_link_from_html
from atcdr.util.parse import ProblemHTML


def open_html(file: str) -> None:
Expand All @@ -21,7 +21,7 @@ def open_html(file: str) -> None:
)
return

url = find_link_from_html(html_content)
url = ProblemHTML(html_content).link
if url:
webbrowser.open_new_tab(url)
console.print(
Expand Down
40 changes: 5 additions & 35 deletions atcdr/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from enum import Enum
from typing import Dict, Generator, List, Optional, Tuple, Union

from bs4 import BeautifulSoup as bs
from rich.console import Group, RenderableType
from rich.live import Live
from rich.markup import escape
Expand All @@ -26,6 +25,7 @@
detect_language,
lang2str,
)
from atcdr.util.parse import ProblemHTML


@dataclass
Expand Down Expand Up @@ -76,37 +76,6 @@ class TestInformation:
compile_time: Optional[int] = None


def create_testcases_from_html(html: str) -> List[LabeledTestCase]:
soup = bs(html, 'html.parser')
test_cases = []

for i in range(1, 20):
sample_input_section = soup.find('h3', text=f'Sample Input {i}')
sample_output_section = soup.find('h3', text=f'Sample Output {i}')
if not sample_input_section or not sample_output_section:
break

sample_input_pre = sample_input_section.find_next('pre')
sample_output_pre = sample_output_section.find_next('pre')

sample_input = (
sample_input_pre.get_text(strip=True)
if sample_input_pre is not None
else ''
)
sample_output = (
sample_output_pre.get_text(strip=True)
if sample_output_pre is not None
else ''
)

test_case = TestCase(input=sample_input, output=sample_output)
labeled_test_case = LabeledTestCase(label=f'Sample {i}', case=test_case)
test_cases.append(labeled_test_case)

return test_cases


def run_code(cmd: list, case: TestCase) -> TestCaseResult:
start_time = time.time()
try:
Expand Down Expand Up @@ -454,9 +423,10 @@ def run_test(path_of_code: str) -> None:
with open(html_paths[0], 'r') as file:
html = file.read()

test_cases = create_testcases_from_html(html)
test_results = judge_code_from(test_cases, path_of_code)
render_results(test_results)
ltest_cases = ProblemHTML(html).load_labeled_testcase()

ltest_results = judge_code_from(ltest_cases, path_of_code)
render_results(ltest_results)


def test(*args: str) -> None:
Expand Down
Loading

0 comments on commit bfef2f1

Please sign in to comment.