From 1d82999f69a4391da78ce7dfa9e032d04e95409c Mon Sep 17 00:00:00 2001 From: Quildra Date: Wed, 30 Oct 2024 21:02:27 +0000 Subject: [PATCH] - Adding in users to the site --- Site/OriginDex.py | 123 +++++++++++++++++++++++++++++++---- Site/templates/index.html | 15 ++++- Site/templates/login.html | 20 ++++++ Site/templates/register.html | 20 ++++++ 4 files changed, 163 insertions(+), 15 deletions(-) create mode 100644 Site/templates/login.html create mode 100644 Site/templates/register.html diff --git a/Site/OriginDex.py b/Site/OriginDex.py index ff47c8d..8b21478 100644 --- a/Site/OriginDex.py +++ b/Site/OriginDex.py @@ -1,11 +1,13 @@ import sqlite3 -from flask import Flask, render_template, jsonify +from flask import Flask, render_template, jsonify, request, redirect, url_for from collections import defaultdict import os import json import re import wordninja from typing import List, Set +from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user +from werkzeug.security import generate_password_hash, check_password_hash class CustomWordNinja: def __init__(self, custom_words: List[str] = None): @@ -54,6 +56,77 @@ POKEMON_PROPER_NOUNS = { } app = Flask(__name__) +app.secret_key = '8PQ46ThghoOUsmr4iPMHvrT91FESh9kHu' # Change this to a secure secret key +login_manager = LoginManager() +login_manager.init_app(app) +login_manager.login_view = 'login' + +class User(UserMixin): + def __init__(self, id, username): + self.id = id + self.username = username + +@login_manager.user_loader +def load_user(user_id): + conn = sqlite3.connect('user_data.db') + cursor = conn.cursor() + cursor.execute('SELECT id, username FROM users WHERE id = ?', (user_id,)) + user = cursor.fetchone() + conn.close() + + if user: + return User(user[0], user[1]) + return None + +# Add login/register routes +@app.route('/login', methods=['GET', 'POST']) +def login(): + if request.method == 'POST': + username = request.form.get('username') + password = request.form.get('password') + + conn = sqlite3.connect('user_data.db') + cursor = conn.cursor() + cursor.execute('SELECT id, password_hash FROM users WHERE username = ?', (username,)) + user = cursor.fetchone() + conn.close() + + if user and check_password_hash(user[1], password): + login_user(User(user[0], username)) + return redirect(url_for('index')) + + return 'Invalid username or password' + + return render_template('login.html') + +@app.route('/register', methods=['GET', 'POST']) +def register(): + if request.method == 'POST': + username = request.form.get('username') + password = request.form.get('password') + + conn = sqlite3.connect('user_data.db') + cursor = conn.cursor() + + try: + cursor.execute( + 'INSERT INTO users (username, password_hash) VALUES (?, ?)', + (username, generate_password_hash(password)) + ) + conn.commit() + conn.close() + return redirect(url_for('login')) + except sqlite3.IntegrityError: + conn.close() + return 'Username already exists' + + return render_template('register.html') + +@app.route('/logout') +@login_required +def logout(): + logout_user() + return redirect(url_for('index')) def load_pokemon_data(): pokemon_list = [] @@ -272,15 +345,27 @@ def pokemon_details(pfic): return jsonify(encounters) def init_user_db(): - """Initialize the user database and create necessary tables""" conn = sqlite3.connect('user_data.db') cursor = conn.cursor() - # Create the caught Pokemon table + # Create users table + cursor.execute(''' + CREATE TABLE IF NOT EXISTS users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT UNIQUE NOT NULL, + password_hash TEXT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + ''') + + # Modify caught_pokemon table to include user_id cursor.execute(''' CREATE TABLE IF NOT EXISTS caught_pokemon ( - pfic TEXT PRIMARY KEY, - caught_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + user_id INTEGER, + pfic TEXT, + caught_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (user_id, pfic), + FOREIGN KEY (user_id) REFERENCES users(id) ) ''') @@ -288,8 +373,9 @@ def init_user_db(): conn.close() @app.route('/toggle_catch/', methods=['POST']) +@login_required def toggle_catch(pfic): - # First verify PFIC exists in pokemon_forms.db + # Verify PFIC exists ref_conn = sqlite3.connect('pokemon_forms.db') ref_cursor = ref_conn.cursor() @@ -299,22 +385,27 @@ def toggle_catch(pfic): return jsonify({'error': 'Invalid PFIC'}), 400 ref_conn.close() - # Now handle the caught status in user_data.db user_conn = sqlite3.connect('user_data.db') user_cursor = user_conn.cursor() try: - # Check if Pokemon is already caught - user_cursor.execute('SELECT pfic FROM caught_pokemon WHERE pfic = ?', (pfic,)) + user_cursor.execute( + 'SELECT 1 FROM caught_pokemon WHERE user_id = ? AND pfic = ?', + (current_user.id, pfic) + ) result = user_cursor.fetchone() if result: - # Pokemon was caught, so uncatch it - user_cursor.execute('DELETE FROM caught_pokemon WHERE pfic = ?', (pfic,)) + user_cursor.execute( + 'DELETE FROM caught_pokemon WHERE user_id = ? AND pfic = ?', + (current_user.id, pfic) + ) status = 'uncaught' else: - # Pokemon wasn't caught, so catch it - user_cursor.execute('INSERT INTO caught_pokemon (pfic) VALUES (?)', (pfic,)) + user_cursor.execute( + 'INSERT INTO caught_pokemon (user_id, pfic) VALUES (?, ?)', + (current_user.id, pfic) + ) status = 'caught' user_conn.commit() @@ -327,11 +418,15 @@ def toggle_catch(pfic): user_conn.close() @app.route('/get_caught_pokemon') +@login_required def get_caught_pokemon(): user_conn = sqlite3.connect('user_data.db') user_cursor = user_conn.cursor() - user_cursor.execute('SELECT pfic FROM caught_pokemon') + user_cursor.execute( + 'SELECT pfic FROM caught_pokemon WHERE user_id = ?', + (current_user.id,) + ) caught = [row[0] for row in user_cursor.fetchall()] user_conn.close() diff --git a/Site/templates/index.html b/Site/templates/index.html index 99689c4..3cb978e 100644 --- a/Site/templates/index.html +++ b/Site/templates/index.html @@ -463,7 +463,20 @@
-

OriginDex

+
+

OriginDex

+ {% if current_user.is_authenticated %} + + {% else %} + + {% endif %} +
diff --git a/Site/templates/login.html b/Site/templates/login.html new file mode 100644 index 0000000..3bc545f --- /dev/null +++ b/Site/templates/login.html @@ -0,0 +1,20 @@ + + + + Login - OriginDex + + + + + + \ No newline at end of file diff --git a/Site/templates/register.html b/Site/templates/register.html new file mode 100644 index 0000000..7d20913 --- /dev/null +++ b/Site/templates/register.html @@ -0,0 +1,20 @@ + + + + Register - OriginDex + + + +
+

Register for OriginDex

+
+ + + +
+

Already have an account? Login

+
+ + \ No newline at end of file