From 30007fc39382424957aa689ff99d75f78b626b0b Mon Sep 17 00:00:00 2001 From: Breezewish Date: Sat, 5 Aug 2017 23:13:19 +0800 Subject: [PATCH 1/7] Support setting record publicity --- vj4/handler/record.py | 14 ++++++++++++ vj4/locale/zh_CN.yaml | 27 +++++++++++++---------- vj4/locale/zh_TW.yaml | 20 ++++++++--------- vj4/model/adaptor/setting.py | 5 ++++- vj4/model/builtin.py | 29 +++++++++++++++---------- vj4/model/record.py | 10 +++++++++ vj4/ui/components/form/button.page.styl | 6 +++++ vj4/ui/constant/setting.js | 13 ++++++++++- vj4/ui/pages/record_detail.page.js | 6 +++++ vj4/ui/pages/record_detail.page.styl | 1 - vj4/ui/pages/record_main.page.js | 9 +++++--- vj4/ui/templates/contest_main.html | 2 +- vj4/ui/templates/record_detail.html | 22 ++++++++++++++++++- 13 files changed, 124 insertions(+), 40 deletions(-) diff --git a/vj4/handler/record.py b/vj4/handler/record.py index d33057917..cf9d30851 100644 --- a/vj4/handler/record.py +++ b/vj4/handler/record.py @@ -213,6 +213,20 @@ async def post(self, *, rid: objectid.ObjectId): self.json_or_redirect(self.referer_or_main) +@app.route('/records/{rid}/publicity', 'record_set_publicity') +class RecordSetPublicityHandler(base.Handler): + @base.route_argument + @base.post_argument + @base.require_csrf_token + @base.sanitize + async def post(self, *, rid: objectid.ObjectId, publicity: int): + rdoc = await record.get(rid) + if (not self.own(rdoc, field='uid', perm=builtin.PERM_MODIFY_RECORD_VISIBILITY_SELF)): + self.check_perm(builtin.PERM_MODIFY_RECORD_VISIBILITY) + await record.set_publicity(rdoc['_id'], publicity) + self.json_or_redirect(self.referer_or_main) + + @app.route('/records/{rid}/data', 'record_pretest_data') class RecordPretestDataHandler(base.Handler): @base.route_argument diff --git a/vj4/locale/zh_CN.yaml b/vj4/locale/zh_CN.yaml index 4a605bdff..14e1340b2 100644 --- a/vj4/locale/zh_CN.yaml +++ b/vj4/locale/zh_CN.yaml @@ -18,6 +18,8 @@ Begin Time: 开始时间 Belongs to: 属于 Bio: 个人简介 Bio Visibility: 个人简介可见性 +Submission Code Visibility: 递交记录代码可见性 +Sets whether your source code is public to others. This option may be overridden by submission options.: 设置其他人是否可以看到您递交的代码。该设置可能被递交记录的设置覆盖。 Blog: 博客 Boom!: 炸了! Browser: 浏览器 @@ -142,6 +144,7 @@ Save All Changes: 保存所有修改 Saved session: 已保存的会话 Score: 分数 Secret: 保密 +Use account settings: 由账户设置决定 Secret (visible to admins): 保密(对管理员可见) Security: 安全 Select a node to create discussion.: 选择一个节点来发表讨论。 @@ -201,7 +204,7 @@ Using your Vijos universal account: 使用您的 Vijos 通用账户 View Problem: 查看题目 View or create discussion: 查看与发表讨论 View or submit solution: 查看与发表题解 -Visible to registered users: 对注册用户可见 +Public to registered users: 对注册用户可见 Vote: 投票 We use Gravatar to present your avatar icon.: 我们使用 Gravatar 服务来呈现您的头像。 Whether to show tags in the problem list.: 是否在题目列表中显示题目的标签。 @@ -406,33 +409,33 @@ View problems: 查看题目 Submit problem: 递交题目 Read data of problem: 读取题目数据 Read data of own problems: 读取自己题目的数据 -Read record codes: 读取记录的代码 +Read any record codes: 读取任意记录的代码 Rejudge problems: 重测题目 Rejudge records: 重测记录 View problem solutions: 查看题解 Create problem solutions: 创建题解 Vote problem solutions: 为题解投票 -Edit problem solutions: 修改题解 +Edit any problem solutions: 修改任意题解 Edit own problem solutions: 修改自己的题解 -Delete problem solutions: 删除题解 +Delete any problem solutions: 删除任意题解 Delete own problem solutions: 删除自己的题解 Reply problem solutions: 回复题解 -Edit problem solution replies: 修改题解的回复 +Edit any problem solution replies: 修改任意题解的回复 Edit own problem solution replies: 修改题解中自己的回复 -Delete problem solution replies: 删除题解的回复 +Delete any problem solution replies: 删除任意题解的回复 Delete own problem solution replies: 删除题解中自己的回复 View discussions: 查看讨论 Create discussions: 创建讨论 Highlight discussions: 高亮讨论 -Edit discussions: 修改讨论 +Edit any discussions: 修改任意讨论 Edit own discussions: 修改自己的讨论 -Delete discussions: 删除讨论 +Delete any discussions: 删除任意讨论 Delete own discussions: 删除自己的讨论 Reply discussions: 回复讨论 -Edit discussion replies: 修改讨论的回复 +Edit any discussion replies: 修改任意讨论的回复 Edit own discussion replies: 修改讨论中自己的回复 Edit discussion replies of own discussion: 修改自己讨论中的回复 -Delete discussion replies: 删除讨论回复 +Delete any discussion replies: 删除任意讨论回复 Delete own discussion replies: 删除讨论中自己的回复 Delete discussion replies of own discussion: 删除自己讨论中的回复 View contests: 查看比赛 @@ -523,7 +526,7 @@ collapse: 收缩 'Note: Problem title may not be hidden.': 注意:题目标题可能不会被隐藏。 Partic.: 参赛人数 Create training plans: 创建训练计划 -Edit training plans: 修改训练计划 +Edit any training plans: 修改任意训练计划 Edit own training plans: 修改自己的训练计划 Click here to chat with me: 点击这里与我聊天 Terms of Service: 服务条款 @@ -645,3 +648,5 @@ You cannot visit this domain.: 您不能访问此域。 Menu: 菜单 'Copy failed :(': '复制失败 :(' Code copied to clipboard!: 代码已复制到剪贴板! +Set any records' code visibility: 设置任意记录中代码的可见性 +Set own records' code visibility: 设置自己记录中代码的可见性 diff --git a/vj4/locale/zh_TW.yaml b/vj4/locale/zh_TW.yaml index c15d30780..f7267455c 100644 --- a/vj4/locale/zh_TW.yaml +++ b/vj4/locale/zh_TW.yaml @@ -198,7 +198,7 @@ Using your Vijos universal account: 使用您的 Vijos 通用賬戶 View Problem: 檢視題目 View or create discussion: 檢視與發表討論 View or submit solution: 檢視與發表題解 -Visible to registered users: 對註冊使用者可見 +Public to registered users: 對註冊使用者可見 Vote: 投票 We use Gravatar to present your avatar icon.: 我們使用 Gravatar 服務來呈現您的頭像。 Whether to show tags in the problem list.: 是否在題目列表中顯示題目的標籤。 @@ -400,33 +400,33 @@ View problems: 檢視題目 Submit problem: 遞交題目 Read data of problem: 讀取題目資料 Read data of own problems: 讀取自己題目的資料 -Read record codes: 讀取記錄的程式碼 +Read any record codes: 讀取記錄的程式碼 Rejudge problems: 重測題目 Rejudge records: 重測記錄 View problem solutions: 檢視題解 Create problem solutions: 創建題解 Vote problem solutions: 為題解投票 -Edit problem solutions: 修改題解 +Edit any problem solutions: 修改題解 Edit own problem solutions: 修改自己的題解 -Delete problem solutions: 刪除題解 +Delete any problem solutions: 刪除題解 Delete own problem solutions: 刪除自己的題解 Reply problem solutions: 回覆題解 -Edit problem solution replies: 修改題解的回覆 +Edit any problem solution replies: 修改題解的回覆 Edit own problem solution replies: 修改題解中自己的回覆 -Delete problem solution replies: 刪除題解的回覆 +Delete any problem solution replies: 刪除題解的回覆 Delete own problem solution replies: 刪除題解中自己的回覆 View discussions: 檢視討論 Create discussions: 創建討論 Highlight discussions: 高亮討論 -Edit discussions: 修改討論 +Edit any discussions: 修改討論 Edit own discussions: 修改自己的討論 -Delete discussions: 刪除討論 +Delete any discussions: 刪除討論 Delete own discussions: 刪除自己的討論 Reply discussions: 回覆討論 -Edit discussion replies: 修改討論的回覆 +Edit any discussion replies: 修改討論的回覆 Edit own discussion replies: 修改討論中自己的回覆 Edit discussion replies of own discussion: 修改自己討論中的回覆 -Delete discussion replies: 刪除討論回覆 +Delete any discussion replies: 刪除討論回覆 Delete own discussion replies: 刪除討論中自己的回覆 Delete discussion replies of own discussion: 刪除自己討論中的回覆 View contests: 檢視比賽 diff --git a/vj4/model/adaptor/setting.py b/vj4/model/adaptor/setting.py index ca81d783d..8d30660d6 100644 --- a/vj4/model/adaptor/setting.py +++ b/vj4/model/adaptor/setting.py @@ -53,7 +53,10 @@ Setting('setting_privacy', 'show_gender', int, range=constant.setting.PRIVACY_RANGE, ui='select', name='Gender Visibility'), Setting('setting_privacy', 'show_bio', int, range=constant.setting.PRIVACY_RANGE, - ui='select', name='Bio Visibility')] + ui='select', name='Bio Visibility'), + Setting('setting_privacy', 'show_submission_code', int, range=constant.setting.PRIVACY_RANGE, + ui='select', name='Submission Code Visibility', default=constant.setting.PRIVACY_SECRET, + desc='Sets whether your source code is public to others. This option may be overridden by submission options.')] SETTINGS = PREFERENCE_SETTINGS + ACCOUNT_SETTINGS SETTINGS_BY_KEY = collections.OrderedDict(zip((s.key for s in SETTINGS), SETTINGS)) diff --git a/vj4/model/builtin.py b/vj4/model/builtin.py index f2ea9a706..faa429920 100644 --- a/vj4/model/builtin.py +++ b/vj4/model/builtin.py @@ -71,6 +71,10 @@ PERM_EDIT_TRAINING = 1 << 48 PERM_EDIT_TRAINING_SELF = 1 << 49 +# Additional Permissions. +PERM_MODIFY_RECORD_VISIBILITY = 1 << 50 +PERM_MODIFY_RECORD_VISIBILITY_SELF = 1 << 51 + PERM_ALL = -1 Permission = functools.partial( @@ -90,33 +94,35 @@ Permission('perm_problem', PERM_SUBMIT_PROBLEM, 'Submit problem'), Permission('perm_problem', PERM_READ_PROBLEM_DATA, 'Read data of problem'), Permission('perm_problem', PERM_READ_PROBLEM_DATA_SELF, 'Read data of own problems'), - Permission('perm_record', PERM_READ_RECORD_CODE, 'Read record codes'), + Permission('perm_record', PERM_READ_RECORD_CODE, 'Read any record codes'), + Permission('perm_record', PERM_MODIFY_RECORD_VISIBILITY, 'Set any records\' code visibility'), + Permission('perm_record', PERM_MODIFY_RECORD_VISIBILITY_SELF, 'Set own records\' code visibility'), Permission('perm_record', PERM_REJUDGE_PROBLEM, 'Rejudge problems'), Permission('perm_record', PERM_REJUDGE, 'Rejudge records'), Permission('perm_problem_solution', PERM_VIEW_PROBLEM_SOLUTION, 'View problem solutions'), Permission('perm_problem_solution', PERM_CREATE_PROBLEM_SOLUTION, 'Create problem solutions'), Permission('perm_problem_solution', PERM_VOTE_PROBLEM_SOLUTION, 'Vote problem solutions'), - Permission('perm_problem_solution', PERM_EDIT_PROBLEM_SOLUTION, 'Edit problem solutions'), + Permission('perm_problem_solution', PERM_EDIT_PROBLEM_SOLUTION, 'Edit any problem solutions'), Permission('perm_problem_solution', PERM_EDIT_PROBLEM_SOLUTION_SELF, 'Edit own problem solutions'), - Permission('perm_problem_solution', PERM_DELETE_PROBLEM_SOLUTION, 'Delete problem solutions'), + Permission('perm_problem_solution', PERM_DELETE_PROBLEM_SOLUTION, 'Delete any problem solutions'), Permission('perm_problem_solution', PERM_DELETE_PROBLEM_SOLUTION_SELF, 'Delete own problem solutions'), Permission('perm_problem_solution', PERM_REPLY_PROBLEM_SOLUTION, 'Reply problem solutions'), - Permission('perm_problem_solution', PERM_EDIT_PROBLEM_SOLUTION_REPLY, 'Edit problem solution replies'), + Permission('perm_problem_solution', PERM_EDIT_PROBLEM_SOLUTION_REPLY, 'Edit any problem solution replies'), Permission('perm_problem_solution', PERM_EDIT_PROBLEM_SOLUTION_REPLY_SELF, 'Edit own problem solution replies'), - Permission('perm_problem_solution', PERM_DELETE_PROBLEM_SOLUTION_REPLY, 'Delete problem solution replies'), + Permission('perm_problem_solution', PERM_DELETE_PROBLEM_SOLUTION_REPLY, 'Delete any problem solution replies'), Permission('perm_problem_solution', PERM_DELETE_PROBLEM_SOLUTION_REPLY_SELF, 'Delete own problem solution replies'), Permission('perm_discussion', PERM_VIEW_DISCUSSION, 'View discussions'), Permission('perm_discussion', PERM_CREATE_DISCUSSION, 'Create discussions'), Permission('perm_discussion', PERM_HIGHLIGHT_DISCUSSION, 'Highlight discussions'), - Permission('perm_discussion', PERM_EDIT_DISCUSSION, 'Edit discussions'), + Permission('perm_discussion', PERM_EDIT_DISCUSSION, 'Edit any discussions'), Permission('perm_discussion', PERM_EDIT_DISCUSSION_SELF, 'Edit own discussions'), - Permission('perm_discussion', PERM_DELETE_DISCUSSION, 'Delete discussions'), + Permission('perm_discussion', PERM_DELETE_DISCUSSION, 'Delete any discussions'), Permission('perm_discussion', PERM_DELETE_DISCUSSION_SELF, 'Delete own discussions'), Permission('perm_discussion', PERM_REPLY_DISCUSSION, 'Reply discussions'), - Permission('perm_discussion', PERM_EDIT_DISCUSSION_REPLY, 'Edit discussion replies'), + Permission('perm_discussion', PERM_EDIT_DISCUSSION_REPLY, 'Edit any discussion replies'), Permission('perm_discussion', PERM_EDIT_DISCUSSION_REPLY_SELF, 'Edit own discussion replies'), Permission('perm_discussion', PERM_EDIT_DISCUSSION_REPLY_SELF_DISCUSSION, 'Edit discussion replies of own discussion'), - Permission('perm_discussion', PERM_DELETE_DISCUSSION_REPLY, 'Delete discussion replies'), + Permission('perm_discussion', PERM_DELETE_DISCUSSION_REPLY, 'Delete any discussion replies'), Permission('perm_discussion', PERM_DELETE_DISCUSSION_REPLY_SELF, 'Delete own discussion replies'), Permission('perm_discussion', PERM_DELETE_DISCUSSION_REPLY_SELF_DISCUSSION, 'Delete discussion replies of own discussion'), Permission('perm_contest', PERM_VIEW_CONTEST, 'View contests'), @@ -126,7 +132,7 @@ Permission('perm_contest', PERM_ATTEND_CONTEST, 'Attend contests'), Permission('perm_training', PERM_VIEW_TRAINING, 'View training plans'), Permission('perm_training', PERM_CREATE_TRAINING, 'Create training plans'), - Permission('perm_training', PERM_EDIT_TRAINING, 'Edit training plans'), + Permission('perm_training', PERM_EDIT_TRAINING, 'Edit any training plans'), Permission('perm_training', PERM_EDIT_TRAINING_SELF, 'Edit own training plans'), ] @@ -209,7 +215,8 @@ PERM_ATTEND_CONTEST | PERM_VIEW_TRAINING | PERM_CREATE_TRAINING | - PERM_EDIT_TRAINING_SELF + PERM_EDIT_TRAINING_SELF | + PERM_MODIFY_RECORD_VISIBILITY_SELF ) ADMIN_PERMISSIONS = PERM_ALL DOMAIN_SYSTEM = { diff --git a/vj4/model/record.py b/vj4/model/record.py index 04b2c9264..88474e8d1 100644 --- a/vj4/model/record.py +++ b/vj4/model/record.py @@ -74,6 +74,16 @@ async def rejudge(record_id: objectid.ObjectId, enqueue: bool=True): await queue.publish('judge', rid=doc['_id']) +@argmethod.wrap +async def set_publicity(record_id: objectid.ObjectId, publicity: int): + if publicity not in constant.setting.SUBMISSION_PUBLICITY_RANGE: + raise error.ValidationError('publicity') + coll = db.coll('record') + doc = await coll.find_one_and_update(filter={'_id': record_id}, + update={'$set': {'settings.publicity': publicity}}, + return_document=ReturnDocument.AFTER) + + @argmethod.wrap def get_all_multi(end_id: objectid.ObjectId=None, get_hidden: bool=False, *, fields=None, **kwargs): diff --git a/vj4/ui/components/form/button.page.styl b/vj4/ui/components/form/button.page.styl index c46581a1d..4a19cffc8 100644 --- a/vj4/ui/components/form/button.page.styl +++ b/vj4/ui/components/form/button.page.styl @@ -57,6 +57,12 @@ cursor: default opacity: 0.5 + &.compact + margin-bottom: 0 + height: rem($compact-control-height) + line-height: rem($compact-control-height - 2) + padding: rem(0 15px) + .button.inverse line-height: rem($form-control-height - 4) border: 2px solid #FFF diff --git a/vj4/ui/constant/setting.js b/vj4/ui/constant/setting.js index 6b3e0ec44..ad682c356 100644 --- a/vj4/ui/constant/setting.js +++ b/vj4/ui/constant/setting.js @@ -5,11 +5,22 @@ export const PRIVACY_REGISTERED_ONLY = 1; export const PRIVACY_SECRET = 2; export const PRIVACY_RANGE = { [PRIVACY_PUBLIC]: 'Public', - [PRIVACY_REGISTERED_ONLY]: 'Visible to registered users', + [PRIVACY_REGISTERED_ONLY]: 'Public to registered users', [PRIVACY_SECRET]: 'Secret', }; attachObjectMeta(PRIVACY_RANGE, 'intKey', true); +export const SUBMISSION_PUBLICITY_USE_SETTINGS = 3; +export const SUBMISSION_PUBLICITY_RANGE = { + [PRIVACY_PUBLIC]: 'Public', + [PRIVACY_REGISTERED_ONLY]: 'Public to registered users', + [PRIVACY_SECRET]: 'Secret', + [SUBMISSION_PUBLICITY_USE_SETTINGS]: 'Use account settings', +}; +attachObjectMeta(SUBMISSION_PUBLICITY_RANGE, 'intKey', true); + +export const SUBMISSION_PUBLICITY_DEFAULT = SUBMISSION_PUBLICITY_USE_SETTINGS; + export const FUNCTION_RANGE = { 0: 'Disabled', 1: 'Enabled', diff --git a/vj4/ui/pages/record_detail.page.js b/vj4/ui/pages/record_detail.page.js index bc6416640..f09c271a9 100644 --- a/vj4/ui/pages/record_detail.page.js +++ b/vj4/ui/pages/record_detail.page.js @@ -1,6 +1,12 @@ import { NamedPage } from 'vj/misc/PageLoader'; const page = new NamedPage('record_detail', async () => { + // Update publicity + $('[name="publicity-form"] [name="publicity"]').change(() => { + $('[name="publicity-form"]').submit(); + }); + + // Realtime update const SockJs = await System.import('sockjs-client'); const DiffDOM = await System.import('diff-dom'); diff --git a/vj4/ui/pages/record_detail.page.styl b/vj4/ui/pages/record_detail.page.styl index afe6a8fc3..5deea1310 100644 --- a/vj4/ui/pages/record_detail.page.styl +++ b/vj4/ui/pages/record_detail.page.styl @@ -1,7 +1,6 @@ .page--record_detail .compiler-text - padding: rem(20px 0) font-size: rem($font-size-small) &:empty display: none diff --git a/vj4/ui/pages/record_main.page.js b/vj4/ui/pages/record_main.page.js index c035dab08..6a926be4b 100644 --- a/vj4/ui/pages/record_main.page.js +++ b/vj4/ui/pages/record_main.page.js @@ -2,6 +2,12 @@ import { NamedPage } from 'vj/misc/PageLoader'; import UserSelectAutoComplete from 'vj/components/autocomplete/UserSelectAutoComplete'; const page = new NamedPage('record_main', async () => { + // Autocomplete + UserSelectAutoComplete.getOrConstruct($('.filter-user [name="uid_or_name"]'), { + clearDefaultValue: false, + }); + + // Realtime update const SockJs = await System.import('sockjs-client'); const DiffDOM = await System.import('diff-dom'); @@ -18,9 +24,6 @@ const page = new NamedPage('record_main', async () => { $('.record_main__table tbody').prepend(newTr); } }; - UserSelectAutoComplete.getOrConstruct($('.filter-user [name="uid_or_name"]'), { - clearDefaultValue: false, - }); }); export default page; diff --git a/vj4/ui/templates/contest_main.html b/vj4/ui/templates/contest_main.html index c5212e31b..5ee828258 100644 --- a/vj4/ui/templates/contest_main.html +++ b/vj4/ui/templates/contest_main.html @@ -66,7 +66,7 @@

{% if not rule %}{{ _('All Contests') }}{% else %}{{ {% endfor %} - diff --git a/vj4/ui/templates/record_detail.html b/vj4/ui/templates/record_detail.html index a5217bfaf..3423328f4 100644 --- a/vj4/ui/templates/record_detail.html +++ b/vj4/ui/templates/record_detail.html @@ -10,13 +10,33 @@ {% if show_status %} {% include 'record_detail_status.html' %} {% endif %} - {% if rdoc['code'] %} + {% set can_set_publicity = handler.own(rdoc, field='uid', perm=vj4.model.builtin.PERM_MODIFY_RECORD_VISIBILITY_SELF) or handler.has_perm(vj4.model.builtin.PERM_MODIFY_RECORD_VISIBILITY) %} + {% if rdoc['code'] or can_set_publicity %}

{{ _('Code') }}

+
+
+ {{ _('Publicity') }}: + {% set current_publicity=rdoc['settings']['publicity'] | default(vj4.constant.setting.SUBMISSION_PUBLICITY_DEFAULT) %} + + + +
+
+ {% if rdoc['code'] %}
{{ rdoc['code'] }}
+ {% else %} + {{ nothing.render('You don\'t have the permission to view the code.') }} + {% endif %}
{% endif %} From a27c8cb124713d0aff376293e0fe73ea53783879 Mon Sep 17 00:00:00 2001 From: Wende Tan Date: Sun, 13 Aug 2017 02:01:52 +0800 Subject: [PATCH 2/7] uniform `visibility` --- vj4/handler/record.py | 10 ++++++---- vj4/model/record.py | 8 ++++---- vj4/ui/constant/setting.js | 10 +++++----- vj4/ui/pages/record_detail.page.js | 6 +++--- vj4/ui/templates/record_detail.html | 14 +++++++------- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/vj4/handler/record.py b/vj4/handler/record.py index cf9d30851..cf8f0e384 100644 --- a/vj4/handler/record.py +++ b/vj4/handler/record.py @@ -213,17 +213,19 @@ async def post(self, *, rid: objectid.ObjectId): self.json_or_redirect(self.referer_or_main) -@app.route('/records/{rid}/publicity', 'record_set_publicity') -class RecordSetPublicityHandler(base.Handler): +@app.route('/records/{rid}/visibility', 'record_visibility') +class RecordVisibilityHandler(base.Handler): @base.route_argument @base.post_argument @base.require_csrf_token @base.sanitize - async def post(self, *, rid: objectid.ObjectId, publicity: int): + async def post(self, *, rid: objectid.ObjectId, visibility: int): rdoc = await record.get(rid) + if not rdoc: + raise error.RecordNotFoundError(rid) if (not self.own(rdoc, field='uid', perm=builtin.PERM_MODIFY_RECORD_VISIBILITY_SELF)): self.check_perm(builtin.PERM_MODIFY_RECORD_VISIBILITY) - await record.set_publicity(rdoc['_id'], publicity) + await record.set_visibility(rdoc['_id'], visibility) self.json_or_redirect(self.referer_or_main) diff --git a/vj4/model/record.py b/vj4/model/record.py index 88474e8d1..63ac83b6e 100644 --- a/vj4/model/record.py +++ b/vj4/model/record.py @@ -75,12 +75,12 @@ async def rejudge(record_id: objectid.ObjectId, enqueue: bool=True): @argmethod.wrap -async def set_publicity(record_id: objectid.ObjectId, publicity: int): +async def set_visibility(rid: objectid.ObjectId, visibility: int): if publicity not in constant.setting.SUBMISSION_PUBLICITY_RANGE: - raise error.ValidationError('publicity') + raise error.ValidationError('visibility') coll = db.coll('record') - doc = await coll.find_one_and_update(filter={'_id': record_id}, - update={'$set': {'settings.publicity': publicity}}, + doc = await coll.find_one_and_update(filter={'_id': rid}, + update={'$set': {'visibility': visibility}}, return_document=ReturnDocument.AFTER) diff --git a/vj4/ui/constant/setting.js b/vj4/ui/constant/setting.js index ca33c2246..8398f14c4 100644 --- a/vj4/ui/constant/setting.js +++ b/vj4/ui/constant/setting.js @@ -10,16 +10,16 @@ export const PRIVACY_RANGE = { }; attachObjectMeta(PRIVACY_RANGE, 'intKey', true); -export const SUBMISSION_PUBLICITY_USE_SETTINGS = 3; -export const SUBMISSION_PUBLICITY_RANGE = { +export const SUBMISSION_VISIBILITY_USE_SETTINGS = 3; +export const SUBMISSION_VISIBILITY_RANGE = { [PRIVACY_PUBLIC]: 'Public', [PRIVACY_REGISTERED_ONLY]: 'Public to registered users', [PRIVACY_SECRET]: 'Secret', - [SUBMISSION_PUBLICITY_USE_SETTINGS]: 'Use account settings', + [SUBMISSION_VISIBILITY_USE_SETTINGS]: 'Use account settings', }; -attachObjectMeta(SUBMISSION_PUBLICITY_RANGE, 'intKey', true); +attachObjectMeta(SUBMISSION_VISIBILITY_RANGE, 'intKey', true); -export const SUBMISSION_PUBLICITY_DEFAULT = SUBMISSION_PUBLICITY_USE_SETTINGS; +export const SUBMISSION_VISIBILITY_DEFAULT = SUBMISSION_VISIBILITY_USE_SETTINGS; export const FUNCTION_RANGE = { 0: 'Disabled', diff --git a/vj4/ui/pages/record_detail.page.js b/vj4/ui/pages/record_detail.page.js index f09c271a9..e0200afb9 100644 --- a/vj4/ui/pages/record_detail.page.js +++ b/vj4/ui/pages/record_detail.page.js @@ -1,9 +1,9 @@ import { NamedPage } from 'vj/misc/PageLoader'; const page = new NamedPage('record_detail', async () => { - // Update publicity - $('[name="publicity-form"] [name="publicity"]').change(() => { - $('[name="publicity-form"]').submit(); + // Update visibility + $('[name="visibility-form"] [name="visibility"]').change(() => { + $('[name="visibility-form"]').submit(); }); // Realtime update diff --git a/vj4/ui/templates/record_detail.html b/vj4/ui/templates/record_detail.html index 3423328f4..244935ee1 100644 --- a/vj4/ui/templates/record_detail.html +++ b/vj4/ui/templates/record_detail.html @@ -10,18 +10,18 @@ {% if show_status %} {% include 'record_detail_status.html' %} {% endif %} - {% set can_set_publicity = handler.own(rdoc, field='uid', perm=vj4.model.builtin.PERM_MODIFY_RECORD_VISIBILITY_SELF) or handler.has_perm(vj4.model.builtin.PERM_MODIFY_RECORD_VISIBILITY) %} - {% if rdoc['code'] or can_set_publicity %} + {% set can_set_visibility = handler.own(rdoc, field='uid', perm=vj4.model.builtin.PERM_MODIFY_RECORD_VISIBILITY_SELF) or handler.has_perm(vj4.model.builtin.PERM_MODIFY_RECORD_VISIBILITY) %} + {% if rdoc['code'] or can_set_visibility %}

{{ _('Code') }}

- {{ _('Publicity') }}: - {% set current_publicity=rdoc['settings']['publicity'] | default(vj4.constant.setting.SUBMISSION_PUBLICITY_DEFAULT) %} - + {% for k, v in vj4.constant.setting.SUBMISSION_VISIBILITY_RANGE.items() %} + {% endfor %} From 6c23a133e6b4ca52e6b130d5485344c15d707304 Mon Sep 17 00:00:00 2001 From: Wende Tan Date: Sun, 13 Aug 2017 02:02:47 +0800 Subject: [PATCH 3/7] translation --- vj4/locale/zh_CN.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vj4/locale/zh_CN.yaml b/vj4/locale/zh_CN.yaml index 000d6ddb3..cefefc043 100644 --- a/vj4/locale/zh_CN.yaml +++ b/vj4/locale/zh_CN.yaml @@ -652,4 +652,5 @@ Code copied to clipboard!: 代码已复制到剪贴板! Set any records' code visibility: 设置任意记录中代码的可见性 Set own records' code visibility: 设置自己记录中代码的可见性 No comments so far...: 目前还没有评论... -No solutions so far...: 目前还没有题解... \ No newline at end of file +No solutions so far...: 目前还没有题解... +You don't have the permission to view the code.: 您没有权限查看代码。 From 9ca4c140a55740c7477ecc1625d0b7c74b7e4c0c Mon Sep 17 00:00:00 2001 From: Wende Tan Date: Sun, 13 Aug 2017 02:28:52 +0800 Subject: [PATCH 4/7] impl --- vj4/handler/record.py | 18 ++++++++++++++---- vj4/locale/zh_CN.yaml | 1 + vj4/model/record.py | 2 +- vj4/ui/templates/record_detail.html | 4 +++- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/vj4/handler/record.py b/vj4/handler/record.py index cf8f0e384..b06e0a28f 100644 --- a/vj4/handler/record.py +++ b/vj4/handler/record.py @@ -17,6 +17,7 @@ from vj4.model import user from vj4.model.adaptor import contest from vj4.model.adaptor import problem +from vj4.model.adaptor import setting from vj4.service import bus from vj4.util import options @@ -143,15 +144,24 @@ async def get(self, *, rid: objectid.ObjectId): else: tdoc = None # TODO(twd2): futher check permission for visibility. - if (not self.own(rdoc, field='uid') + udoc, dudoc = await asyncio.gather( + user.get_by_uid(rdoc['uid']), + domain.get_user(self.domain_id, rdoc['uid'])) + # check visibility + visibility = rdoc.get('visibility', constant.setting.SUBMISSION_VISIBILITY_DEFAULT) + if visibility == constant.setting.SUBMISSION_VISIBILITY_USE_SETTINGS: + u = setting.UserSetting(udoc) + visibility = u.get_setting('show_submission_code') + can_view_code = visibility == constant.setting.PRIVACY_PUBLIC \ + or (visibility == constant.setting.PRIVACY_REGISTERED_ONLY + and self.has_priv(builtin.PRIV_USER_PROFILE)) + if (not can_view_code + and not self.own(rdoc, field='uid') and not self.has_perm(builtin.PERM_READ_RECORD_CODE) and not self.has_priv(builtin.PRIV_READ_RECORD_CODE)): del rdoc['code'] if not show_status and 'code' not in rdoc: raise error.PermissionError(builtin.PERM_VIEW_CONTEST_HIDDEN_STATUS) - udoc, dudoc = await asyncio.gather( - user.get_by_uid(rdoc['uid']), - domain.get_user(self.domain_id, rdoc['uid'])) try: pdoc = await problem.get(rdoc['domain_id'], rdoc['pid']) except error.ProblemNotFoundError: diff --git a/vj4/locale/zh_CN.yaml b/vj4/locale/zh_CN.yaml index cefefc043..0456cc7d1 100644 --- a/vj4/locale/zh_CN.yaml +++ b/vj4/locale/zh_CN.yaml @@ -654,3 +654,4 @@ Set own records' code visibility: 设置自己记录中代码的可见性 No comments so far...: 目前还没有评论... No solutions so far...: 目前还没有题解... You don't have the permission to view the code.: 您没有权限查看代码。 +Visibility: 可见性 diff --git a/vj4/model/record.py b/vj4/model/record.py index 63ac83b6e..89e6266c8 100644 --- a/vj4/model/record.py +++ b/vj4/model/record.py @@ -76,7 +76,7 @@ async def rejudge(record_id: objectid.ObjectId, enqueue: bool=True): @argmethod.wrap async def set_visibility(rid: objectid.ObjectId, visibility: int): - if publicity not in constant.setting.SUBMISSION_PUBLICITY_RANGE: + if visibility not in constant.setting.SUBMISSION_VISIBILITY_RANGE: raise error.ValidationError('visibility') coll = db.coll('record') doc = await coll.find_one_and_update(filter={'_id': rid}, diff --git a/vj4/ui/templates/record_detail.html b/vj4/ui/templates/record_detail.html index 244935ee1..b0caa694e 100644 --- a/vj4/ui/templates/record_detail.html +++ b/vj4/ui/templates/record_detail.html @@ -15,8 +15,9 @@

{{ _('Code') }}

+ {% if can_set_visibility %}
- + {{ _('Visibility') }}: {% set current_visibility=rdoc['visibility']|default(vj4.constant.setting.SUBMISSION_VISIBILITY_DEFAULT) %}