discord-media-server
Version:
Self-hosted Discord bot for scanning and serving information on local media files.
147 lines (126 loc) • 5.04 kB
JavaScript
// setup.js — interactive setup for discord-media-server
import fs from 'fs';
import path from 'path';
import readline from 'readline';
import dotenv from 'dotenv';
import { fileURLToPath } from 'url';
import { createTables } from './setupDatabase.js';
import { CONFIG_DIR, DATA_DIR, DB_PATH } from './setupConfig.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const envPath = path.join(__dirname, '../.env');
dotenv.config({ path: envPath });
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
//function ask(question) {
// return new Promise(resolve => rl.question(question, answer => resolve(answer.trim())));
//}
function ask(question, defaultValue = '') {
const fullQ = defaultValue ? `${question} (${defaultValue}): ` : `${question}: `;
return new Promise(resolve => {
rl.question(fullQ, answer => { resolve(answer.trim() || defaultValue); });
});
}
function updateOrAdd(key, value) {
let lines = [];
if (fs.existsSync(envPath)) {
lines = fs.readFileSync(envPath, 'utf8')
.split('\n')
.filter(line => line.trim() !== '' && !line.startsWith(key + '='));
}
lines.push(`${key}=${value}`);
fs.writeFileSync(envPath, lines.join('\n').trim() + '\n', 'utf8');
}
async function promptValidMediaPath() {
let dir = '';
while (true) {
dir = await ask('Full path to media folder', process.env.MEDIA_DIR || 'e.g., /home/user/Movies or D:\\Media\\Movies');
if (fs.existsSync(dir)) return dir;
console.log('That folder does not exist. Try again.');
}
}
export default async function runSetup() {
await main();
}
async function main() {
console.log('Running setup...\n');
let shouldWriteEnv = false;
if (fs.existsSync(envPath)) {
const overwriteEnv = (await ask('.env already exists. Edit? (y/N)', 'N')).toLowerCase();
if (overwriteEnv !== 'y') {
console.log('Using existing .env values...');
} else {
shouldWriteEnv = true;
}
} else {
shouldWriteEnv = true;
}
const { connectMySQL, connectSQLite, query } = await import('./database.js');
// Always update .env from config
let dbConfig = {};
let discordClientId = '';
if (shouldWriteEnv) {
const mediaDirectory = await promptValidMediaPath();
const dbChoice = await ask('Choose database type:\n1. SQLite\n2. MySQL\nEnter number', process.env.DB_TYPE == 'mysql' ? '2' : '1');
let dbType = dbChoice === '1' ? 'sqlite' : 'mysql';
let dbName = await ask('Database name:', process.env.DB_NAME || 'media');
if (dbType === 'sqlite') {
dbConfig = {
filename: path.join(DATA_DIR, dbName+".sqlite") || path.resolve(__dirname, `../data/${dbName}.sqlite`),
database: dbName
};
//await connectSQLite(dbConfig);
} else {
dbConfig = {
host: await ask('MySQL Host', process.env.DB_HOST || 'localhost'),
user: await ask('MySQL User', process.env.DB_USER || 'root'),
password: await ask('MySQL Password', process.env.DB_PASS || ''),
database: dbName
};
//await connectMySQL(dbConfig);
}
const discordToken = await ask('Discord Bot Token (optional)', process.env.DISCORD_TOKEN || '');
discordClientId = await ask('Discord Client ID (optional)', process.env.DISCORD_CLIENT_ID || '');
const tmdbKey = await ask('TMDb API Key (optional)', process.env.TMDB_API_KEY || '');
let port = await ask('Server port', process.env.PORT || '8080');
// insert into .env
updateOrAdd('MEDIA_DIR', mediaDirectory);
updateOrAdd('DISCORD_TOKEN', discordToken);
if (discordClientId) updateOrAdd('DISCORD_CLIENT_ID', discordClientId);
updateOrAdd('TMDB_API_KEY', tmdbKey);
updateOrAdd('DB_TYPE', dbType);
if (dbType === 'sqlite') {
updateOrAdd('DB_FILE', dbName+".sqlite");
updateOrAdd('DB_PATH', dbConfig.filename);
} else {
updateOrAdd('DB_HOST', dbConfig.host);
updateOrAdd('DB_USER', dbConfig.user);
updateOrAdd('DB_PASS', dbConfig.password);
}
updateOrAdd('DB_NAME', dbName);
updateOrAdd('PORT', port);
updateOrAdd('CONFIG_DIR', CONFIG_DIR);
updateOrAdd('DATA_DIR', DATA_DIR);
// database creation
try {
console.log('\nCreating database tables...');
let config = { dbType, dbConfig };
await createTables(config);
console.log('Database configured.');
} catch (err) {
//res.status(500).send(`<pre>Database error:\n${err.stack}</pre>`);
console.error('Database error:', err.stack);
process.exit(1);
return;
}
}
rl.close();
console.log('\nSetup complete.');
if (discordClientId) {
console.log(`\nInvite your bot with this link:\nhttps://discord.com/oauth2/authorize?client_id=${discordClientId}&scope=bot&permissions=274877975552`);
}
}
//main();
export { runSetup };