Skip to content

Commit 4a6a85a

Browse files
committed
0.5.70 - added media type filtering per content source, improved performance monitor
1 parent 5024c8c commit 4a6a85a

File tree

10 files changed

+548
-97
lines changed

10 files changed

+548
-97
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,4 @@ run.sh
142142
config/config.json.backup
143143
config/secret_key
144144
config
145+
auto_blacklist

database/wanted_items.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
from metadata.metadata import get_tmdb_id_and_media_type
88
import random
99
import os
10+
from config_manager import load_config
1011

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

15-
1616
conn = get_db_connection()
1717
try:
1818
items_added = 0
@@ -25,10 +25,15 @@ def add_wanted_items(media_items_batch: List[Dict[str, Any]], versions_input):
2525
'existing_episode_tmdb': 0,
2626
'missing_ids': 0,
2727
'blacklisted': 0,
28-
'already_watched': 0
28+
'already_watched': 0,
29+
'media_type_mismatch': 0
2930
}
3031
airtime_cache = {}
3132

33+
# Load config to get content source settings
34+
config = load_config()
35+
content_sources = config.get('Content Sources', {})
36+
3237
# Check if we should skip watched content
3338
do_not_add_watched = get_setting('Debug','do_not_add_plex_watch_history_items_to_queue', False)
3439
watch_history_conn = None
@@ -56,7 +61,24 @@ def add_wanted_items(media_items_batch: List[Dict[str, Any]], versions_input):
5661
episode_imdb_keys = set()
5762
episode_tmdb_keys = set()
5863

64+
filtered_media_items_batch = []
5965
for item in media_items_batch:
66+
# Get content source settings
67+
content_source = item.get('content_source')
68+
if content_source and content_source in content_sources:
69+
source_config = content_sources[content_source]
70+
source_media_type = source_config.get('media_type', 'All')
71+
72+
# Skip if content source is not Collected and media type doesn't match
73+
if not content_source.startswith('Collected_'):
74+
item_type = 'episode' if 'season_number' in item and 'episode_number' in item else 'movie'
75+
if source_media_type != 'All':
76+
if (source_media_type == 'Movies' and item_type != 'movie') or \
77+
(source_media_type == 'Shows' and item_type != 'episode'):
78+
skip_stats['media_type_mismatch'] += 1
79+
items_skipped += 1
80+
continue
81+
6082
imdb_id = item.get('imdb_id')
6183
tmdb_id = item.get('tmdb_id')
6284

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

110+
filtered_media_items_batch.append(item)
111+
112+
media_items_batch = filtered_media_items_batch
113+
88114
existing_movies = set()
89115
batch_size = 450
90116

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

317345
if skip_report:
318346
logging.info("Wanted items processing complete. Skip summary:\n" + "\n".join(skip_report))

main.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,40 @@ def main():
852852
logging.info("Resetting Torbox debrid provider to Real-Debrid")
853853
set_setting('Debrid Provider', 'provider', 'RealDebrid')
854854

855+
# Add migration for media_type setting
856+
from config_manager import load_config, save_config
857+
config = load_config()
858+
if 'Content Sources' in config:
859+
updated = False
860+
for source_id, source_config in config['Content Sources'].items():
861+
# Skip the Collected source as it doesn't use media_type
862+
if source_id.startswith('Collected_'):
863+
continue
864+
865+
# Check if media_type is missing
866+
if 'media_type' not in source_config:
867+
# Create new ordered dict with desired key order
868+
new_config = {}
869+
# Copy existing keys except display_name
870+
for key in source_config:
871+
if key != 'display_name':
872+
new_config[key] = source_config[key]
873+
# Add media_type before display_name
874+
new_config['media_type'] = 'All'
875+
# Add display_name last if it exists
876+
if 'display_name' in source_config:
877+
new_config['display_name'] = source_config['display_name']
878+
879+
# Replace the old config with the new ordered one
880+
config['Content Sources'][source_id] = new_config
881+
logging.info(f"Adding default media_type 'All' to content source {source_id}")
882+
updated = True
883+
884+
# Save the updated config if changes were made
885+
if updated:
886+
save_config(config)
887+
logging.info("Successfully migrated content sources to include media_type setting")
888+
855889
# Get battery port from environment variable
856890
battery_port = int(os.environ.get('CLI_DEBRID_BATTERY_PORT', '5001'))
857891

performance_monitor.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ def _log_basic_metrics(self):
164164
memory_info = process.memory_info()
165165
virtual_memory = psutil.virtual_memory()
166166

167+
# Calculate actual memory usage percentage without cache
168+
total_memory = virtual_memory.total
169+
used_memory = virtual_memory.total - virtual_memory.available
170+
memory_percent = (used_memory / total_memory) * 100
171+
167172
memory_delta_str = ""
168173
if self._last_memory_info is not None:
169174
try:
@@ -174,15 +179,16 @@ def _log_basic_metrics(self):
174179

175180
self._last_memory_info = memory_info.rss
176181

177-
# Create entry
182+
# Create entry with UTC timestamp
183+
current_time = datetime.utcnow()
178184
entry = {
179-
"timestamp": datetime.now().isoformat(),
185+
"timestamp": current_time.isoformat(),
180186
"type": "basic_metrics",
181187
"metrics": {
182188
"cpu_percent": cpu_percent,
183189
"memory_rss": memory_info.rss / 1024 / 1024, # Convert to MB
184190
"memory_vms": memory_info.vms / 1024 / 1024, # Convert to MB
185-
"system_memory_used": virtual_memory.percent,
191+
"system_memory_used": memory_percent,
186192
"swap_used": psutil.swap_memory().used / 1024 / 1024, # Convert to MB
187193
"cpu_user_time": cpu_times.user,
188194
"cpu_system_time": cpu_times.system
@@ -213,7 +219,7 @@ def _log_basic_metrics(self):
213219
memory_info.rss / 1024 / 1024,
214220
memory_delta_str,
215221
memory_info.vms / 1024 / 1024,
216-
virtual_memory.percent,
222+
memory_percent,
217223
psutil.swap_memory().used / 1024 / 1024
218224
))
219225

routes/performance_routes.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def get_performance_log():
2121
limit = request.args.get('limit', type=int, default=1000)
2222
entry_type = request.args.get('type', type=str) # Optional type filter
2323
metric_type = request.args.get('metric', type=str) # Optional metric filter
24-
cutoff_time = datetime.now() - timedelta(hours=hours)
24+
cutoff_time = datetime.utcnow() - timedelta(hours=hours)
2525

2626
try:
2727
entries = []
@@ -42,15 +42,19 @@ def get_performance_log():
4242
if metric_type and ('metrics' not in entry or metric_type not in entry['metrics']):
4343
continue
4444

45-
entry_time = datetime.fromisoformat(entry['timestamp'])
45+
entry_time = datetime.fromisoformat(entry['timestamp'].replace('Z', '+00:00'))
4646
if entry_time >= cutoff_time:
4747
entries.append(entry)
48-
if len(entries) >= limit:
49-
break
5048
except (json.JSONDecodeError, KeyError, ValueError) as e:
5149
continue
5250

53-
# Sort entries by timestamp
51+
# Sort entries by timestamp in descending order (newest first)
52+
entries.sort(key=lambda x: x.get('timestamp', ''), reverse=True)
53+
54+
# Take only the most recent entries up to the limit
55+
entries = entries[:limit]
56+
57+
# Re-sort in ascending order for display
5458
entries.sort(key=lambda x: x.get('timestamp', ''))
5559

5660
# Get system info for metadata

settings_schema.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@
440440
"enabled": {"type": "boolean", "default": False},
441441
"urls": {"type": "string", "default": ""},
442442
"versions": {"type": "dict", "default": {"Default": True}},
443+
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
443444
"display_name": {"type": "string", "default": "MDBList"}
444445
},
445446
"Collected": {
@@ -450,48 +451,56 @@
450451
"Trakt Watchlist": {
451452
"enabled": {"type": "boolean", "default": False},
452453
"versions": {"type": "dict", "default": {"Default": True}},
454+
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
453455
"display_name": {"type": "string", "default": "Trakt Watchlist"}
454456
},
455457
"Trakt Lists": {
456458
"enabled": {"type": "boolean", "default": False},
457459
"trakt_lists": {"type": "string", "default": ""},
458460
"versions": {"type": "dict", "default": {"Default": True}},
461+
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
459462
"display_name": {"type": "string", "default": "Trakt Lists"}
460463
},
461464
"Trakt Collection": {
462465
"enabled": {"type": "boolean", "default": False},
463466
"versions": {"type": "dict", "default": {"Default": True}},
467+
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
464468
"display_name": {"type": "string", "default": "Trakt Collection"}
465469
},
466470
"Overseerr": {
467471
"enabled": {"type": "boolean", "default": False},
468472
"url": {"type": "string", "default": "", "validate": "url"},
469473
"api_key": {"type": "string", "default": "", "sensitive": True},
470474
"versions": {"type": "dict", "default": {"Default": True}},
475+
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
471476
"display_name": {"type": "string", "default": "Overseerr"}
472477
},
473478
"My Plex Watchlist": {
474479
"enabled": {"type": "boolean", "default": False},
475480
"versions": {"type": "dict", "default": {"Default": True}},
481+
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
476482
"display_name": {"type": "string", "default": "My Plex Watchlist"}
477483
},
478484
"Other Plex Watchlist": {
479485
"enabled": {"type": "boolean", "default": False},
480486
"username": {"type": "string", "default": ""},
481487
"token": {"type": "string", "default": "", "sensitive": True},
482488
"versions": {"type": "dict", "default": {"Default": True}},
489+
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
483490
"display_name": {"type": "string", "default": "Other Plex Watchlist"}
484491
},
485492
"My Plex RSS Watchlist": {
486493
"enabled": {"type": "boolean", "default": False},
487494
"url": {"type": "string", "default": "", "validate": "url"},
488495
"versions": {"type": "dict", "default": {"Default": True}},
496+
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
489497
"display_name": {"type": "string", "default": "My Plex RSS Watchlist"}
490498
},
491499
"My Friends Plex RSS Watchlist": {
492500
"enabled": {"type": "boolean", "default": False},
493501
"url": {"type": "string", "default": "", "validate": "url"},
494502
"versions": {"type": "dict", "default": {"Default": True}},
503+
"media_type": {"type": "string", "default": "All", "choices": ["All", "Movies", "Shows"]},
495504
"display_name": {"type": "string", "default": "My Friends Plex RSS Watchlist"}
496505
}
497506
}

0 commit comments

Comments
 (0)