Пример #1
0
def do_hijack(self, cmd):
    """
    usage: hijack <stolen_cookie>

    Set the SID and cookie to the stolen ones.
    """
    brutejudge.cheats.cheating(self)
    if cmd.strip() == '':
        return self.do_help('hijack')
    try:
        a, b = cmd.strip().split('-')
        int(a, 16)
        int(b, 16)
    except Exception:
        raise BruteError("Invalid cookie: " + cmd.strip())
    if not isinstance(self.url, Ejudge):
        raise BruteError("Testing system is not ejudge")
    if isinstance(self.url, Informatics):
        raise BruteError("informatics.msk.ru is not supported")
    self.url.urls = {
        k: v.replace(self.url['sid'], a)
        for k, v in self.url.items()
    }
    self.url.cookie = 'EJSID=' + b
    if isinstance(self.url, EJFuse):
        self.url.cookies = (a, b)
Пример #2
0
 def download_file(self, prob_id, filename):
     code, headers, data = self._cache_get(self.urls['download_file'].format(prob_id=prob_id, filename=filename))
     if code == 404:
         raise BruteError("File not found.")
     elif code != 200:
         raise BruteError("Error downloading.")
     return data
Пример #3
0
 def tasks(self):
     code, headers, data = self._cache_get(self.urls['summary'])
     if b'<input type="submit" name="action_35" value="Change!" />' in data:
         raise BruteError("Password change is required.")
     if code != 200:
         raise BruteError("Failed to fetch task list.")
     data = data.decode('utf-8')
     #tl = self._task_list(data)
     ti = self._task_ids(data)
     #if len(tl) < len(ti): tl.extend([None]*(len(ti)-len(tl)))
     #else: ti.extend([None]*(len(tl)-len(ti)))
     return [bjtypes.task_t(i, j, None) for i, j in ti]
Пример #4
0
 def status(self):
     code, headers, data = self._cache_get(self.urls['summary'])
     if b'<input type="submit" name="action_35" value="Change!" />' in data:
         raise BruteError("Password change is required.")
     if code != 200:
         raise BruteError("Failed to fetch task list")
     ths = [i.split('</th>', 1)[0] for i in data.decode('utf-8').split('<th class="b1">')[1:]]
     w = len(ths)
     if w == 0: return {}
     splitted = data.decode('utf-8').split('<td class="b1">')[1:]
     data = [x.split("</td>")[0] for x in splitted]
     idx = ths.index('Status')
     return collections.OrderedDict((a, b if b != '&nbsp;' else None) for a, b in zip(data[ths.index('Short name')::w], data[idx::w]))
Пример #5
0
def do_samples(self, cmd):
    """
    usage: samples [--binary] <submission_id> (<dump_dir> || --input || --output || --correct || --stderr || --checker)

    Dump sample test cases from a submission. If a flag is specified, dump the corresponding files to standard output.
    """
    if len(cmd.split(' ')) < 2:
        return self.do_help("samples")
    cmd, ddir = cmd.split(' ', 1)
    kwargs = {}
    if cmd == '--binary':
        if not has_feature(self.url, self.cookie, 'get_samples', 'binary'):
            raise BruteError(
                "This system does not support --binary in samples.")
        kwargs['binary'] = True
        if len(ddir.split(' ')) < 2:
            return self.do_help("samples")
        cmd, ddir = ddir.split(' ', 1)
    if not cmd.isnumeric():
        raise BruteError("Submission ID must be a number")
    tests = get_samples(self.url, self.cookie, int(cmd), **kwargs)
    flags = {
        '--input': 'Input',
        '--output': 'Output',
        '--correct': 'Correct',
        '--stderr': 'Stderr',
        '--checker': 'Checker output'
    }
    if ddir not in flags:
        os.makedirs(ddir)
    out_sep = False
    for k, v in tests.items():
        for what, data in v.items():
            if ddir in flags:
                if what == flags[ddir]:
                    if out_sep: print('#' * 20)
                    else: out_sep = True
                    (sys.stdout.buffer
                     if 'binary' in kwargs else sys.stdout).write(data)
                    (sys.stdout.buffer
                     if 'binary' in kwargs else sys.stdout).flush()
                continue
            if what == 'Input':
                suff = ''
            elif what == 'Correct':
                suff = '.a'
            else:
                suff = '_' + what.replace(' ', '_') + '.txt'
            with open(os.path.join(ddir, '%02d' % k + suff),
                      'wb' if 'binary' in kwargs else 'w') as file:
                file.write(data)
Пример #6
0
 def compile_error(self, id):
     code, headers, data = self._cache_get(self.urls['protocol'].format(run_id=id))
     if b'<input type="submit" name="action_35" value="Change!" />' in data:
         raise BruteError("Password change is required.")
     if code != 200:
         raise BruteError("Failed to fetch testing protocol.")
     splitted = data.decode('utf-8').split('<pre>')[1:]
     ans = []
     for i in splitted:
         i = i.split('</pre>')[0]
         i = i.split('<')
         i = i[0] + ''.join(j.split('>', 1)[1] for j in i[1:])
         import html
         ans.append(html.unescape(i))
     return '\n'.join(ans)
Пример #7
0
 def _get_submissions(self):
     with self.cache_lock:
         if self._gs_cache != None: return self._gs_cache
     data = self.opener.open(self.base_url + '/my?locale=en')
     if data.geturl() not in (self.base_url + '/my',
                              self.base_url + '/my?locale=en'):
         raise BruteError("Failed to fetch submission list")
     data = data.read().decode('utf-8', 'replace')
     csrf = self._get_csrf(data)
     data = data.replace(
         '<tr class="last-row" data-submission-id="',
         '<tr data-submission-id="').split('<tr data-submission-id="')
     subms = []
     for i in data[1:]:
         subm_id = int(i.split('"', 1)[0])
         meta = {}
         data2 = i.split('>', 1)[1].split('</tr>', 1)[0].split('<td')
         for j in data2[1:]:
             try:
                 cls = j.split('class="', 1)[1].split('"', 1)[0]
             except IndexError:
                 cls = None
             data = j.split('>', 1)[1].split('</td>', 1)[0]
             meta[cls] = data
         subms.append((subm_id, meta))
     ans = (subms, csrf)
     with self.cache_lock:
         if self.caching: self._gs_cache = ans
     return ans
Пример #8
0
def do_incat(self, cmd):
    """
    usage: incat [--base64] <task> <filepath> [savepath]

    Tries to retrieve the specified ASCII file using .incbin directive.
    The data will be base64-encoded if --base64 is specified.
    """
    brutejudge.cheats.cheating(self)
    data = shlex.split(cmd)
    filter = ''
    if data and data[0] == '--base64':
        filter = base64_filter
        del data[0]
    if len(data) not in (2, 3):
        return self.do_help('incat')
    data.append(None)
    task, filepath, savepath = data[:3]
    task_list = tasks(self.url, self.cookie)
    for i in task_list:
        if i[1] == task:
            task_id = i[0]
            break
    else:
        raise BruteError("No such task.")
    if savepath == None:
        f = sys.stdout
    else:
        f = open(savepath, "w")
    incat(self, task, task_id, filepath, f, filter=filter)
    if savepath != None: f.close()
Пример #9
0
def do_astatus(self, cmd):
    """
    usage: astatus <subm_id>

    Fancy testing progress display
    """
    subm_id = cmd.strip()
    if not subm_id.isnumeric():
        return self.do_help('astatus')
    chars = '\\|/-'
    idx = 0
    prev = ''
    subm_id = int(subm_id)
    while True:
        try:
            cur = next(i.status for i in submissions(self.url, self.cookie)
                       if i.id == subm_id)
        except StopIteration:
            raise BruteError('No such submission')
        cur = cur.strip()
        sys.stderr.write(' ' * len(prev) + '\r')
        sys.stderr.flush()
        if still_running(cur):
            prev = '%%%ds' % len(prev) % (cur + ' ' + chars[idx])
            idx = (idx + 1) % 4
            #           print(prev)
            sys.stderr.write(prev + '\r')
            sys.stderr.flush()
        else:
            print(cur)
            break
Пример #10
0
def get_tailcode(self, subm_id, suf):
    if submission_status(self.url, self.cookie,
                         subm_id) not in ('Compilation error',
                                          'Compiler failed'):
        raise BruteError("Submission didn't fail to compile")
    err = compile_error(self.url, self.cookie, subm_id)
    if err == None: err = ''
    err = err.strip()
    lines = {}
    it = iter(err.split('\n'))
    for line in it:
        if not line[:1].isspace():
            l = (line + ':::').split(':')
            if l[0].endswith(suf) and l[1].isnumeric() and l[2].isnumeric():
                lineno = int(l[1])
                if lineno not in lines:
                    try:
                        lines[lineno] = next(it).strip()
                    except StopIteration:
                        break
    if not lines: return ''
    minno = min(lines)
    maxno = max(lines)
    ans = ''
    for i in range(minno, maxno + 1):
        ans += lines.get(i, '###### FAILED TO FETCH ######') + '\n'
    return ans
Пример #11
0
 def __init__(self, url, login, password):
     Backend.__init__(self)
     self.locale = 'en'
     if '#locale=' in url:
         url, self.locale = url.rsplit('#locale=', 1)
     if url.startswith('http:'):
         url = 'https:' + url[5:]
     if url.find('/contest') == url.find('/contests'):
         url = '/contest'.join(url.split('/contests', 1))
     self.base_url = url
     self.handle = login
     self.host = url.split('/')[2]
     self.opener = OpenerWrapper(
         urllib.request.build_opener(urllib.request.HTTPCookieProcessor))
     csrf = self._get_csrf(
         self.opener.open('https://%s/enter?back=%%2F' %
                          self.host).read().decode('utf-8', 'replace'))
     ln = self.opener.open(
         'https://%s/enter?back=%%2F' % self.host,
         urllib.parse.urlencode({
             'csrf_token': csrf,
             'action': 'enter',
             'ftaa': '',
             'bfaa': '',
             'handleOrEmail': login,
             'password': password
         }).encode('ascii'))
     if ln.geturl() != 'https://%s/' % self.host:
         raise BruteError("Login failed.")
     self._gs_cache = None
     self._st_cache = None
     self._subms_cache = {}
Пример #12
0
 def _get_samples(self, err):
     if err == None: err = ''
     err = err.strip()
     if "====== Test #" not in err:
         raise BruteError("No test cases available")
     err = err[err.find("====== Test #"):]
     lines = iter(err.split('\n'))
     tests = {}
     curr = None
     for line in lines:
         if line.startswith("====== Test #"):
             num = int(line[13:-7])
             curr = tests[num] = {}
         elif line.startswith('--- '):
             line = line[4:-4]
             if ': size ' not in line: continue
             what, size = line.split(': size ')
             size = int(size) + 1
             data = ''
             while len(data) < size:
                 try: data += '\n' + next(lines)
                 except StopIteration: break
             data = data[1:]
             curr[what] = data
     return tests
Пример #13
0
 def contest_info(self):
     code, headers, data = self._cache_get(self.urls['contest_info'])
     if b'<input type="submit" name="action_35" value="Change!" />' in data:
         raise BruteError("Password change is required.")
     data = data.decode('utf-8')
     try: pbs = '\n'.join(html.unescape(i.split('</b></p>', 1)[0]) for i in data.split('<p><b>')[1:])
     except IndexError: pbs = ''
     datas = {}
     for i in data.split('<tr><td class="b0">')[1:]:
         i = i.split('</td></tr>', 1)[0] 
         try: key, value = i.split('<td class="b0">')
         except IndexError: pass
         else: datas[html.unescape(key.split('</td>', 1)[0])] = html.unescape(value)
     data1 = {}
     for k1, k2 in (('server_time', 'Server time:'), ('contest_start', 'Contest start time'), ('contest_duration', 'Duration:')):
         if k2 not in datas: continue
         if datas[k2] == 'Unlimited':
             data1[k1] = math.inf
             continue
         if ' ' in datas[k2]:
             date, s_time = datas[k2].split(' ')
             year, month, day = map(int, date.split('/'))
             hour, minute, second = map(int, s_time.split(':'))
             data1[k1] = time.mktime((year, month, day, hour, minute, second, -1, -1, -1))
         else:
             data1[k1] = 0
             for i in map(int, datas[k2].split(':')):
                 data1[k1] = data1[k1] * 60 + i
     if 'contest_start' in data1 and 'contest_duration' in data1:
         data1['contest_end'] = data1['contest_start'] + data1['contest_duration']
     if 'contest_start' in data1 and 'server_time' in data1:
         data1['contest_time'] = data1['server_time'] - data1['contest_start']
     return (pbs, datas, data1)
Пример #14
0
def do_info(self, cmd):
    """
    usage: info [-t] [task]

    Show testing information and problem statement for a task, or for the whole contest if task is not specified.
    If -t is specified, attempt to decode embedded TeX expressions into human-readable form.
    """
    cmd = cmd.strip()
    tex = False
    if cmd[:2] == '-t' and (len(cmd) == 2 or cmd[2:3].isspace()):
        tex = True
        cmd = cmd[2:].strip()
    if cmd == '--help':
        return self.do_help('info')
    if cmd:
        try: task_id = next(i.id for i in tasks(self.url, self.cookie) if i.short_name == cmd)
        except StopIteration:
            raise BruteError("No such task.")
        a, b = problem_info(self.url, self.cookie, task_id)
    else:
        b, a, j = contest_info(self.url, self.cookie)
        print(j)
    for k, v in a.items(): print(k+': '+v)
    print()
    print(untex(b) if tex else b)
Пример #15
0
 def submission_protocol(self, id):
     code, headers, data = self._cache_get(self.urls['protocol'].format(run_id=id))
     if b'<input type="submit" name="action_35" value="Change!" />' in data:
         raise BruteError("Password change is required.")
     if code != 200:
         raise BruteError("Failed to fetch testing protocol.")
     w = data.count(b'<th ')
     if w == 0: return []
     splitted = data.decode('utf-8').split('<td class="b1">')[1:]
     data = [x.split("</td>")[0] for x in splitted]
     statuses = [i[:-7].split('>')[-1] for i in data[1::w]]
     tls = []
     for i in map(html.unescape, data[2::w]):
         if i.startswith('>'): i = i[1:]
         tls.append(float(i))
     assert len(statuses) == len(tls)
     return [bjtypes.test_t(i, {'time_usage': j}) for i, j in zip(statuses, tls)]
Пример #16
0
 def scores(self, *, total=None):
     code, headers, data = self._cache_get(self.urls['summary'])
     if b'<input type="submit" name="action_35" value="Change!" />' in data:
         raise BruteError("Password change is required.")
     if code != 200:
         raise BruteError("Failed to fetch task list")
     data0 = data.decode('utf-8')
     ths = [i.split('</th>', 1)[0] for i in data0.split('<th class="b1">')[1:]]
     w = len(ths)
     splitted = data.decode('utf-8').split('<td class="b1">')[1:]
     data = [x.split("</td>")[0] for x in splitted]
     if 'Score' not in ths: ans = {}
     else: ans = collections.OrderedDict(zip(data[ths.index('Short name')::w], [None if x == '&nbsp;' else int(x) for x in data[ths.index('Score')::w]]))
     if total != None and '<p><big>Total score: ' in data0:
         try: ans[total] = int(data0.split('<p><big>Total score: ', 1)[1].split('</big></p>', 1)[0])
         except (ValueError, IndexError): pass
     return ans
Пример #17
0
 def submission_source(self, id):
     code, headers, data = self._cache_get(self.urls['source'].format(run_id=id))
     rhd = dict(headers)
     if 'html' in rhd['Content-Type'] and b'<input type="submit" name="action_35" value="Change!" />' in data:
         raise BruteError("Password change is required.")
     if code != 200 or 'html' in rhd['Content-Type']:
         return None
     return data
Пример #18
0
def login(url, login, password, **kwds):
    for i in backend_path:
        try:
            f = i.detect(url)
        except Exception:
            f = False
        if f:
            return (i(url, login, password, **kwds), True)
    raise BruteError("Unknown CMS")
Пример #19
0
 def clar_list(self):
     code, headers, data = self._cache_get(self.urls['clars'])
     if b'<input type="submit" name="action_35" value="Change!" />' in data:
         raise BruteError("Password change is required.")
     ths = [i.split('</th>', 1)[0] for i in data.decode('utf-8').split('<th class="b1">')[1:]]
     w = len(ths)
     splitted = data.decode('utf-8').split('<td class="b1">')[1:]
     data = [x.split("</td>")[0] for x in splitted]
     return [bjtypes.clar_t(i, j) for i, j in zip(map(int, data[ths.index('Clar ID')::w]), map(html.unescape, data[ths.index('Subject')::w]))]
Пример #20
0
def do_brute(self, cmd):
    """
    usage: brute <task> <reader> [dump_path] [max_count]

    Tries to retrieve the test cases using binary search.
    """
    brutejudge.cheats.cheating(self)
    sp = cmd.split()
    if len(sp) not in range(2, 5):
        return self.do_help('brute')
    tasks = task_list(self.url, self.cookie)
    try:
        task_id = tasks.index(sp[0])
    except ValueError:
        raise BruteError("No such task.")
    try:
        with open(sp[1]) as file:
            code = file.read()
    except FileNotFoundError:
        raise BruteError("File not found.")
    srch = Searcher(self.url,
                    self.cookie,
                    task_id,
                    input_file=getattr(self, 'input_file', None),
                    output_file=getattr(self, 'output_file', None))
    max_tests = -1
    if len(sp) == 4:
        try:
            max_tests = int(sp[3])
        except ValueError:
            raise BruteError("max_tests must be a number")
    srch.execute(code, max_tests)
    if len(sp) == 2 or sp[2] == '-':
        from sys import stdout as file
        do_close = False
    else:
        try:
            file = open(sp[2], "a")
        except IOError as e:
            raise BruteError("Error creating output file: " + str(e))
        do_close = True
    for i, t in enumerate(srch.tests):
        print("---------- test #", i, sep='', file=file)
        print(t, file=file)
Пример #21
0
def get_lang_id(self, lang_name, task_id):
    lang_id = [
        i for i, j, k in compiler_list(self.url, self.cookie, task_id)
        if j == lang_name
    ]
    try:
        lang_id, = lang_id
    except ValueError:
        raise BruteError("Unknown language: " + lang_name)
    return lang_id
Пример #22
0
def do_control(self, cmd):
    """
    usage: do_control <action> [args]

    `action` can be one of:
        start-virtual
        Start virtual contest.

        stop-virtual
        Stop virtual contest.
    """
    cmd = cmd.strip()
    if cmd == 'start-virtual':
        if not do_action(self.url, self.cookie):
            raise BruteError("Failed to start virtual contest")
    elif cmd == 'stop-virtual':
        if not do_action(self.url, self.cookie):
            raise BruteError("Failed to stop virtual contest")
    else:
        return self.do_help('control')
Пример #23
0
 def scores(self):
     tli = self.tasks()
     ans = collections.OrderedDict()
     for task in tli:
         code, headers, data = self._cache_get(self.url+'?SID=%s&EJSID=%s&action=problem-status-json&problem=%%d&json=1'%self.cookies%task.id, False)
         data = mb_problem_status(data)
         if code != 200 or not data or not data['ok']:
             raise BruteError("Failed to fetch task list.")
         try: ans[task.short_name] = data['result']['problem_status']['best_score']
         except KeyError: ans[task.short_name] = None
     return ans
Пример #24
0
 def scoreboard(self):
     code, headers, data = self._cache_get(self.urls['standings'])
     if b'<input type="submit" name="action_35" value="Change!" />' in data:
         raise BruteError("Password change is required.")
     if code != 200:
         raise BruteError("Failed to fetch scoreboard.")
     teams = data.decode('utf-8').split('<td  class="st_team">')[1:]
     probs = data.decode('utf-8').split('<td  class="st_prob')[1:]
     naux = 0
     if not teams and b'<table border=1 cellspacing=1 celpadding=3>\n  <tr >\n    <th  align=right>Place</th>' in data:
         probs = sum((i.split('<td class="st_prob') for i in data.decode('utf-8').split('<td  align=center')), [])[1:]
         teams = data.decode('utf-8').split('<td  align=left>')[1:]
         naux = 1
     probs = [x.split("</td>", 1)[0] for x in probs]
     teams = [html.unescape(x.split("</td>", 1)[0]) for x in teams]
     try: ntasks = len(probs) // len(teams) - naux
     except ZeroDivisionError: return []
     del teams[-3:]
     del probs[-3*ntasks:]
     probs = iter(probs)
     ans = []
     for i in teams:
         ans.append(({'name': i}, []))
         for j in range(ntasks):
             j = next(probs).split('>', 1)[1]
             if j == '&nbsp;': ans[-1][1].append(None)
             elif j[:1] in ('+', '-'):
                 attempts = int(j[0]+'0'+j[1:])
                 ans[-1][1].append({'attempts': attempts})
             elif j.startswith('<b>') and j.endswith('</b>') and j[3:-4].isnumeric():
                 score = int(j[3:-4])
                 attempts = float('inf')
                 ans[-1][1].append({'score': score, 'attempts': attempts})
             elif j.isnumeric():
                 score = int(j)
                 attempts = float('-inf')
                 ans[-1][1].append({'score': score, 'attempts': attempts})
             else:
                 assert False, repr(j)
         for j in range(naux): next(probs)
     return ans
Пример #25
0
 def submissions(self):
     code, headers, data = self._cache_get(self.urls['submissions'])
     if b'<input type="submit" name="action_35" value="Change!" />' in data:
         raise BruteError("Password change is required.")
     if code != 200:
         raise BruteError("Failed to fetch submission list.")
     ths = [i.split('</th>', 1)[0] for i in data.decode('utf-8').split('<th class="b1">')[1:]]
     w = len(ths)
     if w == 0: return []
     splitted = data.decode('utf-8').split('<td class="b1">')[1:]
     data = [x.split("</td>")[0] for x in splitted]
     run_ids = list(map(lambda x:(int(x[:-1]) if x[-1:] == '#' else int(x)), data[ths.index('Run ID')::w]))
     task_ids = data[ths.index('Problem')::w]
     if 'Result' in ths:
         statuses = data[ths.index('Result')::w]
     else:
         statuses = [None]*len(run_ids)
     if 'Score' in ths:
         scores = []
         for i in data[ths.index('Score')::w]:
             i = i.strip()
             if i.startswith('<b>'): i = i[3:].split('</b>', 1)[0] # TODO: report score_ex in submission_stats
             i = i.strip()
             if i in ('', 'N/A', '&nbsp;'): scores.append(None)
             else: scores.append(int(i))
     else:
         scores = [None]*len(run_ids)
     if 'Tests passed' in ths:
         oktests = []
         for i in data[ths.index('Tests passed')::w]:
             i = i.strip()
             if i.startswith('<b>'): i = i[3:]
             if i.endswith('</b>'): i = i[:-4]
             i = i.strip()
             if i in ('', 'N/A', '&nbsp;'): oktests.append(None)
             else: oktests.append(int(i))
     else:
         oktests = [None]*len(run_ids)
     assert len(run_ids) == len(task_ids) == len(statuses) == len(scores) == len(oktests)
     return [bjtypes.submission_t(i, j, k, l, m) for i, j, k, l, m in zip(run_ids, task_ids, statuses, scores, oktests)]
Пример #26
0
 def __init__(self, url, login, password):
     Backend.__init__(self)
     url0 = url
     url = url.replace('/new-register?', '/new-client?')
     contest_id = url.split("contest_id=")[1].split("&")[0]
     self.contest_id = int(contest_id)
     base_url = url.split("?")[0]
     code, headers, data = post(url0.split("?")[0], {'contest_id': contest_id, 'locale_id': 0, 'login': login, 'password': password, 'action_213': ''})
     if code != 302:
         raise BruteError("Login failed.")
     rhd = dict(headers)
     base_url = rhd['Location'].split('&')[0]
     base_url = base_url.replace('/new-register?', '/new-client?')
     if 'new-client?SID=' in base_url:
         urls = ej371.get_urls(base_url)
     elif any(i in base_url for i in ('/user/', '/client/', '/register/', '/register?SID=')):
         urls = ej373.get_urls(base_url)
     else:
         raise BruteError("Unknown ejudge version.")
     self.urls = urls
     self.cookie = rhd["Set-Cookie"].split(";")[0]
     self._get_cache = {}
Пример #27
0
 def compiler_list(self, prob_id):
     code, headers, data = self._cache_get(self.urls['submission'].format(prob_id=prob_id))
     if b'<input type="submit" name="action_35" value="Change!" />' in data:
         raise BruteError("Password change is required.")
     data = data.decode('utf-8')
     if '<input type="hidden" name="lang_id" value="' in data:
         data = data.split('<input type="hidden" name="lang_id" value="', 1)[1]
         num_id = int(data.split('"', 1)[0])
         lit_id = html.unescape(data.split('</td><td class="b0">', 1)[1].split('</td>', 1)[0])
         short, long = lit_id.strip().split(' - ')
         return [bjtypes.compiler_t(num_id, short, long)]
     try: data = data.split('<select name="lang_id">', 1)[1].split('</select>', 1)[0]
     except IndexError: raise BruteError("Failed to fetch language list")
     data = data.split('<option ')[1:]
     ans = [] 
     for i in data:
         a, b = (' '+i).split(' value="', 1)[1].split('"', 1)
         b = b.split('>', 1)[1].split('</option>', 1)[0]
         if not a.isnumeric(): continue
         b, c = html.unescape(b).split(' - ')
         ans.append(bjtypes.compiler_t(int(a), b.strip(), c.strip()))
     return ans
Пример #28
0
 def __init__(self, url, login, password):
     Backend.__init__(self)
     url, params = url.split('?')
     url = url.replace('+jjs', '', 1)
     if url.endswith('/'): url = url[:-1]
     params = {k: v for k, v in (i.split('=', 1) if '=' in i else (i, None) for i in params.split('&'))}
     contest_id = params['contest']
     if params.get('auth', None) == 'token':
         self.cookie = 'Bearer '+password
     elif params.get('auth', None) == 'gettoken':
         sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
         sock.connect('/tmp/jjs-auth-sock')
         token = b''
         while True:
             chk = sock.recv(1024)
             token += chk
             if not chk: break
         token = token.decode('ascii').strip()
         if not (token.startswith('===') and token.endswith('===')):
             raise BruteError('Login failed: failed to get token from jjs-auth-sock')
         self.cookie = 'Bearer '+token[3:-3]
     elif params.get('auth', None) == 'guest':
         self.cookie = 'Bearer Guest'
     else:
         code, headers, data = json_req(url + '/auth/simple', {'login': login, 'password': password})
         if code != 200:
             try: msg = 'Login failed: %s'%data['detail']
             except Exception: msg = 'Login failed.'
             raise BruteError(msg)
         self.cookie = 'Bearer '+data['data']
     self.url = url
     self.params = params
     self.contest = contest_id
     self.lsu_cache = {}
     self._get_cache = {}
     code, headers, data = json_req(url + '/contests/' + urlescape(self.contest), None, {'Authorization': self.cookie})
     if code != 200 or data == None:
         raise BruteError('Login failed: unknown contest')
Пример #29
0
 def __init__(self, url, login, password):
     Backend.__init__(self)
     assert url.startswith('ejfuse:http://') or url.startswith('ejfuse:https://')
     url = url[7:].replace('/new-register?', '/new-client?').replace('/new-client?', '/client?')
     contest_id = url.split("contest_id=")[1].split("&")[0]
     self.contest_id = int(contest_id)
     base_url = url.split("/client?")[0]
     code, headers, data = post(base_url+'/register', {'action': 'login-json', 'login': login, 'password': password, 'json': 1})
     data = mbjson(data)
     if code != 200 or not data or not data['ok']:
         raise BruteError("Login failed.")
     self.url = base_url+'/register'
     self.cookies = (data['result']['SID'], data['result']['EJSID'])
     code, headers, data = post(self.url, {'SID': self.cookies[0], 'EJSID': self.cookies[1], 'action': 'enter-contest-json', 'contest_id': self.contest_id, 'json': 1})
     data = mbjson(data)
     if code != 200 or not data or not data['ok']:
         raise BruteError("Login failed.")
     self.url = base_url+'/client'
     self.cookies = (data['result']['SID'], data['result']['EJSID'])
     # will fall back to normal ejudge if an unimplemented feature is encountered
     self.urls = get_urls(base_url+'/new-client?SID='+self.cookies[0])
     self.cookie = 'EJSID='+self.cookies[1]
     self._get_cache = {}
Пример #30
0
def do_getsource(self, cmd):
    """
    usage: getsource <submission_id> <shell command>

    Retrieve the source code of a submission.
    """
    id, cmd = (cmd.strip()+' ').split(' ', 1)
    if not id.isnumeric():
        return self.do_help('getsource')
    src = submission_source(self.url, self.cookie, int(id))
    if src == None:
        raise BruteError('Source code is not available')
    p = subprocess.Popen('cat '+cmd, stdin=subprocess.PIPE, shell=True)
    p.stdin.write(src)
    p.stdin.close()
    p.wait()