Source code for onlinejudge.service.csacademy

# Python Version: 3.x
"""
the module for CS Academy (https://csacademy.com/)
"""

import json
import re
import urllib.parse
from typing import *

import requests

import onlinejudge._implementation.logging as log
import onlinejudge._implementation.utils as utils
import onlinejudge.type
from onlinejudge.type import TestCase


[docs]class CSAcademyService(onlinejudge.type.Service):
[docs] def get_url(self) -> str: return 'https://csacademy.com/'
[docs] def get_name(self) -> str: return 'CS Academy'
[docs] @classmethod def from_url(cls, url: str) -> Optional['CSAcademyService']: # example: https://csacademy.com/ result = urllib.parse.urlparse(url) if result.scheme in ('', 'http', 'https') \ and result.netloc in ('csacademy.com', 'www.csacademy.com'): return cls() return None
[docs]class CSAcademyProblem(onlinejudge.type.Problem): def __init__(self, *, contest_name: str, task_name: str): self.contest_name = contest_name self.task_name = task_name
[docs] def download_sample_cases(self, *, session: Optional[requests.Session] = None) -> List[TestCase]: session = session or utils.get_default_session() base_url = self.get_url() # get csrftoken resp = utils.request('GET', base_url, session=session) csrftoken = None for cookie in session.cookies: if cookie.name == 'csrftoken' and cookie.domain == 'csacademy.com': # type: ignore csrftoken = cookie.value # type: ignore if csrftoken is None: log.error('csrftoken is not found') return [] # get config headers = { 'x-csrftoken': csrftoken, 'x-requested-with': 'XMLHttpRequest', } contest_url = 'https://csacademy.com/contest/{}/'.format(self.contest_name) resp = utils.request('GET', contest_url, session=session, headers=headers) # parse config assert resp.encoding is None config = json.loads(resp.content.decode()) # NOTE: Should I memoize this? Is the CSAcademyRound class required? task_config = None for it in config['state']['contesttask']: if it['name'] == self.task_name: task_config = it if task_config is None: log.error('no such task: %s', self.task_name) return [] # get get_contest_task_url = 'https://csacademy.com/contest/get_contest_task/' payload = {'contestTaskId': (None, str(task_config['id']))} headers = { 'x-csrftoken': csrftoken, 'x-requested-with': 'XMLHttpRequest', 'Referer': base_url, } resp = utils.request('POST', get_contest_task_url, session=session, files=payload, headers=headers) # parse assert resp.encoding is None contest_task = json.loads(resp.content.decode()) # NOTE: Should I memoize this? if contest_task.get('title') == 'Page not found': log.error('something wrong') return [] samples = [] for test_number, example_test in enumerate(contest_task['state']['EvalTask'][0]['exampleTests']): inname = 'Input {}'.format(test_number) outname = 'Output {}'.format(test_number) samples += [TestCase( 'sample-{}'.format(test_number + 1), inname, example_test['input'].encode(), outname, example_test['output'].encode(), )] return samples
[docs] def get_url(self) -> str: return 'https://csacademy.com/content/{}/task/{}/'.format(self.contest_name, self.task_name)
[docs] def get_service(self) -> CSAcademyService: return CSAcademyService()
[docs] @classmethod def from_url(cls, url: str) -> Optional['CSAcademyProblem']: # example: https://csacademy.com/contest/round-38/task/path-union/ # example: https://csacademy.com/contest/round-38/task/path-union/discussion/ # example: https://csacademy.com/contest/archive/task/swap_permutation/ # example: https://csacademy.com/contest/archive/task/swap_permutation/statement/ result = urllib.parse.urlparse(url) if result.scheme in ('', 'http', 'https') \ and result.netloc in ('csacademy.com', 'www.csacademy.com'): m = re.match(r'^/contest/([0-9A-Za-z_-]+)/task/([0-9A-Za-z_-]+)(|/statement|/solution|/discussion|/statistics|/submissions)/?$', utils.normpath(result.path)) if m: return cls(contest_name=m.group(1), task_name=m.group(2)) return None
onlinejudge.dispatch.services += [CSAcademyService] onlinejudge.dispatch.problems += [CSAcademyProblem]