Add support to upload custom file

This commit is contained in:
2023-12-15 19:53:36 +08:00
parent efcb276c45
commit cf38e9e981
12 changed files with 252 additions and 43 deletions

75
routes/api/file/upload.ts Normal file
View File

@@ -0,0 +1,75 @@
import { Handlers } from "$fresh/server.ts";
import type { EhFile } from "../../../db.ts";
import { get_task_manager } from "../../../server.ts";
import { return_data, return_error } from "../../../server/utils.ts";
import { get_string, parse_bool } from "../../../server/parse_form.ts";
import { fb_get_size } from "../../../thumbnail/ffmpeg_binary.ts";
import { sure_dir } from "../../../utils.ts";
import mime from "mime";
import { extname, join, resolve } from "std/path/mod.ts";
export const handler: Handlers = {
async POST(req, _ctx) {
const m = get_task_manager();
try {
const form = await req.formData();
const file = form.get("file");
if (!file) {
return return_error(1, "Missing file.");
}
const mext = typeof file === "string"
? null
: `.${mime.getExtension(file.type)}`;
const filename = (await get_string(form.get("filename"))) ||
(typeof file === "string" ? null : file.name);
if (!filename) {
return return_error(2, "Missing filename.");
}
const fext = extname(filename);
const fn = mext == fext
? filename
: `${filename.slice(0, filename.length - fext.length)}${mext}`;
const dir = (await get_string(form.get("dir"))) ||
join(m.cfg.base, "uploaded");
const is_original = await parse_bool(
form.get("is_original"),
false,
);
const token = await get_string(form.get("token"));
if (!token) {
return return_error(3, "Missing token.");
}
const path = join(dir, fn);
await sure_dir(dir);
try {
if (typeof file === "string") {
await Deno.writeTextFile(path, file);
} else {
await Deno.writeFile(path, file.stream());
}
const size = await fb_get_size(path);
if (!size) {
await Deno.remove(path);
return return_error(4, "Failed to get file size.");
}
const rpath = resolve(path);
const f = {
id: 0,
path: rpath,
width: size.width,
height: size.height,
is_original,
token,
} as EhFile;
const nf = m.db.add_file(f, false);
return return_data(nf);
} catch (e) {
await Deno.remove(path);
throw e;
}
} catch (e) {
console.error(e);
return return_error(500, "Internal Server Error.");
}
},
};

View File

@@ -26,6 +26,9 @@ export const handler: Handlers = {
m.cfg.ffmpeg_path,
);
const ffmpeg_api_enabled = await check_ffmpeg_api();
const ffprobe_binary_enabled = await check_ffmpeg_binary(
m.cfg.ffprobe_path,
);
const meilisearch_enabled = m.meilisearch !== undefined;
let meilisearch;
if (
@@ -50,6 +53,7 @@ export const handler: Handlers = {
return return_data<StatusData>({
ffmpeg_api_enabled,
ffmpeg_binary_enabled,
ffprobe_binary_enabled,
meilisearch_enabled,
meilisearch,
no_user,

31
routes/upload.tsx Normal file
View File

@@ -0,0 +1,31 @@
import { Handlers, PageProps } from "$fresh/server.ts";
import GlobalContext from "../components/GlobalContext.tsx";
import Uploader from "../islands/Upload.tsx";
import { get_i18nmap, i18n_handle_request } from "../server/i18ns.ts";
type Props = {
lang: string;
};
export const handler: Handlers<Props> = {
GET(req, ctx) {
const re = i18n_handle_request(req);
if (typeof re === "string") {
return ctx.render({
lang: re,
});
}
return re;
},
};
export default function Upload({ data }: PageProps<Props>) {
const i18n = get_i18nmap(data.lang, "upload");
return (
<body>
<GlobalContext>
<Uploader i18n={i18n} lang={data.lang} />
</GlobalContext>
</body>
);
}