mirror of
https://github.com/lifegpc/eh-downloader.git
synced 2026-07-08 01:31:00 +08:00
Add new API
This commit is contained in:
45
db.ts
45
db.ts
@@ -1432,6 +1432,22 @@ export class EhDb {
|
||||
[uid, client],
|
||||
);
|
||||
}
|
||||
list_shared_tokens<T extends SharedTokenType = SharedTokenType>(
|
||||
type: T,
|
||||
info: SharedTokenTypeMap[T] | null = null,
|
||||
) {
|
||||
const where_sql = info === null ? "" : " AND info = ?";
|
||||
const args: QueryParameter[] = [type];
|
||||
if (info !== null) {
|
||||
args.push(toJSON(info));
|
||||
}
|
||||
return this.convert_shared_token(
|
||||
this.db.queryEntries<SharedTokenRaw>(
|
||||
`SELECT * FROM shared_token WHERE type = ?${where_sql};`,
|
||||
args,
|
||||
),
|
||||
);
|
||||
}
|
||||
optimize() {
|
||||
this.db.execute("VACUUM;");
|
||||
}
|
||||
@@ -1480,6 +1496,35 @@ export class EhDb {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
update_shared_token<T extends SharedTokenType = SharedTokenType>(
|
||||
token: string,
|
||||
type: T,
|
||||
expired: number | null | undefined = undefined,
|
||||
info: SharedTokenTypeMap[T] | null = null,
|
||||
) {
|
||||
if (expired === undefined && info === null) {
|
||||
return this.get_shared_token(token);
|
||||
}
|
||||
const args: QueryParameter[] = [];
|
||||
const set_sqls = [];
|
||||
if (expired !== undefined) {
|
||||
set_sqls.push("expired = ?");
|
||||
args.push(expired ? new Date(expired) : null);
|
||||
}
|
||||
if (info !== null) {
|
||||
set_sqls.push("info = ?");
|
||||
args.push(toJSON(info));
|
||||
}
|
||||
args.push(token);
|
||||
args.push(type);
|
||||
this.db.query(
|
||||
`UPDATE shared_token SET ${
|
||||
set_sqls.join(", ")
|
||||
} WHERE token = ? AND type = ?;`,
|
||||
args,
|
||||
);
|
||||
return this.get_shared_token(token);
|
||||
}
|
||||
update_tags(tag: string, translated: string, intro: string) {
|
||||
const id = this.#tags.get(tag);
|
||||
if (id === undefined) {
|
||||
|
||||
@@ -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_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";
|
||||
import * as $api_tag_id_ from "./routes/api/tag/[id].ts";
|
||||
import * as $api_tag_rows from "./routes/api/tag/rows.ts";
|
||||
@@ -71,6 +72,7 @@ const manifest = {
|
||||
"./routes/api/gallery/meta/[gids].ts": $api_gallery_meta_gids_,
|
||||
"./routes/api/health_check.ts": $api_health_check,
|
||||
"./routes/api/shared_token.ts": $api_shared_token,
|
||||
"./routes/api/shared_token/list.ts": $api_shared_token_list,
|
||||
"./routes/api/status.ts": $api_status,
|
||||
"./routes/api/tag/[id].ts": $api_tag_id_,
|
||||
"./routes/api/tag/rows.ts": $api_tag_rows,
|
||||
|
||||
@@ -20,6 +20,57 @@ export const handler: Handlers = {
|
||||
if (!st) return return_error(1, "No token.");
|
||||
return return_data(st);
|
||||
},
|
||||
async PATCH(req, ctx) {
|
||||
const user = <User | undefined> ctx.state.user;
|
||||
let form: FormData | undefined;
|
||||
try {
|
||||
form = await req.formData();
|
||||
} catch (_) {
|
||||
return return_error(400, "Bad Request");
|
||||
}
|
||||
const typ = await get_string(form.get("type"));
|
||||
const expired = await parse_int(form.get("expired"), null);
|
||||
const token = await get_string(form.get("token"));
|
||||
if (!token) {
|
||||
return return_error(2, "token not specfied.");
|
||||
}
|
||||
if (typ == "gallery") {
|
||||
if (
|
||||
user && !user.is_admin &&
|
||||
!(user.permissions & UserPermission.ShareGallery)
|
||||
) {
|
||||
return return_error(403, "Permission denied.");
|
||||
}
|
||||
const m = get_task_manager();
|
||||
const st = m.db.update_shared_token(
|
||||
token,
|
||||
SharedTokenType.Gallery,
|
||||
expired === 0 ? undefined : expired,
|
||||
);
|
||||
if (!st) return return_error(404, "Not found");
|
||||
let flutter_base = import.meta.resolve("../../static/flutter")
|
||||
.slice(7);
|
||||
if (Deno.build.os === "windows") {
|
||||
flutter_base = flutter_base.slice(1);
|
||||
}
|
||||
if (m.cfg.flutter_frontend) {
|
||||
flutter_base = m.cfg.flutter_frontend;
|
||||
}
|
||||
const existed = await exists(flutter_base);
|
||||
const host = get_host(req);
|
||||
const base = host + (existed ? "/flutter" : "/api/");
|
||||
const token2 = encodeURIComponent(st.token);
|
||||
const gid = st.info.gid;
|
||||
const url = existed
|
||||
? `${base}/gallery/${gid}?share=${token2}`
|
||||
: `https://dev.ehf.lifegpc.com/#/gallery/${gid}?base=${
|
||||
encodeURIComponent(base)
|
||||
}&share=${token2}`;
|
||||
return return_data({ url, token: st });
|
||||
} else {
|
||||
return return_error(1, "Unknown type");
|
||||
}
|
||||
},
|
||||
async PUT(req, ctx) {
|
||||
const user = <User | undefined> ctx.state.user;
|
||||
let form: FormData | undefined;
|
||||
|
||||
51
routes/api/shared_token/list.ts
Normal file
51
routes/api/shared_token/list.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Handlers } from "$fresh/server.ts";
|
||||
import { exists } from "@std/fs/exists";
|
||||
import { SharedTokenType, User, UserPermission } from "../../../db.ts";
|
||||
import { get_task_manager } from "../../../server.ts";
|
||||
import { get_string, parse_big_int } from "../../../server/parse_form.ts";
|
||||
import { get_host, return_data, return_error } from "../../../server/utils.ts";
|
||||
|
||||
export const handler: Handlers = {
|
||||
async GET(req, ctx) {
|
||||
const user = <User | undefined> ctx.state.user;
|
||||
const u = new URL(req.url);
|
||||
const typ = await get_string(u.searchParams.get("type"));
|
||||
if (typ == "gallery") {
|
||||
if (
|
||||
user && !user.is_admin &&
|
||||
!(user.permissions & UserPermission.ShareGallery)
|
||||
) {
|
||||
return return_error(403, "Permission denied.");
|
||||
}
|
||||
const gid = await parse_big_int(u.searchParams.get("gid"), null);
|
||||
const m = get_task_manager();
|
||||
let flutter_base = import.meta.resolve("../../../static/flutter")
|
||||
.slice(7);
|
||||
if (Deno.build.os === "windows") {
|
||||
flutter_base = flutter_base.slice(1);
|
||||
}
|
||||
if (m.cfg.flutter_frontend) {
|
||||
flutter_base = m.cfg.flutter_frontend;
|
||||
}
|
||||
const existed = await exists(flutter_base);
|
||||
const host = get_host(req);
|
||||
const base = host + (existed ? "/flutter" : "/api/");
|
||||
const data = m.db.list_shared_tokens(
|
||||
SharedTokenType.Gallery,
|
||||
gid ? { gid } : null,
|
||||
).map((st) => {
|
||||
const token2 = encodeURIComponent(st.token);
|
||||
const gid = st.info.gid;
|
||||
const url = existed
|
||||
? `${base}/gallery/${gid}?share=${token2}`
|
||||
: `https://dev.ehf.lifegpc.com/#/gallery/${gid}?base=${
|
||||
encodeURIComponent(base)
|
||||
}&share=${token2}`;
|
||||
return { url, token: st };
|
||||
});
|
||||
return return_data(data);
|
||||
} else {
|
||||
return return_error(1, "Unknown type");
|
||||
}
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user