Skip to content

Final Project Submission #23

Merged
merged 1 commit into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions Backend/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
"""
This module provides functions for HTTP communication and
route functions
"""
from flask import Flask, request, jsonify
from flask_cors import CORS
from database_files import databasefunctions
app = Flask(__name__)
CORS(app)
# -----------------------------------------------------------------------------------------

@app.route("/add_newuser", methods=["POST"])
def add_newuser():
"""
Adds new user to database
"""
data = request.get_json()
newuser_id = databasefunctions.insert_user(data.get("username"),data.get("password"),
data.get("first_name"), data.get("last_name"))

return jsonify({'user_id': newuser_id}), 200

@app.route("/add_newpet", methods=["POST"])
def add_newpet():
"""
Adds new pet to database
"""
data = request.get_json()
newpet_id = databasefunctions.insert_pet(data.get("name"), data.get("age"),
data.get("gender"), data.get("type"),
data.get("location"),
data.get("photo_path"),
data.get("breed"),
data.get("paragraph"))

return jsonify({'pet_id': newpet_id}), 200


@app.route("/add_newfavorite", methods=["POST"])
def add_newfavorite():
"""
Adds new user favorite to database
INSERT INTO pets (name, age, gender, type, location, photo_path)
"""
data = request.get_json()
newfavorite_id = databasefunctions.insert_favorite(data.get("user_id"), data.get("pet_id"))

return jsonify({'faviorte_id': newfavorite_id}), 200



#------------------------------------------------------------------------------------------------

@app.route("/remove_user", methods=["DELETE"])
def removeuser():
"""
Remove user from database
"""
data = request.get_json()
userid = data.get("user_id")
roweffected = databasefunctions.remove_user(userid)

return (f"{roweffected}, row was deleted in user table"), 200


@app.route("/remove_pet", methods=["DELETE"])
def removepet():
"""
Remove pet from database
"""
data = request.get_json()
petid = data.get("pet_id")
roweffected = databasefunctions.remove_pet(petid)

return (f"{roweffected}, row was deleted in pet table"), 200


@app.route("/remove_favorite", methods=["DELETE"])
def removefavorite():
"""
Remove favorite from database
"""
data = request.get_json()
roweffected = databasefunctions.remove_favorite(data.get("user_id"),data.get("pet_id"))

return (f"{roweffected}, row was deleted in the favorite table"), 200

# ---------------------------------------------------------------------



@app.route("/fetch_userid", methods=["POST"])
def fetch_userid():
"""
fetch userid associated with username and password
"""
data = request.get_json()
username = data.get("username")
password = data.get("password")


userid = databasefunctions.fetch_userid_from_username_and_password(username, password)

return jsonify(userid), 200





@app.route("/fetch_pet", methods=["POST"])
def fetch_pet():
"""
fetch pet from database
"""
data = request.get_json()
petid = data.get("pet_id")
users_row = databasefunctions.fetch_pet_by_id(petid)

return jsonify(users_row), 200


@app.route("/fetch_user", methods=["POST"])
def fetch_user():
"""
fetch user from database
"""
data = request.get_json()
userid = data.get("user_id")
users_row = databasefunctions.fetch_user_by_id(userid)

return jsonify(users_row), 200


@app.route("/fetch_favorited_pets", methods=["POST"])
def fetch_favorite_pet():
"""
fetches all pets favorited by a user
"""
data = request.get_json()
userid = data.get("user_id")
favorited_pets = databasefunctions.fetch_favorites_by_user(userid)

return jsonify(favorited_pets), 200


# ---------------------------------------------------------------

@app.route("/fetch_allusers", methods=["POST"])
def fetch_allusers():
"""
fetches all users in database
"""

allusers = databasefunctions.fetch_all_users()
return jsonify(allusers), 200


@app.route("/fetch_allpets", methods=["POST"])
def fetch_allpets():
"""
fetches all pets in database
"""

allpets = databasefunctions.fetch_all_pets()
return jsonify(allpets), 200

if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
Binary file not shown.
218 changes: 218 additions & 0 deletions Backend/database_files/databasefunctions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
'''DATABASE FUNCTIONS'''
from contextlib import closing
import sqlite3

def connect_db():
"""Establish a connection to the SQLite database."""
return sqlite3.connect('projectdatabase.db') #this might change

# --------------------- insert functions

def insert_user(username, password, first_name, last_name):
"""Insert a new user into the accounts table."""
with closing(connect_db()) as conn, conn:
cursor = conn.cursor()

# Check if the username already exists
cursor.execute('''SELECT COUNT(*) FROM accounts WHERE username = ?''', (username,))
user_exists = cursor.fetchone()[0]

if user_exists > 0:
# If the username already exists, return None or an error message
return None # or return some error message or status

cursor.execute(
'''INSERT INTO accounts (username, password, first_name, last_name)
VALUES (?, ?, ?, ?)''',
(username, password, first_name, last_name)
)
conn.commit()
return cursor.lastrowid


def insert_pet(name, age, gender, type, location, photo_path=None, breed=None, paragraph=None):
"""Insert a new pet into the pets table."""
with closing(connect_db()) as conn, conn:
cursor = conn.cursor()
cursor.execute(
'''INSERT INTO pets (name, age, gender, type, location, photo_path, breed, paragraph)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)''',
(name, age, gender, type, location, photo_path, breed, paragraph)
)
conn.commit()
return cursor.lastrowid


def insert_favorite(user_id, pet_id):
"""Insert usere favorite pet into favorites table"""
with closing(connect_db()) as conn, conn:
cursor = conn.cursor()
cursor.execute(
'''INSERT INTO favorites (user_id, pet_id)
VALUES (?, ?)''',
(user_id, pet_id)
)
conn.commit()
return cursor.lastrowid

# ---------------------------remove functions

def remove_user(user_id):
"""Remove a pet from the accounts table."""
with closing(connect_db()) as conn, conn:
cursor = conn.cursor()
cursor.execute(
'''DELETE FROM accounts
WHERE user_id = ?''',
(user_id,)
)
conn.commit()
return cursor.rowcount


def remove_pet(pet_id):
"""Remove a pet from the pets table."""
with closing(connect_db()) as conn, conn:
cursor = conn.cursor()
cursor.execute(
'''DELETE FROM pets
WHERE pet_id = ?''',
(pet_id,)
)
conn.commit()
return cursor.rowcount


def remove_favorite(user_id, pet_id):
"""Remove a favorite row from the favorites table based on user_id and pet_id."""
with closing(connect_db()) as conn:
cursor = conn.cursor()

# Execute DELETE query to remove the row matching user_id and pet_id
cursor.execute("""
DELETE FROM favorites
WHERE user_id = ? AND pet_id = ?
""", (user_id, pet_id))

conn.commit()
return cursor.rowcount # Returns the number of rows affected (should be 1 if successful)

# ------------------------------------------- change fucntions


def change_user_attributes(user_id, attribute, change):
"""Update a user's attribute in the accounts table."""

# List of valid column names to avoid SQL injection
valid_columns = ['name', 'age', 'location', 'password'] # Add your valid column names here

if attribute not in valid_columns:
raise ValueError("Invalid attribute name.")

with closing(connect_db()) as conn:
cursor = conn.cursor()

# Use the attribute directly, now it's safe since we validated it
cursor.execute(f"""
UPDATE accounts
SET {attribute} = ?
WHERE user_id = ?
""", (change, user_id))

conn.commit()
return fetch_user_by_id(user_id)


def change_pet_attributes(pet_id, attribute, change):
"""Update a user's attribute in the accounts table."""

# List of valid column names to avoid SQL injection
valid_columns = ['name', 'age', 'location', 'breed',
'gender', 'type', 'photo_path'] # Add your valid column names here

if attribute not in valid_columns:
raise ValueError("Invalid attribute name.")

with closing(connect_db()) as conn:
cursor = conn.cursor()

# Use the attribute directly, now it's safe since we validated it
cursor.execute(f"""
UPDATE pets
SET {attribute} = ?
WHERE pet_id = ?
""", (change, pet_id))

conn.commit()
return fetch_pet_by_id(pet_id)

# ------------------------------------- fetch functions


def fetch_userid_from_username_and_password(username,password):
"""Get a users ID from there username and password"""

with closing(connect_db()) as conn:
cursor = conn.cursor()

# Execute DELETE query to remove the row matching user_id and pet_id
cursor.execute("""
SELECT user_id FROM accounts
WHERE username = ? AND password = ?
""", (username, password))

result = cursor.fetchone()
if result:
return result[0]
else:
return None


def fetch_favorites_by_user(user_id):
"""Fetch all favorite pets for a given user_id."""
with closing(connect_db()) as conn:
cursor = conn.cursor()

cursor.execute("""
SELECT pets.*
FROM pets
INNER JOIN favorites ON pets.pet_id = favorites.pet_id
WHERE favorites.user_id = ?
""", (user_id,))

return cursor.fetchall()


def fetch_all_users():
"""Retrieve all users from the accounts table."""
with closing(connect_db()) as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM accounts")
return cursor.fetchall()


def fetch_all_pets():
"""Retrieve all pets from the pets table."""
with closing(connect_db()) as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM pets")
return cursor.fetchall()


def fetch_user_by_id(user_id):
"""Retrieve a user by their account_id."""
with closing(connect_db()) as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM accounts WHERE user_id = ?", (user_id,))
return cursor.fetchone()


def fetch_pet_by_id(pet_id):
"""Retrieve a pet by their pet_id."""
with closing(connect_db()) as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM pets WHERE pet_id = ?", (pet_id,))
return cursor.fetchone()


# -------------------------------------------------------------
Loading