Skip to content

Commit fc29863

Browse files
committed
String PID Support
1 parent b3cafdc commit fc29863

File tree

7 files changed

+23
-12
lines changed

7 files changed

+23
-12
lines changed

vj4/handler/contest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ async def get(self, *, tid: objectid.ObjectId):
132132
file_name='{}.zip'.format(tdoc['title']))
133133

134134

135-
@app.route('/contest/{tid}/{pid:-?\d+|\w{24}}', 'contest_detail_problem')
135+
@app.route('/contest/{tid}/{pid:[A-Z0-9]+}', 'contest_detail_problem')
136136
class ContestDetailProblemHandler(contest.ContestMixin, base.Handler):
137137
@base.route_argument
138138
@base.require_perm(builtin.PERM_VIEW_CONTEST)

vj4/handler/homework.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ async def get(self, *, tid: objectid.ObjectId):
157157
file_name='{}.zip'.format(tdoc['title']))
158158

159159

160-
@app.route('/homework/{tid}/{pid:-?\d+|\w{24}}', 'homework_detail_problem')
160+
@app.route('/homework/{tid}/{pid:[A-Z0-9]+}', 'homework_detail_problem')
161161
class HomeworkDetailProblemHandler(contest.ContestMixin, base.Handler):
162162
@base.route_argument
163163
@base.require_perm(builtin.PERM_VIEW_HOMEWORK)

vj4/handler/problem.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ async def get(self, *, category: str):
185185
self.json_or_redirect(self.referer_or_main)
186186

187187

188-
@app.route('/p/{pid:-?\d+|\w{24}}', 'problem_detail')
188+
@app.route('/p/{pid:[A-Z0-9]+}', 'problem_detail')
189189
class ProblemDetailHandler(base.OperationHandler):
190190
async def _get_related_trainings(self, pid):
191191
if self.has_perm(builtin.PERM_VIEW_TRAINING):
@@ -580,9 +580,8 @@ async def get(self):
580580
@base.post_argument
581581
@base.require_csrf_token
582582
@base.sanitize
583-
async def post(self, *, title: str, content: str, hidden: bool=False, numeric_pid: bool=False):
584-
pid = None
585-
if numeric_pid:
583+
async def post(self, *, title: str, content: str, hidden: bool=False, pid: str):
584+
if not pid:
586585
pid = await domain.inc_pid_counter(self.domain_id)
587586
pid = await problem.add(self.domain_id, title, content, self.user['_id'],
588587
hidden=hidden, pid=pid)

vj4/locale/zh_CN.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,8 @@ display_name: 显示名
773773
home_domain_account: 当前域的设置
774774
'The value `{1}` of {0} already exists.': '{0} 的值 `{1}` 已经存在。'
775775
Display name {1} you want to set is used by others.: 您想要设置的显示名 {1} 已经被其他人使用了。
776-
Numeric PID: 数字题号
776+
Leave blank to use an allocated one.: 留空以自动获取题号
777+
PID: 数字题号
777778
Only {0} problems can be copied in one request, got {1}.: 一次请求只能复制 {0} 个题目,但是您输入了 {1} 个。
778779
Problem is successfully copied.: 题目复制完成。
779780
problem_copy: 复制题目

vj4/model/adaptor/problem.py

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ async def add(domain_id: str, title: str, content: str, owner_uid: int,
3939
category: list=[], tag: list=[], hidden: bool=False):
4040
validator.check_title(title)
4141
validator.check_content(content)
42+
validator.check_pid(pid)
4243
pid = await document.add(domain_id, content, owner_uid, document.TYPE_PROBLEM,
4344
pid, title=title, data=data, category=category, tag=tag,
4445
hidden=hidden, num_submit=0, num_accept=0)

vj4/ui/templates/problem_edit.html

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@
66
<div class="section__body">
77
<form method="post">
88
<div class="row">
9-
<div class="medium-8 columns">
9+
<div class="medium-7 columns">
1010
<label>
1111
{{ _('Title') }}
1212
<input name="title" placeholder="{{ _('title') }}" value="{{ pdoc['title']|default('') }}" class="textbox" autofocus>
1313
</label>
1414
</div>
1515
{% if page_name == 'problem_create' %}
16-
<div class="medium-2 columns">
16+
<div class="medium-3 columns">
1717
<label>
18-
{{ _('Settings') }}
18+
{{ _('PID') }}
1919
<br>
20-
<label class="checkbox">
21-
<input type="checkbox" name="numeric_pid" value="on" checked>{{ _('Numeric PID') }}
20+
<label>
21+
<input name="pid" placeholder="{{ _('Leave blank to use an allocated one.') }}" class="textbox">
2222
</label>
2323
</label>
2424
</div>

vj4/util/validator.py

+10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
ID_RE = re.compile(r'[^\\/\s\u3000]([^\\/\n\r]*[^\\/\s\u3000])?')
1313
ROLE_RE = re.compile(r'[_0-9A-Za-z]{1,256}')
1414
DOMAIN_INVITATION_CODE_RE = re.compile(r'[0-9A-Za-z]{1,64}')
15+
PID_RE = re.compile(r'[0-9A-Z]{1,23}')
1516

1617

1718
def is_uid(s):
@@ -23,6 +24,15 @@ def check_uid(s):
2324
raise error.ValidationError('uid')
2425

2526

27+
def is_pid(s):
28+
return bool(PID_RE.fullmatch(s))
29+
30+
31+
def check_uid(s):
32+
if not is_pid(s):
33+
raise error.ValidationError('pid')
34+
35+
2636
def is_uname(s):
2737
return bool(UNAME_RE.fullmatch(s))
2838

0 commit comments

Comments
 (0)