UNPKG

khamba

Version:

A cli tool for sharing files through local network.

176 lines (175 loc) 7.1 kB
import express from 'express'; import { useCallback, useEffect } from 'react'; import fs from 'fs'; import path from 'path'; import { hashFile, hashFolder } from '../functions/useHashCheck.js'; import { log, logError } from '../functions/log.js'; import { SEND_PATH } from '../functions/variables.js'; // import {default as tarFs} from 'tar-fs'; import { c } from 'tar'; import { $sendingFiles } from '../stores/baseStore.js'; import { useStore } from '@nanostores/react'; import { initTransferInfo } from '../stores/fileHandlerStore.js'; import { $connectedPeers } from '../stores/peersStore.js'; export const useHttpServer = (MY_IP, TCP_PORT, isSending, sendingFileNames) => { const sendingFiles = useStore($sendingFiles); // const connectedPeers = useStore($connectedPeers); const initSenderTransfer = useCallback((peerID) => { const connectedPeers = $connectedPeers.get(); const selectedPeer = connectedPeers[peerID]; if (!selectedPeer) { return log('⭕ Selected Peer not found ⭕', peerID); } if (!sendingFiles) { return log('⭕ No sending files found ⭕'); } const selectedPeerFiles = Object.fromEntries(Object.entries(sendingFiles).map(([fileId, fileInfo]) => [ fileId, { fileId, ...fileInfo }, ])); const totalFiles = Object.entries(sendingFiles).length; initTransferInfo({ peerID: peerID, peerIP: selectedPeer.ip, peerHttpPort: selectedPeer.httpPort, senderName: selectedPeer.name, }, totalFiles, selectedPeerFiles); }, [sendingFiles]); useEffect(() => { const app = express(); app.use(express.json()); app.get('/', (req, res) => { res.json({ msg: 'Hoe!', }); }); app.get('/get-active-peer-info', (req, res) => { res.json({ isSending, sendingFileNames, }); }); app.get('/get-active-peer', (req, res) => { setTimeout(() => { res.json({ active: true }); }, 10000); }); app.get('/init-sender-transfer/*', (req, res) => { console.log('Req To: /init-sender-transfer/'); try { const peerID = req.params['0']; if (!peerID) { return res.status(400).json({ msg: 'filename required.' }); } initSenderTransfer(peerID); res.json({ msg: 'transfer initialized', }); } catch (error) { logError(error); } }); app.get('/download/*', (req, res) => { console.log('Req To: /download/*'); try { const filename = req.params['0']; if (!filename) { return res.status(400).json({ msg: 'filename required.' }); } const filePath = path.join(SEND_PATH, filename); if (!fs.existsSync(filePath)) { return res.status(404).json({ msg: 'File not found!', filePath }); } // const stat = fs.statSync(filePath); // const fileSize = stat.size; // res.setHeader('Content-Length', fileSize); res.setHeader('Content-Disposition', `attachment; filename=${filename}`); const fileStream = fs.createReadStream(filePath); fileStream.pipe(res); // res.download(filePath, path.basename(filePath), err => { // if (err) { // logError('Error downloading file:', err); // res.status(500).send('Error downloading file'); // } // }); } catch (error) { logError(error); } }); app.get('/download-tar/*', (req, res) => { console.log('Req To: /download-tar/*'); try { const foldername = req.params['0']; if (!foldername) { return res.status(400).json({ msg: 'foldername required.' }); } const folderPath = path.join(SEND_PATH, foldername); if (!fs.existsSync(folderPath)) { return res.status(404).json({ msg: 'Folder not found!', folderPath }); } // const folderSize = getFolderSize(folderPath); res.setHeader('Content-Type', 'application/x-tar'); // res.setHeader('Content-Length', folderSize); res.setHeader('Content-Disposition', `attachment; filename=${foldername}.tar`); // const pack = tarFs.pack(folderPath); const pack = c({ C: folderPath, }, ['']); pack.on('error', (err) => { logError('Pack stream error:', err); res.status(500).end('Internal Server Error'); }); res.on('error', err => { logError('Response stream error:', err); }); res.on('close', () => { log('Response stream closed'); }); // pack.on('data', chunk => { // log('chunk.length', chunk.length); // }); pack.pipe(res); } catch (error) { logError(error); } }); app.get('/get-hash/*', async (req, res) => { try { const filename = req.params['0']; if (!filename) { return res.status(400).json({ msg: 'filename required.' }); } const filePath = path.join(SEND_PATH, filename); if (!fs.existsSync(filePath)) { return res.status(404).json({ msg: 'File not found!!' }); } try { const stats = fs.statSync(filePath); const hash = stats.isDirectory() ? await hashFolder(filePath) : await hashFile(filePath); log(`Hash of ${filename} is -> ${hash}`); return res.status(200).json({ msg: 'Hash Successful!', hash }); } catch (err) { logError('Error hashing file:', err); return res.status(400).json({ msg: 'Hash Failed!' }); } } catch (error) { logError(error); } }); const server = app.listen(TCP_PORT, MY_IP, () => { console.log(`Server is running on http://${MY_IP}:${TCP_PORT}`); }); return () => { server.close(() => { log('Server stopped listening for requests.'); }); }; }, []); };