aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFlorian CUNY <poslovitch@bentobox.world>2022-05-31 16:01:11 +0200
committerGitHub <noreply@github.com>2022-05-31 16:01:11 +0200
commitc6f8ca4d6596572de981162983bd02eb2613791d (patch)
treef2ff530c1e1888202d0208837dfc928f1388a6e3
parentb0185d7351f71bbc5ccbeed5bba86a619a7de70b (diff)
downloadPeerTube-c6f8ca4d6596572de981162983bd02eb2613791d.tar.gz
PeerTube-c6f8ca4d6596572de981162983bd02eb2613791d.tar.zst
PeerTube-c6f8ca4d6596572de981162983bd02eb2613791d.zip
Added "total views" in the my channels list (#5007)
* Added "total views" in the my channels list Implements https://github.com/Chocobozzz/PeerTube/issues/4331 * Fix lint * applied suggested change * updated openAPI spec for the use "withStats" when getting video channels * applied code change * removed GROUP BY in query * Fixed test
-rw-r--r--client/src/app/+my-library/+my-video-channels/my-video-channels.component.html2
-rw-r--r--client/src/app/shared/shared-main/video-channel/video-channel.model.ts5
-rw-r--r--server/models/video/video-channel.ts13
-rw-r--r--server/tests/api/videos/video-channels.ts19
-rw-r--r--shared/models/videos/channel/video-channel.model.ts1
-rw-r--r--support/doc/api/openapi.yaml2
6 files changed, 41 insertions, 1 deletions
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html
index e7003f1e4..f17f62bba 100644
--- a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html
+++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html
@@ -36,6 +36,8 @@
36 36
37 <div i18n class="video-channel-videos">{videoChannel.videosCount, plural, =0 {No videos} =1 {1 video} other {{{ videoChannel.videosCount }} videos}}</div> 37 <div i18n class="video-channel-videos">{videoChannel.videosCount, plural, =0 {No videos} =1 {1 video} other {{{ videoChannel.videosCount }} videos}}</div>
38 38
39 <div i18n class="video-channel-views">{videoChannel.totalViews, plural, =0 {No views} =1 {1 view} other {{{ videoChannel.totalViews }} views}}</div>
40
39 <div class="video-channel-buttons"> 41 <div class="video-channel-buttons">
40 <my-edit-button label [routerLink]="[ '/manage/update', videoChannel.nameWithHost ]"></my-edit-button> 42 <my-edit-button label [routerLink]="[ '/manage/update', videoChannel.nameWithHost ]"></my-edit-button>
41 <my-delete-button label (click)="deleteVideoChannel(videoChannel)"></my-delete-button> 43 <my-delete-button label (click)="deleteVideoChannel(videoChannel)"></my-delete-button>
diff --git a/client/src/app/shared/shared-main/video-channel/video-channel.model.ts b/client/src/app/shared/shared-main/video-channel/video-channel.model.ts
index 32376bf62..62bd94349 100644
--- a/client/src/app/shared/shared-main/video-channel/video-channel.model.ts
+++ b/client/src/app/shared/shared-main/video-channel/video-channel.model.ts
@@ -27,6 +27,7 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
27 videosCount?: number 27 videosCount?: number
28 28
29 viewsPerDay?: ViewsPerDate[] 29 viewsPerDay?: ViewsPerDate[]
30 totalViews?: number
30 31
31 static GET_ACTOR_AVATAR_URL (actor: { avatars: { width: number, url?: string, path: string }[] }, size: number) { 32 static GET_ACTOR_AVATAR_URL (actor: { avatars: { width: number, url?: string, path: string }[] }, size: number) {
32 return Actor.GET_ACTOR_AVATAR_URL(actor, size) 33 return Actor.GET_ACTOR_AVATAR_URL(actor, size)
@@ -74,6 +75,10 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
74 this.viewsPerDay = hash.viewsPerDay.map(v => ({ ...v, date: new Date(v.date) })) 75 this.viewsPerDay = hash.viewsPerDay.map(v => ({ ...v, date: new Date(v.date) }))
75 } 76 }
76 77
78 if (hash.totalViews !== null && hash.totalViews !== undefined) {
79 this.totalViews = hash.totalViews
80 }
81
77 if (hash.ownerAccount) { 82 if (hash.ownerAccount) {
78 this.ownerAccount = hash.ownerAccount 83 this.ownerAccount = hash.ownerAccount
79 this.ownerBy = Actor.CREATE_BY_STRING(hash.ownerAccount.name, hash.ownerAccount.host) 84 this.ownerBy = Actor.CREATE_BY_STRING(hash.ownerAccount.name, hash.ownerAccount.host)
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts
index d6dd1b8bb..91dafbcf1 100644
--- a/server/models/video/video-channel.ts
+++ b/server/models/video/video-channel.ts
@@ -311,6 +311,16 @@ export type SummaryOptions = {
311 ')' 311 ')'
312 ), 312 ),
313 'viewsPerDay' 313 'viewsPerDay'
314 ],
315 [
316 literal(
317 '(' +
318 'SELECT COALESCE(SUM("video".views), 0) AS totalViews ' +
319 'FROM "video" ' +
320 'WHERE "video"."channelId" = "VideoChannelModel"."id"' +
321 ')'
322 ),
323 'totalViews'
314 ] 324 ]
315 ] 325 ]
316 } 326 }
@@ -766,6 +776,8 @@ ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"`
766 }) 776 })
767 } 777 }
768 778
779 const totalViews = this.get('totalViews') as number
780
769 const actor = this.Actor.toFormattedJSON() 781 const actor = this.Actor.toFormattedJSON()
770 const videoChannel = { 782 const videoChannel = {
771 id: this.id, 783 id: this.id,
@@ -779,6 +791,7 @@ ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"`
779 791
780 videosCount, 792 videosCount,
781 viewsPerDay, 793 viewsPerDay,
794 totalViews,
782 795
783 avatars: actor.avatars, 796 avatars: actor.avatars,
784 797
diff --git a/server/tests/api/videos/video-channels.ts b/server/tests/api/videos/video-channels.ts
index 6f495c42d..42e0cf431 100644
--- a/server/tests/api/videos/video-channels.ts
+++ b/server/tests/api/videos/video-channels.ts
@@ -478,6 +478,25 @@ describe('Test video channels', function () {
478 } 478 }
479 }) 479 })
480 480
481 it('Should report correct total views count', async function () {
482 // check if there's the property
483 {
484 const { data } = await servers[0].channels.listByAccount({ accountName, withStats: true })
485
486 for (const channel of data) {
487 expect(channel).to.haveOwnProperty('totalViews')
488 expect(channel.totalViews).to.be.a('number')
489 }
490 }
491
492 // Check if the totalViews count can be updated
493 {
494 const { data } = await servers[0].channels.listByAccount({ accountName, withStats: true })
495 const channelWithView = data.find(channel => channel.id === servers[0].store.channel.id)
496 expect(channelWithView.totalViews).to.equal(2)
497 }
498 })
499
481 it('Should report correct videos count', async function () { 500 it('Should report correct videos count', async function () {
482 const { data } = await servers[0].channels.listByAccount({ accountName, withStats: true }) 501 const { data } = await servers[0].channels.listByAccount({ accountName, withStats: true })
483 502
diff --git a/shared/models/videos/channel/video-channel.model.ts b/shared/models/videos/channel/video-channel.model.ts
index 58b60c177..68e2f9c4c 100644
--- a/shared/models/videos/channel/video-channel.model.ts
+++ b/shared/models/videos/channel/video-channel.model.ts
@@ -18,6 +18,7 @@ export interface VideoChannel extends Actor {
18 18
19 videosCount?: number 19 videosCount?: number
20 viewsPerDay?: ViewsPerDate[] // chronologically ordered 20 viewsPerDay?: ViewsPerDate[] // chronologically ordered
21 totalViews?: number
21 22
22 banners: ActorImage[] 23 banners: ActorImage[]
23 24
diff --git a/support/doc/api/openapi.yaml b/support/doc/api/openapi.yaml
index 294aa50ab..8521f684e 100644
--- a/support/doc/api/openapi.yaml
+++ b/support/doc/api/openapi.yaml
@@ -3602,7 +3602,7 @@ paths:
3602 - $ref: '#/components/parameters/name' 3602 - $ref: '#/components/parameters/name'
3603 - name: withStats 3603 - name: withStats
3604 in: query 3604 in: query
3605 description: include view statistics for the last 30 days (only if authentified as the account user) 3605 description: include daily view statistics for the last 30 days and total views (only if authentified as the account user)
3606 schema: 3606 schema:
3607 type: boolean 3607 type: boolean
3608 - $ref: '#/components/parameters/start' 3608 - $ref: '#/components/parameters/start'