feat(live): add language-aware flexible channel search (#23)
Add backend language detection, flexible live channel search, iptv-org catalog caching, and protected built-in EPG source registration. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
16
server/db.js
16
server/db.js
@ -1,6 +1,7 @@
|
||||
const fs = require('fs/promises');
|
||||
const path = require('path');
|
||||
const { existsSync, mkdirSync } = require('fs');
|
||||
const { ensureBuiltinSources } = require('./services/builtinEpgRegistry');
|
||||
|
||||
// Ensure data directory exists (sync is fine for startup)
|
||||
const dataDir = path.join(__dirname, '..', 'data');
|
||||
@ -17,25 +18,25 @@ async function loadDb() {
|
||||
try {
|
||||
const fileContent = await fs.readFile(dbPath, 'utf-8');
|
||||
const data = JSON.parse(fileContent);
|
||||
return {
|
||||
return ensureBuiltinSources({
|
||||
sources: data.sources || [],
|
||||
hiddenItems: data.hiddenItems || [],
|
||||
favorites: data.favorites || [],
|
||||
settings: data.settings || getDefaultSettings(),
|
||||
users: data.users || [],
|
||||
nextId: data.nextId || 1
|
||||
};
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
// File doesn't exist, return default
|
||||
return {
|
||||
return ensureBuiltinSources({
|
||||
sources: [],
|
||||
hiddenItems: [],
|
||||
favorites: [],
|
||||
settings: getDefaultSettings(),
|
||||
users: [],
|
||||
nextId: 1
|
||||
};
|
||||
});
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
@ -168,6 +169,11 @@ const sources = {
|
||||
const index = db.sources.findIndex(s => s.id === parseInt(id));
|
||||
if (index === -1) return null;
|
||||
|
||||
const existing = db.sources[index];
|
||||
if (existing.builtinKey) {
|
||||
const allowed = Object.keys(updates).every(key => key === 'enabled');
|
||||
if (!allowed) throw Object.assign(new Error('Built-in sources can only be enabled or disabled'), { code: 'BUILTIN_SOURCE_READONLY' });
|
||||
}
|
||||
db.sources[index] = {
|
||||
...db.sources[index],
|
||||
...updates,
|
||||
@ -179,6 +185,8 @@ const sources = {
|
||||
|
||||
async delete(id) {
|
||||
const db = await loadDb();
|
||||
const existing = db.sources.find(s => s.id === parseInt(id));
|
||||
if (existing?.builtinKey) throw Object.assign(new Error('Built-in sources cannot be removed'), { code: 'BUILTIN_SOURCE_PROTECTED' });
|
||||
db.sources = db.sources.filter(s => s.id !== parseInt(id));
|
||||
// Also delete related hidden items and favorites
|
||||
db.hiddenItems = db.hiddenItems.filter(h => h.source_id !== parseInt(id));
|
||||
|
||||
Reference in New Issue
Block a user