shuarya2011 commited on
Commit
28268ed
·
verified ·
1 Parent(s): 488bbfc

Update app.js

Browse files
Files changed (1) hide show
  1. app.js +47 -65
app.js CHANGED
@@ -4,9 +4,10 @@ const fetch = require('node-fetch');
4
  const bodyParser = require('body-parser');
5
 
6
  const app = express();
7
- const PORT = 7860;
8
 
9
  // --- CONFIGURATION ---
 
10
  const STORAGE_POOLS = [
11
  {
12
  repo: "abhy60098/MY-STORAGE",
@@ -25,92 +26,80 @@ const STORAGE_POOLS = [
25
  const DB_FILE = "db.json";
26
 
27
  // --- MIDDLEWARE ---
28
- app.use(cors());
29
- app.use(bodyParser.json({ limit: '50mb' }));
30
- app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
31
 
32
  // --- ROUTES ---
33
 
34
- // HOME - Serve Tester HTML
35
  app.get('/', (req, res) => {
36
- res.sendFile(__dirname + '/tester.html');
 
 
 
 
 
 
37
  });
38
 
39
- // HEALTH CHECK
40
- app.get('/health', (req, res) => {
41
- const configuredTokens = STORAGE_POOLS.filter(p => p.token).length;
42
- res.json({
43
- status: 'ok',
44
- timestamp: new Date().toISOString(),
45
- tokensConfigured: configuredTokens
46
- });
47
- });
48
-
49
- // GET: Fetch posts from all pools
50
  app.get('/posts', async (req, res) => {
51
  try {
52
  const allResults = await Promise.all(STORAGE_POOLS.map(async (pool) => {
 
53
  if (!pool.token) return [];
54
 
55
  const url = `https://huggingface.co/api/datasets/${pool.repo}/raw/main/${DB_FILE}`;
56
- try {
57
- const response = await fetch(url, {
58
- headers: { Authorization: `Bearer ${pool.token}` }
59
- });
60
-
61
- if (response.ok) {
62
- const data = await response.json();
63
- return data.posts || [];
64
- }
65
- return [];
66
- } catch (err) {
67
- return [];
68
  }
 
69
  }));
70
 
 
71
  const mergedPosts = allResults.flat().sort((a, b) => b.id - a.id);
72
  res.json(mergedPosts);
73
  } catch (err) {
74
- res.status(500).json({ error: "Failed to fetch posts." });
 
75
  }
76
  });
77
 
78
- // POST: Upload post
79
  app.post('/posts', async (req, res) => {
80
  try {
81
  const { username, caption, imageBase64, fileName } = req.body;
82
 
83
  if (!imageBase64 || !username) {
84
- return res.status(400).json({ error: "Missing username or image." });
85
  }
86
 
 
87
  const pool = STORAGE_POOLS[Math.floor(Math.random() * STORAGE_POOLS.length)];
88
 
89
  if (!pool.token) {
90
- return res.status(500).json({ error: "Storage pool token not configured." });
91
  }
92
 
93
  const timestamp = Date.now();
94
  const imagePath = `uploads/${timestamp}-${fileName}`;
95
- const imageBuffer = Buffer.from(imageBase64, 'base64');
96
 
97
- // Upload image
98
- const uploadImageUrl = `https://huggingface.co/api/datasets/${pool.repo}/commit/main`;
99
  const imageUploadRes = await fetch(uploadImageUrl, {
100
  method: 'POST',
101
  headers: {
102
- Authorization: `Bearer ${pool.token}`,
103
- 'Content-Type': 'application/json'
104
  },
105
  body: JSON.stringify({
106
- operations: [
107
- {
108
- operation: "add",
109
- path: imagePath,
110
- content: imageBuffer.toString('base64')
111
- }
112
- ],
113
- commit_message: `Upload from ${username}`
114
  })
115
  });
116
 
@@ -121,7 +110,7 @@ app.post('/posts', async (req, res) => {
121
 
122
  const finalImageUrl = `https://huggingface.co/datasets/${pool.repo}/resolve/main/${imagePath}`;
123
 
124
- // Fetch existing db.json
125
  const dbUrl = `https://huggingface.co/api/datasets/${pool.repo}/raw/main/${DB_FILE}`;
126
  const dbRes = await fetch(dbUrl, {
127
  headers: { Authorization: `Bearer ${pool.token}` }
@@ -132,7 +121,7 @@ app.post('/posts', async (req, res) => {
132
  db = await dbRes.json();
133
  }
134
 
135
- // Add new post
136
  db.posts.unshift({
137
  id: timestamp,
138
  username,
@@ -141,37 +130,30 @@ app.post('/posts', async (req, res) => {
141
  pool: pool.repo
142
  });
143
 
144
- // Update db.json
145
- const updateDbUrl = `https://huggingface.co/api/datasets/${pool.repo}/commit/main`;
146
  const dbUploadRes = await fetch(updateDbUrl, {
147
  method: 'POST',
148
  headers: {
149
- Authorization: `Bearer ${pool.token}`,
150
- 'Content-Type': 'application/json'
151
  },
152
  body: JSON.stringify({
153
- operations: [
154
- {
155
- operation: "add",
156
- path: DB_FILE,
157
- content: Buffer.from(JSON.stringify(db, null, 2)).toString('base64')
158
- }
159
- ],
160
- commit_message: "Update database"
161
  })
162
  });
163
 
164
- if (!dbUploadRes.ok) {
165
- throw new Error("Database update failed.");
166
- }
167
 
168
  res.status(201).json({ success: true, imageUrl: finalImageUrl });
169
-
170
  } catch (err) {
 
171
  res.status(500).json({ error: err.message });
172
  }
173
  });
174
 
 
175
  app.listen(PORT, () => {
176
- console.log(`\n✅ Insta API Server Running on http://localhost:${PORT}\n`);
177
  });
 
4
  const bodyParser = require('body-parser');
5
 
6
  const app = express();
7
+ const PORT = 7860; // Default port for Hugging Face Spaces
8
 
9
  // --- CONFIGURATION ---
10
+ // These tokens must be set in your Space Settings -> Variables and secrets
11
  const STORAGE_POOLS = [
12
  {
13
  repo: "abhy60098/MY-STORAGE",
 
26
  const DB_FILE = "db.json";
27
 
28
  // --- MIDDLEWARE ---
29
+ app.use(cors()); // Allows any website to connect
30
+ app.use(bodyParser.json({ limit: '50mb' })); // Allows large image uploads
 
31
 
32
  // --- ROUTES ---
33
 
34
+ // 1. Health Check / Home Page
35
  app.get('/', (req, res) => {
36
+ res.send(`
37
+ <div style="font-family: sans-serif; text-align: center; margin-top: 50px;">
38
+ <h1>🚀 Distributed Storage API is Online</h1>
39
+ <p>Status: <b>Connected to ${STORAGE_POOLS.length} Storage Pools</b></p>
40
+ <p>Use <code>/posts</code> (GET) to fetch data and <code>/posts</code> (POST) to upload.</p>
41
+ </div>
42
+ `);
43
  });
44
 
45
+ // 2. GET: Fetch data from all 3 datasets and merge them
 
 
 
 
 
 
 
 
 
 
46
  app.get('/posts', async (req, res) => {
47
  try {
48
  const allResults = await Promise.all(STORAGE_POOLS.map(async (pool) => {
49
+ // We check if the token exists before calling
50
  if (!pool.token) return [];
51
 
52
  const url = `https://huggingface.co/api/datasets/${pool.repo}/raw/main/${DB_FILE}`;
53
+ const response = await fetch(url, {
54
+ headers: { Authorization: `Bearer ${pool.token}` }
55
+ });
56
+
57
+ if (response.ok) {
58
+ const data = await response.json();
59
+ return data.posts || [];
 
 
 
 
 
60
  }
61
+ return []; // Return empty if file doesn't exist yet
62
  }));
63
 
64
+ // Flatten the array of arrays and sort by ID (timestamp) descending
65
  const mergedPosts = allResults.flat().sort((a, b) => b.id - a.id);
66
  res.json(mergedPosts);
67
  } catch (err) {
68
+ console.error("GET Error:", err);
69
+ res.status(500).json({ error: "Failed to fetch posts from pools." });
70
  }
71
  });
72
 
73
+ // 3. POST: Upload image and update database in a random pool
74
  app.post('/posts', async (req, res) => {
75
  try {
76
  const { username, caption, imageBase64, fileName } = req.body;
77
 
78
  if (!imageBase64 || !username) {
79
+ return res.status(400).json({ error: "Missing required fields (username or image)." });
80
  }
81
 
82
+ // Pick a random pool to distribute storage usage
83
  const pool = STORAGE_POOLS[Math.floor(Math.random() * STORAGE_POOLS.length)];
84
 
85
  if (!pool.token) {
86
+ return res.status(500).json({ error: "Storage pool token not configured in Secrets." });
87
  }
88
 
89
  const timestamp = Date.now();
90
  const imagePath = `uploads/${timestamp}-${fileName}`;
 
91
 
92
+ // A. Upload the Image file
93
+ const uploadImageUrl = `https://huggingface.co/api/datasets/${pool.repo}/upload/main/${imagePath}`;
94
  const imageUploadRes = await fetch(uploadImageUrl, {
95
  method: 'POST',
96
  headers: {
97
+ Authorization: `Bearer ${pool.token}`,
98
+ 'Content-Type': 'application/json'
99
  },
100
  body: JSON.stringify({
101
+ content: imageBase64, // Expecting raw base64 string
102
+ message: `Upload image from ${username}`
 
 
 
 
 
 
103
  })
104
  });
105
 
 
110
 
111
  const finalImageUrl = `https://huggingface.co/datasets/${pool.repo}/resolve/main/${imagePath}`;
112
 
113
+ // B. Fetch existing db.json from the SAME pool
114
  const dbUrl = `https://huggingface.co/api/datasets/${pool.repo}/raw/main/${DB_FILE}`;
115
  const dbRes = await fetch(dbUrl, {
116
  headers: { Authorization: `Bearer ${pool.token}` }
 
121
  db = await dbRes.json();
122
  }
123
 
124
+ // C. Add new post to the beginning of the list
125
  db.posts.unshift({
126
  id: timestamp,
127
  username,
 
130
  pool: pool.repo
131
  });
132
 
133
+ // D. Upload the updated db.json back to Hugging Face
134
+ const updateDbUrl = `https://huggingface.co/api/datasets/${pool.repo}/upload/main/${DB_FILE}`;
135
  const dbUploadRes = await fetch(updateDbUrl, {
136
  method: 'POST',
137
  headers: {
138
+ Authorization: `Bearer ${pool.token}`,
139
+ 'Content-Type': 'application/json'
140
  },
141
  body: JSON.stringify({
142
+ content: Buffer.from(JSON.stringify(db, null, 2)).toString('base64'),
143
+ message: "Update database JSON"
 
 
 
 
 
 
144
  })
145
  });
146
 
147
+ if (!dbUploadRes.ok) throw new Error("Database update failed.");
 
 
148
 
149
  res.status(201).json({ success: true, imageUrl: finalImageUrl });
 
150
  } catch (err) {
151
+ console.error("POST Error:", err);
152
  res.status(500).json({ error: err.message });
153
  }
154
  });
155
 
156
+ // Start the server
157
  app.listen(PORT, () => {
158
+ console.log(`Server is running on http://localhost:${PORT}`);
159
  });