UPDATE: Revamped database class, and implemented some routes in streams.py

This commit is contained in:
2025-01-28 20:36:13 +00:00
parent cbef531b3e
commit 440063bbd0
6 changed files with 130 additions and 85 deletions

View File

@@ -1,8 +1,8 @@
from flask import Blueprint, session, jsonify, g
from utils.stream_utils import streamer_live_status, streamer_most_recent_stream, user_stream, followed_live_streams
from utils.stream_utils import streamer_live_status, streamer_most_recent_stream, user_stream, followed_live_streams, followed_streamers
from utils.user_utils import get_user_id
from utils import login_required
from database.database import Database, fetch_data_as_list
from blueprints.utils import login_required
from database.database import Database
stream_bp = Blueprint("stream", __name__)
@@ -11,24 +11,12 @@ def get_sample_streams() -> list[dict]:
"""
Returns a list of (sample) streams live right now
"""
# top 25, if not logged in
# if logged in, show streams that match user's tags
# user attains tags from the tags of the streamers they follow, and streamers they've watched
# TODO Add a category field to the stream object
db = Database()
cursor = db.create_connection()
# fetch top 25 most viewed live streams if not logged in
# TODO Add a check to see if user is logged in, if they are, find streams that match categories they follow
query = """SELECT * FROM streams
ORDER BY num_viewers DESC
LIMIT 25; """
streams = fetch_data_as_list(cursor, query)
db = Database()
db.create_connection()
streams = db.fetchall("""SELECT * FROM streams
ORDER BY num_viewers DESC
LIMIT 25; """)
return jsonify({
"streams": streams
})
@@ -69,30 +57,34 @@ def get_categories() -> list[dict]:
"""
db = Database()
cursor = db.create_connection()
# fetch top categories by number of viewers
query = """SELECT categories.category_id, category_name, SUM(num_viewers) as num_viewers FROM categories, streams
db.create_connection()
categories = db.fetchall("""SELECT categories.category_id, category_name, SUM(num_viewers) as num_viewers FROM categories, streams
WHERE categories.category_id = streams.category_id
GROUP BY category_name
ORDER BY SUM(num_viewers) DESC
LIMIT 25; """
LIMIT 25; """)
categories = fetch_data_as_list(cursor, query)
return jsonify({'categories': categories})
@login_required
@stream_bp.route('/get_followed_categories')
def get_followed_categories() -> list | list[dict]:
@stream_bp.route('/get_recommended_categories')
def get_recommended_categories() -> list | list[dict]:
"""
Queries DB to get a list of followed categories
Queries DB to get a list of recommended categories for the user
"""
username = session.get('username')
user_id = get_user_id(username)
db = Database()
cursor = db.create_connection()
db.create_connection()
categories = db.fetchall("""SELECT categories.category_id, categories.category_name, favourability
FROM categories, user_preferences
WHERE user_id = ? AND categories.category_id = user_preferences.category_id,
ORDER BY favourability DESC""", (user_id,))
return jsonify({'categories': categories})
# fetch categories that the user follows
@stream_bp.route('/get_streamer_data/<int:streamer_username>')
def get_streamer_data(streamer_username):
@@ -107,48 +99,65 @@ def get_streamer_status(streamer_username):
"""
Returns a streamer's status, if they are live or not and their most recent stream
"""
return {"status": "live", "streamId": 1}
streamers_id = streamer_id(streamer_username)
if not streamers_id:
return # whatever
streamer_status = streamer_live_status(streamers_id)
stream_id = streamer_most_recent_stream(streamers_id)
return {"live": streamer_status, "streamerId": streamers_id, "streamId": stream_id}
user_id = get_user_id(streamer_username)
if not user_id:
return jsonify({
"error": "User not found"
})
is_live = streamer_live_status(user_id)
most_recent_stream = streamer_most_recent_stream(user_id)
@stream_bp.route('/get_stream_data/<int:streamer_username>', methods=['GET'])
if not most_recent_stream:
most_recent_stream = {'stream_id': None}
return jsonify({
"is_live": is_live,
"most_recent_stream": most_recent_stream['stream_id']
})
@stream_bp.route('/get_stream_data/<string:streamer_username>', methods=['GET'])
def get_stream(streamer_username):
"""
Returns a streamer's most recent stream data
"""
return # Whatever
user_id = get_user_id(streamer_username)
if not user_id:
return jsonify({
"error": "User not found"
})
return jsonify(streamer_most_recent_stream(user_id))
@stream_bp.route('/get_stream_data/<int:streamer_username>/<int:stream_id>', methods=['GET'])
@stream_bp.route('/get_stream_data/<string:streamer_username>/<int:stream_id>', methods=['GET'])
def get_specific_stream(streamer_username, stream_id):
"""
Returns a streamer's stream data given stream_id
"""
stream = user_stream(streamer_username, stream_id)
user_id = get_user_id(streamer_username)
stream = user_stream(user_id, stream_id)
if stream:
return stream
return jsonify(stream)
return # whatever
return jsonify({
"error": "Stream not found"
})
# @login_required
# need to add in a lock to this route for only logged in users since we will be taking from the session
@stream_bp.route('/get_followed_streams', methods=['GET'])
@login_required
@stream_bp.route('/get_followed_streamers', methods=['GET'])
def get_followed_streamers():
"""
Queries DB to get a list of followed streamers
"""
username = session.get('username')
user_id = get_user_id(username)
live_following_streams = followed_live_streams(user_id)
if not followed_live_streams:
return # whatever
live_following_streams = followed_streamers(user_id)
return live_following_streams
@@ -156,7 +165,8 @@ def get_followed_streamers():
def stream_thumbnail_snapshot(streamer_id):
"""
Function to be called periodically which saves the current live stream as an img to be used for the thumbnail to be displayed
will be asking streamer guy how to get the picture
will be asking streamer guy how to get the picture
will also be asking myself how to do this - Dylan
will be saved as a png stream_id.streamer_id.png or similar to create a unique image
"""
return

Binary file not shown.

View File

@@ -4,13 +4,49 @@ import os
class Database:
def __init__(self) -> None:
self._db = os.path.join(os.path.abspath(os.path.dirname(__file__)), "app.db")
self.cursor = None
def create_connection(self) -> sqlite3.Cursor:
conn = sqlite3.connect(self._db)
conn.row_factory = sqlite3.Row
self._conn = conn
cursor = conn.cursor()
return cursor
self.cursor = conn.cursor()
return self.cursor
def fetchall(self, query: str, parameters=None) -> list[dict]:
if parameters:
self.cursor.execute(query, parameters)
else:
self.cursor.execute(query)
result = self.cursor.fetchall()
return self.convert_to_list_dict(result)
def fetchone(self, query: str, parameters=None) -> list[dict]:
if parameters:
self.cursor.execute(query, parameters)
else:
self.cursor.execute(query)
result = self.cursor.fetchone()
return self.convert_to_list_dict(result)
def convert_to_list_dict(self, result):
"""
Converts a query result to a list of dictionaries
"""
# Get the column names from the cursor
columns = [description[0] for description in self.cursor.description]
if not result:
# for empty result
return []
elif isinstance(result, sqlite3.Row):
# for fetchone
return dict(zip(columns, result))
else:
# for fetchall or fetchmany
return [dict(zip(columns, row)) for row in result]
def commit_data(self):
try:
@@ -19,17 +55,4 @@ class Database:
print(e)
def close_connection(self) -> None:
self._conn.close()
def fetch_data_as_list(cursor, query, params=None):
# Execute the query with parameters (if any)
cursor.execute(query, params or [])
# Get the column names from the cursor
columns = [description[0] for description in cursor.description]
# Convert rows to dictionaries
rows = cursor.fetchall()
result = [dict(zip(columns, row)) for row in rows]
return result
self._conn.close()

View File

@@ -53,7 +53,5 @@ SELECT * FROM user_preferences;
SELECT * FROM subscribes;
SELECT * FROM categories;
INSERT INTO streams (user_id, title, start_time, num_viewers, isLive, vod_id, category_id) VALUES
(6, 'Epic Gaming Session 2', '2025-01-26 18:00:00', 800, 1, NULL, 1);
INSERT INTO users (username, password, email, num_followers, stream_key, is_partnered, bio) VALUES
('GamerDude2', 'password123', 'gamerdude2@gmail.com', 3200, '6789', 0, 'Streaming my gaming adventures!');
('GamerDude2', 'password123', 'gamerdude3@gmail.com', 3200, '7890', 0, 'Streaming my gaming adventures!');

View File

@@ -1,52 +1,66 @@
from database.database import Database
from typing import Optional
import sqlite3
def streamer_live_status(user_id: int) -> bool:
"""
Returns whether the given streamer is live
Returns boolean on whether the given streamer is live
"""
db = Database()
cursor = db.create_connection()
return bool(cursor.execute("SELECT 1 FROM streams WHERE user_id = ? AND isLive = 1 ORDER BY stream_id DESC", (user_id,)).fetchone())
def followed_live_streams(user_id: int):
def followed_live_streams(user_id: int) -> list[dict]:
"""
Searches for streamers who the user followed which are currently live
"""
db = Database()
cursor = db.create_connection()
live_streams = cursor.execute("""
live_streams = db.fetchall("""
SELECT user_id, stream_id, title, num_viewers
FROM streams
WHERE user_id IN (SELECT followed_id FROM follows WHERE user_id = ?)
AND stream_id = (SELECT MAX(stream_id) FROM streams WHERE user_id = streams.user_id)
AND isLive = 1;
""", (user_id,)).fetchall()
""", (user_id,))
return live_streams
def streamer_most_recent_stream(user_id: int):
def followed_streamers(user_id: int) -> list[dict]:
"""
Returns a list of streamers who the user follows
"""
db = Database()
db.create_connection()
followed_streamers = db.fetchall("""
SELECT user_id, username
FROM users
WHERE user_id IN (SELECT followed_id FROM follows WHERE user_id = ?);
""", (user_id,))
return followed_streamers
def streamer_most_recent_stream(user_id: int) -> dict:
"""
Returns data of the most recent stream by a streamer
"""
db = Database()
cursor = db.create_connection()
most_recent_stream = cursor.execute("""SELECT * FROM streams WHERE
db.create_connection()
most_recent_stream = db.fetchone("""SELECT * FROM streams WHERE
user_id = ? AND
stream_id = (SELECT MAX(stream_id) FROM
streams WHERE user_id = ?)""", (user_id, user_id)).fetchone()
streams WHERE user_id = ?)""", (user_id, user_id))
return most_recent_stream
def user_stream(user_id: int, stream_id: int):
def user_stream(user_id: int, stream_id: int) -> dict:
"""
Returns data of a streamers selected stream
"""
db = Database()
cursor = db.create_connection()
stream = cursor.execute("SELECT * FROM streams WHERE user_id = ? AND stream_id = ?", (user_id,stream_id)).fetchone()
stream = db.fetchone("SELECT * FROM streams WHERE user_id = ? AND stream_id = ?", (user_id,stream_id))
return stream
return stream

View File

@@ -18,7 +18,7 @@ def get_user_id(username: str) -> Optional[int]:
try:
data = cursor.execute(
"SELECT user_id FROM user WHERE username = ?",
"SELECT user_id FROM users WHERE username = ?",
(username,)
).fetchone()
return data[0] if data else None