Add user authentication routes: implement login, registration, and logout functionality, along with user profile and admin routes. Enhance mindmap API with error handling and default node creation.
This commit is contained in:
415
website/app.py
415
website/app.py
@@ -31,6 +31,204 @@ def create_app():
|
||||
except Exception as e:
|
||||
print(f"Error initializing database: {str(e)}")
|
||||
|
||||
# Register all routes with the app
|
||||
@login_manager.user_loader
|
||||
def load_user(id):
|
||||
return User.query.get(int(id))
|
||||
|
||||
@app.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
if request.method == 'POST':
|
||||
username = request.form.get('username')
|
||||
password = request.form.get('password')
|
||||
|
||||
user = User.query.filter_by(username=username).first()
|
||||
if user and user.check_password(password):
|
||||
login_user(user)
|
||||
next_page = request.args.get('next')
|
||||
return redirect(next_page or url_for('index'))
|
||||
flash('Ungültiger Benutzername oder Passwort')
|
||||
return render_template('login.html')
|
||||
|
||||
@app.route('/register', methods=['GET', 'POST'])
|
||||
def register():
|
||||
if request.method == 'POST':
|
||||
username = request.form.get('username')
|
||||
email = request.form.get('email')
|
||||
password = request.form.get('password')
|
||||
|
||||
if User.query.filter_by(username=username).first():
|
||||
flash('Benutzername existiert bereits')
|
||||
return redirect(url_for('register'))
|
||||
|
||||
if User.query.filter_by(email=email).first():
|
||||
flash('E-Mail ist bereits registriert')
|
||||
return redirect(url_for('register'))
|
||||
|
||||
user = User(username=username, email=email)
|
||||
user.set_password(password)
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
||||
login_user(user)
|
||||
return redirect(url_for('index'))
|
||||
return render_template('register.html')
|
||||
|
||||
@app.route('/logout')
|
||||
@login_required
|
||||
def logout():
|
||||
logout_user()
|
||||
return redirect(url_for('index'))
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
@app.route('/mindmap')
|
||||
def mindmap():
|
||||
try:
|
||||
root_node = MindMapNode.query.filter_by(parent_id=None).first()
|
||||
if not root_node:
|
||||
root_node = MindMapNode(name="Wissenschaft")
|
||||
db.session.add(root_node)
|
||||
db.session.commit()
|
||||
return render_template('mindmap.html')
|
||||
except Exception as e:
|
||||
app.logger.error(f"Error loading mindmap: {str(e)}")
|
||||
return render_template('mindmap.html', error="Fehler beim Laden der Mindmap. Bitte versuchen Sie es erneut.")
|
||||
|
||||
@app.route('/profile')
|
||||
@login_required
|
||||
def profile():
|
||||
thoughts = Thought.query.filter_by(user_id=current_user.id).order_by(Thought.timestamp.desc()).all()
|
||||
return render_template('profile.html', thoughts=thoughts)
|
||||
|
||||
@app.route('/api/mindmap')
|
||||
def get_mindmap():
|
||||
try:
|
||||
root_nodes = MindMapNode.query.filter_by(parent_id=None).all()
|
||||
|
||||
def build_tree(node):
|
||||
return {
|
||||
'id': node.id,
|
||||
'name': node.name,
|
||||
'children': [build_tree(child) for child in node.children]
|
||||
}
|
||||
|
||||
result = [build_tree(node) for node in root_nodes]
|
||||
if not result:
|
||||
root = MindMapNode(name="Wissenschaft")
|
||||
db.session.add(root)
|
||||
db.session.commit()
|
||||
result = [build_tree(root)]
|
||||
|
||||
return jsonify(result)
|
||||
except Exception as e:
|
||||
app.logger.error(f"Error in get_mindmap: {str(e)}")
|
||||
return jsonify({'error': 'Fehler beim Laden der Mindmap'}), 500
|
||||
|
||||
@app.route('/api/thoughts/<int:node_id>', methods=['GET'])
|
||||
def get_thoughts(node_id):
|
||||
node = MindMapNode.query.get_or_404(node_id)
|
||||
thoughts = []
|
||||
|
||||
for thought in node.thoughts:
|
||||
thoughts.append({
|
||||
'id': thought.id,
|
||||
'content': thought.content,
|
||||
'author': thought.author.username,
|
||||
'timestamp': thought.timestamp.strftime('%d.%m.%Y, %H:%M'),
|
||||
'comments_count': len(thought.comments),
|
||||
'branch': thought.branch
|
||||
})
|
||||
|
||||
return jsonify(thoughts)
|
||||
|
||||
@app.route('/api/thoughts', methods=['POST'])
|
||||
@login_required
|
||||
def add_thought():
|
||||
data = request.json
|
||||
node_id = data.get('node_id')
|
||||
content = data.get('content')
|
||||
|
||||
if not node_id or not content:
|
||||
return jsonify({'error': 'Fehlende Daten'}), 400
|
||||
|
||||
node = MindMapNode.query.get_or_404(node_id)
|
||||
|
||||
thought = Thought(
|
||||
content=content,
|
||||
branch=node.name,
|
||||
user_id=current_user.id
|
||||
)
|
||||
|
||||
db.session.add(thought)
|
||||
node.thoughts.append(thought)
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({
|
||||
'id': thought.id,
|
||||
'content': thought.content,
|
||||
'author': thought.author.username,
|
||||
'timestamp': thought.timestamp.strftime('%d.%m.%Y, %H:%M'),
|
||||
'branch': thought.branch
|
||||
})
|
||||
|
||||
@app.route('/api/comments/<int:thought_id>', methods=['GET'])
|
||||
def get_comments(thought_id):
|
||||
thought = Thought.query.get_or_404(thought_id)
|
||||
comments = [
|
||||
{
|
||||
'id': comment.id,
|
||||
'content': comment.content,
|
||||
'author': comment.author.username,
|
||||
'timestamp': comment.timestamp.strftime('%d.%m.%Y, %H:%M')
|
||||
}
|
||||
for comment in thought.comments
|
||||
]
|
||||
return jsonify(comments)
|
||||
|
||||
@app.route('/api/comments', methods=['POST'])
|
||||
@login_required
|
||||
def add_comment():
|
||||
data = request.json
|
||||
thought_id = data.get('thought_id')
|
||||
content = data.get('content')
|
||||
|
||||
if not thought_id or not content:
|
||||
return jsonify({'error': 'Fehlende Daten'}), 400
|
||||
|
||||
thought = Thought.query.get_or_404(thought_id)
|
||||
|
||||
comment = Comment(
|
||||
content=content,
|
||||
thought_id=thought_id,
|
||||
user_id=current_user.id
|
||||
)
|
||||
|
||||
db.session.add(comment)
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({
|
||||
'id': comment.id,
|
||||
'content': comment.content,
|
||||
'author': comment.author.username,
|
||||
'timestamp': comment.timestamp.strftime('%d.%m.%Y, %H:%M')
|
||||
})
|
||||
|
||||
@app.route('/admin')
|
||||
@login_required
|
||||
def admin():
|
||||
if not current_user.is_admin:
|
||||
flash('Zugriff verweigert')
|
||||
return redirect(url_for('index'))
|
||||
|
||||
users = User.query.all()
|
||||
nodes = MindMapNode.query.all()
|
||||
thoughts = Thought.query.all()
|
||||
|
||||
return render_template('admin.html', users=users, nodes=nodes, thoughts=thoughts)
|
||||
|
||||
return app
|
||||
|
||||
# Database Models
|
||||
@@ -77,223 +275,6 @@ node_thought_association = db.Table('node_thought_association',
|
||||
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))
|
||||
|
||||
# Routes for authentication
|
||||
@app.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
if request.method == 'POST':
|
||||
username = request.form.get('username')
|
||||
password = request.form.get('password')
|
||||
|
||||
user = User.query.filter_by(username=username).first()
|
||||
if user and user.check_password(password):
|
||||
login_user(user)
|
||||
next_page = request.args.get('next')
|
||||
return redirect(next_page or url_for('index'))
|
||||
flash('Ungültiger Benutzername oder Passwort')
|
||||
return render_template('login.html')
|
||||
|
||||
@app.route('/register', methods=['GET', 'POST'])
|
||||
def register():
|
||||
if request.method == 'POST':
|
||||
username = request.form.get('username')
|
||||
email = request.form.get('email')
|
||||
password = request.form.get('password')
|
||||
|
||||
if User.query.filter_by(username=username).first():
|
||||
flash('Benutzername existiert bereits')
|
||||
return redirect(url_for('register'))
|
||||
|
||||
if User.query.filter_by(email=email).first():
|
||||
flash('E-Mail ist bereits registriert')
|
||||
return redirect(url_for('register'))
|
||||
|
||||
user = User(username=username, email=email)
|
||||
user.set_password(password)
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
||||
login_user(user)
|
||||
return redirect(url_for('index'))
|
||||
return render_template('register.html')
|
||||
|
||||
@app.route('/logout')
|
||||
@login_required
|
||||
def logout():
|
||||
logout_user()
|
||||
return redirect(url_for('index'))
|
||||
|
||||
# Route for the homepage
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
# Route for the mindmap page
|
||||
@app.route('/mindmap')
|
||||
def mindmap():
|
||||
try:
|
||||
root_node = MindMapNode.query.filter_by(parent_id=None).first()
|
||||
if not root_node:
|
||||
root_node = MindMapNode(name="Wissenschaft")
|
||||
db.session.add(root_node)
|
||||
db.session.commit()
|
||||
return render_template('mindmap.html')
|
||||
except Exception as e:
|
||||
app.logger.error(f"Error loading mindmap: {str(e)}")
|
||||
return render_template('mindmap.html', error="Fehler beim Laden der Mindmap. Bitte versuchen Sie es erneut.")
|
||||
|
||||
# Route for user profile
|
||||
@app.route('/profile')
|
||||
@login_required
|
||||
def profile():
|
||||
thoughts = Thought.query.filter_by(user_id=current_user.id).order_by(Thought.timestamp.desc()).all()
|
||||
return render_template('profile.html', thoughts=thoughts)
|
||||
|
||||
# API routes for mindmap and thoughts
|
||||
@app.route('/api/mindmap')
|
||||
def get_mindmap():
|
||||
try:
|
||||
root_nodes = MindMapNode.query.filter_by(parent_id=None).all()
|
||||
|
||||
def build_tree(node):
|
||||
return {
|
||||
'id': node.id,
|
||||
'name': node.name,
|
||||
'children': [build_tree(child) for child in node.children]
|
||||
}
|
||||
|
||||
result = [build_tree(node) for node in root_nodes]
|
||||
if not result:
|
||||
# Create default root if no nodes exist
|
||||
root = MindMapNode(name="Wissenschaft")
|
||||
db.session.add(root)
|
||||
db.session.commit()
|
||||
result = [build_tree(root)]
|
||||
|
||||
return jsonify(result)
|
||||
except Exception as e:
|
||||
app.logger.error(f"Error in get_mindmap: {str(e)}")
|
||||
return jsonify({'error': 'Fehler beim Laden der Mindmap'}), 500
|
||||
|
||||
@app.route('/api/thoughts/<int:node_id>', methods=['GET'])
|
||||
def get_thoughts(node_id):
|
||||
node = MindMapNode.query.get_or_404(node_id)
|
||||
thoughts = []
|
||||
|
||||
for thought in node.thoughts:
|
||||
thoughts.append({
|
||||
'id': thought.id,
|
||||
'content': thought.content,
|
||||
'author': thought.author.username,
|
||||
'timestamp': thought.timestamp.strftime('%d.%m.%Y, %H:%M'),
|
||||
'comments_count': len(thought.comments),
|
||||
'branch': thought.branch
|
||||
})
|
||||
|
||||
return jsonify(thoughts)
|
||||
|
||||
@app.route('/api/thought/<int:thought_id>', methods=['GET'])
|
||||
def get_thought(thought_id):
|
||||
thought = Thought.query.get_or_404(thought_id)
|
||||
|
||||
return jsonify({
|
||||
'id': thought.id,
|
||||
'content': thought.content,
|
||||
'author': thought.author.username,
|
||||
'timestamp': thought.timestamp.strftime('%d.%m.%Y, %H:%M'),
|
||||
'branch': thought.branch,
|
||||
'comments_count': len(thought.comments)
|
||||
})
|
||||
|
||||
@app.route('/api/thoughts', methods=['POST'])
|
||||
@login_required
|
||||
def add_thought():
|
||||
data = request.json
|
||||
node_id = data.get('node_id')
|
||||
content = data.get('content')
|
||||
|
||||
if not node_id or not content:
|
||||
return jsonify({'error': 'Fehlende Daten'}), 400
|
||||
|
||||
node = MindMapNode.query.get_or_404(node_id)
|
||||
|
||||
thought = Thought(
|
||||
content=content,
|
||||
branch=node.name,
|
||||
user_id=current_user.id
|
||||
)
|
||||
|
||||
db.session.add(thought)
|
||||
node.thoughts.append(thought)
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({
|
||||
'id': thought.id,
|
||||
'content': thought.content,
|
||||
'author': thought.author.username,
|
||||
'timestamp': thought.timestamp.strftime('%d.%m.%Y, %H:%M'),
|
||||
'branch': thought.branch
|
||||
})
|
||||
|
||||
@app.route('/api/comments/<int:thought_id>', methods=['GET'])
|
||||
def get_comments(thought_id):
|
||||
thought = Thought.query.get_or_404(thought_id)
|
||||
comments = [
|
||||
{
|
||||
'id': comment.id,
|
||||
'content': comment.content,
|
||||
'author': comment.author.username,
|
||||
'timestamp': comment.timestamp.strftime('%d.%m.%Y, %H:%M')
|
||||
}
|
||||
for comment in thought.comments
|
||||
]
|
||||
return jsonify(comments)
|
||||
|
||||
@app.route('/api/comments', methods=['POST'])
|
||||
@login_required
|
||||
def add_comment():
|
||||
data = request.json
|
||||
thought_id = data.get('thought_id')
|
||||
content = data.get('content')
|
||||
|
||||
if not thought_id or not content:
|
||||
return jsonify({'error': 'Fehlende Daten'}), 400
|
||||
|
||||
thought = Thought.query.get_or_404(thought_id)
|
||||
|
||||
comment = Comment(
|
||||
content=content,
|
||||
thought_id=thought_id,
|
||||
user_id=current_user.id
|
||||
)
|
||||
|
||||
db.session.add(comment)
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({
|
||||
'id': comment.id,
|
||||
'content': comment.content,
|
||||
'author': comment.author.username,
|
||||
'timestamp': comment.timestamp.strftime('%d.%m.%Y, %H:%M')
|
||||
})
|
||||
|
||||
# Admin routes
|
||||
@app.route('/admin')
|
||||
@login_required
|
||||
def admin():
|
||||
if not current_user.is_admin:
|
||||
flash('Zugriff verweigert')
|
||||
return redirect(url_for('index'))
|
||||
|
||||
users = User.query.all()
|
||||
nodes = MindMapNode.query.all()
|
||||
thoughts = Thought.query.all()
|
||||
|
||||
return render_template('admin.html', users=users, nodes=nodes, thoughts=thoughts)
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = create_app()
|
||||
app.run(host="0.0.0.0", port=6000, debug=True)
|
||||
Reference in New Issue
Block a user