add config model

This commit is contained in:
Jonathan Baecker 2020-04-15 18:10:16 +02:00
parent 9b52184910
commit a187ad8ee8
8 changed files with 160 additions and 21 deletions

View File

@ -1,3 +1,13 @@
from django.contrib import admin
# Register your models here.
from api.models import GuiSettings
class GuiSettingsAdmin(admin.ModelAdmin):
class Meta:
model = GuiSettings
fields = '__all__'
admin.site.register(GuiSettings, GuiSettingsAdmin)

View File

@ -1,3 +1,34 @@
import psutil
from django.db import models
# Create your models here.
class GuiSettings(models.Model):
"""
Here we manage the settings for the web GUI:
- Player URL
- settings for the statistics
"""
addrs = psutil.net_if_addrs()
addrs = [(i, i) for i in addrs.keys()]
player_url = models.CharField(max_length=255)
playout_config = models.CharField(max_length=255)
net_interface = models.CharField(
max_length=20,
choices=addrs,
default=None,
)
media_disk = models.CharField(max_length=255)
def save(self, *args, **kwargs):
if self.pk is not None:
super(GuiSettings, self).save(*args, **kwargs)
def delete(self, *args, **kwargs):
if not self.related_query.all():
super(GuiSettings, self).delete(*args, **kwargs)
class Meta:
verbose_name_plural = "guisettings"

View File

@ -0,0 +1,57 @@
from django.contrib.auth.models import User
from rest_framework import serializers
from api.models import GuiSettings
class UserSerializer(serializers.ModelSerializer):
confirm_password = serializers.CharField(write_only=False, required=False)
new_password = serializers.CharField(write_only=True, required=False)
old_password = serializers.CharField(write_only=True, required=False)
class Meta:
model = User
fields = ['username', 'old_password',
'new_password', 'confirm_password', 'email']
def update(self, instance, validated_data):
instance.password = validated_data.get('password', instance.password)
if not validated_data['new_password']:
raise serializers.ValidationError({'new_password': 'not found'})
if not validated_data['old_password']:
raise serializers.ValidationError({'old_password': 'not found'})
if not instance.check_password(validated_data['old_password']):
raise serializers.ValidationError(
{'old_password': 'wrong password'})
if validated_data['new_password'] != \
validated_data['confirm_password']:
raise serializers.ValidationError(
{'passwords': 'passwords do not match'})
if validated_data['new_password'] == \
validated_data['confirm_password'] and \
instance.check_password(validated_data['old_password']):
# instance.password = validated_data['new_password']
instance.set_password(validated_data['new_password'])
instance.save()
return instance
return instance
class GuiSettingsSerializer(serializers.ModelSerializer):
class Meta:
model = GuiSettings
fields = '__all__'
def get_fields(self, *args, **kwargs):
fields = super().get_fields(*args, **kwargs)
request = self.context.get('request')
if request is not None and not request.parser_context.get('kwargs'):
fields.pop('id', None)
return fields

View File

@ -7,19 +7,24 @@ import psutil
import yaml
from pymediainfo import MediaInfo
from django.conf import settings
from api.models import GuiSettings
from natsort import natsorted
def read_yaml():
if os.path.isfile(settings.FFPLAYOUT_CONFIG):
with open(settings.FFPLAYOUT_CONFIG, 'r') as config_file:
config = GuiSettings.objects.filter(id=1).values()[0]
if os.path.isfile(config['playout_config']):
with open(config['playout_config'], 'r') as config_file:
return yaml.safe_load(config_file)
def write_yaml(data):
if os.path.isfile(settings.FFPLAYOUT_CONFIG):
with open(settings.FFPLAYOUT_CONFIG, 'w') as outfile:
config = GuiSettings.objects.filter(id=1).values()[0]
if os.path.isfile(config['playout_config']):
with open(config['playoutConfig'], 'w') as outfile:
yaml.dump(data, outfile, default_flow_style=False,
sort_keys=False, indent=4)
@ -43,7 +48,7 @@ def sizeof_fmt(num, suffix='B'):
class SystemStats:
def __init__(self):
pass
self.config = GuiSettings.objects.filter(id=1).values()[0]
def all(self):
return {
@ -83,7 +88,7 @@ class SystemStats:
}
def disk(self):
root = psutil.disk_usage(settings.MEDIA_DISK)
root = psutil.disk_usage(self.config['media_disk'])
return {
'disk_total': [root.total, sizeof_fmt(root.total)],
'disk_used': [root.used, sizeof_fmt(root.used)],
@ -102,20 +107,20 @@ class SystemStats:
def net_speed(self):
net = psutil.net_if_stats()
if settings.NET_INTERFACE not in net:
if self.config['net_interface'] not in net:
return {
'net_speed_send': 'no network interface set!',
'net_speed_recv': 'no network interface set!'
}
net = psutil.net_io_counters(pernic=True)[settings.NET_INTERFACE]
net = psutil.net_io_counters(pernic=True)[self.config['net_interface']]
send_start = net.bytes_sent
recv_start = net.bytes_recv
sleep(1)
net = psutil.net_io_counters(pernic=True)[settings.NET_INTERFACE]
net = psutil.net_io_counters(pernic=True)[self.config['net_interface']]
send_end = net.bytes_sent
recv_end = net.bytes_recv
@ -160,7 +165,8 @@ def get_media_path(dir=None):
for track in media_info.tracks:
if track.track_type == 'General':
try:
duration = float(track.to_data()["duration"]) / 1000
duration = float(
track.to_data()["duration"]) / 1000
break
except KeyError:
pass

View File

@ -1,14 +1,48 @@
import os
from urllib.parse import unquote
from django.contrib.auth.models import User
from django_filters import rest_framework as filters
from rest_framework import viewsets
from rest_framework.parsers import FileUploadParser, JSONParser
from rest_framework.response import Response
from rest_framework.views import APIView
from api.models import GuiSettings
from api.serializers import GuiSettingsSerializer, UserSerializer
from .utils import (SystemStats, get_media_path, read_json, read_yaml,
write_yaml)
class CurrentUserView(APIView):
def get(self, request):
serializer = UserSerializer(request.user)
return Response(serializer.data)
class UserFilter(filters.FilterSet):
class Meta:
model = User
fields = ['username']
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = (filters.DjangoFilterBackend,)
filterset_class = UserFilter
class GuiSettingsViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows media to be viewed.
"""
queryset = GuiSettings.objects.all()
serializer_class = GuiSettingsSerializer
class Config(APIView):
"""
read and write config from ffplayout engine
@ -17,7 +51,7 @@ class Config(APIView):
parser_classes = [JSONParser]
def get(self, request, *args, **kwargs):
if 'config' in request.GET.dict():
if 'configPlayout' in request.GET.dict():
yaml_input = read_yaml()
if yaml_input:
@ -72,10 +106,11 @@ class Statistics(APIView):
"""
def get(self, request, *args, **kwargs):
stats = SystemStats()
if 'stats' in request.GET.dict() and request.GET.dict()['stats'] \
and hasattr(SystemStats(), request.GET.dict()['stats']):
and hasattr(stats, request.GET.dict()['stats']):
return Response(
getattr(SystemStats(), request.GET.dict()['stats'])())
getattr(stats, request.GET.dict()['stats'])())
else:
return Response({"success": False})

Binary file not shown.

View File

@ -38,6 +38,7 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_filters',
'rest_framework',
'corsheaders',
'api'
@ -112,11 +113,7 @@ REST_FRAMEWORK = {
],
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_PAGINATION_CLASS': (
'rest_framework.pagination.LimitOffsetPagination',
),
'PAGE_SIZE': 50
)
}
CORS_ORIGIN_WHITELIST = (

View File

@ -25,6 +25,8 @@ from rest_framework_simplejwt.views import (
)
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'guisettings', views.GuiSettingsViewSet, 'guisettings')
urlpatterns = [
path('admin/', admin.site.urls),
@ -32,6 +34,7 @@ urlpatterns = [
path('api/config/', views.Config.as_view()),
path('api/playlist/', views.Playlist.as_view()),
path('api/stats/', views.Statistics.as_view()),
path('api/current/user/', views.CurrentUserView.as_view()),
path('api/media/', views.Media.as_view()),
path('api-auth/', include(
'rest_framework.urls', namespace='rest_framework')),