add manga library
This commit is contained in:
71
src/app/api/comics/page/route.ts
Normal file
71
src/app/api/comics/page/route.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { getLibrary, resolveLibraryRoot, resolveAndJail } from '@/lib/libraries'
|
||||
import { getComicPageBuffer } from '@/lib/comics'
|
||||
import { requireLibraryAccess } from '@/lib/auth'
|
||||
import { getDb } from '@/lib/db'
|
||||
|
||||
const EXT_TO_MIME: Record<string, string> = {
|
||||
'.jpg': 'image/jpeg',
|
||||
'.jpeg': 'image/jpeg',
|
||||
'.png': 'image/png',
|
||||
'.webp': 'image/webp',
|
||||
'.gif': 'image/gif',
|
||||
}
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const { searchParams } = request.nextUrl
|
||||
const libraryId = searchParams.get('libraryId')
|
||||
const issueKey = searchParams.get('issueKey')
|
||||
const pageIndexStr = searchParams.get('pageIndex')
|
||||
|
||||
if (!libraryId || !issueKey || pageIndexStr === null) {
|
||||
return NextResponse.json({ error: 'Missing libraryId, issueKey, or pageIndex' }, { status: 400 })
|
||||
}
|
||||
|
||||
const pageIndex = parseInt(pageIndexStr, 10)
|
||||
if (isNaN(pageIndex) || pageIndex < 0) {
|
||||
return NextResponse.json({ error: 'Invalid pageIndex' }, { status: 400 })
|
||||
}
|
||||
|
||||
const auth = await requireLibraryAccess(request, libraryId)
|
||||
if (auth instanceof NextResponse) return auth
|
||||
|
||||
const library = getLibrary(libraryId)
|
||||
if (!library) {
|
||||
return NextResponse.json({ error: 'Library not found' }, { status: 404 })
|
||||
}
|
||||
|
||||
const db = getDb()
|
||||
const row = db
|
||||
.prepare('SELECT file_path FROM media_items WHERE item_key = ? AND item_type = ?')
|
||||
.get(issueKey, 'comic_issue') as { file_path: string | null } | undefined
|
||||
|
||||
if (!row?.file_path) {
|
||||
return NextResponse.json({ error: 'Issue not found' }, { status: 404 })
|
||||
}
|
||||
|
||||
const root = resolveLibraryRoot(library)
|
||||
|
||||
let absPath: string
|
||||
try {
|
||||
absPath = resolveAndJail(root, row.file_path)
|
||||
} catch {
|
||||
return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
|
||||
}
|
||||
|
||||
const result = getComicPageBuffer(absPath, pageIndex)
|
||||
if (!result) {
|
||||
return NextResponse.json({ error: 'Page not found' }, { status: 404 })
|
||||
}
|
||||
|
||||
const mimeType = EXT_TO_MIME[result.ext] ?? 'image/jpeg'
|
||||
|
||||
return new NextResponse(result.buffer as unknown as BodyInit, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': mimeType,
|
||||
'Content-Length': String(result.buffer.length),
|
||||
'Cache-Control': 'public, max-age=86400',
|
||||
},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user