mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-08-04 15:52:58 +00:00
first run at m3u profiles
This commit is contained in:
parent
eec6e06b1d
commit
53836fdac3
5 changed files with 115 additions and 8 deletions
|
|
@ -1,6 +1,6 @@
|
|||
from django.urls import path, include
|
||||
from rest_framework.routers import DefaultRouter
|
||||
from .api_views import M3UAccountViewSet, M3UFilterViewSet, ServerGroupViewSet, RefreshM3UAPIView, RefreshSingleM3UAPIView, UserAgentViewSet
|
||||
from .api_views import M3UAccountViewSet, M3UFilterViewSet, ServerGroupViewSet, RefreshM3UAPIView, RefreshSingleM3UAPIView, UserAgentViewSet, M3UAccountProfileViewSet
|
||||
|
||||
app_name = 'm3u'
|
||||
|
||||
|
|
@ -8,10 +8,13 @@ router = DefaultRouter()
|
|||
router.register(r'accounts', M3UAccountViewSet, basename='m3u-account')
|
||||
router.register(r'filters', M3UFilterViewSet, basename='m3u-filter')
|
||||
router.register(r'server-groups', ServerGroupViewSet, basename='server-group')
|
||||
router.register(r'profiles', M3UAccountViewSet, basename='m3u-account-profiles')
|
||||
|
||||
urlpatterns = [
|
||||
path('refresh/', RefreshM3UAPIView.as_view(), name='m3u_refresh'),
|
||||
path('refresh/<int:account_id>/', RefreshSingleM3UAPIView.as_view(), name='m3u_refresh_single'),
|
||||
path('accounts/<int:m3u_account_id>/profiles/', M3UAccountProfileViewSet.as_view({'get': 'list', 'post': 'create'})),
|
||||
path('accounts/<int:m3u_account_id>/profiles/<int:pk>/', M3UAccountProfileViewSet.as_view({'put': 'update', 'delete': 'destroy'})),
|
||||
]
|
||||
|
||||
urlpatterns += router.urls
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from django.http import JsonResponse
|
|||
from django.core.cache import cache
|
||||
|
||||
# Import all models, including UserAgent.
|
||||
from .models import M3UAccount, M3UFilter, ServerGroup
|
||||
from .models import M3UAccount, M3UFilter, ServerGroup, M3UAccountProfile
|
||||
from core.models import UserAgent
|
||||
from core.serializers import UserAgentSerializer
|
||||
# Import all serializers, including the UserAgentSerializer.
|
||||
|
|
@ -17,6 +17,7 @@ from .serializers import (
|
|||
M3UAccountSerializer,
|
||||
M3UFilterSerializer,
|
||||
ServerGroupSerializer,
|
||||
M3UAccountProfileSerializer,
|
||||
)
|
||||
|
||||
from .tasks import refresh_single_m3u_account, refresh_m3u_accounts
|
||||
|
|
@ -68,3 +69,16 @@ class UserAgentViewSet(viewsets.ModelViewSet):
|
|||
serializer_class = UserAgentSerializer
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
class M3UAccountProfileViewSet(viewsets.ModelViewSet):
|
||||
queryset = M3UAccountProfile.objects.all()
|
||||
serializer_class = M3UAccountProfileSerializer
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_queryset(self):
|
||||
account_id = self.kwargs['account_id']
|
||||
return M3UAccountProfile.objects.filter(account_id=account_id)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
account_id = self.kwargs['account_id']
|
||||
account = M3UAccount.objects.get(id=account_id)
|
||||
serializer.save(account=account)
|
||||
|
|
|
|||
62
apps/m3u/migrations/0001_initial.py
Normal file
62
apps/m3u/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# Generated by Django 5.1.6 on 2025-02-28 01:36
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('core', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ServerGroup',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(help_text='Unique name for this server group.', max_length=100, unique=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='M3UAccount',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(help_text='Unique name for this M3U account', max_length=255, unique=True)),
|
||||
('server_url', models.URLField(blank=True, help_text='The base URL of the M3U server (optional if a file is uploaded)', null=True)),
|
||||
('uploaded_file', models.FileField(blank=True, null=True, upload_to='m3u_uploads/')),
|
||||
('max_streams', models.PositiveIntegerField(default=0, help_text='Maximum number of concurrent streams (0 for unlimited)')),
|
||||
('is_active', models.BooleanField(default=True, help_text='Set to false to deactivate this M3U account')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, help_text='Time when this account was created')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, help_text='Time when this account was last updated')),
|
||||
('user_agent', models.ForeignKey(blank=True, help_text='The User-Agent associated with this M3U account.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='m3u_accounts', to='core.useragent')),
|
||||
('server_group', models.ForeignKey(blank=True, help_text='The server group this M3U account belongs to', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='m3u_accounts', to='m3u.servergroup')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='M3UFilter',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('filter_type', models.CharField(choices=[('group', 'Group Title'), ('name', 'Stream Name')], default='group', help_text='Filter based on either group title or stream name.', max_length=50)),
|
||||
('regex_pattern', models.CharField(help_text='A regex pattern to match streams or groups.', max_length=200)),
|
||||
('exclude', models.BooleanField(default=True, help_text='If True, matching items are excluded; if False, only matches are included.')),
|
||||
('m3u_account', models.ForeignKey(help_text='The M3U account this filter is applied to.', on_delete=django.db.models.deletion.CASCADE, related_name='filters', to='m3u.m3uaccount')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='M3UAccountProfile',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(help_text='Name for the M3U account profile', max_length=255)),
|
||||
('max_streams', models.PositiveIntegerField(default=0, help_text='Maximum number of concurrent streams (0 for unlimited)')),
|
||||
('search_pattern', models.CharField(max_length=255)),
|
||||
('replace_pattern', models.CharField(max_length=255)),
|
||||
('m3u_account_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='m3u.m3uaccount')),
|
||||
],
|
||||
options={
|
||||
'constraints': [models.UniqueConstraint(fields=('m3u_account_id', 'name'), name='unique_account_name')],
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
@ -134,7 +134,7 @@ class M3UFilter(models.Model):
|
|||
# If no include filters exist, assume all non-excluded streams are valid
|
||||
if not any(not f.exclude for f in filters):
|
||||
return streams.exclude(id__in=[s.id for s in excluded_streams])
|
||||
|
||||
|
||||
return streams.filter(id__in=[s.id for s in included_streams])
|
||||
|
||||
|
||||
|
|
@ -148,3 +148,27 @@ class ServerGroup(models.Model):
|
|||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class M3UAccountProfile(models.Model):
|
||||
name = models.CharField(
|
||||
max_length=255,
|
||||
help_text="Name for the M3U account profile"
|
||||
)
|
||||
m3u_account_id = models.ForeignKey(M3UAccount,
|
||||
on_delete=models.CASCADE
|
||||
)
|
||||
max_streams = models.PositiveIntegerField(
|
||||
default=0,
|
||||
help_text="Maximum number of concurrent streams (0 for unlimited)"
|
||||
)
|
||||
search_pattern = models.CharField(
|
||||
max_length=255,
|
||||
)
|
||||
replace_pattern = models.CharField(
|
||||
max_length=255,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
constraints = [
|
||||
models.UniqueConstraint(fields=['m3u_account_id', 'name'], name='unique_account_name')
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from rest_framework import serializers
|
||||
from .models import M3UAccount, M3UFilter, ServerGroup
|
||||
from .models import M3UAccount, M3UFilter, ServerGroup, M3UAccountProfile
|
||||
from core.models import UserAgent
|
||||
|
||||
class M3UFilterSerializer(serializers.ModelSerializer):
|
||||
|
|
@ -9,6 +9,12 @@ class M3UFilterSerializer(serializers.ModelSerializer):
|
|||
model = M3UFilter
|
||||
fields = ['id', 'filter_type', 'regex_pattern', 'exclude']
|
||||
|
||||
class M3UAccountProfileSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for M3U Account Profiles"""
|
||||
|
||||
class Meta:
|
||||
model = M3UAccountProfile
|
||||
fields = ['id', 'name', 'm3u_account_id', 'search_pattern', 'replace_pattern']
|
||||
|
||||
class M3UAccountSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for M3U Account"""
|
||||
|
|
@ -18,20 +24,18 @@ class M3UAccountSerializer(serializers.ModelSerializer):
|
|||
queryset=UserAgent.objects.all(),
|
||||
required=True
|
||||
)
|
||||
profiles = M3UAccountProfileSerializer(many=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = M3UAccount
|
||||
fields = [
|
||||
'id', 'name', 'server_url', 'uploaded_file', 'server_group',
|
||||
'max_streams', 'is_active', 'created_at', 'updated_at', 'filters', 'user_agent'
|
||||
'max_streams', 'is_active', 'created_at', 'updated_at', 'filters', 'user_agent', 'profiles'
|
||||
]
|
||||
|
||||
|
||||
class ServerGroupSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for Server Group"""
|
||||
|
||||
class Meta:
|
||||
model = ServerGroup
|
||||
fields = ['id', 'name']
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue