diff --git a/README.md b/README.md index 22fd403..9527087 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ ComfyUI Prompt Manager functions as a drop-in replacement for ComfyUI's standard - **🔍 Metadata Viewer**: Launch standalone PNG analysis tool - **📸 Scan Images**: Bulk scan output directories for ComfyUI images - **💾 Backup/Restore**: Database backup and recovery operations - - **🔧 Maintenance**: Database optimization and cleanup tools + - **🔧 Maintenance**: Database optimization and cleanup tools including orphaned prompt removal - **📋 Logs**: Comprehensive logging system with download capability - **🔍 Diagnostics**: System health checks and troubleshooting - **Export Tools**: Download prompts and metadata in various formats @@ -99,10 +99,11 @@ ComfyUI Prompt Manager functions as a drop-in replacement for ComfyUI's standard - **SQLite backend** for reliable local storage - **Automatic schema creation** and management -- **Database optimization** with proper indexing +- **Database optimization** with proper indexing and maintenance tools - **Export functionality** to JSON or CSV formats - **Backup and restore** capabilities - **Relationship tracking** between prompts and generated images +- **Orphaned prompt cleanup** to remove prompts without linked images ## Installation @@ -216,6 +217,21 @@ The comprehensive web interface provides: - **Settings Panel**: Configure auto-save and display options - **Diagnostics**: System health checks and troubleshooting +### 🔧 Database Maintenance + +Keep your database optimized with built-in maintenance tools: + +1. **Open the admin dashboard** and click **"🔧 Maintenance"** +2. **Select maintenance operations**: + - **Remove Duplicates**: Find and merge duplicate prompts while preserving images + - **Vacuum Database**: Optimize database file size and performance + - **Clean Orphaned Images**: Remove image records for missing files + - **🚮 Prune Orphaned Prompts**: Remove prompts that have no linked images + - **Check Consistency**: Verify database integrity and relationships + - **Database Statistics**: Generate detailed database reports +3. **Run selected operations** and monitor progress in real-time +4. **Review results** showing detailed information about each operation + ### Database Location By default, the database is saved as `example_prompts.db` in the node directory. This file contains all your prompts and linked images and can be backed up or shared. @@ -558,6 +574,7 @@ MIT License - see LICENSE file for details. - **🖼️ Integrated Metadata Panel**: Real-time workflow analysis in the image viewer - **📸 Bulk Image Scanning**: Mass import and analysis of existing ComfyUI output directories - **🛠️ System Management Suite**: Complete backup, restore, maintenance, and diagnostic tools +- **🚮 Orphaned Prompt Cleanup**: Remove prompts that have no linked images for database optimization - **📋 Advanced Logging**: Comprehensive logging system with web-based log viewer - **🎨 Enhanced Admin Dashboard**: Modern dark theme with improved UX and management tools - **🔧 Robust Error Handling**: Advanced PNG parsing with NaN value cleaning and error recovery diff --git a/py/api.py b/py/api.py index 4b96101..1c7c0a1 100644 --- a/py/api.py +++ b/py/api.py @@ -1582,6 +1582,42 @@ class PromptManagerAPI: 'message': 'Failed to get database statistics' } + # Prune orphaned prompts (prompts with no linked images) + if 'prune_orphaned_prompts' in operations: + try: + with self.db.model.get_connection() as conn: + # Find prompts that have no images linked to them + cursor = conn.execute(""" + SELECT p.id + FROM prompts p + LEFT JOIN generated_images gi ON p.id = gi.prompt_id + WHERE gi.prompt_id IS NULL + """) + orphaned_prompts = cursor.fetchall() + orphaned_count = len(orphaned_prompts) + + if orphaned_count > 0: + # Delete the orphaned prompts + orphaned_ids = [row['id'] for row in orphaned_prompts] + placeholders = ','.join(['?'] * len(orphaned_ids)) + cursor = conn.execute(f"DELETE FROM prompts WHERE id IN ({placeholders})", orphaned_ids) + conn.commit() + removed_count = cursor.rowcount + else: + removed_count = 0 + + results['prune_orphaned_prompts'] = { + 'success': True, + 'removed_count': removed_count, + 'message': f'Removed {removed_count} orphaned prompts (prompts with no linked images)' + } + except Exception as e: + results['prune_orphaned_prompts'] = { + 'success': False, + 'error': str(e), + 'message': 'Failed to prune orphaned prompts' + } + # Check for consistency issues if 'check_consistency' in operations: try: diff --git a/web/admin.html b/web/admin.html index 69c76b8..55c576a 100644 --- a/web/admin.html +++ b/web/admin.html @@ -112,9 +112,14 @@ + + - -
+ +
+
+
+
@@ -201,6 +206,7 @@ 🔍 Metadata
+
@@ -510,6 +516,14 @@
Generate detailed database statistics report
+ +
@@ -953,6 +967,8 @@ modal.addEventListener("click", (e) => { if (e.target === modal) { modal.classList.add("hidden"); + modal.classList.remove("flex"); + document.body.style.overflow = ""; } }); }); @@ -1290,11 +1306,13 @@ showModal(modalId) { document.getElementById(modalId).classList.remove("hidden"); document.getElementById(modalId).classList.add("flex"); + document.body.style.overflow = "hidden"; } hideModal(modalId) { document.getElementById(modalId).classList.add("hidden"); document.getElementById(modalId).classList.remove("flex"); + document.body.style.overflow = ""; } showSettingsModal() { @@ -2375,6 +2393,7 @@ `; document.body.appendChild(modal); + document.body.style.overflow = "hidden"; // Auto-select the text in the textarea const textarea = modal.querySelector('textarea'); @@ -2385,8 +2404,14 @@ modal.addEventListener('click', (e) => { if (e.target === modal) { modal.remove(); + document.body.style.overflow = ""; } }); + + // Also handle the close button + modal.querySelector('button').addEventListener('click', () => { + document.body.style.overflow = ""; + }); } // Scan functionality