diff --git a/web_server/blueprints/streams.py b/web_server/blueprints/streams.py index f5e8b65..3c27838 100644 --- a/web_server/blueprints/streams.py +++ b/web_server/blueprints/streams.py @@ -1,5 +1,6 @@ -from flask import Blueprint - +from flask import Blueprint, session +from utils.stream_utils import streamer_data, streamer_id, streamer_live_status, streamer_most_recent_stream, streamer_stream, followed_live_streams +from utils.user_utils import get_user_id stream_bp = Blueprint("stream", __name__) @@ -125,6 +126,7 @@ def get_categories(): def get_followed_categories(): """ Queries DB to get a list of followed categories + Hmm.. """ categories = [] if categories: @@ -132,40 +134,76 @@ def get_followed_categories(): return get_categories() -@stream_bp.route('/get_streamer_data/', methods=['GET']) -def get_streamer(streamer_id): +@stream_bp.route('/get_streamer_data/', methods=['GET']) +def get_streamer_data(streamer_username): """ - Returns a streamer's data + Returns a given streamer's data """ - return + streamers_id = streamer_id(streamer_username) + if not streamers_id: + return #whatever + streamers_data = streamer_data(streamers_id) + return streamers_data -@stream_bp.route('/streamer//status') -def get_streamer_status(streamerName): +@stream_bp.route('/streamer//status') +def get_streamer_status(streamer_username): """ - Returns a streamer's status, if they are live or not + 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} -@stream_bp.route('/get_stream_data/', methods=['GET']) -def get_stream(stream_id): +@stream_bp.route('/get_stream_data/', methods=['GET']) +def get_stream(streamer_username): """ - Returns a streamer's stream data + Returns a streamer's most recent stream data """ - return + streamers_id = streamer_id(streamer_username) + if not streamers_id: + return #whatever + most_recent_stream = streamer_most_recent_stream(streamers_id) + if most_recent_stream: + return most_recent_stream + + return #Whatever +@stream_bp.route('/get_stream_data//', methods=['GET']) +def get_specific_stream(streamer_username,stream_id): + """ + Returns a streamer's stream data given stream_id + """ + stream = streamer_stream(streamer_username, stream_id) + if stream: + return stream + + return #whatever +#@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']) def get_followed_streamers(): """ Queries DB to get a list of followed streamers """ - return + 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 + return live_following_streams @stream_bp.route('/save_stream_thumbnail/', methods=['POST']) 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 saved as a png stream_id.streamer_id.png or similar to create a unique image """ return diff --git a/web_server/blueprints/user.py b/web_server/blueprints/user.py index ad7738e..08c7532 100644 --- a/web_server/blueprints/user.py +++ b/web_server/blueprints/user.py @@ -1,6 +1,5 @@ from flask import Blueprint, jsonify, session -from database.database import Database -from datetime import datetime +from utils.user_utils import is_subscribed, is_following, subscription_expiration user_bp = Blueprint("user", __name__) @@ -9,10 +8,7 @@ def user_subscribed(user_id, streamer_id): """ Checks to see if user is subscribed to a streamer """ - db = Database() - cursor = db.create_connection() - data = cursor.execute("SELECT * FROM subscribes WHERE user_id = ? AND streamer_id = ? AND expires > since", (user_id, streamer_id)).fetchone() - if data: + if is_subscribed(user_id, streamer_id): return jsonify({"subscribed": True}) return jsonify({"subscribed": False}) @@ -21,10 +17,7 @@ def user_following(user_id, streamer_id): """ Checks to see if user is following a streamer """ - db = Database() - cursor = db.create_connection() - data = cursor.execute("SELECT * FROM follows WHERE user_id = ? AND streamer_id = ?", (user_id, streamer_id)).fetchone() - if data: + if is_following(user_id, streamer_id): return jsonify({"following": True}) return jsonify({"following": False}) @@ -34,21 +27,11 @@ def user_subscription_expiration(user_id, streamer_id): """ Returns remaining time until subscription expiration """ - db = Database() - cursor = db.create_connection() - data = cursor.execute("SELECT expires from subscriptions WHERE user_id = ? AND streamer_id = ? AND expires > since", (user_id,streamer_id)) - if data: - expiration_date = data[0] - - ends_datetime = datetime.strptime(expiration_date, '%Y-%m-%d %H:%M:%S') - - remaining_time = ends_datetime - datetime.now() + remaining_time = subscription_expiration(user_id, streamer_id) - return jsonify({"remaining_time": remaining_time.seconds}) + return jsonify({"remaining_time": remaining_time}) - return jsonify({"remaining_time": 0}) - -@user_bp.route('/get_login_status') +@user_bp.route('/get_login_status', methods=['GET']) def get_login_status(): """ Returns whether the user is logged in or not @@ -61,3 +44,11 @@ def authenticate_user(): Authenticates the user """ return {"authenticated": True} + +@user_bp.route('/forgot_password', methods=['POST']) +def forgot_password(): + """ + Will send link to email to reset password by looking at the user_id within session to see whos password should be reset + Creates a super random number to be used a the link to reset password I guess a random number generator seeded with a secret + """ + return diff --git a/web_server/utils/recommendation_utils.py b/web_server/utils/recommendation_utils.py new file mode 100644 index 0000000..58ada9f --- /dev/null +++ b/web_server/utils/recommendation_utils.py @@ -0,0 +1,26 @@ +from database.database import Database +from user_utils import get_user_id +from typing import Optional, List, Tuple + +def user_recommendation_category(username: str) -> Optional[int]: + """ + Queries user_preferences database to find users favourite streaming category and returns the category + """ + db = Database() + cursor = db.create_connection() + user_id = get_user_id(username) + + data = cursor.execute( + "SELECT category_id FROM user_preferences WHERE user_id = ? ORDER BY favourability DESC LIMIT 1", (user_id,)).fetchone() + return data[0] + +def recommendations_based_on_category(category_id: int) -> Optional[List[Tuple[int, str, int]]]: + """ + Queries stream database to get top 10 most viewed streams based on given category and returns (stream_id, title, num_viewers) + """ + db = Database() + cursor = db.create_connection() + + data = cursor.execute( + "SELECT streamer_id, stream_id, title, num_viewers FROM streams WHERE category_id = ? ORDER BY num_viwers DESC LIMIT 10", (category_id,)).fetchall() + return data \ No newline at end of file diff --git a/web_server/utils/stream_utils.py b/web_server/utils/stream_utils.py new file mode 100644 index 0000000..f97d785 --- /dev/null +++ b/web_server/utils/stream_utils.py @@ -0,0 +1,85 @@ +from database.database import Database +from typing import Optional + +def streamer_data(streamer_id: int): + """ + Retrieves data given streamer (username, since, isPartnered) + """ + db = Database() + cursor = db.create_connection() + streamer_data = cursor.execute("""SELECT username, since, isPartnered FROM + streamers JOIN users ON + streamers.user_id = users.user_id + WHERE streamer_id = ?""", (streamer_id,)).fetchone() + return streamer_data + +def streamer_live_status(streamer_id: int) -> bool: + """ + Returns whether the given streamer is live + """ + db = Database() + cursor = db.create_connection() + return bool(cursor.execute("SELECT 1 FROM streams WHERE streamer_id = ? AND isLive = 1 ORDER BY stream_id DESC", (streamer_id,)).fetchone()) + +def followed_live_streams(user_id: int): + """ + Searches for streamers who the user followed which are currently live + """ + db = Database() + cursor = db.create_connection() + + live_streams = cursor.execute(""" + SELECT streamer_id, stream_id, title, num_viewers + FROM streams + WHERE streamer_id IN (SELECT streamer_id FROM follows WHERE user_id = ?) + AND stream_id = (SELECT MAX(stream_id) FROM streams WHERE streamer_id = streams.streamer_id) + AND isLive = 1 + """, (user_id,)).fetchall() + + return live_streams + +def streamer_name(streamer_id: int) -> Optional[str]: + """ + Returns streamers username given streamer_id + """ + db = Database() + cursor = db.create_connection() + + streamer_username = cursor.execute( + "SELECT username FROM users WHERE user_id = (SELECT user_id FROM streamers WHERE streamer_id = ?)", (streamer_id,)).fetchone() + return streamer_username[0] if streamer_username else None + +def streamer_id(streamer_name: str) -> Optional[int]: + """ + Returns streamers id given streamers name + """ + db = Database() + cursor = db.create_connection() + + streamer_id = cursor.execute( + "SELECT streamer_id FROM streamers WHERE user_id = (SELECT user_id FROM users WHERE username = ?)",(streamer_name,)).fetchone() + return streamer_id[0] if streamer_id else None + +def streamer_most_recent_stream(streamer_id: int): + """ + 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 + streamer_id = ? AND + stream_id = (SELECT MAX(stream_id) FROM + streams WHERE streamer_id = ?)""", (streamer_id,streamer_id)).fetchone() + return most_recent_stream + +def streamer_stream(streamer_id: int, stream_id: int): + """ + Returns data of a streamers selected stream + """ + db = Database() + cursor = db.create_connection() + + stream = cursor.execute("SELECT * FROM streams WHERE streamer_id = ? AND stream_id = ?", (streamer_id,stream_id)).fetchone() + + return stream diff --git a/web_server/utils/user_utils.py b/web_server/utils/user_utils.py new file mode 100644 index 0000000..f118f91 --- /dev/null +++ b/web_server/utils/user_utils.py @@ -0,0 +1,55 @@ +from database.database import Database +from typing import Optional +from datetime import datetime + +def get_user_id(username: str) -> Optional[int]: + """ + Returns user_id associated with given username + """ + db = Database() + cursor = db.create_connection() + data = cursor.execute("SELECT user_id FROM user WHERE username = ?", (username,)).fetchone() + return data[0] if data else None + +def get_username(user_id: str) -> Optional[str]: + """ + Returns username associated with given user_id + """ + db = Database() + cursor = db.create_connection() + data = cursor.execute("SELECT username FROM user WHERE username = ?", (user_id,)).fetchone() + return data[0] if data else None + +def is_subscribed(user_id: int, streamer_id: int) -> bool: + """ + Returns True if user is subscribed to a streamer else False + """ + db = Database() + cursor = db.create_connection() + return bool(cursor.execute( + "SELECT 1 FROM subscribes WHERE user_id = ? AND streamer_id = ? AND expires > since", + (user_id, streamer_id) + ).fetchone()) + +def is_following(user_id: int, streamer_id:int) -> bool: + db = Database() + cursor = db.create_connection() + return bool(cursor.execute( + "SELECT 1 FROM follows WHERE user_id = ? AND streamer_id = ?", + (user_id, streamer_id) + ).fetchone()) + +def subscription_expiration(user_id: int, streamer_id: int) -> int: + """ + Returns the amount of time left until user subscription to a streamer ends + """ + db = Database() + cursor = db.create_connection() + data = cursor.execute( + "SELECT expires from subscriptions WHERE user_id = ? AND streamer_id = ? AND expires > since", (user_id,streamer_id)).fetchone() + remaining_time = 0 + if data: + expiration_date = data[0] + + remaining_time = (expiration_date - datetime.now()).seconds + return remaining_time diff --git a/web_server/utils/utils.py b/web_server/utils/utils.py new file mode 100644 index 0000000..c0d33dc --- /dev/null +++ b/web_server/utils/utils.py @@ -0,0 +1,19 @@ +from database.database import Database + +def categories(): + """ + Returns all possible streaming categories + """ + db = Database() + cursor = db.create_connection() + all_categories = cursor.execute("SELECT * FROM categories").fetchall() + return all_categories + +def tags(): + """ + Returns all possible streaming tags + """ + db = Database() + cursor = db.create_connection() + all_tags = cursor.execute("SELECT * FROM tags").fetchall() + return all_tags \ No newline at end of file