feat: set botanical favicon
This commit is contained in:
1 parent
d138a5bdd0
commit
ecd3e0537b
4 files changed
+148
-4
No files matched your search
@@ -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');
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
|
||||||
<circle cx="16" cy="16" r="15" fill="#7C9A6E"/>
|
|
||||||
<text x="16" y="21" text-anchor="middle" font-family="Georgia,serif" font-size="14" fill="white" font-weight="bold">N&T</text>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 251 B |
+64
@@ -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');
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="128" height="128">
|
||||||
|
<path d="M18 54 Q32 40 46 14" stroke="#5A7A4E" stroke-width="2" fill="none" stroke-linecap="round"/>
|
||||||
|
<path d="M26 44 Q14 42 16 30 Q28 32 26 44" fill="#7C9A6E"/>
|
||||||
|
<path d="M36 34 Q48 36 50 24 Q38 22 36 34" fill="#7C9A6E"/>
|
||||||
|
<path d="M24 28 Q12 26 14 14 Q26 16 24 28" fill="#7C9A6E"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 382 B |
Reference in new issue
Block a user