changes to db and added requirements.txt for setup
This commit is contained in:
83
main.py
83
main.py
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user