예제 #1
0
 def get_user_info(self, contest_cid, course_oj_username):
     oj_username = course_oj_username.oj_username
     pass_list = []
     rank = 0
     http = SpiderHttp()
     url = 'https://ac.nowcoder.com/acm-heavy/acm/contest/' \
           'real-time-rank-data?id={}&' \
           'searchUserName={}'.format(contest_cid, quote(oj_username))
     res = http.get(url=url).json()
     if res['msg'] != 'OK':
         return {'success': False, 'data': None}
     problem_dict = {}
     for problem_info in res['data']['problemData']:
         problem_dict[problem_info['problemId']] = problem_info['name']
     for item in res['data']['rankData']:
         if item['userName'] != oj_username:
             continue
         rank = item['ranking']
         for problem_info in item['scoreList']:
             if not problem_info['accepted']:
                 continue
             pass_list.append(problem_dict[problem_info['problemId']])
     if rank == 0:
         return {'success': False, 'data': None}
     result = {
         'success': True,
         'data': {
             'pass_list': pass_list,
             'rank': rank
         }
     }
     return result
예제 #2
0
 def _get_gym_contest_rating(contest_id):
     star_rating = [DEFAULT_PROBLEM_RATING, 1200, 1600, 2000, 2400, 2800]
     mapping = Mapping.get_by_id('gym-{}'.format(contest_id))
     stars = mapping.value
     if stars:
         return star_rating[int(stars)]
     url = 'https://codeforces.com/gyms'
     req = SpiderHttp()
     res = req.get(url=url)
     soup = BeautifulSoup(res.text, 'lxml')
     token = soup.find('input', {'name': 'csrf_token'})['value']
     res = req.post(url=url,
                    data={
                        'csrf_token': token,
                        'searchByNameOrIdQuery': contest_id,
                        'searchByProblem': False,
                    })
     soup = BeautifulSoup(res.text, 'lxml')
     stars = len(
         soup.find('tr', {
             'data-contestid': contest_id
         }).findAll('img'))
     mapping.modify(value=str(stars))
     return star_rating[stars]
예제 #3
0
class VjudgeSpider(BaseSpider):
    def __init__(self):
        self.vjudge_http = SpiderHttp()

    def get_user_info(self, oj_username, accept_problems):
        username = oj_username.oj_username
        password = oj_username.oj_password
        try:
            cookie = json.loads(oj_username.oj_cookies)
            headers = {'Cookie': Cookie.dict_to_str(cookie)}
            self.vjudge_http.headers.update(headers)
            assert self.check_login_status() == username
        except:
            try:
                cookie = self._get_cookies(username, password)
            except:
                return {'success': False, 'data': []}
            headers = {'Cookie': Cookie.dict_to_str(cookie)}
            self.vjudge_http.headers.update(headers)
            assert self.check_login_status() == username

        oj_username.modify(oj_cookies=json.dumps(cookie, sort_keys=True))

        accept_problem_list = []
        success = False
        start = 0
        length = 20
        ok = False
        while not ok:
            url = "https://vjudge.net/status/data/?&length=20&res=1&start={}&un={}".format(
                start, username)
            res = self.vjudge_http.get(url=url).json()
            if not res['data']:
                break
            success = True
            for submission in res['data']:
                if submission['statusCanonical'] != 'AC':
                    continue
                time_stamp = submission['time'] / 1000
                accept_time = timestamp_to_str(time_stamp)
                oj = self._change_oj_name(submission['oj'])
                problem_id = submission['probNum']
                if accept_problems.get('{}-{}'.format(
                        oj, problem_id)) == accept_time:
                    ok = True
                    continue
                accept_problem_list.append({
                    'oj': oj,
                    'problem_pid': problem_id,
                    'accept_time': accept_time
                })
            start += length

        return {'success': success, 'data': accept_problem_list}

    def check_login_status(self):
        url = 'https://vjudge.net/user/update'
        res = self.vjudge_http.get(url=url).json()
        return res.get('username', None)

    def _get_cookies(self, username, password):
        url = 'https://vjudge.net/user/login'
        data = {'username': username, 'password': password}
        res = self.vjudge_http.post(url=url, data=data).text
        if res == 'success':
            return Cookie.str_to_dict(
                Cookie.dict_to_str(self.vjudge_http.sess.cookies))
        raise Exception(res)

    def get_problem_info(self, problem_id):
        pass

    @staticmethod
    def _change_oj_name(name):
        name = name.lower()
        if name == 'gym':
            name = 'codeforces'
        elif name == 'zju':
            name = 'zoj'
        elif name == 'pku':
            name = 'poj'
        elif name == '计蒜客':
            name = 'jisuanke'
        elif name == 'uvalive':
            name = 'uva'
        elif name == 'libreoj':
            name = 'loj'
        return name
예제 #4
0
class ZuccSpider(BaseSpider):
    zucc_http = SpiderHttp()

    def __init__(self):
        try:
            self.check_cookie()
        except AssertionError:
            self.get_new_cookie()
            self.check_cookie()

    def check_cookie(self):
        self.zucc_http = SpiderHttp()
        mapping = Mapping.get_by_id('zucc-cookie')
        cookie = json.loads(mapping.value)
        for k, v in cookie.items():
            self.zucc_http.sess.cookies.set(k, v)
        self.zucc_http.sess.cookies.set("lang", "cn")
        assert self.check_login_status() == ZUCC_ID

    def get_new_cookie(self):
        self.zucc_http = SpiderHttp()
        self.login(ZUCC_ID, ZUCC_PASSWORD)
        assert self.check_login_status() == ZUCC_ID
        cookie = {}
        for i in self.zucc_http.sess.cookies:
            cookie[i.name] = i.value
        Mapping.get_by_id('zucc-cookie').modify(
            value=json.dumps(cookie, sort_keys=True))

    def get_user_info(self, oj_username, accept_problems):
        username = oj_username.oj_username
        if not self._judge_user(username):
            return {'success': False, 'data': []}
        accept_problem_list = []
        url = 'http://acm.zucc.edu.cn/status.php?user_id={}'.format(username)
        ok = False
        while not ok:
            res = self.zucc_http.get(url=url)
            soup = BeautifulSoup(res.text, 'lxml')
            trs = soup.find('tbody').find_all('tr')
            next = -1
            if not trs:
                break
            for tr in trs:
                tds = tr.find_all('td')
                next = int(tds[0].text)
                status = tds[3].find_all('a')[0]['class']
                if 'label-success' not in status:
                    continue
                problem_id = tds[2].text
                accept_time = tds[8].text
                accept_time = re.findall(
                    r'\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}',
                    accept_time)[0]
                if accept_problems.get('zucc-' + problem_id) == accept_time:
                    ok = True
                    continue
                accept_problem_list.append({
                    'oj': 'zucc',
                    'problem_pid': problem_id,
                    'accept_time': accept_time
                })
            new_url = 'http://acm.zucc.edu.cn/status.php?user_id={}&top={}'.format(
                username, next - 1)
            if new_url == url:
                break
            url = new_url
        return {'success': True, 'data': accept_problem_list}

    def get_problem_info(self, problem_id):
        url = 'http://acm.zucc.edu.cn/problem.php?id={}'.format(problem_id)
        res = self.zucc_http.get(url=url)
        try:
            total = int(
                re.search(r'Submit: </span>(\d+)(&nbsp;)*<span',
                          res.text).group(1))
            accept = int(
                re.search(r'Solved: </span>(\d+)(&nbsp;)*<br>',
                          res.text).group(1))
            rating = DEFAULT_PROBLEM_RATING
        except:
            rating = DEFAULT_PROBLEM_RATING

        return {'rating': rating}

    def _judge_user(self, username):
        url = 'http://acm.zucc.edu.cn/userinfo.php?user={}'.format(username)
        res = self.zucc_http.get(url=url)
        return not re.findall(r"No such User!", res.text)

    def check_login_status(self):
        url = 'http://acm.zucc.edu.cn/template/bs3/profile.php'
        res = self.zucc_http.get(url=url)
        try:
            return re.search(
                r'document\.getElementById\("profile"\)\.innerHTML="(.*)";',
                res.text).group(1)
        except:
            return None

    def _get_csrf_value(self):
        url = 'http://acm.zucc.edu.cn/csrf.php'
        res = self.zucc_http.get(url=url)
        return re.search(r'value="(.*?)"', res.text).group(1)

    def login(self, username, password):
        url = 'http://acm.zucc.edu.cn/login.php'
        data = {
            'user_id': username,
            'password': password,
            'csrf': self._get_csrf_value()
        }
        res = self.zucc_http.post(url=url, data=data)