| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- import { Injectable } from '@nestjs/common';
- import Database from 'better-sqlite3';
- import fs from 'fs';
- import path from 'path';
- @Injectable()
- export class ConfigService {
- private dataDir: string;
- private unifiedDbPath: 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.dataDir = path.resolve(projectRoot, 'data');
- this.unifiedDbPath = path.resolve(this.dataDir, 'database.db');
- console.log('ConfigService: Database path:', this.unifiedDbPath);
- console.log('ConfigService: Project root:', projectRoot);
- console.log('ConfigService: Current working directory:', process.cwd());
- // Ensure database and tables exist
- const db = new Database(this.unifiedDbPath);
- db.exec(`
- CREATE TABLE IF NOT EXISTS settings (
- key TEXT PRIMARY KEY,
- value TEXT
- );
- `);
- db.close();
- }
- getSettings(key?: string, defaultValue?: any): any {
- try {
- const db = new Database(this.unifiedDbPath, { readonly: true });
- if (key) {
- const row = db
- .prepare('SELECT value FROM settings WHERE key = ?')
- .get(key) as { value?: string } | undefined;
- db.close();
- return row && row.value !== undefined
- ? JSON.parse(row.value)
- : defaultValue;
- } else {
- const rows = db
- .prepare('SELECT key, value FROM settings')
- .all() as Array<{ key: string; value: string }>;
- db.close();
- const settings: Record<string, any> = {};
- for (const row of rows) {
- settings[row.key] = JSON.parse(row.value);
- }
- return settings;
- }
- } catch (e) {
- if (key) return defaultValue;
- return {};
- }
- }
- getConfigFile(name: string): any {
- // For datasources: name = kids.json, pr0n.json, tvshows.json
- const base = name.replace(/\.json$/, '');
- try {
- const db = new Database(this.unifiedDbPath, { readonly: true });
- const row = db
- .prepare('SELECT data FROM datasets WHERE name = ?')
- .get(base) as { data?: string } | undefined;
- db.close();
- return row && row.data !== undefined ? JSON.parse(row.data) : null;
- } catch (e) {
- return null;
- }
- }
- listConfigs(): string[] {
- // Return all dataset names as .json (regardless of enabled)
- try {
- const db = new Database(this.unifiedDbPath, { readonly: true });
- const rows = db.prepare('SELECT name FROM datasets').all() as Array<{
- name: string;
- }>;
- db.close();
- // Debug: log found rows
- if (rows.length === 0) {
- console.warn('No configs found in datasets table');
- }
- return rows.map((row) => row.name + '.json');
- } catch (e) {
- console.error('Error in listConfigs:', e);
- return [];
- }
- }
- setSettings(settings: Record<string, any>): boolean {
- try {
- const db = new Database(this.unifiedDbPath);
- const insert = db.prepare(
- 'INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)',
- );
- for (const [key, value] of Object.entries(settings)) {
- // If value is already a JSON string, save it as-is
- // Otherwise, stringify it
- let valueToSave: string;
- if (typeof value === 'string') {
- // Check if it's already valid JSON
- try {
- JSON.parse(value);
- valueToSave = value;
- } catch {
- // Not valid JSON, stringify it
- valueToSave = JSON.stringify(value);
- }
- } else {
- // It's an object, stringify it
- valueToSave = JSON.stringify(value);
- }
- insert.run(key, valueToSave);
- }
- db.close();
- return true;
- } catch (e) {
- console.error('Error setting settings:', e);
- return false;
- }
- }
- deleteSetting(key: string): boolean {
- try {
- const db = new Database(this.unifiedDbPath);
- const result = db.prepare('DELETE FROM settings WHERE key = ?').run(key);
- db.close();
- return result.changes > 0;
- } catch (e) {
- console.error('Error deleting setting:', e);
- return false;
- }
- }
- }
|