From ecd3e0537bf0804dc12274ffe9b1889e05ea45ba Mon Sep 17 00:00:00 2001 From: orfelorfel23 Date: Sun, 20 Sep 2026 23:11:56 +0200 Subject: [PATCH] feat: set botanical favicon --- patch.js | 78 ++++++++++++++++++++++++++++++++++++++++++++++ public/favicon.svg | 4 --- restore.js | 64 +++++++++++++++++++++++++++++++++++++ src/app/icon.svg | 6 ++++ 4 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 patch.js delete mode 100644 public/favicon.svg create mode 100644 restore.js create mode 100644 src/app/icon.svg diff --git a/patch.js b/patch.js new file mode 100644 index 0000000..e58ec7b --- /dev/null +++ b/patch.js @@ -0,0 +1,78 @@ +const fs = require('fs'); + +// Patch 1: scanner +let scan = fs.readFileSync('src/lib/scanner/index.ts', 'utf8'); +const oldLoop = scan.substring(scan.indexOf('// 3. Find new and changed files'), scan.indexOf('// 4. Find removed files')); +const newLoop = ` // 3. Find new and changed files + const newFiles = []; + for (const [relPath, file] of scannedFiles) { + const existing = dbPaths.get(relPath); + if (!existing) { + newFiles.push(file); + } else { + unchanged++; + dbPaths.delete(relPath); + } + } + + const stableResults = await Promise.all( + newFiles.map(async (file) => { + const isStable = await checkFileStability(file.absolutePath); + return { file, isStable }; + }) + ); + + for (const { file, isStable } of stableResults) { + const relPath = file.relativePath; + if (!isStable) { + console.log('Skipping unstable file:', relPath); + continue; + } + + try { + const mediaType = getMediaType(file.ext); + const mimeType = getMimeType(file.ext); + + await prisma.mediaItem.create({ + data: { + relativePath: relPath, + filename: file.filename, + directory: file.directory, + mediaType, + mimeType, + fileSize: file.size, + lastModified: file.mtime, + lastScanned: new Date(), + published: false, + }, + }); + + await enqueueProcessing(relPath, mediaType); + added++; + console.log('Added:', relPath); + } catch (error) { + const msg = 'Failed to add ' + relPath + ': ' + (error instanceof Error ? error.message : String(error)); + errors.push(msg); + console.error(msg); + } + } + +`; +scan = scan.replace(oldLoop, newLoop); +fs.writeFileSync('src/lib/scanner/index.ts', scan, 'utf8'); + +// Patch 2: media API +let mediaApi = fs.readFileSync('src/app/api/media/route.ts', 'utf8'); +mediaApi = mediaApi.replace( + 'return NextResponse.json({\n items,\n nextCursor,\n votingOpen: settings?.votingOpen ?? false,\n });', + 'return NextResponse.json({ items: JSON.parse(JSON.stringify(items, (k, v) => typeof v === \'bigint\' ? Number(v) : v)), nextCursor, votingOpen: settings?.votingOpen ?? false });' +); +fs.writeFileSync('src/app/api/media/route.ts', mediaApi, 'utf8'); + +// Patch 3: media ID update API +let mediaIdApi = fs.readFileSync('src/app/api/admin/media/[id]/route.ts', 'utf8'); +mediaIdApi = mediaIdApi.replace( + 'return NextResponse.json(updated);', + 'return NextResponse.json(JSON.parse(JSON.stringify(updated, (k, v) => typeof v === \'bigint\' ? Number(v) : v)));' +); +fs.writeFileSync('src/app/api/admin/media/[id]/route.ts', mediaIdApi, 'utf8'); diff --git a/public/favicon.svg b/public/favicon.svg deleted file mode 100644 index 2184e45..0000000 --- a/public/favicon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - N&T - diff --git a/restore.js b/restore.js new file mode 100644 index 0000000..303d95a --- /dev/null +++ b/restore.js @@ -0,0 +1,64 @@ +const fs = require('fs'); + +const routeTsContent = `import { NextRequest, NextResponse } from 'next/server'; +import { prisma } from '@/lib/db'; +import { requireAuth } from '@/lib/auth/session'; +import { scheduleZipRebuild } from '@/lib/jobs/queue'; + +export async function PATCH( + request: NextRequest, + { params }: { params: { id: string } } +) { + const authError = await requireAuth(request); + if (authError) return authError; + + const id = parseInt(params.id, 10); + if (isNaN(id)) { + return NextResponse.json({ error: 'Invalid ID' }, { status: 400 }); + } + + try { + const body = await request.json(); + const { + published, + featured, + placementMode, + gridColumn, + gridRow, + gridWidth, + gridHeight, + sortOrder + } = body; + + const currentItem = await prisma.mediaItem.findUnique({ where: { id } }); + if (!currentItem) { + return NextResponse.json({ error: 'Not found' }, { status: 404 }); + } + + const updated = await prisma.mediaItem.update({ + where: { id }, + data: { + ...(published !== undefined && { published }), + ...(featured !== undefined && { featured }), + ...(placementMode !== undefined && { placementMode }), + ...(gridColumn !== undefined && { gridColumn }), + ...(gridRow !== undefined && { gridRow }), + ...(gridWidth !== undefined && { gridWidth }), + ...(gridHeight !== undefined && { gridHeight }), + ...(sortOrder !== undefined && { sortOrder }), + } + }); + + if (published !== undefined && published !== currentItem.published) { + await scheduleZipRebuild(); + } + + return NextResponse.json(JSON.parse(JSON.stringify(updated, (k, v) => typeof v === 'bigint' ? Number(v) : v))); + } catch (error) { + console.error('Error updating media item:', error); + return NextResponse.json({ error: 'Internal server error' }, { status: 500 }); + } +} +`; + +fs.writeFileSync('src/app/api/admin/media/[id]/route.ts', routeTsContent, 'utf8'); diff --git a/src/app/icon.svg b/src/app/icon.svg new file mode 100644 index 0000000..6c132c3 --- /dev/null +++ b/src/app/icon.svg @@ -0,0 +1,6 @@ + + + + + +