From 0705ecce5996d72483d3f12d3cc97a2b321dd2f4 Mon Sep 17 00:00:00 2001 From: Till Tomczak Date: Sun, 27 Apr 2025 07:02:54 +0200 Subject: [PATCH] Implement database path configuration and enhance category management: Update database URI to use an absolute path, ensure directory creation for the database, and implement default category creation on initialization. Add new routes for searching thoughts and user account management, while improving the UI with navigation updates for better accessibility. --- website/__pycache__/app.cpython-311.pyc | Bin 57103 -> 51172 bytes website/app.py | 367 ++++++++++-------------- website/database/systades.db | Bin 0 -> 106496 bytes website/example.env | 3 +- website/init_db.py | 9 +- website/instance/mindmap.db | Bin 49152 -> 0 bytes website/templates/base.html | 18 +- 7 files changed, 176 insertions(+), 221 deletions(-) create mode 100644 website/database/systades.db delete mode 100644 website/instance/mindmap.db diff --git a/website/__pycache__/app.cpython-311.pyc b/website/__pycache__/app.cpython-311.pyc index 8e1da6b6d26f4d1a1f5e3a0555fc0766a0c3473b..1f4242025fa2901ff625a30ea012194771c3fb4c 100644 GIT binary patch delta 12744 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 D?T}nI diff --git a/website/app.py b/website/app.py index b23942e..84c35f4 100755 --- a/website/app.py +++ b/website/app.py @@ -21,15 +21,22 @@ from dotenv import load_dotenv # Modelle importieren from models import ( db, User, Thought, Comment, MindMapNode, ThoughtRelation, ThoughtRating, - RelationType, Category, UserMindmap, UserMindmapNode, MindmapNote + RelationType, Category, UserMindmap, UserMindmapNode, MindmapNote, + node_thought_association, user_thought_bookmark ) # Lade .env-Datei load_dotenv() +# Bestimme den absoluten Pfad zur Datenbank +basedir = os.path.abspath(os.path.dirname(__file__)) +db_path = os.path.join(basedir, 'database', 'systades.db') +# Stellen Sie sicher, dass das Verzeichnis existiert +os.makedirs(os.path.dirname(db_path), exist_ok=True) + app = Flask(__name__) app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'default-dev-key') -app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mindmap.db' +app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{db_path}' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=365) # Langlebige Session für Dark Mode-Einstellung @@ -67,103 +74,6 @@ def admin_required(f): return f(*args, **kwargs) return decorated_function -class RelationType(Enum): - SUPPORTS = "stützt" - CONTRADICTS = "widerspricht" - BUILDS_UPON = "baut auf auf" - GENERALIZES = "verallgemeinert" - SPECIFIES = "spezifiziert" - INSPIRES = "inspiriert" - -class ThoughtRelation(db.Model): - id = db.Column(db.Integer, primary_key=True) - source_id = db.Column(db.Integer, db.ForeignKey('thought.id'), nullable=False) - target_id = db.Column(db.Integer, db.ForeignKey('thought.id'), nullable=False) - relation_type = db.Column(db.Enum(RelationType), nullable=False) - created_at = db.Column(db.DateTime, default=datetime.utcnow) - created_by_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) - -class ThoughtRating(db.Model): - id = db.Column(db.Integer, primary_key=True) - thought_id = db.Column(db.Integer, db.ForeignKey('thought.id'), nullable=False) - user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) - relevance_score = db.Column(db.Integer, nullable=False) # 1-5 - created_at = db.Column(db.DateTime, default=datetime.utcnow) - - __table_args__ = ( - db.UniqueConstraint('thought_id', 'user_id', name='unique_thought_rating'), - ) - -# Database Models -class User(UserMixin, db.Model): - id = db.Column(db.Integer, primary_key=True) - username = db.Column(db.String(80), unique=True, nullable=False) - email = db.Column(db.String(120), unique=True, nullable=False) - password_hash = db.Column(db.String(128)) - is_admin = db.Column(db.Boolean, default=False) - thoughts = db.relationship('Thought', backref='author', lazy=True) - - def set_password(self, password): - self.password_hash = generate_password_hash(password) - - def check_password(self, password): - return check_password_hash(self.password_hash, password) - -class Thought(db.Model): - id = db.Column(db.Integer, primary_key=True) - content = db.Column(db.Text, nullable=False) - timestamp = db.Column(db.DateTime, default=datetime.utcnow) - branch = db.Column(db.String(100), nullable=False) - user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) - title = db.Column(db.String(200), nullable=False) - abstract = db.Column(db.Text) - keywords = db.Column(db.String(500)) - color_code = db.Column(db.String(7)) # Hex color code - source_type = db.Column(db.String(50)) # PDF, Markdown, Text etc. - - comments = db.relationship('Comment', backref='thought', lazy=True, cascade="all, delete-orphan") - ratings = db.relationship('ThoughtRating', backref='thought', lazy=True) - - outgoing_relations = db.relationship( - 'ThoughtRelation', - foreign_keys=[ThoughtRelation.source_id], - backref='source_thought', - lazy=True - ) - incoming_relations = db.relationship( - 'ThoughtRelation', - foreign_keys=[ThoughtRelation.target_id], - backref='target_thought', - lazy=True - ) - - @property - def average_rating(self): - if not self.ratings: - return 0 - return sum(r.relevance_score for r in self.ratings) / len(self.ratings) - -class Comment(db.Model): - id = db.Column(db.Integer, primary_key=True) - content = db.Column(db.Text, nullable=False) - timestamp = db.Column(db.DateTime, default=datetime.utcnow) - thought_id = db.Column(db.Integer, db.ForeignKey('thought.id'), nullable=False) - user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) - author = db.relationship('User', backref='comments') - -class MindMapNode(db.Model): - id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.String(100), nullable=False) - parent_id = db.Column(db.Integer, db.ForeignKey('mind_map_node.id'), nullable=True) - children = db.relationship('MindMapNode', backref=db.backref('parent', remote_side=[id])) - thoughts = db.relationship('Thought', secondary='node_thought_association', backref='nodes') - -# Association table for many-to-many relationship between MindMapNode and Thought -node_thought_association = db.Table('node_thought_association', - db.Column('node_id', db.Integer, db.ForeignKey('mind_map_node.id'), primary_key=True), - db.Column('thought_id', db.Integer, db.ForeignKey('thought.id'), primary_key=True) -) - @login_manager.user_loader def load_user(id): return User.query.get(int(id)) @@ -234,6 +144,13 @@ def index(): # Route for the mindmap page @app.route('/mindmap') def mindmap(): + """Zeigt die öffentliche Mindmap an.""" + # Sicherstellen, dass wir Kategorien haben + with app.app_context(): + if Category.query.count() == 0: + create_default_categories() + + # Hole alle Kategorien der obersten Ebene categories = Category.query.filter_by(parent_id=None).all() return render_template('mindmap.html', categories=categories) @@ -690,8 +607,10 @@ def get_mindmap(): root_nodes = MindMapNode.query.filter_by(parent_id=None).all() if not root_nodes: - # Wenn keine Nodes existieren, erstelle Beispieldaten - create_sample_mindmap() + # Wenn keine Nodes existieren, rufen wir initialize_database direkt auf + # anstatt create_sample_mindmap zu verwenden + with app.app_context(): + initialize_database() root_nodes = MindMapNode.query.filter_by(parent_id=None).all() # Ergebnisse in hierarchischer Struktur zurückgeben @@ -1039,7 +958,118 @@ def chat_with_assistant(): }), 500 # App-Kontext-Funktion für Initialisierung der Datenbank -@app.before_first_request +def create_default_categories(): + """Erstellt die Standard-Kategorien und wissenschaftlichen Bereiche.""" + categories = [ + { + 'name': 'Naturwissenschaften', + 'description': 'Empirische Untersuchung und Erklärung natürlicher Phänomene', + 'color_code': '#4CAF50', + 'icon': 'flask', + 'children': [ + { + 'name': 'Physik', + 'description': 'Studium der Materie, Energie und deren Wechselwirkungen', + 'color_code': '#81C784', + 'icon': 'atom' + }, + { + 'name': 'Biologie', + 'description': 'Wissenschaft des Lebens und lebender Organismen', + 'color_code': '#66BB6A', + 'icon': 'leaf' + }, + { + 'name': 'Chemie', + 'description': 'Wissenschaft der Materie, ihrer Eigenschaften und Reaktionen', + 'color_code': '#A5D6A7', + 'icon': 'vial' + } + ] + }, + { + 'name': 'Sozialwissenschaften', + 'description': 'Untersuchung von Gesellschaft und menschlichem Verhalten', + 'color_code': '#2196F3', + 'icon': 'users', + 'children': [ + { + 'name': 'Psychologie', + 'description': 'Wissenschaftliches Studium des Geistes und Verhaltens', + 'color_code': '#64B5F6', + 'icon': 'brain' + }, + { + 'name': 'Soziologie', + 'description': 'Studium sozialer Beziehungen und Institutionen', + 'color_code': '#42A5F5', + 'icon': 'network-wired' + } + ] + }, + { + 'name': 'Geisteswissenschaften', + 'description': 'Studium menschlicher Kultur und Kreativität', + 'color_code': '#9C27B0', + 'icon': 'book', + 'children': [ + { + 'name': 'Philosophie', + 'description': 'Untersuchung grundlegender Fragen über Existenz, Wissen und Ethik', + 'color_code': '#BA68C8', + 'icon': 'lightbulb' + }, + { + 'name': 'Geschichte', + 'description': 'Studium der Vergangenheit und ihres Einflusses auf die Gegenwart', + 'color_code': '#AB47BC', + 'icon': 'landmark' + }, + { + 'name': 'Literatur', + 'description': 'Studium literarischer Werke und ihrer Bedeutung', + 'color_code': '#CE93D8', + 'icon': 'feather' + } + ] + }, + { + 'name': 'Technologie', + 'description': 'Anwendung wissenschaftlicher Erkenntnisse für praktische Zwecke', + 'color_code': '#FF9800', + 'icon': 'microchip', + 'children': [ + { + 'name': 'Informatik', + 'description': 'Studium von Computern und Berechnungssystemen', + 'color_code': '#FFB74D', + 'icon': 'laptop-code' + }, + { + 'name': 'Künstliche Intelligenz', + 'description': 'Entwicklung intelligenter Maschinen und Software', + 'color_code': '#FFA726', + 'icon': 'robot' + } + ] + } + ] + + # Kategorien in die Datenbank einfügen + for category_data in categories: + children_data = category_data.pop('children', []) + category = Category(**category_data) + db.session.add(category) + db.session.flush() # Um die ID zu generieren + + # Unterkategorien hinzufügen + for child_data in children_data: + child = Category(**child_data, parent_id=category.id) + db.session.add(child) + + db.session.commit() + print("Standard-Kategorien wurden erstellt!") + def initialize_database(): """Initialisiert die Datenbank, falls sie noch nicht existiert.""" db.create_all() @@ -1048,119 +1078,26 @@ def initialize_database(): if Category.query.count() == 0: create_default_categories() -def create_default_categories(): - """Erstellt die Standard-Kategorien und wissenschaftlichen Bereiche.""" - with app.app_context(): - # Hauptkategorien erstellen - categories = [ - { - 'name': 'Naturwissenschaften', - 'description': 'Empirische Untersuchung und Erklärung natürlicher Phänomene', - 'color_code': '#4CAF50', - 'icon': 'flask', - 'children': [ - { - 'name': 'Physik', - 'description': 'Studium der Materie, Energie und deren Wechselwirkungen', - 'color_code': '#81C784', - 'icon': 'atom' - }, - { - 'name': 'Biologie', - 'description': 'Wissenschaft des Lebens und lebender Organismen', - 'color_code': '#66BB6A', - 'icon': 'leaf' - }, - { - 'name': 'Chemie', - 'description': 'Wissenschaft der Materie, ihrer Eigenschaften und Reaktionen', - 'color_code': '#A5D6A7', - 'icon': 'vial' - } - ] - }, - { - 'name': 'Sozialwissenschaften', - 'description': 'Untersuchung von Gesellschaft und menschlichem Verhalten', - 'color_code': '#2196F3', - 'icon': 'users', - 'children': [ - { - 'name': 'Psychologie', - 'description': 'Wissenschaftliches Studium des Geistes und Verhaltens', - 'color_code': '#64B5F6', - 'icon': 'brain' - }, - { - 'name': 'Soziologie', - 'description': 'Studium sozialer Beziehungen und Institutionen', - 'color_code': '#42A5F5', - 'icon': 'network-wired' - } - ] - }, - { - 'name': 'Geisteswissenschaften', - 'description': 'Studium menschlicher Kultur und Kreativität', - 'color_code': '#9C27B0', - 'icon': 'book', - 'children': [ - { - 'name': 'Philosophie', - 'description': 'Untersuchung grundlegender Fragen über Existenz, Wissen und Ethik', - 'color_code': '#BA68C8', - 'icon': 'lightbulb' - }, - { - 'name': 'Geschichte', - 'description': 'Studium der Vergangenheit und ihres Einflusses auf die Gegenwart', - 'color_code': '#AB47BC', - 'icon': 'landmark' - }, - { - 'name': 'Literatur', - 'description': 'Studium literarischer Werke und ihrer Bedeutung', - 'color_code': '#CE93D8', - 'icon': 'feather' - } - ] - }, - { - 'name': 'Technologie', - 'description': 'Anwendung wissenschaftlicher Erkenntnisse für praktische Zwecke', - 'color_code': '#FF9800', - 'icon': 'microchip', - 'children': [ - { - 'name': 'Informatik', - 'description': 'Studium von Computern und Berechnungssystemen', - 'color_code': '#FFB74D', - 'icon': 'laptop-code' - }, - { - 'name': 'Künstliche Intelligenz', - 'description': 'Entwicklung intelligenter Maschinen und Software', - 'color_code': '#FFA726', - 'icon': 'robot' - } - ] - } - ] - - # Kategorien in die Datenbank einfügen - for category_data in categories: - children_data = category_data.pop('children', []) - category = Category(**category_data) - db.session.add(category) - db.session.flush() # Um die ID zu generieren - - # Unterkategorien hinzufügen - for child_data in children_data: - child = Category(**child_data, parent_id=category.id) - db.session.add(child) - - db.session.commit() - print("Standard-Kategorien wurden erstellt!") +# Führe die Datenbankinitialisierung beim Starten der App aus +with app.app_context(): + initialize_database() + +@app.route('/search') +def search_thoughts_page(): + """Seite zur Gedankensuche anzeigen.""" + return render_template('search.html') + +@app.route('/my_account') +def my_account(): + """Zeigt die persönliche Merkliste an.""" + if not current_user.is_authenticated: + flash('Bitte melde dich an, um auf deine Merkliste zuzugreifen.', 'warning') + return redirect(url_for('login')) + + # Hole die Lesezeichen des Benutzers + bookmarked_thoughts = current_user.bookmarked_thoughts + + return render_template('my_account.html', bookmarked_thoughts=bookmarked_thoughts) # Flask starten if __name__ == '__main__': diff --git a/website/database/systades.db b/website/database/systades.db new file mode 100644 index 0000000000000000000000000000000000000000..ee1415381e380b4d59b03fa2dbfbd6799873312d GIT binary patch literal 106496 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 literal 0 HcmV?d00001 diff --git a/website/example.env b/website/example.env index 035e4a2..831801d 100644 --- a/website/example.env +++ b/website/example.env @@ -9,4 +9,5 @@ OPENAI_API_KEY=sk-dein-openai-api-schluessel-hier # Datenbank # Bei Bedarf kann hier eine andere Datenbank-URL angegeben werden -# SQLALCHEMY_DATABASE_URI=sqlite:///mindmap.db \ No newline at end of file +# Der Pfad wird relativ zum Projektverzeichnis angegeben +# SQLALCHEMY_DATABASE_URI=sqlite:////absoluter/pfad/zu/database/systades.db \ No newline at end of file diff --git a/website/init_db.py b/website/init_db.py index 4e0ab66..4a46282 100755 --- a/website/init_db.py +++ b/website/init_db.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from app import app, initialize_database +from app import app, initialize_database, db_path from models import db, User, Thought, Comment, MindMapNode, ThoughtRelation, ThoughtRating, RelationType from models import Category, UserMindmap, UserMindmapNode, MindmapNote import os @@ -10,8 +10,11 @@ def init_database(): """Initialisiert die Datenbank mit Beispieldaten.""" with app.app_context(): # Datenbank löschen und neu erstellen - if os.path.exists('instance/mindmap.db'): - os.remove('instance/mindmap.db') + if os.path.exists(db_path): + os.remove(db_path) + + # Stellen Sie sicher, dass das Verzeichnis existiert + os.makedirs(os.path.dirname(db_path), exist_ok=True) db.create_all() diff --git a/website/instance/mindmap.db b/website/instance/mindmap.db deleted file mode 100644 index 1db9c4d6eef2c9847f9474421a3f2b90b30ce84e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49152 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 NdG}wM3X8HV{R{2Crgs1U diff --git a/website/templates/base.html b/website/templates/base.html index 688d036..b20d577 100644 --- a/website/templates/base.html +++ b/website/templates/base.html @@ -545,8 +545,8 @@