120 lines
3.9 KiB
JavaScript
120 lines
3.9 KiB
JavaScript
const express = require('express');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const crypto = require('crypto');
|
|
const multer = require('multer');
|
|
const { listAds, getAd, updateAd, updateAdFile, updateAdThumbnail, deleteAd } = require('../db');
|
|
const { captureScreenshot } = require('../utils/screenshot');
|
|
|
|
const UPLOADS_DIR = process.env.UPLOADS_DIR || path.join(__dirname, '..', '..', 'uploads');
|
|
|
|
const fileStorage = multer.diskStorage({
|
|
destination: (_req, _file, cb) => cb(null, UPLOADS_DIR),
|
|
filename: (_req, _file, cb) => cb(null, `${crypto.randomUUID()}.html`),
|
|
});
|
|
|
|
const uploadFile = multer({
|
|
storage: fileStorage,
|
|
fileFilter: (_req, file, cb) => {
|
|
if (file.mimetype === 'text/html' || file.originalname.endsWith('.html')) {
|
|
cb(null, true);
|
|
} else {
|
|
cb(new Error('Only .html files are allowed'));
|
|
}
|
|
},
|
|
limits: { fileSize: 50 * 1024 * 1024 },
|
|
});
|
|
|
|
const router = express.Router();
|
|
|
|
router.get('/', (req, res) => {
|
|
res.json(listAds(req.query.appId));
|
|
});
|
|
|
|
router.get('/:id', (req, res) => {
|
|
const ad = getAd(req.params.id);
|
|
if (!ad) return res.status(404).json({ error: 'Not found' });
|
|
res.json(ad);
|
|
});
|
|
|
|
router.patch('/:id', (req, res) => {
|
|
const existing = getAd(req.params.id);
|
|
if (!existing) return res.status(404).json({ error: 'Not found' });
|
|
|
|
const { title, appId, tags, developer, repo, branch, notes } = req.body;
|
|
const updated = updateAd(req.params.id, {
|
|
title: title ?? existing.title,
|
|
appId: appId ?? existing.appId ?? null,
|
|
tags: tags ?? existing.tags ?? [],
|
|
developer: developer ?? existing.developer ?? '',
|
|
repo: repo ?? existing.repo ?? '',
|
|
branch: branch ?? existing.branch ?? '',
|
|
notes: notes ?? existing.notes ?? '',
|
|
});
|
|
res.json(updated);
|
|
});
|
|
|
|
router.post('/:id/thumbnail', express.json({ limit: '10mb' }), (req, res) => {
|
|
const ad = getAd(req.params.id);
|
|
if (!ad) return res.status(404).json({ error: 'Not found' });
|
|
|
|
const { dataUrl } = req.body;
|
|
if (!dataUrl || !dataUrl.startsWith('data:image/')) {
|
|
return res.status(400).json({ error: 'Invalid dataUrl' });
|
|
}
|
|
|
|
const thumbFilename = `${req.params.id}-thumb.png`;
|
|
const base64Data = dataUrl.replace(/^data:image\/\w+;base64,/, '');
|
|
fs.writeFileSync(path.join(UPLOADS_DIR, thumbFilename), Buffer.from(base64Data, 'base64'));
|
|
|
|
const updated = updateAdThumbnail(req.params.id, thumbFilename);
|
|
res.json(updated);
|
|
});
|
|
|
|
router.post('/:id/screenshot', async (req, res) => {
|
|
const ad = getAd(req.params.id);
|
|
if (!ad) return res.status(404).json({ error: 'Not found' });
|
|
|
|
try {
|
|
const port = process.env.PORT || 3000;
|
|
const url = `http://127.0.0.1:${port}/uploads/${ad.filename}`;
|
|
const buffer = await captureScreenshot(url);
|
|
|
|
const thumbFilename = `${req.params.id}-thumb.png`;
|
|
fs.writeFileSync(path.join(UPLOADS_DIR, thumbFilename), buffer);
|
|
|
|
const updated = updateAdThumbnail(req.params.id, thumbFilename);
|
|
res.json(updated);
|
|
} catch (err) {
|
|
console.error('Screenshot failed:', err.message);
|
|
res.status(500).json({ error: 'Screenshot failed' });
|
|
}
|
|
});
|
|
|
|
router.post('/:id/file', uploadFile.single('file'), (req, res) => {
|
|
const ad = getAd(req.params.id);
|
|
if (!ad) return res.status(404).json({ error: 'Not found' });
|
|
if (!req.file) return res.status(400).json({ error: 'No file uploaded' });
|
|
|
|
const oldPath = path.join(UPLOADS_DIR, ad.filename);
|
|
if (fs.existsSync(oldPath)) fs.unlinkSync(oldPath);
|
|
|
|
const updated = updateAdFile(req.params.id, req.file.filename);
|
|
res.json(updated);
|
|
});
|
|
|
|
router.delete('/:id', (req, res) => {
|
|
const ad = deleteAd(req.params.id);
|
|
if (!ad) return res.status(404).json({ error: 'Not found' });
|
|
|
|
const filePath = path.join(UPLOADS_DIR, ad.filename);
|
|
if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
|
|
|
|
const thumbPath = path.join(UPLOADS_DIR, `${ad.id}-thumb.png`);
|
|
if (fs.existsSync(thumbPath)) fs.unlinkSync(thumbPath);
|
|
|
|
res.status(204).end();
|
|
});
|
|
|
|
module.exports = router;
|