diff --git a/db.ts b/db.ts index f25f519..1a2ca77 100644 --- a/db.ts +++ b/db.ts @@ -461,6 +461,12 @@ export class EhDb { return s[s.length - 1]; } } + add_filemeta(m: EhFileMeta) { + this.db.query( + "INSERT OR REPLACE INTO filemeta VALUES (:token, :is_nsfw, :is_ad);", + m, + ); + } add_pmeta(pmeta: PMeta) { this.db.queryEntries( "INSERT OR REPLACE INTO pmeta VALUES (:gid, :index, :token, :name, :width, :height)", @@ -682,6 +688,13 @@ export class EhDb { )); return d.length ? d[0] : null; } + get_filemeta(token: string) { + const d = this.convert_filemeta(this.db.queryEntries( + "SELECT * FROM filemeta WHERE token = ?;", + [token], + )); + return d.length ? d[0] : null; + } get_files(token: string) { return this.convert_file(this.db.queryEntries( "SELECT * FROM file WHERE token = ?;", diff --git a/fresh.gen.ts b/fresh.gen.ts index 710d6aa..f9ed9e7 100644 --- a/fresh.gen.ts +++ b/fresh.gen.ts @@ -9,9 +9,11 @@ import * as $3 from "./routes/api/exit.ts"; import * as $4 from "./routes/api/export/gallery/zip/[gid].ts"; import * as $5 from "./routes/api/file/[id].ts"; import * as $6 from "./routes/api/file/random.ts"; -import * as $7 from "./routes/api/gallery/[gid].ts"; -import * as $8 from "./routes/api/task.ts"; -import * as $9 from "./routes/index.tsx"; +import * as $7 from "./routes/api/filemeta.ts"; +import * as $8 from "./routes/api/filemeta/[token].ts"; +import * as $9 from "./routes/api/gallery/[gid].ts"; +import * as $10 from "./routes/api/task.ts"; +import * as $11 from "./routes/index.tsx"; import * as $$0 from "./islands/Container.tsx"; import * as $$1 from "./islands/Settings.tsx"; import * as $$2 from "./islands/TaskManager.tsx"; @@ -25,9 +27,11 @@ const manifest = { "./routes/api/export/gallery/zip/[gid].ts": $4, "./routes/api/file/[id].ts": $5, "./routes/api/file/random.ts": $6, - "./routes/api/gallery/[gid].ts": $7, - "./routes/api/task.ts": $8, - "./routes/index.tsx": $9, + "./routes/api/filemeta.ts": $7, + "./routes/api/filemeta/[token].ts": $8, + "./routes/api/gallery/[gid].ts": $9, + "./routes/api/task.ts": $10, + "./routes/index.tsx": $11, }, islands: { "./islands/Container.tsx": $$0, diff --git a/routes/api/filemeta.ts b/routes/api/filemeta.ts new file mode 100644 index 0000000..ba543c7 --- /dev/null +++ b/routes/api/filemeta.ts @@ -0,0 +1,79 @@ +import { Handlers } from "$fresh/server.ts"; +import { EhFileMeta } from "../../db.ts"; +import { get_task_manager } from "../../server.ts"; +import { get_string, parse_bool } from "../../server/parse_form.ts"; +import { return_data, return_error } from "../../server/utils.ts"; + +export function get_filemeta(token: string) { + const m = get_task_manager(); + const f = m.db.get_filemeta(token); + if (!f) { + const f = m.db.get_files(token); + if (f.length) { + return return_data({ + token, + is_nsfw: false, + is_ad: false, + }); + } else { + return return_error(404, "file not found."); + } + } + return return_data(f); +} + +export function put_filemeta(d: EhFileMeta) { + const m = get_task_manager(); + m.db.add_filemeta(d); + return return_data({}); +} + +export const handler: Handlers = { + GET(req, _ctx) { + const u = new URL(req.url); + const token = u.searchParams.get("token"); + if (token) return get_filemeta(token); + return return_error(400, "token is needed."); + }, + async PUT(req, _ctx) { + const ct = req.headers.get("Content-Type").split(";")[0].trim() || ""; + if (ct === "application/json") { + if (!req.body) return_error(1, "Body not found."); + let b = null; + try { + b = await req.json(); + } catch (_) { + return return_error(2, "Invaild JSON file."); + } + if (typeof b.token === "string") { + if ( + typeof b.is_nsfw === "boolean" && + typeof b.is_ad === "boolean" + ) { + return put_filemeta(b); + } else return return_error(3, "Invalid parameters."); + } + return return_error(5, "Unknown JSON format."); + } else if ( + ct === "application/x-www-form-urlencoded" || + ct === "multipart/form-data" + ) { + let d: FormData | null = null; + try { + d = await req.formData(); + } catch (_) { + return return_error(3, "Invalid parameters."); + } + const token = await get_string(d.get("token")); + if (token) { + const is_nsfw = await parse_bool(d.get("is_nsfw"), null); + const is_ad = await parse_bool(d.get("is_ad"), null); + if (is_nsfw === null || is_ad === null) { + return return_error(3, "Invalid parameters."); + } + return put_filemeta({ token, is_nsfw, is_ad }); + } + } + return return_error(4, "Unknown format."); + }, +}; diff --git a/routes/api/filemeta/[token].ts b/routes/api/filemeta/[token].ts new file mode 100644 index 0000000..a1980ff --- /dev/null +++ b/routes/api/filemeta/[token].ts @@ -0,0 +1,11 @@ +import { Handlers } from "$fresh/server.ts"; +import { return_error } from "../../../server/utils.ts"; +import { get_filemeta } from "../filemeta.ts"; + +export const handler: Handlers = { + GET(_req, ctx) { + const token = ctx.params.token; + if (token) return get_filemeta(token); + return return_error(400, "token is needed."); + }, +}; diff --git a/server/parse_form.ts b/server/parse_form.ts index 9990120..7155932 100644 --- a/server/parse_form.ts +++ b/server/parse_form.ts @@ -1,3 +1,8 @@ +export async function get_string(value: FormDataEntryValue | null) { + if (value === null) return null; + return typeof value === "string" ? value : await value.text(); +} + export async function parse_bool( value: FormDataEntryValue | null, def: T, diff --git a/server/utils.ts b/server/utils.ts index b571039..8f2f517 100644 --- a/server/utils.ts +++ b/server/utils.ts @@ -13,8 +13,7 @@ export type JSONResult = { error: string; }; -function gen_response(d: JSONResult) { - let status = 200; +function gen_response(d: JSONResult, status = 200) { if (d.status !== 0) { status = (d.status >= 400 && d.status < 600) ? d.status : 400; } @@ -31,6 +30,6 @@ export function return_error( return gen_response({ ok: false, status, error }); } -export function return_data(data: T) { - return gen_response({ ok: true, status: 0, data }); +export function return_data(data: T, status = 200) { + return gen_response({ ok: true, status: 0, data }, status); }