record_main & record_detail

This commit is contained in:
masnn committed 2020-04-04 12:14:10 +08:00
1 parent ffa193b5dd
commit 5b4f5b6520
37 files changed
+222 -266

No files matched your search

+1 -1
View File
@@ -21,7 +21,7 @@ class ForbiddenError extends UserFacingError {
} }
class NotFoundError extends UserFacingError { class NotFoundError extends UserFacingError {
constructor(type) { constructor(type) {
super(type); super(type || 'NotFoundError');
this.code = 404; this.code = 404;
} }
} }
+1
View File
@@ -44,6 +44,7 @@ MIDDLEWARE(async (ctx, next) => {
} }
} }
}; };
ctx.csrf_token = await token.add(token.TYPE_CSRF_TOKEN, 600, ctx.path);
console.log(ctx.session.uid); console.log(ctx.session.uid);
await next(); await next();
if (ctx.session.sid) if (ctx.session.sid)
+10 -1
View File
@@ -41,9 +41,18 @@ GET('/p/:pid', requirePerm(PERM_VIEW_PROBLEM), async ctx => {
ctx.templateName = 'problem_detail.html'; ctx.templateName = 'problem_detail.html';
ctx.body = { pdoc, udoc, title: pdoc.title }; ctx.body = { pdoc, udoc, title: pdoc.title };
}); });
GET('/p/:pid/submit', requirePerm(PERM_SUBMIT_PROBLEM), async ctx => {
let uid = ctx.state.user._id,
pid = ctx.params.pid;
let pdoc = await problem.get({ pid, uid });
if (pdoc.hidden) ctx.checkPerm(PERM_VIEW_PROBLEM_HIDDEN);
let udoc = await user.getById(pdoc.owner);
ctx.templateName = 'problem_submit.html';
ctx.body = { pdoc, udoc, title: pdoc.title };
});
POST('/p/:pid/submit', requirePerm(PERM_SUBMIT_PROBLEM), async ctx => { POST('/p/:pid/submit', requirePerm(PERM_SUBMIT_PROBLEM), async ctx => {
let rid = await record.add({ let rid = await record.add({
creator: ctx.state.user._id, uid: ctx.state.user._id,
lang: ctx.request.body.language, lang: ctx.request.body.language,
code: ctx.request.body.code, code: ctx.request.body.code,
pid: ctx.params.pid pid: ctx.params.pid
+11 -2
View File
@@ -3,19 +3,28 @@ const
{ constants } = require('../options'), { constants } = require('../options'),
{ GET } = require('../service/server'), { GET } = require('../service/server'),
record = require('../model/record'), record = require('../model/record'),
user = require('../model/user'),
problem = require('../model/problem'),
{ PERM_READ_RECORD_CODE, PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD } = require('../permission'); { PERM_READ_RECORD_CODE, PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD } = require('../permission');
GET('/r', async ctx => { GET('/r', async ctx => {
let q = {}, let q = {},
page = ctx.query.page || 1; page = ctx.query.page || 1;
let rdocs = await record.getMany(q, { rid: 1 }, page, constants.RECORD_PER_PAGE); let rdocs = await record.getMany(q, { rid: 1 }, page, constants.RECORD_PER_PAGE);
ctx.body = { page, rdocs }; let pdict, udict;
for (let rdoc in rdocs) {
udict[rdoc.uid] = await user.getById(rdoc.uid);
pdict[rdoc.pid] = await problem.get({ pid: rdoc.pid, uid: ctx.state.user._id });
}
ctx.templateName = 'record_main.html';
ctx.body = { page, rdocs, pdict, udict };
}); });
GET('/r/:rid', async ctx => { GET('/r/:rid', async ctx => {
let uid = ctx.state.user._id, rid = new bson.ObjectID(ctx.params.rid); let uid = ctx.state.user._id, rid = new bson.ObjectID(ctx.params.rid);
let rdoc = await record.get(rid); let rdoc = await record.get(rid);
if (rdoc.hidden) ctx.checkPerm(PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD); if (rdoc.hidden) ctx.checkPerm(PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD);
if (rdoc.creator != uid && !ctx.state.user.hasPerm(PERM_READ_RECORD_CODE)) rdoc.code = null; if (rdoc.uid != uid && !ctx.state.user.hasPerm(PERM_READ_RECORD_CODE)) rdoc.code = null;
ctx.templateName = 'record_detail.html';
ctx.body = { rdoc }; ctx.body = { rdoc };
}); });
+6 -2
View File
@@ -70,7 +70,8 @@ MIDDLEWARE(async (ctx, next) => {
ctx.render = async (name, context) => { ctx.render = async (name, context) => {
ctx.user = ctx.state.user; ctx.user = ctx.state.user;
ctx.translate = str => { ctx.translate = str => {
return str.translate(ctx.state.user.language); if (!str) return '';
return str.toString().translate(ctx.state.user.language);
}; };
ctx.has_perm = perm => ctx.state.user.hasPerm(perm); ctx.has_perm = perm => ctx.state.user.hasPerm(perm);
ctx.body = await new Promise((resolve, reject) => { ctx.body = await new Promise((resolve, reject) => {
@@ -87,15 +88,18 @@ MIDDLEWARE(async (ctx, next) => {
try { try {
try { try {
await next(); await next();
if (!ctx.body) throw new NotFoundError(); if (ctx.body || ctx.templateName) {
if (ctx.query.template || ctx.templateName) { if (ctx.query.template || ctx.templateName) {
ctx.body = ctx.body || {};
Object.assign(ctx.body, JSON.parse(ctx.query.data || '{}')); Object.assign(ctx.body, JSON.parse(ctx.query.data || '{}'));
await ctx.render(ctx.query.template || ctx.templateName, ctx.body); await ctx.render(ctx.query.template || ctx.templateName, ctx.body);
} else if (ctx.setRedirect) { } else if (ctx.setRedirect) {
ctx.response.type = 'application/octet-stream'; ctx.response.type = 'application/octet-stream';
ctx.redirect(ctx.setRedirect); ctx.redirect(ctx.setRedirect);
} }
} else throw new NotFoundError();
} catch (error) { } catch (error) {
console.log(error);
if (error.toString().startsWith('Template render error')) throw error; if (error.toString().startsWith('Template render error')) throw error;
await ctx.render('error.html', { error }); await ctx.render('error.html', { error });
} }
+3 -2
View File
@@ -1,5 +1,5 @@
const const
{ GET, POST, CONTEXT } = require('../service/server.js'), { GET, POST } = require('../service/server.js'),
user = require('../model/user'), user = require('../model/user'),
token = require('../model/token'), token = require('../model/token'),
system = require('../model/system'), system = require('../model/system'),
@@ -30,7 +30,8 @@ POST('/login', async ctx => {
ctx.session.uid = udoc._id; ctx.session.uid = udoc._id;
ctx.session.rememberme = rememberme; ctx.session.rememberme = rememberme;
ctx.body = {}; ctx.body = {};
ctx.setRedirect = ctx.request.headers.referer || '/'; let referer = ctx.request.headers.referer || '/';
ctx.setRedirect = referer.endsWith('/login') ? '/' : referer;
}); });
POST('/logout', requirePerm(PERM_LOGGEDIN), async ctx => { POST('/logout', requirePerm(PERM_LOGGEDIN), async ctx => {
ctx.session = { uid: 1 }; ctx.session = { uid: 1 };
+36 -2
View File
@@ -177,6 +177,40 @@ const FOOTER_EXTRA_HTMLS = [];
const VIEW_LANGS = [ const VIEW_LANGS = [
{ code: 'zh-CN', name: 'zh-CN' } { code: 'zh-CN', name: 'zh-CN' }
]; ];
module.exports = { const LANGS = [
BUILTIN_USERS, BUILTIN_ROLES, CATEGORIES, VIEW_LANGS, FOOTER_EXTRA_HTMLS { id: 'cc', name: 'cpp' }
];
const LANG_TEXTS = {
c: 'C',
cc: 'C++',
cs: 'C#',
pas: 'Pascal',
java: 'Java',
py: 'Python',
py3: 'Python 3',
php: 'PHP',
rs: 'Rust',
hs: 'Haskell',
js: 'JavaScript',
go: 'Go',
rb: 'Ruby',
};
const LANG_HIGHLIGHT_ID = {
c: 'c',
cc: 'cpp',
cs: 'csharp',
pas: 'pascal',
java: 'java',
py: 'python',
py3: 'python',
php: 'php',
rs: 'rust',
hs: 'haskell',
js: 'javascript',
go: 'go',
rb: 'ruby',
};
module.exports = {
BUILTIN_USERS, BUILTIN_ROLES, CATEGORIES, VIEW_LANGS, FOOTER_EXTRA_HTMLS, LANGS,
LANG_TEXTS, LANG_HIGHLIGHT_ID
}; };
+1
View File
@@ -4,6 +4,7 @@ const
module.exports = { module.exports = {
TYPE_SESSION: 0, TYPE_SESSION: 0,
TYPE_CSRF_TOKEN: 1,
TYPE_REGISTER: 2, TYPE_REGISTER: 2,
/** /**
* Add a token. * Add a token.
+54 -54
View File
@@ -1,12 +1,12 @@
{% macro form_begin(args) %} {% macro form_begin(args) %}
{% set label = args.pop('label') %} {% set label = args.label %}
{% set columns = args.pop('columns') %} {% set columns = args.columns %}
{% set last_column = args.pop('last_column', true) %} {% set last_column = args.last_column or true %}
{% set required = args.pop('required', false) %} {% set required = args.required or false %}
{% set hotkeys = args.pop('hotkeys', none) %} {% set hotkeys = args.hotkeys or none %}
{% set row = args.pop('row', true) %} {% set row = args.row or true %}
{% set no_label = args.pop('no_label', false) %} {% set no_label = args.no_label or false %}
{% set label_wrap = args.pop('label_wrap', true) %} {% set label_wrap = args.label_wrap or true %}
{% if row %} {% if row %}
<div class="row"> <div class="row">
{% endif %} {% endif %}
@@ -27,10 +27,10 @@
{% endmacro %} {% endmacro %}
{% macro form_end(args) %} {% macro form_end(args) %}
{% set help_text = args.pop('help_text', none) %} {% set help_text = args.help_text or none %}
{% set row = args.pop('row', true) %} {% set row = args.row or true %}
{% set no_label = args.pop('no_label', false) %} {% set no_label = args.no_label or false %}
{% set label_wrap = args.pop('label_wrap', true) %} {% set label_wrap = args.label_wrap or true %}
{% if not no_label and label_wrap %} {% if not no_label and label_wrap %}
</label> </label>
{% endif %} {% endif %}
@@ -44,11 +44,11 @@
{% endmacro %} {% endmacro %}
{% macro form_attr(form_class, args) %} {% macro form_attr(form_class, args) %}
{% set disabled = args.pop('disabled', false) %} {% set disabled = args.disabled or false %}
{% set required = args.pop('required', false) %} {% set required = args.required or false %}
{% set autofocus = args.pop('autofocus', false) %} {% set autofocus = args.autofocus or false %}
{% set date = args.pop('date', false) %} {% set date = args.date or false %}
{% set time = args.pop('time', false) %} {% set time = args.time or false %}
class="{{ form_class }}{% if extra_class %} {{ extra_class }}{% endif %}" class="{{ form_class }}{% if extra_class %} {{ extra_class }}{% endif %}"
{% if disabled %}disabled{% endif %} {% if disabled %}disabled{% endif %}
{% if required %}required{% endif %} {% if required %}required{% endif %}
@@ -58,22 +58,22 @@
{% endmacro %} {% endmacro %}
{% macro container_attr(container_class, args) %} {% macro container_attr(container_class, args) %}
{% set extra_class = args.pop('extra_class', none) %} {% set extra_class = args.extra_class or none %}
class="{{ container_class }}{% if extra_class %} {{ extra_class }}{% endif %}" class="{{ container_class }}{% if extra_class %} {{ extra_class }}{% endif %}"
{% endmacro %} {% endmacro %}
{% macro select(options, name='', value='', args) %} {% macro select(args) %}
<div <div
name="form_item_{{ name }}" name="form_item_{{ args.name }}"
{{ container_attr('select-container', args) }} {{ container_attr('select-container', args) }}
> >
<select <select
name="{{ name }}" name="{{ args.name }}"
{{ form_attr('select', args) }} {{ form_attr('select', args) }}
> >
{% for k, v in options %} {% for item in args.options %}
<option value="{{ k }}"{% if value == k %} selected{% endif %}> <option value="{{ item.id }}"{% if value == item.id %} selected{% endif %}>
{{ _(v) }} {{ _(item.name) }}
</option> </option>
{% endfor %} {% endfor %}
</select> </select>
@@ -86,20 +86,20 @@
{{ form_end({columns:columns}|assign(args)) }} {{ form_end({columns:columns}|assign(args)) }}
{% endmacro %} {% endmacro %}
{% macro radio(options, name='', value='', args) %} {% macro radio(args) %}
<div <div
name="form_item_{{ name }}" name="form_item_{{ args.name }}"
{{ container_attr('radiobox-container', args) }} {{ container_attr('radiobox-container', args) }}
> >
{% for k, v in options %} {% for item in options %}
<label class="radiobox"> <label class="radiobox">
<input <input
value="{{ k }}" value="{{ item.id }}"
type="radio" type="radio"
name="{{ name }}" name="{{ args.name }}"
{{ form_attr('radiobox__input', args) }} {{ form_attr('radiobox__input', args) }}
{% if value == k %} checked{% endif %} {% if value == args.id %} checked{% endif %}
/> {{ _(v) }} /> {{ _(item.name) }}
</label> </label>
{% endfor %} {% endfor %}
</div> </div>
@@ -111,22 +111,22 @@
{{ form_end({columns:columns, label_warp:false}|assign(args)) }} {{ form_end({columns:columns, label_warp:false}|assign(args)) }}
{% endmacro %} {% endmacro %}
{% macro image_radio(options, name='', value='', image_class='', args) %} {% macro image_radio(args) %}
<div <div
name="form_item_{{ name }}" name="form_item_{{ args.name }}"
{{ container_attr('radiobox-container with-image', args) }} {{ container_attr('radiobox-container with-image', args) }}
> >
{% for k, v in options %} {% for item in options %}
<label class="radiobox with-image"> <label class="radiobox with-image">
<input <input
value="{{ k }}" value="{{ item.id }}"
type="radio" type="radio"
name="{{ name }}" name="{{ name }}"
{{ form_attr('radiobox__input', args) }} {{ form_attr('radiobox__input', args) }}
{% if value == k %} checked{% endif %} {% if value == item.id %} checked{% endif %}
/> />
<div class="radiobox__image-container" data-tooltip="{{ _(v) }}"> <div class="radiobox__image-container" data-tooltip="{{ _(item.name) }}">
<div class="radiobox__image {{ image_class.format(k) }}"></div> <div class="radiobox__image {{ image_class.format(item.id) }}"></div>
</div> </div>
</label> </label>
{% endfor %} {% endfor %}
@@ -139,16 +139,16 @@
{{ form_end({columns:columns, label_warp:false}|assign(args)) }} {{ form_end({columns:columns, label_warp:false}|assign(args)) }}
{% endmacro %} {% endmacro %}
{% macro text(name='', value='', placeholder='', type='text', args) %} {% macro text(args) %}
<div <div
name="form_item_{{ name }}" name="form_item_{{ args.name }}"
{{ container_attr('textbox-container', args) }} {{ container_attr('textbox-container', args) }}
> >
<input <input
type="{{ type }}" type="{{ args.type or 'text' }}"
name="{{ name }}" name="{{ args.name }}"
value="{{ value }}" value="{{ args.value }}"
placeholder="{{ placeholder }}" placeholder="{{ args.placeholder }}"
{{ form_attr('textbox', args) }} {{ form_attr('textbox', args) }}
> >
</div> </div>
@@ -160,18 +160,18 @@
{{ form_end({columns:columns}|assign(args)) }} {{ form_end({columns:columns}|assign(args)) }}
{% endmacro %} {% endmacro %}
{% macro textarea(name='', value='', placeholder='', args) %} {% macro textarea(args) %}
{% set markdown = args.pop('markdown', false) %} {% set markdown = args.markdown or false %}
<div <div
name="form_item_{{ name }}" name="form_item_{{ args.name }}"
{{ container_attr('textarea-container', args) }} {{ container_attr('textarea-container', args) }}
> >
<textarea <textarea
name="{{ name }}" name="{{ args.name }}"
placeholder="{{ placeholder }}" placeholder="{{ args.placeholder }}"
{% if markdown %}data-markdown{% endif %} {% if markdown %}data-markdown{% endif %}
{{ form_attr('textbox', args) }} {{ form_attr('textbox', args) }}
>{{ value }}</textarea> >{{ args.value }}</textarea>
</div> </div>
{% endmacro %} {% endmacro %}
@@ -181,15 +181,15 @@
{{ form_end({columns:columns}|assign(args)) }} {{ form_end({columns:columns}|assign(args)) }}
{% endmacro %} {% endmacro %}
{% macro checkbox(label='', name='', value=false, args) %} {% macro checkbox(args) %}
<div <div
name="form_item_{{ name }}" name="form_item_{{ args.name }}"
{{ container_attr('checkbox-container', args) }} {{ container_attr('checkbox-container', args) }}
> >
<label class="checkbox"> <label class="checkbox">
<input type="checkbox" name="{{ name }}"{% if value %} checked{% endif %} <input type="checkbox" name="{{ args.name }}"{% if args.value %} checked{% endif %}
{{ form_attr('checkbox', args) }} {{ form_attr('checkbox', args) }}
>{{ _(label) }} >{{ _(args.label) }}
</label> </label>
</div> </div>
{% endmacro %} {% endmacro %}
+5 -5
View File
@@ -1,12 +1,12 @@
{% macro render_status_td(rdoc, rid_key='_id') %} {% macro render_status_td(rdoc, rid_key='_id') %}
<td class="col--status record-status--border {{ vj4.constant.record.STATUS_CODES[rdoc['status']] }}"> <td class="col--status record-status--border {{ status.STATUS_CODES[rdoc['status']] }}">
<div class="col--status__text"> <div class="col--status__text">
<span class="icon record-status--icon {{ vj4.constant.record.STATUS_CODES[rdoc['status']] }}"></span> <span class="icon record-status--icon {{ status.STATUS_CODES[rdoc['status']] }}"></span>
<a href="{{ reverse_url('record_detail', rid=rdoc[rid_key], domain_id=rdoc['domain_id']) }}" class="record-status--text {{ vj4.constant.record.STATUS_CODES[rdoc['status']] }}"> <a href="{{ reverse_url('record_detail', rid=rdoc[rid_key], domain_id=rdoc['domain_id']) }}" class="record-status--text {{ status.STATUS_CODES[rdoc['status']] }}">
{{ vj4.constant.record.STATUS_TEXTS[rdoc['status']] }} {{ status.STATUS_TEXTS[rdoc['status']] }}
</a> </a>
</div> </div>
{% if rdoc['status'] == vj4.constant.record.STATUS_JUDGING %} {% if rdoc['status'] == status.STATUS_JUDGING %}
<div class="col--status__progress-container"> <div class="col--status__progress-container">
<div class="col--status__progress" style="width: {{ rdoc['progress']|default(50)|int }}%"></div> <div class="col--status__progress" style="width: {{ rdoc['progress']|default(50)|int }}%"></div>
</div> </div>
+2 -2
View File
@@ -31,7 +31,7 @@
</div> </div>
<div class="media__right middle"> <div class="media__right middle">
<div class="section__body"> <div class="section__body">
<a href="{{ reverse_url('contest_detail', tid=tdoc['doc_id']) }}" class="detail-button">{{ _('View Details') }}</a> <a href="/t/{{ tdoc._id }}" class="detail-button">{{ _('View Details') }}</a>
<div class="typo text-center"> <div class="typo text-center">
{% if tsdict[tdoc['doc_id']]['attend'] == 1 %} {% if tsdict[tdoc['doc_id']]['attend'] == 1 %}
<p><span class="icon icon-check"></span> {{ _('Attended') }}</p> <p><span class="icon icon-check"></span> {{ _('Attended') }}</p>
@@ -87,7 +87,7 @@
</div> </div>
</div> </div>
<div class="media__body medium"> <div class="media__body medium">
<h1 class="contest__title"><a href="{{ reverse_url('contest_detail', tid=tdoc['doc_id']) }}" data-emoji-enabled>{{ tdoc['title'] }}</a></h1> <h1 class="contest__title"><a href="/t/{{ tdoc._id }}" data-emoji-enabled>{{ tdoc['title'] }}</a></h1>
<ul class="supplementary list"> <ul class="supplementary list">
<li> <li>
<a href="?rule={{ tdoc['rule'] }}" class="contest-type-tag"><span class="icon icon-award"></span>{{ vj4.constant.contest.RULE_TEXTS[tdoc['rule']] }}</a> <a href="?rule={{ tdoc['rule'] }}" class="contest-type-tag"><span class="icon icon-award"></span>{{ vj4.constant.contest.RULE_TEXTS[tdoc['rule']] }}</a>
+1 -1
View File
@@ -101,7 +101,7 @@
<div class="balancer sidebar-user-stat"> <div class="balancer sidebar-user-stat">
<div class="balancer__body"> <div class="balancer__body">
<div class="numbox"> <div class="numbox">
<div class="numbox__num medium">{{ dudict[ddoc['owner_uid']]['num_accept'] or 0 }}</div> <div class="numbox__num medium">{{ dudict[ddoc['owner_uid']].nAccept or 0 }}</div>
<div class="numbox__text">{{ _('Accepted') }}</div> <div class="numbox__text">{{ _('Accepted') }}</div>
</div> </div>
</div> </div>
+1 -1
View File
@@ -33,7 +33,7 @@
</div> </div>
</div> </div>
<div class="media__body medium"> <div class="media__body medium">
<h1 class="contest__title"><a href="{{ reverse_url('contest_detail', tid=tdoc['doc_id']) }}" data-emoji-enabled>{{ tdoc['title'] }}</a></h1> <h1 class="contest__title"><a href="/t/{{ tdoc._id }}" data-emoji-enabled>{{ tdoc['title'] }}</a></h1>
<ul class="supplementary list"> <ul class="supplementary list">
<li> <li>
<a href="{{ reverse_url('contest_main') }}?rule={{ tdoc['rule'] }}" class="contest-type-tag"><span class="icon icon-award"></span>{{ vj4.constant.contest.RULE_TEXTS[tdoc['rule']] }}</a> <a href="{{ reverse_url('contest_main') }}?rule={{ tdoc['rule'] }}" class="contest-type-tag"><span class="icon icon-award"></span>{{ vj4.constant.contest.RULE_TEXTS[tdoc['rule']] }}</a>
+2 -4
View File
@@ -13,10 +13,8 @@
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
{% with show_topics = false %} {% set show_topics = false %}
{% include "partials/footer.html" %} {% include "partials/footer.html" %}
{% endwith %}
</div> </div>
{% include "partials/login_dialog.html" %} {% include "partials/login_dialog.html" %}
+4 -4
View File
@@ -2,7 +2,7 @@
{% import "components/contest.html" as contest with context %} {% import "components/contest.html" as contest with context %}
<div class="section side"> <div class="section side">
{% if page_name != 'contest_detail' %} {% if page_name != 'contest_detail' %}
<a class="contest-sidebar__bg" href="{{ reverse_url('contest_detail', tid=tdoc['doc_id']) }}"> <a class="contest-sidebar__bg" href="/t/{{ tdoc._id }}">
<div class="section__body"> <div class="section__body">
<h1>{{ tdoc['title'] }}</h1> <h1>{{ tdoc['title'] }}</h1>
<div class="contest-sidebar__status"> <div class="contest-sidebar__status">
@@ -34,14 +34,14 @@
<li class="menu__seperator"></li> <li class="menu__seperator"></li>
{% endif %} {% endif %}
{% if page_name != 'contest_detail' %} {% if page_name != 'contest_detail' %}
<li class="menu__item"><a class="menu__link" href="{{ reverse_url('contest_detail', tid=tdoc['doc_id']) }}"> <li class="menu__item"><a class="menu__link" href="/t/{{ tdoc._id }}">
<span class="icon icon-award"></span> {{ _('View Contest') }} <span class="icon icon-award"></span> {{ _('View Contest') }}
</a></li> </a></li>
{% endif %} {% endif %}
{% if not attended and not handler.is_done(tdoc) %} {% if not attended and not handler.is_done(tdoc) %}
<li class="menu__item"> <li class="menu__item">
{% if handler.has_perm(perm.PERM_ATTEND_CONTEST) and handler.has_perm(perm.PERM_LOGGEDIN) %} {% if handler.has_perm(perm.PERM_ATTEND_CONTEST) and handler.has_perm(perm.PERM_LOGGEDIN) %}
<form action="{{ reverse_url('contest_detail', tid=tdoc['doc_id']) }}" method="POST"> <form action="/t/{{ tdoc._id }}" method="POST">
<input type="hidden" name="operation" value="attend"> <input type="hidden" name="operation" value="attend">
<input type="hidden" name="csrf_token" value="{{ handler.csrf_token }}"> <input type="hidden" name="csrf_token" value="{{ handler.csrf_token }}">
<button class="menu__link" type="submit"> <button class="menu__link" type="submit">
@@ -78,7 +78,7 @@
<span class="icon icon-download"></span> {{ _('Export All Code') }} <span class="icon icon-download"></span> {{ _('Export All Code') }}
</a></li> </a></li>
{% endif %} {% endif %}
<li class="menu__item"><a class="menu__link" href="{{ reverse_url('record_main') }}?tid={{ tdoc['doc_id'] }}"> <li class="menu__item"><a class="menu__link" href="/r?tid={{ tdoc['doc_id'] }}">
<span class="icon icon-flag"></span> {{ _('All Submissions') }} <span class="icon icon-flag"></span> {{ _('All Submissions') }}
</a></li> </a></li>
<li class="menu__item"><a class="menu__link" href="{{ reverse_url('wiki_help') }}#contest"> <li class="menu__item"><a class="menu__link" href="{{ reverse_url('wiki_help') }}#contest">
+1 -4
View File
@@ -10,7 +10,7 @@
</span> </span>
</h1> </h1>
<div class="footer__category__expander"><ul class="footer__category__list"> <div class="footer__category__expander"><ul class="footer__category__list">
<li class="footer__category__item"><a href="{{ reverse_url('record_main') }}">{{ _('Judging Queue') }}</a></li> <li class="footer__category__item"><a href="/r">{{ _('Judging Queue') }}</a></li>
<li class="footer__category__item"><a href="#">{{ _('Service Status') }}</a></li> <li class="footer__category__item"><a href="#">{{ _('Service Status') }}</a></li>
</ul></div> </ul></div>
</div> </div>
@@ -34,9 +34,6 @@
</span> </span>
</h1> </h1>
<div class="footer__category__expander"><ul class="footer__category__list"> <div class="footer__category__expander"><ul class="footer__category__list">
{% if domain_id != vj4.model.builtin.DOMAIN_ID_SYSTEM %}
<li class="footer__category__item"><a href="{{ reverse_url('domain_main', domain_id=vj4.model.builtin.DOMAIN_ID_SYSTEM) }}">{{ _('Vijos') }}</a></li>
{% endif %}
<li class="footer__category__item"><a href="//vijos.github.io/about-vijos/">{{ _('Help') }}</a></li> <li class="footer__category__item"><a href="//vijos.github.io/about-vijos/">{{ _('Help') }}</a></li>
<!--<li class="footer__category__item"><a href="#">{{ _('Blog') }}</a></li>--> <!--<li class="footer__category__item"><a href="#">{{ _('Blog') }}</a></li>-->
<li class="footer__category__item"><a href="//vijos.github.io/about-vijos/about/contact-us/">{{ _('QQ Group') }}</a></li> <li class="footer__category__item"><a href="//vijos.github.io/about-vijos/about/contact-us/">{{ _('QQ Group') }}</a></li>
+1 -6
View File
@@ -2,12 +2,7 @@
<div class="header--mobile"> <div class="header--mobile">
<div class="row"><div class="columns clearfix"> <div class="row"><div class="columns clearfix">
<div class="float-left"> <div class="float-left">
{% if domain_id == vj4.model.builtin.DOMAIN_ID_SYSTEM %} <a class="header--mobile__domain is--system" href="/" target="_self">&nbsp;</a>
<a class="header--mobile__domain is--system" href="{{ reverse_url('domain_main', domain_id=vj4.model.builtin.DOMAIN_ID_SYSTEM) }}" target="_self">&nbsp;</a>
{% else %}
<a class="header--mobile__domain" href="{{ reverse_url('domain_main') }}" target="_self">{{ domain['name'] }}</a>
<a class="header--mobile__system" href="{{ reverse_url('domain_main', domain_id=vj4.model.builtin.DOMAIN_ID_SYSTEM) }}" target="_blank">Powered by Vijos</a>
{% endif %}
</div> </div>
<div class="float-right"> <div class="float-right">
{% include "partials/hamburger.html" %} {% include "partials/hamburger.html" %}
+1 -1
View File
@@ -63,7 +63,7 @@
</a></li> </a></li>
{% endif %} {% endif %}
{% if attended %} {% if attended %}
<li class="menu__item"><a class="menu__link" href="{{ reverse_url('record_main') }}?uid_or_name={{ handler.user['_id'] }}&tid={{ tdoc['doc_id'] }}"> <li class="menu__item"><a class="menu__link" href="/r?uid_or_name={{ handler.user['_id'] }}&tid={{ tdoc['doc_id'] }}">
<span class="icon icon-flag"></span> {{ _('My Recent Submissions') }} <span class="icon icon-flag"></span> {{ _('My Recent Submissions') }}
</a></li> </a></li>
{% endif %} {% endif %}
@@ -30,10 +30,10 @@
{% endif %} {% endif %}
{% if handler.own(pdoc, perm.PERM_EDIT_PROBLEM_SELF) or handler.has_perm(perm.PERM_EDIT_PROBLEM) %} {% if handler.own(pdoc, perm.PERM_EDIT_PROBLEM_SELF) or handler.has_perm(perm.PERM_EDIT_PROBLEM) %}
<li class="menu__seperator"></li> <li class="menu__seperator"></li>
<li class="menu__item"><a class="menu__link{% if page_name == 'problem_edit' %} active{% endif %}" href="{{ reverse_url('problem_edit', pid=pdoc['_id']) }}"> <li class="menu__item"><a class="menu__link{% if page_name == 'problem_edit' %} active{% endif %}" href="/p/{{ pdoc.pid }}/edit">
<span class="icon icon-edit"></span> {{ _('Edit') }} <span class="icon icon-edit"></span> {{ _('Edit') }}
</a></li> </a></li>
<li class="menu__item"><a class="menu__link{% if page_name == 'problem_settings' %} active{% endif %}" href="{{ reverse_url('problem_settings', pid=pdoc['_id']) }}"> <li class="menu__item"><a class="menu__link{% if page_name == 'problem_settings' %} active{% endif %}" href="/p/{{ pdoc.pid }}/settings">
<span class="icon icon-wrench"></span> {{ _('Settings') }} <span class="icon icon-wrench"></span> {{ _('Settings') }}
</a></li> </a></li>
{% endif %} {% endif %}
@@ -30,10 +30,10 @@
{% endif %} {% endif %}
{% if handler.own(pdoc, perm.PERM_EDIT_PROBLEM_SELF) or handler.has_perm(perm.PERM_EDIT_PROBLEM) %} {% if handler.own(pdoc, perm.PERM_EDIT_PROBLEM_SELF) or handler.has_perm(perm.PERM_EDIT_PROBLEM) %}
<li class="menu__seperator"></li> <li class="menu__seperator"></li>
<li class="menu__item"><a class="menu__link{% if page_name == 'problem_edit' %} active{% endif %}" href="{{ reverse_url('problem_edit', pid=pdoc['_id']) }}"> <li class="menu__item"><a class="menu__link{% if page_name == 'problem_edit' %} active{% endif %}" href="/p/{{ pdoc.pid }}/edit">
<span class="icon icon-edit"></span> {{ _('Edit') }} <span class="icon icon-edit"></span> {{ _('Edit') }}
</a></li> </a></li>
<li class="menu__item"><a class="menu__link{% if page_name == 'problem_settings' %} active{% endif %}" href="{{ reverse_url('problem_settings', pid=pdoc['_id']) }}"> <li class="menu__item"><a class="menu__link{% if page_name == 'problem_settings' %} active{% endif %}" href="/p/{{ pdoc.pid }}/settings">
<span class="icon icon-wrench"></span> {{ _('Settings') }} <span class="icon icon-wrench"></span> {{ _('Settings') }}
</a></li> </a></li>
{% endif %} {% endif %}
+13 -13
View File
@@ -39,7 +39,7 @@
</a></li> </a></li>
{% endif %} {% endif %}
{% if handler.has_perm(perm.PERM_SUBMIT_PROBLEM) %} {% if handler.has_perm(perm.PERM_SUBMIT_PROBLEM) %}
<li class="menu__item scratchpad--hide"><a class="menu__link{% if page_name == 'problem_submit' %} active{% endif %}" href="{{ reverse_url('problem_submit', pid=pdoc['_id']) }}"> <li class="menu__item scratchpad--hide"><a class="menu__link{% if page_name == 'problem_submit' %} active{% endif %}" href="/p/{{ pdoc.pid }}/submit">
<span class="icon icon-send"></span> {{ _('Submit') }} <span class="icon icon-send"></span> {{ _('Submit') }}
</a></li> </a></li>
{% elif not handler.has_perm(perm.PERM_LOGGEDIN) %} {% elif not handler.has_perm(perm.PERM_LOGGEDIN) %}
@@ -60,7 +60,7 @@
</a></li> </a></li>
{% endif %} {% endif %}
{% if handler.has_perm(perm.PERM_VIEW_PROBLEM_SOLUTION) %} {% if handler.has_perm(perm.PERM_VIEW_PROBLEM_SOLUTION) %}
<li class="menu__item"><a class="menu__link{% if page_name == 'problem_solution' %} active{% endif %}" href="{{ reverse_url('problem_solution', pid=pdoc['_id']) }}"> <li class="menu__item"><a class="menu__link{% if page_name == 'problem_solution' %} active{% endif %}" href="/p/{{ pdoc.pid }}/solution">
<span class="icon icon-comment--text"></span> {{ _('Solutions') }} <span class="icon icon-comment--text"></span> {{ _('Solutions') }}
</a></li> </a></li>
{% endif %} {% endif %}
@@ -72,10 +72,10 @@
{% endif %} {% endif %}
{% if handler.user._id == pdoc.owner or handler.has_perm(perm.PERM_EDIT_PROBLEM) %} {% if handler.user._id == pdoc.owner or handler.has_perm(perm.PERM_EDIT_PROBLEM) %}
<li class="menu__seperator"></li> <li class="menu__seperator"></li>
<li class="menu__item"><a class="menu__link{% if page_name == 'problem_edit' %} active{% endif %}" href="{{ reverse_url('problem_edit', pid=pdoc['_id']) }}"> <li class="menu__item"><a class="menu__link{% if page_name == 'problem_edit' %} active{% endif %}" href="/p/{{ pdoc.pid }}/edit">
<span class="icon icon-edit"></span> {{ _('Edit') }} <span class="icon icon-edit"></span> {{ _('Edit') }}
</a></li> </a></li>
<li class="menu__item"><a class="menu__link{% if page_name == 'problem_settings' %} active{% endif %}" href="{{ reverse_url('problem_settings', pid=pdoc['_id']) }}"> <li class="menu__item"><a class="menu__link{% if page_name == 'problem_settings' %} active{% endif %}" href="/p/{{ pdoc.pid }}/settings">
<span class="icon icon-wrench"></span> {{ _('Settings') }} <span class="icon icon-wrench"></span> {{ _('Settings') }}
</a></li> </a></li>
{% endif %} {% endif %}
@@ -98,15 +98,15 @@
<dt>{{ _('Submission') }}</dt> <dt>{{ _('Submission') }}</dt>
<dd> <dd>
{% if pdoc['psdoc']['status'] %} {% if pdoc['psdoc']['status'] %}
<span class="icon record-status--icon {{ vj4.constant.record.STATUS_CODES[pdoc['psdoc']['status']] }}"></span> <span class="icon record-status--icon {{ status.STATUS_CODES[pdoc['psdoc']['status']] }}"></span>
<a href="{{ reverse_url('record_detail', rid=pdoc['psdoc']['rid'], domain_id=pdoc['psdoc']['domain_id']) }}" class="record-status--text {{ vj4.constant.record.STATUS_CODES[pdoc['psdoc']['status']] }}"> <a href="/r/{{ pdoc['psdoc']['rid'] }}" class="record-status--text {{ status.STATUS_CODES[pdoc['psdoc']['status']] }}">
{{ vj4.constant.record.STATUS_TEXTS[pdoc['psdoc']['status']] }} {{ status.STATUS_TEXTS[pdoc['psdoc']['status']] }}
</a> </a>
{% else %} {% else %}
{{ _('(None)') }} {{ _('(None)') }}
{% endif %} {% endif %}
</dd> </dd>
{% if pdoc['ac_msg'] and pdoc['psdoc']['status'] == vj4.constant.record.STATUS_ACCEPTED %} {% if pdoc['ac_msg'] and pdoc['psdoc']['status'] == status.STATUS_ACCEPTED %}
<dt>{{ _('AC Message') }}</dt> <dt>{{ _('AC Message') }}</dt>
<dd>{{ pdoc['ac_msg'] }}</dd> <dd>{{ pdoc['ac_msg'] }}</dd>
{% endif %} {% endif %}
@@ -141,17 +141,17 @@
{{ problem.render_problem_tags(pdoc, true) }} {{ problem.render_problem_tags(pdoc, true) }}
</dd> </dd>
<dt>{{ _('# Submissions') }}</dt> <dt>{{ _('# Submissions') }}</dt>
<dd><a href="{{ reverse_url('record_main') }}?pid={{ pdoc['_id'] }}">{{ pdoc['num_submit'] }}</a></dd> <dd><a href="/r?pid={{ pdoc['_id'] }}">{{ pdoc.nSubmit }}</a></dd>
{% if page_name != 'discussion_node' and page_name != 'discussion_detail' %} {% if page_name != 'discussion_node' and page_name != 'discussion_detail' %}
{% if handler.has_perm(perm.PERM_LOGGEDIN) %} {% if handler.has_perm(perm.PERM_LOGGEDIN) %}
<dt>{{ _('# My Submissions') }}</dt> <dt>{{ _('# My Submissions') }}</dt>
<dd><a href="{{ reverse_url('record_main') }}?pid={{ pdoc['_id'] }}&uid_or_name={{ handler.user['_id'] }}">{{ pdoc['psdoc']['num_submit']|default(0) }}</a></dd> <dd><a href="/r?pid={{ pdoc['_id'] }}&uid_or_name={{ handler.user['_id'] }}">{{ pdoc['psdoc'].nSubmit|default(0) }}</a></dd>
{% endif %} {% endif %}
{% endif %} {% endif %}
<dt>{{ _('Accepted') }}</dt> <dt>{{ _('Accepted') }}</dt>
<dd>{{ pdoc['num_accept'] }}</dd> <dd>{{ pdoc.nAccept }}</dd>
<dt>{{ _('Accepted Ratio') }}</dt> <dt>{{ _('Accepted Ratio') }}</dt>
<dd>{% if pdoc['num_submit'] > 0 %}{{ (100 * pdoc['num_accept'] / pdoc['num_submit'])|round|int }}%{% else %}{{ _('?') }}{% endif %}</dd> <dd>{% if pdoc.nSubmit > 0 %}{{ (100 * pdoc.nAccept / pdoc.nSubmit)|round|int }}%{% else %}{{ _('?') }}{% endif %}</dd>
{% if pdoc['num_be_copied'] %} {% if pdoc['num_be_copied'] %}
<dt>{{ _('Be Copied') }}</dt> <dt>{{ _('Be Copied') }}</dt>
<dd>{{ pdoc['num_be_copied'] }}</dd> <dd>{{ pdoc['num_be_copied'] }}</dd>
@@ -178,7 +178,7 @@
{% if ctdocs %} {% if ctdocs %}
<p>{{ _('In following contests') }}: </p> <p>{{ _('In following contests') }}: </p>
{% for tdoc in ctdocs %} {% for tdoc in ctdocs %}
<p><a href="{{ reverse_url('contest_detail', tid=tdoc['doc_id']) }}">{{ tdoc['title'] }}</a></p> <p><a href="/t/{{ tdoc._id }}">{{ tdoc['title'] }}</a></p>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if htdocs %} {% if htdocs %}
+1 -1
View File
@@ -59,7 +59,7 @@
</div> </div>
<div class="medium-3 columns"> <div class="medium-3 columns">
{% if page_name == 'problem_edit' %} {% if page_name == 'problem_edit' %}
{% with owner_udoc=udoc, owner_dudoc=dudoc %} {% set owner_udoc=udoc %}{% set owner_dudoc=dudoc %}
{% include "partials/problem_sidebar.html" %} {% include "partials/problem_sidebar.html" %}
{% endwith %} {% endwith %}
{% else %} {% else %}
@@ -8,8 +8,8 @@
<div class="row"> <div class="row">
<div class="medium-8 columns"> <div class="medium-8 columns">
<label> <label>
{{ _('Copy from') }} {{ _('Import from') }}
<input name="src_domain_id" placeholder="{{ _('Domain ID') }}" class="textbox" autocomplete="off"> <input name="src" placeholder="{{ _('Source') }}" class="textbox" autocomplete="off">
</label> </label>
</div> </div>
<div class="medium-2 columns"> <div class="medium-2 columns">
@@ -17,7 +17,7 @@
{{ _('Settings') }} {{ _('Settings') }}
<br> <br>
<label class="checkbox"> <label class="checkbox">
<input type="checkbox" name="numeric_pid" value="on" checked>{{ _('Numeric PID') }} <input name="src" placeholder="{{ _('ProblemID') }}" class="textbox" autocomplete="off">
</label> </label>
</label> </label>
</div> </div>
@@ -32,8 +32,8 @@
</div> </div>
<div class="row"><div class="columns"> <div class="row"><div class="columns">
<label> <label>
{{ _('Problem ID List') }} {{ _('Source URL') }}
<textarea name="src_pids" class="textbox" style="height: 300px"></textarea> <textarea name="src" class="textbox" style="height: 300px"></textarea>
</label> </label>
</div></div> </div></div>
<div class="row"><div class="columns"> <div class="row"><div class="columns">
@@ -52,10 +52,10 @@
<div class="medium-3 columns"> <div class="medium-3 columns">
<div class="section side"> <div class="section side">
<div class="section__body typo"> <div class="section__body typo">
<h2>{{ _('What\'s this?') }}</h2> <h2>{{ _('What is this?') }}</h2>
<p>{{ _('With this feature, you can copy problems that you can view from a domain to some other domain. Their title, content, tags and categories will be copied. However, their test data are not copied directly.') }}</p> <p>{{ _('With this feature, you can import problems that you can view from a site to here. Their title, content, tags and categories will be imported. However, their test data are not copied directly.') }}</p>
<h2>{{ _('About test data') }}</h2> <h2>{{ _('About test data') }}</h2>
<p>{{ _('Instead of copying the test data directly, the test data of the copied problems will be linked to the test data of the source problems (called the source test data). Thus, the copied problems can observe the changes in the source test data. The permissions of the test data of the copied problems follow the source test data, e.g., you still might not download them but the judges can. By uploading some new test data, the link will be broken and the new test data will be used.') }}</p> <p>{{ _('Instead of copying the test data directly, the test data of the import problems will be linked to the test data of the source problems (called the source test data). Thus, the copied problems can observe the changes in the source test data. The permissions of the test data of the copied problems follow the source test data, e.g., you still might not download them but the judges can. By uploading some new test data, the link will be broken and the new test data will be used.') }}</p>
</div> </div>
</div> </div>
</div> </div>
+2 -2
View File
@@ -10,7 +10,7 @@
<iframe src="{{ reverse_url('problem_upload', pid=pdoc['_id']) }}" frameborder="0" style="width: 100%; height: 100px;"></iframe> <iframe src="{{ reverse_url('problem_upload', pid=pdoc['_id']) }}" frameborder="0" style="width: 100%; height: 100px;"></iframe>
<p class="help-text">{{ _('Hint') }}: <a href="{{ reverse_url('wiki_help') }}#upload">{{ _('Dataset Format') }}</a>, {{ _('An example of dataset') }}: <a href="https://github.com/vijos/jd4/blob/master/jd4/testdata/aplusb-legacy.zip?raw=true">{{ _('Download') }}</a></p> <p class="help-text">{{ _('Hint') }}: <a href="{{ reverse_url('wiki_help') }}#upload">{{ _('Dataset Format') }}</a>, {{ _('An example of dataset') }}: <a href="https://github.com/vijos/jd4/blob/master/jd4/testdata/aplusb-legacy.zip?raw=true">{{ _('Download') }}</a></p>
{% if pdoc and (handler.own(pdoc, perm.PERM_READ_PROBLEM_DATA_SELF) or handler.has_perm(perm.PERM_READ_PROBLEM_DATA) or handler.has_priv(vj4.model.builtin.PRIV_READ_PROBLEM_DATA)) %} {% if pdoc and (handler.own(pdoc, perm.PERM_READ_PROBLEM_DATA_SELF) or handler.has_perm(perm.PERM_READ_PROBLEM_DATA) or handler.has_priv(vj4.model.builtin.PRIV_READ_PROBLEM_DATA)) %}
<p><a href="{{ reverse_url('problem_data', pid=pdoc['_id']) }}" class="expanded button">{{ _('Download Dataset') }}</a></p> <p><a href="/p/{{ pdoc.pid }}/data" class="expanded button">{{ _('Download Dataset') }}</a></p>
{% endif %} {% endif %}
</div> </div>
</div> </div>
@@ -65,7 +65,7 @@
</div> </div>
</div> </div>
<div class="medium-3 columns"> <div class="medium-3 columns">
{% with owner_udoc=udoc, owner_dudoc=dudoc %} {% set owner_udoc=udoc %}{% set owner_dudoc=dudoc %}
{% include "partials/problem_sidebar.html" %} {% include "partials/problem_sidebar.html" %}
{% endwith %} {% endwith %}
</div> </div>
+1 -1
View File
@@ -12,7 +12,7 @@
</div> </div>
</div> </div>
<div class="medium-3 columns"> <div class="medium-3 columns">
{% with owner_udoc=udoc, owner_dudoc=dudoc %} {% set owner_udoc=udoc %}{% set owner_dudoc=dudoc %}
{% include "partials/problem_sidebar.html" %} {% include "partials/problem_sidebar.html" %}
{% endwith %} {% endwith %}
</div> </div>
+3 -3
View File
@@ -1,3 +1,4 @@
{% set page_name = "problem_submit" %}
{% extends "layout/basic.html" %} {% extends "layout/basic.html" %}
{% block content %} {% block content %}
<div class="row"> <div class="row">
@@ -44,7 +45,7 @@
</div> </div>
<div class="section__body"> <div class="section__body">
<form method="post"> <form method="post">
{{ form.form_select(label='Code language', options=vj4.constant.language.LANG_TEXTS.items(), name='lang', value=handler.get_setting('code_lang')) }} {{ form.form_select(label='Code language', options=builtin.LANGS, name='lang', value=handler.user.codeLang) }}
{{ form.form_textarea(label='Code', columns=12, name='code', extra_class='monospace', autofocus=true) }} {{ form.form_textarea(label='Code', columns=12, name='code', extra_class='monospace', autofocus=true) }}
<div class="row"><div class="columns"> <div class="row"><div class="columns">
<input type="hidden" name="csrf_token" value="{{ handler.csrf_token }}"> <input type="hidden" name="csrf_token" value="{{ handler.csrf_token }}">
@@ -55,9 +56,8 @@
</div> </div>
</div> </div>
<div class="medium-3 columns"> <div class="medium-3 columns">
{% with owner_udoc=udoc, owner_dudoc=dudoc %} {% set owner_udoc=udoc %}{% set owner_dudoc=dudoc %}
{% include "partials/problem_sidebar.html" %} {% include "partials/problem_sidebar.html" %}
{% endwith %}
</div> </div>
</div> </div>
+2 -2
View File
@@ -9,10 +9,10 @@
{% endif %} {% endif %}
</td> </td>
<td class="col--memory"> <td class="col--memory">
{{ (rdoc['memory_kb'] / 1000)|round(0, 'ceil')|int }} MB {{ (rdoc.memory / 1000)|round(0, 'ceil')|int }} MB
</td> </td>
<td class="col--time"> <td class="col--time">
{{ (rdoc['time_ms'] / 1000)|round(1) }}s {{ (rdoc.time / 1000)|round(1) }}s
</td> </td>
<td class="col--submit-at">{{ datetime_span(rdoc['_id'].generation_time) }}</td> <td class="col--submit-at">{{ datetime_span(rdoc['_id'].generation_time) }}</td>
</tr> </tr>
+2 -2
View File
@@ -1,8 +1,8 @@
{% extends 'layout/simple.html' %} {% extends 'layout/simple.html' %}
{% block body %} {% block body %}
<form method="post" enctype="multipart/form-data"> <form method="post" enctype="multipart/form-data">
{% if pdoc['data'] is mapping %} {% if pdoc['data'].startsWith('from:') %}
<p><b>{{ _('Current dataset comes from') }} <a href="{{ reverse_url('problem_detail', domain_id=pdoc['data']['domain'], pid=pdoc['data']['pid']) }}" target="_blank">{{ pdoc['data']['domain'] }}/{{ pdoc['data']['pid'] }}</a></b></p> <p><b>{{ _('Current dataset comes from') }} <a href="{{ pdoc.data.split('from:')[1] }}" target="_blank">{{ pdoc.data.split('from:')[1] }}</a></b></p>
{% else %} {% else %}
<p>{{ _('Current dataset: {0}').format(pdoc['data']|default(_('(None)'))) }}</p> <p>{{ _('Current dataset: {0}').format(pdoc['data']|default(_('(None)'))) }}</p>
<p>{{ _('MD5: {0}').format(md5|default(_('(None)'))) }}</p> <p>{{ _('MD5: {0}').format(md5|default(_('(None)'))) }}</p>
+9 -8
View File
@@ -2,9 +2,9 @@
{% import "components/problem.html" as problem with context %} {% import "components/problem.html" as problem with context %}
{% block content %} {% block content %}
<script> <script>
var Context = {{ { var Context = {
'socketUrl': socket_url, 'socketUrl': "{{ socket_url }}",
}|json|safe }}; };
</script> </script>
<div class="row"> <div class="row">
<div class="medium-9 columns"> <div class="medium-9 columns">
@@ -17,7 +17,7 @@
<h1 class="section__title">{{ _('Code') }}</h1> <h1 class="section__title">{{ _('Code') }}</h1>
</div> </div>
<div class="section__body" data-syntax-hl-show-line-number> <div class="section__body" data-syntax-hl-show-line-number>
<pre><code class="language-{{ vj4.constant.language.LANG_HIGHLIGHT_ID[rdoc['lang']] }}">{{ rdoc['code'] }}</code></pre> <pre><code class="language-{{ builtin.LANG_HIGHLIGHT_ID[rdoc['lang']] }}">{{ rdoc['code'] }}</code></pre>
</div> </div>
</div> </div>
{% endif %} {% endif %}
@@ -31,7 +31,7 @@
<div class="section__body no-padding"> <div class="section__body no-padding">
<ol class="menu"> <ol class="menu">
<li class="menu__item"> <li class="menu__item">
<form method="post" action="{{ reverse_url('record_rejudge', rid=rdoc['_id']) }}"> <form method="post" action="/r/{{ rdoc._id }}/rejudge">
<input type="hidden" name="csrf_token" value="{{ handler.csrf_token }}"> <input type="hidden" name="csrf_token" value="{{ handler.csrf_token }}">
<button type="submit" class="menu__link"> <button type="submit" class="menu__link">
<span class="icon icon-refresh"></span> {{ _('Rejudge') }} <span class="icon icon-refresh"></span> {{ _('Rejudge') }}
@@ -39,7 +39,8 @@
</form> </form>
</li> </li>
<li class="menu__item"> <li class="menu__item">
<form method="post" action="{{ reverse_url('judge_score', rid=rdoc['_id']) }}"> <form method="post" action="/judge/end">
<input type="hidden" name="rid" value="{{ rdoc._id }}">
<input type="hidden" name="csrf_token" value="{{ handler.csrf_token }}"> <input type="hidden" name="csrf_token" value="{{ handler.csrf_token }}">
<input type="hidden" name="score" value="0"> <input type="hidden" name="score" value="0">
<input type="hidden" name="message" value="{{ _('score canceled') }}"> <input type="hidden" name="message" value="{{ _('score canceled') }}">
@@ -67,7 +68,7 @@
{% if tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST %} {% if tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST %}
<dt>{{ _('Contest') }}</dt> <dt>{{ _('Contest') }}</dt>
<dd> <dd>
<a href="{{ reverse_url('contest_detail', tid=tdoc['doc_id']) }}">{{ tdoc['title'] }}</a> <a href="/t/{{ tdoc._id }}">{{ tdoc['title'] }}</a>
</dd> </dd>
{% else %}{# tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST #} {% else %}{# tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST #}
<dt>{{ _('Homework') }}</dt> <dt>{{ _('Homework') }}</dt>
@@ -81,7 +82,7 @@
<dd><a href="{{ reverse_url('record_pretest_data', rid=rdoc['_id']) }}"><span class="icon icon-download"></span> {{ _('Download') }}</a></dd> <dd><a href="{{ reverse_url('record_pretest_data', rid=rdoc['_id']) }}"><span class="icon icon-download"></span> {{ _('Download') }}</a></dd>
{% elif rdoc['type'] == vj4.constant.record.TYPE_SUBMISSION and pdoc and (handler.own(pdoc, perm.PERM_READ_PROBLEM_DATA_SELF) or handler.has_perm(perm.PERM_READ_PROBLEM_DATA) or handler.has_priv(vj4.model.builtin.PRIV_READ_PROBLEM_DATA)) %} {% elif rdoc['type'] == vj4.constant.record.TYPE_SUBMISSION and pdoc and (handler.own(pdoc, perm.PERM_READ_PROBLEM_DATA_SELF) or handler.has_perm(perm.PERM_READ_PROBLEM_DATA) or handler.has_priv(vj4.model.builtin.PRIV_READ_PROBLEM_DATA)) %}
<dt>{{ _('Problem Data') }}</dt> <dt>{{ _('Problem Data') }}</dt>
<dd><a href="{{ reverse_url('problem_data', pid=pdoc['_id']) }}"><span class="icon icon-download"></span> {{ _('Download') }}</a></dd> <dd><a href="/p/{{ pdoc.pid }}/data"><span class="icon icon-download"></span> {{ _('Download') }}</a></dd>
{% endif %} {% endif %}
<dt>{{ _('Language') }}</dt> <dt>{{ _('Language') }}</dt>
<dd> <dd>
+12 -12
View File
@@ -1,18 +1,18 @@
<div class="section visible" id="status"> <div class="section visible" id="status">
<div class="section__header"> <div class="section__header">
<h1 class="section__title"> <h1 class="section__title">
<span class="icon record-status--icon {{ vj4.constant.record.STATUS_CODES[rdoc['status']] }}"></span> <span class="icon record-status--icon {{ status.STATUS_CODES[rdoc['status']] }}"></span>
<span class="record-status--text {{ vj4.constant.record.STATUS_CODES[rdoc['status']] }}"> <span class="record-status--text {{ status.STATUS_CODES[rdoc['status']] }}">
{{ vj4.constant.record.STATUS_TEXTS[rdoc['status']] }} {{ status.STATUS_TEXTS[rdoc['status']] }}
</span> </span>
</h1> </h1>
</div> </div>
<div class="section__body"> <div class="section__body">
<pre class="compiler-text">{{ rdoc['compiler_texts']|join('\n') }}</pre> <pre class="compiler-text">{{ rdoc.compilerTexts|join('\n') }}</pre>
</div> </div>
{% if rdoc['judge_texts'] %} {% if rdoc.judgeTexts %}
<div class="section__body"> <div class="section__body">
<pre class="judge-text">{{ rdoc['judge_texts']|join('\n') }}</pre> <pre class="judge-text">{{ rdoc.judgeTexts|join('\n') }}</pre>
</div> </div>
{% endif %} {% endif %}
{% if rdoc['cases'] %} {% if rdoc['cases'] %}
@@ -35,19 +35,19 @@
<tbody> <tbody>
{% for rcdoc in rdoc['cases'] %} {% for rcdoc in rdoc['cases'] %}
<tr> <tr>
<td class="col--case record-status--border {{ vj4.constant.record.STATUS_CODES[rcdoc['status']] }}"> <td class="col--case record-status--border {{ status.STATUS_CODES[rcdoc['status']] }}">
#{{ loop.index }} #{{ loop.index }}
</td> </td>
<td class="col--status"> <td class="col--status">
<span class="icon record-status--icon {{ vj4.constant.record.STATUS_CODES[rcdoc['status']] }}"></span> <span class="icon record-status--icon {{ status.STATUS_CODES[rcdoc['status']] }}"></span>
<span class="record-status--text {{ vj4.constant.record.STATUS_CODES[rcdoc['status']] }}"> <span class="record-status--text {{ status.STATUS_CODES[rcdoc['status']] }}">
{{ vj4.constant.record.STATUS_TEXTS[rcdoc['status']] }} {{ status.STATUS_TEXTS[rcdoc['status']] }}
</span> </span>
<span>{{ rcdoc['judge_text'] }}</span> <span>{{ rcdoc['judge_text'] }}</span>
<a class="tool-button" href="{{ reverse_url('wiki_help') }}#status"><span class="icon icon-help"></span></a> <a class="tool-button" href="{{ reverse_url('wiki_help') }}#status"><span class="icon icon-help"></span></a>
</td> </td>
<td class="col--time">{% if rcdoc['status'] == vj4.constant.record.STATUS_TIME_LIMIT_EXCEEDED or rcdoc['status'] == vj4.constant.record.STATUS_MEMORY_LIMIT_EXCEEDED or rcdoc['status'] == vj4.constant.record.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rcdoc['time_ms'] }}ms</td> <td class="col--time">{% if rcdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rcdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rcdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rcdoc['time_ms'] }}ms</td>
<td class="col--memory">{% if rcdoc['status'] == vj4.constant.record.STATUS_TIME_LIMIT_EXCEEDED or rcdoc['status'] == vj4.constant.record.STATUS_MEMORY_LIMIT_EXCEEDED or rcdoc['status'] == vj4.constant.record.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rcdoc['memory_kb']|format_size(1024) }}</td> <td class="col--memory">{% if rcdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rcdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rcdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rcdoc['memory_kb']|format_size(1024) }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
+2 -2
View File
@@ -4,7 +4,7 @@
<dd>{{ rdoc['score'] }}</dd> <dd>{{ rdoc['score'] }}</dd>
{% endif %} {% endif %}
<dt>{{ _('Total Time') }}</dt> <dt>{{ _('Total Time') }}</dt>
<dd>{% if rdoc['status'] == vj4.constant.record.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rdoc['time_ms'] }}ms</dd> <dd>{% if rdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rdoc.time }}ms</dd>
<dt>{{ _('Peak Memory') }}</dt> <dt>{{ _('Peak Memory') }}</dt>
<dd>{% if rdoc['status'] == vj4.constant.record.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rdoc['memory_kb']|format_size(1024) }}</dd> <dd>{% if rdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rdoc.memory|format_size(1024) }}</dd>
</dl> </dl>
+8 -7
View File
@@ -1,9 +1,10 @@
{% set page_name = "record_main" %}
{% extends "layout/basic.html" %} {% extends "layout/basic.html" %}
{% block content %} {% block content %}
<script> <script>
var Context = {{ { var Context = {
'socketUrl': socket_url, 'socketUrl': "/socket/{{ socket_url }}",
}|json|safe }}; };
</script> </script>
<div class="row"> <div class="row">
<div class="medium-12 columns"> <div class="medium-12 columns">
@@ -13,7 +14,7 @@
<h1 class="section__title">{{ _('Filter') }}</h1> <h1 class="section__title">{{ _('Filter') }}</h1>
<div class="section__tools"> <div class="section__tools">
<button type="submit" class="primary button"><span class="icon icon-filter"></span> {{ _('Filter') }}</button> <button type="submit" class="primary button"><span class="icon icon-filter"></span> {{ _('Filter') }}</button>
<a href="{{ reverse_url('record_main') }}" class="button">{{ _('Reset') }}</a> <a href="/r" class="button">{{ _('Reset') }}</a>
</div> </div>
</div> </div>
<div class="section__body"> <div class="section__body">
@@ -73,13 +74,13 @@
</thead> </thead>
<tbody> <tbody>
{% for rdoc in rdocs %} {% for rdoc in rdocs %}
{% with udoc = udict[rdoc['uid']], dudoc = dudict[rdoc['uid']], pdoc = pdict[(rdoc['domain_id'], rdoc['pid'])] %} {% set udoc = udict[rdoc['uid']] %}
{% set pdoc = pdict[rdoc['pid']] %}
{% include 'record_main_tr.html' %} {% include 'record_main_tr.html' %}
{% endwith %}
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% if handler.has_priv(vj4.model.builtin.PRIV_VIEW_JUDGE_STATISTICS) %} {% if handler.has_perm(perm.PERM_VIEW_JUDGE_STATISTICS) %}
<ul class="pager"> <ul class="pager">
<li> <li>
<a class="pager__item next link" href="?start={{ rdocs[-1]['_id'] }}&{{ query_string }}">{{ _('pager_next') }}</a> <a class="pager__item next link" href="?start={{ rdocs[-1]['_id'] }}&{{ query_string }}">{{ _('pager_next') }}</a>
+6 -10
View File
@@ -3,8 +3,8 @@
<tr data-rid="{{ rdoc['_id'] }}"> <tr data-rid="{{ rdoc['_id'] }}">
{{ record.render_status_td(rdoc) }} {{ record.render_status_td(rdoc) }}
<td class="col--problem col--problem-name"> <td class="col--problem col--problem-name">
{% if (rdoc['domain_id'] == handler.domain_id and handler.has_perm(perm.PERM_REJUDGE)) or handler.has_priv(vj4.model.builtin.PRIV_REJUDGE) %} {% if = handler.has_perm(perm.PERM_REJUDGE) %}
<form class="form--inline" method="post" action="{{ reverse_url('record_rejudge', rid=rdoc['_id']) }}"> <form class="form--inline" method="post" action="/r/{{ rdoc._id }}/rejudge">
<input type="hidden" name="csrf_token" value="{{ handler.csrf_token }}"> <input type="hidden" name="csrf_token" value="{{ handler.csrf_token }}">
<button type="submit" class="link text-maroon lighter"> <button type="submit" class="link text-maroon lighter">
<span class="icon icon-refresh"></span> <span class="icon icon-refresh"></span>
@@ -15,23 +15,19 @@
{% if rdoc['type'] == vj4.constant.record.TYPE_PRETEST %} {% if rdoc['type'] == vj4.constant.record.TYPE_PRETEST %}
({{ _('Pretest') }}) ({{ _('Pretest') }})
{% endif %} {% endif %}
{% if pdoc and (not pdoc['hidden'] or (pdoc['domain_id'] == handler.domain_id and handler.has_perm(perm.PERM_VIEW_PROBLEM_HIDDEN))) %} {% if pdoc and (not pdoc['hidden'] or handler.has_perm(perm.PERM_VIEW_PROBLEM_HIDDEN)) %}
{{ problem.render_problem_title(pdoc, show_tags=false) }} {{ problem.render_problem_title(pdoc, show_tags=false) }}
{% else %} {% else %}
* *
{% endif %} {% endif %}
</td> </td>
<td class="col--submit-by"> <td class="col--submit-by">
<a href="{{ reverse_url('user_detail', uid=rdoc['uid']) }}"> <a href="/u/{{ rdoc.uid }}">
{% if dudoc['display_name'] %}
{{ dudoc['display_name'] }} ({{ udoc['uname'] }})
{% else %}
{{ udoc['uname'] }} {{ udoc['uname'] }}
{% endif %}
</a> </a>
</td> </td>
<td class="col--time">{% if rdoc['status'] == vj4.constant.record.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rdoc['time_ms'] }}ms</td> <td class="col--time">{% if rdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rdoc.time }}ms</td>
<td class="col--memory">{% if rdoc['status'] == vj4.constant.record.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rdoc['memory_kb']|format_size(1024) }}</td> <td class="col--memory">{% if rdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rdoc.memory|format_size(1024) }}</td>
<td class="col--lang">{{ vj4.constant.language.LANG_TEXTS[rdoc['lang']] }}</td> <td class="col--lang">{{ vj4.constant.language.LANG_TEXTS[rdoc['lang']] }}</td>
<td class="col--submit-at">{{ datetime_span(rdoc['_id'].generation_time) }}</td> <td class="col--submit-at">{{ datetime_span(rdoc['_id'].generation_time) }}</td>
</tr> </tr>
-87
View File
@@ -1,87 +0,0 @@
{% macro form_begin(kwargs) %}
{% set label = kwargs.pop('label') %}
{% set columns = kwargs.pop('columns') %}
{% set last_column = kwargs.pop('last_column', true) %}
{% set required = kwargs.pop('required', false) %}
{% set hotkeys = kwargs.pop('hotkeys', none) %}
{% set row = kwargs.pop('row', true) %}
{% set no_label = kwargs.pop('no_label', false) %}
{% set label_wrap = kwargs.pop('label_wrap', true) %}
{% if row %}
<div class="row">
{% endif %}
<div
class="{% if columns %}medium-{{ columns }} {% endif %}columns form__item{% if last_column %} end{% endif %}"
{% if hotkeys %}data-hotkey="{{ hotkeys }}"{% endif %}
>
{% if not no_label %}
<label>
{{ _(label) }}
{% if required %}
({{ _('required') }})
{% endif %}
{% if not label_wrap %}
</label>
{% endif %}
{% endif %}
{% endmacro %}
{% macro form_end(kwargs) %}
{% set help_text = kwargs.pop('help_text', none) %}
{% set row = kwargs.pop('row', true) %}
{% set no_label = kwargs.pop('no_label', false) %}
{% set label_wrap = kwargs.pop('label_wrap', true) %}
{% if not no_label and label_wrap %}
</label>
{% endif %}
{% if help_text %}
<p class="help-text">{{ _(help_text)|safe }}</p>
{% endif %}
</div>
{% if row %}
</div>
{% endif %}
{% endmacro %}
{% macro form_attr(form_class, kwargs) %}
{% set disabled = kwargs.pop('disabled', false) %}
{% set required = kwargs.pop('required', false) %}
{% set autofocus = kwargs.pop('autofocus', false) %}
{% set date = kwargs.pop('date', false) %}
{% set time = kwargs.pop('time', false) %}
class="{{ form_class }}{% if extra_class %} {{ extra_class }}{% endif %}"
{% if disabled %}disabled{% endif %}
{% if required %}required{% endif %}
{% if autofocus %}autofocus data-autofocus{% endif %}
{% if date %}data-pick-date{% endif %}
{% if time %}data-pick-time{% endif %}
{% endmacro %}
{% macro container_attr(container_class, kwargs) %}
{% set extra_class = kwargs.pop('extra_class', none) %}
class="{{ container_class }}{% if extra_class %} {{ extra_class }}{% endif %}"
{% endmacro %}
{% macro select(options, name='', value='', kwargs) %}
<div
name="form_item_{{ name }}"
{{ container_attr('select-container', kwargs) }}
>
<select
name="{{ name }}"
{{ form_attr('select', kwargs) }}
>
{% for k, v in options %}
<option value="{{ k }}"{% if value == k %} selected{% endif %}>
{{ _(v) }}
</option>
{% endfor %}
</select>
</div>
{% endmacro %}
{% macro form_select(columns=5) %}
{{ form_begin({columns:1, ...kwargs}, kwargs) }}
{{ select(columns=columns, kwargs) }}
{{ form_end(columns=columns, kwargs) }}
{% endmacro %}
+3 -3
View File
@@ -126,11 +126,11 @@
pdoc, pdoc,
invalid=not tsdoc['enroll'], invalid=not tsdoc['enroll'],
show_tags=false, show_tags=false,
rp=vj4.job.rp.get_rp_expect(pdoc) if (not psdoc or psdoc['status'] != vj4.constant.record.STATUS_ACCEPTED) else none rp=vj4.job.rp.get_rp_expect(pdoc) if (not psdoc or psdoc['status'] != status.STATUS_ACCEPTED) else none
) }} ) }}
</td> </td>
<td class="col--submit_n">{{ pdoc['num_submit'] }}</td> <td class="col--submit_n">{{ pdoc.nSubmit }}</td>
<td class="col--ac_rate">{{ (100 * pdoc['num_accept'] / pdoc['num_submit'])|round|int if pdoc['num_submit'] > 0 else _('?') }}</td> <td class="col--ac_rate">{{ (100 * pdoc.nAccept / pdoc.nSubmit)|round|int if pdoc.nSubmit > 0 else _('?') }}</td>
<td class="col--difficulty">{{ pdoc['difficulty'] or _('(None)') }}</td> <td class="col--difficulty">{{ pdoc['difficulty'] or _('(None)') }}</td>
</tr> </tr>
{% endwith %} {% endwith %}
+4 -9
View File
@@ -12,12 +12,7 @@
</div> </div>
<div class="media__body profile-header__main"> <div class="media__body profile-header__main">
<h1> <h1>
{% if dudoc['display_name'] %}
{{ dudoc['display_name'] }}
<small>{{ udoc['uname'] }}</small>
{% else %}
{{ udoc['uname'] }} {{ udoc['uname'] }}
{% endif %}
<small>({{ _('UID') }}: {{ udoc['_id'] }})</small> <small>({{ _('UID') }}: {{ udoc['_id'] }})</small>
</h1> </h1>
<p> <p>
@@ -29,14 +24,14 @@
{{ _('currently offline') }}. {{ _('currently offline') }}.
{% endif %} {% endif %}
</p> </p>
<p>{{ _('Solved {0} problems, RP: {1} (No. {2})').format(dudoc['num_accept']|default(0), dudoc['rp']|default(0.0)|round(2), dudoc['rank']|default('?')) }}</p> <p>{{ _('Solved {0} problems, RP: {1} (No. {2})').format(dudoc.nAccept|default(0), dudoc['rp']|default(0.0)|round(2), dudoc['rank']|default('?')) }}</p>
<div class="profile-header__contact-bar"> <div class="profile-header__contact-bar">
{% if is_self_profile %} {% if is_self_profile %}
<a class="profile-header__contact-item" href="{{ reverse_url('home_account') }}#setting_info" data-tooltip="{{ _('Edit Profile') }}"> <a class="profile-header__contact-item" href="{{ reverse_url('home_account') }}#setting_info" data-tooltip="{{ _('Edit Profile') }}">
<span class="icon icon-edit"></span> <span class="icon icon-edit"></span>
</a> </a>
{% endif %} {% endif %}
<a class="profile-header__contact-item" href="{{ reverse_url('home_messages') }}?target_uid={{ udoc['_id'] }}" target="_blank" data-tooltip="{{ _('Send Message') }}"> <a class="profile-header__contact-item" href="/home/messages?target_uid={{ udoc['_id'] }}" target="_blank" data-tooltip="{{ _('Send Message') }}">
<span class="icon icon-comment--multiple"></span> <span class="icon icon-comment--multiple"></span>
</a> </a>
{% if handler.can_view(udoc, 'mail') and udoc['mail'] %} {% if handler.can_view(udoc, 'mail') and udoc['mail'] %}
@@ -137,7 +132,7 @@
</div> </div>
</li> </li>
<li class="section__tab-item"> <li class="section__tab-item">
<h1 class="section__tab-title">{{ _('Submissions') }} ({{ dudoc['num_submit']|default(0) }})</h1> <h1 class="section__tab-title">{{ _('Submissions') }} ({{ dudoc.nSubmit|default(0) }})</h1>
<div class="section__tab-main"> <div class="section__tab-main">
{% if not rdocs %} {% if not rdocs %}
{{ nothing.render('Oh, the user hasn\'t submitted yet!') }} {{ nothing.render('Oh, the user hasn\'t submitted yet!') }}
@@ -193,7 +188,7 @@
<div class="balancer sidebar-user-stat"> <div class="balancer sidebar-user-stat">
<div class="balancer__body"> <div class="balancer__body">
<div class="numbox"> <div class="numbox">
<div class="numbox__num medium">{{ dudoc['num_accept'] or 0 }}</div> <div class="numbox__num medium">{{ dudoc.nAccept or 0 }}</div>
<div class="numbox__text">{{ _('Accepted') }}</div> <div class="numbox__text">{{ _('Accepted') }}</div>
</div> </div>
</div> </div>
+1
View File
@@ -1,3 +1,4 @@
{% set page_name = "user_login" %}
{% extends "layout/immersive.html" %} {% extends "layout/immersive.html" %}
{% block content %} {% block content %}
<div class="row"><div class="columns"> <div class="row"><div class="columns">