import { Context, Next } from 'koa'; import Router from 'koa-router'; import {Content, ContentAccessor, isContentContent} from './../model/contents'; import {QueryListOption} from './../model/contents'; import {ParseQueryNumber, ParseQueryArray, ParseQueryBoolean} from './util' import {sendError} from './error_handler'; import { createContentReferrer } from '../content/mod'; import { join } from 'path'; import {AllContentRouter} from './all'; import {createPermissionCheckMiddleware as PerCheck, Permission as Per, AdminOnlyMiddleware as AdminOnly} from '../permission/permission'; const ContentIDHandler = (controller: ContentAccessor) => async (ctx: Context,next: Next)=>{ const num = Number.parseInt(ctx.params['num']); let content = await controller.findById(num,true); if (content == undefined){ return sendError(404,"content does not exist."); } ctx.body = content; ctx.type = 'json'; console.log(content.additional); }; const ContentTagIDHandler = (controller: ContentAccessor) => async (ctx: Context,next: Next)=>{ const num = Number.parseInt(ctx.params['num']); let content = await controller.findById(num,true); if (content == undefined){ return sendError(404,"content does not exist."); } ctx.body = content.tags || []; ctx.type = 'json'; }; const ContentQueryHandler = (controller : ContentAccessor) => async (ctx: Context,next: Next)=>{ const limit = ParseQueryNumber(ctx.query['limit']); const cursor = ParseQueryNumber(ctx.query['cursor']); const word: string|undefined = ctx.query['word']; const content_type:string|undefined = ctx.query['content_type']; const offset = ParseQueryNumber(ctx.query['offset']); if(limit === NaN || cursor === NaN || offset === NaN){ return sendError(400,"parameter limit, cursor or offset is not a number"); } const allow_tag = ParseQueryArray(ctx.query['allow_tag[]']); let [ok,use_offset] = ParseQueryBoolean(ctx.query['use_offset']); if(!ok){ return sendError(400,"use_offset must be true or false."); } const option :QueryListOption = { limit: limit, allow_tag: allow_tag, word: word, cursor: cursor, eager_loading: true, offset: offset, use_offset: use_offset, content_type:content_type, }; let content = await controller.findList(option); ctx.body = content; ctx.type = 'json'; } const UpdateContentHandler = (controller : ContentAccessor) => async (ctx: Context, next: Next) => { const num = Number.parseInt(ctx.params['num']); if(ctx.request.type !== 'json'){ return sendError(400,"update fail. invalid content type: it is not json."); } if(typeof ctx.request.body !== "object"){ return sendError(400,"update fail. invalid argument: not"); } const content_desc: Partial & {id: number} = { id:num,...ctx.request.body }; const success = await controller.update(content_desc); ctx.body = JSON.stringify(success); ctx.type = 'json'; } const CreateContentHandler = (controller : ContentAccessor) => async (ctx: Context, next: Next) => { const content_desc = ctx.request.body; if(!isContentContent(content_desc)){ return sendError(400,"it is not a valid format"); } const id = await controller.add(content_desc); ctx.body = JSON.stringify(id); ctx.type = 'json'; }; const AddTagHandler = (controller: ContentAccessor)=>async (ctx: Context, next: Next)=>{ let tag_name = ctx.params['tag']; const num = Number.parseInt(ctx.params['num']); if(typeof tag_name === undefined){ return sendError(400,"??? Unreachable"); } tag_name = String(tag_name); const c = await controller.findById(num); if(c === undefined){ return sendError(404); } const r = await controller.addTag(c,tag_name); ctx.body = JSON.stringify(r); ctx.type = 'json'; }; const DelTagHandler = (controller: ContentAccessor)=>async (ctx: Context, next: Next)=>{ let tag_name = ctx.params['tag']; const num = Number.parseInt(ctx.params['num']); if(typeof tag_name === undefined){ return sendError(400,"?? Unreachable"); } tag_name = String(tag_name); const c = await controller.findById(num); if(c === undefined){ return sendError(404); } const r = await controller.delTag(c,tag_name); ctx.body = JSON.stringify(r); ctx.type = 'json'; } const DeleteContentHandler = (controller : ContentAccessor) => async (ctx: Context, next: Next) => { const num = Number.parseInt(ctx.params['num']); const r = await controller.del(num); ctx.body = JSON.stringify(r); ctx.type = 'json'; }; const ContentHandler = (controller : ContentAccessor) => async (ctx:Context, next:Next) => { const num = Number.parseInt(ctx.params['num']); let content = await controller.findById(num,true); if (content == undefined){ return sendError(404,"content does not exist."); } const path = join(content.basepath,content.filename); ctx.state['content'] = createContentReferrer(content.content_type,path,content.additional); await next(); }; export const getContentRouter = (controller: ContentAccessor)=>{ const ret = new Router(); ret.get("/search",PerCheck(Per.QueryContent),ContentQueryHandler(controller)); ret.get("/:num(\\d+)",PerCheck(Per.QueryContent),ContentIDHandler(controller)); ret.post("/:num(\\d+)",AdminOnly,UpdateContentHandler(controller)); //ret.use("/:num(\\d+)/:content_type"); ret.post("/",AdminOnly,CreateContentHandler(controller)); ret.get("/:num(\\d+)/tags",PerCheck(Per.QueryContent),ContentTagIDHandler(controller)); ret.post("/:num(\\d+)/tags/:tag",PerCheck(Per.ModifyTag),AddTagHandler(controller)); ret.del("/:num(\\d+)/tags/:tag",PerCheck(Per.ModifyTag),DelTagHandler(controller)); ret.del("/:num(\\d+)",AdminOnly,DeleteContentHandler(controller)); ret.all("/:num(\\d+)/(.*)",PerCheck(Per.QueryContent),ContentHandler(controller)); ret.use("/:num",PerCheck(Per.QueryContent),(new AllContentRouter).routes()); return ret; } export default getContentRouter;