changes to db and added requirements.txt for setup

This commit is contained in:
Brandon4466
2025-05-31 18:15:25 -07:00
parent cc290d5720
commit b8f1ce3b13
4 changed files with 14872 additions and 18 deletions

83
main.py
View File

@@ -5,12 +5,21 @@ import requests
import time
import jwt
import json
import logging # New import for logging
from fastapi import FastAPI, HTTPException, Request, Depends, Header, WebSocket, WebSocketDisconnect, Query
from fastapi.responses import StreamingResponse, FileResponse
from passlib.context import CryptContext
import media_scanner # Import the Rust module
from rapidfuzz import fuzz
# Configure logging
logging.basicConfig(
filename="scan.log", # Log file name
filemode="a", # Append mode
format="%(asctime)s - %(levelname)s - %(message)s",
level=logging.INFO
)
# Configuration
MOVIES_DIR = r"Z:\plexmediaserver\movies" # Directory containing movie files
TV_SHOWS_DIR = r"Z:\plexmediaserver\tv" # Directory containing TV shows and episodes
@@ -179,6 +188,9 @@ def fetch_movie_details(title, year=None):
response = requests.get('http://www.omdbapi.com/', params=params)
data = response.json()
if data.get('Response') == 'True':
logging.info(data)
if data['Poster'] == 'N/A':
data['Poster'] = 'https://placehold.co/500x750/jpg?text=No+Poster'
return data
else:
raise ValueError(f"Movie '{title}' not found.")
@@ -217,11 +229,15 @@ def add_tv_show_to_db(details):
def scan_and_populate():
init_db()
processed_shows = set() # Keep track of processed TV shows
log_messages = [] # Collect log messages
try:
# Use Rust for scanning movies
print("Scanning movies...")
msg = "Scanning movies..."
print(msg)
logging.info(msg)
movie_files = media_scanner.scan_movies(MOVIES_DIR)
print(f"Found movie files: {movie_files}")
msg = f"Found movie files: {movie_files}"
print(msg)
logging.info(msg)
for full_path in movie_files:
parent = os.path.basename(os.path.dirname(full_path))
match = re.match(r"(.+?)\s*\((\d{4})\)$", parent)
@@ -233,20 +249,29 @@ def scan_and_populate():
year = None
rel_path = os.path.relpath(full_path, MOVIES_DIR)
if movie_exists(rel_path):
print(f"Movie already exists: {title} ({year or 'n/a'})")
msg = f"Movie already exists: {title} ({year or 'n/a'})"
print(msg)
logging.info(msg)
continue
try:
details = fetch_movie_details(title, year)
details['filepath'] = rel_path
add_movie_to_db(details)
print(f"Added {title} ({year or 'n/a'}) to database.")
msg = f"Added {title} ({year or 'n/a'}) to database."
print(msg)
logging.info(msg)
except Exception as e:
print(f"Skipping {title}: {e}")
msg = f"Skipping {title}: {e}"
print(msg)
logging.error(msg)
# Updated logic for scanning TV shows with fuzzy matching
print("Scanning TV shows...")
msg = "Scanning TV shows..."
print(msg)
logging.info(msg)
tv_show_files = media_scanner.scan_tv_shows(TV_SHOWS_DIR)
print(f"Found TV show files: {tv_show_files}")
msg = f"Found TV show files: {tv_show_files}"
print(msg)
logging.info(msg)
for full_path in tv_show_files:
# Extract TV show name from the folder structure: "Show Name\Season X\filename"
show_name = os.path.basename(os.path.dirname(os.path.dirname(full_path)))
@@ -254,14 +279,18 @@ def scan_and_populate():
season_dir = os.path.basename(os.path.dirname(full_path))
season_match = re.search(r"Season\s*(\d+)", season_dir, re.IGNORECASE)
if not season_match:
print(f"Skipping {full_path}: Season number not found in directory '{season_dir}'")
msg = f"Skipping {full_path}: Season number not found in directory '{season_dir}'"
print(msg)
logging.warning(msg)
continue
season = int(season_match.group(1))
# Extract episode number solely from the SxxEyy pattern in the filename
basename = os.path.basename(full_path)
ep_match = re.search(r"(?i)S(\d{2})E(\d{2})", basename)
if not ep_match:
print(f"Skipping {full_path}: SxxEyy pattern not found in filename")
msg = f"Skipping {full_path}: SxxEyy pattern not found in filename"
print(msg)
logging.warning(msg)
continue
episode = int(ep_match.group(2))
# Check and add TV show details if not processed yet
@@ -270,11 +299,17 @@ def scan_and_populate():
try:
tv_details = fetch_tv_show_details(show_name)
add_tv_show_to_db(tv_details)
print(f"Added TV show details: {show_name}")
msg = f"Added TV show details: {show_name}"
print(msg)
logging.info(msg)
except Exception as e:
print(f"Skipping TV show details for {show_name}: {e}")
msg = f"Skipping TV show details for {show_name}: {e}"
print(msg)
logging.error(msg)
else:
print(f"TV show already exists: {show_name}")
msg = f"TV show already exists: {show_name}"
print(msg)
logging.info(msg)
processed_shows.add(show_name)
rel_path = os.path.relpath(full_path, TV_SHOWS_DIR)
conn = sqlite3.connect(DB_PATH)
@@ -296,9 +331,13 @@ def scan_and_populate():
break
if tv_show_row:
tv_show_id = tv_show_row[0]
print(f"Fuzzy matched '{show_name}' to '{tv_show_row[1]}' with score {similarity}")
msg = f"Fuzzy matched '{show_name}' to '{tv_show_row[1]}' with score {similarity}"
print(msg)
logging.info(msg)
else:
print(f"TV show id not found for {show_name}")
msg = f"TV show id not found for {show_name}"
print(msg)
logging.warning(msg)
conn.close()
continue
# Use the complete filename (without extension) as the episode title
@@ -309,9 +348,17 @@ def scan_and_populate():
''', (rel_path, tv_show_id, season, episode, title))
conn.commit()
conn.close()
print(f"Added episode: {show_name} Season {season} Episode {episode}")
msg = f"Added episode: {show_name} Season {season} Episode {episode}"
print(msg)
logging.info(msg)
except Exception as e:
print(f"Error during scanning: {e}")
msg = f"Error during scanning: {e}"
print(msg)
logging.error(msg)
finally:
msg = "Scan and populate completed."
print(msg)
logging.info(msg)
def range_streamer(file_path: str, range_header: str = None, chunk_size: int = 1024*1024):
file_size = os.path.getsize(file_path)