mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Fix image's api from 500ing when image is not available + optimize etag
This commit is contained in:
parent
4ff0a1fe09
commit
16f6399c4f
@ -1,28 +1,24 @@
|
|||||||
import type { Stats } from "node:fs";
|
import type { Stats } from "node:fs";
|
||||||
import type { BunFile, S3File, S3Stats } from "bun";
|
import type { S3Stats } from "bun";
|
||||||
import { type SQL, and, eq, sql } from "drizzle-orm";
|
import { and, eq, type SQL, sql } from "drizzle-orm";
|
||||||
import Elysia, { type Context, t } from "elysia";
|
import Elysia, { type Context, t } from "elysia";
|
||||||
import { prefix } from "~/base";
|
import { prefix } from "~/base";
|
||||||
import { db } from "~/db";
|
import { db } from "~/db";
|
||||||
import {
|
import {
|
||||||
showTranslations,
|
|
||||||
shows,
|
shows,
|
||||||
|
showTranslations,
|
||||||
staff,
|
staff,
|
||||||
studioTranslations,
|
|
||||||
studios,
|
studios,
|
||||||
|
studioTranslations,
|
||||||
} from "~/db/schema";
|
} from "~/db/schema";
|
||||||
import { sqlarr } from "~/db/utils";
|
import { sqlarr } from "~/db/utils";
|
||||||
import { KError } from "~/models/error";
|
import { KError } from "~/models/error";
|
||||||
import { bubble } from "~/models/examples";
|
import { bubble } from "~/models/examples";
|
||||||
import { AcceptLanguage, isUuid, processLanguages } from "~/models/utils";
|
import { AcceptLanguage, isUuid, processLanguages } from "~/models/utils";
|
||||||
import { getFile } from "~/utils";
|
import { comment, getFile } from "~/utils";
|
||||||
import { imageDir } from "./seed/images";
|
import { imageDir } from "./seed/images";
|
||||||
|
|
||||||
function getRedirectToImageHandler({
|
function getRedirectToImageHandler({ filter }: { filter?: SQL }) {
|
||||||
filter,
|
|
||||||
}: {
|
|
||||||
filter?: SQL;
|
|
||||||
}) {
|
|
||||||
return async function Handler({
|
return async function Handler({
|
||||||
params: { id, image },
|
params: { id, image },
|
||||||
headers: { "accept-language": languages },
|
headers: { "accept-language": languages },
|
||||||
@ -97,11 +93,30 @@ function getRedirectToImageHandler({
|
|||||||
export const imagesH = new Elysia({ tags: ["images"] })
|
export const imagesH = new Elysia({ tags: ["images"] })
|
||||||
.get(
|
.get(
|
||||||
"/images/:id",
|
"/images/:id",
|
||||||
async ({ params: { id }, query: { quality }, headers: reqHeaders }) => {
|
async ({
|
||||||
|
params: { id },
|
||||||
|
query: { quality },
|
||||||
|
headers: reqHeaders,
|
||||||
|
status,
|
||||||
|
}) => {
|
||||||
const path = `${imageDir}/${id}.${quality}.jpg`;
|
const path = `${imageDir}/${id}.${quality}.jpg`;
|
||||||
const file = getFile(path);
|
const file = getFile(path);
|
||||||
|
|
||||||
const etag = await generateETag(file);
|
const stat = await file.stat().catch(() => undefined);
|
||||||
|
if (!stat) {
|
||||||
|
return status(404, {
|
||||||
|
status: 404,
|
||||||
|
message: comment`
|
||||||
|
No image available with this ID.
|
||||||
|
Either the id is invalid or the image has not been downloaded yet.
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const etag =
|
||||||
|
"etag" in stat
|
||||||
|
? stat.etag
|
||||||
|
: Buffer.from(stat.mtime.toISOString(), "utf8").toString("base64");
|
||||||
|
|
||||||
if (await isCached(reqHeaders, etag, path))
|
if (await isCached(reqHeaders, etag, path))
|
||||||
return new Response(null, { status: 304 });
|
return new Response(null, { status: 304 });
|
||||||
|
|
||||||
@ -387,10 +402,3 @@ export async function isCached(
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generateETag(file: BunFile | S3File) {
|
|
||||||
const hash = new Bun.CryptoHasher("md5");
|
|
||||||
hash.update(await file.arrayBuffer());
|
|
||||||
|
|
||||||
return hash.digest("base64");
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user