|
|
@ -1,11 +1,13 @@ |
|
|
import sqlite3 |
|
|
import sqlite3 |
|
|
from flask import Flask, render_template, jsonify |
|
|
from flask import Flask, render_template, jsonify, request, redirect, url_for |
|
|
from collections import defaultdict |
|
|
from collections import defaultdict |
|
|
import os |
|
|
import os |
|
|
import json |
|
|
import json |
|
|
import re |
|
|
import re |
|
|
import wordninja |
|
|
import wordninja |
|
|
from typing import List, Set |
|
|
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: |
|
|
class CustomWordNinja: |
|
|
def __init__(self, custom_words: List[str] = None): |
|
|
def __init__(self, custom_words: List[str] = None): |
|
|
@ -54,6 +56,77 @@ POKEMON_PROPER_NOUNS = { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
app = Flask(__name__) |
|
|
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(): |
|
|
def load_pokemon_data(): |
|
|
pokemon_list = [] |
|
|
pokemon_list = [] |
|
|
@ -272,15 +345,27 @@ def pokemon_details(pfic): |
|
|
return jsonify(encounters) |
|
|
return jsonify(encounters) |
|
|
|
|
|
|
|
|
def init_user_db(): |
|
|
def init_user_db(): |
|
|
"""Initialize the user database and create necessary tables""" |
|
|
|
|
|
conn = sqlite3.connect('user_data.db') |
|
|
conn = sqlite3.connect('user_data.db') |
|
|
cursor = conn.cursor() |
|
|
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(''' |
|
|
cursor.execute(''' |
|
|
CREATE TABLE IF NOT EXISTS caught_pokemon ( |
|
|
CREATE TABLE IF NOT EXISTS caught_pokemon ( |
|
|
pfic TEXT PRIMARY KEY, |
|
|
user_id INTEGER, |
|
|
caught_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|
|
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() |
|
|
conn.close() |
|
|
|
|
|
|
|
|
@app.route('/toggle_catch/<string:pfic>', methods=['POST']) |
|
|
@app.route('/toggle_catch/<string:pfic>', methods=['POST']) |
|
|
|
|
|
@login_required |
|
|
def toggle_catch(pfic): |
|
|
def toggle_catch(pfic): |
|
|
# First verify PFIC exists in pokemon_forms.db |
|
|
# Verify PFIC exists |
|
|
ref_conn = sqlite3.connect('pokemon_forms.db') |
|
|
ref_conn = sqlite3.connect('pokemon_forms.db') |
|
|
ref_cursor = ref_conn.cursor() |
|
|
ref_cursor = ref_conn.cursor() |
|
|
|
|
|
|
|
|
@ -299,22 +385,27 @@ def toggle_catch(pfic): |
|
|
return jsonify({'error': 'Invalid PFIC'}), 400 |
|
|
return jsonify({'error': 'Invalid PFIC'}), 400 |
|
|
ref_conn.close() |
|
|
ref_conn.close() |
|
|
|
|
|
|
|
|
# Now handle the caught status in user_data.db |
|
|
|
|
|
user_conn = sqlite3.connect('user_data.db') |
|
|
user_conn = sqlite3.connect('user_data.db') |
|
|
user_cursor = user_conn.cursor() |
|
|
user_cursor = user_conn.cursor() |
|
|
|
|
|
|
|
|
try: |
|
|
try: |
|
|
# Check if Pokemon is already caught |
|
|
user_cursor.execute( |
|
|
user_cursor.execute('SELECT pfic FROM caught_pokemon WHERE pfic = ?', (pfic,)) |
|
|
'SELECT 1 FROM caught_pokemon WHERE user_id = ? AND pfic = ?', |
|
|
|
|
|
(current_user.id, pfic) |
|
|
|
|
|
) |
|
|
result = user_cursor.fetchone() |
|
|
result = user_cursor.fetchone() |
|
|
|
|
|
|
|
|
if result: |
|
|
if result: |
|
|
# Pokemon was caught, so uncatch it |
|
|
user_cursor.execute( |
|
|
user_cursor.execute('DELETE FROM caught_pokemon WHERE pfic = ?', (pfic,)) |
|
|
'DELETE FROM caught_pokemon WHERE user_id = ? AND pfic = ?', |
|
|
|
|
|
(current_user.id, pfic) |
|
|
|
|
|
) |
|
|
status = 'uncaught' |
|
|
status = 'uncaught' |
|
|
else: |
|
|
else: |
|
|
# Pokemon wasn't caught, so catch it |
|
|
user_cursor.execute( |
|
|
user_cursor.execute('INSERT INTO caught_pokemon (pfic) VALUES (?)', (pfic,)) |
|
|
'INSERT INTO caught_pokemon (user_id, pfic) VALUES (?, ?)', |
|
|
|
|
|
(current_user.id, pfic) |
|
|
|
|
|
) |
|
|
status = 'caught' |
|
|
status = 'caught' |
|
|
|
|
|
|
|
|
user_conn.commit() |
|
|
user_conn.commit() |
|
|
@ -327,11 +418,15 @@ def toggle_catch(pfic): |
|
|
user_conn.close() |
|
|
user_conn.close() |
|
|
|
|
|
|
|
|
@app.route('/get_caught_pokemon') |
|
|
@app.route('/get_caught_pokemon') |
|
|
|
|
|
@login_required |
|
|
def get_caught_pokemon(): |
|
|
def get_caught_pokemon(): |
|
|
user_conn = sqlite3.connect('user_data.db') |
|
|
user_conn = sqlite3.connect('user_data.db') |
|
|
user_cursor = user_conn.cursor() |
|
|
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()] |
|
|
caught = [row[0] for row in user_cursor.fetchall()] |
|
|
|
|
|
|
|
|
user_conn.close() |
|
|
user_conn.close() |
|
|
|