br0tcabeln/app.py
2024-08-17 18:57:14 +02:00

235 lines
7.4 KiB
Python

from flask import Flask, request, jsonify, redirect, url_for, session, render_template
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from flask_session import Session
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
import random
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key' # Ändere dies zu einem echten geheimen Schlüssel
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///vocab.db'
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SESSION_PERMANENT'] = False
app.config['SESSION_USE_SIGNER'] = True
db = SQLAlchemy(app)
Session(app)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
# Models
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(150), unique=True, nullable=False)
password = db.Column(db.String(150), nullable=False)
vocabularies = db.relationship('Vocabulary', backref='owner', lazy=True)
class Vocabulary(db.Model):
id = db.Column(db.Integer, primary_key=True)
english = db.Column(db.String(100), nullable=False)
german = db.Column(db.String(100), nullable=False)
level = db.Column(db.Integer, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
def get_random_vocab(user_id):
vocab_list = Vocabulary.query.filter_by(user_id=user_id).all()
if not vocab_list:
return None
# Weight levels: Level 1 should be most common, Level 5 the least
weighted_vocab_list = []
for vocab in vocab_list:
weight = max(1, 6 - vocab.level) # Weight 5 for level 1, 4 for level 2, ..., 1 for level 5
weighted_vocab_list.extend([vocab] * weight)
return random.choice(weighted_vocab_list)
@app.route('/get_random_vocab', methods=['GET'])
@login_required
def get_random_vocab_route():
vocab = get_random_vocab(current_user.id)
if vocab:
return jsonify({
'english': vocab.english,
'german': vocab.german,
'level': vocab.level,
'id': vocab.id,
}), 200
return jsonify({'error': 'No vocabulary found'}), 404
@app.route('/update_vocab_level/<int:id>', methods=['POST'])
@login_required
def update_vocab_level(id):
vocab = Vocabulary.query.get(id)
if vocab and vocab.user_id == current_user.id:
if vocab.level < 5:
vocab.level += 1
db.session.commit()
return jsonify({'success': True}), 200
return jsonify({'message': 'Max level reached'}), 200
return jsonify({'error': 'Not found or unauthorized'}), 404
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
@app.route('/')
def index():
return render_template('start.html')
@app.route('/train')
@login_required
def train():
return render_template('train.html')
@app.route('/settings')
@login_required
def settings():
return render_template('settings.html')
@app.route('/vocab')
@login_required
def vocab():
return render_template('vocab.html')
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
if not username or not password:
return render_template('register.html', error='Username and password are required'), 400
existing_user = User.query.filter_by(username=username).first()
if existing_user:
return render_template('register.html', error='Username already taken'), 409 # 409 Conflict
hashed_password = generate_password_hash(password, method='pbkdf2:sha256')
new_user = User(username=username, password=hashed_password)
db.session.add(new_user)
db.session.commit()
return redirect(url_for('login'))
return render_template('register.html')
@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 check_password_hash(user.password, password):
login_user(user)
return jsonify({'success': True}), 200
else:
return jsonify({'error': 'Invalid credentials'}), 401
# GET request: render login page
return render_template('login.html')
@app.route('/logout', methods=['POST'])
@login_required
def logout():
logout_user()
return redirect(url_for('index'))
@app.route('/add_vocab', methods=['POST'])
@login_required
def add_vocab():
english = request.form.get('english')
german = request.form.get('german')
level = int(request.form.get('level', 1))
if not english or not german or not level:
return jsonify({'error': 'All fields are required'}), 400
vocab = Vocabulary(english=english, german=german, level=level, user_id=current_user.id)
try:
db.session.add(vocab)
db.session.commit()
return jsonify({'success': True}), 201
except Exception as e:
db.session.rollback()
return jsonify({'error': str(e)}), 500
@app.route('/update_vocab/<int:id>', methods=['PUT'])
@login_required
def update_vocab(id):
vocab = Vocabulary.query.get(id)
if not vocab or vocab.user_id != current_user.id:
return jsonify({'error': 'Not found or unauthorized'}), 404
english = request.json.get('english')
german = request.json.get('german')
level = request.json.get('level')
if english:
vocab.english = english
if german:
vocab.german = german
if level:
vocab.level = level
try:
db.session.commit()
return jsonify({'success': True}), 200
except Exception as e:
db.session.rollback()
return jsonify({'error': str(e)}), 500
@app.route('/delete_vocab/<int:id>', methods=['DELETE'])
@login_required
def delete_vocab(id):
vocab = Vocabulary.query.get(id)
if not vocab or vocab.user_id != current_user.id:
return jsonify({'error': 'Not found or unauthorized'}), 404
try:
db.session.delete(vocab)
db.session.commit()
return jsonify({'success': True}), 200
except Exception as e:
db.session.rollback()
return jsonify({'error': str(e)}), 500
@app.route('/get_vocab', methods=['GET'])
@login_required
def get_vocab():
vocab_list = Vocabulary.query.filter_by(user_id=current_user.id).all()
result = [{'id': v.id, 'english': v.english, 'german': v.german, 'level': v.level} for v in vocab_list]
return jsonify(result)
@app.route('/change_username', methods=['POST'])
@login_required
def change_username():
new_username = request.form.get('new_username')
if not new_username:
return jsonify({'error': 'Benutzername ist erforderlich'}), 400
if User.query.filter_by(username=new_username).first():
return jsonify({'error': 'Benutzername bereits vergeben'}), 409
current_user.username = new_username
try:
db.session.commit()
return jsonify({'success': True}), 200
except Exception as e:
db.session.rollback()
return jsonify({'error': str(e)}), 500
if __name__ == '__main__':
with app.app_context():
db.create_all()
app.run(debug=True)