aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-11-30 09:21:11 +0100
committerChocobozzz <florian.bigard@gmail.com>2017-11-30 09:21:11 +0100
commit1f3e9feca2caf68024168b0ea9ed39d8438fa235 (patch)
treeb77b02d11796cf435496fd22b85c430a7ed2479f
parent86d13ec2aa94ec10810ddf9c8b33314bd4968791 (diff)
downloadPeerTube-1f3e9feca2caf68024168b0ea9ed39d8438fa235.tar.gz
PeerTube-1f3e9feca2caf68024168b0ea9ed39d8438fa235.tar.zst
PeerTube-1f3e9feca2caf68024168b0ea9ed39d8438fa235.zip
Better view counter
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts31
-rw-r--r--client/src/app/videos/shared/video.service.ts6
-rw-r--r--server/controllers/api/videos/index.ts28
-rw-r--r--server/tests/api/multiple-servers.ts33
-rw-r--r--server/tests/api/single-server.ts5
-rw-r--r--server/tests/utils/videos.ts10
6 files changed, 75 insertions, 38 deletions
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts
index 2a7290cbd..b26f3092f 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -1,22 +1,18 @@
1import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core' 1import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { MetaService } from '@ngx-meta/core'
4import { NotificationsService } from 'angular2-notifications'
3import { Observable } from 'rxjs/Observable' 5import { Observable } from 'rxjs/Observable'
4import { Subscription } from 'rxjs/Subscription' 6import { Subscription } from 'rxjs/Subscription'
5
6import videojs from 'video.js' 7import videojs from 'video.js'
8import { UserVideoRateType, VideoRateType } from '../../../../../shared'
7import '../../../assets/player/peertube-videojs-plugin' 9import '../../../assets/player/peertube-videojs-plugin'
8
9import { MetaService } from '@ngx-meta/core'
10import { NotificationsService } from 'angular2-notifications'
11
12import { AuthService, ConfirmService } from '../../core' 10import { AuthService, ConfirmService } from '../../core'
11import { VideoBlacklistService } from '../../shared'
12import { MarkdownService, VideoDetails, VideoService } from '../shared'
13import { VideoDownloadComponent } from './video-download.component' 13import { VideoDownloadComponent } from './video-download.component'
14import { VideoShareComponent } from './video-share.component'
15import { VideoReportComponent } from './video-report.component' 14import { VideoReportComponent } from './video-report.component'
16import { VideoDetails, VideoService, MarkdownService } from '../shared' 15import { VideoShareComponent } from './video-share.component'
17import { VideoBlacklistService } from '../../shared'
18import { UserVideoRateType, VideoRateType } from '../../../../../shared'
19import { BehaviorSubject } from 'rxjs/BehaviorSubject'
20 16
21@Component({ 17@Component({
22 selector: 'my-video-watch', 18 selector: 'my-video-watch',
@@ -320,6 +316,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
320 316
321 this.setOpenGraphTags() 317 this.setOpenGraphTags()
322 this.checkUserRating() 318 this.checkUserRating()
319
320 this.prepareViewAdd()
323 } 321 }
324 ) 322 )
325 } 323 }
@@ -360,4 +358,17 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
360 this.metaService.setTag('og:url', window.location.href) 358 this.metaService.setTag('og:url', window.location.href)
361 this.metaService.setTag('url', window.location.href) 359 this.metaService.setTag('url', window.location.href)
362 } 360 }
361
362 private prepareViewAdd () {
363 // After 30 seconds (or 3/4 of the video), increment add a view
364 let viewTimeoutSeconds = 30
365 if (this.video.duration < viewTimeoutSeconds) viewTimeoutSeconds = (this.video.duration * 3) / 4
366
367 setTimeout(() => {
368 this.videoService
369 .viewVideo(this.video.uuid)
370 .subscribe()
371
372 }, viewTimeoutSeconds * 1000)
373 }
363} 374}
diff --git a/client/src/app/videos/shared/video.service.ts b/client/src/app/videos/shared/video.service.ts
index b1ab5f8b9..5d25a26d4 100644
--- a/client/src/app/videos/shared/video.service.ts
+++ b/client/src/app/videos/shared/video.service.ts
@@ -41,6 +41,12 @@ export class VideoService {
41 .catch((res) => this.restExtractor.handleError(res)) 41 .catch((res) => this.restExtractor.handleError(res))
42 } 42 }
43 43
44 viewVideo (uuid: string): Observable<VideoDetails> {
45 return this.authHttp.post(VideoService.BASE_VIDEO_URL + uuid + '/views', {})
46 .map(this.restExtractor.extractDataBool)
47 .catch(this.restExtractor.handleError)
48 }
49
44 updateVideo (video: VideoEdit) { 50 updateVideo (video: VideoEdit) {
45 const language = video.language ? video.language : null 51 const language = video.language ? video.language : null
46 52
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index 244d91914..e2798830e 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -104,6 +104,10 @@ videosRouter.get('/:id',
104 asyncMiddleware(videosGetValidator), 104 asyncMiddleware(videosGetValidator),
105 getVideo 105 getVideo
106) 106)
107videosRouter.post('/:id/views',
108 asyncMiddleware(videosGetValidator),
109 asyncMiddleware(viewVideo)
110)
107 111
108videosRouter.delete('/:id', 112videosRouter.delete('/:id',
109 authenticate, 113 authenticate,
@@ -311,25 +315,25 @@ async function updateVideo (req: express.Request, res: express.Response) {
311 } 315 }
312} 316}
313 317
314async function getVideo (req: express.Request, res: express.Response) { 318function getVideo (req: express.Request, res: express.Response) {
319 const videoInstance = res.locals.video
320
321 return res.json(videoInstance.toFormattedDetailsJSON())
322}
323
324async function viewVideo (req: express.Request, res: express.Response) {
315 const videoInstance = res.locals.video 325 const videoInstance = res.locals.video
316 326
317 const baseIncrementPromise = videoInstance.increment('views') 327 await videoInstance.increment('views')
318 .then(() => getServerAccount()) 328 const serverAccount = await getServerAccount()
319 329
320 if (videoInstance.isOwned()) { 330 if (videoInstance.isOwned()) {
321 // The increment is done directly in the database, not using the instance value 331 await sendCreateViewToVideoFollowers(serverAccount, videoInstance, undefined)
322 baseIncrementPromise
323 .then(serverAccount => sendCreateViewToVideoFollowers(serverAccount, videoInstance, undefined))
324 .catch(err => logger.error('Cannot add view to video/send view to followers for %s.', videoInstance.uuid, err))
325 } else { 332 } else {
326 baseIncrementPromise 333 await sendCreateViewToOrigin(serverAccount, videoInstance, undefined)
327 .then(serverAccount => sendCreateViewToOrigin(serverAccount, videoInstance, undefined))
328 .catch(err => logger.error('Cannot send view to origin server for %s.', videoInstance.uuid, err))
329 } 334 }
330 335
331 // Do not wait the view system 336 return res.status(204).end()
332 return res.json(videoInstance.toFormattedDetailsJSON())
333} 337}
334 338
335async function getVideoDescription (req: express.Request, res: express.Response) { 339async function getVideoDescription (req: express.Request, res: express.Response) {
diff --git a/server/tests/api/multiple-servers.ts b/server/tests/api/multiple-servers.ts
index 052b0231f..c80ded862 100644
--- a/server/tests/api/multiple-servers.ts
+++ b/server/tests/api/multiple-servers.ts
@@ -25,6 +25,7 @@ import {
25 doubleFollow 25 doubleFollow
26} from '../utils' 26} from '../utils'
27import { createUser } from '../utils/users' 27import { createUser } from '../utils/users'
28import { viewVideo } from '../utils/videos'
28 29
29const expect = chai.expect 30const expect = chai.expect
30 31
@@ -486,10 +487,10 @@ describe('Test multiple servers', function () {
486 this.timeout(10000) 487 this.timeout(10000)
487 488
488 const tasks: Promise<any>[] = [] 489 const tasks: Promise<any>[] = []
489 tasks.push(getVideo(servers[2].url, localVideosServer3[0])) 490 tasks.push(viewVideo(servers[2].url, localVideosServer3[0]))
490 tasks.push(getVideo(servers[2].url, localVideosServer3[0])) 491 tasks.push(viewVideo(servers[2].url, localVideosServer3[0]))
491 tasks.push(getVideo(servers[2].url, localVideosServer3[0])) 492 tasks.push(viewVideo(servers[2].url, localVideosServer3[0]))
492 tasks.push(getVideo(servers[2].url, localVideosServer3[1])) 493 tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
493 494
494 await Promise.all(tasks) 495 await Promise.all(tasks)
495 496
@@ -502,8 +503,8 @@ describe('Test multiple servers', function () {
502 const video0 = videos.find(v => v.uuid === localVideosServer3[0]) 503 const video0 = videos.find(v => v.uuid === localVideosServer3[0])
503 const video1 = videos.find(v => v.uuid === localVideosServer3[1]) 504 const video1 = videos.find(v => v.uuid === localVideosServer3[1])
504 505
505 expect(video0.views).to.equal(7) 506 expect(video0.views).to.equal(3)
506 expect(video1.views).to.equal(5) 507 expect(video1.views).to.equal(1)
507 } 508 }
508 }) 509 })
509 510
@@ -511,16 +512,16 @@ describe('Test multiple servers', function () {
511 this.timeout(15000) 512 this.timeout(15000)
512 513
513 const tasks: Promise<any>[] = [] 514 const tasks: Promise<any>[] = []
514 tasks.push(getVideo(servers[0].url, remoteVideosServer1[0])) 515 tasks.push(viewVideo(servers[0].url, remoteVideosServer1[0]))
515 tasks.push(getVideo(servers[1].url, remoteVideosServer2[0])) 516 tasks.push(viewVideo(servers[1].url, remoteVideosServer2[0]))
516 tasks.push(getVideo(servers[1].url, remoteVideosServer2[0])) 517 tasks.push(viewVideo(servers[1].url, remoteVideosServer2[0]))
517 tasks.push(getVideo(servers[2].url, remoteVideosServer3[0])) 518 tasks.push(viewVideo(servers[2].url, remoteVideosServer3[0]))
518 tasks.push(getVideo(servers[2].url, remoteVideosServer3[1])) 519 tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1]))
519 tasks.push(getVideo(servers[2].url, remoteVideosServer3[1])) 520 tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1]))
520 tasks.push(getVideo(servers[2].url, remoteVideosServer3[1])) 521 tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1]))
521 tasks.push(getVideo(servers[2].url, localVideosServer3[1])) 522 tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
522 tasks.push(getVideo(servers[2].url, localVideosServer3[1])) 523 tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
523 tasks.push(getVideo(servers[2].url, localVideosServer3[1])) 524 tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
524 525
525 await Promise.all(tasks) 526 await Promise.all(tasks)
526 527
diff --git a/server/tests/api/single-server.ts b/server/tests/api/single-server.ts
index 40e2c64fe..041d13225 100644
--- a/server/tests/api/single-server.ts
+++ b/server/tests/api/single-server.ts
@@ -33,6 +33,7 @@ import {
33 searchVideoWithSort, 33 searchVideoWithSort,
34 updateVideo 34 updateVideo
35} from '../utils' 35} from '../utils'
36import { viewVideo } from '../utils/videos'
36 37
37describe('Test a single server', function () { 38describe('Test a single server', function () {
38 let server: ServerInfo = null 39 let server: ServerInfo = null
@@ -214,6 +215,10 @@ describe('Test a single server', function () {
214 }) 215 })
215 216
216 it('Should have the views updated', async function () { 217 it('Should have the views updated', async function () {
218 await viewVideo(server.url, videoId)
219 await viewVideo(server.url, videoId)
220 await viewVideo(server.url, videoId)
221
217 const res = await getVideo(server.url, videoId) 222 const res = await getVideo(server.url, videoId)
218 223
219 const video = res.body 224 const video = res.body
diff --git a/server/tests/utils/videos.ts b/server/tests/utils/videos.ts
index dababe924..73a9f1a0a 100644
--- a/server/tests/utils/videos.ts
+++ b/server/tests/utils/videos.ts
@@ -55,6 +55,15 @@ function getVideo (url: string, id: number | string, expectedStatus = 200) {
55 .expect(expectedStatus) 55 .expect(expectedStatus)
56} 56}
57 57
58function viewVideo (url: string, id: number | string, expectedStatus = 204) {
59 const path = '/api/v1/videos/' + id + '/views'
60
61 return request(url)
62 .post(path)
63 .set('Accept', 'application/json')
64 .expect(expectedStatus)
65}
66
58function getVideoWithToken (url: string, token: string, id: number | string, expectedStatus = 200) { 67function getVideoWithToken (url: string, token: string, id: number | string, expectedStatus = 200) {
59 const path = '/api/v1/videos/' + id 68 const path = '/api/v1/videos/' + id
60 69
@@ -313,5 +322,6 @@ export {
313 uploadVideo, 322 uploadVideo,
314 updateVideo, 323 updateVideo,
315 rateVideo, 324 rateVideo,
325 viewVideo,
316 parseTorrentVideo 326 parseTorrentVideo
317} 327}