add tag api
This commit is contained in:
parent
8758e78f88
commit
253311bbd7
@ -1,10 +1,16 @@
|
|||||||
|
import {Knex as k} from "knex";
|
||||||
|
|
||||||
export namespace Knex {
|
export namespace Knex {
|
||||||
export const config = {
|
export const config: {
|
||||||
|
development: k.Config,
|
||||||
|
production: k.Config
|
||||||
|
} = {
|
||||||
development: {
|
development: {
|
||||||
client: 'sqlite3',
|
client: 'sqlite3',
|
||||||
connection: {
|
connection: {
|
||||||
filename: './devdb.sqlite3'
|
filename: './devdb.sqlite3'
|
||||||
}
|
},
|
||||||
|
debug: true,
|
||||||
},
|
},
|
||||||
production: {
|
production: {
|
||||||
client: 'sqlite3',
|
client: 'sqlite3',
|
||||||
|
@ -4,10 +4,23 @@ import {Knex as KnexConfig} from './config';
|
|||||||
import { get_setting } from './SettingConfig';
|
import { get_setting } from './SettingConfig';
|
||||||
|
|
||||||
export async function connectDB(){
|
export async function connectDB(){
|
||||||
const config = KnexConfig.config;
|
|
||||||
const env = get_setting().mode;
|
const env = get_setting().mode;
|
||||||
const init_need = !existsSync(config[env].connection.filename);
|
const config = KnexConfig.config[env];
|
||||||
const knex = Knex(config[env]);
|
if(!config.connection){
|
||||||
|
throw new Error("connection options required.");
|
||||||
|
}
|
||||||
|
const connection = config.connection
|
||||||
|
if(typeof connection === "string"){
|
||||||
|
throw new Error("unknown connection options");
|
||||||
|
}
|
||||||
|
if(typeof connection === "function"){
|
||||||
|
throw new Error("connection provider not supported...");
|
||||||
|
}
|
||||||
|
if(!("filename" in connection) ){
|
||||||
|
throw new Error("sqlite3 config need");
|
||||||
|
}
|
||||||
|
const init_need = !existsSync(connection.filename);
|
||||||
|
const knex = Knex(config);
|
||||||
let tries = 0;
|
let tries = 0;
|
||||||
for(;;){
|
for(;;){
|
||||||
try{
|
try{
|
||||||
|
@ -3,7 +3,7 @@ import {Knex} from 'knex';
|
|||||||
import {createKnexTagController} from './tag';
|
import {createKnexTagController} from './tag';
|
||||||
import { TagAccessor } from '../model/tag';
|
import { TagAccessor } from '../model/tag';
|
||||||
|
|
||||||
type DBTagContentRelation = {
|
export type DBTagContentRelation = {
|
||||||
doc_id:number,
|
doc_id:number,
|
||||||
tag_name:string
|
tag_name:string
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import {Tag, TagAccessor} from '../model/tag';
|
import {Tag, TagAccessor, TagCount} from '../model/tag';
|
||||||
import {Knex} from 'knex';
|
import {Knex} from 'knex';
|
||||||
|
import {DBTagContentRelation} from './doc';
|
||||||
|
|
||||||
type DBTags = {
|
type DBTags = {
|
||||||
name: string,
|
name: string,
|
||||||
@ -11,7 +12,12 @@ class KnexTagAccessor implements TagAccessor{
|
|||||||
constructor(knex:Knex){
|
constructor(knex:Knex){
|
||||||
this.knex = knex;
|
this.knex = knex;
|
||||||
}
|
}
|
||||||
async getTagAllList(onlyname?:boolean){
|
async getAllTagCount(): Promise<TagCount[]> {
|
||||||
|
const result = await this.knex<DBTagContentRelation>("doc_tag_relation").select("tag_name")
|
||||||
|
.count("*",{as:"occurs"}).groupBy<TagCount[]>("tag_name");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
async getAllTagList(onlyname?:boolean){
|
||||||
onlyname = onlyname ?? false;
|
onlyname = onlyname ?? false;
|
||||||
const t:DBTags[] = await this.knex.select(onlyname ? "*" : "name").from("tags")
|
const t:DBTags[] = await this.knex.select(onlyname ? "*" : "name").from("tags")
|
||||||
return t;
|
return t;
|
||||||
|
@ -3,10 +3,16 @@ export interface Tag{
|
|||||||
description?: string
|
description?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TagAccessor{
|
export interface TagCount{
|
||||||
getTagAllList: (onlyname?:boolean)=> Promise<Tag[]>
|
tagname: string;
|
||||||
getTagByName: (name:string)=>Promise<Tag|undefined>,
|
occurs: number;
|
||||||
addTag: (tag:Tag)=>Promise<boolean>,
|
}
|
||||||
delTag: (name:string) => Promise<boolean>,
|
|
||||||
updateTag: (name:string,tag:string) => Promise<boolean>
|
export interface TagAccessor{
|
||||||
|
getAllTagList: (onlyname?:boolean)=> Promise<Tag[]>;
|
||||||
|
getAllTagCount(): Promise<TagCount[]>;
|
||||||
|
getTagByName: (name:string)=>Promise<Tag|undefined>;
|
||||||
|
addTag: (tag:Tag)=>Promise<boolean>;
|
||||||
|
delTag: (name:string) => Promise<boolean>;
|
||||||
|
updateTag: (name:string,tag:string) => Promise<boolean>;
|
||||||
}
|
}
|
||||||
|
32
src/route/tags.ts
Normal file
32
src/route/tags.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import {Context, Next} from "koa";
|
||||||
|
import Router,{RouterContext} from "koa-router";
|
||||||
|
import { TagAccessor } from "../model/tag";
|
||||||
|
import { sendError } from "./error_handler";
|
||||||
|
import { createPermissionCheckMiddleware as PerCheck, Permission } from "../permission/permission";
|
||||||
|
|
||||||
|
export function getTagRounter(tagController: TagAccessor){
|
||||||
|
let router = new Router();
|
||||||
|
router.get("/",PerCheck(Permission.QueryContent),
|
||||||
|
async (ctx: Context)=>{
|
||||||
|
if(ctx.query["withCount"]){
|
||||||
|
const c = await tagController.getAllTagCount();
|
||||||
|
ctx.body = c;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const c = await tagController.getAllTagList();
|
||||||
|
ctx.body = c;
|
||||||
|
}
|
||||||
|
ctx.type = "json";
|
||||||
|
});
|
||||||
|
router.get("/:tag_name", PerCheck(Permission.QueryContent),
|
||||||
|
async (ctx: RouterContext)=>{
|
||||||
|
const tag_name = ctx.params["tag_name"];
|
||||||
|
const c = await tagController.getTagByName(tag_name);
|
||||||
|
if (!c){
|
||||||
|
sendError(404, "tags not found");
|
||||||
|
}
|
||||||
|
ctx.body = c;
|
||||||
|
ctx.type = "json";
|
||||||
|
});
|
||||||
|
return router;
|
||||||
|
}
|
@ -7,25 +7,31 @@ import {DiffManager, createDiffRouter} from './diff/mod';
|
|||||||
|
|
||||||
import { createReadStream, readFileSync } from 'fs';
|
import { createReadStream, readFileSync } from 'fs';
|
||||||
import getContentRouter from './route/contents';
|
import getContentRouter from './route/contents';
|
||||||
import { createKnexDocumentAccessor, createKnexUserController } from './db/mod';
|
import { createKnexDocumentAccessor, createKnexTagController, createKnexUserController } from './db/mod';
|
||||||
import bodyparser from 'koa-bodyparser';
|
import bodyparser from 'koa-bodyparser';
|
||||||
import {error_handler} from './route/error_handler';
|
import {error_handler} from './route/error_handler';
|
||||||
import {createUserMiddleWare, createLoginRouter, isAdminFirst, getAdmin} from './login';
|
import {createUserMiddleWare, createLoginRouter, isAdminFirst, getAdmin} from './login';
|
||||||
|
|
||||||
import {createInterface as createReadlineInterface} from 'readline';
|
import {createInterface as createReadlineInterface} from 'readline';
|
||||||
import { DocumentAccessor, UserAccessor } from './model/mod';
|
import { DocumentAccessor, UserAccessor, TagAccessor } from './model/mod';
|
||||||
import { createComicWatcher } from './diff/watcher/comic_watcher';
|
import { createComicWatcher } from './diff/watcher/comic_watcher';
|
||||||
|
import { getTagRounter } from './route/tags';
|
||||||
class ServerApplication{
|
class ServerApplication{
|
||||||
readonly userController: UserAccessor;
|
readonly userController: UserAccessor;
|
||||||
readonly documentController: DocumentAccessor;
|
readonly documentController: DocumentAccessor;
|
||||||
readonly diffManger;
|
readonly tagController: TagAccessor;
|
||||||
|
readonly diffManger: DiffManager;
|
||||||
readonly app: Koa;
|
readonly app: Koa;
|
||||||
private index_html:Buffer;
|
private index_html:Buffer;
|
||||||
private constructor(userController: UserAccessor,documentController:DocumentAccessor){
|
private constructor(controller:{
|
||||||
this.userController = userController;
|
userController: UserAccessor,
|
||||||
this.documentController = documentController;
|
documentController:DocumentAccessor,
|
||||||
this.diffManger = new DiffManager(documentController);
|
tagController: TagAccessor}){
|
||||||
|
this.userController = controller.userController;
|
||||||
|
this.documentController = controller.documentController;
|
||||||
|
this.tagController = controller.tagController;
|
||||||
|
|
||||||
|
this.diffManger = new DiffManager(this.documentController);
|
||||||
this.app = new Koa();
|
this.app = new Koa();
|
||||||
this.index_html = readFileSync("index.html");
|
this.index_html = readFileSync("index.html");
|
||||||
}
|
}
|
||||||
@ -66,6 +72,11 @@ class ServerApplication{
|
|||||||
const content_router = getContentRouter(this.documentController);
|
const content_router = getContentRouter(this.documentController);
|
||||||
router.use('/api/doc',content_router.routes());
|
router.use('/api/doc',content_router.routes());
|
||||||
router.use('/api/doc',content_router.allowedMethods());
|
router.use('/api/doc',content_router.allowedMethods());
|
||||||
|
|
||||||
|
const tags_router = getTagRounter(this.tagController);
|
||||||
|
router.use("/api/tags",tags_router.routes());
|
||||||
|
router.use("/api/tags",tags_router.allowedMethods());
|
||||||
|
|
||||||
const login_router = createLoginRouter(this.userController);
|
const login_router = createLoginRouter(this.userController);
|
||||||
router.use('/user',login_router.routes());
|
router.use('/user',login_router.routes());
|
||||||
router.use('/user',login_router.allowedMethods());
|
router.use('/user',login_router.allowedMethods());
|
||||||
@ -75,7 +86,8 @@ class ServerApplication{
|
|||||||
let mm_count = 0;
|
let mm_count = 0;
|
||||||
app.use(async (ctx,next)=>{
|
app.use(async (ctx,next)=>{
|
||||||
console.log(`==========================${mm_count++}`);
|
console.log(`==========================${mm_count++}`);
|
||||||
const fromClient = ctx.state['user'].username === "" ? ctx.ip : ctx.state['user'].username;
|
const ip = (ctx.get("X-Real-IP")) ?? ctx.ip;
|
||||||
|
const fromClient = ctx.state['user'].username === "" ? ip : ctx.state['user'].username;
|
||||||
console.log(`${fromClient} : ${ctx.method} ${ctx.url}`);
|
console.log(`${fromClient} : ${ctx.method} ${ctx.url}`);
|
||||||
await next();
|
await next();
|
||||||
//console.log(`404`);
|
//console.log(`404`);
|
||||||
@ -136,8 +148,11 @@ class ServerApplication{
|
|||||||
const setting = get_setting();
|
const setting = get_setting();
|
||||||
let db = await connectDB();
|
let db = await connectDB();
|
||||||
|
|
||||||
const app = new ServerApplication(createKnexUserController(db)
|
const app = new ServerApplication({
|
||||||
,createKnexDocumentAccessor(db));
|
userController:createKnexUserController(db),
|
||||||
|
documentController: createKnexDocumentAccessor(db),
|
||||||
|
tagController: createKnexTagController(db),
|
||||||
|
});
|
||||||
await app.setup();
|
await app.setup();
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user