shuarya2011's picture
Update app.js
28268ed verified
Raw
History Blame Contribute Delete
5 kB
const express = require('express');
const cors = require('cors');
const fetch = require('node-fetch');
const bodyParser = require('body-parser');
const app = express();
const PORT = 7860; // Default port for Hugging Face Spaces
// --- CONFIGURATION ---
// These tokens must be set in your Space Settings -> Variables and secrets
const STORAGE_POOLS = [
{
repo: "abhy60098/MY-STORAGE",
token: process.env.HF_TOKEN_1
},
{
repo: "sushmasinharnc/MY-STORAGE",
token: process.env.HF_TOKEN_2
},
{
repo: "shuarya2011/MY-STORAGE",
token: process.env.HF_TOKEN_3
}
];
const DB_FILE = "db.json";
// --- MIDDLEWARE ---
app.use(cors()); // Allows any website to connect
app.use(bodyParser.json({ limit: '50mb' })); // Allows large image uploads
// --- ROUTES ---
// 1. Health Check / Home Page
app.get('/', (req, res) => {
res.send(`
<div style="font-family: sans-serif; text-align: center; margin-top: 50px;">
<h1>🚀 Distributed Storage API is Online</h1>
<p>Status: <b>Connected to ${STORAGE_POOLS.length} Storage Pools</b></p>
<p>Use <code>/posts</code> (GET) to fetch data and <code>/posts</code> (POST) to upload.</p>
</div>
`);
});
// 2. GET: Fetch data from all 3 datasets and merge them
app.get('/posts', async (req, res) => {
try {
const allResults = await Promise.all(STORAGE_POOLS.map(async (pool) => {
// We check if the token exists before calling
if (!pool.token) return [];
const url = `https://huggingface.co/api/datasets/${pool.repo}/raw/main/${DB_FILE}`;
const response = await fetch(url, {
headers: { Authorization: `Bearer ${pool.token}` }
});
if (response.ok) {
const data = await response.json();
return data.posts || [];
}
return []; // Return empty if file doesn't exist yet
}));
// Flatten the array of arrays and sort by ID (timestamp) descending
const mergedPosts = allResults.flat().sort((a, b) => b.id - a.id);
res.json(mergedPosts);
} catch (err) {
console.error("GET Error:", err);
res.status(500).json({ error: "Failed to fetch posts from pools." });
}
});
// 3. POST: Upload image and update database in a random pool
app.post('/posts', async (req, res) => {
try {
const { username, caption, imageBase64, fileName } = req.body;
if (!imageBase64 || !username) {
return res.status(400).json({ error: "Missing required fields (username or image)." });
}
// Pick a random pool to distribute storage usage
const pool = STORAGE_POOLS[Math.floor(Math.random() * STORAGE_POOLS.length)];
if (!pool.token) {
return res.status(500).json({ error: "Storage pool token not configured in Secrets." });
}
const timestamp = Date.now();
const imagePath = `uploads/${timestamp}-${fileName}`;
// A. Upload the Image file
const uploadImageUrl = `https://huggingface.co/api/datasets/${pool.repo}/upload/main/${imagePath}`;
const imageUploadRes = await fetch(uploadImageUrl, {
method: 'POST',
headers: {
Authorization: `Bearer ${pool.token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
content: imageBase64, // Expecting raw base64 string
message: `Upload image from ${username}`
})
});
if (!imageUploadRes.ok) {
const errorText = await imageUploadRes.text();
throw new Error(`Image Upload Failed: ${errorText}`);
}
const finalImageUrl = `https://huggingface.co/datasets/${pool.repo}/resolve/main/${imagePath}`;
// B. Fetch existing db.json from the SAME pool
const dbUrl = `https://huggingface.co/api/datasets/${pool.repo}/raw/main/${DB_FILE}`;
const dbRes = await fetch(dbUrl, {
headers: { Authorization: `Bearer ${pool.token}` }
});
let db = { posts: [] };
if (dbRes.ok) {
db = await dbRes.json();
}
// C. Add new post to the beginning of the list
db.posts.unshift({
id: timestamp,
username,
caption,
imageUrl: finalImageUrl,
pool: pool.repo
});
// D. Upload the updated db.json back to Hugging Face
const updateDbUrl = `https://huggingface.co/api/datasets/${pool.repo}/upload/main/${DB_FILE}`;
const dbUploadRes = await fetch(updateDbUrl, {
method: 'POST',
headers: {
Authorization: `Bearer ${pool.token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
content: Buffer.from(JSON.stringify(db, null, 2)).toString('base64'),
message: "Update database JSON"
})
});
if (!dbUploadRes.ok) throw new Error("Database update failed.");
res.status(201).json({ success: true, imageUrl: finalImageUrl });
} catch (err) {
console.error("POST Error:", err);
res.status(500).json({ error: err.message });
}
});
// Start the server
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});