import datetime import hashlib from flask import Flask, render_template, redirect, url_for, request from flask_login import login_required, LoginManager, login_user, logout_user, current_user from models.Habit import Habit from models.HabitTrackings import HabitTrackings from models.User import User from utils import anonymous_required # Create a new Flask instance app = Flask(__name__) app.secret_key = 'PSSSSSHHHT!' # Initialize the Flask-Login extension login_manager = LoginManager() login_manager.login_view = 'login' login_manager.init_app(app) @login_manager.user_loader def load_user(user_id): return User.get(user_id) @app.context_processor def inject_user(): return dict(user=current_user) @app.route('/login') @anonymous_required def login(): return render_template('auth/login.html', errors={}) @app.route('/signup') @anonymous_required def signup(): return render_template('auth/signup.html', errors={}) @app.route('/login', methods=['POST']) def login_post(): email = request.form.get('email') password = request.form.get('password') # Check for errors errors = {} if not email: errors['email'] = 'Die E-Mail Adresse ist erforderlich.' if not password: errors['password'] = 'Das Passwort ist erforderlich.' # Check if user exists user = User.get_by_email(email) if not user: errors['email'] = 'E-Mail Adresse nicht gefunden.' elif user.password is None or hashlib.sha256(password.encode()).hexdigest() != user.password: errors['password'] = 'Das Passwort ist falsch.' if errors: return render_template( 'auth/login.html', email=email, password=password, errors=errors ) login_user(user) # Redirect to login page return redirect(url_for('index')) @app.route('/signup', methods=['POST']) def signup_post(): email = request.form.get('email') name = request.form.get('name') password = request.form.get('password') # Check for errors errors = {} if not email: errors['email'] = 'Die E-Mail Adresse ist erforderlich.' if not name: errors['name'] = 'Der Name ist erforderlich.' if not password: errors['password'] = 'Das Passwort ist erforderlich.' if errors: return render_template( 'auth/signup.html', email=email, name=name, password=password, errors=errors ) # Save user to database. Maybe log the user in directly. user = User.create(name, email, password) login_user(user) # Redirect to login page return redirect(url_for('index')) @app.route('/logout') @login_required def logout(): # Log out functionality logout_user() return redirect(url_for('index')) # Create a new route @app.route('/') def index(): if current_user.is_authenticated: habits = current_user.get_habits() name = "Hallo " + current_user.name else: habits = [] name = "Bitte melde dich an, du Vollhorst." # Add checked attribute to habits (if they have been checked today) for habit in habits: trackings = habit.get_habitTrackings() for tracking in trackings: # day if habit.unit == 0: if tracking.created_at.date() == datetime.date.today(): habit.checked = True break # week elif habit.unit == 1: if tracking.created_at.date().isocalendar()[1] == datetime.date.today().isocalendar()[1]: habit.checked = True break # month elif habit.unit == 2: if tracking.created_at.date().month == datetime.date.today().month: habit.checked = True break # year elif habit.unit == 3: if tracking.created_at.date().year == datetime.date.today().year: habit.checked = True break else: habit.checked = False # Sort habits by whether they have been checked today and then by slot habits.sort(key=lambda habit: (habit.checked, habit.slot)) return render_template( 'index.html', title=name, utc_dt=datetime.datetime.now().strftime("%d.%m.%Y %H:%M %A"), habits=habits, errors={}, ) @app.route('/habit') @login_required def habit_creation(): return render_template( 'habit.html', title='Erstelle ein Habit', unit=1, errors={}, ) @app.route('/habit', methods=['POST']) @login_required def habit_create(): name = request.form.get('name') note = request.form.get('note') times = request.form.get('times') unit = request.form.get('unit') # Check for errors errors = {} if not name: errors['name'] = 'Der Name ist erforderlich.' if not times: errors['times'] = 'Die Anzahl ist erforderlich.' if not note: note = '' if not unit: errors['unit'] = 'Die Einheit ist erforderlich.' # Check if times is an integer try: times = int(times) # Check that times is greater than 0 if times <= 0: errors['times'] = 'Die Anzahl muss größer als 0 sein.' except ValueError: errors['times'] = 'Die Anzahl muss eine Zahl sein.' # Check that unit is valid if unit not in ['Tag', 'Woche', 'Monat', 'Jahr']: errors['unit'] = 'Die Einheit ist ungültig.' if errors: return render_template( 'habit.html', title='Erstelle ein Habit', name=name, note=note, times=times, unit=unit, errors=errors ) # Map unit to integer if unit == 'Tag': unit = 0 elif unit == 'Woche': unit = 1 elif unit == 'Monat': unit = 2 elif unit == 'Jahr': unit = 3 else: unit = 1 # Save habit to database habit = Habit.create(current_user.id, name, times, note, unit) # Back to index return redirect(url_for('index')) """return render_template( 'habit.html', title='Erstelle ein Habit', name=name, note=note, times=times, unit=unit, errors=errors, )""" @app.route('/check', methods=['POST']) @login_required def check_habit(): habit_id = request.get_json()["habitId"] habit = Habit.get(habit_id) if habit is None: return {"error": "Habit not found"} # Check if habit belongs to user if habit.user_id != current_user.id: return {"error": "Habit does not belong to user"} trackings = habit.get_habitTrackings() # Check if habit has been tracked today delete_tracking = None for tracking in trackings: # day if habit.unit == 0: if tracking.created_at.date() == datetime.date.today(): delete_tracking = tracking break # week elif habit.unit == 1: if tracking.created_at.date().isocalendar()[1] == datetime.date.today().isocalendar()[1]: delete_tracking = tracking break # month elif habit.unit == 2: if tracking.created_at.date().month == datetime.date.today().month: delete_tracking = tracking break # year elif habit.unit == 3: if tracking.created_at.date().year == datetime.date.today().year: delete_tracking = tracking break if not delete_tracking: HabitTrackings.create(habit_id, 1) else: delete_tracking.delete() return { "habitId": habit_id, "unchecked": not delete_tracking } # Run the application if __name__ == '__main__': app.run(port=5000, debug=True)