UPDATE: Revamped database class, and implemented some routes in streams.py
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
from flask import Blueprint, session, jsonify, g
|
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.user_utils import get_user_id
|
||||||
from utils import login_required
|
from blueprints.utils import login_required
|
||||||
from database.database import Database, fetch_data_as_list
|
from database.database import Database
|
||||||
stream_bp = Blueprint("stream", __name__)
|
stream_bp = Blueprint("stream", __name__)
|
||||||
|
|
||||||
|
|
||||||
@@ -11,24 +11,12 @@ def get_sample_streams() -> list[dict]:
|
|||||||
"""
|
"""
|
||||||
Returns a list of (sample) streams live right now
|
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
|
# 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
|
db = Database()
|
||||||
ORDER BY num_viewers DESC
|
db.create_connection()
|
||||||
LIMIT 25; """
|
streams = db.fetchall("""SELECT * FROM streams
|
||||||
|
ORDER BY num_viewers DESC
|
||||||
streams = fetch_data_as_list(cursor, query)
|
LIMIT 25; """)
|
||||||
|
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"streams": streams
|
"streams": streams
|
||||||
})
|
})
|
||||||
@@ -69,30 +57,34 @@ def get_categories() -> list[dict]:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
db = Database()
|
db = Database()
|
||||||
cursor = db.create_connection()
|
db.create_connection()
|
||||||
|
categories = db.fetchall("""SELECT categories.category_id, category_name, SUM(num_viewers) as num_viewers FROM categories, streams
|
||||||
# fetch top categories by number of viewers
|
|
||||||
query = """SELECT categories.category_id, category_name, SUM(num_viewers) as num_viewers FROM categories, streams
|
|
||||||
WHERE categories.category_id = streams.category_id
|
WHERE categories.category_id = streams.category_id
|
||||||
GROUP BY category_name
|
GROUP BY category_name
|
||||||
ORDER BY SUM(num_viewers) DESC
|
ORDER BY SUM(num_viewers) DESC
|
||||||
LIMIT 25; """
|
LIMIT 25; """)
|
||||||
|
|
||||||
categories = fetch_data_as_list(cursor, query)
|
|
||||||
return jsonify({'categories': categories})
|
return jsonify({'categories': categories})
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@stream_bp.route('/get_followed_categories')
|
@stream_bp.route('/get_recommended_categories')
|
||||||
def get_followed_categories() -> list | list[dict]:
|
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()
|
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>')
|
@stream_bp.route('/get_streamer_data/<int:streamer_username>')
|
||||||
def get_streamer_data(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
|
Returns a streamer's status, if they are live or not and their most recent stream
|
||||||
"""
|
"""
|
||||||
return {"status": "live", "streamId": 1}
|
user_id = get_user_id(streamer_username)
|
||||||
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}
|
|
||||||
|
|
||||||
|
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):
|
def get_stream(streamer_username):
|
||||||
"""
|
"""
|
||||||
Returns a streamer's most recent stream data
|
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):
|
def get_specific_stream(streamer_username, stream_id):
|
||||||
"""
|
"""
|
||||||
Returns a streamer's stream data given 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:
|
if stream:
|
||||||
return stream
|
return jsonify(stream)
|
||||||
|
|
||||||
return # whatever
|
return jsonify({
|
||||||
|
"error": "Stream not found"
|
||||||
|
})
|
||||||
|
|
||||||
# @login_required
|
# @login_required
|
||||||
# need to add in a lock to this route for only logged in users since we will be taking from the session
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
@stream_bp.route('/get_followed_streams', methods=['GET'])
|
@stream_bp.route('/get_followed_streamers', methods=['GET'])
|
||||||
def get_followed_streamers():
|
def get_followed_streamers():
|
||||||
"""
|
"""
|
||||||
Queries DB to get a list of followed streamers
|
Queries DB to get a list of followed streamers
|
||||||
"""
|
"""
|
||||||
username = session.get('username')
|
username = session.get('username')
|
||||||
user_id = get_user_id(username)
|
user_id = get_user_id(username)
|
||||||
live_following_streams = followed_live_streams(user_id)
|
|
||||||
if not followed_live_streams:
|
live_following_streams = followed_streamers(user_id)
|
||||||
return # whatever
|
|
||||||
return live_following_streams
|
return live_following_streams
|
||||||
|
|
||||||
|
|
||||||
@@ -156,7 +165,8 @@ def get_followed_streamers():
|
|||||||
def stream_thumbnail_snapshot(streamer_id):
|
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
|
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
|
will be saved as a png stream_id.streamer_id.png or similar to create a unique image
|
||||||
"""
|
"""
|
||||||
return
|
return
|
||||||
|
|||||||
Binary file not shown.
@@ -4,13 +4,49 @@ import os
|
|||||||
class Database:
|
class Database:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self._db = os.path.join(os.path.abspath(os.path.dirname(__file__)), "app.db")
|
self._db = os.path.join(os.path.abspath(os.path.dirname(__file__)), "app.db")
|
||||||
|
self.cursor = None
|
||||||
|
|
||||||
def create_connection(self) -> sqlite3.Cursor:
|
def create_connection(self) -> sqlite3.Cursor:
|
||||||
conn = sqlite3.connect(self._db)
|
conn = sqlite3.connect(self._db)
|
||||||
conn.row_factory = sqlite3.Row
|
conn.row_factory = sqlite3.Row
|
||||||
self._conn = conn
|
self._conn = conn
|
||||||
cursor = conn.cursor()
|
self.cursor = conn.cursor()
|
||||||
return 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):
|
def commit_data(self):
|
||||||
try:
|
try:
|
||||||
@@ -19,17 +55,4 @@ class Database:
|
|||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
def close_connection(self) -> None:
|
def close_connection(self) -> None:
|
||||||
self._conn.close()
|
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
|
|
||||||
@@ -53,7 +53,5 @@ SELECT * FROM user_preferences;
|
|||||||
SELECT * FROM subscribes;
|
SELECT * FROM subscribes;
|
||||||
SELECT * FROM categories;
|
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
|
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!');
|
||||||
|
|||||||
@@ -1,52 +1,66 @@
|
|||||||
from database.database import Database
|
from database.database import Database
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
|
||||||
def streamer_live_status(user_id: int) -> bool:
|
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()
|
db = Database()
|
||||||
cursor = db.create_connection()
|
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())
|
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
|
Searches for streamers who the user followed which are currently live
|
||||||
"""
|
"""
|
||||||
db = Database()
|
db = Database()
|
||||||
cursor = db.create_connection()
|
cursor = db.create_connection()
|
||||||
|
|
||||||
live_streams = cursor.execute("""
|
live_streams = db.fetchall("""
|
||||||
SELECT user_id, stream_id, title, num_viewers
|
SELECT user_id, stream_id, title, num_viewers
|
||||||
FROM streams
|
FROM streams
|
||||||
WHERE user_id IN (SELECT followed_id FROM follows WHERE user_id = ?)
|
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 stream_id = (SELECT MAX(stream_id) FROM streams WHERE user_id = streams.user_id)
|
||||||
AND isLive = 1;
|
AND isLive = 1;
|
||||||
""", (user_id,)).fetchall()
|
""", (user_id,))
|
||||||
|
|
||||||
return live_streams
|
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
|
Returns data of the most recent stream by a streamer
|
||||||
"""
|
"""
|
||||||
db = Database()
|
db = Database()
|
||||||
cursor = db.create_connection()
|
db.create_connection()
|
||||||
|
most_recent_stream = db.fetchone("""SELECT * FROM streams WHERE
|
||||||
most_recent_stream = cursor.execute("""SELECT * FROM streams WHERE
|
|
||||||
user_id = ? AND
|
user_id = ? AND
|
||||||
stream_id = (SELECT MAX(stream_id) FROM
|
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
|
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
|
Returns data of a streamers selected stream
|
||||||
"""
|
"""
|
||||||
db = Database()
|
db = Database()
|
||||||
cursor = db.create_connection()
|
cursor = db.create_connection()
|
||||||
|
stream = db.fetchone("SELECT * FROM streams WHERE user_id = ? AND stream_id = ?", (user_id,stream_id))
|
||||||
stream = cursor.execute("SELECT * FROM streams WHERE user_id = ? AND stream_id = ?", (user_id,stream_id)).fetchone()
|
|
||||||
|
|
||||||
return stream
|
return stream
|
||||||
@@ -18,7 +18,7 @@ def get_user_id(username: str) -> Optional[int]:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
data = cursor.execute(
|
data = cursor.execute(
|
||||||
"SELECT user_id FROM user WHERE username = ?",
|
"SELECT user_id FROM users WHERE username = ?",
|
||||||
(username,)
|
(username,)
|
||||||
).fetchone()
|
).fetchone()
|
||||||
return data[0] if data else None
|
return data[0] if data else None
|
||||||
|
|||||||
Reference in New Issue
Block a user