Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 66 additions & 7 deletions backend/api-server/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ const cors = require('cors');
const multer = require('multer');
const fs = require('fs');
const path = require('path');
const uploadToPinata = require('./upload');
const deleteAllPinataFiles = require('./delete');

const app = express();
const port = 3002;
Expand All @@ -25,6 +27,44 @@ const upload = multer({ storage: storage });

app.use(cors());

async function updatePinataFiles(sourcePath) {
try {
console.log('Starting Pinata files update process...');
console.log('Step 1: Deleting all existing files from Pinata...');

const deleteResult = await deleteAllPinataFiles();
if (!deleteResult.success) {
throw new Error(`Delete operation failed: ${deleteResult.error}`);
}

console.log(`Successfully deleted ${deleteResult.deletedCount} files from Pinata`);
console.log('Step 2: Uploading new files to Pinata...');

const uploadResult = await uploadToPinata(sourcePath);
if (!uploadResult.success) {
throw new Error(`Upload operation failed: ${uploadResult.error}`);
}

console.log(`Successfully uploaded ${uploadResult.successfulUploads} files to Pinata`);

return {
success: true,
deletedCount: deleteResult.deletedCount,
uploadedCount: uploadResult.successfulUploads,
failedDeletions: deleteResult.failedDeletions || [],
failedUploads: uploadResult.results ?
uploadResult.results.filter(r => r.status === 'failed') : []
};
} catch (error) {
console.error('Error in updatePinataFiles:', error);
return {
success: false,
error: error.message,
details: error.stack
};
}
}

app.post('/save-pdf', upload.single('pdfFile'), (req, res) => {
try {
if (!req.file) {
Expand All @@ -43,21 +83,40 @@ app.post('/save-pdf', upload.single('pdfFile'), (req, res) => {
}
});

app.post('/git-update', (req, res) => {
app.post('/git-update', async (req, res) => {
try {
// update pinata files tbd
const result = await updatePinataFiles(storageDir);
if (result.success) {
res.json({
message: 'Pinata files updated successfully',
details: {
deletedCount: result.deletedCount,
uploadedCount: result.uploadedCount,
failedDeletions: result.failedDeletions,
failedUploads: result.failedUploads
}
});
} else {
res.status(500).json({
message: 'Failed to update Pinata files',
error: result.error,
details: result.details
});
}
} catch (error) {
res.send("done");
console.error('Error in git-update endpoint:', error);
res.status(500).json({
message: 'Internal server error',
error: error.message
});
}
});
});


app.use((error, req, res, next) => {
console.error('Server error:', error);
res.status(500).json({ message: 'Internal server error', error: error.message });
});

app.listen(port, () => {
console.log(`Server started on port ${port}`);
});

});
105 changes: 105 additions & 0 deletions backend/api-server/delete.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
require('dotenv').config();
const axios = require('axios');

async function deleteAllPinataFiles() {
const apiKey = process.env.PINATA_API_KEY;
const apiSecret = process.env.PINATA_API_SECRET;

if (!apiKey || !apiSecret) {
throw new Error('PINATA_API_KEY and PINATA_API_SECRET must be set in environment variables');
}

try {
const pinataClient = axios.create({
headers: {
'pinata_api_key': apiKey,
'pinata_secret_api_key': apiSecret
}
});

console.log('Fetching list of pinned files...');

const pinsResponse = await pinataClient.get(
'https://api.pinata.cloud/data/pinList?status=pinned'
);

const totalPins = pinsResponse.data.rows.length;
console.log(`Found ${totalPins} files to delete`);

if (totalPins === 0) {
console.log('No files to delete');
return {
success: true,
deletedCount: 0,
failedCount: 0
};
}

let deletedCount = 0;
let failedCount = 0;
const failedDeletions = [];

for (const pin of pinsResponse.data.rows) {
try {
console.log(`Deleting ${pin.metadata?.name || pin.ipfs_pin_hash}...`);

await pinataClient.delete(
`https://api.pinata.cloud/pinning/unpin/${pin.ipfs_pin_hash}`
);

console.log(`✓ Successfully deleted ${pin.metadata?.name || pin.ipfs_pin_hash}`);
deletedCount++;
} catch (deleteError) {
console.error(`✗ Failed to delete ${pin.metadata?.name || pin.ipfs_pin_hash}: ${deleteError.message}`);
failedCount++;
failedDeletions.push({
name: pin.metadata?.name || pin.ipfs_pin_hash,
error: deleteError.message
});
}
}

console.log('\n=== Deletion Summary ===');
console.log(`Total files found: ${totalPins}`);
console.log(`Successfully deleted: ${deletedCount}`);
console.log(`Failed deletions: ${failedCount}`);

if (failedDeletions.length > 0) {
console.log('\nFailed deletions:');
failedDeletions.forEach(failure => {
console.log(`- ${failure.name}: ${failure.error}`);
});
}

return {
success: true,
deletedCount,
failedCount,
failedDeletions
};

} catch (error) {
console.error('Error:', error.message);
return {
success: false,
error: error.message
};
}
}

if (require.main === module) {
deleteAllPinataFiles()
.then(result => {
if (!result.success) {
console.error('Operation failed:', result.error);
process.exit(1);
}
process.exit(0);
})
.catch(error => {
console.error('Operation failed:', error);
process.exit(1);
});
}

module.exports = deleteAllPinataFiles;
64 changes: 64 additions & 0 deletions backend/api-server/delete_upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const uploadToPinata = require('./upload');
const deleteAllPinataFiles = require('./delete');

async function updatePinataFiles(sourcePath) {
try {
console.log('Starting Pinata files update process...');
console.log('Step 1: Deleting all existing files from Pinata...');

const deleteResult = await deleteAllPinataFiles();
if (!deleteResult.success) {
throw new Error(`Delete operation failed: ${deleteResult.error}`);
}

console.log(`Successfully deleted ${deleteResult.deletedCount} files from Pinata`);
console.log('Step 2: Uploading new files to Pinata...');

const uploadResult = await uploadToPinata(sourcePath);
if (!uploadResult.success) {
throw new Error(`Upload operation failed: ${uploadResult.error}`);
}

console.log(`Successfully uploaded ${uploadResult.successfulUploads} files to Pinata`);

return {
success: true,
deletedCount: deleteResult.deletedCount,
uploadedCount: uploadResult.successfulUploads,
failedDeletions: deleteResult.failedDeletions || [],
failedUploads: uploadResult.results ?
uploadResult.results.filter(r => r.status === 'failed') : []
};
} catch (error) {
console.error('Error in updatePinataFiles:', error);
return {
success: false,
error: error.message,
details: error.stack
};
}
}

if (require.main === module) {
const sourcePath = process.argv[2];
if (!sourcePath) {
console.error('Please provide a source path as an argument');
process.exit(1);
}

updatePinataFiles(sourcePath)
.then(result => {
if (!result.success) {
console.error('Update failed:', result.error);
process.exit(1);
}
console.log('Update completed successfully');
process.exit(0);
})
.catch(error => {
console.error('Update failed:', error);
process.exit(1);
});
}

module.exports = updatePinataFiles;
Loading