145 lines
No EOL
5.4 KiB
TypeScript
145 lines
No EOL
5.4 KiB
TypeScript
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';
|
|
|
|
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){
|
|
sendError(404,"content does not exist.");
|
|
return;
|
|
}
|
|
ctx.body = content;
|
|
ctx.type = 'json';
|
|
return await next();
|
|
};
|
|
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){
|
|
sendError(404,"content does not exist.");
|
|
return;
|
|
}
|
|
ctx.body = content.tags || [];
|
|
ctx.type = 'json';
|
|
return await next();
|
|
};
|
|
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 offset = ParseQueryNumber(ctx.query['offset']);
|
|
if(limit === NaN || cursor === NaN || offset === NaN){
|
|
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){
|
|
sendError(400,"use_offset must be true or false.");
|
|
return;
|
|
}
|
|
const option :QueryListOption = {
|
|
limit: limit,
|
|
allow_tag: allow_tag,
|
|
word: word,
|
|
cursor: cursor,
|
|
eager_loading: true,
|
|
offset: offset,
|
|
use_offset: use_offset
|
|
};
|
|
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']);
|
|
const content_desc: Partial<Content> & {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)){
|
|
sendError(400,"it is not a valid format");
|
|
return;
|
|
}
|
|
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){
|
|
sendError(400,"??? Unreachable");
|
|
}
|
|
tag_name = String(tag_name);
|
|
const c = await controller.findById(num);
|
|
if(c === undefined){
|
|
sendError(404);
|
|
return;
|
|
}
|
|
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){
|
|
sendError(400,"?? Unreachable");
|
|
}
|
|
tag_name = String(tag_name);
|
|
const c = await controller.findById(num);
|
|
if(c === undefined){
|
|
sendError(404);
|
|
return;
|
|
}
|
|
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){
|
|
sendError(404,"content does not exist.");
|
|
return;
|
|
}
|
|
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",ContentQueryHandler(controller));
|
|
ret.get("/:num(\\d+)",ContentIDHandler(controller));
|
|
ret.get("/:num(\\d+)",UpdateContentHandler(controller));
|
|
ret.use("/:num(\\d+)/:content_type");
|
|
ret.post("/",CreateContentHandler(controller));
|
|
ret.get("/:num(\\d+)/tags",ContentTagIDHandler(controller));
|
|
ret.post("/:num(\\d+)/tags/:tag",AddTagHandler(controller));
|
|
ret.del("/:num(\\d+)/tags/:tag",DelTagHandler(controller));
|
|
ret.del("/:num(\\d+)",DeleteContentHandler(controller));
|
|
ret.all("/:num(\\d+)/(.*)",ContentHandler(controller));
|
|
ret.use("/:num",(new AllContentRouter).routes());
|
|
return ret;
|
|
}
|
|
|
|
export default getContentRouter; |