97 lines
3.0 KiB
TypeScript
97 lines
3.0 KiB
TypeScript
import { exec } from 'child_process';
|
|
import { promisify } from 'util';
|
|
import * as fs from 'fs/promises';
|
|
import * as path from 'path';
|
|
import * as os from 'os';
|
|
|
|
const execAsync = promisify(exec);
|
|
|
|
export type ToolStatus = {
|
|
name: string;
|
|
exists: boolean;
|
|
path?: string;
|
|
};
|
|
|
|
export type ToolCheckResult = {
|
|
allExists: boolean;
|
|
tools: ToolStatus[];
|
|
mkbrrPresetExists?: boolean;
|
|
};
|
|
|
|
const REQUIRED_TOOLS = ['sox', 'mkbrr', 'salmon'];
|
|
|
|
async function checkMkbrrPreset(): Promise<boolean> {
|
|
const tempDir = os.tmpdir();
|
|
const dummyFile = path.join(tempDir, `mkbrr_check_${Date.now()}`);
|
|
const outputFile = `${dummyFile}.torrent`;
|
|
const presetName = 'red';
|
|
|
|
try {
|
|
// Create a dummy file
|
|
await fs.writeFile(dummyFile, 'test');
|
|
|
|
// Try to create a torrent with the red preset
|
|
// We expect this to fail if the preset doesn't exist
|
|
// If it succeeds (or fails for other reasons but finds the preset), we're good
|
|
try {
|
|
// Explicitly set output file to ensure we know where it is for cleanup
|
|
await execAsync(`mkbrr create "${dummyFile}" -P ${presetName} -o "${outputFile}"`);
|
|
return true;
|
|
} catch (error: any) {
|
|
// Check for the specific error message indicating the preset is missing
|
|
// We use the presetName variable so this logic holds if we change the preset for testing
|
|
if (error.stderr && error.stderr.includes(`preset "${presetName}" not found`)) {
|
|
return false;
|
|
}
|
|
// If it failed for another reason (e.g. file issue), but didn't complain about the preset,
|
|
// we assume the preset exists.
|
|
return true;
|
|
}
|
|
} catch (error) {
|
|
console.error('Error checking mkbrr preset:', error);
|
|
return false; // Fail safe
|
|
} finally {
|
|
// Cleanup
|
|
try {
|
|
await fs.unlink(dummyFile);
|
|
await fs.unlink(outputFile).catch(() => { }); // Ignore if torrent wasn't created
|
|
} catch (e) {
|
|
// Ignore cleanup errors
|
|
}
|
|
}
|
|
}
|
|
|
|
export async function checkTools(): Promise<ToolCheckResult> {
|
|
const results: ToolStatus[] = await Promise.all(
|
|
REQUIRED_TOOLS.map(async (tool) => {
|
|
try {
|
|
const { stdout } = await execAsync(`which ${tool}`);
|
|
return {
|
|
name: tool,
|
|
exists: true,
|
|
path: stdout.trim(),
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
name: tool,
|
|
exists: false,
|
|
};
|
|
}
|
|
})
|
|
);
|
|
|
|
const allExists = results.every((result) => result.exists);
|
|
|
|
let mkbrrPresetExists = true;
|
|
const mkbrrStatus = results.find(r => r.name === 'mkbrr');
|
|
if (mkbrrStatus && mkbrrStatus.exists) {
|
|
mkbrrPresetExists = await checkMkbrrPreset();
|
|
}
|
|
|
|
return {
|
|
allExists: allExists && mkbrrPresetExists,
|
|
tools: results,
|
|
mkbrrPresetExists,
|
|
};
|
|
}
|