diff --git a/__pycache__/app.cpython-313.pyc b/__pycache__/app.cpython-313.pyc index 6b1dbbc..eccc867 100644 Binary files a/__pycache__/app.cpython-313.pyc and b/__pycache__/app.cpython-313.pyc differ diff --git a/app.py b/app.py index c965712..d368134 100644 --- a/app.py +++ b/app.py @@ -122,6 +122,62 @@ socketio = SocketIO(app) migrate = Migrate(app, db) +# Automatische Datenbankinitialisierung +@app.before_first_request +def initialize_app(): + """Initialisierung der Anwendung beim ersten Request""" + print("Initialisierung der Anwendung...") + with app.app_context(): + # Prüfen, ob die Datenbank existiert und initialisiert ist + try: + # Prüfen, ob Tabellen existieren + db.create_all() + + # Prüfen, ob Stammdaten vorhanden sind + if User.query.count() == 0: + print("Erstelle Standardbenutzer...") + create_default_users() + + if Category.query.count() == 0: + print("Erstelle Standardkategorien...") + create_default_categories() + + if MindMapNode.query.count() == 0 and Category.query.count() > 0: + print("Erstelle Beispiel-Mindmap...") + create_sample_mindmap() + + print("Datenbank wurde erfolgreich initialisiert.") + except Exception as e: + import traceback + print(f"Fehler bei der Datenbankinitialisierung: {e}") + print(traceback.format_exc()) + +def create_default_users(): + """Erstellt Standardbenutzer für die Anwendung""" + users = [ + { + 'username': 'admin', + 'email': 'admin@example.com', + 'password': 'admin', + 'role': 'admin' + }, + { + 'username': 'user', + 'email': 'user@example.com', + 'password': 'user', + 'role': 'user' + } + ] + + for user_data in users: + password = user_data.pop('password') + user = User(**user_data) + user.set_password(password) + db.session.add(user) + + db.session.commit() + print(f"{len(users)} Benutzer wurden erstellt.") + def create_default_categories(): """Erstellt die Standardkategorien für die Mindmap""" # Hauptkategorien @@ -1569,67 +1625,121 @@ def chat_with_assistant(): def check_database_query(user_message): """ - Überprüft, ob die Benutzeranfrage nach Datenbankinformationen sucht und extrahiert - relevante Daten aus der Datenbank. + Prüft, ob die Benutzeranfrage nach Datenbankinformationen sucht + und gibt relevante Informationen aus der Datenbank zurück. + + Returns: + (bool, str): Tupel aus (ist_db_anfrage, db_antwort) """ - context = [] + user_message = user_message.lower() - # Prüfen auf verschiedene Datenbankabfragemuster - if any(keyword in user_message.lower() for keyword in ['gedanken', 'thought', 'beitrag', 'inhalt']): - # Suche nach relevanten Gedanken - thoughts = Thought.query.filter( - db.or_( - Thought.title.ilike(f'%{word}%') for word in user_message.split() - if len(word) > 3 # Nur längere Wörter zur Suche verwenden - ) - ).limit(5).all() + # Schlüsselwörter, die auf eine Datenbankanfrage hindeuten + db_keywords = [ + 'wie viele', 'wieviele', 'anzahl', 'liste', 'zeige', 'zeig mir', 'datenbank', + 'statistik', 'stats', 'benutzer', 'gedanken', 'kategorien', 'mindmap', + 'neueste', 'kürzlich', 'gespeichert', 'zähle', 'suche nach', 'finde' + ] + + # Überprüfen, ob die Nachricht eine Datenbankanfrage sein könnte + is_db_query = any(keyword in user_message for keyword in db_keywords) + + if not is_db_query: + return False, "" + + # Datenbank-Antwort vorbereiten + response = "Hier sind Informationen aus der Datenbank:\n\n" + + try: + # 1. Benutzer-Statistiken + if any(kw in user_message for kw in ['benutzer', 'user', 'nutzer']): + user_count = User.query.count() + active_users = User.query.filter_by(is_active=True).count() + admins = User.query.filter_by(role='admin').count() + + response += f"**Benutzer-Statistiken:**\n" + response += f"- Gesamt: {user_count} Benutzer\n" + response += f"- Aktiv: {active_users} Benutzer\n" + response += f"- Administratoren: {admins} Benutzer\n\n" - if thoughts: - context.append("Relevante Gedanken:") - for thought in thoughts: - context.append(f"- Titel: {thought.title}") - context.append(f" Zusammenfassung: {thought.abstract if thought.abstract else 'Keine Zusammenfassung verfügbar'}") - context.append(f" Keywords: {thought.keywords if thought.keywords else 'Keine Keywords verfügbar'}") - context.append("") - - if any(keyword in user_message.lower() for keyword in ['kategorie', 'category', 'themengebiet', 'bereich']): - # Suche nach Kategorien - categories = Category.query.filter( - db.or_( - Category.name.ilike(f'%{word}%') for word in user_message.split() - if len(word) > 3 - ) - ).limit(5).all() + # 2. Gedanken-Statistiken + if any(kw in user_message for kw in ['gedanken', 'thought', 'inhalt']): + thought_count = Thought.query.count() + + if thought_count > 0: + avg_rating = db.session.query(func.avg(ThoughtRating.relevance_score)).scalar() or 0 + avg_rating = round(avg_rating, 1) + + recent_thoughts = Thought.query.order_by(Thought.created_at.desc()).limit(5).all() + + response += f"**Gedanken-Statistiken:**\n" + response += f"- Gesamt: {thought_count} Gedanken\n" + response += f"- Durchschnittliche Bewertung: {avg_rating}/5\n\n" + + if recent_thoughts: + response += "**Neueste Gedanken:**\n" + for thought in recent_thoughts: + response += f"- {thought.title} (von {thought.author.username})\n" + response += "\n" + else: + response += "Es sind noch keine Gedanken in der Datenbank gespeichert.\n\n" - if categories: - context.append("Relevante Kategorien:") - for category in categories: - context.append(f"- Name: {category.name}") - context.append(f" Beschreibung: {category.description}") - context.append("") - - if any(keyword in user_message.lower() for keyword in ['mindmap', 'karte', 'visualisierung']): - # Suche nach öffentlichen Mindmaps - mindmap_nodes = MindMapNode.query.filter( - db.and_( - MindMapNode.is_public == True, - db.or_( - MindMapNode.name.ilike(f'%{word}%') for word in user_message.split() - if len(word) > 3 - ) - ) - ).limit(5).all() + # 3. Kategorien-Statistiken + if any(kw in user_message for kw in ['kategorie', 'category', 'thema']): + category_count = Category.query.filter_by(parent_id=None).count() + subcategory_count = Category.query.filter(Category.parent_id != None).count() + + response += f"**Kategorien-Statistiken:**\n" + response += f"- Hauptkategorien: {category_count}\n" + response += f"- Unterkategorien: {subcategory_count}\n\n" + + main_categories = Category.query.filter_by(parent_id=None).all() + if main_categories: + response += "**Hauptkategorien:**\n" + for category in main_categories: + subcats = Category.query.filter_by(parent_id=category.id).count() + response += f"- {category.name} ({subcats} Unterkategorien)\n" + response += "\n" - if mindmap_nodes: - context.append("Relevante Mindmap-Knoten:") - for node in mindmap_nodes: - context.append(f"- Name: {node.name}") - context.append(f" Beschreibung: {node.description if node.description else 'Keine Beschreibung verfügbar'}") - if node.category: - context.append(f" Kategorie: {node.category.name}") - context.append("") - - return "\n".join(context) if context else "" + # 4. Mindmap-Statistiken + if any(kw in user_message for kw in ['mindmap', 'karte', 'map', 'knoten']): + public_nodes = MindMapNode.query.count() + user_mindmaps = UserMindmap.query.count() + + response += f"**Mindmap-Statistiken:**\n" + response += f"- Öffentliche Knoten: {public_nodes}\n" + response += f"- Benutzerdefinierte Mindmaps: {user_mindmaps}\n\n" + + if user_mindmaps > 0: + recent_mindmaps = UserMindmap.query.order_by(UserMindmap.created_at.desc()).limit(3).all() + + if recent_mindmaps: + response += "**Neueste Mindmaps:**\n" + for mindmap in recent_mindmaps: + response += f"- {mindmap.name} (von {mindmap.user.username})\n" + response += "\n" + + # Wenn keine spezifischen Daten angefordert wurden, allgemeine Übersicht geben + if not any(kw in user_message for kw in ['benutzer', 'user', 'gedanken', 'thought', 'kategorie', 'category', 'mindmap']): + users = User.query.count() + thoughts = Thought.query.count() + categories = Category.query.count() + nodes = MindMapNode.query.count() + user_maps = UserMindmap.query.count() + + response += f"**Übersicht über die Datenbank:**\n" + response += f"- Benutzer: {users}\n" + response += f"- Gedanken: {thoughts}\n" + response += f"- Kategorien: {categories}\n" + response += f"- Mindmap-Knoten: {nodes}\n" + response += f"- Benutzerdefinierte Mindmaps: {user_maps}\n" + + return True, response + + except Exception as e: + import traceback + print(f"Fehler bei der Datenbankabfrage: {e}") + print(traceback.format_exc()) + return True, "Es ist ein Fehler bei der Abfrage der Datenbank aufgetreten. Bitte versuchen Sie es später erneut." @app.route('/search') def search_thoughts_page():