This repository has been archived by the owner on Jun 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
__init__.py
141 lines (123 loc) · 5.04 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/python
# -*- coding: utf-8 -*-
# TODO use swagger based autogenerated library for implementing these functions
# TODO use colors for heading and contests
from ...models import Judge
from ...utils.logging import logger
import click
import requests
import json
from .utils import get_data, login_oauth, login_web
from beautifultable import BeautifulTable
import os
ALLOW_WEB = False
class Codechef(Judge):
def __init__(self, session_data=None):
# Init should not have any network requests
# do them in login, logout, check_running_contest
logger.debug("Initializing class Codechef with session_data:\n%s"
% session_data)
self.name = "Codechef"
self.url = "https://www.codechef.com"
self.api_url = "https://api.codechef.com"
# In case main api is down, use the env CODECHEF_WEB
# as a feature switch to use the browser based Non
# authenticated API. This is very helpful for testing
self.CODECHEF_WEB = (
'TERMICODER_CODECHEF_WEB' in os.environ and
os.environ['TERMICODER_CODECHEF_WEB'].lower() == 'true'
and ALLOW_WEB)
if(self.CODECHEF_WEB):
self.api_url = "https://www.codechef.com/api"
self.session_data = session_data
if(session_data is not None):
self._update_session()
def check_login(self):
logger.debug("Checking Login")
if(self.session is None):
logger.debug("No session object initialized")
return False
path = 'user/me' if self.CODECHEF_WEB else 'users/me'
me_url = self._make_url(path)
r = self._request_api(me_url)
def login(self):
if self.CODECHEF_WEB:
token = login_web(self)
else:
token = login_oauth()
self.session_data = token
self._update_session()
self.check_login()
def logout(self):
logger.warning("Logout of CodeChef.")
click.confirm("Are you sure?", default=True, abort=True)
self.session_data = None
def get_running_contests(self):
logger.debug('get running contests')
contests = get_data.running_contests(self)
table = BeautifulTable()
table.width_exceed_policy = BeautifulTable.WEP_WRAP
# TODO: use map style.headers instead of str
# requires change with beautifultable. we may try dev version
table.column_headers = list(
map(str, ['code', 'name', 'end', 'start']))
for contest in contests:
table.append_row(
[
contest['code'], contest['name'],
str(contest['startDate']), str(contest['endDate'])
]
)
return table
# This method serves both as a problem getter as well as kind of factory
# for problem
def get_problem(self, problem_name, contest_name, problem_data=None):
# If problem data is passed, it should take precedence
# Method should call the respective Problem.__init__ method to create a
# problem instance and return it
raise NotImplementedError
def get_contest(self, contest_name, contest_data=None):
# If contest data is passed, it should take precedence
# Method should call the respective Problem.__init__ method to create a
# problem instance and return it
pass
def _update_session(self):
self.session = requests.Session()
def debug_url(r, *args, **kwargs):
logger.debug('Getting url %s' % r.url)
def debug_data(r, *args, **kwargs):
try:
response = json.dumps(r.json(), indent=1)
except json.JSONDecodeError:
response = r.text
logger.debug('Response %s' % response)
self.session.hooks['response'].append(debug_url)
self.session.hooks['response'].append(debug_data)
if(self.CODECHEF_WEB and 'cookies' in self.session_data):
logger.debug(self.session_data['cookies'])
self.session.cookies = self.session_data['cookies']
elif('data' in self.session_data):
logger.debug('Token: ' + self.session_data['data']['access_token'])
OAuth2_Header = {
'Authorization': 'Bearer ' +
self.session_data['data']['access_token']
}
self.session.headers.update(OAuth2_Header)
def _make_url(self, rel_url):
rel_url = rel_url.strip('/')
api_url = self.api_url.strip('/')
return "/".join([api_url, rel_url])
def _request_api(self, url):
logger.debug('fetching url %s' % url)
with self.session as s:
r = s.get(url)
logger.debug(r)
r.raise_for_status()
return r.json()
def _refresh_token(self):
logger.debug('refreshing token')
url = 'http://termicoder.diveshuttam.me/refresh_token/'
raise NotImplementedError
# TODO implement this on server side
r = requests.get(url, data=self.session_data)
logger.debug(r.json())