mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-18 00:55:50 +00:00
Enhancement: For auto channel sync, allow using provider number, fixed start number or next available. (Closes #956, #433)
This commit is contained in:
parent
a05f89ab85
commit
2c9f6d7360
2 changed files with 177 additions and 26 deletions
|
|
@ -1665,6 +1665,8 @@ def sync_auto_channels(account_id, scan_start_time=None):
|
|||
stream_profile_id = None
|
||||
custom_logo_id = None
|
||||
custom_epg_id = None # New option: select specific EPG source (takes priority over force_dummy_epg)
|
||||
channel_numbering_mode = "fixed" # Default mode
|
||||
channel_numbering_fallback = 1 # Default fallback for provider mode
|
||||
if group_relation.custom_properties:
|
||||
group_custom_props = group_relation.custom_properties
|
||||
force_dummy_epg = group_custom_props.get("force_dummy_epg", False)
|
||||
|
|
@ -1682,6 +1684,8 @@ def sync_auto_channels(account_id, scan_start_time=None):
|
|||
)
|
||||
stream_profile_id = group_custom_props.get("stream_profile_id")
|
||||
custom_logo_id = group_custom_props.get("custom_logo_id")
|
||||
channel_numbering_mode = group_custom_props.get("channel_numbering_mode", "fixed")
|
||||
channel_numbering_fallback = group_custom_props.get("channel_numbering_fallback", 1)
|
||||
|
||||
# Determine which group to use for created channels
|
||||
target_group = channel_group
|
||||
|
|
@ -1697,7 +1701,7 @@ def sync_auto_channels(account_id, scan_start_time=None):
|
|||
)
|
||||
|
||||
logger.info(
|
||||
f"Processing auto sync for group: {channel_group.name} (start: {start_number})"
|
||||
f"Processing auto sync for group: {channel_group.name} (mode: {channel_numbering_mode}, start: {start_number})"
|
||||
)
|
||||
|
||||
# Get all current streams in this group for this M3U account, filter out stale streams
|
||||
|
|
@ -1848,10 +1852,31 @@ def sync_auto_channels(account_id, scan_start_time=None):
|
|||
if stream.id in existing_channel_map:
|
||||
channel = existing_channel_map[stream.id]
|
||||
|
||||
# Find next available number starting from temp_channel_number
|
||||
target_number = temp_channel_number
|
||||
while target_number in used_numbers:
|
||||
target_number += 1
|
||||
# Determine target number based on numbering mode
|
||||
if channel_numbering_mode == "provider":
|
||||
# Use provider number if available, otherwise use fallback with next available logic
|
||||
if stream.stream_chno is not None:
|
||||
target_number = stream.stream_chno
|
||||
# If provider number is already used, find next available
|
||||
if target_number in used_numbers:
|
||||
target_number = channel_numbering_fallback
|
||||
while target_number in used_numbers:
|
||||
target_number += 1
|
||||
else:
|
||||
# No provider number, use fallback and find next available
|
||||
target_number = channel_numbering_fallback
|
||||
while target_number in used_numbers:
|
||||
target_number += 1
|
||||
elif channel_numbering_mode == "next_available":
|
||||
# Find next available starting from 1
|
||||
target_number = 1
|
||||
while target_number in used_numbers:
|
||||
target_number += 1
|
||||
else: # fixed mode (default)
|
||||
# Find next available number starting from temp_channel_number
|
||||
target_number = temp_channel_number
|
||||
while target_number in used_numbers:
|
||||
target_number += 1
|
||||
|
||||
# Add this number to used_numbers so we don't reuse it in this batch
|
||||
used_numbers.add(target_number)
|
||||
|
|
@ -1863,9 +1888,11 @@ def sync_auto_channels(account_id, scan_start_time=None):
|
|||
f"Will renumber channel '{channel.name}' to {target_number}"
|
||||
)
|
||||
|
||||
temp_channel_number += 1.0
|
||||
if temp_channel_number % 1 != 0: # Has decimal
|
||||
temp_channel_number = int(temp_channel_number) + 1.0
|
||||
# Only increment temp_channel_number in fixed mode
|
||||
if channel_numbering_mode == "fixed":
|
||||
temp_channel_number += 1.0
|
||||
if temp_channel_number % 1 != 0: # Has decimal
|
||||
temp_channel_number = int(temp_channel_number) + 1.0
|
||||
|
||||
# Bulk update channel numbers if any need renumbering
|
||||
if channels_to_renumber:
|
||||
|
|
@ -2060,10 +2087,31 @@ def sync_auto_channels(account_id, scan_start_time=None):
|
|||
|
||||
else:
|
||||
# Create new channel
|
||||
# Find next available channel number
|
||||
target_number = current_channel_number
|
||||
while target_number in used_numbers:
|
||||
target_number += 1
|
||||
# Determine channel number based on numbering mode
|
||||
if channel_numbering_mode == "provider":
|
||||
# Use provider number if available, otherwise use fallback with next available logic
|
||||
if stream.stream_chno is not None:
|
||||
target_number = stream.stream_chno
|
||||
# If provider number is already used, find next available from fallback
|
||||
if target_number in used_numbers:
|
||||
target_number = channel_numbering_fallback
|
||||
while target_number in used_numbers:
|
||||
target_number += 1
|
||||
else:
|
||||
# No provider number, use fallback and find next available
|
||||
target_number = channel_numbering_fallback
|
||||
while target_number in used_numbers:
|
||||
target_number += 1
|
||||
elif channel_numbering_mode == "next_available":
|
||||
# Find next available starting from 1
|
||||
target_number = 1
|
||||
while target_number in used_numbers:
|
||||
target_number += 1
|
||||
else: # fixed mode (default)
|
||||
# Find next available channel number starting from current_channel_number
|
||||
target_number = current_channel_number
|
||||
while target_number in used_numbers:
|
||||
target_number += 1
|
||||
|
||||
# Add this number to used_numbers
|
||||
used_numbers.add(target_number)
|
||||
|
|
@ -2190,10 +2238,11 @@ def sync_auto_channels(account_id, scan_start_time=None):
|
|||
f"Created auto channel: {channel.channel_number} - {channel.name}"
|
||||
)
|
||||
|
||||
# Increment channel number for next iteration
|
||||
current_channel_number += 1.0
|
||||
if current_channel_number % 1 != 0: # Has decimal
|
||||
current_channel_number = int(current_channel_number) + 1.0
|
||||
# Increment channel number for next iteration (only in fixed mode)
|
||||
if channel_numbering_mode == "fixed":
|
||||
current_channel_number += 1.0
|
||||
if current_channel_number % 1 != 0: # Has decimal
|
||||
current_channel_number = int(current_channel_number) + 1.0
|
||||
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
|
|
|
|||
|
|
@ -314,17 +314,119 @@ const LiveGroupFilter = ({
|
|||
|
||||
{group.auto_channel_sync && group.enabled && (
|
||||
<>
|
||||
<NumberInput
|
||||
label="Start Channel #"
|
||||
value={group.auto_sync_channel_start}
|
||||
onChange={(value) =>
|
||||
updateChannelStart(group.channel_group, value)
|
||||
<Tooltip
|
||||
label={
|
||||
<div>
|
||||
<div>
|
||||
<strong>Fixed:</strong> Start at a specific number
|
||||
and increment
|
||||
</div>
|
||||
<div>
|
||||
<strong>Provider:</strong> Use channel numbers
|
||||
from the M3U source
|
||||
</div>
|
||||
<div>
|
||||
<strong>Next Available:</strong> Auto-assign
|
||||
starting from 1, skipping used numbers
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
min={1}
|
||||
step={1}
|
||||
size="xs"
|
||||
precision={1}
|
||||
/>
|
||||
withArrow
|
||||
multiline
|
||||
w={280}
|
||||
openDelay={500}
|
||||
>
|
||||
<Select
|
||||
label="Channel Numbering Mode"
|
||||
placeholder="Select mode..."
|
||||
value={
|
||||
group.custom_properties?.channel_numbering_mode ||
|
||||
'fixed'
|
||||
}
|
||||
onChange={(value) => {
|
||||
setGroupStates(
|
||||
groupStates.map((state) => {
|
||||
if (
|
||||
state.channel_group === group.channel_group
|
||||
) {
|
||||
return {
|
||||
...state,
|
||||
custom_properties: {
|
||||
...state.custom_properties,
|
||||
channel_numbering_mode: value || 'fixed',
|
||||
},
|
||||
};
|
||||
}
|
||||
return state;
|
||||
})
|
||||
);
|
||||
}}
|
||||
data={[
|
||||
{
|
||||
value: 'fixed',
|
||||
label: 'Fixed Start Number',
|
||||
},
|
||||
{
|
||||
value: 'provider',
|
||||
label: 'Use Provider Number',
|
||||
},
|
||||
{
|
||||
value: 'next_available',
|
||||
label: 'Next Available',
|
||||
},
|
||||
]}
|
||||
size="xs"
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
{(!group.custom_properties?.channel_numbering_mode ||
|
||||
group.custom_properties?.channel_numbering_mode ===
|
||||
'fixed') && (
|
||||
<NumberInput
|
||||
label="Start Channel #"
|
||||
value={group.auto_sync_channel_start}
|
||||
onChange={(value) =>
|
||||
updateChannelStart(group.channel_group, value)
|
||||
}
|
||||
min={1}
|
||||
step={1}
|
||||
size="xs"
|
||||
precision={0}
|
||||
/>
|
||||
)}
|
||||
|
||||
{group.custom_properties?.channel_numbering_mode ===
|
||||
'provider' && (
|
||||
<NumberInput
|
||||
label="Fallback Channel # (if provider # missing)"
|
||||
value={
|
||||
group.custom_properties
|
||||
?.channel_numbering_fallback || 1
|
||||
}
|
||||
onChange={(value) => {
|
||||
setGroupStates(
|
||||
groupStates.map((state) => {
|
||||
if (
|
||||
state.channel_group === group.channel_group
|
||||
) {
|
||||
return {
|
||||
...state,
|
||||
custom_properties: {
|
||||
...state.custom_properties,
|
||||
channel_numbering_fallback: value || 1,
|
||||
},
|
||||
};
|
||||
}
|
||||
return state;
|
||||
})
|
||||
);
|
||||
}}
|
||||
min={1}
|
||||
step={1}
|
||||
size="xs"
|
||||
precision={0}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Auto Channel Sync Options Multi-Select */}
|
||||
<MultiSelect
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue