Source code for ac_core.result

from dataclasses import dataclass
from enum import Enum
import json
import os
import re

from bs4 import BeautifulSoup
from ac_core.constant import _SITE_URL
from ac_core.interfaces.HttpUtil import HttpUtilInterface


[docs]@dataclass class SubmissionResult:
[docs] class Status(Enum): INIT: str = 'Init' PENDING: str = 'Waiting for Judging' RUNNING: str = 'Judging' RE: str = 'Runtime Error' AC: str = 'Accepted' WA: str = 'Wrong Answer' CE: str = 'Compilation Error' TLE: str = 'Time Limit Exceeded'
id: str = '' url: str = '' # json url for refetch score: int = 500 status: Status = Status.INIT time_cost_ms: int = 0 mem_cost_kb: int = 0 msg_txt: str = ''
[docs]def watch_result(url: str) -> str: # sock url, single submissions return ''
# title=\"Compilation Error\"\u003eCE\u003c/span\u003e\u003c/td\u003e","Score":"0"
[docs]def parse_result(resp: str) -> SubmissionResult: """parse submit result get from json result :param resp: the json result get from ``https://atcoder.jp/contests/{contest_id}/submissions/me/status/json?sids[]={submision id}`` :examples: .. code-block:: import requests from ac_core.result import parse_result r = requests.get('https://atcoder.jp/contests/abc101/submissions/me/status/json?sids[]=5371077') if r.status_code == 200: print(parse_result(r.text)) # pass html """ res = json.loads(resp)["Result"] sub_id = list(res.keys())[0] soup = BeautifulSoup(res[sub_id]["Html"], "lxml") tds = soup.find_all('td') status = SubmissionResult.Status(str(tds[0].find('span').attrs.get('title'))) try: score = int(res[sub_id]["Score"]) except: score = 0 try: time_cost_ms = int(tds[1].text.split(" ")[0]) except: time_cost_ms = 0 try: mem_cost_kb = int(tds[2].text.split(" ")[0]) except: mem_cost_kb = 0 msg_txt = '' if status == SubmissionResult.Status.RUNNING: msg_txt = soup.text.strip() return SubmissionResult( id=sub_id, score=score, status=status, time_cost_ms=time_cost_ms, mem_cost_kb=mem_cost_kb, msg_txt=msg_txt, )
[docs]def fetch_result_by_url(http_util: HttpUtilInterface, json_url: str) -> SubmissionResult: """parse submit result by *http_util* with submission *json_url*. :param http_util: e.g. ``requests.session()`` :param json_url: e.g. ``https://atcoder.jp/contests/abc101/submissions/me/status/json?sids[]=5371077`` :examples: .. code-block:: import requests from ac_core.result import fetch_result_by_url print(fetch_result_by_url(requests.session(),'https://atcoder.jp/contests/abc101/submissions/me/status/json?sids[]=5371077')) the structured data returned by :py:func:`fetch_result` has the submission json url .. code-block:: import requests from ac_core.auth import fetch_login, is_logged_in from ac_core.result import fetch_result, fetch_result_by_url h = requests.session() fetch_login(h, 'username', 'password') assert(is_logged_in(h)) result = fetch_result(h,'https://atcoder.jp/contests/abc275/tasks/abc275_f') print(fetch_result_by_url(h,result.url)) """ response = http_util.get(url=json_url) ret = parse_result(resp=response.text) ret.url = json_url return ret
def _problem_url_to_sub_url(problem_url: str) -> str: # problem_url https://atcoder.jp/contests/abc275/tasks/abc275_f r = re.match('^(.*)/tasks/(.*)$', problem_url) assert r is not None prefix = r.group(1) problem_suffix = r.group(2) # https://atcoder.jp/contests/abc275/submissions/me?f.Task=abc275_f return os.path.join(prefix, f'submissions/me?f.Task={problem_suffix}') def _parse_json_url(html: str): soup = BeautifulSoup(html, 'lxml') # <a href='/contests/abc101/submissions/5371227'>Detail</a> r = re.search('<td class="text-center">.*?"/contests/(.*?)/submissions/([0-9]*?)\">Detail</a>', str(soup), re.DOTALL | re.MULTILINE) assert r is not None # no submission return os.path.join(_SITE_URL, f"contests/{r.group(1)}/submissions/me/status/json?sids[]={r.group(2)}")
[docs]def fetch_result(http_util: HttpUtilInterface, problem_url: str) -> SubmissionResult: """parse submit result by *http_util* with *problem_url*. You need logged in before using this method. This function will find your last submission for the problem. :param http_util: e.g. ``requests.session()`` :param problem_url: e.g. ``https://atcoder.jp/contests/abc275/tasks/abc275_f`` :examples: .. code-block:: import requests from ac_core.auth import fetch_login, is_logged_in from ac_core.result import fetch_result h = requests.session() fetch_login(h, 'username', 'password') assert(is_logged_in(h)) print(fetch_result(h,'https://atcoder.jp/contests/abc275/tasks/abc275_f')) """ # https://atcoder.jp/contests/abc275/submissions/me?f.Task=abc275_f submission_url = _problem_url_to_sub_url(problem_url) # <a href='/contests/abc101/submissions/5371227'>Detail</a> # https://atcoder.jp/contests/abc101/submissions/me/status/json?sids[]=5371077 resp = http_util.get(submission_url) json_url = _parse_json_url(resp.text) return fetch_result_by_url(http_util, json_url)