From eaed0e84f517af4fd02081bc960547af8ac6744f Mon Sep 17 00:00:00 2001 From: undefined Date: Tue, 14 Jul 2020 19:02:19 +0800 Subject: [PATCH] =?UTF-8?q?=E2=80=9C=E6=88=91=E7=9A=84=E5=9F=9F=E2=80=9D?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hydro/handler/home.ts | 24 +++++++++++++--- hydro/handler/misc.ts | 2 +- hydro/handler/problem.ts | 2 +- hydro/model/domain.ts | 2 +- hydro/model/problem.ts | 4 +-- hydro/model/setting.ts | 3 +- hydro/model/system.ts | 2 +- hydro/service/server.ts | 45 +++++++++++++++++++---------- templates/domain_create.html | 10 +++++++ templates/home_domain.html | 53 +++++++++++++++++++++++++++++++++++ ui/components/socket/index.js | 2 +- 11 files changed, 122 insertions(+), 27 deletions(-) create mode 100644 templates/home_domain.html diff --git a/hydro/handler/home.ts b/hydro/handler/home.ts index cdea59ef6..22a37b999 100644 --- a/hydro/handler/home.ts +++ b/hydro/handler/home.ts @@ -241,6 +241,10 @@ class UserChangemailWithCodeHandler extends Handler { class HomeDomainHandler extends Handler { async get() { + const path = [ + ['Hydro', 'homepage'], + ['home_domain', null], + ]; const dudict = await domain.getDictUserByDomainId(this.user._id); const dids = Object.keys(dudict); const ddocs = await domain.getMulti({ _id: { $in: dids } }).toArray(); @@ -252,19 +256,27 @@ class HomeDomainHandler extends Handler { || udoc.hasPriv(PRIV.PRIV_MANAGE_ALL_DOMAIN); } this.response.template = 'home_domain.html'; - this.response.body = { ddocs, dudict, canManage }; + this.response.body = { + ddocs, dudict, canManage, path, + }; } } class HomeDomainCreateHandler extends Handler { async get() { - this.response.body = 'home_domain_create.html'; + this.response.body = { + path: [ + ['Hydro', 'homepage'], + ['domain_create', null], + ], + }; + this.response.template = 'domain_create.html'; } @param('id', Types.String) @param('name', Types.String, isTitle) @param('bulletin', Types.String, isContent) - @param('gravatar', Types.String, isEmail, true) + @param('gravatar', Types.String, true, isEmail) async post(_: string, id: string, name: string, bulletin: string, gravatar: string) { gravatar = gravatar || this.user.gravatar || this.user.mail || 'guest@hydro.local'; const domainId = await domain.add(id, this.user._id, name, bulletin); @@ -342,9 +354,13 @@ class HomeMessagesConnectionHandler extends ConnectionHandler { class HomeFileHandler extends Handler { async get() { + const path = [ + ['Hydro', 'homepage'], + ['domain_file', null], + ]; const ufdocs = await file.getMulti({ owner: this.user._id }).toArray(); this.response.template = 'home_file.html'; - this.response.body = { ufdocs }; + this.response.body = { ufdocs, path }; } @param('ufid', Types.ObjectID) diff --git a/hydro/handler/misc.ts b/hydro/handler/misc.ts index 2f144f177..2e5c41b37 100644 --- a/hydro/handler/misc.ts +++ b/hydro/handler/misc.ts @@ -127,7 +127,7 @@ class UiSettingsHandler extends Handler { 'ui.header_logo', 'ui.header_logo_2x', 'ui.nav_logo_dark', 'ui.nav_logo_light', 'ui.nav_logo_dark_2x', 'ui.nav_logo_light_2x', - 'ui.headerBackground', 'ui.headerBackground2x', + 'ui.header_background', 'ui.header_background2x', ]); this.response.body = await this.renderHTML('extra.css', { header_logo, diff --git a/hydro/handler/problem.ts b/hydro/handler/problem.ts index b964c4f31..07de89d5e 100644 --- a/hydro/handler/problem.ts +++ b/hydro/handler/problem.ts @@ -361,7 +361,7 @@ class ProblemDataUploadHandler extends ProblemManageHandler { async post({ domainId }) { let md5; if (!this.request.files.file) throw new BadRequestError(); - await problem.setTestdata( + this.pdoc = await problem.setTestdata( domainId, this.pdoc.docId, this.request.files.file.path, ); if (this.pdoc.data && typeof this.pdoc.data === 'object') { diff --git a/hydro/model/domain.ts b/hydro/model/domain.ts index 327c09ec1..9b5c0bb98 100644 --- a/hydro/model/domain.ts +++ b/hydro/model/domain.ts @@ -13,7 +13,7 @@ export async function add(domainId: string, owner: number, name: string, bulleti return domainId; } -export function get(domainId: string): Promise { +export function get(domainId: string): Promise { return coll.findOne({ _id: domainId }); } diff --git a/hydro/model/problem.ts b/hydro/model/problem.ts index d7c3c2206..1eef4b81c 100644 --- a/hydro/model/problem.ts +++ b/hydro/model/problem.ts @@ -28,7 +28,7 @@ export async function add( domainId: string, pid: string = null, title: string, content: string, owner: number, tag: string[] = [], category: string[] = [], data: ObjectID = null, hidden = false, ) { - const d = await domain.inc(domainId, 'pidCounter', 1); + const d = await domain.inc(domainId, 'pid_counter', 1); if (!pid) pid = d.pidCounter.toString(); return await document.add( domainId, content, owner, document.TYPE_PROBLEM, d.pidCounter, null, null, @@ -153,7 +153,7 @@ export function setStar(domainId: string, pid: number, uid: number, star: boolea export async function setTestdata(domainId: string, _id: number, filePath: string) { const pdoc = await get(domainId, _id); const config = await readConfig(filePath); - const id = await file.add(filePath, 'data.zip'); + const id = await file.add(filePath, 'data.zip', 1); if (pdoc.data && typeof pdoc.data === 'object') file.dec(pdoc.data); return await edit(domainId, _id, { data: id, config }); } diff --git a/hydro/model/setting.ts b/hydro/model/setting.ts index 467ebb298..cfbe55c4f 100644 --- a/hydro/model/setting.ts +++ b/hydro/model/setting.ts @@ -99,6 +99,7 @@ DomainSetting( Setting('setting_domain', 'name', null, 'New domain', 'text', 'name'), Setting('setting_domain', 'gravatar', null, '', 'text', 'gravatar', 'Will be used as the domain icon.'), Setting('setting_domain', 'bulletin', null, '', 'markdown', 'Bulletin'), + Setting('storage', 'pid_counter', null, 0, 'number', 'Problem ID Counter', null, FLAG_HIDDEN | FLAG_DISABLED), Setting('storage', 'nAccept', null, 0, 'number', 'nAccept', null, FLAG_HIDDEN | FLAG_DISABLED), Setting('storage', 'nSubmit', null, 0, 'number', 'nSubmit', null, FLAG_HIDDEN | FLAG_DISABLED), Setting('storage', 'nLike', null, 0, 'number', 'nLike', null, FLAG_HIDDEN | FLAG_DISABLED), @@ -126,7 +127,7 @@ SystemSetting( Setting('setting_ui', 'ui.header_logo', null, '/components/header/header-logo.png', 'text', 'Header Logo'), Setting('setting_ui', 'ui.header_logo_2x', null, '/components/header/header-logo@2x.png', 'text', 'Header Logo@2x'), Setting('setting_ui', 'ui.header_background', null, '/components/header/header-background.png', 'text', 'Header Background'), - Setting('setting_ui', 'ui.header_background_2x', null, '/components/header/header-background@2x.png', 'text', 'Header Logo@2x'), + Setting('setting_ui', 'ui.header_background_2x', null, '/components/header/header-background@2x.png', 'text', 'Header Background@2x'), Setting('setting_ui', 'ui.nav_logo_light', null, '/components/navigation/nav-logo-small_light.png', 'text', 'Nav Logo(Light)'), Setting('setting_ui', 'ui.nav_logo_dark', null, '/components/navigation/nav-logo-small_dark.png', 'text', 'Nav Logo(Dark)'), Setting('setting_ui', 'ui.nav_logo_light_2x', null, '/components/navigation/nav-logo-small@2x_light.png', 'text', 'Nav Logo@2x(Light)'), diff --git a/hydro/model/system.ts b/hydro/model/system.ts index c528200e0..25552e1be 100644 --- a/hydro/model/system.ts +++ b/hydro/model/system.ts @@ -10,7 +10,7 @@ export async function get(_id: string) { return null; } -export async function getMany(keys: string[]): Promise> { +export async function getMany(keys: string[]): Promise { const docs = await coll.find({ _id: { $in: keys } }).toArray(); const dict = {}; const res = []; diff --git a/hydro/service/server.ts b/hydro/service/server.ts index 3bc41500f..84f43e2bb 100644 --- a/hydro/service/server.ts +++ b/hydro/service/server.ts @@ -12,21 +12,22 @@ import Body from 'koa-body'; import Router from 'koa-router'; import cache from 'koa-static-cache'; import sockjs from 'sockjs'; +import { lrucache } from '../utils'; +import { Udoc, DomainDoc } from '../interface'; +import { + UserNotFoundError, BlacklistedError, PermissionError, + UserFacingError, ValidationError, PrivilegeError, + CsrfTokenError, InvalidOperationError, MethodNotAllowedError, NotFoundError, +} from '../error'; import { render } from '../lib/template'; import * as misc from '../lib/misc'; import * as user from '../model/user'; +import * as domain from '../model/domain'; import * as system from '../model/system'; import * as blacklist from '../model/blacklist'; import * as token from '../model/token'; import * as opcount from '../model/opcount'; -import { - UserNotFoundError, BlacklistedError, PermissionError, - UserFacingError, ValidationError, PrivilegeError, - CsrfTokenError, InvalidOperationError, MethodNotAllowedError, -} from '../error'; import hash from '../lib/hash.hydro'; -import { lrucache } from '../utils'; -import { Udoc } from '../interface'; let enableLog = true; @@ -145,7 +146,7 @@ export function param(name: string, ...args: any): MethodDecorator { if (!rawArgs[item.name]) throw new ValidationError(item.name); if (item.validate) { if (!item.validate(rawArgs[item.name])) { - throw new ValidationError(item.name, rawArgs[item.name]); + throw new ValidationError(item.name); } } if (item.convert) c.push(item.convert(rawArgs[item.name])); @@ -223,6 +224,8 @@ export class Handler { user: Udoc; + domain: DomainDoc; + constructor(ctx: Koa.Context) { this.ctx = ctx; this.request = { @@ -263,7 +266,7 @@ export class Handler { async renderHTML(name: string, context: any): Promise { if (enableLog) console.time(name); - const UserContext = { ...this.user, gravatar: misc.gravatar(this.user.gravatar, 128) }; + const UserContext = { ...this.user, gravatar: misc.gravatar(this.user.gravatar || '', 128) }; const res = await render(name, { handler: this, UserContext, @@ -326,7 +329,7 @@ export class Handler { let res = '#'; const args: any = { ...kwargs }; try { - if (this.args.domainId !== 'system') { + if (this.args.domainId !== 'system' || args.domainId) { name += '_with_domainId'; args.domainId = args.domainId || this.args.domainId; } @@ -372,14 +375,25 @@ export class Handler { async init({ domainId }) { const xff = await system.get('server.xff'); if (xff) this.request.ip = this.request.headers[xff.toLowerCase()]; - await Promise.all([ + [this.domain] = await Promise.all([ + domain.get(domainId), this.getSession(), this.getBdoc(), ]); + if (!this.domain) { + this.args.domainId = 'system'; + [this.user, this.UIContext.token] = await Promise.all([ + user.getById('system', this.session.uid), + token.createOrUpdate( + token.TYPE_TOKEN, 600, { uid: this.session.uid, domainId }, + ), + ]); + throw new NotFoundError(domainId); + } [this.user, this.UIContext.token] = await Promise.all([ user.getById(domainId, this.session.uid), token.createOrUpdate( - token.TYPE_TOKEN, 300, { uid: this.session.uid }, + token.TYPE_TOKEN, 600, { uid: this.session.uid, domainId }, ), ]); this.csrfToken = this.getCsrfToken(this.session._id || String.random(32)); @@ -640,11 +654,11 @@ export class ConnectionHandler { } } - url(name, kwargs = {}) { + url(name: string, kwargs = {}) { let res = '#'; const args: any = { ...kwargs }; try { - if (this.args.domainId !== 'system') { + if (this.args.domainId !== 'system' || args.domainId) { name += '_with_domainId'; args.domainId = args.domainId || this.args.domainId; } @@ -676,8 +690,9 @@ export class ConnectionHandler { try { this.session = await token.get(this.request.params.token, token.TYPE_TOKEN, true); } catch (e) { - this.session = { uid: 0 }; + this.session = { uid: 0, domainId: 'system' }; } + this.args.domainId = this.session.domainId; const bdoc = await blacklist.get(this.request.ip); if (bdoc) throw new BlacklistedError(this.request.ip); this.user = await user.getById(domainId, this.session.uid); diff --git a/templates/domain_create.html b/templates/domain_create.html index 9d98d78db..ea957b6b4 100644 --- a/templates/domain_create.html +++ b/templates/domain_create.html @@ -29,6 +29,16 @@ name:'name', required:true }) }} + {{ form.form_textarea({ + label:'Bulletin', + name:'bulletin', + markdown:true, + required:true + }) }} + {{ form.form_text({ + label:'Gravatar', + name:'gravatar' + }) }}