def callback() -> Any: """Callback endpoint for SSO service Returns: Any: Redirect to home page if everything went well, else return 401. """ try: discord.callback() if DISCORD_GUILD_ID: if not verify(): # When the callback succeeds, the token for the user gets set in memory # Since the user isn't a member of the guild, we reset the session # to prevent access to the API session.clear() return abort(401) resp = discord.fetch_user() # Assume successful login if not check_if_user_exists(resp.id): add_user(resp.username, resp.id, resp.avatar_url) else: current_app.logger.info(f"User {resp.username} has just signed in") # Update last login time update_login_time(resp.id) return redirect(url_for("index.home")) except RateLimited: return "We are currently being rate limited, try again later."
def watch_stream(username: str, unique_id: Union[str, None] = None) -> Any: """Generates a page to watch streams with. Args: username (str): The user whose stream to watch unique_id (Union[str, None], optional): The unique ID of a stream. This is only set if the stream is either private, or archived. Defaults to None. Returns: Any: Static page rendered by Flask. """ stream = get_livestreams_by_username(username) if stream and not unique_id: # Regular livestream return render_template("watch.html", live=True, stream=stream) if unique_id: # Lets first check if its an unlisted stream unlisted = get_unlisted_livestreams_by_username(username) if unlisted: # Unlisted stream return render_template("watch.html", live=True, stream=unlisted) # It's an archived stream at this point try: stream = get_archived_stream(unique_id) return return_stream_page(unique_id, stream) except StopIteration: pass # Unlisted and archived try: stream = get_archived_stream(unique_id, all_metadata=True, private=True) if bool(stream["archivable"]) and bool(stream["unlisted"]): return return_stream_page(unique_id, stream) except StopIteration: pass # Private stream try: user = discord.fetch_user() stream = get_archived_stream(unique_id, private=True) if stream["user_snowflake"] == user.id: return return_stream_page(unique_id, stream) else: return render_template("alert.html", error="Invalid stream key.") except StopIteration: # The stream ID doesn't exist at all at this point return ( render_template("alert.html", error="Invalid stream key."), 404, ) return render_template("watch.html")
def manage_stream(unique_id: str) -> Any: """Manage a stream's properties via its unique ID. Args: unique_id (str): The stream's unique ID. Returns: Any: A static page rendered by Flask. """ user = discord.fetch_user() form = StreamGenerationForm() stream = query_one( "SELECT title, description, category, archivable, unlisted, user_snowflake FROM stream WHERE unique_id = ?", [unique_id], ) if not stream: return render_template("alert.html", error="Invalid stream ID."), 404 # Populate the stream editing form. form.title.data = stream["title"] form.description.data = stream["description"] form.category.data = stream["category"] form.archivable.data = stream["archivable"] form.unlisted.data = stream["unlisted"] if stream["user_snowflake"] == user.id: if request.method == "GET": return render_template("manage_stream.html", form=form, unique_id=unique_id) if request.method == "POST": form = StreamGenerationForm(request.form) if form.validate(): keys_to_change = {} for key, value in form.data.items(): if stream[key] != value: keys_to_change[key] = value update_db_fields(unique_id, **keys_to_change) return render_template("manage_stream.html", form=form, unique_id=unique_id, update=True) else: # User does not have access to manage this stream ID. return abort(403)
def generate_stream_key() -> Any: form = StreamGenerationForm(request.form) server = f"rtmp://{environ.get('RTMP_SERVER')}" if request.method == "GET": return render_template("generate_stream.html", form=form, server=server) else: user = discord.fetch_user() snowflake = user.id keyvar = uuid.uuid4() stream_key = str(keyvar)[0:8] unique_id = str(keyvar)[24:32] if form.validate(): title = form.title.data description = form.description.data category = form.category.data archivable = form.archivable.data unlisted = form.unlisted.data add_stream_to_db( snowflake, title, description, category, archivable, unique_id, stream_key, unlisted, ) return render_template( "generate_stream.html", form=form, user=user, key=stream_key, id=unique_id, unlisted=unlisted, server=server, )
def me() -> Text: """Render a page to manage stream properties Returns: Text: Static page rendered by Flask. """ discord_user = discord.fetch_user() user = query_one("SELECT * FROM user WHERE snowflake = ?", [discord_user.id]) streams = query_many( "SELECT * FROM stream WHERE user_snowflake = ?", [discord_user.id] ) if streams: for stream in streams: try: duration = stream["end_date"] - stream["start_date"] stream["duration"] = str(duration) except TypeError: continue stream["username"] = user["username"] return render_template("manage_user.html", user=user, streams=streams) return render_template("manage_user.html", user=user)
def serve_archive(unique_id: str) -> Response: """Serves stream from the archive. Args: unique_id (str): The stream's unique ID. Returns: Response: File being served by Flask's Response class. """ user = discord.fetch_user() stream = query_one( "SELECT * FROM stream WHERE archived_file IS NOT NULL AND unique_id = ?", [unique_id], ) if user.id == stream["user_snowflake"]: # The user requesting the stream created it. # Therefore they shall always have access to the file. return serve_file(stream) elif bool(stream["archivable"]): # The stream is publically archived. return serve_file(stream) else: # The stream does not exist. return abort(404)