From 7610369c6d4899928eeae63fa68875c19bf53ce4 Mon Sep 17 00:00:00 2001
From: nai-degen
User | diff --git a/src/info-page.ts b/src/info-page.ts index cb038ee..1bb9157 100644 --- a/src/info-page.ts +++ b/src/info-page.ts @@ -190,6 +190,7 @@ function buildRecentImageSection() { `; } html += ``; + html += `` return html; } diff --git a/src/proxy/middleware/response/save-image.ts b/src/proxy/middleware/response/save-image.ts index efca911..cf2dd15 100644 --- a/src/proxy/middleware/response/save-image.ts +++ b/src/proxy/middleware/response/save-image.ts @@ -19,10 +19,9 @@ export const saveImage: ProxyResHandlerWithBody = async ( } if (body.data) { - const baseUrl = req.protocol + "://" + req.get("host"); const prompt = body.data[0].revised_prompt ?? req.body.prompt; const res = await mirrorGeneratedImage( - baseUrl, + req, prompt, body as OpenAIImageGenerationResult ); diff --git a/src/shared/api-schemas/openai.ts b/src/shared/api-schemas/openai.ts index db5e543..92195eb 100644 --- a/src/shared/api-schemas/openai.ts +++ b/src/shared/api-schemas/openai.ts @@ -52,7 +52,7 @@ export const OpenAIV1ChatCompletionSchema = z .number() .int() .nullish() - .default(OPENAI_OUTPUT_MAX) + .default(Math.min(OPENAI_OUTPUT_MAX, 4096)) .transform((v) => Math.min(v ?? OPENAI_OUTPUT_MAX, OPENAI_OUTPUT_MAX)), frequency_penalty: z.number().optional().default(0), presence_penalty: z.number().optional().default(0), diff --git a/src/shared/file-storage/image-history.ts b/src/shared/file-storage/image-history.ts index 54a3215..796ca72 100644 --- a/src/shared/file-storage/image-history.ts +++ b/src/shared/file-storage/image-history.ts @@ -1,15 +1,18 @@ -const IMAGE_HISTORY_SIZE = 30; +const IMAGE_HISTORY_SIZE = 10000; const imageHistory = new Array
---|
Model Family | diff --git a/src/user/routes.ts b/src/user/routes.ts index 2009f31..28d273b 100644 --- a/src/user/routes.ts +++ b/src/user/routes.ts @@ -1,8 +1,10 @@ import express, { Router } from "express"; import { injectCsrfToken, checkCsrfToken } from "../shared/inject-csrf"; +import { browseImagesRouter } from "./web/browse-images"; import { selfServiceRouter } from "./web/self-service"; import { injectLocals } from "../shared/inject-locals"; import { withSession } from "../shared/with-session"; +import { config } from "../config"; const userRouter = Router(); @@ -13,7 +15,9 @@ userRouter.use( userRouter.use(withSession); userRouter.use(injectCsrfToken, checkCsrfToken); userRouter.use(injectLocals); - +if (config.showRecentImages) { + userRouter.use(browseImagesRouter); +} userRouter.use(selfServiceRouter); userRouter.use( diff --git a/src/user/web/browse-images.ts b/src/user/web/browse-images.ts new file mode 100644 index 0000000..c73ab75 --- /dev/null +++ b/src/user/web/browse-images.ts @@ -0,0 +1,54 @@ +import express, { Request, Response } from "express"; +import { getLastNImages } from "../../shared/file-storage/image-history"; +import { paginate } from "../../shared/utils"; +import { ipLimiter } from "../../proxy/rate-limit"; + +const IMAGES_PER_PAGE = 24; + +const metadataCacheTTL = 1000 * 60 * 3; +let metadataCache: unknown | null = null; +let metadataCacheValid = 0; + +const handleImageHistoryPage = (req: Request, res: Response) => { + const page = parseInt(req.query.page as string) || 1; + const allImages = getLastNImages().reverse(); + const { items, pageCount } = paginate(allImages, page, IMAGES_PER_PAGE); + + res.render("image_history", { + images: items, + pagination: { + currentPage: page, + totalPages: pageCount, + }, + }); +}; + +const handleMetadataRequest = (_req: Request, res: Response) => { + res.setHeader("Cache-Control", "public, max-age=180"); + res.setHeader("Content-Type", "application/json"); + res.setHeader( + "Content-Disposition", + `attachment; filename="image-metadata-${new Date().toISOString()}.json"` + ); + if (new Date().getTime() - metadataCacheValid < metadataCacheTTL) { + return res.status(200).json(metadataCache); + } + + const images = getLastNImages().map(({ prompt, url }) => ({ url, prompt })); + const metadata = { + exportedAt: new Date().toISOString(), + totalImages: images.length, + images, + }; + metadataCache = metadata; + metadataCacheValid = new Date().getTime(); + res.status(200).json(metadata); +}; + +export const browseImagesRouter = express.Router(); +browseImagesRouter.get("/image-history", handleImageHistoryPage); +browseImagesRouter.get( + "/image-history/metadata", + ipLimiter, + handleMetadataRequest +); diff --git a/src/user/web/views/image_history.ejs b/src/user/web/views/image_history.ejs new file mode 100644 index 0000000..f61c9db --- /dev/null +++ b/src/user/web/views/image_history.ejs @@ -0,0 +1,71 @@ +<%- include("partials/shared_header", { title: "Image History" }) %> +
---|