replace DRF with django-ninja
This commit is contained in:
		
							parent
							
								
									4299d46b7b
								
							
						
					
					
						commit
						813780a18b
					
				| 
						 | 
				
			
			@ -0,0 +1,112 @@
 | 
			
		|||
from ninja import Router, Schema
 | 
			
		||||
from ninja.errors import HttpError
 | 
			
		||||
from concierge import models
 | 
			
		||||
from typing import List
 | 
			
		||||
from django.db import transaction
 | 
			
		||||
from django.shortcuts import get_object_or_404
 | 
			
		||||
from django.utils.timezone import now
 | 
			
		||||
from django.views.decorators.csrf import csrf_exempt
 | 
			
		||||
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
router = Router()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ClaimReference(Schema):
 | 
			
		||||
  uuid: str
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AvailableTask(Schema):
 | 
			
		||||
  uuid: str
 | 
			
		||||
  type: str
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HeartbeatResponse(Schema):
 | 
			
		||||
  success: bool = True
 | 
			
		||||
  claims: List[ClaimReference]
 | 
			
		||||
  available: List[AvailableTask]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ClaimResponse(Schema):
 | 
			
		||||
  uuid: str
 | 
			
		||||
  type: str
 | 
			
		||||
  configuration: dict
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ReleaseResponse(Schema):
 | 
			
		||||
  success: bool = True
 | 
			
		||||
  uuid: str
 | 
			
		||||
  type: str
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.post('/heartbeat/{identity}', response=HeartbeatResponse)
 | 
			
		||||
@csrf_exempt
 | 
			
		||||
def receive_heartbeat(request, identity: str):
 | 
			
		||||
  try:
 | 
			
		||||
    id = models.Identity.objects.get(identity=identity)
 | 
			
		||||
  except models.Identity.DoesNotExist:
 | 
			
		||||
    raise HttpError(403, "identity unknown")
 | 
			
		||||
 | 
			
		||||
  # update heartbeat
 | 
			
		||||
  id.heartbeat = now()
 | 
			
		||||
  id.save()
 | 
			
		||||
 | 
			
		||||
  # get current claims and available tasks
 | 
			
		||||
  claims = models.Task.objects.filter(claimed_by=id).all()
 | 
			
		||||
  available = models.Task.objects.filter(claimed_by=None).all()
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
      'success': True,
 | 
			
		||||
      'claims': [{'uuid': str(o.uuid)} for o in list(claims)],
 | 
			
		||||
      'available': [{'uuid': str(o.uuid), 'type': o.type} for o in list(available)],
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.post('/claim/{identity}/{task_uuid}', response=ClaimResponse)
 | 
			
		||||
@csrf_exempt
 | 
			
		||||
def claim_task(request, identity: str, task_uuid: str):
 | 
			
		||||
  try:
 | 
			
		||||
    id = models.Identity.objects.get(identity=identity)
 | 
			
		||||
  except models.Identity.DoesNotExist:
 | 
			
		||||
    raise HttpError(403, "identity unknown")
 | 
			
		||||
 | 
			
		||||
  with transaction.atomic():
 | 
			
		||||
    task = get_object_or_404(models.Task, uuid=task_uuid)
 | 
			
		||||
 | 
			
		||||
    if task.claimed_by:
 | 
			
		||||
      raise HttpError(423, "task already claimed")
 | 
			
		||||
 | 
			
		||||
    task.claimed_by = id
 | 
			
		||||
    task.save()
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        'success': True,
 | 
			
		||||
        'uuid': task.uuid,
 | 
			
		||||
        'type': task.type,
 | 
			
		||||
        'configuration': json.loads(task.configuration)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.post('/release/{identity}/{task_uuid}')
 | 
			
		||||
@csrf_exempt
 | 
			
		||||
def release_task(request, identity: str, task_uuid: str):
 | 
			
		||||
  try:
 | 
			
		||||
    id = models.Identity.objects.get(identity=identity)
 | 
			
		||||
  except models.Identity.DoesNotExist:
 | 
			
		||||
    raise HttpError(403, "identity unknown")
 | 
			
		||||
 | 
			
		||||
  with transaction.atomic():
 | 
			
		||||
    task = get_object_or_404(models.Task, uuid=task_uuid)
 | 
			
		||||
 | 
			
		||||
    if task.claimed_by != id:
 | 
			
		||||
      raise HttpError(403, "task not claimed by this identity")
 | 
			
		||||
 | 
			
		||||
    task.claimed_by = None
 | 
			
		||||
    task.save()
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      'success': True,
 | 
			
		||||
      'uuid': task.uuid,
 | 
			
		||||
      'type': task.type,
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +0,0 @@
 | 
			
		|||
from django.urls import path
 | 
			
		||||
from . import views
 | 
			
		||||
 | 
			
		||||
urlpatterns = [
 | 
			
		||||
    path('api/<uuid:identity>/heartbeat', views.heartbeat, name='heartbeat'),
 | 
			
		||||
    path('api/<uuid:identity>/claim/<uuid:task_uuid>', views.claim, name='claim'),
 | 
			
		||||
    path('api/<uuid:identity>/release/<uuid:task_uuid>', views.release, name='release'),
 | 
			
		||||
]
 | 
			
		||||
| 
						 | 
				
			
			@ -1,94 +0,0 @@
 | 
			
		|||
import json
 | 
			
		||||
 | 
			
		||||
from django.db import transaction
 | 
			
		||||
from django.http import JsonResponse
 | 
			
		||||
from django.views.decorators.csrf import csrf_exempt
 | 
			
		||||
from django.views.decorators.http import require_POST
 | 
			
		||||
from django.core.exceptions import ObjectDoesNotExist
 | 
			
		||||
from django.utils.timezone import now
 | 
			
		||||
 | 
			
		||||
from .models import Identity, Task
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@csrf_exempt
 | 
			
		||||
@require_POST
 | 
			
		||||
def heartbeat(request, identity):
 | 
			
		||||
    try:
 | 
			
		||||
        id = Identity.objects.get(identity=identity)
 | 
			
		||||
    except ObjectDoesNotExist:
 | 
			
		||||
        return JsonResponse({'error': 'identity unknown'}, status=403)
 | 
			
		||||
 | 
			
		||||
    # update heartbeat
 | 
			
		||||
    id.heartbeat = now()
 | 
			
		||||
    id.save()
 | 
			
		||||
 | 
			
		||||
    # get current claims and available tasks
 | 
			
		||||
    claims = Task.objects.filter(claimed_by=id).all()
 | 
			
		||||
    available = Task.objects.filter(claimed_by=None).all()
 | 
			
		||||
 | 
			
		||||
    data = {
 | 
			
		||||
        'success': True,
 | 
			
		||||
        'claims': [{'uuid': str(o.uuid)} for o in list(claims)],
 | 
			
		||||
        'available': [{'uuid': str(o.uuid), 'type': o.type} for o in list(available)],
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return JsonResponse(data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@csrf_exempt
 | 
			
		||||
@require_POST
 | 
			
		||||
def claim(request, identity, task_uuid):
 | 
			
		||||
    try:
 | 
			
		||||
        id = Identity.objects.get(identity=identity)
 | 
			
		||||
    except ObjectDoesNotExist:
 | 
			
		||||
        return JsonResponse({'error': 'identity unknown'}, status=403)
 | 
			
		||||
 | 
			
		||||
    with transaction.atomic():
 | 
			
		||||
        try:
 | 
			
		||||
            task = Task.objects.get(uuid=task_uuid)
 | 
			
		||||
        except ObjectDoesNotExist:
 | 
			
		||||
            return JsonResponse({'error': 'task unknown'}, status=404)
 | 
			
		||||
 | 
			
		||||
        if task.claimed_by:
 | 
			
		||||
            return JsonResponse({'error': 'task already claimed'}, status=423)
 | 
			
		||||
 | 
			
		||||
        task.claimed_by = id
 | 
			
		||||
        task.save()
 | 
			
		||||
 | 
			
		||||
        data = {
 | 
			
		||||
            'success': True,
 | 
			
		||||
            'uuid': task.uuid,
 | 
			
		||||
            'type': task.type,
 | 
			
		||||
            'configuration': json.loads(task.configuration)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return JsonResponse(data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@csrf_exempt
 | 
			
		||||
@require_POST
 | 
			
		||||
def release(request, identity, task_uuid):
 | 
			
		||||
    try:
 | 
			
		||||
        id = Identity.objects.get(identity=identity)
 | 
			
		||||
    except ObjectDoesNotExist:
 | 
			
		||||
        return JsonResponse({'error': 'identity unknown'}, status=403)
 | 
			
		||||
 | 
			
		||||
    with transaction.atomic():
 | 
			
		||||
        try:
 | 
			
		||||
            task = Task.objects.get(uuid=task_uuid)
 | 
			
		||||
        except ObjectDoesNotExist:
 | 
			
		||||
            return JsonResponse({'error': 'task unknown'}, status=404)
 | 
			
		||||
 | 
			
		||||
        if task.claimed_by != id:
 | 
			
		||||
            return JsonResponse({'error': 'task claimed by other identity'}, status=403)
 | 
			
		||||
 | 
			
		||||
        task.claimed_by = None
 | 
			
		||||
        task.save()
 | 
			
		||||
 | 
			
		||||
        data = {
 | 
			
		||||
            'success': True,
 | 
			
		||||
            'uuid': task.uuid,
 | 
			
		||||
            'type': task.type,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return JsonResponse(data)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,144 @@
 | 
			
		|||
from ninja import Router, ModelSchema, Schema
 | 
			
		||||
from ninja.errors import HttpError
 | 
			
		||||
from config import models
 | 
			
		||||
from typing import List
 | 
			
		||||
from guardian.shortcuts import get_objects_for_user, assign_perm
 | 
			
		||||
from django.shortcuts import get_object_or_404
 | 
			
		||||
 | 
			
		||||
router = Router()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Restream(ModelSchema):
 | 
			
		||||
  class Meta:
 | 
			
		||||
    model = models.Restream
 | 
			
		||||
    fields = "__all__"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class RestreamPatch(ModelSchema):
 | 
			
		||||
  class Meta:
 | 
			
		||||
    model = models.Restream
 | 
			
		||||
    exclude = ["id"]
 | 
			
		||||
    fields_optional = "__all__"
 | 
			
		||||
    extra = "forbid"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Stream(ModelSchema):
 | 
			
		||||
  class Meta:
 | 
			
		||||
    model = models.Stream
 | 
			
		||||
    fields = "__all__"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class StreamPatch(ModelSchema):
 | 
			
		||||
  class Meta:
 | 
			
		||||
    model = models.Stream
 | 
			
		||||
    fields = ["name"]
 | 
			
		||||
    fields_optional = "__all__"
 | 
			
		||||
    extra = "forbid"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class StreamCreate(ModelSchema):
 | 
			
		||||
  class Meta:
 | 
			
		||||
    model = models.Stream
 | 
			
		||||
    fields = ["name"]
 | 
			
		||||
    extra = "forbid"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.get('/streams', response=List[Stream])
 | 
			
		||||
def list_streams(request):
 | 
			
		||||
  return get_objects_for_user(request.user, 'view_stream', models.Stream.objects.all())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.post('/streams', response=Stream)
 | 
			
		||||
def create_stream(request, payload: StreamCreate):
 | 
			
		||||
  stream = models.Stream.objects.create(**payload.dict())
 | 
			
		||||
  assign_perm('view_stream', request.user, stream)
 | 
			
		||||
  assign_perm('change_stream', request.user, stream)
 | 
			
		||||
  assign_perm('delete_stream', request.user, stream)
 | 
			
		||||
  return stream
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.get('/streams/{id}', response=Stream)
 | 
			
		||||
def get_stream(request, id: int):
 | 
			
		||||
  stream = get_object_or_404(models.Stream, id=id)
 | 
			
		||||
 | 
			
		||||
  if not request.user.has_perm('view_stream', stream):
 | 
			
		||||
    raise HttpError(401, "unauthorized")
 | 
			
		||||
  return stream
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.patch('/streams/{id}', response=Stream)
 | 
			
		||||
def update_stream(request, id: int, payload: StreamPatch):
 | 
			
		||||
  stream = get_object_or_404(models.Stream, id=id)
 | 
			
		||||
 | 
			
		||||
  if not request.user.has_perm('change_stream', stream):
 | 
			
		||||
    raise HttpError(401, "unauthorized")
 | 
			
		||||
 | 
			
		||||
  stream.name = payload.name
 | 
			
		||||
  stream.save()
 | 
			
		||||
  return stream
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.delete('/streams/{id}', response=None)
 | 
			
		||||
def delete_stream(request, id: int):
 | 
			
		||||
  stream = get_object_or_404(models.Stream, id=id)
 | 
			
		||||
 | 
			
		||||
  if not request.user.has_perm('delete_stream', stream):
 | 
			
		||||
    raise HttpError(401, "unauthorized")
 | 
			
		||||
 | 
			
		||||
  stream.delete()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.get('/restreams', response=List[Restream])
 | 
			
		||||
def list_restreams(request):
 | 
			
		||||
  return get_objects_for_user(request.user, 'view_restream', models.Restream.objects.all())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.post('/restreams', response=Restream)
 | 
			
		||||
def create_restream(request, payload: Restream):
 | 
			
		||||
  if not request.user.has_perm('view_stream', payload.stream):
 | 
			
		||||
    raise HttpError(401, "unauthorized")
 | 
			
		||||
 | 
			
		||||
  restream = models.Restream.objects.create(**payload.dict())
 | 
			
		||||
  assign_perm('view_restream', request.user, restream)
 | 
			
		||||
  assign_perm('change_restream', request.user, restream)
 | 
			
		||||
  assign_perm('delete_restream', request.user, restream)
 | 
			
		||||
  return restream
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.get('/restreams/{id}', response=Restream)
 | 
			
		||||
def get_restream(request, id: int):
 | 
			
		||||
  restream = get_object_or_404(models.Restream, id=id)
 | 
			
		||||
  
 | 
			
		||||
  if not request.user.has_perm('view_restream', restream):
 | 
			
		||||
    raise HttpError(401, "unauthorized")
 | 
			
		||||
 | 
			
		||||
  return restream
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.patch('/restreams/{id}', response=Restream)
 | 
			
		||||
def update_restream(request, id: int, payload: RestreamPatch):
 | 
			
		||||
  restream = get_object_or_404(models.Restream, id=id)
 | 
			
		||||
 | 
			
		||||
  if not request.user.has_perm('change_restream', restream):
 | 
			
		||||
    raise HttpError(401, "unauthorized")
 | 
			
		||||
 | 
			
		||||
  if payload.stream:
 | 
			
		||||
    payload.stream = get_object_or_404(models.Stream, id=payload.stream)
 | 
			
		||||
    
 | 
			
		||||
    if not request.user.has_perm('view_stream', payload.stream):
 | 
			
		||||
      raise HttpError(401, "unauthorized")
 | 
			
		||||
 | 
			
		||||
  for key, value in payload.dict(exclude_unset=True).items():
 | 
			
		||||
    setattr(restream, key, value)
 | 
			
		||||
  restream.save()
 | 
			
		||||
  return restream
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.delete('/restreams/{id}', response=None)
 | 
			
		||||
def delete_restream(request, id: int):
 | 
			
		||||
  restream = get_object_or_404(models.Restream, id=id)
 | 
			
		||||
 | 
			
		||||
  if not request.user.has_perm('delete_restream', restream):
 | 
			
		||||
    raise HttpError(401, "unauthorized")
 | 
			
		||||
 | 
			
		||||
  restream.delete()
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
from ninja import NinjaAPI, ModelSchema, Router
 | 
			
		||||
from ninja.security import django_auth
 | 
			
		||||
from django.contrib.auth.models import User
 | 
			
		||||
 | 
			
		||||
from config.api import router as config_router
 | 
			
		||||
from concierge.api import router as concierge_router
 | 
			
		||||
 | 
			
		||||
core_router = Router()
 | 
			
		||||
 | 
			
		||||
class UserSchema(ModelSchema):
 | 
			
		||||
  class Meta:
 | 
			
		||||
    model = User
 | 
			
		||||
    fields = ["id", "username", "email"]
 | 
			
		||||
 | 
			
		||||
@core_router.get("/me", response=UserSchema)
 | 
			
		||||
def me(request):
 | 
			
		||||
  return request.user
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
api = NinjaAPI(
 | 
			
		||||
  title="Portier API",
 | 
			
		||||
  version="2.0.0",
 | 
			
		||||
  description="HTTP API for Portier. Use this to interact with the Portier backend.",
 | 
			
		||||
  csrf=True,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
api.add_router("/", core_router, auth=django_auth, tags=["Core"])
 | 
			
		||||
api.add_router("/config/", config_router, auth=django_auth, tags=["Configuration"])
 | 
			
		||||
api.add_router("/concierge/", concierge_router, auth=None, tags=["Concierge"])
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +41,8 @@ INSTALLED_APPS = [
 | 
			
		|||
    'django.contrib.sessions',
 | 
			
		||||
    'django.contrib.messages',
 | 
			
		||||
    'django.contrib.staticfiles',
 | 
			
		||||
    'rest_framework',
 | 
			
		||||
    'ninja',
 | 
			
		||||
    #'rest_framework',
 | 
			
		||||
    'guardian',
 | 
			
		||||
    'django_registration',
 | 
			
		||||
    'bootstrap4',
 | 
			
		||||
| 
						 | 
				
			
			@ -194,7 +195,7 @@ DJANGO_CELERY_BEAT_TZ_AWARE = False
 | 
			
		|||
 | 
			
		||||
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
 | 
			
		||||
 | 
			
		||||
if DEBUG:
 | 
			
		||||
if DEBUG == "LOLOLOL":
 | 
			
		||||
    LOGGING = {
 | 
			
		||||
        'version': 1,
 | 
			
		||||
        'disable_existing_loggers': False,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,14 @@
 | 
			
		|||
from django.contrib import admin
 | 
			
		||||
from django.urls import include, path
 | 
			
		||||
 | 
			
		||||
from .api import api
 | 
			
		||||
 | 
			
		||||
urlpatterns = [
 | 
			
		||||
    path('accounts/', include('django_registration.backends.activation.urls')),
 | 
			
		||||
    path('accounts/', include('django.contrib.auth.urls')),
 | 
			
		||||
    path('i18n/', include('django.conf.urls.i18n')),
 | 
			
		||||
    path('admin/', admin.site.urls),
 | 
			
		||||
    path('config/', include('config.urls')),
 | 
			
		||||
    path('concierge/', include('concierge.urls')),
 | 
			
		||||
    path('api/v1/', include('restapi.urls')),
 | 
			
		||||
    path('api/v2/', api.urls),
 | 
			
		||||
    path('', include('core.urls')),
 | 
			
		||||
]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,8 +5,7 @@ django-guardian
 | 
			
		|||
django-fontawesome-5
 | 
			
		||||
django-celery-beat
 | 
			
		||||
django-filter
 | 
			
		||||
djangorestframework
 | 
			
		||||
djangorestframework-guardian
 | 
			
		||||
django-ninja
 | 
			
		||||
celery>=5.3
 | 
			
		||||
gunicorn>=20
 | 
			
		||||
psycopg2-binary
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +0,0 @@
 | 
			
		|||
from django.apps import AppConfig
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class RestapiConfig(AppConfig):
 | 
			
		||||
    name = 'restapi'
 | 
			
		||||
| 
						 | 
				
			
			@ -1,16 +0,0 @@
 | 
			
		|||
from django.urls import path, include
 | 
			
		||||
from rest_framework import routers
 | 
			
		||||
 | 
			
		||||
from .views import StreamViewSet, RestreamViewSet
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
router = routers.DefaultRouter()
 | 
			
		||||
router.register(r'stream', StreamViewSet)
 | 
			
		||||
router.register(r'restream', RestreamViewSet)
 | 
			
		||||
 | 
			
		||||
app_name = 'restapi'
 | 
			
		||||
 | 
			
		||||
urlpatterns = [
 | 
			
		||||
    path('', include(router.urls)),
 | 
			
		||||
    path('auth/', include('rest_framework.urls', namespace='rest_framework'))
 | 
			
		||||
]
 | 
			
		||||
| 
						 | 
				
			
			@ -1,51 +0,0 @@
 | 
			
		|||
from rest_framework_guardian.serializers import ObjectPermissionsAssignmentMixin
 | 
			
		||||
from rest_framework import serializers, viewsets
 | 
			
		||||
from rest_framework_guardian import filters
 | 
			
		||||
from config.models import Stream, Restream
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class StreamSerializer(ObjectPermissionsAssignmentMixin, serializers.ModelSerializer):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = Stream
 | 
			
		||||
        fields = '__all__'
 | 
			
		||||
        read_only_fields = ['publish_counter']
 | 
			
		||||
 | 
			
		||||
    def get_permissions_map(self, created):
 | 
			
		||||
        current_user = self.context['request'].user
 | 
			
		||||
        return {
 | 
			
		||||
            'view_stream': [current_user],
 | 
			
		||||
            'change_stream': [current_user],
 | 
			
		||||
            'delete_stream': [current_user]
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class StreamViewSet(viewsets.ModelViewSet):
 | 
			
		||||
    queryset = Stream.objects.all()
 | 
			
		||||
    serializer_class = StreamSerializer
 | 
			
		||||
    filter_backends = [filters.ObjectPermissionsFilter]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class RestreamSerializer(ObjectPermissionsAssignmentMixin, serializers.ModelSerializer):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = Restream
 | 
			
		||||
        fields = '__all__'
 | 
			
		||||
 | 
			
		||||
    def get_permissions_map(self, created):
 | 
			
		||||
        current_user = self.context['request'].user
 | 
			
		||||
        return {
 | 
			
		||||
            'view_restream': [current_user],
 | 
			
		||||
            'change_restream': [current_user],
 | 
			
		||||
            'delete_restream': [current_user]
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def validate_stream(self, value):
 | 
			
		||||
        request = self.context['request']
 | 
			
		||||
        if not request.user.has_perm('config.view_stream', value):
 | 
			
		||||
            raise serializers.ValidationError('Access to stream is not authorized')
 | 
			
		||||
        return value
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class RestreamViewSet(viewsets.ModelViewSet):
 | 
			
		||||
    queryset = Restream.objects.all()
 | 
			
		||||
    serializer_class = RestreamSerializer
 | 
			
		||||
    filter_backends = [filters.ObjectPermissionsFilter]
 | 
			
		||||
| 
						 | 
				
			
			@ -13,7 +13,7 @@ var app = new Vue({
 | 
			
		|||
    },
 | 
			
		||||
    toggleActive(cfg) {
 | 
			
		||||
      axios
 | 
			
		||||
        .patch('/api/v1/restream/' + cfg.id + '/', { active: !cfg.active })
 | 
			
		||||
        .patch('/api/v2/config/restreams/' + cfg.id, { active: !cfg.active })
 | 
			
		||||
        .then(response => {
 | 
			
		||||
            i = this.cfgs.findIndex((obj => obj.id == cfg.id))
 | 
			
		||||
            Vue.set(this.cfgs, i, response.data)
 | 
			
		||||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ var app = new Vue({
 | 
			
		|||
    },
 | 
			
		||||
    fetchData() {
 | 
			
		||||
      axios
 | 
			
		||||
        .get('/api/v1/restream/')
 | 
			
		||||
        .get('/api/v2/config/restreams')
 | 
			
		||||
        .then(response => {
 | 
			
		||||
          this.cfgs = response.data
 | 
			
		||||
          this.isLoading = false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,7 @@ var app = new Vue({
 | 
			
		|||
    },
 | 
			
		||||
    fetchData() {
 | 
			
		||||
      axios
 | 
			
		||||
        .get('/api/v1/stream/')
 | 
			
		||||
        .get('/api/v2/config/streams')
 | 
			
		||||
        .then(response => {
 | 
			
		||||
          this.streams = response.data
 | 
			
		||||
          this.isLoading = false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue