Bug Fix: Auto Channel Sync Force EPG Source feature not properly forcing "No EPG" assignment - When selecting "Force EPG Source" > "No EPG (Disabled)", channels were still being auto-matched to EPG data instead of forcing dummy/no EPG. Now correctly sets force_dummy_epg flag to prevent unwanted EPG assignment. (Fixes #788)

This commit is contained in:
SergeantPanda 2026-01-02 15:22:25 -06:00
parent 058de26bdf
commit 3f46f28a70
2 changed files with 90 additions and 44 deletions

View file

@ -43,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Auto Channel Sync Force EPG Source feature not properly forcing "No EPG" assignment - When selecting "Force EPG Source" > "No EPG (Disabled)", channels were still being auto-matched to EPG data instead of forcing dummy/no EPG. Now correctly sets `force_dummy_epg` flag to prevent unwanted EPG assignment. (Fixes #788)
- VOD episode processing now properly handles season and episode numbers from APIs that return string values instead of integers, with comprehensive error logging to track data quality issues - Thanks [@patchy8736](https://github.com/patchy8736) (Fixes #770)
- VOD episode-to-stream relations are now validated to ensure episodes have been saved to the database before creating relations, preventing integrity errors when bulk_create operations encounter conflicts - Thanks [@patchy8736](https://github.com/patchy8736)
- VOD category filtering now correctly handles category names containing pipe "|" characters (e.g., "PL | BAJKI", "EN | MOVIES") by using `rsplit()` to split from the right instead of the left, ensuring the category type is correctly extracted as the last segment - Thanks [@Vitekant](https://github.com/Vitekant)

View file

@ -369,7 +369,8 @@ const LiveGroupFilter = ({
if (
group.custom_properties?.custom_epg_id !==
undefined ||
group.custom_properties?.force_dummy_epg
group.custom_properties?.force_dummy_epg ||
group.custom_properties?.force_epg_selected
) {
selectedValues.push('force_epg');
}
@ -432,23 +433,20 @@ const LiveGroupFilter = ({
// Handle force_epg
if (selectedOptions.includes('force_epg')) {
// Migrate from old force_dummy_epg if present
// Set default to force_dummy_epg if no EPG settings exist yet
if (
newCustomProps.force_dummy_epg &&
newCustomProps.custom_epg_id === undefined
newCustomProps.custom_epg_id ===
undefined &&
!newCustomProps.force_dummy_epg
) {
// Migrate: force_dummy_epg=true becomes custom_epg_id=null
newCustomProps.custom_epg_id = null;
delete newCustomProps.force_dummy_epg;
} else if (
newCustomProps.custom_epg_id === undefined
) {
// New configuration: initialize with null (no EPG/default dummy)
newCustomProps.custom_epg_id = null;
// Default to "No EPG (Disabled)"
newCustomProps.force_dummy_epg = true;
}
} else {
// Only remove custom_epg_id when deselected
// Remove all EPG settings when deselected
delete newCustomProps.custom_epg_id;
delete newCustomProps.force_dummy_epg;
delete newCustomProps.force_epg_selected;
}
// Handle group_override
@ -1124,7 +1122,8 @@ const LiveGroupFilter = ({
{/* Show EPG selector when force_epg is selected */}
{(group.custom_properties?.custom_epg_id !== undefined ||
group.custom_properties?.force_dummy_epg) && (
group.custom_properties?.force_dummy_epg ||
group.custom_properties?.force_epg_selected) && (
<Tooltip
label="Force a specific EPG source for all auto-synced channels in this group. For dummy EPGs, all channels will share the same EPG data. For regular EPG sources (XMLTV, Schedules Direct), channels will be matched by their tvg_id within that source. Select 'No EPG' to disable EPG assignment."
withArrow
@ -1133,44 +1132,90 @@ const LiveGroupFilter = ({
label="EPG Source"
placeholder="No EPG (Disabled)"
value={(() => {
// Handle migration from force_dummy_epg
// Show custom EPG if set
if (
group.custom_properties?.custom_epg_id !==
undefined
undefined &&
group.custom_properties?.custom_epg_id !== null
) {
// Convert to string, use '0' for null/no EPG
return group.custom_properties.custom_epg_id ===
null
? '0'
: group.custom_properties.custom_epg_id.toString();
} else if (
group.custom_properties?.force_dummy_epg
) {
// Show "No EPG" for old force_dummy_epg configs
return group.custom_properties.custom_epg_id.toString();
}
// Show "No EPG" if force_dummy_epg is set
if (group.custom_properties?.force_dummy_epg) {
return '0';
}
return '0';
// Otherwise show empty/placeholder
return null;
})()}
onChange={(value) => {
// Convert back: '0' means no EPG (null)
const newValue =
value === '0' ? null : parseInt(value);
setGroupStates(
groupStates.map((state) => {
if (
state.channel_group === group.channel_group
) {
return {
...state,
custom_properties: {
if (value === '0') {
// "No EPG (Disabled)" selected - use force_dummy_epg
setGroupStates(
groupStates.map((state) => {
if (
state.channel_group ===
group.channel_group
) {
const newProps = {
...state.custom_properties,
custom_epg_id: newValue,
},
};
}
return state;
})
);
};
delete newProps.custom_epg_id;
delete newProps.force_epg_selected;
newProps.force_dummy_epg = true;
return {
...state,
custom_properties: newProps,
};
}
return state;
})
);
} else if (value) {
// Specific EPG source selected
const epgId = parseInt(value);
setGroupStates(
groupStates.map((state) => {
if (
state.channel_group ===
group.channel_group
) {
const newProps = {
...state.custom_properties,
};
newProps.custom_epg_id = epgId;
delete newProps.force_dummy_epg;
delete newProps.force_epg_selected;
return {
...state,
custom_properties: newProps,
};
}
return state;
})
);
} else {
// Cleared - remove all EPG settings
setGroupStates(
groupStates.map((state) => {
if (
state.channel_group ===
group.channel_group
) {
const newProps = {
...state.custom_properties,
};
delete newProps.custom_epg_id;
delete newProps.force_dummy_epg;
delete newProps.force_epg_selected;
return {
...state,
custom_properties: newProps,
};
}
return state;
})
);
}
}}
data={[
{ value: '0', label: 'No EPG (Disabled)' },