diff --git a/__pycache__/app.cpython-313.pyc b/__pycache__/app.cpython-313.pyc index 621e517..764f5e3 100644 Binary files a/__pycache__/app.cpython-313.pyc and b/__pycache__/app.cpython-313.pyc differ diff --git a/__pycache__/models.cpython-313.pyc b/__pycache__/models.cpython-313.pyc index 7136ff4..d03e1c9 100644 Binary files a/__pycache__/models.cpython-313.pyc and b/__pycache__/models.cpython-313.pyc differ diff --git a/app.py b/app.py index a0d7e87..fcc686a 100644 --- a/app.py +++ b/app.py @@ -19,6 +19,7 @@ from openai import OpenAI from dotenv import load_dotenv from flask_socketio import SocketIO, emit from flask_migrate import Migrate +import sqlalchemy # Modelle importieren from models import ( @@ -316,15 +317,21 @@ def register(): user = User(username=username, email=email) user.set_password(password) db.session.add(user) + db.session.commit() # Commit, um eine ID für den Benutzer zu erhalten # Erstelle eine Standard-Mindmap für den neuen Benutzer - default_mindmap = UserMindmap( - name='Meine Mindmap', - description='Meine persönliche Wissenslandschaft', - user=user - ) - db.session.add(default_mindmap) - db.session.commit() + try: + default_mindmap = UserMindmap( + name='Meine Mindmap', + description='Meine persönliche Wissenslandschaft', + user_id=user.id + ) + db.session.add(default_mindmap) + db.session.commit() + except Exception as e: + print(f"Fehler beim Erstellen der Standard-Mindmap: {e}") + # Stelle sicher, dass wir trotzdem weitermachen können + db.session.rollback() login_user(user) flash('Dein Konto wurde erfolgreich erstellt!', 'success') @@ -379,49 +386,96 @@ def mindmap(): @app.route('/profile') @login_required def profile(): - # Lade Benutzer-Mindmaps - user_mindmaps = UserMindmap.query.filter_by(user_id=current_user.id).all() - - # Lade Statistiken - thought_count = Thought.query.filter_by(user_id=current_user.id).count() - bookmark_count = db.session.query(user_thought_bookmark).filter( - user_thought_bookmark.c.user_id == current_user.id).count() - - # Berechne tatsächliche Werte für Benutzerstatistiken - contributions_count = Comment.query.filter_by(user_id=current_user.id).count() - - # Berechne Verbindungen (Anzahl der Gedankenverknüpfungen) - connections_count = ThoughtRelation.query.filter( - (ThoughtRelation.source_id.in_( - db.session.query(Thought.id).filter_by(user_id=current_user.id) - )) | - (ThoughtRelation.target_id.in_( - db.session.query(Thought.id).filter_by(user_id=current_user.id) - )) - ).count() - - # Berechne durchschnittliche Bewertung der Gedanken des Benutzers - avg_rating = db.session.query(func.avg(ThoughtRating.relevance_score)).join( - Thought, Thought.id == ThoughtRating.thought_id - ).filter(Thought.user_id == current_user.id).scalar() or 0 - - # Hole die Anzahl der Follower (falls implementiert) - # In diesem Beispiel nehmen wir an, dass es keine Follower-Funktionalität gibt - followers_count = 0 - - # Hole den Standort des Benutzers aus der Datenbank, falls vorhanden - location = "Deutschland" # Standardwert - - return render_template('profile.html', - user=current_user, - user_mindmaps=user_mindmaps, - thought_count=thought_count, - bookmark_count=bookmark_count, - connections_count=connections_count, - contributions_count=contributions_count, - followers_count=followers_count, - rating=round(avg_rating, 1), - location=location) + try: + # Versuche auf die neue Benutzermodellstruktur zuzugreifen + _ = current_user.bio # Dies wird fehlschlagen, wenn die Spalte nicht existiert + + # Wenn keine Ausnahme, fahre mit normalem Profil fort + # Lade Benutzer-Mindmaps + user_mindmaps = UserMindmap.query.filter_by(user_id=current_user.id).all() + + # Prüfe, ob der Benutzer eine Standard-Mindmap hat, sonst erstelle eine + if not user_mindmaps: + try: + default_mindmap = UserMindmap( + name='Meine Mindmap', + description='Meine persönliche Wissenslandschaft', + user_id=current_user.id + ) + db.session.add(default_mindmap) + db.session.commit() + + # Aktualisiere die Liste nach dem Erstellen + user_mindmaps = [default_mindmap] + except Exception as e: + print(f"Fehler beim Erstellen der Standard-Mindmap in Profil: {e}") + # Flash-Nachricht für den Benutzer + flash('Es gab ein Problem beim Laden deiner Mindmaps. Bitte versuche es später erneut.', 'warning') + + # Lade Statistiken + thought_count = Thought.query.filter_by(user_id=current_user.id).count() + bookmark_count = db.session.query(user_thought_bookmark).filter( + user_thought_bookmark.c.user_id == current_user.id).count() + + # Berechne tatsächliche Werte für Benutzerstatistiken + contributions_count = Comment.query.filter_by(user_id=current_user.id).count() + + # Berechne Verbindungen (Anzahl der Gedankenverknüpfungen) + connections_count = ThoughtRelation.query.filter( + (ThoughtRelation.source_id.in_( + db.session.query(Thought.id).filter_by(user_id=current_user.id) + )) | + (ThoughtRelation.target_id.in_( + db.session.query(Thought.id).filter_by(user_id=current_user.id) + )) + ).count() + + # Berechne durchschnittliche Bewertung der Gedanken des Benutzers + avg_rating = db.session.query(func.avg(ThoughtRating.relevance_score)).join( + Thought, Thought.id == ThoughtRating.thought_id + ).filter(Thought.user_id == current_user.id).scalar() or 0 + + # Sammle alle Statistiken in einem Wörterbuch + stats = { + 'thought_count': thought_count, + 'bookmark_count': bookmark_count, + 'connections_count': connections_count, + 'contributions_count': contributions_count, + 'followers_count': 0, # Platzhalter für zukünftige Funktionalität + 'rating': round(avg_rating, 1) + } + + # Hole die letzten Gedanken des Benutzers + thoughts = Thought.query.filter_by(user_id=current_user.id).order_by(Thought.created_at.desc()).limit(5).all() + + # Hole den Standort des Benutzers aus der Datenbank, falls vorhanden + location = "Deutschland" # Standardwert + + return render_template('profile.html', + user=current_user, + user_mindmaps=user_mindmaps, + stats=stats, + thoughts=thoughts, + location=location) + + except (AttributeError, sqlalchemy.exc.OperationalError) as e: + # Die Spalte existiert nicht, verwende stattdessen das einfache Profil + print(f"Verwende einfaches Profil wegen Datenbankfehler: {e}") + flash('Dein Profil wird im einfachen Modus angezeigt, bis die Datenbank aktualisiert wird.', 'warning') + + # Lade nur die grundlegenden Informationen + user_mindmaps = UserMindmap.query.filter_by(user_id=current_user.id).all() + thoughts = Thought.query.filter_by(user_id=current_user.id).order_by(Thought.created_at.desc()).limit(5).all() + + return render_template('simple_profile.html', + user=current_user, + user_mindmaps=user_mindmaps, + thoughts=thoughts) + except Exception as e: + # Eine andere Ausnahme ist aufgetreten + print(f"Fehler beim Laden des Profils: {e}") + flash('Dein Benutzerprofil konnte nicht geladen werden. Bitte kontaktiere den Support.', 'error') + return redirect(url_for('index')) # Route für Benutzereinstellungen @app.route('/settings', methods=['GET', 'POST']) @@ -1548,4 +1602,28 @@ def redirect_to_index(): @app.route('/static/js/mindmap-init.js') def serve_mindmap_init_js(): """Bedient die Mindmap-Initialisierungsdatei.""" - return app.send_static_file('js/mindmap-init.js'), 200, {'Content-Type': 'application/javascript'} \ No newline at end of file + return app.send_static_file('js/mindmap-init.js'), 200, {'Content-Type': 'application/javascript'} + +# Datenbank-Update-Route (admin-geschützt) +@app.route('/admin/update-database', methods=['GET', 'POST']) +@admin_required +def admin_update_database(): + """Admin-Route zum Aktualisieren der Datenbank""" + message = None + success = None + + if request.method == 'POST': + try: + import update_db + update_success = update_db.update_user_table() + if update_success: + message = "Die Datenbank wurde erfolgreich aktualisiert." + success = True + else: + message = "Es gab ein Problem bei der Aktualisierung der Datenbank." + success = False + except Exception as e: + message = f"Fehler: {str(e)}" + success = False + + return render_template('admin/update_database.html', message=message, success=success) \ No newline at end of file diff --git a/database/systades.db b/database/systades.db index c9cf76e..fc79cc0 100644 Binary files a/database/systades.db and b/database/systades.db differ diff --git a/models.py b/models.py index ae14f19..597b234 100644 --- a/models.py +++ b/models.py @@ -53,11 +53,20 @@ class User(db.Model, UserMixin): created_at = db.Column(db.DateTime, default=datetime.utcnow) is_active = db.Column(db.Boolean, default=True) role = db.Column(db.String(20), default="user") # 'user', 'admin', 'moderator' + bio = db.Column(db.Text, nullable=True) # Profil-Bio + location = db.Column(db.String(100), nullable=True) # Standort + website = db.Column(db.String(200), nullable=True) # Website + avatar = db.Column(db.String(200), nullable=True) # Profilbild-URL + last_login = db.Column(db.DateTime, nullable=True) # Letzter Login # Relationships threads = db.relationship('Thread', backref='creator', lazy=True) messages = db.relationship('Message', backref='author', lazy=True) projects = db.relationship('Project', backref='owner', lazy=True) + mindmaps = db.relationship('UserMindmap', backref='user', lazy=True) + thoughts = db.relationship('Thought', backref='author', lazy=True) + bookmarked_thoughts = db.relationship('Thought', secondary=user_thought_bookmark, + lazy='dynamic', backref=db.backref('bookmarked_by', lazy='dynamic')) def __repr__(self): return f'' @@ -67,6 +76,10 @@ class User(db.Model, UserMixin): def check_password(self, password): return check_password_hash(self.password, password) + + @property + def is_admin(self): + return self.role == 'admin' class Category(db.Model): """Wissenschaftliche Kategorien für die Gliederung der öffentlichen Mindmap""" diff --git a/templates/admin/update_database.html b/templates/admin/update_database.html new file mode 100644 index 0000000..2facee2 --- /dev/null +++ b/templates/admin/update_database.html @@ -0,0 +1,46 @@ +{% extends "base.html" %} + +{% block title %}Datenbank aktualisieren{% endblock %} + +{% block content %} +
+
+

Datenbank aktualisieren

+ + {% if message %} +
+

{{ message }}

+
+ {% endif %} + +
+

+ Diese Funktion aktualisiert die Datenbankstruktur, um mit dem aktuellen Datenmodell kompatibel zu sein. + Dabei werden folgende Änderungen vorgenommen: +

+ +
    +
  • Hinzufügen von bio, location, website, avatar und last_login zur Benutzer-Tabelle
  • +
+ +
+

+ + Warnung: Bitte stelle sicher, dass du ein Backup der Datenbank erstellt hast, bevor du fortfährst. +

+
+
+ +
+
+ + Zurück zur Startseite + + +
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/profile.html b/templates/profile.html index a243f45..e5700c2 100644 --- a/templates/profile.html +++ b/templates/profile.html @@ -559,6 +559,7 @@
Aktivitäten
Gedanken
+
Mindmaps
Sammlungen
Verbindungen
Einstellungen
@@ -632,6 +633,44 @@
+ + +