mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-01-23 02:35:14 +00:00
Allow users to change proxy settings.
This commit is contained in:
parent
e753d9b9f8
commit
7812a410b3
4 changed files with 183 additions and 5 deletions
|
|
@ -34,6 +34,13 @@ class ConfigHelper:
|
|||
@staticmethod
|
||||
def channel_shutdown_delay():
|
||||
"""Get channel shutdown delay in seconds"""
|
||||
try:
|
||||
from core.models import ProxySettings
|
||||
settings = ProxySettings.objects.first()
|
||||
if settings:
|
||||
return settings.channel_shutdown_delay
|
||||
except:
|
||||
pass
|
||||
return ConfigHelper.get('CHANNEL_SHUTDOWN_DELAY', 0)
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -54,6 +61,13 @@ class ConfigHelper:
|
|||
@staticmethod
|
||||
def redis_chunk_ttl():
|
||||
"""Get Redis chunk TTL in seconds"""
|
||||
try:
|
||||
from core.models import ProxySettings
|
||||
settings = ProxySettings.objects.first()
|
||||
if settings:
|
||||
return settings.redis_chunk_ttl
|
||||
except:
|
||||
pass
|
||||
return ConfigHelper.get('REDIS_CHUNK_TTL', 60)
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -85,11 +99,39 @@ class ConfigHelper:
|
|||
def failover_grace_period():
|
||||
"""Get extra time (in seconds) to allow for stream switching before disconnecting clients"""
|
||||
return ConfigHelper.get('FAILOVER_GRACE_PERIOD', 20) # Default to 20 seconds
|
||||
|
||||
@staticmethod
|
||||
def buffering_timeout():
|
||||
"""Get buffering timeout in seconds"""
|
||||
try:
|
||||
from core.models import ProxySettings
|
||||
settings = ProxySettings.objects.first()
|
||||
if settings:
|
||||
return settings.buffering_timeout
|
||||
except:
|
||||
pass
|
||||
return ConfigHelper.get('BUFFERING_TIMEOUT', 15) # Default to 15 seconds
|
||||
|
||||
@staticmethod
|
||||
def buffering_speed():
|
||||
"""Get buffering speed in bytes per second"""
|
||||
return ConfigHelper.get('BUFFERING_SPEED',1) # Default to 1x
|
||||
"""Get buffering speed threshold"""
|
||||
try:
|
||||
from core.models import ProxySettings
|
||||
settings = ProxySettings.objects.first()
|
||||
if settings:
|
||||
return settings.buffering_speed
|
||||
except:
|
||||
pass
|
||||
return ConfigHelper.get('BUFFERING_SPEED', 1) # Default to 1x
|
||||
|
||||
@staticmethod
|
||||
def channel_init_grace_period():
|
||||
"""Get channel initialization grace period in seconds"""
|
||||
try:
|
||||
from core.models import ProxySettings
|
||||
settings = ProxySettings.objects.first()
|
||||
if settings:
|
||||
return settings.channel_init_grace_period
|
||||
except:
|
||||
pass
|
||||
return ConfigHelper.get('CHANNEL_INIT_GRACE_PERIOD', 5) # Default to 5 seconds
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
# core/api_views.py
|
||||
|
||||
from rest_framework import viewsets, status
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from django.shortcuts import get_object_or_404
|
||||
from .models import UserAgent, StreamProfile, CoreSettings, STREAM_HASH_KEY
|
||||
from .serializers import UserAgentSerializer, StreamProfileSerializer, CoreSettingsSerializer
|
||||
from .models import UserAgent, StreamProfile, CoreSettings, ProxySettings, STREAM_HASH_KEY
|
||||
from .serializers import UserAgentSerializer, StreamProfileSerializer, CoreSettingsSerializer, ProxySettingsSerializer
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.decorators import api_view, permission_classes
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
|
|
@ -44,6 +45,63 @@ class CoreSettingsViewSet(viewsets.ModelViewSet):
|
|||
|
||||
return response
|
||||
|
||||
class ProxySettingsViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
API endpoint for proxy settings.
|
||||
This is treated as a singleton: only one instance should exist.
|
||||
"""
|
||||
serializer_class = ProxySettingsSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
# Always return the singleton settings
|
||||
return ProxySettings.objects.all()
|
||||
|
||||
def get_object(self):
|
||||
# Always return the singleton settings (create if doesn't exist)
|
||||
return ProxySettings.get_settings()
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
# Return the singleton settings as a single object
|
||||
settings = self.get_object()
|
||||
serializer = self.get_serializer(settings)
|
||||
return Response(serializer.data)
|
||||
|
||||
def retrieve(self, request, *args, **kwargs):
|
||||
# Always return the singleton settings regardless of ID
|
||||
settings = self.get_object()
|
||||
serializer = self.get_serializer(settings)
|
||||
return Response(serializer.data)
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
# Update the singleton settings
|
||||
settings = self.get_object()
|
||||
serializer = self.get_serializer(settings, data=request.data, partial=True)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
|
||||
def partial_update(self, request, *args, **kwargs):
|
||||
return self.update(request, *args, **kwargs)
|
||||
|
||||
@action(detail=False, methods=['get', 'patch'])
|
||||
def settings(self, request):
|
||||
"""
|
||||
Get or update the proxy settings.
|
||||
"""
|
||||
settings = self.get_object()
|
||||
|
||||
if request.method == 'GET':
|
||||
# Return current settings
|
||||
serializer = self.get_serializer(settings)
|
||||
return Response(serializer.data)
|
||||
|
||||
elif request.method == 'PATCH':
|
||||
# Update settings
|
||||
serializer = self.get_serializer(settings, data=request.data, partial=True)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
|
||||
@swagger_auto_schema(
|
||||
method='get',
|
||||
operation_description="Endpoint for environment details",
|
||||
|
|
|
|||
|
|
@ -183,3 +183,41 @@ class CoreSettings(models.Model):
|
|||
return cls.objects.get(key=AUTO_IMPORT_MAPPED_FILES).value
|
||||
except cls.DoesNotExist:
|
||||
return None
|
||||
|
||||
class ProxySettings(models.Model):
|
||||
"""Proxy configuration settings"""
|
||||
|
||||
buffering_timeout = models.IntegerField(
|
||||
default=15,
|
||||
help_text="Seconds to wait for buffering before switching streams"
|
||||
)
|
||||
|
||||
buffering_speed = models.FloatField(
|
||||
default=1.0,
|
||||
help_text="Speed threshold to consider stream buffering (1.0 = normal speed)"
|
||||
)
|
||||
|
||||
redis_chunk_ttl = models.IntegerField(
|
||||
default=60,
|
||||
help_text="Time in seconds before Redis chunks expire"
|
||||
)
|
||||
|
||||
channel_shutdown_delay = models.IntegerField(
|
||||
default=0,
|
||||
help_text="Seconds to wait after last client before shutting down channel"
|
||||
)
|
||||
|
||||
channel_init_grace_period = models.IntegerField(
|
||||
default=5,
|
||||
help_text="Seconds to wait for first client after channel initialization"
|
||||
)
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Proxy Settings"
|
||||
verbose_name_plural = "Proxy Settings"
|
||||
|
||||
def __str__(self):
|
||||
return "Proxy Settings"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# core/serializers.py
|
||||
|
||||
from rest_framework import serializers
|
||||
from .models import UserAgent, StreamProfile, CoreSettings
|
||||
from .models import CoreSettings, UserAgent, StreamProfile, ProxySettings
|
||||
|
||||
class UserAgentSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
|
|
@ -17,3 +17,43 @@ class CoreSettingsSerializer(serializers.ModelSerializer):
|
|||
class Meta:
|
||||
model = CoreSettings
|
||||
fields = '__all__'
|
||||
|
||||
class ProxySettingsSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ProxySettings
|
||||
fields = [
|
||||
'id',
|
||||
'buffering_timeout',
|
||||
'buffering_speed',
|
||||
'redis_chunk_ttl',
|
||||
'channel_shutdown_delay',
|
||||
'channel_init_grace_period',
|
||||
'created_at',
|
||||
'updated_at'
|
||||
]
|
||||
read_only_fields = ['id', 'created_at', 'updated_at']
|
||||
|
||||
def validate_buffering_timeout(self, value):
|
||||
if value < 1 or value > 300:
|
||||
raise serializers.ValidationError("Buffering timeout must be between 1 and 300 seconds")
|
||||
return value
|
||||
|
||||
def validate_buffering_speed(self, value):
|
||||
if value < 0.1 or value > 10.0:
|
||||
raise serializers.ValidationError("Buffering speed must be between 0.1 and 10.0")
|
||||
return value
|
||||
|
||||
def validate_redis_chunk_ttl(self, value):
|
||||
if value < 10 or value > 3600:
|
||||
raise serializers.ValidationError("Redis chunk TTL must be between 10 and 3600 seconds")
|
||||
return value
|
||||
|
||||
def validate_channel_shutdown_delay(self, value):
|
||||
if value < 0 or value > 300:
|
||||
raise serializers.ValidationError("Channel shutdown delay must be between 0 and 300 seconds")
|
||||
return value
|
||||
|
||||
def validate_channel_init_grace_period(self, value):
|
||||
if value < 1 or value > 60:
|
||||
raise serializers.ValidationError("Channel init grace period must be between 1 and 60 seconds")
|
||||
return value
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue