mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-01-23 02:35:14 +00:00
Merge pull request #518 from Dispatcharr/Assign-tvg-id-from-epg
This commit is contained in:
commit
18dc73cbcb
5 changed files with 237 additions and 2 deletions
|
|
@ -555,6 +555,37 @@ class ChannelViewSet(viewsets.ModelViewSet):
|
|||
"channel_count": len(channel_ids)
|
||||
})
|
||||
|
||||
@action(detail=False, methods=["post"], url_path="set-tvg-ids-from-epg")
|
||||
def set_tvg_ids_from_epg(self, request):
|
||||
"""
|
||||
Trigger a Celery task to set channel TVG-IDs from EPG data
|
||||
"""
|
||||
from .tasks import set_channels_tvg_ids_from_epg
|
||||
|
||||
data = request.data
|
||||
channel_ids = data.get("channel_ids", [])
|
||||
|
||||
if not channel_ids:
|
||||
return Response(
|
||||
{"error": "channel_ids is required"},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
|
||||
if not isinstance(channel_ids, list):
|
||||
return Response(
|
||||
{"error": "channel_ids must be a list"},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
|
||||
# Start the Celery task
|
||||
task = set_channels_tvg_ids_from_epg.delay(channel_ids)
|
||||
|
||||
return Response({
|
||||
"message": f"Started EPG TVG-ID setting task for {len(channel_ids)} channels",
|
||||
"task_id": task.id,
|
||||
"channel_count": len(channel_ids)
|
||||
})
|
||||
|
||||
@action(detail=False, methods=["get"], url_path="ids")
|
||||
def get_ids(self, request, *args, **kwargs):
|
||||
# Get the filtered queryset
|
||||
|
|
|
|||
|
|
@ -2711,3 +2711,98 @@ def set_channels_logos_from_epg(self, channel_ids):
|
|||
'error': str(e)
|
||||
})
|
||||
raise
|
||||
|
||||
|
||||
@shared_task(bind=True)
|
||||
def set_channels_tvg_ids_from_epg(self, channel_ids):
|
||||
"""
|
||||
Celery task to set channel TVG-IDs from EPG data for multiple channels
|
||||
"""
|
||||
from core.utils import send_websocket_update
|
||||
|
||||
task_id = self.request.id
|
||||
total_channels = len(channel_ids)
|
||||
updated_count = 0
|
||||
errors = []
|
||||
|
||||
try:
|
||||
logger.info(f"Starting EPG TVG-ID setting task for {total_channels} channels")
|
||||
|
||||
# Send initial progress
|
||||
send_websocket_update('updates', 'update', {
|
||||
'type': 'epg_tvg_id_setting_progress',
|
||||
'task_id': task_id,
|
||||
'progress': 0,
|
||||
'total': total_channels,
|
||||
'status': 'running',
|
||||
'message': 'Starting EPG TVG-ID setting...'
|
||||
})
|
||||
|
||||
batch_size = 100
|
||||
for i in range(0, total_channels, batch_size):
|
||||
batch_ids = channel_ids[i:i + batch_size]
|
||||
batch_updates = []
|
||||
|
||||
# Get channels and their EPG data
|
||||
channels = Channel.objects.filter(id__in=batch_ids).select_related('epg_data')
|
||||
|
||||
for channel in channels:
|
||||
try:
|
||||
if channel.epg_data and channel.epg_data.tvg_id:
|
||||
if channel.tvg_id != channel.epg_data.tvg_id:
|
||||
channel.tvg_id = channel.epg_data.tvg_id
|
||||
batch_updates.append(channel)
|
||||
updated_count += 1
|
||||
except Exception as e:
|
||||
errors.append(f"Channel {channel.id}: {str(e)}")
|
||||
logger.error(f"Error processing channel {channel.id}: {e}")
|
||||
|
||||
# Bulk update the batch
|
||||
if batch_updates:
|
||||
Channel.objects.bulk_update(batch_updates, ['tvg_id'])
|
||||
|
||||
# Send progress update
|
||||
progress = min(i + batch_size, total_channels)
|
||||
send_websocket_update('updates', 'update', {
|
||||
'type': 'epg_tvg_id_setting_progress',
|
||||
'task_id': task_id,
|
||||
'progress': progress,
|
||||
'total': total_channels,
|
||||
'status': 'running',
|
||||
'message': f'Updated {updated_count} channel TVG-IDs...',
|
||||
'updated_count': updated_count
|
||||
})
|
||||
|
||||
# Send completion notification
|
||||
send_websocket_update('updates', 'update', {
|
||||
'type': 'epg_tvg_id_setting_progress',
|
||||
'task_id': task_id,
|
||||
'progress': total_channels,
|
||||
'total': total_channels,
|
||||
'status': 'completed',
|
||||
'message': f'Successfully updated {updated_count} channel TVG-IDs from EPG data',
|
||||
'updated_count': updated_count,
|
||||
'error_count': len(errors),
|
||||
'errors': errors
|
||||
})
|
||||
|
||||
logger.info(f"EPG TVG-ID setting task completed. Updated {updated_count} channels")
|
||||
return {
|
||||
'status': 'completed',
|
||||
'updated_count': updated_count,
|
||||
'error_count': len(errors),
|
||||
'errors': errors
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"EPG TVG-ID setting task failed: {e}")
|
||||
send_websocket_update('updates', 'update', {
|
||||
'type': 'epg_tvg_id_setting_progress',
|
||||
'task_id': task_id,
|
||||
'progress': 0,
|
||||
'total': total_channels,
|
||||
'status': 'failed',
|
||||
'message': f'Task failed: {str(e)}',
|
||||
'error': str(e)
|
||||
})
|
||||
raise
|
||||
|
|
|
|||
|
|
@ -562,6 +562,29 @@ export default class API {
|
|||
}
|
||||
}
|
||||
|
||||
static async setChannelTvgIdsFromEpg(channelIds) {
|
||||
try {
|
||||
const response = await request(
|
||||
`${host}/api/channels/channels/set-tvg-ids-from-epg/`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: { channel_ids: channelIds },
|
||||
}
|
||||
);
|
||||
|
||||
notifications.show({
|
||||
title: 'Task Started',
|
||||
message: response.message,
|
||||
color: 'blue',
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (e) {
|
||||
errorNotification('Failed to start EPG TVG-ID setting task', e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
static async assignChannelNumbers(channelIds, startingNum = 1) {
|
||||
try {
|
||||
const response = await request(`${host}/api/channels/channels/assign/`, {
|
||||
|
|
|
|||
|
|
@ -263,6 +263,34 @@ const ChannelForm = ({ channel = null, isOpen, onClose }) => {
|
|||
}
|
||||
};
|
||||
|
||||
const handleSetTvgIdFromEpg = () => {
|
||||
const epgDataId = formik.values.epg_data_id;
|
||||
if (!epgDataId) {
|
||||
notifications.show({
|
||||
title: 'No EPG Selected',
|
||||
message: 'Please select an EPG source first.',
|
||||
color: 'orange',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const tvg = tvgsById[epgDataId];
|
||||
if (tvg && tvg.tvg_id) {
|
||||
formik.setFieldValue('tvg_id', tvg.tvg_id);
|
||||
notifications.show({
|
||||
title: 'Success',
|
||||
message: `TVG-ID set to "${tvg.tvg_id}"`,
|
||||
color: 'green',
|
||||
});
|
||||
} else {
|
||||
notifications.show({
|
||||
title: 'No TVG-ID Available',
|
||||
message: 'No TVG-ID found in the selected EPG data.',
|
||||
color: 'orange',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
name: '',
|
||||
|
|
@ -823,7 +851,23 @@ const ChannelForm = ({ channel = null, isOpen, onClose }) => {
|
|||
<TextInput
|
||||
id="tvg_id"
|
||||
name="tvg_id"
|
||||
label="TVG-ID"
|
||||
label={
|
||||
<Group gap="xs">
|
||||
<span>TVG-ID</span>
|
||||
{formik.values.epg_data_id && (
|
||||
<Button
|
||||
size="xs"
|
||||
variant="transparent"
|
||||
onClick={handleSetTvgIdFromEpg}
|
||||
title="Set TVG-ID from EPG data"
|
||||
p={0}
|
||||
h="auto"
|
||||
>
|
||||
Use EPG TVG-ID
|
||||
</Button>
|
||||
)}
|
||||
</Group>
|
||||
}
|
||||
value={formik.values.tvg_id}
|
||||
onChange={formik.handleChange}
|
||||
error={formik.errors.tvg_id ? formik.touched.tvg_id : ''}
|
||||
|
|
|
|||
|
|
@ -202,6 +202,40 @@ const ChannelBatchForm = ({ channelIds, isOpen, onClose }) => {
|
|||
}
|
||||
};
|
||||
|
||||
const handleSetTvgIdsFromEpg = async () => {
|
||||
if (!channelIds || channelIds.length === 0) {
|
||||
notifications.show({
|
||||
title: 'No Channels Selected',
|
||||
message: 'No channels to update.',
|
||||
color: 'orange',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Start the backend task
|
||||
await API.setChannelTvgIdsFromEpg(channelIds);
|
||||
|
||||
// The task will send WebSocket updates for progress
|
||||
// Just show that it started successfully
|
||||
notifications.show({
|
||||
title: 'Task Started',
|
||||
message: `Started setting TVG-IDs from EPG for ${channelIds.length} channels. Progress will be shown in notifications.`,
|
||||
color: 'blue',
|
||||
});
|
||||
|
||||
// Close the modal since the task is now running in background
|
||||
onClose();
|
||||
} catch (error) {
|
||||
console.error('Failed to start EPG TVG-ID setting task:', error);
|
||||
notifications.show({
|
||||
title: 'Error',
|
||||
message: 'Failed to start EPG TVG-ID setting task.',
|
||||
color: 'red',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// useEffect(() => {
|
||||
// // const sameStreamProfile = channels.every(
|
||||
// // (channel) => channel.stream_profile_id == channels[0].stream_profile_id
|
||||
|
|
@ -317,9 +351,17 @@ const ChannelBatchForm = ({ channelIds, isOpen, onClose }) => {
|
|||
>
|
||||
Set Logos from EPG
|
||||
</Button>
|
||||
<Button
|
||||
size="xs"
|
||||
variant="light"
|
||||
onClick={handleSetTvgIdsFromEpg}
|
||||
style={{ flex: 1 }}
|
||||
>
|
||||
Set TVG-IDs from EPG
|
||||
</Button>
|
||||
</Group>
|
||||
<Text size="xs" c="dimmed" mt="xs">
|
||||
Updates channel names and logos based on their assigned EPG
|
||||
Updates channel names, logos, and TVG-IDs based on their assigned EPG
|
||||
data
|
||||
</Text>
|
||||
</Paper>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue