const minisrv_service_file = true; if (!minisrv_config.services['mms']) { throw ("ERROR: mms service not defined in config!"); } const mmsVaults = []; // Check mms service vault for .wma, .wmv, and .asf files if (minisrv_config.config.ServiceVaults) { Object.keys(minisrv_config.config.ServiceVaults).forEach(function (k) { const service_vault = wtvshared.getAbsolutePath(minisrv_config.config.ServiceVaults[k]); mmsVaults.push(service_vault + "/mms"); }) } else { throw ("ERROR: No Service Vaults defined!"); } // Detect subdirectory structure of this catchall.js file and strip it from requests // e.g., if at /ServiceVault/wtv-music/asxgen/catchall.js, extract "ragen" // if at /ServiceVault/wtv-music/asx/gen/catchall.js, extract "asx/gen" let subDirPath = ''; const currentDir = path.dirname(__filename); const serviceVaultIdx = currentDir.indexOf('ServiceVault'); console.log("DEBUG: currentDir =", currentDir, "serviceVaultIdx =", serviceVaultIdx); if (serviceVaultIdx !== -1) { const afterVault = currentDir.substring(serviceVaultIdx + 12); // 12 = length of 'ServiceVault' console.log("DEBUG: afterVault =", afterVault); const parts = afterVault.split(path.sep).filter(p => p); console.log("DEBUG: parts =", parts); if (parts.length > 1) { // parts[0] is the service name (e.g., 'wtv-music'), parts[1+] are the subdirs const subdirs = parts.slice(1); subDirPath = '/' + subdirs.join('/'); } } const url_path = request_headers.request_url.split('?')[0]; const pathParts = url_path.split('/').filter(p => p); const serviceName = pathParts.length > 0 ? pathParts[0] : ''; let remainingPath = '/' + pathParts.slice(1).join('/'); const hadTrailingSlash = request_headers.request_url.endsWith('/'); let strippedSubDir = ''; // Store what was stripped for link rebuilding // Strip the subdirectory structure from the request path if (subDirPath) { if (remainingPath.startsWith(subDirPath + '/')) { // Has something after the subdirectory, e.g., /ragen/classicrom strippedSubDir = subDirPath; remainingPath = remainingPath.substring(subDirPath.length); } else if (remainingPath === subDirPath || remainingPath === subDirPath + '/') { // Just the subdirectory itself, e.g., /ragen or /ragen/ strippedSubDir = subDirPath; remainingPath = '/'; } } // Restore trailing slash if original URL had one if (hadTrailingSlash && !remainingPath.endsWith('/')) { remainingPath += '/'; } const filename = remainingPath.endsWith('/') ? '' : remainingPath.split('/').pop().replace('.asx', ''); const directory = remainingPath.endsWith('/') ? remainingPath.replace(/\/$/, '') : remainingPath.substring(0, remainingPath.lastIndexOf('/')); let fileFound = false; const extensions = ['.asf', '.wma', '.wmv']; let resolvedPath = null; // Check if request is for a directory listing (no filename or ends with /) if (!filename || (request_headers.request_url.endsWith('/') && minisrv_config.services['mms'].allow_indexing !== false)) { const listingDir = filename ? directory : directory || '/'; const allFiles = []; for (const mmsVault of mmsVaults) { const targetDir = path.join(mmsVault, listingDir); if (fs.existsSync(targetDir) && fs.statSync(targetDir).isDirectory()) { const files = fs.readdirSync(targetDir); files.forEach(file => { const fullPath = path.join(targetDir, file); if (fs.statSync(fullPath).isFile() && (file.endsWith('.wma') || file.endsWith('.wmv') || file.endsWith('.asf'))) { const baseFileName = file.substring(0, file.lastIndexOf('.')); allFiles.push(baseFileName + '.asx'); } else if (fs.statSync(fullPath).isDirectory()) { allFiles.push(file + '/'); } }); } } if (allFiles.length > 0) { headers = `200 OK Content-type: text/html`; data = `