mirror of
https://github.com/mudabbir-ahmad/Media-Aggregation-and-Sorting-System.git
synced 2026-10-07 19:40:20 +00:00
343 lines
12 KiB
JavaScript
343 lines
12 KiB
JavaScript
const readline = require('readline');
|
|
const os = require('os');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const config = require('./config');
|
|
const passwordManager = require('./password_manager');
|
|
const { execSync } = require('child_process');
|
|
|
|
const rl = readline.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout,
|
|
});
|
|
|
|
function ask(question) {
|
|
return new Promise(resolve => rl.question(question, resolve));
|
|
}
|
|
|
|
function clearScreen() {
|
|
process.stdout.write(process.platform === 'win32' ? '\x1Bc' : '\033[2J\033[H');
|
|
}
|
|
|
|
let detectedPlatform = null;
|
|
|
|
function printBanner() {
|
|
const user = os.userInfo().username;
|
|
const photosPath = config.getPhotosPath() || 'NOT SET';
|
|
const shortPath = photosPath.length > 25 ? '...' + photosPath.slice(-22) : photosPath;
|
|
|
|
console.log('');
|
|
console.log('╔══════════════════════════════════════════════╗');
|
|
console.log('║ NAS Photo Server - CLI Client ║');
|
|
console.log('╠══════════════════════════════════════════════╣');
|
|
console.log(`║ User: ${user.padEnd(32)}║`);
|
|
|
|
if (passwordManager.hasStoredPassword()) {
|
|
console.log('║ Password: [STORED - Press P to view] ║');
|
|
} else {
|
|
console.log('║ Password: [NOT SET] ║');
|
|
}
|
|
|
|
console.log(`║ Platform: ${(detectedPlatform || 'Unknown').padEnd(32)}║`);
|
|
console.log(`║ Photos: ${shortPath.padEnd(32)}║`);
|
|
console.log(`║ Port: ${String(config.DEFAULT_PORT).padEnd(32)}║`);
|
|
console.log('╚══════════════════════════════════════════════╝');
|
|
console.log('');
|
|
}
|
|
|
|
async function detectOrAskPlatform() {
|
|
const plat = process.platform;
|
|
if (plat === 'win32') {
|
|
detectedPlatform = 'Windows';
|
|
console.log('[*] Detected platform: Windows');
|
|
return 'windows';
|
|
} else if (plat === 'linux') {
|
|
detectedPlatform = 'Linux (Ubuntu)';
|
|
console.log('[*] Detected platform: Linux (assuming Ubuntu)');
|
|
return 'linux';
|
|
} else {
|
|
console.log('');
|
|
console.log('What operating system are you running?');
|
|
console.log(' [1] Windows');
|
|
console.log(' [2] Linux (Ubuntu)');
|
|
const choice = await ask('Select (1/2): ');
|
|
if (choice.trim() === '1') {
|
|
detectedPlatform = 'Windows';
|
|
return 'windows';
|
|
} else {
|
|
detectedPlatform = 'Linux (Ubuntu)';
|
|
return 'linux';
|
|
}
|
|
}
|
|
}
|
|
|
|
function checkDependencies() {
|
|
console.log('[*] Checking dependencies...');
|
|
try {
|
|
execSync('node --version', { stdio: 'ignore' });
|
|
console.log(' [OK] Node.js found');
|
|
} catch {
|
|
console.log(' [!!] Node.js not found. Please install Node.js.');
|
|
return false;
|
|
}
|
|
|
|
const nodeModules = path.join(__dirname, 'node_modules');
|
|
if (!fs.existsSync(nodeModules)) {
|
|
console.log('[*] Installing dependencies...');
|
|
try {
|
|
execSync('npm install', { cwd: __dirname, stdio: 'inherit' });
|
|
console.log(' [OK] Dependencies installed');
|
|
} catch {
|
|
console.log(' [!!] Failed to install dependencies. Run "npm install" manually in ServerFiles/');
|
|
return false;
|
|
}
|
|
} else {
|
|
console.log(' [OK] Dependencies already installed');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
async function setupPhotosPath(platform) {
|
|
const current = config.getPhotosPath();
|
|
if (current) {
|
|
console.log(`[*] Current photos path: ${current}`);
|
|
const change = await ask('Change photos path? (Y/N): ');
|
|
if (change.trim().toUpperCase() !== 'Y') return;
|
|
}
|
|
|
|
let defaultPath;
|
|
if (platform === 'windows') {
|
|
defaultPath = path.join(os.homedir(), 'NASPhotos');
|
|
} else {
|
|
defaultPath = path.join(os.homedir(), 'nas-photos');
|
|
}
|
|
|
|
console.log(`Default path: ${defaultPath}`);
|
|
const inputPath = await ask('Enter photos storage path (or press Enter for default): ');
|
|
const finalPath = inputPath.trim() || defaultPath;
|
|
|
|
if (!fs.existsSync(finalPath)) {
|
|
console.log(`[*] Creating directory: ${finalPath}`);
|
|
fs.mkdirSync(finalPath, { recursive: true });
|
|
}
|
|
|
|
config.setPhotosPath(finalPath);
|
|
console.log(`[OK] Photos path set to: ${finalPath}`);
|
|
}
|
|
|
|
async function handlePassword() {
|
|
console.log('');
|
|
console.log('╔══════════════════════════════════════════════╗');
|
|
console.log('║ Password Management ║');
|
|
console.log('╠══════════════════════════════════════════════╣');
|
|
|
|
if (passwordManager.hasStoredPassword()) {
|
|
console.log('║ A password is currently stored. ║');
|
|
console.log('║ [V] View password ║');
|
|
console.log('║ [C] Change password ║');
|
|
console.log('║ [D] Delete password ║');
|
|
console.log('║ [B] Back ║');
|
|
console.log('╚══════════════════════════════════════════════╝');
|
|
|
|
const choice = await ask('Select option: ');
|
|
switch (choice.trim().toUpperCase()) {
|
|
case 'V': {
|
|
const pw = passwordManager.retrievePassword();
|
|
if (pw) {
|
|
console.log('');
|
|
console.log(` User: ${os.userInfo().username}`);
|
|
console.log(` Password: ${pw}`);
|
|
console.log('');
|
|
} else {
|
|
console.log('[!!] Could not decrypt password. It may have been created on another machine.');
|
|
}
|
|
await ask('Press Enter to continue...');
|
|
break;
|
|
}
|
|
case 'C': {
|
|
const newPw = await ask('Enter new password: ');
|
|
if (newPw.trim().length > 0) {
|
|
passwordManager.storePassword(newPw.trim());
|
|
console.log('[OK] Password updated.');
|
|
console.log(` New password: ${newPw.trim()}`);
|
|
} else {
|
|
console.log('[!] Empty password not saved.');
|
|
}
|
|
await ask('Press Enter to continue...');
|
|
break;
|
|
}
|
|
case 'D': {
|
|
const confirm = await ask('Are you sure? (Y/N): ');
|
|
if (confirm.trim().toUpperCase() === 'Y') {
|
|
passwordManager.deletePassword();
|
|
console.log('[OK] Password deleted.');
|
|
}
|
|
await ask('Press Enter to continue...');
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
} else {
|
|
console.log('║ No password is stored. ║');
|
|
console.log('╚══════════════════════════════════════════════╝');
|
|
const store = await ask('Do you want to store a password? (Y/N): ');
|
|
if (store.trim().toUpperCase() === 'Y') {
|
|
const pw = await ask('Enter password: ');
|
|
if (pw.trim().length > 0) {
|
|
passwordManager.storePassword(pw.trim());
|
|
console.log(`[OK] Password stored successfully.`);
|
|
console.log(` Your password: ${pw.trim()}`);
|
|
} else {
|
|
console.log('[!] Empty password not saved.');
|
|
}
|
|
await ask('Press Enter to continue...');
|
|
}
|
|
}
|
|
}
|
|
|
|
function showConnectionInfo() {
|
|
const interfaces = os.networkInterfaces();
|
|
const addresses = [];
|
|
|
|
for (const [name, nets] of Object.entries(interfaces)) {
|
|
for (const net of nets) {
|
|
if (net.family === 'IPv4' && !net.internal) {
|
|
addresses.push({ name, address: net.address });
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log('');
|
|
console.log('╔══════════════════════════════════════════════╗');
|
|
console.log('║ Connection Information ║');
|
|
console.log('╠══════════════════════════════════════════════╣');
|
|
console.log(`║ User: ${os.userInfo().username.padEnd(35)}║`);
|
|
|
|
if (passwordManager.hasStoredPassword()) {
|
|
console.log('║ Pass: [STORED] ║');
|
|
} else {
|
|
console.log('║ Pass: [NOT SET] ║');
|
|
}
|
|
|
|
console.log(`║ Port: ${String(config.DEFAULT_PORT).padEnd(35)}║`);
|
|
console.log('║ ║');
|
|
|
|
if (addresses.length > 0) {
|
|
console.log('║ Network Addresses: ║');
|
|
for (const addr of addresses) {
|
|
const line = ` ${addr.name}: http://${addr.address}:${config.DEFAULT_PORT}`;
|
|
console.log(`║${line.padEnd(46)}║`);
|
|
}
|
|
} else {
|
|
console.log('║ No network interfaces found ║');
|
|
}
|
|
|
|
console.log('╚══════════════════════════════════════════════╝');
|
|
}
|
|
|
|
async function startServerInteractive() {
|
|
const photosPath = config.getPhotosPath();
|
|
if (!photosPath) {
|
|
console.log('[!!] Photos path not set. Please configure it first.');
|
|
await ask('Press Enter to continue...');
|
|
return false;
|
|
}
|
|
|
|
const portInput = await ask(`Enter port (default ${config.DEFAULT_PORT}): `);
|
|
const port = parseInt(portInput.trim()) || config.DEFAULT_PORT;
|
|
|
|
console.log(`[*] Starting NAS server on port ${port}...`);
|
|
console.log(`[*] Photos path: ${photosPath}`);
|
|
console.log('[*] Press Ctrl+C to stop the server.');
|
|
console.log('');
|
|
|
|
const { startServer } = require('./server');
|
|
startServer(port);
|
|
return true; // Server takes over the process
|
|
}
|
|
|
|
async function mainMenu(platform) {
|
|
while (true) {
|
|
clearScreen();
|
|
printBanner();
|
|
console.log(' [1] Start NAS Server');
|
|
console.log(' [2] Configure Photos Path');
|
|
console.log(' [3] Password Management (P)');
|
|
console.log(' [4] Show Connection Info');
|
|
console.log(' [5] Exit');
|
|
console.log('');
|
|
|
|
const choice = await ask('Select option: ');
|
|
|
|
switch (choice.trim().toUpperCase()) {
|
|
case '1': {
|
|
const started = await startServerInteractive();
|
|
if (started) return; // Server is now running
|
|
break;
|
|
}
|
|
case '2':
|
|
await setupPhotosPath(platform);
|
|
break;
|
|
case '3':
|
|
case 'P':
|
|
await handlePassword();
|
|
break;
|
|
case '4':
|
|
showConnectionInfo();
|
|
await ask('\nPress Enter to continue...');
|
|
break;
|
|
case '5':
|
|
console.log('Goodbye!');
|
|
rl.close();
|
|
process.exit(0);
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
clearScreen();
|
|
console.log('Welcome to NAS Photo Server Setup');
|
|
console.log('');
|
|
|
|
const platform = await detectOrAskPlatform();
|
|
console.log('');
|
|
|
|
if (!checkDependencies()) {
|
|
rl.close();
|
|
process.exit(1);
|
|
}
|
|
console.log('');
|
|
|
|
// First-time setup: photos path
|
|
if (!config.getPhotosPath()) {
|
|
console.log('[!] No photos path configured. Let\'s set one up.');
|
|
await setupPhotosPath(platform);
|
|
console.log('');
|
|
}
|
|
|
|
// Ask about password on first run
|
|
if (!passwordManager.hasStoredPassword()) {
|
|
const storePw = await ask('Do you want to store a password? (Y/N): ');
|
|
if (storePw.trim().toUpperCase() === 'Y') {
|
|
const pw = await ask('Enter password: ');
|
|
if (pw.trim().length > 0) {
|
|
passwordManager.storePassword(pw.trim());
|
|
console.log(`[OK] Password stored. Your password: ${pw.trim()}`);
|
|
}
|
|
}
|
|
console.log('');
|
|
}
|
|
|
|
await mainMenu(platform);
|
|
}
|
|
|
|
main().catch(err => {
|
|
console.error('Fatal error:', err);
|
|
process.exit(1);
|
|
});
|
|
|