| 2883 | |
| 2884 | @action(detail=True, methods=["post"], url_path="duplicate", permission_classes=[IsAdmin]) |
| 2885 | def duplicate(self, request, pk=None): |
| 2886 | requested_name = str(request.data.get("name", "")).strip() |
| 2887 | |
| 2888 | if not requested_name: |
| 2889 | return Response( |
| 2890 | {"detail": "Name is required to duplicate a profile."}, |
| 2891 | status=status.HTTP_400_BAD_REQUEST, |
| 2892 | ) |
| 2893 | |
| 2894 | if ChannelProfile.objects.filter(name=requested_name).exists(): |
| 2895 | return Response( |
| 2896 | {"detail": "A channel profile with this name already exists."}, |
| 2897 | status=status.HTTP_400_BAD_REQUEST, |
| 2898 | ) |
| 2899 | |
| 2900 | source_profile = self.get_object() |
| 2901 | |
| 2902 | with transaction.atomic(): |
| 2903 | new_profile = ChannelProfile.objects.create(name=requested_name) |
| 2904 | |
| 2905 | source_memberships = ChannelProfileMembership.objects.filter( |
| 2906 | channel_profile=source_profile |
| 2907 | ) |
| 2908 | source_enabled_map = { |
| 2909 | membership.channel_id: membership.enabled |
| 2910 | for membership in source_memberships |
| 2911 | } |
| 2912 | |
| 2913 | new_memberships = list( |
| 2914 | ChannelProfileMembership.objects.filter(channel_profile=new_profile) |
| 2915 | ) |
| 2916 | for membership in new_memberships: |
| 2917 | membership.enabled = source_enabled_map.get( |
| 2918 | membership.channel_id, False |
| 2919 | ) |
| 2920 | |
| 2921 | if new_memberships: |
| 2922 | ChannelProfileMembership.objects.bulk_update( |
| 2923 | new_memberships, ["enabled"] |
| 2924 | ) |
| 2925 | |
| 2926 | serializer = self.get_serializer(new_profile) |
| 2927 | return Response(serializer.data, status=status.HTTP_201_CREATED) |
| 2928 | |
| 2929 | |
| 2930 | class GetChannelStreamsAPIView(APIView): |