mirror of
https://github.com/lifegpc/eh-downloader.git
synced 2026-06-06 05:38:44 +08:00
feat: Add log entry retrieval and deletion API endpoints
This commit is contained in:
93
api.yml
93
api.yml
@@ -808,6 +808,15 @@ components:
|
||||
stack:
|
||||
type: string
|
||||
description: Stack trace
|
||||
LogEntryApiResult:
|
||||
description: Api response for getLog
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/ApiResponse"
|
||||
- type: object
|
||||
required: [data]
|
||||
properties:
|
||||
data:
|
||||
$ref: "#/components/schemas/LogEntry"
|
||||
LogEntries:
|
||||
description: Log entries
|
||||
type: object
|
||||
@@ -2652,6 +2661,90 @@ paths:
|
||||
$ref: "#/components/schemas/ApiResponseError"
|
||||
example:
|
||||
{ "ok": false, "status": 403, "error": "Permission denied." }
|
||||
/log/{id}:
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
default: ''
|
||||
required: true
|
||||
description: Log entry ID
|
||||
delete:
|
||||
operationId: deleteLog
|
||||
summary: Delete a log entry
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ApiResponseTrue"
|
||||
"400":
|
||||
description: Bad request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ApiResponseError"
|
||||
example:
|
||||
{ "ok": false, "status": 1, "error": "id is required." }
|
||||
"401":
|
||||
description: Authorization information is missing or invalid
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ApiResponseError"
|
||||
example: { "ok": false, "status": 401, "error": "Unauthorized" }
|
||||
"403":
|
||||
description: Permission denied
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ApiResponseError"
|
||||
example:
|
||||
{ "ok": false, "status": 403, "error": "Permission denied." }
|
||||
get:
|
||||
operationId: getLog
|
||||
summary: Get a log entry
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/LogEntryApiResult"
|
||||
"400":
|
||||
description: Bad request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ApiResponseError"
|
||||
example:
|
||||
{ "ok": false, "status": 1, "error": "id is required." }
|
||||
"401":
|
||||
description: Authorization information is missing or invalid
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ApiResponseError"
|
||||
example: { "ok": false, "status": 401, "error": "Unauthorized" }
|
||||
"403":
|
||||
description: Permission denied
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ApiResponseError"
|
||||
example:
|
||||
{ "ok": false, "status": 403, "error": "Permission denied." }
|
||||
"404":
|
||||
description: Not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ApiResponseError"
|
||||
example:
|
||||
{ "ok": false, "status": 404, "error": "log not found." }
|
||||
/shared_token:
|
||||
delete:
|
||||
operationId: deleteSharedToken
|
||||
|
||||
@@ -23,6 +23,7 @@ import * as $api_gallery_list from "./routes/api/gallery/list.ts";
|
||||
import * as $api_gallery_meta_gids_ from "./routes/api/gallery/meta/[gids].ts";
|
||||
import * as $api_health_check from "./routes/api/health_check.ts";
|
||||
import * as $api_log from "./routes/api/log.ts";
|
||||
import * as $api_log_id_ from "./routes/api/log/[id].ts";
|
||||
import * as $api_shared_token from "./routes/api/shared_token.ts";
|
||||
import * as $api_shared_token_list from "./routes/api/shared_token/list.ts";
|
||||
import * as $api_status from "./routes/api/status.ts";
|
||||
@@ -74,6 +75,7 @@ const manifest = {
|
||||
"./routes/api/gallery/meta/[gids].ts": $api_gallery_meta_gids_,
|
||||
"./routes/api/health_check.ts": $api_health_check,
|
||||
"./routes/api/log.ts": $api_log,
|
||||
"./routes/api/log/[id].ts": $api_log_id_,
|
||||
"./routes/api/shared_token.ts": $api_shared_token,
|
||||
"./routes/api/shared_token/list.ts": $api_shared_token_list,
|
||||
"./routes/api/status.ts": $api_status,
|
||||
|
||||
41
routes/api/log/[id].ts
Normal file
41
routes/api/log/[id].ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { return_data, return_error } from "../../../server/utils.ts";
|
||||
import { User, UserPermission } from "../../../db.ts";
|
||||
import { parse_big_int } from "../../../server/parse_form.ts";
|
||||
import { base_logger } from "../../../utils/logger.ts";
|
||||
|
||||
export const handler: Handlers = {
|
||||
async GET(_req, ctx) {
|
||||
const user = <User | undefined> ctx.state.user;
|
||||
if (
|
||||
user && !user.is_admin &&
|
||||
!(Number(user.permissions) & UserPermission.QueryLog)
|
||||
) {
|
||||
return return_error(403, "Permission denied.");
|
||||
}
|
||||
const id = await parse_big_int(ctx.params["id"], null);
|
||||
if (id === null) {
|
||||
return return_error(1, "id is required.");
|
||||
}
|
||||
const log = base_logger.get_log(id);
|
||||
if (!log) {
|
||||
return return_error(404, "log not found.");
|
||||
}
|
||||
return return_data(log);
|
||||
},
|
||||
async DELETE(_req, ctx) {
|
||||
const user = <User | undefined> ctx.state.user;
|
||||
if (
|
||||
user && !user.is_admin &&
|
||||
!(Number(user.permissions) & UserPermission.QueryLog)
|
||||
) {
|
||||
return return_error(403, "Permission denied.");
|
||||
}
|
||||
const id = await parse_big_int(ctx.params["id"], null);
|
||||
if (id === null) {
|
||||
return return_error(1, "id is required.");
|
||||
}
|
||||
base_logger.delete_log(id);
|
||||
return return_data(true);
|
||||
},
|
||||
};
|
||||
@@ -150,6 +150,41 @@ class BaseLogger {
|
||||
],
|
||||
);
|
||||
}
|
||||
clear(
|
||||
type?: string | null,
|
||||
min_level?: number | null,
|
||||
max_level?: number | null,
|
||||
deleted_level?: number[],
|
||||
end_time?: Date | null,
|
||||
) {
|
||||
if (!this.db) return;
|
||||
const where = [];
|
||||
const args: QueryParameterSet = [];
|
||||
if (type) {
|
||||
where.push("type = ?");
|
||||
args.push(type);
|
||||
}
|
||||
if (min_level) {
|
||||
where.push("level >= ?");
|
||||
args.push(min_level);
|
||||
}
|
||||
if (max_level) {
|
||||
where.push("level <= ?");
|
||||
args.push(max_level);
|
||||
}
|
||||
if (deleted_level) {
|
||||
where.push(
|
||||
"level IN (" + deleted_level.map(() => "?").join(",") + ")",
|
||||
);
|
||||
args.push(...deleted_level);
|
||||
}
|
||||
if (end_time) {
|
||||
where.push("time <= ?");
|
||||
args.push(end_time.getTime());
|
||||
}
|
||||
const where_str = where.length ? " WHERE " + where.join(" AND ") : "";
|
||||
this.db.query(`DELETE FROM log${where_str};`, args);
|
||||
}
|
||||
close() {
|
||||
this.db?.close();
|
||||
this.db = undefined;
|
||||
@@ -201,6 +236,10 @@ class BaseLogger {
|
||||
debug(type: string, ...messages: unknown[]) {
|
||||
this.add(type, LogLevel.Debug, ...messages);
|
||||
}
|
||||
delete_log(id: number | bigint) {
|
||||
if (!this.db) return;
|
||||
this.db.query("DELETE FROM log WHERE id = ?;", [id]);
|
||||
}
|
||||
error(type: string, ...messages: unknown[]) {
|
||||
this.add(type, LogLevel.Error, ...messages);
|
||||
}
|
||||
@@ -240,6 +279,14 @@ class BaseLogger {
|
||||
);
|
||||
}
|
||||
}
|
||||
get_log(id: number | bigint) {
|
||||
if (!this.db) return null;
|
||||
const cur = this.#convert(this.db.queryEntries<LogEntryRaw>(
|
||||
"SELECT * FROM log WHERE id = ?;",
|
||||
[id],
|
||||
));
|
||||
return cur.length ? cur[0] : null;
|
||||
}
|
||||
get_logger(type: string) {
|
||||
return new Logger(this, type);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user