import { Injectable } from '@nestjs/common'; import Database from 'better-sqlite3'; import fs from 'fs'; import path from 'path'; @Injectable() export class DatasetsService { private dbPath: string; constructor() { // Find project root by traversing up from current directory until we find the root package.json let projectRoot = process.cwd(); while (projectRoot !== path.dirname(projectRoot)) { if (fs.existsSync(path.join(projectRoot, 'package.json'))) { try { const pkg = JSON.parse( fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf-8'), ); if (pkg.name === 'watch-finished-turbo') { break; } } catch (e) { // ignore } } projectRoot = path.dirname(projectRoot); } this.dbPath = path.resolve(projectRoot, 'data/database.db'); } /** * Returns all enabled dataset paths from the settings.datasets key in the database * Only includes paths from datasets that are not explicitly disabled */ getEnabledDatasetPaths(): string[] { const db = new Database(this.dbPath, { readonly: true }); const row = db .prepare('SELECT value FROM settings WHERE key = ?') .get('datasets') as { value?: string } | undefined; db.close(); if (!row || !row.value) return []; let datasets; try { datasets = JSON.parse(row.value); } catch (e) { return []; } // Each dataset (kids, pr0n, tvshows, etc) is an object, each value is a config object // Find all paths in all datasets const paths: string[] = []; for (const datasetName of Object.keys(datasets)) { const datasetObj = datasets[datasetName]; if (typeof datasetObj === 'object' && datasetObj !== null) { // Check if dataset is explicitly disabled (handles false, "false", 0, "0", etc.) const isDisabled = datasetObj.enabled === false || datasetObj.enabled === 'false' || datasetObj.enabled === 0 || datasetObj.enabled === '0'; if (!isDisabled) { for (const pathKey of Object.keys(datasetObj)) { if (pathKey !== 'enabled') { // Skip the enabled property itself paths.push(pathKey); } } } } } return paths; } /** * Returns all dataset names from the settings.datasets key in the database * Includes both enabled and disabled datasets */ getAllDatasetNames(): string[] { const db = new Database(this.dbPath, { readonly: true }); const row = db .prepare('SELECT value FROM settings WHERE key = ?') .get('datasets') as { value?: string } | undefined; db.close(); if (!row || !row.value) return []; let datasets; try { datasets = JSON.parse(row.value); } catch (e) { return []; } return Object.keys(datasets); } /** * Returns the full dataset configuration from settings */ getDatasetConfig(): Record { const db = new Database(this.dbPath, { readonly: true }); const row = db .prepare('SELECT value FROM settings WHERE key = ?') .get('datasets') as { value?: string } | undefined; db.close(); if (!row || !row.value) return {}; try { return JSON.parse(row.value); } catch (e) { return {}; } } /** * Returns the exts array for a specific dataset */ getDatasetExts(datasetName: string): string[] | null { const config = this.getDatasetConfig(); const datasetConfig = config[datasetName]; if (!datasetConfig || !datasetConfig.exts) { return null; } return Array.isArray(datasetConfig.exts) ? datasetConfig.exts : null; } }