Merge pull request #20 from PiratesIRC/claude/add-stream-group-filter-01JSc4xu35T9sUJNLXXWkTCJ
Add group filter field for streams
This commit is contained in:
@@ -158,6 +158,22 @@ class Plugin:
|
|||||||
"placeholder": "Sports, News, Entertainment",
|
"placeholder": "Sports, News, Entertainment",
|
||||||
"help_text": "Specific channel groups to process, or leave empty for all groups.",
|
"help_text": "Specific channel groups to process, or leave empty for all groups.",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "selected_stream_groups",
|
||||||
|
"label": "📺 Stream Groups (comma-separated)",
|
||||||
|
"type": "string",
|
||||||
|
"default": "",
|
||||||
|
"placeholder": "TVE, Cable, Satellite",
|
||||||
|
"help_text": "Specific stream groups to use when matching, or leave empty for all stream groups. Multiple groups can be specified separated by commas.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "selected_m3us",
|
||||||
|
"label": "📡 M3U Sources (comma-separated)",
|
||||||
|
"type": "string",
|
||||||
|
"default": "",
|
||||||
|
"placeholder": "IPTV Provider 1, Local M3U, Sports",
|
||||||
|
"help_text": "Specific M3U sources to use when matching, or leave empty for all M3U sources. Multiple M3U sources can be specified separated by commas.",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "ignore_tags",
|
"id": "ignore_tags",
|
||||||
"label": "🏷️ Ignore Tags (comma-separated)",
|
"label": "🏷️ Ignore Tags (comma-separated)",
|
||||||
@@ -1975,6 +1991,10 @@ class Plugin:
|
|||||||
profile_names_str = profile_names_str.strip() if profile_names_str else ""
|
profile_names_str = profile_names_str.strip() if profile_names_str else ""
|
||||||
selected_groups_str = settings.get("selected_groups") or ""
|
selected_groups_str = settings.get("selected_groups") or ""
|
||||||
selected_groups_str = selected_groups_str.strip() if selected_groups_str else ""
|
selected_groups_str = selected_groups_str.strip() if selected_groups_str else ""
|
||||||
|
selected_stream_groups_str = settings.get("selected_stream_groups") or ""
|
||||||
|
selected_stream_groups_str = selected_stream_groups_str.strip() if selected_stream_groups_str else ""
|
||||||
|
selected_m3us_str = settings.get("selected_m3us") or ""
|
||||||
|
selected_m3us_str = selected_m3us_str.strip() if selected_m3us_str else ""
|
||||||
ignore_tags_str = settings.get("ignore_tags") or ""
|
ignore_tags_str = settings.get("ignore_tags") or ""
|
||||||
ignore_tags_str = ignore_tags_str.strip() if ignore_tags_str else ""
|
ignore_tags_str = ignore_tags_str.strip() if ignore_tags_str else ""
|
||||||
visible_channel_limit_str = settings.get("visible_channel_limit", "1")
|
visible_channel_limit_str = settings.get("visible_channel_limit", "1")
|
||||||
@@ -2049,6 +2069,82 @@ class Plugin:
|
|||||||
|
|
||||||
group_name_to_id = {g['name']: g['id'] for g in all_groups if 'name' in g and 'id' in g}
|
group_name_to_id = {g['name']: g['id'] for g in all_groups if 'name' in g and 'id' in g}
|
||||||
|
|
||||||
|
# Fetch stream groups with rate limiting
|
||||||
|
self._send_progress_update("load_process_channels", 'running', 35, 'Fetching stream groups...', context)
|
||||||
|
all_stream_groups = []
|
||||||
|
page = 1
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
api_stream_groups = self._get_api_data(f"/api/channels/stream-groups/?page={page}", token, settings, logger, limiter=limiter)
|
||||||
|
except Exception as e:
|
||||||
|
# If we get an error (e.g., 404 for non-existent page), we've reached the end
|
||||||
|
if page > 1:
|
||||||
|
logger.debug(f"[Stream-Mapparr] No more stream group pages available (attempted page {page})")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# If error on first page, stream groups might not be available in this API version
|
||||||
|
logger.warning(f"[Stream-Mapparr] Could not fetch stream groups (API may not support this endpoint): {e}")
|
||||||
|
break
|
||||||
|
|
||||||
|
if isinstance(api_stream_groups, dict) and 'results' in api_stream_groups:
|
||||||
|
results = api_stream_groups['results']
|
||||||
|
if not results:
|
||||||
|
logger.debug("[Stream-Mapparr] Reached last page of stream groups (empty results)")
|
||||||
|
break
|
||||||
|
all_stream_groups.extend(results)
|
||||||
|
if not api_stream_groups.get('next'):
|
||||||
|
break
|
||||||
|
page += 1
|
||||||
|
elif isinstance(api_stream_groups, list):
|
||||||
|
if not api_stream_groups:
|
||||||
|
logger.debug("[Stream-Mapparr] Reached last page of stream groups (empty results)")
|
||||||
|
break
|
||||||
|
all_stream_groups.extend(api_stream_groups)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
stream_group_name_to_id = {g['name']: g['id'] for g in all_stream_groups if 'name' in g and 'id' in g}
|
||||||
|
logger.info(f"[Stream-Mapparr] Found {len(all_stream_groups)} stream groups")
|
||||||
|
|
||||||
|
# Fetch M3U sources with rate limiting
|
||||||
|
self._send_progress_update("load_process_channels", 'running', 37, 'Fetching M3U sources...', context)
|
||||||
|
all_m3us = []
|
||||||
|
page = 1
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
api_m3us = self._get_api_data(f"/api/channels/m3us/?page={page}", token, settings, logger, limiter=limiter)
|
||||||
|
except Exception as e:
|
||||||
|
# If we get an error (e.g., 404 for non-existent page), we've reached the end
|
||||||
|
if page > 1:
|
||||||
|
logger.debug(f"[Stream-Mapparr] No more M3U pages available (attempted page {page})")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# If error on first page, M3Us might not be available in this API version
|
||||||
|
logger.warning(f"[Stream-Mapparr] Could not fetch M3U sources (API may not support this endpoint): {e}")
|
||||||
|
break
|
||||||
|
|
||||||
|
if isinstance(api_m3us, dict) and 'results' in api_m3us:
|
||||||
|
results = api_m3us['results']
|
||||||
|
if not results:
|
||||||
|
logger.debug("[Stream-Mapparr] Reached last page of M3Us (empty results)")
|
||||||
|
break
|
||||||
|
all_m3us.extend(results)
|
||||||
|
if not api_m3us.get('next'):
|
||||||
|
break
|
||||||
|
page += 1
|
||||||
|
elif isinstance(api_m3us, list):
|
||||||
|
if not api_m3us:
|
||||||
|
logger.debug("[Stream-Mapparr] Reached last page of M3Us (empty results)")
|
||||||
|
break
|
||||||
|
all_m3us.extend(api_m3us)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
m3u_name_to_id = {m['name']: m['id'] for m in all_m3us if 'name' in m and 'id' in m}
|
||||||
|
logger.info(f"[Stream-Mapparr] Found {len(all_m3us)} M3U sources")
|
||||||
|
|
||||||
# Fetch channels with rate limiting
|
# Fetch channels with rate limiting
|
||||||
self._send_progress_update("load_process_channels", 'running', 40, 'Fetching channels...', context)
|
self._send_progress_update("load_process_channels", 'running', 40, 'Fetching channels...', context)
|
||||||
all_channels = self._get_api_data("/api/channels/channels/", token, settings, logger, limiter=limiter)
|
all_channels = self._get_api_data("/api/channels/channels/", token, settings, logger, limiter=limiter)
|
||||||
@@ -2139,6 +2235,42 @@ class Plugin:
|
|||||||
logger.warning("[Stream-Mapparr] Unexpected streams response format")
|
logger.warning("[Stream-Mapparr] Unexpected streams response format")
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# Filter streams by selected stream groups
|
||||||
|
if selected_stream_groups_str:
|
||||||
|
selected_stream_groups = [g.strip() for g in selected_stream_groups_str.split(',') if g.strip()]
|
||||||
|
valid_stream_group_ids = [stream_group_name_to_id[name] for name in selected_stream_groups if name in stream_group_name_to_id]
|
||||||
|
if not valid_stream_group_ids:
|
||||||
|
logger.warning("[Stream-Mapparr] None of the specified stream groups were found. Using all streams.")
|
||||||
|
selected_stream_groups = []
|
||||||
|
stream_group_filter_info = " (all stream groups - specified groups not found)"
|
||||||
|
else:
|
||||||
|
# Filter streams by stream_group_id
|
||||||
|
filtered_streams = [s for s in all_streams_data if s.get('stream_group_id') in valid_stream_group_ids]
|
||||||
|
logger.info(f"[Stream-Mapparr] Filtered streams from {len(all_streams_data)} to {len(filtered_streams)} based on stream groups: {', '.join(selected_stream_groups)}")
|
||||||
|
all_streams_data = filtered_streams
|
||||||
|
stream_group_filter_info = f" in stream groups: {', '.join(selected_stream_groups)}"
|
||||||
|
else:
|
||||||
|
selected_stream_groups = []
|
||||||
|
stream_group_filter_info = " (all stream groups)"
|
||||||
|
|
||||||
|
# Filter streams by selected M3U sources
|
||||||
|
if selected_m3us_str:
|
||||||
|
selected_m3us = [m.strip() for m in selected_m3us_str.split(',') if m.strip()]
|
||||||
|
valid_m3u_ids = [m3u_name_to_id[name] for name in selected_m3us if name in m3u_name_to_id]
|
||||||
|
if not valid_m3u_ids:
|
||||||
|
logger.warning("[Stream-Mapparr] None of the specified M3U sources were found. Using all streams.")
|
||||||
|
selected_m3us = []
|
||||||
|
m3u_filter_info = " (all M3U sources - specified M3Us not found)"
|
||||||
|
else:
|
||||||
|
# Filter streams by m3u_id
|
||||||
|
filtered_streams = [s for s in all_streams_data if s.get('m3u_id') in valid_m3u_ids]
|
||||||
|
logger.info(f"[Stream-Mapparr] Filtered streams from {len(all_streams_data)} to {len(filtered_streams)} based on M3U sources: {', '.join(selected_m3us)}")
|
||||||
|
all_streams_data = filtered_streams
|
||||||
|
m3u_filter_info = f" in M3U sources: {', '.join(selected_m3us)}"
|
||||||
|
else:
|
||||||
|
selected_m3us = []
|
||||||
|
m3u_filter_info = " (all M3U sources)"
|
||||||
|
|
||||||
self.loaded_channels = channels_to_process
|
self.loaded_channels = channels_to_process
|
||||||
self.loaded_streams = all_streams_data
|
self.loaded_streams = all_streams_data
|
||||||
|
|
||||||
@@ -2149,6 +2281,8 @@ class Plugin:
|
|||||||
"profile_id": profile_id,
|
"profile_id": profile_id,
|
||||||
"profile_ids": profile_ids,
|
"profile_ids": profile_ids,
|
||||||
"selected_groups": selected_groups,
|
"selected_groups": selected_groups,
|
||||||
|
"selected_stream_groups": selected_stream_groups,
|
||||||
|
"selected_m3us": selected_m3us,
|
||||||
"ignore_tags": ignore_tags,
|
"ignore_tags": ignore_tags,
|
||||||
"visible_channel_limit": visible_channel_limit,
|
"visible_channel_limit": visible_channel_limit,
|
||||||
"ignore_quality": ignore_quality,
|
"ignore_quality": ignore_quality,
|
||||||
@@ -2182,6 +2316,8 @@ class Plugin:
|
|||||||
|
|
||||||
profile_name = processed_data.get('profile_name', 'N/A')
|
profile_name = processed_data.get('profile_name', 'N/A')
|
||||||
selected_groups = processed_data.get('selected_groups', [])
|
selected_groups = processed_data.get('selected_groups', [])
|
||||||
|
selected_stream_groups = processed_data.get('selected_stream_groups', [])
|
||||||
|
selected_m3us = processed_data.get('selected_m3us', [])
|
||||||
current_threshold = settings.get('fuzzy_match_threshold', 85)
|
current_threshold = settings.get('fuzzy_match_threshold', 85)
|
||||||
|
|
||||||
# Build header with all settings except login credentials
|
# Build header with all settings except login credentials
|
||||||
@@ -2191,7 +2327,9 @@ class Plugin:
|
|||||||
"#",
|
"#",
|
||||||
"# === Profile & Group Settings ===",
|
"# === Profile & Group Settings ===",
|
||||||
f"# Profile Name(s): {profile_name}",
|
f"# Profile Name(s): {profile_name}",
|
||||||
f"# Selected Groups: {', '.join(selected_groups) if selected_groups else '(all groups)'}",
|
f"# Selected Channel Groups: {', '.join(selected_groups) if selected_groups else '(all groups)'}",
|
||||||
|
f"# Selected Stream Groups: {', '.join(selected_stream_groups) if selected_stream_groups else '(all stream groups)'}",
|
||||||
|
f"# Selected M3U Sources: {', '.join(selected_m3us) if selected_m3us else '(all M3U sources)'}",
|
||||||
"#",
|
"#",
|
||||||
"# === Matching Settings ===",
|
"# === Matching Settings ===",
|
||||||
f"# Fuzzy Match Threshold: {current_threshold}",
|
f"# Fuzzy Match Threshold: {current_threshold}",
|
||||||
|
|||||||
Reference in New Issue
Block a user