点播后台接口

This commit is contained in:
caoqianming 2021-06-28 10:47:25 +08:00
parent ac85dc2486
commit 0eb76f9403
6 changed files with 215 additions and 22 deletions

View File

@ -0,0 +1,58 @@
# Generated by Django 3.0.5 on 2021-06-28 01:59
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('system', '0018_auto_20210430_1156'),
]
operations = [
migrations.CreateModel(
name='Video',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('name', models.CharField(max_length=100, verbose_name='视频名称')),
('description', models.TextField(default='', verbose_name='视频描述')),
('mediaurl', models.CharField(max_length=200, verbose_name='视频地址')),
('coverurl', models.CharField(max_length=200, verbose_name='封面地址')),
('duration', models.IntegerField(default=0, verbose_name='时长(秒)')),
('views', models.IntegerField(default=0, verbose_name='观看次数')),
('category', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='system.Dict', verbose_name='视频分类')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='video_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='video_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'verbose_name': '点播视频',
'verbose_name_plural': '点播视频',
},
),
migrations.CreateModel(
name='ViewRecord',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('num', models.IntegerField(default=0, verbose_name='观看次数')),
('current', models.IntegerField(default=0, verbose_name='当前观看进度')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='viewrecord_user', to=settings.AUTH_USER_MODEL, verbose_name='观看人')),
('video', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vod.Video', verbose_name='点播视频')),
],
options={
'verbose_name': '点播观看记录',
'verbose_name_plural': '点播观看记录',
},
),
]

View File

@ -6,21 +6,28 @@ from apps.system.models import User, CommonAModel, Dict
class Video(CommonAModel):
name = models.CharField(verbose_name='视频名称', max_length=100)
category = models.ForeignKey(Dict, verbose_name='视频分类')
description = models.TextField(verbose_name='视频描述')
category = models.ForeignKey(Dict, verbose_name='视频分类', on_delete=models.DO_NOTHING)
description = models.TextField(verbose_name='视频描述', default='')
mediaurl = models.CharField(verbose_name='视频地址', max_length=200)
coverurl = models.CharField(verbose_name='封面地址', max_length=200)
duration = models.IntegerField(verbose_name='时长(秒)', default=0)
views = models.IntegerField(verbose_name='观看次数', default=0)
class Meta:
verbose_name = '点播视频'
verbose_name_plural = verbose_name
class WatchRecord(BaseModel):
class ViewRecord(BaseModel):
# 观看记录
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='观看人')
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='观看人', related_name='viewrecord_user')
num = models.IntegerField(verbose_name='观看次数', default=0)
total = models.IntegerField(verbose_name='观看总时长', default=0)
current = models.IntegerField(verbose_name='当前观看进度', default=0)
video = models.ForeignKey(Video, verbose_name='点播视频', on_delete=models.CASCADE)
vod_id = models.CharField(verbose_name='视频id', max_length=100)
vod_title = models.CharField(verbose_name='视频标题', max_length=100)
vod_cover = models.CharField(verbose_name='视频封面地址', max_length=200)
class Meta:
verbose_name = '点播观看记录'

View File

@ -0,0 +1,26 @@
from rest_framework import serializers
from .models import Video, ViewRecord
from apps.system.serializers import UserSimpleSerializer
class VideoSerializer(serializers.ModelSerializer):
category_name = serializers.StringRelatedField(source='category', read_only=True)
class Meta:
model = Video
fields = '__all__'
class VideoSimpleSerializer(serializers.ModelSerializer):
class Meta:
model = Video
fields = ['id', 'name', 'duration']
class VRecordSerializer(serializers.ModelSerializer):
user_ = UserSimpleSerializer(source='user', read_only=True)
video_ = VideoSimpleSerializer(source='video', read_only=True)
class Meta:
model = ViewRecord
fields = '__all__'
class VRecordUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = ViewRecord
fields=['num', 'current']

View File

@ -1,9 +1,13 @@
from django.db.models import base
from django.urls import path, include
from .views import ClassView, VideoView
from .views import ClassView, SignatureAPIView, VideoView, VideoViewSet, VRecordViewSet, MyViewRecordAPIView
from rest_framework import routers
router = routers.DefaultRouter()
router.register('video', VideoViewSet, basename="video")
router.register('viewrecord', VRecordViewSet, basename='viewrecord')
urlpatterns = [
path('class/', ClassView.as_view()),
path('video/', VideoView.as_view())
path('', include(router.urls)),
path('video/<int:id>/myview/', MyViewRecordAPIView.as_view()),
path('signature/', SignatureAPIView.as_view()),
]

View File

@ -1,8 +1,16 @@
from rest_framework.mixins import ListModelMixin
from apps.vod.serializers import VRecordSerializer, VRecordUpdateSerializer, VideoSerializer
from apps.vod.models import Video, ViewRecord
from django.shortcuts import render
from .vodclient import getAllClass, searchMedia
from .vodclient import getAllClass, searchMedia, getSignature
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from utils.pagination import PageOrNot
from apps.system.mixins import CreateUpdateModelAMixin
from rest_framework.decorators import action, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.status import HTTP_400_BAD_REQUEST
# Create your views here.
class ClassView(APIView):
@ -28,5 +36,70 @@ class VideoView(APIView):
params['ClassIds']= request.query_params.getlist('classid') if request.query_params.get('classid') else []
return searchMedia(params)
class RecordViewSet(ModelViewSet):
pass
class VideoViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
perms_map={'get':'video_view', 'post':'video_create', 'put':'video_update', 'delete':'video_delete'}
queryset = Video.objects.all()
search_fields = ['name', 'category__name', 'description']
filterset_fields = ['category']
serializer_class = VideoSerializer
ordering = ['-views', '-create_time']
@action(methods=['get'], detail=False, perms_map={'get':'video_view'})
def myview(self, request, *args, **kwargs):
"""
个人观看记录
"""
queryset = ViewRecord.objects.filter(user=request.user)
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(serializer.data)
class VRecordViewSet(ListModelMixin, GenericViewSet):
perms_map = {'get':'viewrecord_view'}
queryset = ViewRecord.objects.all()
search_fields = ['user__name', 'video__name']
serializer_class = VRecordSerializer
ordering = ['-update_time']
class MyViewRecordAPIView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request, id , format=None):
"""
该视频的本人观看信息
"""
try:
video = Video.objects.get(pk=id)
except:
return Response('视频不存在', status=HTTP_400_BAD_REQUEST)
record = ViewRecord.objects.get_or_create(video=video, user=request.user, defaults={'video':video, 'user':request.user})
serializer = VRecordSerializer(instance=record)
return Response(serializer.data)
def put(self, request, id, format=None):
"""
更新该视频本人的观看信息
"""
try:
video = Video.objects.get(pk=id)
except:
return Response('视频不存在', status=HTTP_400_BAD_REQUEST)
record = ViewRecord.objects.get_or_create(video=video, user=request.user, defaults={'video':video, 'user':request.user})
serializer = VRecordUpdateSerializer(record, data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
class SignatureAPIView(APIView):
perms_map={'get':'video_create'}
def get(self, request, format=None):
"""
获取上传签名
"""
return Response(getSignature(procedure=request.query_params.get('procedure', None)))

View File

@ -1,11 +1,19 @@
import base64
import hashlib
import hmac
import json
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.vod.v20180717 import vod_client, models
import random
import time
from rest_framework.response import Response
from rest_framework.status import HTTP_400_BAD_REQUEST
from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import \
TencentCloudSDKException
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.vod.v20180717 import models, vod_client
SecretId = 'AKIDhDTaV9WeXAXcQxEH4buwg9LGvJQHr9Au'
SecretKey = 'VjfKjrhGYrte8MIxMUMxHL9h39zYqrc6'
@ -45,4 +53,21 @@ def searchMedia(params={}):
resp = client.SearchMedia(req)
return doResponse(resp)
except TencentCloudSDKException as err:
print(err)
print(err)
def getSignature(procedure=None):
"""
获取上传签名
可指定
"""
TimeStamp = int(time.time())
ExpireTime = TimeStamp + 86400 * 365 * 10
Random = random.randint(0, 999999)
Original = "secretId=" + SecretId + "&currentTimeStamp=" + str(TimeStamp) + "&expireTime=" + str(ExpireTime) + "&random=" + str(Random)
if procedure:
Original = Original + "&procedure="+procedure
Hmac = hmac.new(bytes(SecretKey, 'utf-8'), bytes(Original, 'utf-8'), hashlib.sha1)
Sha1 = Hmac.digest()
Signature = bytes(Sha1) + bytes(Original, 'utf-8')
Signature2 = base64.b64encode(Signature)
return str(Signature2)