Allow users to change proxy settings.

This commit is contained in:
SergeantPanda 2025-06-10 21:17:30 -05:00
parent e753d9b9f8
commit 7812a410b3
4 changed files with 183 additions and 5 deletions

View file

@ -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

View file

@ -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",

View file

@ -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"

View file

@ -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