Skip to content

Commit

Permalink
merge from dev
Browse files Browse the repository at this point in the history
  • Loading branch information
root committed Oct 12, 2024
2 parents 6a52e67 + 69d1305 commit 4210525
Show file tree
Hide file tree
Showing 10 changed files with 318 additions and 216 deletions.
50 changes: 18 additions & 32 deletions movie_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@
import pytz
from flask import Flask, jsonify, render_template, send_from_directory, request, session
from flask_socketio import SocketIO, emit
from utils.cache_manager import CacheManager
from utils.poster_view import set_current_movie, poster_bp, init_socket
from utils.default_poster_manager import init_default_poster_manager, default_poster_manager
from utils.playback_monitor import PlaybackMonitor
from utils.fetch_movie_links import fetch_movie_links

logging.basicConfig(level=logging.DEBUG)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = Flask(__name__, static_folder='static', template_folder='web')
app.secret_key = 'your_secret_key_here' # Replace with a real secret key
socketio = SocketIO(app)
init_socket(socketio)

from utils.cache_manager import CacheManager

# Initialize the default poster manager
default_poster_manager = init_default_poster_manager(socketio)

Expand All @@ -44,7 +45,7 @@
if PLEX_AVAILABLE:
from utils.plex_service import PlexService
plex = PlexService()
cache_manager = CacheManager(plex, cache_file_path)
cache_manager = CacheManager(plex, cache_file_path, socketio, app)
cache_manager.start()
app.config['PLEX_SERVICE'] = plex
else:
Expand Down Expand Up @@ -88,7 +89,7 @@ def resync_cache():
loading_in_progress = True
try:
if cache_manager:
cache_manager.update_cache()
cache_manager.update_cache(emit_progress=True)
all_plex_unwatched_movies = cache_manager.get_cached_movies()
movies_loaded_from_cache = True
update_cache_status()
Expand Down Expand Up @@ -196,17 +197,17 @@ def random_movie():
@app.route('/filter_movies')
def filter_movies():
current_service = session.get('current_service', get_available_service())
genre = request.args.get('genre')
year = request.args.get('year')
pg_rating = request.args.get('pg_rating')
genres = request.args.get('genres', '').split(',') if request.args.get('genres') else None
years = request.args.get('years', '').split(',') if request.args.get('years') else None
pg_ratings = request.args.get('pg_ratings', '').split(',') if request.args.get('pg_ratings') else None

logger.debug(f"Filtering movies with genre: {genre}, year: {year}, pg_rating: {pg_rating}")
logger.debug(f"Filtering movies with genres: {genres}, years: {years}, pg_ratings: {pg_ratings}")

try:
if current_service == 'plex' and PLEX_AVAILABLE:
movie_data = plex.filter_movies(genre, year, pg_rating)
movie_data = plex.filter_movies(genres, years, pg_ratings)
elif current_service == 'jellyfin' and JELLYFIN_AVAILABLE:
movie_data = jellyfin.filter_movies(genre, year, pg_rating)
movie_data = jellyfin.filter_movies(genres, years, pg_ratings)
else:
return jsonify({"error": "No available media service"}), 400

Expand All @@ -223,33 +224,18 @@ def filter_movies():

@app.route('/next_movie')
def next_movie():
global all_plex_unwatched_movies
current_service = session.get('current_service', get_available_service())
genre = request.args.get('genre')
year = request.args.get('year')
pg_rating = request.args.get('pg_rating')
genres = request.args.get('genres', '').split(',') if request.args.get('genres') else None
years = request.args.get('years', '').split(',') if request.args.get('years') else None
pg_ratings = request.args.get('pg_ratings', '').split(',') if request.args.get('pg_ratings') else None

logger.debug(f"Next movie request with filters - genre: {genre}, year: {year}, pg_rating: {pg_rating}")
logger.debug(f"Next movie request with filters - genres: {genres}, years: {years}, pg_ratings: {pg_ratings}")

try:
if current_service == 'plex' and PLEX_AVAILABLE:
if not all_plex_unwatched_movies:
all_plex_unwatched_movies = plex.get_all_unwatched_movies()

filtered_movies = all_plex_unwatched_movies
if genre:
filtered_movies = [m for m in filtered_movies if genre in m['genres']]
if year:
filtered_movies = [m for m in filtered_movies if m['year'] == int(year)]
if pg_rating:
filtered_movies = [m for m in filtered_movies if m['contentRating'] == pg_rating]

if filtered_movies:
movie_data = random.choice(filtered_movies)
else:
movie_data = None
movie_data = plex.filter_movies(genres, years, pg_ratings)
elif current_service == 'jellyfin' and JELLYFIN_AVAILABLE:
movie_data = jellyfin.filter_movies(genre, year, pg_rating)
movie_data = jellyfin.filter_movies(genres, years, pg_ratings)
else:
return jsonify({"error": "No available media service"}), 400

Expand Down Expand Up @@ -435,7 +421,7 @@ def debug_plex():
"cached_movies": cached_movies,
"loaded_from_cache": movies_loaded_from_cache,
"plex_url": os.getenv('PLEX_URL'),
"movies_library_name": os.getenv('MOVIES_LIBRARY_NAME'),
"movies_library_name": os.getenv('PLEX_MOVIE_LIBRARIES'),
"cache_file_exists": os.path.exists(cache_file_path)
})
except Exception as e:
Expand Down
124 changes: 76 additions & 48 deletions static/js/script.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
let currentFilters = {
genre: '',
year: '',
pgRating: ''
genres: [],
years: [],
pgRatings: []
};

let currentService = 'plex';
Expand All @@ -16,6 +16,7 @@ document.addEventListener('DOMContentLoaded', async function() {
await loadFilterOptions();
setupEventListeners();
checkAndLoadCache();
checkPowerButtonVisibility();
});

function showLoadingOverlay() {
Expand Down Expand Up @@ -172,14 +173,23 @@ function setupEventListeners() {
}
}

async function applyFilter() {
currentFilters.genre = document.getElementById("genreSelect").value;
currentFilters.year = document.getElementById("yearSelect").value;
currentFilters.pgRating = document.getElementById("pgRatingSelect").value;
function applyFilter() {
currentFilters.genres = Array.from(document.getElementById("genreSelect").selectedOptions).map(option => option.value);
currentFilters.years = Array.from(document.getElementById("yearSelect").selectedOptions).map(option => option.value);
currentFilters.pgRatings = Array.from(document.getElementById("pgRatingSelect").selectedOptions).map(option => option.value);

fetchFilteredMovies();
}

async function fetchFilteredMovies() {
try {
const response = await fetch(`/filter_movies?genre=${encodeURIComponent(currentFilters.genre)}&year=${currentFilters.year}&pg_rating=${encodeURIComponent(currentFilters.pgRating)}`);

const queryParams = new URLSearchParams();
if (currentFilters.genres.length) queryParams.append('genres', currentFilters.genres.join(','));
if (currentFilters.years.length) queryParams.append('years', currentFilters.years.join(','));
if (currentFilters.pgRatings.length) queryParams.append('pg_ratings', currentFilters.pgRatings.join(','));

const response = await fetch(`/filter_movies?${queryParams}`);

if (response.status === 204) {
showNoMoviesMessage();
return;
Expand All @@ -200,6 +210,47 @@ async function applyFilter() {
}
}

function clearFilter() {
document.getElementById("genreSelect").selectedIndex = -1;
document.getElementById("yearSelect").selectedIndex = -1;
document.getElementById("pgRatingSelect").selectedIndex = -1;
currentFilters = {
genres: [],
years: [],
pgRatings: []
};
hideMessage();
loadRandomMovie();
document.getElementById("filterDropdown").classList.remove("show");
}

async function loadNextMovie() {
try {
const queryParams = new URLSearchParams();
if (currentFilters.genres.length) queryParams.append('genres', currentFilters.genres.join(','));
if (currentFilters.years.length) queryParams.append('years', currentFilters.years.join(','));
if (currentFilters.pgRatings.length) queryParams.append('pg_ratings', currentFilters.pgRatings.join(','));

const url = `/next_movie?${queryParams}`;
console.log("Requesting next movie with URL:", url);
const response = await fetch(url);

if (response.status === 204) {
showNoMoviesMessage();
return;
}
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log("Loaded next movie from service:", data.service);
currentMovie = data.movie;
updateMovieDisplay(data.movie);
} catch (error) {
console.error("Error fetching next movie:", error);
showErrorMessage(error.message);
}
}

function showMessage() {
document.getElementById("movieContent").classList.add("hidden");
Expand Down Expand Up @@ -235,44 +286,6 @@ function showErrorMessage(message) {
showMessage();
}

function clearFilter() {
document.getElementById("genreSelect").value = '';
document.getElementById("yearSelect").value = '';
document.getElementById("pgRatingSelect").value = '';
currentFilters = {
genre: '',
year: '',
pgRating: ''
};
hideMessage();
loadRandomMovie();
document.getElementById("filterDropdown").classList.remove("show");
}

async function loadNextMovie() {
try {
let url = `/next_movie`;
if (currentFilters.genre || currentFilters.year || currentFilters.pgRating) {
url += `?genre=${encodeURIComponent(currentFilters.genre || '')}&year=${currentFilters.year || ''}&pg_rating=${encodeURIComponent(currentFilters.pgRating || '')}`;
}
const response = await fetch(url);
if (response.status === 204) {
showNoMoviesMessage();
return;
}
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log("Loaded next movie from service:", data.service);
currentMovie = data.movie;
updateMovieDisplay(data.movie);
} catch (error) {
console.error("Error fetching next movie:", error);
showErrorMessage(error.message);
}
}

function updateMovieDisplay(movieData) {
if (!movieData) {
console.error("No movie data to display");
Expand Down Expand Up @@ -374,7 +387,7 @@ function setupDescriptionExpander() {
function checkTruncation() {
description.style.webkitLineClamp = '4';
description.style.display = '-webkit-box';

if (description.scrollHeight > description.clientHeight) {
description.classList.add('truncated');
description.style.cursor = 'pointer';
Expand Down Expand Up @@ -518,6 +531,21 @@ function updateServiceButton() {
}
}

function checkPowerButtonVisibility() {
const powerButton = document.getElementById("btn_power");
if (powerButton) {
fetch('/devices')
.then(response => response.json())
.then(devices => {
powerButton.style.display = devices.length > 0 ? 'flex' : 'none';
})
.catch(error => {
console.error("Error checking devices:", error);
powerButton.style.display = 'none';
});
}
}

async function switchService() {
if (window.HOMEPAGE_MODE) return;

Expand Down
5 changes: 3 additions & 2 deletions static/style/style.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
static/style/style.css
body {
margin: 0;
padding: 0;
Expand Down Expand Up @@ -584,14 +585,14 @@ main {
/* PWA specific styles */
@media all and (display-mode: standalone) and (max-width: 767px) {
body {
padding-top: 0;
padding-top: 0;
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
}

#section {
padding-top: env(safe-area-inset-top);
padding-top: env(safe-area-inset-top);
}

.filter-container {
Expand Down
54 changes: 31 additions & 23 deletions utils/cache_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
logger = logging.getLogger(__name__)

class CacheManager:
def __init__(self, plex_service, cache_file_path, update_interval=600):
def __init__(self, plex_service, cache_file_path, socketio, app, update_interval=600):
self.plex_service = plex_service
self.cache_file_path = cache_file_path
self.socketio = socketio
self.app = app
self.update_interval = update_interval
self.running = False

Expand All @@ -23,30 +25,36 @@ def stop(self):

def _update_loop(self):
while self.running:
self.update_cache()
self.update_cache(emit_progress=False)
time.sleep(self.update_interval)

def update_cache(self):
try:
new_unwatched_movies = self.plex_service.get_all_unwatched_movies()

# Read the current cache
if os.path.exists(self.cache_file_path):
with open(self.cache_file_path, 'r') as f:
current_cache = json.load(f)
else:
current_cache = []

# Check for changes
if len(new_unwatched_movies) != len(current_cache):
logger.info(f"Updating cache. Old count: {len(current_cache)}, New count: {len(new_unwatched_movies)}")
with open(self.cache_file_path, 'w') as f:
json.dump(new_unwatched_movies, f)
else:
logger.info("No changes in unwatched movies. Cache remains the same.")

except Exception as e:
logger.error(f"Error updating cache: {str(e)}")
def update_cache(self, emit_progress=False):
with self.app.app_context():
try:
def progress_callback(progress):
if emit_progress:
self.socketio.emit('loading_progress', {'progress': progress}, namespace='/')
logger.debug(f"Emitted loading_progress: {progress}")

new_unwatched_movies = self.plex_service.get_all_unwatched_movies(progress_callback=progress_callback)

# Read the current cache
if os.path.exists(self.cache_file_path):
with open(self.cache_file_path, 'r') as f:
current_cache = json.load(f)
else:
current_cache = []

# Check for changes
if len(new_unwatched_movies) != len(current_cache):
logger.info(f"Updating cache. Old count: {len(current_cache)}, New count: {len(new_unwatched_movies)}")
with open(self.cache_file_path, 'w') as f:
json.dump(new_unwatched_movies, f)
else:
logger.info("No changes in unwatched movies. Cache remains the same.")

except Exception as e:
logger.error(f"Error updating cache: {str(e)}")

def get_cached_movies(self):
if os.path.exists(self.cache_file_path):
Expand Down
2 changes: 1 addition & 1 deletion utils/default_poster_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import logging
from flask_socketio import SocketIO

logging.basicConfig(level=logging.DEBUG)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class DefaultPosterManager:
Expand Down
Loading

0 comments on commit 4210525

Please sign in to comment.