786 lines
31 KiB
Python
786 lines
31 KiB
Python
from django.shortcuts import render
|
||
import json
|
||
import uuid
|
||
import logging
|
||
from django.db import transaction
|
||
from django.shortcuts import get_object_or_404
|
||
from django.conf import settings
|
||
from django.utils import timezone
|
||
from rest_framework import viewsets, status
|
||
from rest_framework.decorators import action
|
||
from rest_framework.response import Response
|
||
from django.db.models import Q
|
||
import os
|
||
|
||
from .models import OperatorAccount, PlatformAccount, Video
|
||
from .serializers import (
|
||
OperatorAccountSerializer, PlatformAccountSerializer, VideoSerializer,
|
||
MultiPlatformAccountSerializer
|
||
)
|
||
from .pagination import CustomPagination
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
class OperatorAccountViewSet(viewsets.ModelViewSet):
|
||
"""运营账号管理视图集"""
|
||
queryset = OperatorAccount.objects.all()
|
||
serializer_class = OperatorAccountSerializer
|
||
pagination_class = CustomPagination
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
"""获取运营账号列表"""
|
||
queryset = self.filter_queryset(self.get_queryset())
|
||
page = self.paginate_queryset(queryset)
|
||
|
||
if page is not None:
|
||
serializer = self.get_serializer(page, many=True)
|
||
# 使用自定义分页器的响应
|
||
return self.get_paginated_response(serializer.data)
|
||
|
||
serializer = self.get_serializer(queryset, many=True)
|
||
return Response({
|
||
"code": 200,
|
||
"message": "获取运营账号列表成功",
|
||
"data": serializer.data
|
||
})
|
||
|
||
def retrieve(self, request, *args, **kwargs):
|
||
"""获取运营账号详情"""
|
||
instance = self.get_object()
|
||
serializer = self.get_serializer(instance)
|
||
return Response({
|
||
"code": 200,
|
||
"message": "获取运营账号详情成功",
|
||
"data": serializer.data
|
||
})
|
||
|
||
def update(self, request, *args, **kwargs):
|
||
"""更新运营账号信息"""
|
||
partial = kwargs.pop('partial', False)
|
||
instance = self.get_object()
|
||
serializer = self.get_serializer(instance, data=request.data, partial=partial)
|
||
serializer.is_valid(raise_exception=True)
|
||
self.perform_update(serializer)
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "更新运营账号信息成功",
|
||
"data": serializer.data
|
||
})
|
||
|
||
def partial_update(self, request, *args, **kwargs):
|
||
"""部分更新运营账号信息"""
|
||
kwargs['partial'] = True
|
||
return self.update(request, *args, **kwargs)
|
||
|
||
def create(self, request, *args, **kwargs):
|
||
"""创建运营账号"""
|
||
serializer = self.get_serializer(data=request.data)
|
||
serializer.is_valid(raise_exception=True)
|
||
self.perform_create(serializer)
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "运营账号创建成功",
|
||
"data": serializer.data
|
||
}, status=status.HTTP_201_CREATED)
|
||
|
||
def destroy(self, request, *args, **kwargs):
|
||
"""删除运营账号"""
|
||
operator = self.get_object()
|
||
operator.is_active = False # 软删除
|
||
operator.save()
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "运营账号已停用",
|
||
"data": None
|
||
})
|
||
|
||
|
||
class PlatformAccountViewSet(viewsets.ModelViewSet):
|
||
"""平台账号管理视图集"""
|
||
queryset = PlatformAccount.objects.all()
|
||
serializer_class = PlatformAccountSerializer
|
||
pagination_class = CustomPagination
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
"""获取平台账号列表"""
|
||
queryset = self.filter_queryset(self.get_queryset())
|
||
page = self.paginate_queryset(queryset)
|
||
|
||
if page is not None:
|
||
serializer = self.get_serializer(page, many=True)
|
||
# 处理数据结构
|
||
response_data = serializer.data
|
||
restructured_data = []
|
||
for account_data in response_data:
|
||
# 提取平台信息并放入platforms字段
|
||
platform_info = {
|
||
"platform_name": account_data.pop("platform_name"),
|
||
"account_url": account_data.pop("account_url"),
|
||
"account_id": account_data.pop("account_id"),
|
||
"account_name": account_data.pop("account_name")
|
||
}
|
||
# 添加platforms字段作为数组
|
||
account_data["platforms"] = [platform_info]
|
||
# 保留用户传入的name字段,如果没有则使用platform_name
|
||
if not account_data.get("name"):
|
||
account_data["name"] = platform_info["platform_name"]
|
||
restructured_data.append(account_data)
|
||
|
||
# 使用自定义分页器的响应,但替换数据
|
||
return self.get_paginated_response(restructured_data)
|
||
|
||
serializer = self.get_serializer(queryset, many=True)
|
||
# 处理数据结构
|
||
response_data = serializer.data
|
||
restructured_data = []
|
||
for account_data in response_data:
|
||
# 提取平台信息并放入platforms字段
|
||
platform_info = {
|
||
"platform_name": account_data.pop("platform_name"),
|
||
"account_url": account_data.pop("account_url"),
|
||
"account_id": account_data.pop("account_id"),
|
||
"account_name": account_data.pop("account_name")
|
||
}
|
||
# 添加platforms字段作为数组
|
||
account_data["platforms"] = [platform_info]
|
||
# 保留用户传入的name字段,如果没有则使用platform_name
|
||
if not account_data.get("name"):
|
||
account_data["name"] = platform_info["platform_name"]
|
||
restructured_data.append(account_data)
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "获取平台账号列表成功",
|
||
"data": restructured_data
|
||
})
|
||
|
||
def retrieve(self, request, *args, **kwargs):
|
||
"""获取平台账号详情"""
|
||
instance = self.get_object()
|
||
serializer = self.get_serializer(instance)
|
||
# 处理数据结构
|
||
account_data = serializer.data
|
||
# 提取平台信息并放入platforms字段
|
||
platform_info = {
|
||
"platform_name": account_data.pop("platform_name"),
|
||
"account_url": account_data.pop("account_url"),
|
||
"account_id": account_data.pop("account_id"),
|
||
"account_name": account_data.pop("account_name")
|
||
}
|
||
# 添加platforms字段
|
||
account_data["platforms"] = [platform_info]
|
||
# 保留用户传入的name字段,如果没有则使用platform_name
|
||
if not account_data.get("name"):
|
||
account_data["name"] = platform_info["platform_name"]
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "获取平台账号详情成功",
|
||
"data": account_data
|
||
})
|
||
|
||
def update(self, request, *args, **kwargs):
|
||
"""更新平台账号信息"""
|
||
partial = kwargs.pop('partial', False)
|
||
instance = self.get_object()
|
||
|
||
# 单独处理platforms字段,多平台信息需要特殊处理
|
||
data = request.data.copy()
|
||
platforms_data = None
|
||
|
||
if 'platforms' in data and isinstance(data['platforms'], list):
|
||
platforms_data = data.pop('platforms')
|
||
|
||
# 如果有platforms数据,先将第一个平台的信息移至顶层,保证基本平台信息能正常更新
|
||
if platforms_data and len(platforms_data) > 0:
|
||
first_platform = platforms_data[0]
|
||
if 'platform_name' in first_platform:
|
||
data['platform_name'] = first_platform['platform_name']
|
||
if 'account_url' in first_platform:
|
||
data['account_url'] = first_platform['account_url']
|
||
if 'account_id' in first_platform:
|
||
data['account_id'] = first_platform['account_id']
|
||
if 'account_name' in first_platform:
|
||
data['account_name'] = first_platform['account_name']
|
||
|
||
serializer = self.get_serializer(instance, data=data, partial=partial)
|
||
serializer.is_valid(raise_exception=True)
|
||
self.perform_update(serializer)
|
||
|
||
# 处理多平台信息
|
||
# 这里我们需要实现新的逻辑来处理额外的平台
|
||
# 注意:这需要修改模型结构或添加关联模型来支持多平台
|
||
# 由于当前模型结构限制,我们暂时只能在此记录其他平台数据
|
||
# 用于未来扩展,目前会在日志中记录这些信息
|
||
if platforms_data and len(platforms_data) > 1:
|
||
logger = logging.getLogger(__name__)
|
||
logger.info(f"接收到多平台数据,但当前版本仅支持一个平台。额外平台数据: {platforms_data[1:]}")
|
||
|
||
# 这里应该添加创建关联平台记录的代码
|
||
# 例如:
|
||
# for platform_data in platforms_data[1:]:
|
||
# RelatedPlatform.objects.create(
|
||
# primary_account=instance,
|
||
# platform_name=platform_data.get('platform_name', ''),
|
||
# account_id=platform_data.get('account_id', ''),
|
||
# account_name=platform_data.get('account_name', ''),
|
||
# account_url=platform_data.get('account_url', '')
|
||
# )
|
||
|
||
# 处理数据结构
|
||
account_data = serializer.data
|
||
# 提取平台信息并放入platforms字段
|
||
platform_info = {
|
||
"platform_name": account_data.pop("platform_name"),
|
||
"account_url": account_data.pop("account_url"),
|
||
"account_id": account_data.pop("account_id"),
|
||
"account_name": account_data.pop("account_name")
|
||
}
|
||
# 添加platforms字段
|
||
# 如果有platforms_data,使用原始请求中的数据,否则使用当前的单平台数据
|
||
if platforms_data:
|
||
account_data["platforms"] = platforms_data
|
||
else:
|
||
account_data["platforms"] = [platform_info]
|
||
|
||
# 保留用户传入的name字段,如果没有则使用platform_name
|
||
if not account_data.get("name"):
|
||
account_data["name"] = platform_info["platform_name"]
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "更新平台账号信息成功",
|
||
"data": account_data
|
||
})
|
||
|
||
def partial_update(self, request, *args, **kwargs):
|
||
"""部分更新平台账号信息"""
|
||
kwargs['partial'] = True
|
||
return self.update(request, *args, **kwargs)
|
||
|
||
def create(self, request, *args, **kwargs):
|
||
"""创建平台账号"""
|
||
# 传统单平台账号创建流程
|
||
print(f"{request.data}")
|
||
with transaction.atomic():
|
||
# 处理operator字段,可能是字符串类型的ID
|
||
data = request.data.copy()
|
||
if 'operator' in data and isinstance(data['operator'], str):
|
||
try:
|
||
# 尝试通过ID查找运营账号
|
||
operator_id = data['operator']
|
||
try:
|
||
# 先尝试通过整数ID查找
|
||
operator_id_int = int(operator_id)
|
||
operator = OperatorAccount.objects.get(id=operator_id_int)
|
||
except (ValueError, OperatorAccount.DoesNotExist):
|
||
# 如果无法转换为整数或找不到对应账号,尝试通过用户名或真实姓名查找
|
||
operator = OperatorAccount.objects.filter(
|
||
Q(username=operator_id) | Q(real_name=operator_id)
|
||
).first()
|
||
|
||
if not operator:
|
||
return Response({
|
||
"code": 404,
|
||
"message": f"未找到运营账号: {operator_id},请提供有效的ID、用户名或真实姓名",
|
||
"data": None
|
||
}, status=status.HTTP_404_NOT_FOUND)
|
||
|
||
# 更新请求数据中的operator字段为找到的operator的ID
|
||
data['operator'] = operator.id
|
||
|
||
except Exception as e:
|
||
return Response({
|
||
"code": 400,
|
||
"message": f"处理运营账号ID时出错: {str(e)}",
|
||
"data": None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 创建平台账号
|
||
serializer = self.get_serializer(data=data)
|
||
serializer.is_valid(raise_exception=True)
|
||
|
||
# 创建平台账号
|
||
self.perform_create(serializer)
|
||
|
||
# 处理响应数据
|
||
account_data = serializer.data
|
||
# 提取平台信息并放入platforms字段
|
||
platform_info = {
|
||
"platform_name": account_data.pop("platform_name"),
|
||
"account_url": account_data.pop("account_url"),
|
||
"account_id": account_data.pop("account_id"),
|
||
"account_name": account_data.pop("account_name")
|
||
}
|
||
# 添加platforms字段
|
||
account_data["platforms"] = [platform_info]
|
||
# 保留用户传入的name字段,如果没有则使用platform_name
|
||
if not account_data.get("name"):
|
||
account_data["name"] = platform_info["platform_name"]
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "平台账号创建成功",
|
||
"data": account_data
|
||
}, status=status.HTTP_201_CREATED)
|
||
|
||
def destroy(self, request, *args, **kwargs):
|
||
"""删除平台账号"""
|
||
platform_account = self.get_object()
|
||
self.perform_destroy(platform_account)
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "平台账号已删除",
|
||
"data": None
|
||
})
|
||
|
||
@action(detail=True, methods=['post'])
|
||
def update_followers(self, request, pk=None):
|
||
"""更新平台账号粉丝数"""
|
||
platform_account = self.get_object()
|
||
followers_count = request.data.get('followers_count')
|
||
|
||
if not followers_count:
|
||
return Response({
|
||
"code": 400,
|
||
"message": "粉丝数不能为空",
|
||
"data": None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 更新粉丝数
|
||
platform_account.followers_count = followers_count
|
||
platform_account.save()
|
||
|
||
# 准备响应数据,与其他方法保持一致
|
||
platform_data = self.get_serializer(platform_account).data
|
||
# 提取平台信息并放入platforms字段
|
||
platform_info = {
|
||
"platform_name": platform_data.pop("platform_name"),
|
||
"account_url": platform_data.pop("account_url"),
|
||
"account_id": platform_data.pop("account_id"),
|
||
"account_name": platform_data.pop("account_name")
|
||
}
|
||
# 添加platforms字段
|
||
platform_data["platforms"] = [platform_info]
|
||
# 保留用户传入的name字段,如果没有则使用platform_name
|
||
if not platform_data.get("name"):
|
||
platform_data["name"] = platform_info["platform_name"]
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "粉丝数更新成功",
|
||
"data": platform_data
|
||
})
|
||
|
||
@action(detail=True, methods=['post'])
|
||
def update_profile(self, request, pk=None):
|
||
"""更新平台账号的头像、标签和最后发布时间"""
|
||
platform_account = self.get_object()
|
||
|
||
# 获取更新的资料数据
|
||
profile_data = {}
|
||
|
||
# 处理标签
|
||
if 'tags' in request.data:
|
||
# 处理tags,支持字符串或数组格式
|
||
tags = request.data['tags']
|
||
if isinstance(tags, list):
|
||
profile_data['tags'] = ','.join(tags)
|
||
else:
|
||
profile_data['tags'] = tags
|
||
|
||
# 处理头像
|
||
if 'profile_image' in request.data:
|
||
profile_data['profile_image'] = request.data['profile_image']
|
||
|
||
# 处理最后发布时间
|
||
if 'last_posting' in request.data:
|
||
try:
|
||
# 尝试解析时间字符串
|
||
from dateutil import parser
|
||
last_posting = parser.parse(request.data['last_posting'])
|
||
profile_data['last_posting'] = last_posting
|
||
except Exception as e:
|
||
return Response({
|
||
"code": 400,
|
||
"message": f"最后发布时间格式错误: {str(e)}",
|
||
"data": None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 处理名称
|
||
if 'name' in request.data:
|
||
profile_data['name'] = request.data['name']
|
||
|
||
if not profile_data:
|
||
return Response({
|
||
"code": 400,
|
||
"message": "没有提供任何需更新的资料数据",
|
||
"data": None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 更新平台账号资料
|
||
for field, value in profile_data.items():
|
||
setattr(platform_account, field, value)
|
||
platform_account.save()
|
||
|
||
# 准备响应数据,与其他方法保持一致
|
||
platform_data = self.get_serializer(platform_account).data
|
||
# 提取平台信息并放入platforms字段
|
||
platform_info = {
|
||
"platform_name": platform_data.pop("platform_name"),
|
||
"account_url": platform_data.pop("account_url"),
|
||
"account_id": platform_data.pop("account_id"),
|
||
"account_name": platform_data.pop("account_name")
|
||
}
|
||
# 添加platforms字段
|
||
platform_data["platforms"] = [platform_info]
|
||
# 保留用户传入的name字段,如果没有则使用platform_name
|
||
if not platform_data.get("name"):
|
||
platform_data["name"] = platform_info["platform_name"]
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "平台账号资料更新成功",
|
||
"data": platform_data
|
||
})
|
||
|
||
|
||
class VideoViewSet(viewsets.ModelViewSet):
|
||
"""视频管理视图集"""
|
||
queryset = Video.objects.all()
|
||
serializer_class = VideoSerializer
|
||
pagination_class = CustomPagination
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
"""获取视频列表"""
|
||
queryset = self.filter_queryset(self.get_queryset())
|
||
page = self.paginate_queryset(queryset)
|
||
|
||
if page is not None:
|
||
serializer = self.get_serializer(page, many=True)
|
||
# 使用自定义分页器的响应
|
||
return self.get_paginated_response(serializer.data)
|
||
|
||
serializer = self.get_serializer(queryset, many=True)
|
||
return Response({
|
||
"code": 200,
|
||
"message": "获取视频列表成功",
|
||
"data": serializer.data
|
||
})
|
||
|
||
def retrieve(self, request, *args, **kwargs):
|
||
"""获取视频详情"""
|
||
instance = self.get_object()
|
||
serializer = self.get_serializer(instance)
|
||
return Response({
|
||
"code": 200,
|
||
"message": "获取视频详情成功",
|
||
"data": serializer.data
|
||
})
|
||
|
||
def update(self, request, *args, **kwargs):
|
||
"""更新视频信息"""
|
||
partial = kwargs.pop('partial', False)
|
||
instance = self.get_object()
|
||
serializer = self.get_serializer(instance, data=request.data, partial=partial)
|
||
serializer.is_valid(raise_exception=True)
|
||
self.perform_update(serializer)
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "更新视频信息成功",
|
||
"data": serializer.data
|
||
})
|
||
|
||
def partial_update(self, request, *args, **kwargs):
|
||
"""部分更新视频信息"""
|
||
kwargs['partial'] = True
|
||
return self.update(request, *args, **kwargs)
|
||
|
||
def create(self, request, *args, **kwargs):
|
||
"""创建视频"""
|
||
with transaction.atomic():
|
||
# 处理platform_account字段,可能是字符串类型的ID
|
||
data = request.data.copy()
|
||
if 'platform_account' in data and isinstance(data['platform_account'], str):
|
||
try:
|
||
# 尝试通过ID查找平台账号
|
||
platform_id = data['platform_account']
|
||
try:
|
||
# 先尝试通过整数ID查找
|
||
platform_id_int = int(platform_id)
|
||
platform = PlatformAccount.objects.get(id=platform_id_int)
|
||
except (ValueError, PlatformAccount.DoesNotExist):
|
||
# 如果无法转换为整数或找不到对应账号,尝试通过账号名称或账号ID查找
|
||
platform = PlatformAccount.objects.filter(
|
||
Q(account_name=platform_id) | Q(account_id=platform_id)
|
||
).first()
|
||
|
||
if not platform:
|
||
return Response({
|
||
"code": 404,
|
||
"message": f"未找到平台账号: {platform_id},请提供有效的ID、账号名称或账号ID",
|
||
"data": None
|
||
}, status=status.HTTP_404_NOT_FOUND)
|
||
|
||
# 更新请求数据中的platform_account字段为找到的platform的ID
|
||
data['platform_account'] = platform.id
|
||
|
||
except Exception as e:
|
||
return Response({
|
||
"code": 400,
|
||
"message": f"处理平台账号ID时出错: {str(e)}",
|
||
"data": None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 创建视频
|
||
serializer = self.get_serializer(data=data)
|
||
serializer.is_valid(raise_exception=True)
|
||
|
||
# 创建视频
|
||
self.perform_create(serializer)
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "视频创建成功",
|
||
"data": serializer.data
|
||
}, status=status.HTTP_201_CREATED)
|
||
|
||
def destroy(self, request, *args, **kwargs):
|
||
"""删除视频记录"""
|
||
video = self.get_object()
|
||
self.perform_destroy(video)
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "视频记录已删除",
|
||
"data": None
|
||
})
|
||
|
||
@action(detail=True, methods=['post'])
|
||
def update_stats(self, request, pk=None):
|
||
"""更新视频统计数据"""
|
||
video = self.get_object()
|
||
|
||
# 获取更新的统计数据
|
||
stats = {}
|
||
for field in ['views_count', 'likes_count', 'comments_count', 'shares_count']:
|
||
if field in request.data:
|
||
stats[field] = request.data[field]
|
||
|
||
if not stats:
|
||
return Response({
|
||
"code": 400,
|
||
"message": "没有提供任何统计数据",
|
||
"data": None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 更新视频统计数据
|
||
for field, value in stats.items():
|
||
setattr(video, field, value)
|
||
video.save()
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "视频统计数据更新成功",
|
||
"data": {
|
||
"id": video.id,
|
||
"title": video.title,
|
||
"views_count": video.views_count,
|
||
"likes_count": video.likes_count,
|
||
"comments_count": video.comments_count,
|
||
"shares_count": video.shares_count
|
||
}
|
||
})
|
||
|
||
@action(detail=True, methods=['post'])
|
||
def publish(self, request, pk=None):
|
||
"""发布视频并更新状态"""
|
||
video = self.get_object()
|
||
|
||
# 检查视频状态
|
||
if video.status not in ['draft', 'scheduled']:
|
||
return Response({
|
||
"code": 400,
|
||
"message": f"当前视频状态为 {video.get_status_display()},无法发布",
|
||
"data": None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 获取视频URL
|
||
video_url = request.data.get('video_url')
|
||
if not video_url:
|
||
return Response({
|
||
"code": 400,
|
||
"message": "未提供视频URL",
|
||
"data": None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 更新视频状态和URL
|
||
video.video_url = video_url
|
||
video.status = 'published'
|
||
video.publish_time = timezone.now()
|
||
video.save()
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "视频已成功发布",
|
||
"data": {
|
||
"id": video.id,
|
||
"title": video.title,
|
||
"status": video.status,
|
||
"video_url": video.video_url,
|
||
"publish_time": video.publish_time
|
||
}
|
||
})
|
||
|
||
@action(detail=False, methods=['post'])
|
||
def upload_video(self, request):
|
||
"""上传视频文件并创建视频记录"""
|
||
try:
|
||
# 获取上传的视频文件
|
||
video_file = request.FILES.get('video_file')
|
||
if not video_file:
|
||
return Response({
|
||
"code": 400,
|
||
"message": "未提供视频文件",
|
||
"data": None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 获取平台账号ID
|
||
platform_account_id = request.data.get('platform_account')
|
||
if not platform_account_id:
|
||
return Response({
|
||
"code": 400,
|
||
"message": "未提供平台账号ID",
|
||
"data": None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
try:
|
||
platform_account = PlatformAccount.objects.get(id=platform_account_id)
|
||
except PlatformAccount.DoesNotExist:
|
||
return Response({
|
||
"code": 404,
|
||
"message": f"未找到ID为{platform_account_id}的平台账号",
|
||
"data": None
|
||
}, status=status.HTTP_404_NOT_FOUND)
|
||
|
||
# 创建保存视频的目录
|
||
import os
|
||
from django.conf import settings
|
||
|
||
# 确保文件保存目录存在
|
||
media_root = getattr(settings, 'MEDIA_ROOT', os.path.join(settings.BASE_DIR, 'media'))
|
||
videos_dir = os.path.join(media_root, 'videos')
|
||
account_dir = os.path.join(videos_dir, f"{platform_account.platform_name}_{platform_account.account_name}")
|
||
|
||
if not os.path.exists(videos_dir):
|
||
os.makedirs(videos_dir)
|
||
if not os.path.exists(account_dir):
|
||
os.makedirs(account_dir)
|
||
|
||
# 生成唯一的文件名
|
||
import time
|
||
timestamp = int(time.time())
|
||
file_name = f"{timestamp}_{video_file.name}"
|
||
file_path = os.path.join(account_dir, file_name)
|
||
|
||
# 保存视频文件
|
||
with open(file_path, 'wb+') as destination:
|
||
for chunk in video_file.chunks():
|
||
destination.write(chunk)
|
||
|
||
# 创建视频记录
|
||
video_data = {
|
||
'platform_account': platform_account,
|
||
'title': request.data.get('title', os.path.splitext(video_file.name)[0]),
|
||
'description': request.data.get('description', ''),
|
||
'local_path': file_path,
|
||
'status': 'draft',
|
||
'tags': request.data.get('tags', '')
|
||
}
|
||
|
||
# 创建视频记录
|
||
video = Video.objects.create(**video_data)
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "视频上传成功",
|
||
"data": {
|
||
"id": video.id,
|
||
"title": video.title,
|
||
"status": video.get_status_display(),
|
||
}
|
||
}, status=status.HTTP_201_CREATED)
|
||
|
||
except Exception as e:
|
||
logger.error(f"视频上传失败: {str(e)}")
|
||
return Response({
|
||
"code": 500,
|
||
"message": f"视频上传失败: {str(e)}",
|
||
"data": None
|
||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||
|
||
@action(detail=True, methods=['post'])
|
||
def manual_publish(self, request, pk=None):
|
||
"""手动发布视频"""
|
||
video = self.get_object()
|
||
|
||
# 检查视频状态是否允许发布
|
||
if video.status not in ['draft', 'scheduled']:
|
||
return Response({
|
||
"code": 400,
|
||
"message": f"当前视频状态为 {video.get_status_display()},无法发布",
|
||
"data": None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 检查视频文件是否存在
|
||
if video.local_path and not os.path.exists(video.local_path):
|
||
return Response({
|
||
"code": 400,
|
||
"message": "视频文件不存在,无法发布",
|
||
"data": None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
try:
|
||
# 获取视频URL,如果没有提供,则创建一个模拟的URL
|
||
video_url = request.data.get('video_url')
|
||
|
||
if not video_url:
|
||
# 创建模拟的视频URL和ID
|
||
platform_account = video.platform_account
|
||
platform_name = platform_account.platform_name
|
||
video_url = f"https://example.com/{platform_name}/{video.id}"
|
||
|
||
# 更新视频状态
|
||
video.status = 'published'
|
||
video.publish_time = timezone.now()
|
||
video.video_url = video_url
|
||
video.video_id = f"VID_{video.id}"
|
||
video.save()
|
||
|
||
logger.info(f"视频 {video.id} 已手动发布")
|
||
|
||
return Response({
|
||
"code": 200,
|
||
"message": "视频发布成功",
|
||
"data": {
|
||
"id": video.id,
|
||
"title": video.title,
|
||
"status": "published",
|
||
"video_url": video_url,
|
||
"publish_time": video.publish_time.strftime("%Y-%m-%d %H:%M:%S")
|
||
}
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"手动发布视频失败: {str(e)}")
|
||
return Response({
|
||
"code": 500,
|
||
"message": f"发布失败: {str(e)}",
|
||
"data": None
|
||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|