const express = require('express'); const cors = require('cors'); const fs = require('fs'); const path = require('path'); const multer = require('multer'); const app = express(); const PORT = process.env.PORT || 7860; // Persistent storage on Hugging Face const UPLOAD_DIR = '/data/uploads'; const DATA_FILE = '/data/data.json'; // Create upload dir try { if (!fs.existsSync('/data')) fs.mkdirSync('/data', { recursive: true }); if (!fs.existsSync(UPLOAD_DIR)) fs.mkdirSync(UPLOAD_DIR, { recursive: true }); } catch (e) { console.log('Dir note:', e.message); } app.use(cors({ origin: '*' })); app.use(express.json({ limit: '500mb' })); app.use('/uploads', express.static(UPLOAD_DIR)); // Serve static HTML files app.use(express.static(path.join(__dirname, 'public'))); const storage = multer.diskStorage({ destination: (req, file, cb) => cb(null, UPLOAD_DIR), filename: (req, file, cb) => { const ext = path.extname(file.originalname); const name = `${Date.now()}-${Math.round(Math.random() * 1e9)}${ext}`; cb(null, name); } }); const upload = multer({ storage, limits: { fileSize: 500 * 1024 * 1024 } }); function readData() { try { if (!fs.existsSync(DATA_FILE)) return { articles: [], videos: [] }; return JSON.parse(fs.readFileSync(DATA_FILE, 'utf-8')); } catch (e) { return { articles: [], videos: [] }; } } function writeData(data) { try { fs.writeFileSync(DATA_FILE, JSON.stringify(data, null, 2)); } catch (e) { console.error('Write error:', e.message); } } // Health check app.get('/', (req, res) => { res.json({ status: 'ok', message: 'Tera News Server Running!' }); }); // Get all data app.get('/api/data', (req, res) => { res.json(readData()); }); // Update all data app.put('/api/data', (req, res) => { const data = { articles: req.body.articles || [], videos: req.body.videos || [] }; writeData(data); res.json({ success: true, data }); }); // Add article app.post('/api/articles', (req, res) => { const data = readData(); const article = req.body; if (!article || !article.id) return res.status(400).json({ error: 'Invalid article' }); data.articles.unshift(article); writeData(data); res.json({ success: true, article }); }); // Add video app.post('/api/videos', (req, res) => { const data = readData(); const video = req.body; if (!video || !video.id) return res.status(400).json({ error: 'Invalid video' }); data.videos.unshift(video); writeData(data); res.json({ success: true, video }); }); // Delete article app.delete('/api/articles/:id', (req, res) => { const data = readData(); data.articles = data.articles.filter(a => a.id !== parseInt(req.params.id)); writeData(data); res.json({ success: true }); }); // Delete video app.delete('/api/videos/:id', (req, res) => { const data = readData(); data.videos = data.videos.filter(v => v.id !== parseInt(req.params.id)); writeData(data); res.json({ success: true }); }); // Update views app.post('/api/articles/:id/views', (req, res) => { const data = readData(); const article = data.articles.find(a => a.id === parseInt(req.params.id)); if (!article) return res.status(404).json({ error: 'Not found' }); article.views = (article.views || 0) + 1; writeData(data); res.json({ success: true, views: article.views }); }); // Upload file (video or image) app.post('/api/upload', upload.single('file'), (req, res) => { if (!req.file) return res.status(400).json({ error: 'No file uploaded' }); const url = `${req.protocol}://${req.get('host')}/uploads/${req.file.filename}`; res.json({ success: true, url, filename: req.file.filename }); }); // Get uploaded file list app.get('/api/files', (req, res) => { try { const files = fs.readdirSync(UPLOAD_DIR).map(f => ({ name: f, url: `${req.protocol}://${req.get('host')}/uploads/${f}`, size: fs.statSync(path.join(UPLOAD_DIR, f)).size })); res.json({ success: true, files }); } catch (e) { res.json({ success: true, files: [] }); } }); app.listen(PORT, '0.0.0.0', () => { console.log(`Tera News Server running on port ${PORT}`); });