mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-17 16:50:53 +00:00
Bug Fix: Fixed several incorrect or incomplete OpenAPI (@extend_schema) schemas across the API
Some checks are pending
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
Some checks are pending
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
This commit is contained in:
parent
1adbc70f53
commit
f1a82e8843
4 changed files with 53 additions and 5 deletions
|
|
@ -50,6 +50,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Fixed
|
||||
|
||||
- Fixed `PATCH /api/channels/channels/edit/bulk/` returning a 500 error when the request body included a `streams` list. The bulk edit handler was iterating `validated_data` directly and calling `setattr(channel, "streams", value)`, which Django prohibits on ManyToMany fields. Also added an `@extend_schema` decorator so the Swagger UI correctly documents the endpoint as accepting a JSON array and shows the `streams` field. (Fixes #883)
|
||||
- Fixed several incorrect or incomplete OpenAPI (`@extend_schema`) schemas across the API:
|
||||
- `POST /api/epg/import/` — request body was undocumented; now correctly shows the `id` field. Description updated from "import" to "refresh" to match frontend and backend terminology.
|
||||
- `DELETE /api/channels/logos/bulk-delete/` — `delete_files` boolean was missing from the documented request body.
|
||||
- `POST /api/channels/channels/batch-set-epg/` — `epg_data_id` inside each association object was not marked `allow_null`/`required=False`, even though passing `null` is the correct way to remove an EPG link.
|
||||
- `PUT /api/connect/integrations/{id}/subscriptions/set/` — endpoint had no `@extend_schema` at all; now documents that the request body is a JSON array of subscription objects.
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
|||
|
|
@ -1565,7 +1565,11 @@ class ChannelViewSet(viewsets.ModelViewSet):
|
|||
name="EpgAssociation",
|
||||
fields={
|
||||
"channel_id": serializers.IntegerField(),
|
||||
"epg_data_id": serializers.IntegerField(),
|
||||
"epg_data_id": serializers.IntegerField(
|
||||
required=False,
|
||||
allow_null=True,
|
||||
help_text="EPG data ID to link. Pass null to remove EPG linkage.",
|
||||
),
|
||||
},
|
||||
),
|
||||
)
|
||||
|
|
@ -1741,7 +1745,12 @@ class BulkDeleteLogosAPIView(APIView):
|
|||
"logo_ids": serializers.ListField(
|
||||
child=serializers.IntegerField(),
|
||||
help_text="Logo IDs to delete",
|
||||
)
|
||||
),
|
||||
"delete_files": serializers.BooleanField(
|
||||
required=False,
|
||||
default=False,
|
||||
help_text="Whether to also delete local logo files from disk.",
|
||||
),
|
||||
},
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
from rest_framework import viewsets, status
|
||||
from rest_framework import viewsets, status, serializers
|
||||
from rest_framework.pagination import PageNumberPagination
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.decorators import action
|
||||
from django.utils import timezone
|
||||
from drf_spectacular.utils import extend_schema, inline_serializer
|
||||
from .models import Integration, EventSubscription, DeliveryLog
|
||||
from .serializers import (
|
||||
IntegrationSerializer,
|
||||
|
|
@ -37,6 +38,33 @@ class IntegrationViewSet(viewsets.ModelViewSet):
|
|||
serializer = EventSubscriptionSerializer(qs, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@extend_schema(
|
||||
methods=["PUT"],
|
||||
description=(
|
||||
"Replace the integration's event subscriptions with the provided list. "
|
||||
"Accepts a JSON array of subscription objects. "
|
||||
"Existing subscriptions not in the list will be deleted. "
|
||||
"The 'payload_template' field is only relevant for webhook integrations."
|
||||
),
|
||||
request=inline_serializer(
|
||||
name="SetSubscriptionsRequest",
|
||||
fields={
|
||||
"event": serializers.CharField(help_text="Event name (e.g. 'channel_start')."),
|
||||
"enabled": serializers.BooleanField(required=False, default=True),
|
||||
"payload_template": serializers.CharField(required=False, allow_blank=True, allow_null=True, help_text="Custom payload template (webhook integrations only)."),
|
||||
},
|
||||
many=True,
|
||||
),
|
||||
responses={200: inline_serializer(
|
||||
name="SetSubscriptionsResponse",
|
||||
fields={
|
||||
"event": serializers.CharField(),
|
||||
"enabled": serializers.BooleanField(),
|
||||
"payload_template": serializers.CharField(allow_null=True),
|
||||
},
|
||||
many=True,
|
||||
)},
|
||||
)
|
||||
@action(detail=True, methods=["put"], url_path=r"subscriptions/set")
|
||||
def set_subscriptions(self, request, pk=None):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -427,7 +427,13 @@ class EPGImportAPIView(APIView):
|
|||
return [Authenticated()]
|
||||
|
||||
@extend_schema(
|
||||
description="Triggers an EPG data import",
|
||||
description="Triggers an EPG data refresh for the given source.",
|
||||
request=inline_serializer(
|
||||
name="EPGImportRequest",
|
||||
fields={
|
||||
"id": serializers.IntegerField(help_text="ID of the EPG source to refresh."),
|
||||
},
|
||||
),
|
||||
)
|
||||
def post(self, request, format=None):
|
||||
logger.info("EPGImportAPIView: Received request to import EPG data.")
|
||||
|
|
@ -449,7 +455,7 @@ class EPGImportAPIView(APIView):
|
|||
refresh_epg_data.delay(epg_id) # Trigger Celery task
|
||||
logger.info("EPGImportAPIView: Task dispatched to refresh EPG data.")
|
||||
return Response(
|
||||
{"success": True, "message": "EPG data import initiated."},
|
||||
{"success": True, "message": "EPG data refresh initiated."},
|
||||
status=status.HTTP_202_ACCEPTED,
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue