|
|
|
|
@ -723,6 +723,17 @@ class MusicDatabase:
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
# HiFi API instances table
|
|
|
|
|
cursor.execute("""
|
|
|
|
|
CREATE TABLE IF NOT EXISTS hifi_instances (
|
|
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
|
|
url TEXT NOT NULL UNIQUE,
|
|
|
|
|
priority INTEGER NOT NULL DEFAULT 0,
|
|
|
|
|
enabled INTEGER NOT NULL DEFAULT 1,
|
|
|
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
|
|
|
)
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
conn.commit()
|
|
|
|
|
logger.info("Database initialized successfully")
|
|
|
|
|
|
|
|
|
|
@ -11594,6 +11605,88 @@ class MusicDatabase:
|
|
|
|
|
logger.error(f"Error getting issue counts: {e}")
|
|
|
|
|
return {'open': 0, 'in_progress': 0, 'resolved': 0, 'dismissed': 0, 'total': 0}
|
|
|
|
|
|
|
|
|
|
# ===================== HiFi Instances =====================
|
|
|
|
|
|
|
|
|
|
def get_hifi_instances(self) -> List[Dict[str, Any]]:
|
|
|
|
|
"""Get all enabled HiFi instances ordered by priority."""
|
|
|
|
|
try:
|
|
|
|
|
conn = self._get_connection()
|
|
|
|
|
cursor = conn.cursor()
|
|
|
|
|
cursor.execute("SELECT url, priority, enabled FROM hifi_instances WHERE enabled = 1 ORDER BY priority ASC, id ASC")
|
|
|
|
|
return [dict(row) for row in cursor.fetchall()]
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"Error getting HiFi instances: {e}")
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
def get_all_hifi_instances(self) -> List[Dict[str, Any]]:
|
|
|
|
|
"""Get all HiFi instances (including disabled) ordered by priority."""
|
|
|
|
|
try:
|
|
|
|
|
conn = self._get_connection()
|
|
|
|
|
cursor = conn.cursor()
|
|
|
|
|
cursor.execute("SELECT url, priority, enabled FROM hifi_instances ORDER BY priority ASC, id ASC")
|
|
|
|
|
return [dict(row) for row in cursor.fetchall()]
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"Error getting all HiFi instances: {e}")
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
def add_hifi_instance(self, url: str, priority: int = 0) -> bool:
|
|
|
|
|
"""Add a new HiFi instance."""
|
|
|
|
|
try:
|
|
|
|
|
conn = self._get_connection()
|
|
|
|
|
cursor = conn.cursor()
|
|
|
|
|
cursor.execute(
|
|
|
|
|
"INSERT OR IGNORE INTO hifi_instances (url, priority, enabled) VALUES (?, ?, 1)",
|
|
|
|
|
(url, priority)
|
|
|
|
|
)
|
|
|
|
|
conn.commit()
|
|
|
|
|
return cursor.rowcount > 0
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"Error adding HiFi instance: {e}")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def remove_hifi_instance(self, url: str) -> bool:
|
|
|
|
|
"""Remove a HiFi instance."""
|
|
|
|
|
try:
|
|
|
|
|
conn = self._get_connection()
|
|
|
|
|
cursor = conn.cursor()
|
|
|
|
|
cursor.execute("DELETE FROM hifi_instances WHERE url = ?", (url,))
|
|
|
|
|
conn.commit()
|
|
|
|
|
return cursor.rowcount > 0
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"Error removing HiFi instance: {e}")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def reorder_hifi_instances(self, urls: List[str]) -> bool:
|
|
|
|
|
"""Update priorities based on the given URL order."""
|
|
|
|
|
try:
|
|
|
|
|
conn = self._get_connection()
|
|
|
|
|
cursor = conn.cursor()
|
|
|
|
|
for i, url in enumerate(urls):
|
|
|
|
|
cursor.execute("UPDATE hifi_instances SET priority = ? WHERE url = ?", (i, url))
|
|
|
|
|
conn.commit()
|
|
|
|
|
return True
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"Error reordering HiFi instances: {e}")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def seed_hifi_instances(self, default_urls: List[str]) -> None:
|
|
|
|
|
"""Insert default instances if the table is empty."""
|
|
|
|
|
try:
|
|
|
|
|
conn = self._get_connection()
|
|
|
|
|
cursor = conn.cursor()
|
|
|
|
|
cursor.execute("SELECT COUNT(*) as cnt FROM hifi_instances")
|
|
|
|
|
count = cursor.fetchone()['cnt']
|
|
|
|
|
if count == 0:
|
|
|
|
|
for i, url in enumerate(default_urls):
|
|
|
|
|
cursor.execute(
|
|
|
|
|
"INSERT OR IGNORE INTO hifi_instances (url, priority, enabled) VALUES (?, ?, 1)",
|
|
|
|
|
(url, i)
|
|
|
|
|
)
|
|
|
|
|
conn.commit()
|
|
|
|
|
logger.info(f"Seeded {len(default_urls)} default HiFi instances")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"Error seeding HiFi instances: {e}")
|
|
|
|
|
|
|
|
|
|
# Thread-safe singleton pattern for database access
|
|
|
|
|
_database_instances: Dict[int, MusicDatabase] = {} # Thread ID -> Database instance
|
|
|
|
|
_database_lock = threading.Lock()
|
|
|
|
|
|