Spaces:
Paused
Paused
| const express = require('express'); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const multer = require('multer'); | |
| const app = express(); | |
| const uploadDir = path.join(__dirname, 'uploads'); | |
| // Ensure uploads directory exists | |
| if (!fs.existsSync(uploadDir)) { | |
| fs.mkdirSync(uploadDir); | |
| } | |
| // Function to generate a short random ID (alphanumeric) | |
| function generateShortId() { | |
| return Math.random().toString(36).substring(2, 7); // Generates a random string of length 5 | |
| } | |
| // Configure multer for file storage | |
| const storage = multer.diskStorage({ | |
| destination: function (req, file, cb) { | |
| cb(null, uploadDir); | |
| }, | |
| filename: function (req, file, cb) { | |
| const shortId = generateShortId(); | |
| cb(null, `${shortId}-${file.originalname}`); | |
| } | |
| }); | |
| const upload = multer({ storage: storage }); | |
| // Route for browser upload | |
| app.get('/', (req, res) => { | |
| res.send(` | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Enhanced File Upload</title> | |
| <style> | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| height: 100vh; | |
| margin: 0; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| .container { | |
| background-color: rgba(255, 255, 255, 0.9); | |
| padding: 2rem; | |
| border-radius: 10px; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| text-align: center; | |
| width: 300px; | |
| } | |
| h1 { | |
| color: #4a5568; | |
| margin-bottom: 1.5rem; | |
| } | |
| form { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| } | |
| input[type="file"] { | |
| display: none; | |
| } | |
| .file-label { | |
| background-color: #4a5568; | |
| color: white; | |
| padding: 0.5rem 1rem; | |
| border-radius: 5px; | |
| cursor: pointer; | |
| margin-bottom: 1rem; | |
| transition: background-color 0.3s ease; | |
| } | |
| .file-label:hover { | |
| background-color: #2d3748; | |
| } | |
| #file-name { | |
| margin-bottom: 1rem; | |
| word-break: break-all; | |
| } | |
| button { | |
| background-color: #4299e1; | |
| color: white; | |
| border: none; | |
| padding: 0.5rem 1rem; | |
| border-radius: 5px; | |
| cursor: pointer; | |
| transition: background-color 0.3s ease; | |
| } | |
| button:hover { | |
| background-color: #3182ce; | |
| } | |
| #upload-progress { | |
| width: 100%; | |
| background-color: #e2e8f0; | |
| border-radius: 5px; | |
| margin-top: 1rem; | |
| overflow: hidden; | |
| display: none; | |
| } | |
| #progress-bar { | |
| width: 0; | |
| height: 10px; | |
| background-color: #48bb78; | |
| transition: width 0.5s ease; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>Upload File</h1> | |
| <form id="upload-form" action="/upload" method="post" enctype="multipart/form-data"> | |
| <label for="file-upload" class="file-label">Choose File</label> | |
| <input id="file-upload" type="file" name="file"> | |
| <div id="file-name"></div> | |
| <button type="submit">Upload</button> | |
| </form> | |
| <div id="upload-progress"> | |
| <div id="progress-bar"></div> | |
| </div> | |
| </div> | |
| <script> | |
| const fileUpload = document.getElementById('file-upload'); | |
| const fileName = document.getElementById('file-name'); | |
| const uploadForm = document.getElementById('upload-form'); | |
| const uploadProgress = document.getElementById('upload-progress'); | |
| const progressBar = document.getElementById('progress-bar'); | |
| fileUpload.addEventListener('change', (e) => { | |
| if (e.target.files.length > 0) { | |
| fileName.textContent = e.target.files[0].name; | |
| } else { | |
| fileName.textContent = ''; | |
| } | |
| }); | |
| uploadForm.addEventListener('submit', (e) => { | |
| e.preventDefault(); | |
| if (!fileUpload.files.length) { | |
| alert('Please select a file to upload.'); | |
| return; | |
| } | |
| const formData = new FormData(uploadForm); | |
| const xhr = new XMLHttpRequest(); | |
| xhr.open('POST', '/upload', true); | |
| xhr.upload.onprogress = (event) => { | |
| if (event.lengthComputable) { | |
| const percentComplete = (event.loaded / event.total) * 100; | |
| uploadProgress.style.display = 'block'; | |
| progressBar.style.width = percentComplete + '%'; | |
| } | |
| }; | |
| xhr.onload = function() { | |
| if (xhr.status === 200) { | |
| alert('Upload complete!'); | |
| document.body.innerHTML = xhr.responseText; | |
| } else { | |
| alert('Upload failed. Please try again.'); | |
| } | |
| uploadProgress.style.display = 'none'; | |
| progressBar.style.width = '0'; | |
| fileName.textContent = ''; | |
| uploadForm.reset(); | |
| }; | |
| xhr.send(formData); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |
| `); | |
| }); | |
| // Handler for browser upload | |
| app.post('/upload', upload.single('file'), (req, res) => { | |
| if (!req.file) { | |
| return res.status(400).send('No file uploaded.'); | |
| } | |
| const fileUrl = `https://zhofang-temp-storage.hf.space/${req.file.filename.split('-')[0]}/${req.file.originalname}`; | |
| res.send(` | |
| <html> | |
| <head> | |
| <title>File Uploaded</title> | |
| <style> | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| height: 100vh; | |
| margin: 0; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| color: white; | |
| } | |
| .container { | |
| background-color: rgba(255, 255, 255, 0.1); | |
| padding: 2rem; | |
| border-radius: 10px; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| text-align: center; | |
| } | |
| a { | |
| color: #4299e1; | |
| text-decoration: none; | |
| } | |
| a:hover { | |
| text-decoration: underline; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>File Uploaded Successfully</h1> | |
| <p>Uploaded 1 file, ${req.file.size} bytes</p> | |
| <p>Download link: <a href="${fileUrl}">${fileUrl}</a></p> | |
| <p>wget command: <code>wget ${fileUrl}</code></p> | |
| </div> | |
| </body> | |
| </html> | |
| `); | |
| // Delete file after 24 hours | |
| setTimeout(() => { | |
| fs.unlink(req.file.path, (err) => { | |
| if (err) console.error(`Error deleting file: ${err}`); | |
| }); | |
| }, 24 * 60 * 60 * 1000); // 24 hours in milliseconds | |
| }); | |
| // Route for upload via PUT (like bashupload) | |
| app.put('/:filename', (req, res) => { | |
| const shortId = generateShortId(); | |
| const filename = req.params.filename; | |
| const filepath = path.join(uploadDir, `${shortId}-${filename}`); | |
| const fileStream = fs.createWriteStream(filepath); | |
| req.pipe(fileStream); | |
| fileStream.on('finish', () => { | |
| const fileUrl = `https://zhofang-temp-storage.hf.space/${shortId}/${filename}`; | |
| res.send(`Uploaded 1 file, ${req.headers['content-length']} bytes\n\nwget ${fileUrl}\n`); | |
| // Delete file after 24 hours | |
| setTimeout(() => { | |
| fs.unlink(filepath, (err) => { | |
| if (err) console.error(`Error deleting file: ${err}`); | |
| }); | |
| }, 24 * 60 * 60 * 1000); // 24 hours in milliseconds | |
| }); | |
| fileStream.on('error', (err) => { | |
| console.error(`Error writing file: ${err}`); | |
| res.status(500).send('Error uploading file.'); | |
| }); | |
| }); | |
| app.get('/:id/:filename', (req, res) => { | |
| const filepath = path.join(uploadDir, `${req.params.id}-${req.params.filename}`); | |
| res.download(filepath, req.params.filename, (err) => { | |
| if (err) { | |
| console.error(`Error downloading file: ${err}`); | |
| res.status(404).send('File not found.'); | |
| } | |
| }); | |
| }); | |
| app.listen(7860, () => { | |
| console.log('Server is running on http://localhost:3000'); | |
| }); |