Files
Homepage/database.py
Aodhan Collins f6528b2590 Stats fix
2025-07-27 02:10:52 +01:00

204 lines
7.1 KiB
Python

import sqlite3
import os
import json
from datetime import datetime
class DatabaseManager:
def __init__(self, db_path='dashboard.db'):
self.db_path = db_path
self.init_database()
def init_database(self):
"""Initialize the database with required tables"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
# Create applications table for storing custom app data
cursor.execute('''
CREATE TABLE IF NOT EXISTS applications (
id INTEGER PRIMARY KEY AUTOINCREMENT,
container_id TEXT UNIQUE,
container_name TEXT NOT NULL,
display_name TEXT,
icon TEXT DEFAULT 'fas fa-cube',
color TEXT DEFAULT 'gray',
description TEXT,
url TEXT,
status TEXT DEFAULT 'unknown',
custom_data TEXT, -- JSON for additional custom fields
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# Add status column if it doesn't exist (for backward compatibility)
try:
cursor.execute("ALTER TABLE applications ADD COLUMN status TEXT DEFAULT 'unknown'")
print("Added status column to applications table")
except sqlite3.OperationalError as e:
if "duplicate column name" not in str(e).lower():
print(f"Note: {e}")
# Create settings table for general configuration
cursor.execute('''
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
def get_connection(self):
"""Get database connection"""
return sqlite3.connect(self.db_path)
def upsert_application(self, container_data):
"""Insert or update application data"""
conn = self.get_connection()
cursor = conn.cursor()
container_id = container_data.get('id')
container_name = container_data.get('name')
display_name = container_data.get('display_name', container_name)
icon = container_data.get('icon', 'fas fa-cube')
color = container_data.get('color', 'gray')
description = container_data.get('description', container_data.get('image', ''))
url = container_data.get('url', '#')
custom_data = json.dumps(container_data.get('custom_data', {}))
cursor.execute('''
INSERT OR REPLACE INTO applications
(container_id, container_name, display_name, icon, color, description, url, custom_data, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
''', (container_id, container_name, display_name, icon, color, description, url, custom_data))
conn.commit()
conn.close()
def get_applications(self):
"""Get all applications"""
conn = self.get_connection()
cursor = conn.cursor()
cursor.execute('''
SELECT container_id, container_name, display_name, icon, color, description, url, custom_data
FROM applications
ORDER BY display_name
''')
results = cursor.fetchall()
conn.close()
applications = []
for row in results:
app = {
'container_id': row[0],
'container_name': row[1],
'display_name': row[2],
'icon': row[3],
'color': row[4],
'description': row[5],
'url': row[6],
'custom_data': json.loads(row[7]) if row[7] else {}
}
applications.append(app)
return applications
def get_application(self, container_id):
"""Get specific application by container_id"""
conn = self.get_connection()
cursor = conn.cursor()
cursor.execute('''
SELECT container_id, container_name, display_name, icon, color, description, url, custom_data
FROM applications
WHERE container_id = ?
''', (container_id,))
result = cursor.fetchone()
conn.close()
if result:
return {
'container_id': result[0],
'container_name': result[1],
'display_name': result[2],
'icon': result[3],
'color': result[4],
'description': result[5],
'url': result[6],
'custom_data': json.loads(result[7]) if result[7] else {}
}
return None
def update_application(self, container_id, updates):
"""Update application data"""
conn = self.get_connection()
cursor = conn.cursor()
set_clause = []
values = []
for key, value in updates.items():
if key == 'custom_data':
value = json.dumps(value)
set_clause.append(f"{key} = ?")
values.append(value)
if set_clause:
set_clause.append("updated_at = CURRENT_TIMESTAMP")
values.append(container_id)
query = f"UPDATE applications SET {', '.join(set_clause)} WHERE container_id = ?"
cursor.execute(query, values)
conn.commit()
conn.close()
def delete_application(self, container_id):
"""Delete application"""
conn = self.get_connection()
cursor = conn.cursor()
cursor.execute('DELETE FROM applications WHERE container_id = ?', (container_id,))
conn.commit()
conn.close()
def sync_with_containers(self, containers):
"""Sync applications with current containers"""
conn = self.get_connection()
cursor = conn.cursor()
# Get existing container IDs
cursor.execute('SELECT container_id FROM applications')
existing_ids = {row[0] for row in cursor.fetchall()}
# Insert new containers
for container in containers:
container_id = container.get('id')
if container_id not in existing_ids:
self.upsert_application({
'id': container_id,
'name': container.get('name', ''),
'description': container.get('image', ''),
'url': self._generate_url_from_ports(container.get('ports', []))
})
conn.close()
def _generate_url_from_ports(self, ports):
"""Generate URL from container ports"""
if ports and len(ports) > 0:
port = ports[0]
return f"http://localhost:{port.get('host_port', port.get('private_port', 80))}"
return '#'
# Global database instance
db = DatabaseManager()