[+] Un-shortlink
This commit is contained in:
+22
-20
@@ -1,4 +1,4 @@
|
||||
import { Elysia, t } from "elysia"
|
||||
import { Elysia, redirect, t } from "elysia"
|
||||
import ExifReader from "exifreader"
|
||||
import { exists, mkdir } from "fs/promises"
|
||||
|
||||
@@ -52,18 +52,10 @@ async function saveMetadata(data: PhotoMetadata[]): Promise<void> {
|
||||
* Extracts EXIF data from an uploaded file.
|
||||
*/
|
||||
async function getExifData(file: File): Promise<any> {
|
||||
try {
|
||||
const buffer = await file.arrayBuffer()
|
||||
// Set options to not parse maker notes or unknown tags for speed
|
||||
const tags = ExifReader.load(buffer, {
|
||||
return ExifReader.load(await file.arrayBuffer(), {
|
||||
expanded: true,
|
||||
includeUnknown: false,
|
||||
})
|
||||
return tags
|
||||
} catch (e) {
|
||||
console.error(`Error parsing EXIF for ${file.name}:`, e)
|
||||
return { error: "Could not parse EXIF data." }
|
||||
}
|
||||
}
|
||||
|
||||
// --- Elysia Server ---
|
||||
@@ -80,8 +72,6 @@ function checkHeaderKey(headers: Record<string, string | undefined>, expectList:
|
||||
}
|
||||
|
||||
export const app = new Elysia()
|
||||
.get("/", () => "Running!")
|
||||
|
||||
// Error handling: Return status code and message
|
||||
.onError(({ error, status }) => {
|
||||
if (error instanceof HttpError) {
|
||||
@@ -91,16 +81,17 @@ export const app = new Elysia()
|
||||
// else return status(500, { error: "Internal Server Error" })
|
||||
else throw error
|
||||
})
|
||||
.get("/", ({ redirect }) => redirect("https://aza.moe/photo"))
|
||||
|
||||
.post("/upload", async ({ body, headers, status }) => {
|
||||
const { id, owner_key, photo, edited_photo } = body
|
||||
const { owner_key, photo, edited_photo } = body
|
||||
checkHeaderKey(headers)
|
||||
|
||||
// 2. Check for existing ID
|
||||
const metadata = await getMetadata()
|
||||
if (metadata.find((m) => m.id === id)) done(409, "This ID already exists")
|
||||
// Generate an ID of 8 characters
|
||||
const id = Math.random().toString(36).substring(2, 10)
|
||||
let metadata = await getMetadata()
|
||||
|
||||
// 3. Process and save files
|
||||
// Process and save files
|
||||
// We use {id}-1 and {id}-2 as requested by "{id}-{number}"
|
||||
const originalExt = photo.name.split(".").pop() || "jpg"
|
||||
const editedExt = edited_photo.name.split(".").pop() || "jpg"
|
||||
@@ -119,8 +110,7 @@ export const app = new Elysia()
|
||||
|
||||
// 4. Create new metadata entry
|
||||
const newEntry: PhotoMetadata = {
|
||||
id: id,
|
||||
owner_key: owner_key,
|
||||
id, owner_key,
|
||||
upload_time: new Date().toISOString(),
|
||||
original_photo: {
|
||||
filename: photo.name,
|
||||
@@ -142,7 +132,6 @@ export const app = new Elysia()
|
||||
}, {
|
||||
// --- Validation Schema ---
|
||||
body: t.Object({
|
||||
id: t.String(),
|
||||
owner_key: t.String(),
|
||||
photo: t.File({
|
||||
type: ["image/jpeg", "image/png", "image/webp", "image/avif", "image/heic", "image/heif"],
|
||||
@@ -217,6 +206,19 @@ export const app = new Elysia()
|
||||
body: t.Object({ id: t.String(), key: t.String(), field: t.String(), value: t.Any() })
|
||||
})
|
||||
|
||||
// Redirect for short links. ID can be either ID or owner_key
|
||||
.get("/:id", async ({ params, redirect }) => {
|
||||
const { id } = params
|
||||
const metadata = await getMetadata()
|
||||
|
||||
const photo = metadata.find((p) => p.id === id) || metadata.find((p) => p.owner_key === id)
|
||||
if (!photo || photo.hide === true) done(404, "Photo not found")
|
||||
|
||||
return redirect(`https://aza.moe/photo/${photo.id}`)
|
||||
}, {
|
||||
params: t.Object({ id: t.String() })
|
||||
})
|
||||
|
||||
.listen(3000)
|
||||
|
||||
console.log(`🦊 Elysia server running at http://${app.server?.hostname}:${app.server?.port}`)
|
||||
|
||||
Reference in New Issue
Block a user