tera.host / server.js
vedaco's picture
Create server.js
7b1e950 verified
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}`);
});