update logging

update logging to integrate with flask
This commit is contained in:
ksyasuda 2024-09-05 04:20:21 -07:00
parent ae511bdb93
commit 06040a1a05
No known key found for this signature in database

131
server.py
View File

@ -1,4 +1,3 @@
#!/usr/bin/env python3
import logging import logging
import os import os
import socket import socket
@ -10,14 +9,8 @@ import mysql.connector
from flask import Flask, jsonify, request from flask import Flask, jsonify, request
from mysql.connector import Error from mysql.connector import Error
# Set up basic logging MAX_RETRIES = 5
logging.basicConfig( SOCKET_RETRY_DELAY = 1.5
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)
SOCKET_RETRY_DELAY = 5 # Time in seconds between retries to connect to the socket
MAX_RETRIES = 10 # Maximum number of retries to connect to the socket
# Configuration # Configuration
MPV_SOCKET: str = os.getenv("MPV_SOCKET", "/tmp/mpvsocket") MPV_SOCKET: str = os.getenv("MPV_SOCKET", "/tmp/mpvsocket")
HOST_NAME: str = os.getenv("HOST_NAME", "0.0.0.0") HOST_NAME: str = os.getenv("HOST_NAME", "0.0.0.0")
@ -29,25 +22,56 @@ MYSQL_USER: str = os.getenv("MYSQL_USER", "your_username")
MYSQL_PASSWORD: str = os.getenv("MYSQL_PASSWORD", "your_password") MYSQL_PASSWORD: str = os.getenv("MYSQL_PASSWORD", "your_password")
MYSQL_PORT: int = int(os.getenv("MYSQL_PORT", "3306")) MYSQL_PORT: int = int(os.getenv("MYSQL_PORT", "3306"))
LOGLEVEL = os.getenv("LOGLEVEL", "INFO").strip().upper() LOGLEVEL = os.getenv("LOGLEVEL", "INFO").strip().upper()
if LOGLEVEL == "DEBUG":
logging.getLogger().setLevel(logging.DEBUG)
elif LOGLEVEL == "WARNING":
logging.getLogger().setLevel(logging.WARNING)
elif LOGLEVEL == "ERROR":
logging.getLogger().setLevel(logging.ERROR)
else:
logging.getLogger().setLevel(logging.INFO)
# Initialize Flask
app = Flask(__name__) app = Flask(__name__)
def get_mysql_connection(): # Set up logging
"""Get a MySQL database connection.""" def setup_logging():
try: """Sets up logging for both the app and flask."""
logging.debug( if not app.logger.hasHandlers(): # Check if there are already handlers
f"Connection information: {MYSQL_HOST}, {MYSQL_USER}, {MYSQL_PORT}" # Create a formatter
formatter = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
) )
# Create a console handler
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
# Configure the root logger
app.logger.addHandler(console_handler)
# Set the log level based on LOGLEVEL
if LOGLEVEL == "DEBUG":
app.logger.setLevel(logging.DEBUG)
elif LOGLEVEL == "WARNING":
app.logger.setLevel(logging.WARNING)
elif LOGLEVEL == "ERROR":
app.logger.setLevel(logging.ERROR)
else:
app.logger.setLevel(logging.INFO)
# Silence noisy logs from certain libraries if necessary
logging.getLogger("logger").setLevel(logging.INFO)
# Set up logging
setup_logging()
def get_mysql_connection():
"""
Get a MySQL database connection.
--------
Returns
--------
connection: mysql.connector.connection.MySQLConnection
The MySQL connection object if successful, otherwise None.
"""
try:
connection = mysql.connector.connect( connection = mysql.connector.connect(
host=MYSQL_HOST, host=MYSQL_HOST,
user=MYSQL_USER, user=MYSQL_USER,
@ -55,10 +79,10 @@ def get_mysql_connection():
port=MYSQL_PORT, port=MYSQL_PORT,
) )
if connection.is_connected(): if connection.is_connected():
logging.info("Connected to MySQL database") app.logger.debug("Connected to database successfully.")
return connection return connection
except Error as e: except Error as e:
logging.error(f"Error while connecting to MySQL: {e}") app.logger.error(f"Error while connecting to MySQL: {e}")
return None return None
@ -82,15 +106,15 @@ def ensure_watch_history_table_exists():
""" """
) )
connection.commit() connection.commit()
logging.info("Ensured watch_history table exists") app.logger.info("Ensured watch_history table exists")
except Error as e: except Error as e:
logging.error(f"Failed to ensure watch_history table exists: {e}") app.logger.error(f"Failed to ensure watch_history table exists: {e}")
finally: finally:
cursor.close() cursor.close()
connection.close() connection.close()
def send_to_mpv(command): def send_to_mpv(command: str):
"""Send a command to the mpv socket, retrying up to MAX_RETRIES times if the socket is not available.""" """Send a command to the mpv socket, retrying up to MAX_RETRIES times if the socket is not available."""
attempts = 0 attempts = 0
while attempts < MAX_RETRIES: while attempts < MAX_RETRIES:
@ -98,21 +122,38 @@ def send_to_mpv(command):
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client_socket: with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client_socket:
client_socket.connect(MPV_SOCKET) client_socket.connect(MPV_SOCKET)
client_socket.sendall(command.encode("utf-8")) client_socket.sendall(command.encode("utf-8"))
logging.info("Command sent to mpv successfully.") app.logger.info("Command sent to mpv successfully.")
return True return True
except socket.error as e: except socket.error as e:
attempts += 1 attempts += 1
logging.error( app.logger.error(
f"Failed to connect to socket (attempt {attempts}/{MAX_RETRIES}): {e}. Retrying in {SOCKET_RETRY_DELAY} seconds..." f"Failed to connect to socket (attempt {attempts}/{MAX_RETRIES}): {e}. Retrying in {SOCKET_RETRY_DELAY} seconds..."
) )
time.sleep(SOCKET_RETRY_DELAY) time.sleep(SOCKET_RETRY_DELAY)
logging.error(f"Exceeded maximum retries ({MAX_RETRIES}). Ignoring the request.") app.logger.error(f"Exceeded maximum retries ({MAX_RETRIES}). Ignoring the request.")
return False return False
@app.route("/add_video", methods=["POST"]) @app.route("/add_video", methods=["POST"])
def add_video(): def add_video():
"""
Adds a video to the mpv queue and the MySQL database.
--------
Parameters
--------
data: dict
The JSON data containing the video information.
Required fields:
- video_url: str
- video_name: str
- channel_url: str
- channel_name: str
e.g. {"video_url": "https://www.youtube.com/watch?v=video_id", "video_name": "video_name", "channel_url": "https://www.youtube.com/channel/channel_id", "channel_name": "channel_name"}
"""
data = request.get_json() data = request.get_json()
if data: if data:
@ -120,10 +161,11 @@ def add_video():
video_name: str = data.get("video_name") video_name: str = data.get("video_name")
channel_url: str = data.get("channel_url") channel_url: str = data.get("channel_url")
channel_name: str = data.get("channel_name") channel_name: str = data.get("channel_name")
watch_date: date = data.get("watch_date") watch_date: date = date.today().strftime("%Y-%m-%d")
if video_url and video_name and channel_url and channel_name and watch_date: if video_url and video_name and channel_url and channel_name and watch_date:
logging.info(f"Received data: {data}") app.logger.debug(f"Received data: {data}")
app.logger.debug(f"Watch date: {watch_date}")
# Insert the data into the MySQL database # Insert the data into the MySQL database
connection = get_mysql_connection() connection = get_mysql_connection()
@ -145,13 +187,13 @@ def add_video():
), ),
) )
connection.commit() connection.commit()
logging.info("Data inserted into MySQL database") app.logger.info("Data inserted into MySQL database")
return ( return (
jsonify(message="Data added to mpv queue and database"), jsonify(message="Data added to mpv queue and database"),
200, 200,
) )
except Error as e: except Error as e:
logging.error(f"Failed to insert data into MySQL database: {e}") app.logger.error(f"Failed to insert data into MySQL database: {e}")
return jsonify(message="Failed to add data to database"), 500 return jsonify(message="Failed to add data to database"), 500
finally: finally:
cursor.close() cursor.close()
@ -159,19 +201,22 @@ def add_video():
else: else:
return jsonify(message="Failed to connect to MySQL database"), 500 return jsonify(message="Failed to connect to MySQL database"), 500
else: else:
logging.error("Missing required data fields") app.logger.error("Missing required data fields")
return jsonify(message="Missing required data fields"), 400 return jsonify(message="Missing required data fields"), 400
else: else:
logging.error("Invalid JSON data") app.logger.error("Invalid JSON data")
return jsonify(message="Invalid JSON data"), 400 return jsonify(message="Invalid JSON data"), 400
@app.route("/", methods=["GET"]) @app.route("/", methods=["GET"])
def handle_request(): def handle_request():
"""
Handle GET requests to the root URL. This function is used to add a video to the mpv queue.
"""
video_url = request.args.get("url") video_url = request.args.get("url")
if video_url: if video_url:
video_url = urllib.parse.unquote(video_url) # Decode the URL video_url = urllib.parse.unquote(video_url) # Decode the URL
logging.info(f"Received URL: {video_url}") app.logger.info(f"Received URL: {video_url}")
# Create the command to send to mpv # Create the command to send to mpv
command = f'{{"command": ["script-message", "add_to_youtube_queue", "{video_url}"]}}\n' command = f'{{"command": ["script-message", "add_to_youtube_queue", "{video_url}"]}}\n'
@ -182,17 +227,17 @@ def handle_request():
else: else:
return "Failed to add URL to mpv queue after max retries", 500 return "Failed to add URL to mpv queue after max retries", 500
else: else:
logging.error("Missing 'url' parameter") app.logger.error("Missing 'url' parameter")
return "Missing 'url' parameter", 400 return "Missing 'url' parameter", 400
if __name__ == "__main__": if __name__ == "__main__":
logging.info(f"Starting server on {HOST_NAME}:{PORT_NUMBER}...") app.logger.info(f"Starting server on {HOST_NAME}:{PORT_NUMBER}...")
ensure_watch_history_table_exists() ensure_watch_history_table_exists()
try: try:
app.run(host=HOST_NAME, port=PORT_NUMBER) app.run(host=HOST_NAME, port=PORT_NUMBER)
except Exception as e: except Exception as e:
logging.exception(f"Error occurred: {e}") app.logger.exception(f"Error occurred: {e}")
except KeyboardInterrupt: except KeyboardInterrupt:
logging.info("Server is shutting down...") app.logger.info("Server is shutting down...")
logging.info("Server stopped.") app.logger.info("Server stopped.")