UPDATE: migrated one time util methods to blueprints

This commit is contained in:
white
2025-02-07 17:18:46 +00:00
parent ff44f5b379
commit 43edc52c25
7 changed files with 210 additions and 258 deletions

View File

@@ -4,7 +4,7 @@ from flask_cors import cross_origin
from database.database import Database from database.database import Database
from blueprints.utils import login_required, sanitizer from blueprints.utils import login_required, sanitizer
from blueprints.email import send_email from blueprints.email import send_email
from utils.user_utils import get_user_id from blueprints.user import get_user_id
from secrets import token_hex from secrets import token_hex
auth_bp = Blueprint("auth", __name__) auth_bp = Blueprint("auth", __name__)

View File

@@ -3,7 +3,7 @@ from database.database import Database
from .socket import socketio from .socket import socketio
from flask_socketio import emit, join_room, leave_room from flask_socketio import emit, join_room, leave_room
from datetime import datetime from datetime import datetime
from utils.user_utils import get_user_id from blueprints.user import get_user_id
chat_bp = Blueprint("chat", __name__) chat_bp = Blueprint("chat", __name__)

View File

@@ -1,6 +1,6 @@
from authlib.integrations.flask_client import OAuth, OAuthError from authlib.integrations.flask_client import OAuth, OAuthError
from flask import Blueprint, url_for, jsonify, session from flask import Blueprint, url_for, jsonify, session
from utils.user_utils import get_session_info_email from blueprints.user import get_session_info_email
oauth_bp = Blueprint("oauth", __name__) oauth_bp = Blueprint("oauth", __name__)
def init_oauth(app): def init_oauth(app):

View File

@@ -1,10 +1,11 @@
from flask import Blueprint, session, jsonify, request, redirect from flask import Blueprint, session, jsonify, request, redirect
from utils.stream_utils import * from utils.stream_utils import *
from utils.user_utils import get_user_id from blueprints.user import get_user_id
from blueprints.utils import login_required from blueprints.utils import login_required
from database.database import Database from database.database import Database
from datetime import datetime from datetime import datetime
from celery_tasks import update_thumbnail from celery_tasks import update_thumbnail
from typing import List, Optional
stream_bp = Blueprint("stream", __name__) stream_bp = Blueprint("stream", __name__)
@@ -45,9 +46,15 @@ def get_popular_streams_by_category(category_name) -> list[dict]:
Returns a list of streams live now with the highest viewers in a given category Returns a list of streams live now with the highest viewers in a given category
""" """
category_id = get_category_id(category_name)
with Database() as db: with Database() as db:
data = db.fetchone("""
SELECT category_id
FROM categories
WHERE category_name = ?;
""", (category_name,))
category_id = data["category_id"] if data else None
streams = db.fetchall(""" streams = db.fetchall("""
SELECT u.user_id, title, username, num_viewers, c.category_name SELECT u.user_id, title, username, num_viewers, c.category_name
FROM streams s FROM streams s
@@ -97,8 +104,29 @@ def get_stream_data(streamer_id):
""" """
Returns a streamer's current stream data Returns a streamer's current stream data
""" """
with Database() as db:
most_recent_stream = db.fetchone("""
SELECT s.user_id, u.username, s.title, s.start_time, s.num_viewers, c.category_name
FROM streams AS s
JOIN categories AS c ON s.category_id = c.category_id
JOIN users AS u ON s.user_id = u.user_id
WHERE u.user_id = ?
""", (streamer_id,))
return jsonify(get_current_stream_data(streamer_id)) return jsonify(most_recent_stream)
def get_stream_tags(user_id: int) -> Optional[List[str]]:
"""
Given a stream return tags associated with the user's stream
"""
with Database() as db:
tags = db.fetchall("""
SELECT tag_name
FROM tags
JOIN stream_tags ON tags.tag_id = stream_tags.tag_id
WHERE user_id = ?;
""", (user_id,))
return tags
## Category Routes ## Category Routes
@@ -176,7 +204,9 @@ def get_user_live_status(username):
# Check if streamer is live and get their most recent vod # Check if streamer is live and get their most recent vod
is_live = True if get_streamer_live_status(user_id)['is_live'] else False is_live = True if get_streamer_live_status(user_id)['is_live'] else False
most_recent_vod = get_latest_vod(user_id)
with Database() as db:
most_recent_vod = db.fetchone("""SELECT * FROM vods WHERE user_id = ? ORDER BY vod_id DESC LIMIT 1;""", (user_id,))
# If there is no most recent vod, set it to None # If there is no most recent vod, set it to None
if not most_recent_vod: if not most_recent_vod:
@@ -197,9 +227,25 @@ def get_vods(username):
Returns a JSON of all the vods of a streamer Returns a JSON of all the vods of a streamer
""" """
user_id = get_user_id(username) user_id = get_user_id(username)
vods = get_user_vods(user_id)
with Database() as db:
vods = db.fetchall("""SELECT * FROM vods WHERE user_id = ?;""", (user_id,))
return jsonify(vods) return jsonify(vods)
def get_vod_tags(vod_id: int):
"""
Given a vod return tags associated with the vod
"""
with Database() as db:
tags = db.fetchall("""
SELECT tag_name
FROM tags
JOIN vod_tags ON tags.tag_id = vod_tags.tag_id
WHERE vod_id = ?;
""", (vod_id,))
return tags
## RTMP Server Routes ## RTMP Server Routes
@stream_bp.route("/publish_stream", methods=["POST"]) @stream_bp.route("/publish_stream", methods=["POST"])
@@ -248,3 +294,30 @@ def end_stream():
db.execute("""DELETE FROM streams WHERE user_id = ?""", (user_info["user_id"],)) db.execute("""DELETE FROM streams WHERE user_id = ?""", (user_info["user_id"],))
return "Stream ended", 200 return "Stream ended", 200
def transfer_stream_to_vod(user_id: int):
"""
Deletes stream from stream table and moves it to VoD table
TODO: Add functionaliy to save stream permanently
"""
with Database() as db:
stream = db.fetchone("""
SELECT * FROM streams WHERE user_id = ?;
""", (user_id,))
if not stream:
return None
## TODO: calculate length in seconds, currently using temp value
db.execute("""
INSERT INTO vods (user_id, title, datetime, category_id, length, views)
VALUES (?, ?, ?, ?, ?, ?);
""", (stream["user_id"], stream["title"], stream["datetime"], stream["category_id"], 10, stream["num_viewers"]))
db.execute("""
DELETE FROM streams WHERE user_id = ?;
""", (user_id,))
return True

View File

@@ -20,7 +20,93 @@ def get_user_data(username: str):
data = get_user(user_id) data = get_user(user_id)
return jsonify(data) return jsonify(data)
def get_user_id(username: str) -> Optional[int]:
"""
Returns user_id associated with given username
"""
with Database() as db:
data = db.fetchone("""
SELECT user_id
FROM users
WHERE username = ?
""", (username,))
return data['user_id'] if data else None
def get_username(user_id: str) -> Optional[str]:
"""
Returns username associated with given user_id
"""
with Database() as db:
data = db.fetchone("""
SELECT username
FROM user
WHERE user_id = ?
""", (user_id,))
return data['username'] if data else None
def get_email(user_id: int) -> Optional[str]:
with Database() as db:
email = db.fetchone("""
SELECT email
FROM users
WHERE user_id = ?
""", (user_id,))
return email["email"] if email else None
def get_session_info_email(email: str) -> dict:
"""
Returns username and user_id given email
"""
with Database() as db:
session_info = db.fetchone("""
SELECT user_id, username
FROM user
WHERE email = ?
""", (email,))
return session_info
def is_user_partner(user_id: int) -> bool:
"""
Returns True if user is a partner, else False
"""
with Database() as db:
data = db.fetchone("""
SELECT is_partnered
FROM users
WHERE user_id = ?
""", (user_id,))
return bool(data)
def get_user(user_id: int) -> Optional[dict]:
"""
Returns information about a user from user_id
"""
with Database() as db:
data = db.fetchone("""
SELECT user_id, username, bio, num_followers, is_partnered, is_live FROM users
WHERE user_id = ?;
""", (user_id,))
return data
## Subscription Routes ## Subscription Routes
def is_subscribed(user_id: int, subscribed_to_id: int) -> bool:
"""
Returns True if user is subscribed to a streamer, else False
"""
with Database() as db:
result = db.fetchone("""
SELECT *
FROM subscribes
WHERE user_id = ?
AND subscribed_id = ?
AND expires > ?;
""", (user_id, subscribed_to_id, datetime.now()))
print(result)
if result:
return True
return False
@login_required @login_required
@user_bp.route('/user/subscription/<int:subscribed_id>') @user_bp.route('/user/subscription/<int:subscribed_id>')
def user_subscribed(subscribed_id: int): def user_subscribed(subscribed_id: int):
@@ -38,9 +124,20 @@ def user_subscription_expiration(subscribed_id: int):
""" """
Returns remaining time until subscription expiration Returns remaining time until subscription expiration
""" """
with Database() as db:
data = db.fetchone("""
SELECT expires
FROM subscribes
WHERE user_id = ?
AND subscribed_id = ?
AND expires > ?
""", (session.get("user_id"), subscribed_id, datetime.now()))
user_id = session.get("user_id") if data:
remaining_time = subscription_expiration(user_id, subscribed_id) expiration_date = data["expires"]
remaining_time = (parser.parse(expiration_date) - datetime.now()).seconds
else:
remaining_time = 0
return jsonify({"remaining_time": remaining_time}) return jsonify({"remaining_time": remaining_time})
@@ -82,8 +179,30 @@ def get_followed_streamers():
""" """
user_id = session.get('user_id') user_id = session.get('user_id')
live_following_streams = get_followed_streamers(user_id) with Database() as db:
return live_following_streams 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 get_followed_live_streams(user_id: int) -> Optional[List[dict]]:
"""
Searches for streamers who the user followed which are currently live
Returns a list of live streams with the streamer's user id, stream title, and number of viewers
"""
with Database() as db:
live_streams = db.fetchall("""
SELECT users.user_id, streams.title, streams.num_viewers, users.username
FROM streams JOIN users
ON streams.user_id = users.user_id
WHERE users.user_id IN
(SELECT followed_id FROM follows WHERE user_id = ?)
AND users.is_live = 1;
""", (user_id,))
return live_streams
## Login Routes ## Login Routes
@user_bp.route('/user/login_status') @user_bp.route('/user/login_status')

View File

@@ -1,9 +1,5 @@
from database.database import Database from database.database import Database
from typing import Optional import os, subprocess
import sqlite3, os, subprocess
from time import sleep
from typing import Optional, List
from datetime import datetime
def get_streamer_live_status(user_id: int): def get_streamer_live_status(user_id: int):
""" """
@@ -18,72 +14,6 @@ def get_streamer_live_status(user_id: int):
return is_live return is_live
def get_followed_live_streams(user_id: int) -> Optional[List[dict]]:
"""
Searches for streamers who the user followed which are currently live
Returns a list of live streams with the streamer's user id, stream title, and number of viewers
"""
with Database() as db:
live_streams = db.fetchall("""
SELECT users.user_id, streams.title, streams.num_viewers, users.username
FROM streams JOIN users
ON streams.user_id = users.user_id
WHERE users.user_id IN
(SELECT followed_id FROM follows WHERE user_id = ?)
AND users.is_live = 1;
""", (user_id,))
return live_streams
def get_current_stream_data(user_id: int) -> Optional[dict]:
"""
Returns data of the most recent stream by a streamer
"""
with Database() as db:
most_recent_stream = db.fetchone("""
SELECT s.user_id, u.username, s.title, s.start_time, s.num_viewers, c.category_name
FROM streams AS s
JOIN categories AS c ON s.category_id = c.category_id
JOIN users AS u ON s.user_id = u.user_id
WHERE u.user_id = ?
""", (user_id,))
return most_recent_stream
def get_category_id(category_name: str) -> Optional[int]:
"""
Returns the category_id given a category name
"""
with Database() as db:
data = db.fetchone("""
SELECT category_id
FROM categories
WHERE category_name = ?;
""", (category_name,))
return data['category_id'] if data else None
def get_vod(vod_id: int) -> dict:
"""
Returns data of a streamers vod
"""
with Database() as db:
vod = db.fetchone("""SELECT * FROM vods WHERE vod_id = ?;""", (vod_id,))
return vod
def get_latest_vod(user_id: int):
"""
Returns data of the most recent stream by a streamer
"""
with Database() as db:
latest_vod = db.fetchone("""SELECT * FROM vods WHERE user_id = ? ORDER BY vod_id DESC LIMIT 1;""", (user_id,))
return latest_vod
def get_user_vods(user_id: int):
"""
Returns data of all vods by a streamer
"""
with Database() as db:
vods = db.fetchall("""SELECT * FROM vods WHERE user_id = ?;""", (user_id,))
return vods
def generate_thumbnail(user_id: int) -> None: def generate_thumbnail(user_id: int) -> None:
""" """
@@ -112,55 +42,3 @@ def generate_thumbnail(user_id: int) -> None:
subprocess.run(thumbnail_command) subprocess.run(thumbnail_command)
def get_stream_tags(user_id: int) -> Optional[List[str]]:
"""
Given a stream return tags associated with the user's stream
"""
with Database() as db:
tags = db.fetchall("""
SELECT tag_name
FROM tags
JOIN stream_tags ON tags.tag_id = stream_tags.tag_id
WHERE user_id = ?;
""", (user_id,))
return tags
def get_vod_tags(vod_id: int):
"""
Given a vod return tags associated with the vod
"""
with Database() as db:
tags = db.fetchall("""
SELECT tag_name
FROM tags
JOIN vod_tags ON tags.tag_id = vod_tags.tag_id
WHERE vod_id = ?;
""", (vod_id,))
return tags
def transfer_stream_to_vod(user_id: int):
"""
Deletes stream from stream table and moves it to VoD table
TODO: Add functionaliy to save stream permanently
"""
with Database() as db:
stream = db.fetchone("""
SELECT * FROM streams WHERE user_id = ?;
""", (user_id,))
if not stream:
return None
## TODO: calculate length in seconds, currently using temp value
db.execute("""
INSERT INTO vods (user_id, title, datetime, category_id, length, views)
VALUES (?, ?, ?, ?, ?, ?);
""", (stream["user_id"], stream["title"], stream["datetime"], stream["category_id"], 10, stream["num_viewers"]))
db.execute("""
DELETE FROM streams WHERE user_id = ?;
""", (user_id,))
return True

View File

@@ -3,78 +3,13 @@ from typing import Optional, List
from datetime import datetime from datetime import datetime
from itsdangerous import URLSafeTimedSerializer, BadSignature, SignatureExpired from itsdangerous import URLSafeTimedSerializer, BadSignature, SignatureExpired
from os import getenv from os import getenv
from werkzeug.security import generate_password_hash, check_password_hash from werkzeug.security import generate_password_hash
from dateutil import parser from dateutil import parser
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv() load_dotenv()
serializer = URLSafeTimedSerializer(getenv("AUTH_SECRET_KEY")) serializer = URLSafeTimedSerializer(getenv("AUTH_SECRET_KEY"))
def get_user_id(username: str) -> Optional[int]:
"""
Returns user_id associated with given username
"""
with Database() as db:
data = db.fetchone("""
SELECT user_id
FROM users
WHERE username = ?
""", (username,))
return data['user_id'] if data else None
def get_username(user_id: str) -> Optional[str]:
"""
Returns username associated with given user_id
"""
with Database() as db:
data = db.fetchone("""
SELECT username
FROM user
WHERE user_id = ?
""", (user_id,))
return data['username'] if data else None
def get_session_info_email(email: str) -> dict:
"""
Returns username and user_id given email
"""
with Database as db:
session_info = db.fetchone("""
SELECT user_id, username
FROM user
WHERE email = ?
""", (email,))
return session_info
def is_user_partner(user_id: int) -> bool:
"""
Returns True if user is a partner, else False
"""
with Database() as db:
data = db.fetchone("""
SELECT is_partnered
FROM users
WHERE user_id = ?
""", (user_id,))
return bool(data)
def is_subscribed(user_id: int, subscribed_to_id: int) -> bool:
"""
Returns True if user is subscribed to a streamer, else False
"""
with Database() as db:
result = db.fetchone("""
SELECT *
FROM subscribes
WHERE user_id = ?
AND subscribed_id = ?
AND expires > ?;
""", (user_id, subscribed_to_id, datetime.now()))
print(result)
if result:
return True
return False
def is_following(user_id: int, followed_id: int) -> bool: def is_following(user_id: int, followed_id: int) -> bool:
""" """
Returns where a user is following another Returns where a user is following another
@@ -116,27 +51,6 @@ def unfollow(user_id: int, followed_id: int):
""", (user_id, followed_id)) """, (user_id, followed_id))
return {"success": True} return {"success": True}
def subscription_expiration(user_id: int, subscribed_id: int) -> int:
"""
Returns the amount of time left until user subscription to a streamer ends
"""
with Database() as db:
data = db.fetchone("""
SELECT expires
FROM subscribes
WHERE user_id = ?
AND subscribed_id = ?
AND expires > ?
""", (user_id, subscribed_id, datetime.now()))
if data:
expiration_date = data["expires"]
remaining_time = (parser.parse(expiration_date) - datetime.now()).seconds
return remaining_time
return 0
def generate_token(email, salt_value) -> str: def generate_token(email, salt_value) -> str:
""" """
Creates a token for password reset Creates a token for password reset
@@ -174,35 +88,3 @@ def reset_password(new_password: str, email: str) -> bool:
return True return True
def get_email(user_id: int) -> Optional[str]:
with Database() as db:
email = db.fetchone("""
SELECT email
FROM users
WHERE user_id = ?
""", (user_id,))
return email["email"] if email else None
def get_followed_streamers(user_id: int) -> Optional[List[dict]]:
"""
Returns a list of streamers who the user follows
"""
with Database() as db:
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 get_user(user_id: int) -> Optional[dict]:
"""
Returns information about a user from user_id
"""
with Database() as db:
data = db.fetchone("""
SELECT user_id, username, bio, num_followers, is_partnered, is_live FROM users
WHERE user_id = ?;
""", (user_id,))
return data