✨ feat: update app logic and improve mindmap functionality
This commit is contained in:
876
app.py
876
app.py
@@ -26,6 +26,7 @@ import sqlalchemy
|
||||
import ssl
|
||||
import certifi
|
||||
import os
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
# Modelle importieren
|
||||
from models import (
|
||||
@@ -2342,749 +2343,184 @@ if __name__ == '__main__':
|
||||
db.create_all()
|
||||
socketio.run(app, debug=True, host='0.0.0.0')
|
||||
|
||||
@app.route('/api/mindmap/science')
|
||||
def get_science_mindmap():
|
||||
"""
|
||||
API-Endpunkt für die Wissenschaft-Mindmap
|
||||
"""
|
||||
def get_category_mindmap_data(category_name):
|
||||
"""Generische Funktion zum Abrufen der Mindmap-Daten für eine Kategorie."""
|
||||
try:
|
||||
# Stelle sicher, dass wir Kategorien haben
|
||||
if Category.query.count() == 0:
|
||||
create_default_categories()
|
||||
# Kategorie mit allen Unterkategorien in einer Abfrage laden
|
||||
category = Category.query.filter_by(name=category_name).options(
|
||||
joinedload(Category.children)
|
||||
).first_or_404()
|
||||
|
||||
# Überprüfe, ob wir bereits einen "Wissen"-Knoten haben
|
||||
wissen_node = MindMapNode.query.filter_by(name="Wissen").first()
|
||||
# Basis-Knoten erstellen
|
||||
nodes = [{
|
||||
'id': f'cat_{category.id}',
|
||||
'name': category.name,
|
||||
'description': category.description or '',
|
||||
'color_code': category.color_code or '#9F7AEA',
|
||||
'is_center': True,
|
||||
'has_children': bool(category.children),
|
||||
'icon': category.icon or 'fa-solid fa-circle'
|
||||
}]
|
||||
|
||||
# Wenn kein "Wissen"-Knoten existiert, erstelle ihn
|
||||
if not wissen_node:
|
||||
wissen_node = MindMapNode(
|
||||
name="Wissen",
|
||||
description="Zentrale Wissensbasis",
|
||||
color_code="#4299E1",
|
||||
is_public=True
|
||||
)
|
||||
db.session.add(wissen_node)
|
||||
db.session.commit()
|
||||
# Unterkategorien hinzufügen
|
||||
for subcat in category.children:
|
||||
nodes.append({
|
||||
'id': f'cat_{subcat.id}',
|
||||
'name': subcat.name,
|
||||
'description': subcat.description or '',
|
||||
'color_code': subcat.color_code or '#9F7AEA',
|
||||
'category': category_name,
|
||||
'has_children': bool(subcat.children),
|
||||
'icon': subcat.icon or 'fa-solid fa-circle'
|
||||
})
|
||||
|
||||
# Hole alle Kategorien und Knoten
|
||||
categories = Category.query.filter_by(parent_id=None).all()
|
||||
category_tree = [build_category_tree(cat) for cat in categories]
|
||||
|
||||
# Hole alle Mindmap-Knoten außer dem "Wissen"-Knoten
|
||||
nodes = MindMapNode.query.filter(MindMapNode.id != wissen_node.id).all()
|
||||
|
||||
# Vorbereiten der Node- und Edge-Arrays für die Antwort
|
||||
node_data = []
|
||||
edge_data = []
|
||||
|
||||
# Zuerst den "Wissen"-Knoten hinzufügen
|
||||
node_data.append({
|
||||
'id': wissen_node.id,
|
||||
'name': wissen_node.name,
|
||||
'description': wissen_node.description or '',
|
||||
'color_code': wissen_node.color_code or '#4299E1',
|
||||
'thought_count': len(wissen_node.thoughts),
|
||||
'category_id': wissen_node.category_id
|
||||
})
|
||||
|
||||
# Dann die anderen Knoten
|
||||
for node in nodes:
|
||||
node_obj = {
|
||||
'id': node.id,
|
||||
'name': node.name,
|
||||
'description': node.description or '',
|
||||
'color_code': node.color_code or '#9F7AEA',
|
||||
'thought_count': len(node.thoughts),
|
||||
'category_id': node.category_id
|
||||
}
|
||||
|
||||
# Verbinde alle Top-Level-Knoten mit dem Wissen-Knoten
|
||||
if not node.parents.all():
|
||||
edge_data.append({
|
||||
'source': wissen_node.id,
|
||||
'target': node.id
|
||||
})
|
||||
|
||||
# Verbindungen zwischen vorhandenen Knoten hinzufügen
|
||||
node_children = node.children.all()
|
||||
for child in node_children:
|
||||
edge_data.append({
|
||||
'source': node.id,
|
||||
'target': child.id
|
||||
})
|
||||
|
||||
node_data.append(node_obj)
|
||||
# Kanten erstellen (vereinheitlichte Schlüssel)
|
||||
edges = [{
|
||||
'source': f'cat_{category.id}',
|
||||
'target': f'cat_{subcat.id}',
|
||||
'strength': 0.8
|
||||
} for subcat in category.children]
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'categories': category_tree,
|
||||
'nodes': node_data,
|
||||
'edges': edge_data
|
||||
'nodes': nodes,
|
||||
'edges': edges
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Neuladen der Mindmap: {str(e)}")
|
||||
print(f"Fehler beim Abrufen der {category_name}-Mindmap: {str(e)}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Datenbankverbindung konnte nicht hergestellt werden'
|
||||
'error': f'{category_name}-Mindmap konnte nicht geladen werden',
|
||||
'details': str(e)
|
||||
}), 500
|
||||
|
||||
@app.route('/api/mindmap/root')
|
||||
def get_root_mindmap_data():
|
||||
"""Liefert die Daten für die Root-Mindmap."""
|
||||
try:
|
||||
# Hauptkategorien mit Unterkategorien in einer Abfrage laden
|
||||
categories = Category.query.filter_by(parent_id=None).options(
|
||||
joinedload(Category.children)
|
||||
).all()
|
||||
|
||||
# Basis-Knoten erstellen
|
||||
nodes = [{
|
||||
'id': 'root',
|
||||
'name': 'Wissen',
|
||||
'description': 'Zentrale Wissensbasis',
|
||||
'color_code': '#4299E1',
|
||||
'is_center': True,
|
||||
'has_children': bool(categories),
|
||||
'icon': 'fa-solid fa-circle'
|
||||
}]
|
||||
|
||||
# Kategorien als Knoten hinzufügen
|
||||
for category in categories:
|
||||
nodes.append({
|
||||
'id': f'cat_{category.id}',
|
||||
'name': category.name,
|
||||
'description': category.description or '',
|
||||
'color_code': category.color_code or '#9F7AEA',
|
||||
'category': category.name,
|
||||
'has_children': bool(category.children),
|
||||
'icon': category.icon or 'fa-solid fa-circle'
|
||||
})
|
||||
|
||||
# Kanten erstellen (vereinheitlichte Schlüssel)
|
||||
edges = [{
|
||||
'source': 'root',
|
||||
'target': f'cat_{category.id}',
|
||||
'strength': 0.8
|
||||
} for category in categories]
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'nodes': nodes,
|
||||
'edges': edges
|
||||
})
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Abrufen der Root-Mindmap: {str(e)}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Root-Mindmap konnte nicht geladen werden',
|
||||
'details': str(e)
|
||||
}), 500
|
||||
|
||||
# Spezifische Routen für Kategorien
|
||||
@app.route('/api/mindmap/philosophy')
|
||||
def get_philosophy_mindmap_data():
|
||||
return get_category_mindmap_data('Philosophie')
|
||||
|
||||
@app.route('/api/mindmap/science')
|
||||
def get_science_mindmap_data():
|
||||
return get_category_mindmap_data('Wissenschaft')
|
||||
|
||||
@app.route('/api/mindmap/technology')
|
||||
def get_technology_mindmap():
|
||||
"""
|
||||
API-Endpunkt für die Technologie-Mindmap
|
||||
"""
|
||||
try:
|
||||
# Stelle sicher, dass wir Kategorien haben
|
||||
if Category.query.count() == 0:
|
||||
create_default_categories()
|
||||
|
||||
# Überprüfe, ob wir bereits einen "Wissen"-Knoten haben
|
||||
wissen_node = MindMapNode.query.filter_by(name="Wissen").first()
|
||||
|
||||
# Wenn kein "Wissen"-Knoten existiert, erstelle ihn
|
||||
if not wissen_node:
|
||||
wissen_node = MindMapNode(
|
||||
name="Wissen",
|
||||
description="Zentrale Wissensbasis",
|
||||
color_code="#4299E1",
|
||||
is_public=True
|
||||
)
|
||||
db.session.add(wissen_node)
|
||||
db.session.commit()
|
||||
|
||||
# Hole alle Kategorien und Knoten
|
||||
categories = Category.query.filter_by(parent_id=None).all()
|
||||
category_tree = [build_category_tree(cat) for cat in categories]
|
||||
|
||||
# Hole alle Mindmap-Knoten außer dem "Wissen"-Knoten
|
||||
nodes = MindMapNode.query.filter(MindMapNode.id != wissen_node.id).all()
|
||||
|
||||
# Vorbereiten der Node- und Edge-Arrays für die Antwort
|
||||
node_data = []
|
||||
edge_data = []
|
||||
|
||||
# Zuerst den "Wissen"-Knoten hinzufügen
|
||||
node_data.append({
|
||||
'id': wissen_node.id,
|
||||
'name': wissen_node.name,
|
||||
'description': wissen_node.description or '',
|
||||
'color_code': wissen_node.color_code or '#4299E1',
|
||||
'thought_count': len(wissen_node.thoughts),
|
||||
'category_id': wissen_node.category_id
|
||||
})
|
||||
|
||||
# Dann die anderen Knoten
|
||||
for node in nodes:
|
||||
node_obj = {
|
||||
'id': node.id,
|
||||
'name': node.name,
|
||||
'description': node.description or '',
|
||||
'color_code': node.color_code or '#9F7AEA',
|
||||
'thought_count': len(node.thoughts),
|
||||
'category_id': node.category_id
|
||||
}
|
||||
|
||||
# Verbinde alle Top-Level-Knoten mit dem Wissen-Knoten
|
||||
if not node.parents.all():
|
||||
edge_data.append({
|
||||
'source': wissen_node.id,
|
||||
'target': node.id
|
||||
})
|
||||
|
||||
# Verbindungen zwischen vorhandenen Knoten hinzufügen
|
||||
node_children = node.children.all()
|
||||
for child in node_children:
|
||||
edge_data.append({
|
||||
'source': node.id,
|
||||
'target': child.id
|
||||
})
|
||||
|
||||
node_data.append(node_obj)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'categories': category_tree,
|
||||
'nodes': node_data,
|
||||
'edges': edge_data
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Neuladen der Mindmap: {str(e)}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Datenbankverbindung konnte nicht hergestellt werden'
|
||||
}), 500
|
||||
def get_technology_mindmap_data():
|
||||
return get_category_mindmap_data('Technologie')
|
||||
|
||||
@app.route('/api/mindmap/arts')
|
||||
def get_arts_mindmap():
|
||||
"""
|
||||
API-Endpunkt für die Künste-Mindmap
|
||||
"""
|
||||
try:
|
||||
# Stelle sicher, dass wir Kategorien haben
|
||||
if Category.query.count() == 0:
|
||||
create_default_categories()
|
||||
|
||||
# Überprüfe, ob wir bereits einen "Wissen"-Knoten haben
|
||||
wissen_node = MindMapNode.query.filter_by(name="Wissen").first()
|
||||
|
||||
# Wenn kein "Wissen"-Knoten existiert, erstelle ihn
|
||||
if not wissen_node:
|
||||
wissen_node = MindMapNode(
|
||||
name="Wissen",
|
||||
description="Zentrale Wissensbasis",
|
||||
color_code="#4299E1",
|
||||
is_public=True
|
||||
)
|
||||
db.session.add(wissen_node)
|
||||
db.session.commit()
|
||||
|
||||
# Hole alle Kategorien und Knoten
|
||||
categories = Category.query.filter_by(parent_id=None).all()
|
||||
category_tree = [build_category_tree(cat) for cat in categories]
|
||||
|
||||
# Hole alle Mindmap-Knoten außer dem "Wissen"-Knoten
|
||||
nodes = MindMapNode.query.filter(MindMapNode.id != wissen_node.id).all()
|
||||
|
||||
# Vorbereiten der Node- und Edge-Arrays für die Antwort
|
||||
node_data = []
|
||||
edge_data = []
|
||||
|
||||
# Zuerst den "Wissen"-Knoten hinzufügen
|
||||
node_data.append({
|
||||
'id': wissen_node.id,
|
||||
'name': wissen_node.name,
|
||||
'description': wissen_node.description or '',
|
||||
'color_code': wissen_node.color_code or '#4299E1',
|
||||
'thought_count': len(wissen_node.thoughts),
|
||||
'category_id': wissen_node.category_id
|
||||
})
|
||||
|
||||
# Dann die anderen Knoten
|
||||
for node in nodes:
|
||||
node_obj = {
|
||||
'id': node.id,
|
||||
'name': node.name,
|
||||
'description': node.description or '',
|
||||
'color_code': node.color_code or '#9F7AEA',
|
||||
'thought_count': len(node.thoughts),
|
||||
'category_id': node.category_id
|
||||
}
|
||||
|
||||
# Verbinde alle Top-Level-Knoten mit dem Wissen-Knoten
|
||||
if not node.parents.all():
|
||||
edge_data.append({
|
||||
'source': wissen_node.id,
|
||||
'target': node.id
|
||||
})
|
||||
|
||||
# Verbindungen zwischen vorhandenen Knoten hinzufügen
|
||||
node_children = node.children.all()
|
||||
for child in node_children:
|
||||
edge_data.append({
|
||||
'source': node.id,
|
||||
'target': child.id
|
||||
})
|
||||
|
||||
node_data.append(node_obj)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'categories': category_tree,
|
||||
'nodes': node_data,
|
||||
'edges': edge_data
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Neuladen der Mindmap: {str(e)}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Datenbankverbindung konnte nicht hergestellt werden'
|
||||
}), 500
|
||||
def get_arts_mindmap_data():
|
||||
return get_category_mindmap_data('Künste')
|
||||
|
||||
@app.route('/api/mindmap/philosophy')
|
||||
def get_philosophy_mindmap():
|
||||
"""
|
||||
API-Endpunkt für die Philosophie-Mindmap
|
||||
"""
|
||||
try:
|
||||
# Stelle sicher, dass wir Kategorien haben
|
||||
if Category.query.count() == 0:
|
||||
create_default_categories()
|
||||
|
||||
# Überprüfe, ob wir bereits einen "Wissen"-Knoten haben
|
||||
wissen_node = MindMapNode.query.filter_by(name="Wissen").first()
|
||||
|
||||
# Wenn kein "Wissen"-Knoten existiert, erstelle ihn
|
||||
if not wissen_node:
|
||||
wissen_node = MindMapNode(
|
||||
name="Wissen",
|
||||
description="Zentrale Wissensbasis",
|
||||
color_code="#4299E1",
|
||||
is_public=True
|
||||
)
|
||||
db.session.add(wissen_node)
|
||||
db.session.commit()
|
||||
|
||||
# Hole alle Kategorien und Knoten
|
||||
categories = Category.query.filter_by(parent_id=None).all()
|
||||
category_tree = [build_category_tree(cat) for cat in categories]
|
||||
|
||||
# Hole alle Mindmap-Knoten außer dem "Wissen"-Knoten
|
||||
nodes = MindMapNode.query.filter(MindMapNode.id != wissen_node.id).all()
|
||||
|
||||
# Vorbereiten der Node- und Edge-Arrays für die Antwort
|
||||
node_data = []
|
||||
edge_data = []
|
||||
|
||||
# Zuerst den "Wissen"-Knoten hinzufügen
|
||||
node_data.append({
|
||||
'id': wissen_node.id,
|
||||
'name': wissen_node.name,
|
||||
'description': wissen_node.description or '',
|
||||
'color_code': wissen_node.color_code or '#4299E1',
|
||||
'thought_count': len(wissen_node.thoughts),
|
||||
'category_id': wissen_node.category_id
|
||||
})
|
||||
|
||||
# Dann die anderen Knoten
|
||||
for node in nodes:
|
||||
node_obj = {
|
||||
'id': node.id,
|
||||
'name': node.name,
|
||||
'description': node.description or '',
|
||||
'color_code': node.color_code or '#9F7AEA',
|
||||
'thought_count': len(node.thoughts),
|
||||
'category_id': node.category_id
|
||||
}
|
||||
|
||||
# Verbinde alle Top-Level-Knoten mit dem Wissen-Knoten
|
||||
if not node.parents.all():
|
||||
edge_data.append({
|
||||
'source': wissen_node.id,
|
||||
'target': node.id
|
||||
})
|
||||
|
||||
# Verbindungen zwischen vorhandenen Knoten hinzufügen
|
||||
node_children = node.children.all()
|
||||
for child in node_children:
|
||||
edge_data.append({
|
||||
'source': node.id,
|
||||
'target': child.id
|
||||
})
|
||||
|
||||
node_data.append(node_obj)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'categories': category_tree,
|
||||
'nodes': node_data,
|
||||
'edges': edge_data
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Neuladen der Mindmap: {str(e)}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Datenbankverbindung konnte nicht hergestellt werden'
|
||||
}), 500
|
||||
|
||||
# Generische Route für andere Mindmap-Knoten (muss nach den spezifischen Routen kommen)
|
||||
# Generische Route für spezifische Knoten
|
||||
@app.route('/api/mindmap/<node_id>')
|
||||
def get_mindmap_data(node_id):
|
||||
"""
|
||||
Stellt Mindmap-Daten für das Frontend bereit.
|
||||
Liefert für 'root' die Hauptebene und für andere Node-IDs die entsprechenden Unterknoten.
|
||||
Daten werden aus der Datenbank abgerufen.
|
||||
"""
|
||||
if node_id == 'root':
|
||||
try:
|
||||
# Stelle sicher, dass wir Kategorien haben
|
||||
if Category.query.count() == 0:
|
||||
create_default_categories()
|
||||
|
||||
# Überprüfe, ob wir bereits einen "Wissen"-Knoten haben
|
||||
wissen_node = MindMapNode.query.filter_by(name="Wissen").first()
|
||||
|
||||
# Wenn kein "Wissen"-Knoten existiert, erstelle ihn
|
||||
if not wissen_node:
|
||||
wissen_node = MindMapNode(
|
||||
name="Wissen",
|
||||
description="Zentrale Wissensbasis",
|
||||
color_code="#4299E1",
|
||||
is_public=True
|
||||
)
|
||||
db.session.add(wissen_node)
|
||||
db.session.commit()
|
||||
|
||||
# Hole alle Kategorien und Knoten
|
||||
categories = Category.query.filter_by(parent_id=None).all()
|
||||
category_tree = [build_category_tree(cat) for cat in categories]
|
||||
|
||||
# Hole alle Mindmap-Knoten außer dem "Wissen"-Knoten
|
||||
nodes = MindMapNode.query.filter(MindMapNode.id != wissen_node.id).all()
|
||||
|
||||
# Vorbereiten der Node- und Edge-Arrays für die Antwort
|
||||
node_data = []
|
||||
edge_data = []
|
||||
|
||||
# Zuerst den "Wissen"-Knoten hinzufügen
|
||||
node_data.append({
|
||||
'id': wissen_node.id,
|
||||
'name': wissen_node.name,
|
||||
'description': wissen_node.description or '',
|
||||
'color_code': wissen_node.color_code or '#4299E1',
|
||||
'thought_count': len(wissen_node.thoughts),
|
||||
'category_id': wissen_node.category_id
|
||||
})
|
||||
|
||||
# Dann die anderen Knoten
|
||||
for node in nodes:
|
||||
node_obj = {
|
||||
'id': node.id,
|
||||
'name': node.name,
|
||||
'description': node.description or '',
|
||||
'color_code': node.color_code or '#9F7AEA',
|
||||
'thought_count': len(node.thoughts),
|
||||
'category_id': node.category_id
|
||||
}
|
||||
|
||||
# Verbinde alle Top-Level-Knoten mit dem Wissen-Knoten
|
||||
if not node.parents.all():
|
||||
edge_data.append({
|
||||
'source': wissen_node.id,
|
||||
'target': node.id
|
||||
})
|
||||
|
||||
# Verbindungen zwischen vorhandenen Knoten hinzufügen
|
||||
node_children = node.children.all()
|
||||
for child in node_children:
|
||||
edge_data.append({
|
||||
'source': node.id,
|
||||
'target': child.id
|
||||
})
|
||||
|
||||
node_data.append(node_obj)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'categories': category_tree,
|
||||
'nodes': node_data,
|
||||
'edges': edge_data
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
app.logger.error(f"Fehler beim Laden der Root-Mindmap: {str(e)}")
|
||||
"""Liefert die Daten für einen spezifischen Mindmap-Knoten."""
|
||||
try:
|
||||
# Prüfen, ob es sich um eine spezielle Route handelt
|
||||
if node_id in ['root', 'philosophy', 'science', 'technology', 'arts']:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Datenbankverbindung konnte nicht hergestellt werden'
|
||||
}), 500
|
||||
|
||||
app.logger.info(f"Mindmap-Daten werden für Node '{node_id}' angefordert.")
|
||||
|
||||
try:
|
||||
# Fallback-Daten falls Datenbankzugriff fehlschlägt
|
||||
fallback_data = get_fallback_mindmap_data(node_id)
|
||||
|
||||
if node_id.startswith('cat_'):
|
||||
# Unterkategorien einer Hauptkategorie anzeigen
|
||||
category_id = node_id.replace('cat_', '')
|
||||
try:
|
||||
category_id_int = int(category_id)
|
||||
category = Category.query.get(category_id_int)
|
||||
|
||||
if category:
|
||||
# Hole alle Unterkategorien
|
||||
subcategories = Category.query.filter_by(parent_id=category_id_int).all()
|
||||
|
||||
# Hole alle Knoten dieser Kategorie
|
||||
nodes = MindMapNode.query.filter_by(category_id=category_id_int).all()
|
||||
|
||||
# Vorbereiten der Antwort
|
||||
node_data = []
|
||||
edge_data = []
|
||||
|
||||
# Kategorie-Knoten hinzufügen
|
||||
node_data.append({
|
||||
'id': f"cat_{category.id}",
|
||||
'name': category.name,
|
||||
'description': category.description or '',
|
||||
'color_code': category.color_code or '#9F7AEA',
|
||||
'is_category': True
|
||||
})
|
||||
|
||||
# Unterkategorien als Knoten hinzufügen
|
||||
for subcat in subcategories:
|
||||
node_data.append({
|
||||
'id': f"cat_{subcat.id}",
|
||||
'name': subcat.name,
|
||||
'description': subcat.description or '',
|
||||
'color_code': subcat.color_code or '#9F7AEA',
|
||||
'is_category': True
|
||||
})
|
||||
|
||||
# Verbindung zur Hauptkategorie
|
||||
edge_data.append({
|
||||
'source': f"cat_{category.id}",
|
||||
'target': f"cat_{subcat.id}"
|
||||
})
|
||||
|
||||
# Mindmap-Knoten hinzufügen
|
||||
for node in nodes:
|
||||
node_data.append({
|
||||
'id': node.id,
|
||||
'name': node.name,
|
||||
'description': node.description or '',
|
||||
'color_code': node.color_code or '#9F7AEA',
|
||||
'thought_count': len(node.thoughts)
|
||||
})
|
||||
|
||||
# Verbindung zur Kategorie
|
||||
edge_data.append({
|
||||
'source': f"cat_{category.id}",
|
||||
'target': node.id
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'nodes': node_data,
|
||||
'edges': edge_data
|
||||
})
|
||||
|
||||
except (ValueError, TypeError):
|
||||
app.logger.error(f"Ungültige Kategorie-ID: {category_id}")
|
||||
return jsonify(fallback_data)
|
||||
|
||||
else:
|
||||
# Versuche, einen MindMapNode mit der gegebenen ID zu finden
|
||||
try:
|
||||
node_id_int = int(node_id)
|
||||
node = MindMapNode.query.get(node_id_int)
|
||||
|
||||
if node:
|
||||
# Zeige Gedanken oder verwandte Knoten
|
||||
# Hier würden wir verwandte Knoten aus der Datenbank laden
|
||||
# Für den Moment verwenden wir Fallback-Daten
|
||||
app.logger.info(f"Knoten {node.name} gefunden, aber keine spezifische Verarbeitung implementiert.")
|
||||
return jsonify(fallback_data)
|
||||
'error': 'Ungültige Knoten-ID',
|
||||
'details': 'Diese ID ist für spezielle Routen reserviert'
|
||||
}), 400
|
||||
|
||||
except (ValueError, TypeError):
|
||||
# Wenn die ID kein Integer ist, verwende das bisherige Verhalten
|
||||
app.logger.info(f"Falle auf bisheriges Verhalten für Node ID '{node_id}' zurück.")
|
||||
return jsonify(fallback_data)
|
||||
# Knoten mit Unterknoten in einer Abfrage laden
|
||||
node = MindMapNode.query.options(
|
||||
joinedload(MindMapNode.children)
|
||||
).get_or_404(node_id)
|
||||
|
||||
# Wenn wir hier ankommen, gibt es keine spezifische Verarbeitung für diese node_id
|
||||
return jsonify(fallback_data)
|
||||
# Basis-Knoten erstellen
|
||||
nodes = [{
|
||||
'id': str(node.id),
|
||||
'name': node.name,
|
||||
'description': node.description or '',
|
||||
'color_code': node.color_code or '#9F7AEA',
|
||||
'is_center': True,
|
||||
'has_children': bool(node.children),
|
||||
'icon': node.icon or 'fa-solid fa-circle'
|
||||
}]
|
||||
|
||||
# Unterknoten hinzufügen
|
||||
for child in node.children:
|
||||
nodes.append({
|
||||
'id': str(child.id),
|
||||
'name': child.name,
|
||||
'description': child.description or '',
|
||||
'color_code': child.color_code or '#9F7AEA',
|
||||
'category': node.name,
|
||||
'has_children': bool(child.children),
|
||||
'icon': child.icon or 'fa-solid fa-circle'
|
||||
})
|
||||
|
||||
# Kanten erstellen (vereinheitlichte Schlüssel)
|
||||
edges = [{
|
||||
'source': str(node.id),
|
||||
'target': str(child.id),
|
||||
'strength': 0.8
|
||||
} for child in node.children]
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'nodes': nodes,
|
||||
'edges': edges
|
||||
})
|
||||
except Exception as e:
|
||||
app.logger.error(f"Fehler beim Abrufen der Mindmap-Daten: {str(e)}")
|
||||
app.logger.error(f"Stack Trace: {traceback.format_exc()}")
|
||||
return jsonify({"error": "Fehler beim Abrufen der Mindmap-Daten"}), 500
|
||||
|
||||
|
||||
def get_fallback_mindmap_data(node_id):
|
||||
"""
|
||||
Liefert Fallback-Daten für die Mindmap, wenn die Datenbank nicht verfügbar ist.
|
||||
"""
|
||||
if node_id == 'root':
|
||||
# Hauptebene der Mindmap
|
||||
nodes = [
|
||||
{
|
||||
"id": "center",
|
||||
"name": "Wissenskarte",
|
||||
"description": "Zentrale Wissenskarte mit allen Hauptthemen",
|
||||
"is_center": True,
|
||||
"color_code": "#f5f5f5",
|
||||
"has_children": True
|
||||
},
|
||||
{
|
||||
"id": "philosophy",
|
||||
"name": "Philosophie",
|
||||
"description": "Die Lehre vom Denken und der Erkenntnis",
|
||||
"category": "Philosophie",
|
||||
"has_children": True,
|
||||
"color_code": "#9F7AEA"
|
||||
},
|
||||
{
|
||||
"id": "science",
|
||||
"name": "Wissenschaft",
|
||||
"description": "Systematische Erforschung der Natur und Gesellschaft",
|
||||
"category": "Wissenschaft",
|
||||
"has_children": True,
|
||||
"color_code": "#f4b400"
|
||||
},
|
||||
{
|
||||
"id": "technology",
|
||||
"name": "Technologie",
|
||||
"description": "Anwendung wissenschaftlicher Erkenntnisse",
|
||||
"category": "Technologie",
|
||||
"has_children": True,
|
||||
"color_code": "#0d47a1"
|
||||
},
|
||||
{
|
||||
"id": "arts",
|
||||
"name": "Künste",
|
||||
"description": "Kreativer Ausdruck und künstlerische Gestaltung",
|
||||
"category": "Künste",
|
||||
"has_children": True,
|
||||
"color_code": "#c2185b"
|
||||
}
|
||||
]
|
||||
|
||||
edges = [
|
||||
{"source_id": "center", "target_id": "philosophy", "strength": 0.9},
|
||||
{"source_id": "center", "target_id": "science", "strength": 0.9},
|
||||
{"source_id": "center", "target_id": "technology", "strength": 0.9},
|
||||
{"source_id": "center", "target_id": "arts", "strength": 0.9}
|
||||
]
|
||||
|
||||
elif node_id == 'philosophy':
|
||||
nodes = [
|
||||
{
|
||||
"id": "epistemology",
|
||||
"name": "Erkenntnistheorie",
|
||||
"description": "Untersuchung der Natur und Grenzen menschlicher Erkenntnis",
|
||||
"category": "Philosophie",
|
||||
"has_children": True,
|
||||
"color_code": "#9F7AEA"
|
||||
},
|
||||
{
|
||||
"id": "ethics",
|
||||
"name": "Ethik",
|
||||
"description": "Lehre vom moralisch richtigen Handeln",
|
||||
"category": "Philosophie",
|
||||
"has_children": True,
|
||||
"color_code": "#9F7AEA"
|
||||
},
|
||||
{
|
||||
"id": "metaphysics",
|
||||
"name": "Metaphysik",
|
||||
"description": "Grundfragen des Seins und der Wirklichkeit",
|
||||
"category": "Philosophie",
|
||||
"has_children": True,
|
||||
"color_code": "#9F7AEA"
|
||||
}
|
||||
]
|
||||
|
||||
edges = [
|
||||
{"source_id": "philosophy", "target_id": "epistemology", "strength": 0.8},
|
||||
{"source_id": "philosophy", "target_id": "ethics", "strength": 0.8},
|
||||
{"source_id": "philosophy", "target_id": "metaphysics", "strength": 0.8}
|
||||
]
|
||||
|
||||
elif node_id == 'science':
|
||||
nodes = [
|
||||
{
|
||||
"id": "physics",
|
||||
"name": "Physik",
|
||||
"description": "Lehre von der Materie und ihren Wechselwirkungen",
|
||||
"category": "Wissenschaft",
|
||||
"has_children": True,
|
||||
"color_code": "#f4b400"
|
||||
},
|
||||
{
|
||||
"id": "biology",
|
||||
"name": "Biologie",
|
||||
"description": "Lehre von den Lebewesen und ihren Lebensprozessen",
|
||||
"category": "Wissenschaft",
|
||||
"has_children": True,
|
||||
"color_code": "#f4b400"
|
||||
},
|
||||
{
|
||||
"id": "chemistry",
|
||||
"name": "Chemie",
|
||||
"description": "Wissenschaft von den Stoffen und ihren Reaktionen",
|
||||
"category": "Wissenschaft",
|
||||
"has_children": True,
|
||||
"color_code": "#f4b400"
|
||||
}
|
||||
]
|
||||
|
||||
edges = [
|
||||
{"source_id": "science", "target_id": "physics", "strength": 0.8},
|
||||
{"source_id": "science", "target_id": "biology", "strength": 0.8},
|
||||
{"source_id": "science", "target_id": "chemistry", "strength": 0.8}
|
||||
]
|
||||
|
||||
elif node_id == 'technology':
|
||||
nodes = [
|
||||
{
|
||||
"id": "ai",
|
||||
"name": "Künstliche Intelligenz",
|
||||
"description": "Maschinelles Lernen und intelligente Systeme",
|
||||
"category": "Technologie",
|
||||
"has_children": True,
|
||||
"color_code": "#0d47a1"
|
||||
},
|
||||
{
|
||||
"id": "robotics",
|
||||
"name": "Robotik",
|
||||
"description": "Entwicklung und Steuerung von Robotern",
|
||||
"category": "Technologie",
|
||||
"has_children": True,
|
||||
"color_code": "#0d47a1"
|
||||
},
|
||||
{
|
||||
"id": "quantum_computing",
|
||||
"name": "Quantencomputing",
|
||||
"description": "Computer basierend auf Quantenmechanik",
|
||||
"category": "Technologie",
|
||||
"has_children": True,
|
||||
"color_code": "#0d47a1"
|
||||
}
|
||||
]
|
||||
|
||||
edges = [
|
||||
{"source_id": "technology", "target_id": "ai", "strength": 0.8},
|
||||
{"source_id": "technology", "target_id": "robotics", "strength": 0.8},
|
||||
{"source_id": "technology", "target_id": "quantum_computing", "strength": 0.8}
|
||||
]
|
||||
|
||||
elif node_id == 'arts':
|
||||
nodes = [
|
||||
{
|
||||
"id": "visual_arts",
|
||||
"name": "Bildende Kunst",
|
||||
"description": "Malerei, Bildhauerei und andere visuelle Kunstformen",
|
||||
"category": "Künste",
|
||||
"has_children": True,
|
||||
"color_code": "#c2185b"
|
||||
},
|
||||
{
|
||||
"id": "music",
|
||||
"name": "Musik",
|
||||
"description": "Tonkunst und musikalische Komposition",
|
||||
"category": "Künste",
|
||||
"has_children": True,
|
||||
"color_code": "#c2185b"
|
||||
},
|
||||
{
|
||||
"id": "literature",
|
||||
"name": "Literatur",
|
||||
"description": "Schriftliche Kunstwerke und Poesie",
|
||||
"category": "Künste",
|
||||
"has_children": True,
|
||||
"color_code": "#c2185b"
|
||||
}
|
||||
]
|
||||
|
||||
edges = [
|
||||
{"source_id": "arts", "target_id": "visual_arts", "strength": 0.8},
|
||||
{"source_id": "arts", "target_id": "music", "strength": 0.8},
|
||||
{"source_id": "arts", "target_id": "literature", "strength": 0.8}
|
||||
]
|
||||
|
||||
else:
|
||||
# Für jede andere Node-ID geben wir eine leere Struktur zurück
|
||||
nodes = []
|
||||
edges = []
|
||||
|
||||
# Antwort zusammenstellen
|
||||
return {
|
||||
"nodes": nodes,
|
||||
"edges": edges
|
||||
}
|
||||
|
||||
# Diese Routen wurden an den Anfang der Datei verschoben und werden nicht mehr benötigt
|
||||
print(f"Fehler beim Abrufen der Mindmap-Daten für Knoten {node_id}: {str(e)}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Mindmap-Daten konnten nicht geladen werden',
|
||||
'details': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
Reference in New Issue
Block a user