mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-01-23 10:45:27 +00:00
Add priority for providers so VOD's can be auto selected based on the priority.
This commit is contained in:
parent
fa2b3fbe3e
commit
24f876d09f
8 changed files with 72 additions and 14 deletions
|
|
@ -18,6 +18,7 @@ class M3UAccountAdmin(admin.ModelAdmin):
|
|||
"server_url",
|
||||
"server_group",
|
||||
"max_streams",
|
||||
"priority",
|
||||
"is_active",
|
||||
"user_agent_display",
|
||||
"uploaded_file_link",
|
||||
|
|
|
|||
18
apps/m3u/migrations/0016_m3uaccount_priority.py
Normal file
18
apps/m3u/migrations/0016_m3uaccount_priority.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 5.2.4 on 2025-08-20 22:35
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('m3u', '0015_alter_m3ufilter_options_m3ufilter_custom_properties'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='m3uaccount',
|
||||
name='priority',
|
||||
field=models.PositiveIntegerField(default=0, help_text='Priority for VOD provider selection (higher numbers = higher priority). Used when multiple providers offer the same content.'),
|
||||
),
|
||||
]
|
||||
|
|
@ -94,6 +94,10 @@ class M3UAccount(models.Model):
|
|||
default=7,
|
||||
help_text="Number of days after which a stream will be removed if not seen in the M3U source.",
|
||||
)
|
||||
priority = models.PositiveIntegerField(
|
||||
default=0,
|
||||
help_text="Priority for VOD provider selection (higher numbers = higher priority). Used when multiple providers offer the same content.",
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from core.utils import validate_flexible_url
|
||||
from rest_framework import serializers
|
||||
from rest_framework import serializers, status
|
||||
from rest_framework.response import Response
|
||||
from .models import M3UAccount, M3UFilter, ServerGroup, M3UAccountProfile
|
||||
from core.models import UserAgent
|
||||
|
|
@ -113,6 +113,7 @@ class M3UAccountSerializer(serializers.ModelSerializer):
|
|||
"username",
|
||||
"password",
|
||||
"stale_stream_days",
|
||||
"priority",
|
||||
"status",
|
||||
"last_message",
|
||||
"enable_vod",
|
||||
|
|
|
|||
|
|
@ -1077,10 +1077,10 @@ def xc_get_vod_streams(request, user, category_id=None):
|
|||
movies = Movie.objects.filter(**filters).select_related('logo').distinct()
|
||||
|
||||
for movie in movies:
|
||||
# Get the first relation for this movie (for metadata like container_extension)
|
||||
# Get the highest priority relation for this movie (for metadata like container_extension)
|
||||
relation = movie.m3u_relations.filter(
|
||||
m3u_account__is_active=True
|
||||
).first()
|
||||
).select_related('m3u_account').order_by('-m3u_account__priority', 'id').first()
|
||||
|
||||
if relation:
|
||||
relation_custom = relation.custom_properties or {}
|
||||
|
|
@ -1282,9 +1282,11 @@ def xc_get_series_info(request, user, series_id):
|
|||
if season_num not in seasons:
|
||||
seasons[season_num] = []
|
||||
|
||||
# Try to get the first related M3UEpisodeRelation for this episode (for video/audio/bitrate)
|
||||
# Try to get the highest priority related M3UEpisodeRelation for this episode (for video/audio/bitrate)
|
||||
from apps.vod.models import M3UEpisodeRelation
|
||||
first_relation = M3UEpisodeRelation.objects.filter(episode=episode).order_by('id').first()
|
||||
first_relation = M3UEpisodeRelation.objects.filter(
|
||||
episode=episode
|
||||
).select_related('m3u_account').order_by('-m3u_account__priority', 'id').first()
|
||||
video = audio = bitrate = None
|
||||
if first_relation and first_relation.custom_properties:
|
||||
info = first_relation.custom_properties.get('info')
|
||||
|
|
|
|||
|
|
@ -345,16 +345,28 @@ class VODStreamView(View):
|
|||
content_obj = get_object_or_404(Movie, uuid=content_id)
|
||||
logger.info(f"[CONTENT-FOUND] Movie: {content_obj.name} (ID: {content_obj.id})")
|
||||
|
||||
# Get the first active relation
|
||||
relation = content_obj.m3u_relations.filter(m3u_account__is_active=True).first()
|
||||
# Get the highest priority active relation
|
||||
relation = content_obj.m3u_relations.filter(
|
||||
m3u_account__is_active=True
|
||||
).select_related('m3u_account').order_by('-m3u_account__priority', 'id').first()
|
||||
|
||||
if relation:
|
||||
logger.info(f"[PROVIDER-SELECTED] Using provider: {relation.m3u_account.name} (priority: {relation.m3u_account.priority})")
|
||||
|
||||
return content_obj, relation
|
||||
|
||||
elif content_type == 'episode':
|
||||
content_obj = get_object_or_404(Episode, uuid=content_id)
|
||||
logger.info(f"[CONTENT-FOUND] Episode: {content_obj.name} (ID: {content_obj.id}, Series: {content_obj.series.name})")
|
||||
|
||||
# Get the first active relation
|
||||
relation = content_obj.m3u_relations.filter(m3u_account__is_active=True).first()
|
||||
# Get the highest priority active relation
|
||||
relation = content_obj.m3u_relations.filter(
|
||||
m3u_account__is_active=True
|
||||
).select_related('m3u_account').order_by('-m3u_account__priority', 'id').first()
|
||||
|
||||
if relation:
|
||||
logger.info(f"[PROVIDER-SELECTED] Using provider: {relation.m3u_account.name} (priority: {relation.m3u_account.priority})")
|
||||
|
||||
return content_obj, relation
|
||||
|
||||
elif content_type == 'series':
|
||||
|
|
@ -367,7 +379,14 @@ class VODStreamView(View):
|
|||
return None, None
|
||||
|
||||
logger.info(f"[CONTENT-FOUND] First episode: {episode.name} (ID: {episode.id})")
|
||||
relation = episode.m3u_relations.filter(m3u_account__is_active=True).first()
|
||||
# Get the highest priority active relation
|
||||
relation = episode.m3u_relations.filter(
|
||||
m3u_account__is_active=True
|
||||
).select_related('m3u_account').order_by('-m3u_account__priority', 'id').first()
|
||||
|
||||
if relation:
|
||||
logger.info(f"[PROVIDER-SELECTED] Using provider: {relation.m3u_account.name} (priority: {relation.m3u_account.priority})")
|
||||
|
||||
return episode, relation
|
||||
else:
|
||||
logger.error(f"[CONTENT-ERROR] Invalid content type: {content_type}")
|
||||
|
|
|
|||
|
|
@ -108,11 +108,11 @@ class MovieViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
"""Get detailed movie information from the original provider, throttled to 24h."""
|
||||
movie = self.get_object()
|
||||
|
||||
# Get the first active relation
|
||||
# Get the highest priority active relation
|
||||
relation = M3UMovieRelation.objects.filter(
|
||||
movie=movie,
|
||||
m3u_account__is_active=True
|
||||
).select_related('m3u_account').first()
|
||||
).select_related('m3u_account').order_by('-m3u_account__priority', 'id').first()
|
||||
|
||||
if not relation:
|
||||
return Response(
|
||||
|
|
@ -314,11 +314,11 @@ class SeriesViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
series = self.get_object()
|
||||
logger.debug(f"Retrieved series: {series.name} (ID: {series.id})")
|
||||
|
||||
# Get the first active relation
|
||||
# Get the highest priority active relation
|
||||
relation = M3USeriesRelation.objects.filter(
|
||||
series=series,
|
||||
m3u_account__is_active=True
|
||||
).select_related('m3u_account').first()
|
||||
).select_related('m3u_account').order_by('-m3u_account__priority', 'id').first()
|
||||
|
||||
if not relation:
|
||||
return Response(
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ const M3U = ({
|
|||
username: '',
|
||||
password: '',
|
||||
stale_stream_days: 7,
|
||||
priority: 0,
|
||||
enable_vod: false,
|
||||
},
|
||||
|
||||
|
|
@ -93,6 +94,9 @@ const M3U = ({
|
|||
m3uAccount.stale_stream_days !== null
|
||||
? m3uAccount.stale_stream_days
|
||||
: 7,
|
||||
priority: m3uAccount.priority !== undefined && m3uAccount.priority !== null
|
||||
? m3uAccount.priority
|
||||
: 0,
|
||||
enable_vod: m3uAccount.enable_vod || false,
|
||||
});
|
||||
|
||||
|
|
@ -366,6 +370,15 @@ const M3U = ({
|
|||
{...form.getInputProps('stale_stream_days')}
|
||||
/>
|
||||
|
||||
<NumberInput
|
||||
min={0}
|
||||
max={999}
|
||||
label="VOD Priority"
|
||||
description="Priority for VOD provider selection (higher numbers = higher priority). Used when multiple providers offer the same content."
|
||||
{...form.getInputProps('priority')}
|
||||
key={form.key('priority')}
|
||||
/>
|
||||
|
||||
<Checkbox
|
||||
label="Is Active"
|
||||
description="Enable or disable this M3U account"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue