Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Zheng Yile
codiaclient
Commits
0d3d8593
Commit
0d3d8593
authored
May 31, 2021
by
Zheng Yile
Browse files
Add function `startpack`; Update requests
parent
06113ad8
Pipeline
#662
failed with stages
in 0 seconds
Changes
6
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
0d3d8593
...
...
@@ -68,7 +68,7 @@ pid, eid 可以通过客户端查询, 也可以在网页端访问的链接中获
### 取消指定题包
`pid`
或
`p`
.
`
del
pid`
.
取消指定题包.
### 指定题目
...
...
@@ -81,6 +81,11 @@ pid, eid 可以通过客户端查询, 也可以在网页端访问的链接中获
`getexercise`
或
`ge`
.
查看题目内容. 该函数可以指定返回类型, 直接调用默认为
*dict*
, 在查询时默认为
*json*
.
## 开始题包
`startpack`
.
开始一个题包的答题. 返回类型为
*json*
.
## 提交代码
`open PATH`
.
...
...
@@ -89,8 +94,7 @@ pid, eid 可以通过客户端查询, 也可以在网页端访问的链接中获
`submit`
.
提交代码到服务器评测. 直接调用函数的返回类型为
*requests.Response*
, 查询时没有返回.
根据 pid, eid 的值确定提交的题目,并以
`solutioncode`
的内容作为提交的代码.
*Tips: 提交之前请确保 `pid`, `eid`正确。可以获取题面以验证,方法参照:[查看题目内容](#查看题目内容)。另外建议提交之前检查一遍 `solutioncode`. 查询方法参照:[查看程序运行中的变量](#查看程序运行中的变量)。*
*Tips: 如果在提交题包中的题目的代码前没有开始过这个题包,可能会无法记录提交结果。开始题包方法参照:[开始题包](#开始题包)。提交之前请确保 `pid`, `eid`正确。可以获取题面以验证,方法参照:[查看题目内容](#查看题目内容)。另外建议提交之前检查一遍 `solutioncode`. 查询方法参照:[查看程序运行中的变量](#查看程序运行中的变量)。*
## 查询提交过的代码
...
...
@@ -105,7 +109,7 @@ pid, eid 可以通过客户端查询, 也可以在网页端访问的链接中获
## 查看程序运行中的变量
`show [VAR]`
.
查看变量名为VAR的变量; 若没有指定变量名, 则返回
所有变量
*(包括 `username`, `pid`, `eid`, `lang`, `solutioncode`)*
. 返回类型为
*json*
.
查看变量名为VAR的变量; 若没有指定变量名, 则返回
`requests.variables`
中的所有变量
. 返回类型为
*json*
.
# 辅助功能
## 接口相关
...
...
@@ -120,4 +124,4 @@ pid, eid 可以通过客户端查询, 也可以在网页端访问的链接中获
这种记录方法在绝大多数情况下保证无法从配置文件中获取密码的值,并且在密码不正确时不能获取对应的cookie.
在登录时会首先尝试匹配配置中的信息。成功匹配则直接使用配置中的cookie尝试登录,失败则会向服务器提交数据以获得新的cookie.
若在启动程序时加上
`--no-cache`
的选项,则会禁用配置,即不会往配置文件中写入信息,也不会从配置文件中读取信息。
**但已经写入的数据不会删除。**
若在启动程序时加上
`--no-cache`
的选项,则会禁用配置,即不会往配置文件中写入信息,也不会从配置文件中读取信息。
**但已经写入的数据不会删除。**
\ No newline at end of file
codiaclient/__init__.py
View file @
0d3d8593
from
.network
import
variables
as
net_var
,
client_login
,
logined
from
.network
import
variables
as
net_var
,
client_login
from
.argparse
import
ArgParser
from
.requests
import
variables
as
requests_var
,
requests
from
.report
import
variables
as
report_var
...
...
codiaclient/network.py
View file @
0d3d8593
...
...
@@ -3,7 +3,13 @@ from .utils import passwd_hash, cookie_encrypt, cookie_decrypt
from
.cachectrl
import
variables
as
cache_var
,
cache_for_login
as
cache
import
json
variables
=
{
'register'
:
False
'register'
:
False
,
'me'
:
{
'username'
:
None
,
'nickname'
:
None
,
'email'
:
None
,
'verified'
:
None
,
},
}
url
=
'https://code.bdaa.pro/graphql/'
coding_base_headers
=
{
...
...
@@ -95,7 +101,7 @@ def client_login(username, password = None, cookie = None):
coding_base_headers
[
'cookie'
]
=
cookie_decrypt
(
cache_var
[
'logindic'
][
username
][
'cookie'
],
password
)
report
(
"Using cached cookie."
)
displayName
=
logined
()
if
displayName
:
report
(
"
Login succeeded.({})
"
.
format
(
displayName
))
if
displayName
:
report
(
'
Login succeeded.({})
'
.
format
(
displayName
))
else
:
report
(
'Invalid cached cookie.'
,
1
)
login
(
username
,
password
)
...
...
@@ -108,7 +114,7 @@ def client_login(username, password = None, cookie = None):
else
:
report
(
'Invalid cookie input.'
,
3
)
else
:
report
(
'No username or cookie specified.'
,
3
)
def
logined
():
def
logined
(
reportUnverified
:
bool
=
True
):
headers
=
coding_base_headers
.
copy
()
data
=
json
.
dumps
({
"operationName"
:
None
,
...
...
@@ -129,7 +135,16 @@ def logined():
if
not
res
:
return
False
res_data
=
json
.
loads
(
res
.
text
)
if
'errors'
in
res_data
:
return
False
else
:
return
res_data
[
'data'
][
'me'
][
'displayName'
]
else
:
if
reportUnverified
and
not
res_data
[
'data'
][
'me'
][
'verified'
]:
report
(
"The user has not verified."
,
1
)
if
not
res_data
[
'data'
][
'me'
][
'displayName'
]:
res_data
[
'data'
][
'me'
][
'displayName'
]
=
"UNDEFINED"
variables
[
'me'
][
'username'
]
=
res_data
[
'data'
][
'me'
][
'login'
]
variables
[
'me'
][
'nickname'
]
=
res_data
[
'data'
][
'me'
][
'displayName'
]
variables
[
'me'
][
'email'
]
=
res_data
[
'data'
][
'me'
][
'defaultEmail'
]
variables
[
'me'
][
'verified'
]
=
res_data
[
'data'
][
'me'
][
'verified'
]
return
res_data
[
'data'
][
'me'
][
'displayName'
]
def
login
(
username
,
passwd
):
report
(
'Try login.'
)
...
...
@@ -362,6 +377,9 @@ query pack($pid: ID!) {
title
}
}
viewerStatus {
ongoing
}
}
}
}'''
})
...
...
@@ -369,6 +387,51 @@ query pack($pid: ID!) {
if
not
res
:
return
False
return
json
.
loads
(
res
.
text
)[
'data'
][
'node'
]
def
start_pack
(
pid
):
if
show_pack
(
pid
)[
'viewerStatus'
][
'ongoing'
]:
report
(
"This pack is already ongoing."
,
1
)
return
None
headers
=
coding_base_headers
.
copy
()
data
=
json
.
dumps
({
"operationName"
:
"startSession"
,
"variables"
:
{
"pid"
:
pid
},
"query"
:
r
'''
mutation startSession($pid: ID!, $code: String) {
startSession(exercisePackId: $pid, code: $code) {
id
codingExercises {
passedCount
totalCount
edges {
node { id }
userStatus {
attempted
passed
}
}
}
pack {
id
description { content }
codingExercises {
nodes {
id
title
}
}
viewerStatus {
ongoing
due
}
}
}
}'''
})
res
=
post
(
url
=
url
,
headers
=
headers
,
data
=
data
)
if
not
res
:
return
False
return
json
.
loads
(
res
.
text
)[
'data'
][
'startSession'
]
def
_login
(
username
,
passwd
):
headers
=
login_base_headers
.
copy
()
data
=
json
.
dumps
({
...
...
codiaclient/requests.py
View file @
0d3d8593
from
.network
import
get_exercise
,
get_data
,
submit
,
get_pack
,
show_pack
from
.network
import
variables
as
net_var
,
get_exercise
,
get_data
,
submit
,
get_pack
,
show_pack
,
start_pack
from
.report
import
report
from
.utils
import
AliasesDict
import
json
variables
=
{
aliases
=
{
'p'
:
'pid'
,
'e'
:
'eid'
,
'l'
:
'lang'
,
'sc'
:
'solutioncode'
,
}
variables
=
AliasesDict
({
'pid'
:
None
,
'eid'
:
None
,
'lang'
:
None
,
'solutioncode'
:
None
,
'username'
:
None
}
'solutioncode'
:
None
},
aliases
)
class
r
equests
:
class
R
equests
:
queryres
=
""
help_txt
=
"We haven't provide the help text. If you need, please read the code in 'codiaclient/requests.py' to help understanding."
def
__str__
(
self
):
return
self
.
queryres
def
show_msg
(
self
,
qres
):
if
type
(
qres
)
!=
str
:
qres
=
str
(
qres
)
else
:
pass
...
...
@@ -23,17 +27,7 @@ class requests:
self
.
queryres
+=
'
\n
'
def
__init__
(
self
,
conf
:
dict
):
p
=
variables
[
'pid'
]
e
=
variables
[
'eid'
]
l
=
variables
[
'lang'
]
sc
=
variables
[
'solutioncode'
]
un
=
variables
[
'username'
]
pid
=
variables
[
'pid'
]
eid
=
variables
[
'eid'
]
lang
=
variables
[
'lang'
]
solutioncode
=
variables
[
'solutioncode'
]
username
=
variables
[
'username'
]
variables
.
update
(
net_var
[
'me'
])
self
.
queryres
=
""
if
len
(
conf
)
==
0
:
pass
else
:
...
...
@@ -42,57 +36,56 @@ class requests:
elif
conf
[
0
]
in
[
'h'
,
'help'
]:
if
len
(
conf
)
==
1
:
self
.
show_msg
(
self
.
help_txt
)
else
:
report
(
'Invalid request.'
,
1
)
elif
conf
[
0
]
in
[
'p'
,
'pid'
]:
if
len
(
conf
)
==
2
:
variables
[
'pid'
]
=
conf
[
1
]
elif
len
(
conf
)
==
1
:
variables
[
'pid'
]
=
None
else
:
report
(
'Invalid request.'
,
1
)
elif
conf
[
0
]
in
[
'e'
,
'eid'
]:
if
len
(
conf
)
==
2
:
variables
[
'eid'
]
=
conf
[
1
]
elif
len
(
conf
)
==
1
:
variables
[
'eid'
]
=
None
else
:
report
(
'Invalid request.'
,
1
)
elif
conf
[
0
]
in
[
'l'
,
'lang'
]:
if
len
(
conf
)
==
2
:
variables
[
'lang'
]
=
conf
[
1
]
elif
len
(
conf
)
==
1
:
variables
[
'lang'
]
=
None
else
:
report
(
'Invalid request.'
,
1
)
elif
conf
[
0
]
in
[
'sc'
,
'solutioncode'
]:
if
len
(
conf
)
==
1
:
variables
[
'solutioncode'
]
=
None
elif
conf
[
0
]
in
variables
or
conf
[
0
]
in
aliases
:
if
len
(
conf
)
==
2
:
variables
[
conf
[
0
]]
=
conf
[
1
]
else
:
report
(
'Use `show VAR` to show the variables.'
,
1
)
elif
conf
[
0
]
in
[
'del'
,
'reset'
]:
if
len
(
conf
)
==
2
:
if
conf
[
1
]
in
variables
or
conf
[
1
]
in
aliases
:
variables
[
conf
[
1
]]
=
None
else
:
report
(
'Variable `{}` doesn
\'
t exist.'
.
format
(
conf
[
1
]),
1
)
elif
len
(
conf
)
==
1
:
for
x
in
variables
:
variables
[
x
]
=
None
else
:
report
(
'Invalid request.'
,
1
)
elif
conf
[
0
]
in
[
'o'
,
'open'
]:
if
len
(
conf
)
==
1
:
with
open
(
conf
[
1
],
encoding
=
'utf-8'
)
as
f
:
variables
[
'solutioncode'
]
=
f
.
read
()
if
len
(
conf
)
>=
2
:
path
=
' '
.
join
(
conf
[
1
:])
while
path
[:
1
]
==
' '
:
path
=
path
[
1
:]
while
path
[
-
1
:]
==
' '
:
path
=
path
[:
-
1
]
if
path
[:
1
]
==
'
\"
'
:
path
=
path
[
1
:]
if
path
[
-
1
:]
==
'
\"
'
:
path
=
path
[:
-
1
]
try
:
with
open
(
path
,
encoding
=
'utf-8'
)
as
f
:
variables
[
'sc'
]
=
f
.
read
()
except
OSError
as
e
:
report
(
e
,
1
)
else
:
report
(
'Invalid request.'
,
1
)
elif
conf
[
0
]
in
[
'show'
]:
if
len
(
conf
)
==
1
:
self
.
show_msg
(
json
.
dumps
({
"username"
:
username
,
"pid"
:
pid
,
"eid"
:
eid
,
"lang"
:
lang
,
"solutioncode"
:
solutioncode
}))
self
.
show_msg
(
json
.
dumps
(
variables
))
elif
len
(
conf
)
==
2
:
try
:
self
.
show_msg
(
json
.
dumps
({
conf
[
1
]:
e
va
l
(
conf
[
1
]
)
}))
try
:
self
.
show_msg
(
json
.
dumps
({
conf
[
1
]:
va
riables
[
conf
[
1
]
]
}))
except
Exception
as
e
:
report
(
e
.
__repr__
(),
1
)
else
:
report
(
'Invalid request.'
,
1
)
elif
conf
[
0
]
in
[
'ge'
,
'getex'
,
'getexercise'
]:
if
eid
:
res
=
get_exercise
(
eid
=
eid
,
pid
=
pid
,
lang
=
lang
,
feedback
=
'json'
)
if
variables
[
'e'
]
:
res
=
get_exercise
(
eid
=
variables
[
'e'
],
pid
=
variables
[
'p'
],
lang
=
variables
[
'l'
]
,
feedback
=
'json'
)
self
.
show_msg
(
res
)
else
:
report
(
"No eid specified."
,
1
)
elif
conf
[
0
]
in
[
'gc'
,
'getc'
,
'getcode'
]:
# getcode [[N] to [PATH]]
if
len
(
conf
)
<=
2
:
if
eid
:
if
variables
[
'e'
]
:
if
len
(
conf
)
==
1
:
res
=
get_data
(
eid
=
eid
,
pid
=
pid
)
res
=
get_data
(
eid
=
variables
[
'e'
],
pid
=
variables
[
'p'
]
)
self
.
show_msg
(
json
.
dumps
(
res
[
0
][
'solution'
][
'asset'
][
'content'
]))
elif
len
(
conf
)
==
2
:
if
conf
[
1
]
==
'to'
:
res
=
get_data
(
eid
=
eid
,
pid
=
pid
)
res
=
get_data
(
eid
=
variables
[
'e'
],
pid
=
variables
[
'p'
]
)
try
:
with
open
(
'./tmp.txt'
,
'w'
,
encoding
=
'utf-8'
)
as
f
:
f
.
write
(
res
[
0
][
'solution'
][
'asset'
][
'content'
])
except
Exception
as
e
:
report
(
e
,
1
)
else
:
try
:
res
=
get_data
(
eid
=
eid
,
pid
=
pid
,
codecnt
=
int
(
conf
[
1
]))
try
:
res
=
get_data
(
eid
=
variables
[
'e'
],
pid
=
variables
[
'p'
]
,
codecnt
=
int
(
conf
[
1
]))
except
ValueError
:
report
(
'Invalid request: type(codecnt) should be int.'
,
1
)
else
:
if
res
==
None
:
report
(
'Invalid request.'
,
1
)
...
...
@@ -101,12 +94,12 @@ class requests:
else
:
report
(
"No eid specified."
,
1
)
elif
len
(
conf
)
==
3
:
if
conf
[
1
]
==
'to'
:
res
=
get_data
(
eid
=
eid
,
pid
=
pid
)
res
=
get_data
(
eid
=
variables
[
'e'
],
pid
=
variables
[
'p'
]
)
try
:
with
open
(
conf
[
2
],
'w'
,
encoding
=
'utf-8'
)
as
f
:
f
.
write
(
res
[
0
][
'solution'
][
'asset'
][
'content'
])
except
Exception
as
e
:
report
(
e
,
1
)
elif
conf
[
2
]
==
'to'
:
try
:
res
=
get_data
(
eid
=
eid
,
pid
=
pid
,
codecnt
=
int
(
conf
[
1
]))
try
:
res
=
get_data
(
eid
=
variables
[
'e'
],
pid
=
variables
[
'p'
]
,
codecnt
=
int
(
conf
[
1
]))
except
ValueError
:
report
(
'Invalid request: type(lastcnt) should be int.'
,
1
)
else
:
try
:
...
...
@@ -115,7 +108,7 @@ class requests:
else
:
report
(
'Invalid request.'
,
1
)
elif
len
(
conf
)
==
4
:
if
conf
[
2
]
==
'to'
:
try
:
res
=
get_data
(
eid
=
eid
,
pid
=
pid
,
codecnt
=
int
(
conf
[
1
]))
try
:
res
=
get_data
(
eid
=
variables
[
'e'
],
pid
=
variables
[
'p'
]
,
codecnt
=
int
(
conf
[
1
]))
except
ValueError
:
report
(
'Invalid request: type(codecnt) should be int.'
,
1
)
else
:
try
:
...
...
@@ -125,7 +118,7 @@ class requests:
else
:
report
(
'Invalid request.'
,
1
)
elif
conf
[
0
]
in
[
'submit'
]:
if
len
(
conf
)
==
1
:
if
eid
:
res
=
submit
(
eid
=
eid
,
pid
=
pid
,
lang
=
lang
,
solutioncode
=
solutioncode
)
if
variables
[
'e'
]
:
res
=
submit
(
eid
=
variables
[
'e'
],
pid
=
variables
[
'p'
],
lang
=
variables
[
'l'
]
,
solutioncode
=
variables
[
'sc'
]
)
else
:
report
(
"No eid specified."
,
1
)
else
:
report
(
'Invalid request.'
,
1
)
elif
conf
[
0
]
in
[
'gp'
,
'getp'
,
'getpack'
]:
#getpack [N] [before PID]
...
...
@@ -154,10 +147,10 @@ class requests:
else
:
report
(
'Invalid request.'
,
1
)
elif
conf
[
0
]
in
[
'gr'
,
'getr'
,
'getres'
,
'getreport'
,
'getreports'
]:
if
len
(
conf
)
<=
2
:
if
eid
:
if
len
(
conf
)
==
1
:
res
=
get_data
(
eid
=
eid
,
pid
=
pid
)
if
variables
[
'e'
]
:
if
len
(
conf
)
==
1
:
res
=
get_data
(
eid
=
variables
[
'e'
],
pid
=
variables
[
'p'
]
)
elif
len
(
conf
)
==
2
:
try
:
res
=
get_data
(
eid
=
eid
,
pid
=
pid
,
codecnt
=
int
(
conf
[
1
]))
try
:
res
=
get_data
(
eid
=
variables
[
'e'
],
pid
=
variables
[
'p'
]
,
codecnt
=
int
(
conf
[
1
]))
except
ValueError
:
report
(
'Invalid request: type(codecnt) should be int.'
,
1
)
return
...
...
@@ -176,9 +169,20 @@ class requests:
else
:
report
(
'Invalid request.'
,
1
)
elif
conf
[
0
]
in
[
'sp'
,
'showp'
,
'showpack'
]:
if
len
(
conf
)
==
1
:
if
pid
:
res
=
show_pack
(
pid
)
if
variables
[
'p'
]:
res
=
show_pack
(
variables
[
'p'
])
self
.
show_msg
(
json
.
dumps
(
res
))
else
:
report
(
"No pid specified."
,
1
)
else
:
report
(
'Invalid request.'
,
1
)
elif
conf
[
0
]
in
[
'startp'
,
'startpack'
]:
if
len
(
conf
)
==
1
:
if
variables
[
'p'
]:
res
=
start_pack
(
variables
[
'p'
])
self
.
show_msg
(
json
.
dumps
(
res
))
else
:
report
(
"No pid specified."
,
1
)
else
:
report
(
'Invalid request.'
,
1
)
else
:
report
(
'Invalid request.'
,
1
)
def
requests
(
conf
:
dict
):
res
=
Requests
(
conf
)
return
res
.
queryres
\ No newline at end of file
codiaclient/utils.py
View file @
0d3d8593
from
.report
import
report
class
AliasesDict
(
dict
):
aliaseslist
=
{}
def
__init__
(
self
,
dict
,
aliaseslist
=
{}):
self
.
aliaseslist
=
aliaseslist
super
().
__init__
(
dict
)
def
__getitem__
(
self
,
attr
):
if
attr
in
self
.
aliaseslist
:
return
super
().
__getitem__
(
self
.
aliaseslist
[
attr
])
else
:
return
super
().
__getitem__
(
attr
)
def
__setitem__
(
self
,
key
,
value
):
if
key
in
self
.
aliaseslist
:
return
super
().
__setitem__
(
self
.
aliaseslist
[
key
],
value
)
else
:
return
super
().
__setitem__
(
key
,
value
)
def
passwd_hash
(
passwd
):
try
:
from
hashlib
import
new
...
...
@@ -23,3 +35,4 @@ def cookie_encrypt(cookie, passwd):
def
cookie_decrypt
(
_cookie
,
passwd
):
return
str
(
AES
.
new
(
add_to_16
(
passwd
),
AES
.
MODE_ECB
).
decrypt
(
base64
.
decodebytes
(
_cookie
.
encode
(
encoding
=
'utf-8'
))),
encoding
=
'utf-8'
).
replace
(
'
\x00
'
,
''
)
run.py
View file @
0d3d8593
...
...
@@ -11,16 +11,15 @@ if __name__ == "__main__":
if
args
.
origin
:
variables
[
'origin'
]
=
True
if
cc
.
cache_var
[
'cacheOn'
]:
cc
.
cache_load
()
cc
.
report_var
[
'allow_error_deg'
]
=
args
.
allow_error_deg
cc
.
requests_var
[
'l
ang
'
]
=
args
.
lang
cc
.
requests_var
[
'e
id
'
]
=
args
.
eid
cc
.
requests_var
[
'p
id
'
]
=
args
.
pid
cc
.
requests_var
[
'l'
]
=
args
.
lang
cc
.
requests_var
[
'e'
]
=
args
.
eid
cc
.
requests_var
[
'p'
]
=
args
.
pid
if
args
.
open
:
cc
.
requests_var
[
's
olutioncode
'
]
=
args
.
open
.
read
()
cc
.
requests_var
[
's
c
'
]
=
args
.
open
.
read
()
args
.
open
.
close
()
cc
.
client_login
(
username
=
args
.
username
,
password
=
args
.
passwd
,
cookie
=
args
.
cookie
)
cc
.
requests_var
[
'username'
]
=
cc
.
logined
()
if
args
.
request_string
:
try
:
if
not
variables
[
'origin'
]:
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment