mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-20 16:51:10 +00:00
Add option to force dummy epg.
This commit is contained in:
parent
6afd5a38c9
commit
a5f7a88ba0
3 changed files with 96 additions and 19 deletions
|
|
@ -302,13 +302,34 @@ class ChannelGroupM3UAccountSerializer(serializers.ModelSerializer):
|
|||
enabled = serializers.BooleanField()
|
||||
auto_channel_sync = serializers.BooleanField(default=False)
|
||||
auto_sync_channel_start = serializers.FloatField(allow_null=True, required=False)
|
||||
custom_properties = serializers.JSONField(required=False)
|
||||
|
||||
class Meta:
|
||||
model = ChannelGroupM3UAccount
|
||||
fields = ["id", "channel_group", "enabled", "auto_channel_sync", "auto_sync_channel_start"]
|
||||
fields = ["id", "channel_group", "enabled", "auto_channel_sync", "auto_sync_channel_start", "custom_properties"]
|
||||
|
||||
# Optionally, if you only need the id of the ChannelGroup, you can customize it like this:
|
||||
# channel_group = serializers.PrimaryKeyRelatedField(queryset=ChannelGroup.objects.all())
|
||||
def to_representation(self, instance):
|
||||
ret = super().to_representation(instance)
|
||||
# Ensure custom_properties is always a dict or None
|
||||
val = ret.get("custom_properties")
|
||||
if isinstance(val, str):
|
||||
import json
|
||||
try:
|
||||
ret["custom_properties"] = json.loads(val)
|
||||
except Exception:
|
||||
ret["custom_properties"] = None
|
||||
return ret
|
||||
|
||||
def to_internal_value(self, data):
|
||||
# Accept both dict and JSON string for custom_properties
|
||||
val = data.get("custom_properties")
|
||||
if isinstance(val, str):
|
||||
import json
|
||||
try:
|
||||
data["custom_properties"] = json.loads(val)
|
||||
except Exception:
|
||||
pass
|
||||
return super().to_internal_value(data)
|
||||
|
||||
|
||||
class RecordingSerializer(serializers.ModelSerializer):
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import os
|
|||
from rest_framework.decorators import action
|
||||
from django.conf import settings
|
||||
from .tasks import refresh_m3u_groups
|
||||
import json
|
||||
|
||||
from .models import M3UAccount, M3UFilter, ServerGroup, M3UAccountProfile
|
||||
from core.models import UserAgent
|
||||
|
|
@ -154,6 +155,7 @@ class M3UAccountViewSet(viewsets.ModelViewSet):
|
|||
enabled = setting.get("enabled", True)
|
||||
auto_sync = setting.get("auto_channel_sync", False)
|
||||
sync_start = setting.get("auto_sync_channel_start")
|
||||
custom_properties = setting.get("custom_properties", {})
|
||||
|
||||
if group_id:
|
||||
ChannelGroupM3UAccount.objects.update_or_create(
|
||||
|
|
@ -163,6 +165,11 @@ class M3UAccountViewSet(viewsets.ModelViewSet):
|
|||
"enabled": enabled,
|
||||
"auto_channel_sync": auto_sync,
|
||||
"auto_sync_channel_start": sync_start,
|
||||
"custom_properties": (
|
||||
custom_properties
|
||||
if isinstance(custom_properties, str)
|
||||
else json.dumps(custom_properties)
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -43,12 +43,26 @@ const M3UGroupFilter = ({ playlist = null, isOpen, onClose }) => {
|
|||
}
|
||||
|
||||
setGroupStates(
|
||||
playlist.channel_groups.map((group) => ({
|
||||
...group,
|
||||
name: channelGroups[group.channel_group].name,
|
||||
auto_channel_sync: group.auto_channel_sync || false,
|
||||
auto_sync_channel_start: group.auto_sync_channel_start || 1.0,
|
||||
}))
|
||||
playlist.channel_groups.map((group) => {
|
||||
// Parse custom_properties if present
|
||||
let customProps = {};
|
||||
if (group.custom_properties) {
|
||||
try {
|
||||
customProps = typeof group.custom_properties === 'string'
|
||||
? JSON.parse(group.custom_properties)
|
||||
: group.custom_properties;
|
||||
} catch (e) {
|
||||
customProps = {};
|
||||
}
|
||||
}
|
||||
return {
|
||||
...group,
|
||||
name: channelGroups[group.channel_group].name,
|
||||
auto_channel_sync: group.auto_channel_sync || false,
|
||||
auto_sync_channel_start: group.auto_sync_channel_start || 1.0,
|
||||
custom_properties: customProps,
|
||||
};
|
||||
})
|
||||
);
|
||||
}, [playlist, channelGroups]);
|
||||
|
||||
|
|
@ -79,11 +93,36 @@ const M3UGroupFilter = ({ playlist = null, isOpen, onClose }) => {
|
|||
);
|
||||
};
|
||||
|
||||
// Toggle force_dummy_epg in custom_properties for a group
|
||||
const toggleForceDummyEPG = (id) => {
|
||||
setGroupStates(
|
||||
groupStates.map((state) => {
|
||||
if (state.channel_group == id) {
|
||||
const customProps = { ...(state.custom_properties || {}) };
|
||||
customProps.force_dummy_epg = !customProps.force_dummy_epg;
|
||||
return {
|
||||
...state,
|
||||
custom_properties: customProps,
|
||||
};
|
||||
}
|
||||
return state;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
// Prepare groupStates for API: custom_properties must be stringified
|
||||
const payload = groupStates.map((state) => ({
|
||||
...state,
|
||||
custom_properties: state.custom_properties
|
||||
? JSON.stringify(state.custom_properties)
|
||||
: undefined,
|
||||
}));
|
||||
|
||||
// Update group settings via API endpoint
|
||||
await API.updateM3UGroupSettings(playlist.id, groupStates);
|
||||
await API.updateM3UGroupSettings(playlist.id, payload);
|
||||
|
||||
// Show notification about the refresh process
|
||||
notifications.show({
|
||||
|
|
@ -224,15 +263,25 @@ const M3UGroupFilter = ({ playlist = null, isOpen, onClose }) => {
|
|||
/>
|
||||
|
||||
{group.auto_channel_sync && group.enabled && (
|
||||
<NumberInput
|
||||
label="Start Channel #"
|
||||
value={group.auto_sync_channel_start}
|
||||
onChange={(value) => updateChannelStart(group.channel_group, value)}
|
||||
min={1}
|
||||
step={1}
|
||||
size="xs"
|
||||
precision={1}
|
||||
/>
|
||||
<>
|
||||
<NumberInput
|
||||
label="Start Channel #"
|
||||
value={group.auto_sync_channel_start}
|
||||
onChange={(value) => updateChannelStart(group.channel_group, value)}
|
||||
min={1}
|
||||
step={1}
|
||||
size="xs"
|
||||
precision={1}
|
||||
/>
|
||||
|
||||
{/* Force Dummy EPG Checkbox */}
|
||||
<Checkbox
|
||||
label="Force Dummy EPG"
|
||||
checked={!!(group.custom_properties && group.custom_properties.force_dummy_epg)}
|
||||
onChange={() => toggleForceDummyEPG(group.channel_group)}
|
||||
size="xs"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
</Group>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue