Skip to content

Commit

Permalink
0.5.70 - added media type filtering per content source, improved perf…
Browse files Browse the repository at this point in the history
…ormance monitor
  • Loading branch information
godver3 committed Feb 4, 2025
1 parent 5024c8c commit 4a6a85a
Show file tree
Hide file tree
Showing 10 changed files with 548 additions and 97 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,4 @@ run.sh
config/config.json.backup
config/secret_key
config
auto_blacklist
32 changes: 30 additions & 2 deletions database/wanted_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
from metadata.metadata import get_tmdb_id_and_media_type
import random
import os
from config_manager import load_config

def add_wanted_items(media_items_batch: List[Dict[str, Any]], versions_input):
from metadata.metadata import get_show_airtime_by_imdb_id
from settings import get_setting


conn = get_db_connection()
try:
items_added = 0
Expand All @@ -25,10 +25,15 @@ def add_wanted_items(media_items_batch: List[Dict[str, Any]], versions_input):
'existing_episode_tmdb': 0,
'missing_ids': 0,
'blacklisted': 0,
'already_watched': 0
'already_watched': 0,
'media_type_mismatch': 0
}
airtime_cache = {}

# Load config to get content source settings
config = load_config()
content_sources = config.get('Content Sources', {})

# Check if we should skip watched content
do_not_add_watched = get_setting('Debug','do_not_add_plex_watch_history_items_to_queue', False)
watch_history_conn = None
Expand Down Expand Up @@ -56,7 +61,24 @@ def add_wanted_items(media_items_batch: List[Dict[str, Any]], versions_input):
episode_imdb_keys = set()
episode_tmdb_keys = set()

filtered_media_items_batch = []
for item in media_items_batch:
# Get content source settings
content_source = item.get('content_source')
if content_source and content_source in content_sources:
source_config = content_sources[content_source]
source_media_type = source_config.get('media_type', 'All')

# Skip if content source is not Collected and media type doesn't match
if not content_source.startswith('Collected_'):
item_type = 'episode' if 'season_number' in item and 'episode_number' in item else 'movie'
if source_media_type != 'All':
if (source_media_type == 'Movies' and item_type != 'movie') or \
(source_media_type == 'Shows' and item_type != 'episode'):
skip_stats['media_type_mismatch'] += 1
items_skipped += 1
continue

imdb_id = item.get('imdb_id')
tmdb_id = item.get('tmdb_id')

Expand Down Expand Up @@ -85,6 +107,10 @@ def add_wanted_items(media_items_batch: List[Dict[str, Any]], versions_input):
episode_tmdb_ids.add(tmdb_id)
episode_tmdb_keys.add((tmdb_id, season_number, episode_number))

filtered_media_items_batch.append(item)

media_items_batch = filtered_media_items_batch

existing_movies = set()
batch_size = 450

Expand Down Expand Up @@ -313,6 +339,8 @@ def add_wanted_items(media_items_batch: List[Dict[str, Any]], versions_input):
skip_report.append(f"- {skip_stats['blacklisted']} items skipped due to blacklist")
if skip_stats['already_watched'] > 0:
skip_report.append(f"- {skip_stats['already_watched']} items skipped due to watch history")
if skip_stats['media_type_mismatch'] > 0:
skip_report.append(f"- {skip_stats['media_type_mismatch']} items skipped due to media type mismatch")

if skip_report:
logging.info("Wanted items processing complete. Skip summary:\n" + "\n".join(skip_report))
Expand Down
34 changes: 34 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,40 @@ def main():
logging.info("Resetting Torbox debrid provider to Real-Debrid")
set_setting('Debrid Provider', 'provider', 'RealDebrid')

# Add migration for media_type setting
from config_manager import load_config, save_config
config = load_config()
if 'Content Sources' in config:
updated = False
for source_id, source_config in config['Content Sources'].items():
# Skip the Collected source as it doesn't use media_type
if source_id.startswith('Collected_'):
continue

# Check if media_type is missing
if 'media_type' not in source_config:
# Create new ordered dict with desired key order
new_config = {}
# Copy existing keys except display_name
for key in source_config:
if key != 'display_name':
new_config[key] = source_config[key]
# Add media_type before display_name
new_config['media_type'] = 'All'
# Add display_name last if it exists
if 'display_name' in source_config:
new_config['display_name'] = source_config['display_name']

# Replace the old config with the new ordered one
config['Content Sources'][source_id] = new_config
logging.info(f"Adding default media_type 'All' to content source {source_id}")
updated = True

# Save the updated config if changes were made
if updated:
save_config(config)
logging.info("Successfully migrated content sources to include media_type setting")

# Get battery port from environment variable
battery_port = int(os.environ.get('CLI_DEBRID_BATTERY_PORT', '5001'))

Expand Down
14 changes: 10 additions & 4 deletions performance_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ def _log_basic_metrics(self):
memory_info = process.memory_info()
virtual_memory = psutil.virtual_memory()

# Calculate actual memory usage percentage without cache
total_memory = virtual_memory.total
used_memory = virtual_memory.total - virtual_memory.available
memory_percent = (used_memory / total_memory) * 100

memory_delta_str = ""
if self._last_memory_info is not None:
try:
Expand All @@ -174,15 +179,16 @@ def _log_basic_metrics(self):

self._last_memory_info = memory_info.rss

# Create entry
# Create entry with UTC timestamp
current_time = datetime.utcnow()
entry = {
"timestamp": datetime.now().isoformat(),
"timestamp": current_time.isoformat(),
"type": "basic_metrics",
"metrics": {
"cpu_percent": cpu_percent,
"memory_rss": memory_info.rss / 1024 / 1024, # Convert to MB
"memory_vms": memory_info.vms / 1024 / 1024, # Convert to MB
"system_memory_used": virtual_memory.percent,
"system_memory_used": memory_percent,
"swap_used": psutil.swap_memory().used / 1024 / 1024, # Convert to MB
"cpu_user_time": cpu_times.user,
"cpu_system_time": cpu_times.system
Expand Down Expand Up @@ -213,7 +219,7 @@ def _log_basic_metrics(self):
memory_info.rss / 1024 / 1024,
memory_delta_str,
memory_info.vms / 1024 / 1024,
virtual_memory.percent,
memory_percent,
psutil.swap_memory().used / 1024 / 1024
))

Expand Down
14 changes: 9 additions & 5 deletions routes/performance_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def get_performance_log():
limit = request.args.get('limit', type=int, default=1000)
entry_type = request.args.get('type', type=str) # Optional type filter
metric_type = request.args.get('metric', type=str) # Optional metric filter
cutoff_time = datetime.now() - timedelta(hours=hours)
cutoff_time = datetime.utcnow() - timedelta(hours=hours)

try:
entries = []
Expand All @@ -42,15 +42,19 @@ def get_performance_log():
if metric_type and ('metrics' not in entry or metric_type not in entry['metrics']):
continue

entry_time = datetime.fromisoformat(entry['timestamp'])
entry_time = datetime.fromisoformat(entry['timestamp'].replace('Z', '+00:00'))
if entry_time >= cutoff_time:
entries.append(entry)
if len(entries) >= limit:
break
except (json.JSONDecodeError, KeyError, ValueError) as e:
continue

# Sort entries by timestamp
# Sort entries by timestamp in descending order (newest first)
entries.sort(key=lambda x: x.get('timestamp', ''), reverse=True)

# Take only the most recent entries up to the limit
entries = entries[:limit]

# Re-sort in ascending order for display
entries.sort(key=lambda x: x.get('timestamp', ''))

# Get system info for metadata
Expand Down
9 changes: 9 additions & 0 deletions settings_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@
"enabled": {"type": "boolean", "default": False},
"urls": {"type": "string", "default": ""},
"versions": {"type": "dict", "default": {"Default": True}},
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
"display_name": {"type": "string", "default": "MDBList"}
},
"Collected": {
Expand All @@ -450,48 +451,56 @@
"Trakt Watchlist": {
"enabled": {"type": "boolean", "default": False},
"versions": {"type": "dict", "default": {"Default": True}},
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
"display_name": {"type": "string", "default": "Trakt Watchlist"}
},
"Trakt Lists": {
"enabled": {"type": "boolean", "default": False},
"trakt_lists": {"type": "string", "default": ""},
"versions": {"type": "dict", "default": {"Default": True}},
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
"display_name": {"type": "string", "default": "Trakt Lists"}
},
"Trakt Collection": {
"enabled": {"type": "boolean", "default": False},
"versions": {"type": "dict", "default": {"Default": True}},
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
"display_name": {"type": "string", "default": "Trakt Collection"}
},
"Overseerr": {
"enabled": {"type": "boolean", "default": False},
"url": {"type": "string", "default": "", "validate": "url"},
"api_key": {"type": "string", "default": "", "sensitive": True},
"versions": {"type": "dict", "default": {"Default": True}},
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
"display_name": {"type": "string", "default": "Overseerr"}
},
"My Plex Watchlist": {
"enabled": {"type": "boolean", "default": False},
"versions": {"type": "dict", "default": {"Default": True}},
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
"display_name": {"type": "string", "default": "My Plex Watchlist"}
},
"Other Plex Watchlist": {
"enabled": {"type": "boolean", "default": False},
"username": {"type": "string", "default": ""},
"token": {"type": "string", "default": "", "sensitive": True},
"versions": {"type": "dict", "default": {"Default": True}},
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
"display_name": {"type": "string", "default": "Other Plex Watchlist"}
},
"My Plex RSS Watchlist": {
"enabled": {"type": "boolean", "default": False},
"url": {"type": "string", "default": "", "validate": "url"},
"versions": {"type": "dict", "default": {"Default": True}},
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
"display_name": {"type": "string", "default": "My Plex RSS Watchlist"}
},
"My Friends Plex RSS Watchlist": {
"enabled": {"type": "boolean", "default": False},
"url": {"type": "string", "default": "", "validate": "url"},
"versions": {"type": "dict", "default": {"Default": True}},
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
"display_name": {"type": "string", "default": "My Friends Plex RSS Watchlist"}
}
}
Expand Down
Loading

0 comments on commit 4a6a85a

Please sign in to comment.