aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers/api/videos/index.ts
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2022-03-24 13:36:47 +0100
committerChocobozzz <chocobozzz@cpy.re>2022-04-15 09:49:35 +0200
commitb211106695bb82f6c32e53306081b5262c3d109d (patch)
treefa187de1c33b0956665f5362e29af6b0f6d8bb57 /server/controllers/api/videos/index.ts
parent69d48ee30c9d47cddf0c3c047dc99a99dcb6e894 (diff)
downloadPeerTube-b211106695bb82f6c32e53306081b5262c3d109d.tar.gz
PeerTube-b211106695bb82f6c32e53306081b5262c3d109d.tar.zst
PeerTube-b211106695bb82f6c32e53306081b5262c3d109d.zip
Support video views/viewers stats in server
* Add "currentTime" and "event" body params to view endpoint * Merge watching and view endpoints * Introduce WatchAction AP activity * Add tables to store viewer information of local videos * Add endpoints to fetch video views/viewers stats of local videos * Refactor views/viewers handlers * Support "views" and "viewers" counters for both VOD and live videos
Diffstat (limited to 'server/controllers/api/videos/index.ts')
-rw-r--r--server/controllers/api/videos/index.ts31
1 files changed, 5 insertions, 26 deletions
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index c7617093c..be233722c 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -1,7 +1,6 @@
1import express from 'express' 1import express from 'express'
2import { pickCommonVideoQuery } from '@server/helpers/query' 2import { pickCommonVideoQuery } from '@server/helpers/query'
3import { doJSONRequest } from '@server/helpers/requests' 3import { doJSONRequest } from '@server/helpers/requests'
4import { VideoViews } from '@server/lib/video-views'
5import { openapiOperationDoc } from '@server/middlewares/doc' 4import { openapiOperationDoc } from '@server/middlewares/doc'
6import { getServerActor } from '@server/models/application/application' 5import { getServerActor } from '@server/models/application/application'
7import { guessAdditionalAttributesFromQuery } from '@server/models/video/formatter/video-format-utils' 6import { guessAdditionalAttributesFromQuery } from '@server/models/video/formatter/video-format-utils'
@@ -13,7 +12,6 @@ import { logger } from '../../../helpers/logger'
13import { getFormattedObjects } from '../../../helpers/utils' 12import { getFormattedObjects } from '../../../helpers/utils'
14import { REMOTE_SCHEME, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../initializers/constants' 13import { REMOTE_SCHEME, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../initializers/constants'
15import { sequelizeTypescript } from '../../../initializers/database' 14import { sequelizeTypescript } from '../../../initializers/database'
16import { sendView } from '../../../lib/activitypub/send/send-view'
17import { JobQueue } from '../../../lib/job-queue' 15import { JobQueue } from '../../../lib/job-queue'
18import { Hooks } from '../../../lib/plugins/hooks' 16import { Hooks } from '../../../lib/plugins/hooks'
19import { 17import {
@@ -35,28 +33,30 @@ import { VideoModel } from '../../../models/video/video'
35import { blacklistRouter } from './blacklist' 33import { blacklistRouter } from './blacklist'
36import { videoCaptionsRouter } from './captions' 34import { videoCaptionsRouter } from './captions'
37import { videoCommentRouter } from './comment' 35import { videoCommentRouter } from './comment'
38import { studioRouter } from './studio'
39import { filesRouter } from './files' 36import { filesRouter } from './files'
40import { videoImportsRouter } from './import' 37import { videoImportsRouter } from './import'
41import { liveRouter } from './live' 38import { liveRouter } from './live'
42import { ownershipVideoRouter } from './ownership' 39import { ownershipVideoRouter } from './ownership'
43import { rateVideoRouter } from './rate' 40import { rateVideoRouter } from './rate'
41import { statsRouter } from './stats'
42import { studioRouter } from './studio'
44import { transcodingRouter } from './transcoding' 43import { transcodingRouter } from './transcoding'
45import { updateRouter } from './update' 44import { updateRouter } from './update'
46import { uploadRouter } from './upload' 45import { uploadRouter } from './upload'
47import { watchingRouter } from './watching' 46import { viewRouter } from './view'
48 47
49const auditLogger = auditLoggerFactory('videos') 48const auditLogger = auditLoggerFactory('videos')
50const videosRouter = express.Router() 49const videosRouter = express.Router()
51 50
52videosRouter.use('/', blacklistRouter) 51videosRouter.use('/', blacklistRouter)
52videosRouter.use('/', statsRouter)
53videosRouter.use('/', rateVideoRouter) 53videosRouter.use('/', rateVideoRouter)
54videosRouter.use('/', videoCommentRouter) 54videosRouter.use('/', videoCommentRouter)
55videosRouter.use('/', studioRouter) 55videosRouter.use('/', studioRouter)
56videosRouter.use('/', videoCaptionsRouter) 56videosRouter.use('/', videoCaptionsRouter)
57videosRouter.use('/', videoImportsRouter) 57videosRouter.use('/', videoImportsRouter)
58videosRouter.use('/', ownershipVideoRouter) 58videosRouter.use('/', ownershipVideoRouter)
59videosRouter.use('/', watchingRouter) 59videosRouter.use('/', viewRouter)
60videosRouter.use('/', liveRouter) 60videosRouter.use('/', liveRouter)
61videosRouter.use('/', uploadRouter) 61videosRouter.use('/', uploadRouter)
62videosRouter.use('/', updateRouter) 62videosRouter.use('/', updateRouter)
@@ -103,11 +103,6 @@ videosRouter.get('/:id',
103 asyncMiddleware(checkVideoFollowConstraints), 103 asyncMiddleware(checkVideoFollowConstraints),
104 getVideo 104 getVideo
105) 105)
106videosRouter.post('/:id/views',
107 openapiOperationDoc({ operationId: 'addView' }),
108 asyncMiddleware(videosCustomGetValidator('only-video')),
109 asyncMiddleware(viewVideo)
110)
111 106
112videosRouter.delete('/:id', 107videosRouter.delete('/:id',
113 openapiOperationDoc({ operationId: 'delVideo' }), 108 openapiOperationDoc({ operationId: 'delVideo' }),
@@ -150,22 +145,6 @@ function getVideo (_req: express.Request, res: express.Response) {
150 return res.json(video.toFormattedDetailsJSON()) 145 return res.json(video.toFormattedDetailsJSON())
151} 146}
152 147
153async function viewVideo (req: express.Request, res: express.Response) {
154 const video = res.locals.onlyVideo
155
156 const ip = req.ip
157 const success = await VideoViews.Instance.processView({ video, ip })
158
159 if (success) {
160 const serverActor = await getServerActor()
161 await sendView(serverActor, video, undefined)
162
163 Hooks.runAction('action:api.video.viewed', { video: video, ip, req, res })
164 }
165
166 return res.status(HttpStatusCode.NO_CONTENT_204).end()
167}
168
169async function getVideoDescription (req: express.Request, res: express.Response) { 148async function getVideoDescription (req: express.Request, res: express.Response) {
170 const videoInstance = res.locals.videoAll 149 const videoInstance = res.locals.videoAll
171 150