Enhancement: Allow overriding of default stream profile for auto channel sync.

This commit is contained in:
SergeantPanda 2025-08-31 08:49:45 -05:00
parent b17bc21159
commit 3aa68c1a36
2 changed files with 109 additions and 0 deletions

View file

@ -1404,6 +1404,7 @@ def sync_auto_channels(account_id, scan_start_time=None):
channel_profile_ids = None
channel_sort_order = None
channel_sort_reverse = False
stream_profile_id = None
if group_relation.custom_properties:
try:
group_custom_props = json.loads(group_relation.custom_properties)
@ -1419,6 +1420,7 @@ def sync_auto_channels(account_id, scan_start_time=None):
channel_sort_reverse = group_custom_props.get(
"channel_sort_reverse", False
)
stream_profile_id = group_custom_props.get("stream_profile_id")
except Exception:
force_dummy_epg = False
override_group_id = None
@ -1428,6 +1430,7 @@ def sync_auto_channels(account_id, scan_start_time=None):
channel_profile_ids = None
channel_sort_order = None
channel_sort_reverse = False
stream_profile_id = None
# Determine which group to use for created channels
target_group = channel_group
@ -1560,6 +1563,21 @@ def sync_auto_channels(account_id, scan_start_time=None):
else:
profiles_to_assign = list(ChannelProfile.objects.all())
# Get stream profile to assign if specified
from core.models import StreamProfile
stream_profile_to_assign = None
if stream_profile_id:
try:
stream_profile_to_assign = StreamProfile.objects.get(id=int(stream_profile_id))
logger.info(
f"Will assign stream profile '{stream_profile_to_assign.name}' to auto-synced streams in group '{channel_group.name}'"
)
except (StreamProfile.DoesNotExist, ValueError, TypeError):
logger.warning(
f"Stream profile with ID {stream_profile_id} not found for group '{channel_group.name}', streams will use default profile"
)
stream_profile_to_assign = None
# Process each current stream
current_channel_number = start_number
@ -1694,6 +1712,11 @@ def sync_auto_channels(account_id, scan_start_time=None):
existing_channel.epg_data = current_epg_data
channel_updated = True
# Handle stream profile updates for the channel
if stream_profile_to_assign and existing_channel.stream_profile != stream_profile_to_assign:
existing_channel.stream_profile = stream_profile_to_assign
channel_updated = True
if channel_updated:
existing_channel.save()
channels_updated += 1
@ -1797,6 +1820,10 @@ def sync_auto_channels(account_id, scan_start_time=None):
channel.logo = logo
channel.save(update_fields=["logo"])
# Handle stream profile assignment
if stream_profile_to_assign:
channel.stream_profile = stream_profile_to_assign
channel.save(update_fields=['stream_profile'])
channels_created += 1
logger.debug(
f"Created auto channel: {channel.channel_number} - {channel.name}"

View file

@ -19,6 +19,7 @@ import {
} from '@mantine/core';
import { Info } from 'lucide-react';
import useChannelsStore from '../../store/channels';
import useStreamProfilesStore from '../../store/streamProfiles';
import { CircleCheck, CircleX } from 'lucide-react';
// Custom item component for MultiSelect with tooltip
@ -35,8 +36,17 @@ const OptionWithTooltip = forwardRef(
const LiveGroupFilter = ({ playlist, groupStates, setGroupStates }) => {
const channelGroups = useChannelsStore((s) => s.channelGroups);
const profiles = useChannelsStore((s) => s.profiles);
const streamProfiles = useStreamProfilesStore((s) => s.profiles);
const fetchStreamProfiles = useStreamProfilesStore((s) => s.fetchProfiles);
const [groupFilter, setGroupFilter] = useState('');
// Fetch stream profiles when component mounts
useEffect(() => {
if (streamProfiles.length === 0) {
fetchStreamProfiles();
}
}, [streamProfiles.length, fetchStreamProfiles]);
useEffect(() => {
if (Object.keys(channelGroups).length === 0) {
return;
@ -279,6 +289,12 @@ const LiveGroupFilter = ({ playlist, groupStates, setGroupStates }) => {
description:
'Specify the order in which channels are created (name, tvg_id, updated_at)',
},
{
value: 'stream_profile_assignment',
label: 'Stream Profile Assignment',
description:
'Assign a specific stream profile to all channels in this group during auto sync',
},
]}
itemComponent={OptionWithTooltip}
value={(() => {
@ -318,6 +334,12 @@ const LiveGroupFilter = ({ playlist, groupStates, setGroupStates }) => {
) {
selectedValues.push('channel_sort_order');
}
if (
group.custom_properties?.stream_profile_id !==
undefined
) {
selectedValues.push('stream_profile_assignment');
}
return selectedValues;
})()}
onChange={(values) => {
@ -421,6 +443,22 @@ const LiveGroupFilter = ({ playlist, groupStates, setGroupStates }) => {
delete newCustomProps.channel_sort_reverse; // Remove reverse when sort is removed
}
// Handle stream_profile_assignment
if (
selectedOptions.includes(
'stream_profile_assignment'
)
) {
if (
newCustomProps.stream_profile_id ===
undefined
) {
newCustomProps.stream_profile_id = null;
}
} else {
delete newCustomProps.stream_profile_id;
}
return {
...state,
custom_properties: newCustomProps,
@ -601,6 +639,50 @@ const LiveGroupFilter = ({ playlist, groupStates, setGroupStates }) => {
</Tooltip>
)}
{/* Show stream profile select only if stream_profile_assignment is selected */}
{group.custom_properties?.stream_profile_id !==
undefined && (
<Tooltip
label="Select a stream profile to assign to all streams in this group during auto sync."
withArrow
>
<Select
label="Stream Profile"
placeholder="Choose stream profile..."
value={
group.custom_properties?.stream_profile_id?.toString() ||
null
}
onChange={(value) => {
const newValue = value ? parseInt(value) : null;
setGroupStates(
groupStates.map((state) => {
if (
state.channel_group === group.channel_group
) {
return {
...state,
custom_properties: {
...state.custom_properties,
stream_profile_id: newValue,
},
};
}
return state;
})
);
}}
data={streamProfiles.map((profile) => ({
value: profile.id.toString(),
label: profile.name,
}))}
clearable
searchable
size="xs"
/>
</Tooltip>
)}
{/* Show regex fields only if name_regex is selected */}
{(group.custom_properties?.name_regex_pattern !==
undefined ||