aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2020-01-08 14:15:16 +0100
committerChocobozzz <me@florianbigard.com>2020-01-08 14:15:16 +0100
commitfe98765624cdd6695739bda719fcb726b71c2b2a (patch)
tree18b19d427e5c25fc9e5290062f307e668f4c9e45
parentddc07312b041c1c533b68a919681fc9bce83430d (diff)
downloadPeerTube-fe98765624cdd6695739bda719fcb726b71c2b2a.tar.gz
PeerTube-fe98765624cdd6695739bda719fcb726b71c2b2a.tar.zst
PeerTube-fe98765624cdd6695739bda719fcb726b71c2b2a.zip
Add ability to skip count query
-rw-r--r--server/controllers/api/accounts.ts6
-rw-r--r--server/controllers/api/overviews.ts5
-rw-r--r--server/controllers/api/users/my-subscriptions.ts7
-rw-r--r--server/controllers/api/video-channel.ts6
-rw-r--r--server/controllers/api/videos/index.ts7
-rw-r--r--server/controllers/bots.ts7
-rw-r--r--server/helpers/express-utils.ts7
-rw-r--r--server/middlewares/validators/videos/videos.ts4
-rw-r--r--server/models/video/video.ts7
-rw-r--r--server/tests/api/check-params/videos-filter.ts1
-rw-r--r--server/tests/api/check-params/videos.ts6
-rw-r--r--server/tests/api/videos/single-server.ts9
-rw-r--r--shared/extra-utils/videos/videos.ts3
13 files changed, 55 insertions, 20 deletions
diff --git a/server/controllers/api/accounts.ts b/server/controllers/api/accounts.ts
index c49da3c0a..00148ff55 100644
--- a/server/controllers/api/accounts.ts
+++ b/server/controllers/api/accounts.ts
@@ -22,7 +22,7 @@ import {
22import { AccountModel } from '../../models/account/account' 22import { AccountModel } from '../../models/account/account'
23import { AccountVideoRateModel } from '../../models/account/account-video-rate' 23import { AccountVideoRateModel } from '../../models/account/account-video-rate'
24import { VideoModel } from '../../models/video/video' 24import { VideoModel } from '../../models/video/video'
25import { buildNSFWFilter, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils' 25import { buildNSFWFilter, isUserAbleToSearchRemoteURI, getCountVideos } from '../../helpers/express-utils'
26import { VideoChannelModel } from '../../models/video/video-channel' 26import { VideoChannelModel } from '../../models/video/video-channel'
27import { JobQueue } from '../../lib/job-queue' 27import { JobQueue } from '../../lib/job-queue'
28import { logger } from '../../helpers/logger' 28import { logger } from '../../helpers/logger'
@@ -155,6 +155,7 @@ async function listAccountPlaylists (req: express.Request, res: express.Response
155async function listAccountVideos (req: express.Request, res: express.Response) { 155async function listAccountVideos (req: express.Request, res: express.Response) {
156 const account = res.locals.account 156 const account = res.locals.account
157 const followerActorId = isUserAbleToSearchRemoteURI(res) ? null : undefined 157 const followerActorId = isUserAbleToSearchRemoteURI(res) ? null : undefined
158 const countVideos = getCountVideos(req)
158 159
159 const resultList = await VideoModel.listForApi({ 160 const resultList = await VideoModel.listForApi({
160 followerActorId, 161 followerActorId,
@@ -171,7 +172,8 @@ async function listAccountVideos (req: express.Request, res: express.Response) {
171 nsfw: buildNSFWFilter(res, req.query.nsfw), 172 nsfw: buildNSFWFilter(res, req.query.nsfw),
172 withFiles: false, 173 withFiles: false,
173 accountId: account.id, 174 accountId: account.id,
174 user: res.locals.oauth ? res.locals.oauth.token.User : undefined 175 user: res.locals.oauth ? res.locals.oauth.token.User : undefined,
176 countVideos
175 }) 177 })
176 178
177 return res.json(getFormattedObjects(resultList.data, resultList.total)) 179 return res.json(getFormattedObjects(resultList.data, resultList.total))
diff --git a/server/controllers/api/overviews.ts b/server/controllers/api/overviews.ts
index 37ac152db..23706767a 100644
--- a/server/controllers/api/overviews.ts
+++ b/server/controllers/api/overviews.ts
@@ -98,10 +98,11 @@ async function getVideos (
98 sort: '-createdAt', 98 sort: '-createdAt',
99 includeLocalVideos: true, 99 includeLocalVideos: true,
100 nsfw: buildNSFWFilter(res), 100 nsfw: buildNSFWFilter(res),
101 withFiles: false 101 withFiles: false,
102 countVideos: false
102 }, where) 103 }, where)
103 104
104 const { data } = await VideoModel.listForApi(query, false) 105 const { data } = await VideoModel.listForApi(query)
105 106
106 return data.map(d => d.toFormattedJSON()) 107 return data.map(d => d.toFormattedJSON())
107} 108}
diff --git a/server/controllers/api/users/my-subscriptions.ts b/server/controllers/api/users/my-subscriptions.ts
index c52df3154..43c4c37d8 100644
--- a/server/controllers/api/users/my-subscriptions.ts
+++ b/server/controllers/api/users/my-subscriptions.ts
@@ -15,7 +15,7 @@ import {
15} from '../../../middlewares' 15} from '../../../middlewares'
16import { areSubscriptionsExistValidator, userSubscriptionsSortValidator, videosSortValidator } from '../../../middlewares/validators' 16import { areSubscriptionsExistValidator, userSubscriptionsSortValidator, videosSortValidator } from '../../../middlewares/validators'
17import { VideoModel } from '../../../models/video/video' 17import { VideoModel } from '../../../models/video/video'
18import { buildNSFWFilter } from '../../../helpers/express-utils' 18import { buildNSFWFilter, getCountVideos } from '../../../helpers/express-utils'
19import { VideoFilter } from '../../../../shared/models/videos/video-query.type' 19import { VideoFilter } from '../../../../shared/models/videos/video-query.type'
20import { ActorFollowModel } from '../../../models/activitypub/actor-follow' 20import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
21import { JobQueue } from '../../../lib/job-queue' 21import { JobQueue } from '../../../lib/job-queue'
@@ -149,6 +149,8 @@ async function getUserSubscriptions (req: express.Request, res: express.Response
149 149
150async function getUserSubscriptionVideos (req: express.Request, res: express.Response) { 150async function getUserSubscriptionVideos (req: express.Request, res: express.Response) {
151 const user = res.locals.oauth.token.User 151 const user = res.locals.oauth.token.User
152 const countVideos = getCountVideos(req)
153
152 const resultList = await VideoModel.listForApi({ 154 const resultList = await VideoModel.listForApi({
153 start: req.query.start, 155 start: req.query.start,
154 count: req.query.count, 156 count: req.query.count,
@@ -163,7 +165,8 @@ async function getUserSubscriptionVideos (req: express.Request, res: express.Res
163 filter: req.query.filter as VideoFilter, 165 filter: req.query.filter as VideoFilter,
164 withFiles: false, 166 withFiles: false,
165 followerActorId: user.Account.Actor.id, 167 followerActorId: user.Account.Actor.id,
166 user 168 user,
169 countVideos
167 }) 170 })
168 171
169 return res.json(getFormattedObjects(resultList.data, resultList.total)) 172 return res.json(getFormattedObjects(resultList.data, resultList.total))
diff --git a/server/controllers/api/video-channel.ts b/server/controllers/api/video-channel.ts
index acc5b2987..e1f37a8fb 100644
--- a/server/controllers/api/video-channel.ts
+++ b/server/controllers/api/video-channel.ts
@@ -20,7 +20,7 @@ import { videoChannelsNameWithHostValidator, videosSortValidator } from '../../m
20import { sendUpdateActor } from '../../lib/activitypub/send' 20import { sendUpdateActor } from '../../lib/activitypub/send'
21import { VideoChannelCreate, VideoChannelUpdate } from '../../../shared' 21import { VideoChannelCreate, VideoChannelUpdate } from '../../../shared'
22import { createLocalVideoChannel, federateAllVideosOfChannel } from '../../lib/video-channel' 22import { createLocalVideoChannel, federateAllVideosOfChannel } from '../../lib/video-channel'
23import { buildNSFWFilter, createReqFiles, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils' 23import { buildNSFWFilter, createReqFiles, getCountVideos, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils'
24import { setAsyncActorKeys } from '../../lib/activitypub' 24import { setAsyncActorKeys } from '../../lib/activitypub'
25import { AccountModel } from '../../models/account/account' 25import { AccountModel } from '../../models/account/account'
26import { MIMETYPES } from '../../initializers/constants' 26import { MIMETYPES } from '../../initializers/constants'
@@ -256,6 +256,7 @@ async function listVideoChannelPlaylists (req: express.Request, res: express.Res
256async function listVideoChannelVideos (req: express.Request, res: express.Response) { 256async function listVideoChannelVideos (req: express.Request, res: express.Response) {
257 const videoChannelInstance = res.locals.videoChannel 257 const videoChannelInstance = res.locals.videoChannel
258 const followerActorId = isUserAbleToSearchRemoteURI(res) ? null : undefined 258 const followerActorId = isUserAbleToSearchRemoteURI(res) ? null : undefined
259 const countVideos = getCountVideos(req)
259 260
260 const resultList = await VideoModel.listForApi({ 261 const resultList = await VideoModel.listForApi({
261 followerActorId, 262 followerActorId,
@@ -272,7 +273,8 @@ async function listVideoChannelVideos (req: express.Request, res: express.Respon
272 nsfw: buildNSFWFilter(res, req.query.nsfw), 273 nsfw: buildNSFWFilter(res, req.query.nsfw),
273 withFiles: false, 274 withFiles: false,
274 videoChannelId: videoChannelInstance.id, 275 videoChannelId: videoChannelInstance.id,
275 user: res.locals.oauth ? res.locals.oauth.token.User : undefined 276 user: res.locals.oauth ? res.locals.oauth.token.User : undefined,
277 countVideos
276 }) 278 })
277 279
278 return res.json(getFormattedObjects(resultList.data, resultList.total)) 280 return res.json(getFormattedObjects(resultList.data, resultList.total))
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index 35f0b3152..8d4ff07eb 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -48,7 +48,7 @@ import { videoCommentRouter } from './comment'
48import { rateVideoRouter } from './rate' 48import { rateVideoRouter } from './rate'
49import { ownershipVideoRouter } from './ownership' 49import { ownershipVideoRouter } from './ownership'
50import { VideoFilter } from '../../../../shared/models/videos/video-query.type' 50import { VideoFilter } from '../../../../shared/models/videos/video-query.type'
51import { buildNSFWFilter, createReqFiles } from '../../../helpers/express-utils' 51import { buildNSFWFilter, createReqFiles, getCountVideos } from '../../../helpers/express-utils'
52import { ScheduleVideoUpdateModel } from '../../../models/video/schedule-video-update' 52import { ScheduleVideoUpdateModel } from '../../../models/video/schedule-video-update'
53import { videoCaptionsRouter } from './captions' 53import { videoCaptionsRouter } from './captions'
54import { videoImportsRouter } from './import' 54import { videoImportsRouter } from './import'
@@ -495,6 +495,8 @@ async function getVideoDescription (req: express.Request, res: express.Response)
495} 495}
496 496
497async function listVideos (req: express.Request, res: express.Response) { 497async function listVideos (req: express.Request, res: express.Response) {
498 const countVideos = getCountVideos(req)
499
498 const apiOptions = await Hooks.wrapObject({ 500 const apiOptions = await Hooks.wrapObject({
499 start: req.query.start, 501 start: req.query.start,
500 count: req.query.count, 502 count: req.query.count,
@@ -508,7 +510,8 @@ async function listVideos (req: express.Request, res: express.Response) {
508 nsfw: buildNSFWFilter(res, req.query.nsfw), 510 nsfw: buildNSFWFilter(res, req.query.nsfw),
509 filter: req.query.filter as VideoFilter, 511 filter: req.query.filter as VideoFilter,
510 withFiles: false, 512 withFiles: false,
511 user: res.locals.oauth ? res.locals.oauth.token.User : undefined 513 user: res.locals.oauth ? res.locals.oauth.token.User : undefined,
514 countVideos
512 }, 'filter:api.videos.list.params') 515 }, 'filter:api.videos.list.params')
513 516
514 const resultList = await Hooks.wrapPromiseFun( 517 const resultList = await Hooks.wrapPromiseFun(
diff --git a/server/controllers/bots.ts b/server/controllers/bots.ts
index ed1040176..f3e778b04 100644
--- a/server/controllers/bots.ts
+++ b/server/controllers/bots.ts
@@ -61,17 +61,18 @@ async function getSitemapAccountUrls () {
61} 61}
62 62
63async function getSitemapLocalVideoUrls () { 63async function getSitemapLocalVideoUrls () {
64 const resultList = await VideoModel.listForApi({ 64 const { data } = await VideoModel.listForApi({
65 start: 0, 65 start: 0,
66 count: undefined, 66 count: undefined,
67 sort: 'createdAt', 67 sort: 'createdAt',
68 includeLocalVideos: true, 68 includeLocalVideos: true,
69 nsfw: buildNSFWFilter(), 69 nsfw: buildNSFWFilter(),
70 filter: 'local', 70 filter: 'local',
71 withFiles: false 71 withFiles: false,
72 countVideos: false
72 }) 73 })
73 74
74 return resultList.data.map(v => ({ 75 return data.map(v => ({
75 url: WEBSERVER.URL + '/videos/watch/' + v.uuid, 76 url: WEBSERVER.URL + '/videos/watch/' + v.uuid,
76 video: [ 77 video: [
77 { 78 {
diff --git a/server/helpers/express-utils.ts b/server/helpers/express-utils.ts
index 00f3f198b..9bf6d85a8 100644
--- a/server/helpers/express-utils.ts
+++ b/server/helpers/express-utils.ts
@@ -117,6 +117,10 @@ function isUserAbleToSearchRemoteURI (res: express.Response) {
117 (CONFIG.SEARCH.REMOTE_URI.USERS === true && user !== undefined) 117 (CONFIG.SEARCH.REMOTE_URI.USERS === true && user !== undefined)
118} 118}
119 119
120function getCountVideos (req: express.Request) {
121 return req.query.skipCount !== true
122}
123
120// --------------------------------------------------------------------------- 124// ---------------------------------------------------------------------------
121 125
122export { 126export {
@@ -125,5 +129,6 @@ export {
125 isUserAbleToSearchRemoteURI, 129 isUserAbleToSearchRemoteURI,
126 badRequest, 130 badRequest,
127 createReqFiles, 131 createReqFiles,
128 cleanUpReqFiles 132 cleanUpReqFiles,
133 getCountVideos
129} 134}
diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts
index 5e0182cc3..6733d9dec 100644
--- a/server/middlewares/validators/videos/videos.ts
+++ b/server/middlewares/validators/videos/videos.ts
@@ -381,6 +381,10 @@ const commonVideosFiltersValidator = [
381 query('filter') 381 query('filter')
382 .optional() 382 .optional()
383 .custom(isVideoFilterValid).withMessage('Should have a valid filter attribute'), 383 .custom(isVideoFilterValid).withMessage('Should have a valid filter attribute'),
384 query('skipCount')
385 .optional()
386 .customSanitizer(toBooleanOrNull)
387 .custom(isBooleanValid).withMessage('Should have a valid skip count boolean'),
384 388
385 (req: express.Request, res: express.Response, next: express.NextFunction) => { 389 (req: express.Request, res: express.Response, next: express.NextFunction) => {
386 logger.debug('Checking commons video filters query', { parameters: req.query }) 390 logger.debug('Checking commons video filters query', { parameters: req.query })
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index e85c5e38e..cd3245ee4 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -1284,8 +1284,9 @@ export class VideoModel extends Model<VideoModel> {
1284 videoPlaylistId?: number, 1284 videoPlaylistId?: number,
1285 trendingDays?: number, 1285 trendingDays?: number,
1286 user?: MUserAccountId, 1286 user?: MUserAccountId,
1287 historyOfUser?: MUserId 1287 historyOfUser?: MUserId,
1288 }, countVideos = true) { 1288 countVideos?: boolean
1289 }) {
1289 if (options.filter && options.filter === 'all-local' && !options.user.hasRight(UserRight.SEE_ALL_VIDEOS)) { 1290 if (options.filter && options.filter === 'all-local' && !options.user.hasRight(UserRight.SEE_ALL_VIDEOS)) {
1290 throw new Error('Try to filter all-local but no user has not the see all videos right') 1291 throw new Error('Try to filter all-local but no user has not the see all videos right')
1291 } 1292 }
@@ -1328,7 +1329,7 @@ export class VideoModel extends Model<VideoModel> {
1328 trendingDays 1329 trendingDays
1329 } 1330 }
1330 1331
1331 return VideoModel.getAvailableForApi(query, queryOptions, countVideos) 1332 return VideoModel.getAvailableForApi(query, queryOptions, options.countVideos)
1332 } 1333 }
1333 1334
1334 static async searchAndPopulateAccountAndServer (options: { 1335 static async searchAndPopulateAccountAndServer (options: {
diff --git a/server/tests/api/check-params/videos-filter.ts b/server/tests/api/check-params/videos-filter.ts
index 5a5668665..811756745 100644
--- a/server/tests/api/check-params/videos-filter.ts
+++ b/server/tests/api/check-params/videos-filter.ts
@@ -40,7 +40,6 @@ describe('Test videos filters', function () {
40 let server: ServerInfo 40 let server: ServerInfo
41 let userAccessToken: string 41 let userAccessToken: string
42 let moderatorAccessToken: string 42 let moderatorAccessToken: string
43 let playlistUUID: string
44 43
45 // --------------------------------------------------------------- 44 // ---------------------------------------------------------------
46 45
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts
index fa6d6f622..16ef1c505 100644
--- a/server/tests/api/check-params/videos.ts
+++ b/server/tests/api/check-params/videos.ts
@@ -75,8 +75,12 @@ describe('Test videos API validator', function () {
75 await checkBadSortPagination(server.url, path) 75 await checkBadSortPagination(server.url, path)
76 }) 76 })
77 77
78 it('Should fail with a bad skipVideos query', async function () {
79 await makeGetRequest({ url: server.url, path, statusCodeExpected: 200, query: { skipCount: 'toto' } })
80 })
81
78 it('Should success with the correct parameters', async function () { 82 it('Should success with the correct parameters', async function () {
79 await makeGetRequest({ url: server.url, path, statusCodeExpected: 200 }) 83 await makeGetRequest({ url: server.url, path, statusCodeExpected: 200, query: { skipCount: false } })
80 }) 84 })
81 }) 85 })
82 86
diff --git a/server/tests/api/videos/single-server.ts b/server/tests/api/videos/single-server.ts
index d8f394ac7..362d6b78f 100644
--- a/server/tests/api/videos/single-server.ts
+++ b/server/tests/api/videos/single-server.ts
@@ -322,6 +322,15 @@ describe('Test a single server', function () {
322 expect(videos[0].name).to.equal(videosListBase[5].name) 322 expect(videos[0].name).to.equal(videosListBase[5].name)
323 }) 323 })
324 324
325 it('Should not have the total field', async function () {
326 const res = await getVideosListPagination(server.url, 5, 6, 'name', true)
327
328 const videos = res.body.data
329 expect(res.body.total).to.not.exist
330 expect(videos.length).to.equal(1)
331 expect(videos[0].name).to.equal(videosListBase[5].name)
332 })
333
325 it('Should list and sort by name in descending order', async function () { 334 it('Should list and sort by name in descending order', async function () {
326 const res = await getVideosListSort(server.url, '-name') 335 const res = await getVideosListSort(server.url, '-name')
327 336
diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts
index c5de15552..9dec12703 100644
--- a/shared/extra-utils/videos/videos.ts
+++ b/shared/extra-utils/videos/videos.ts
@@ -248,7 +248,7 @@ function getPlaylistVideos (
248 }) 248 })
249} 249}
250 250
251function getVideosListPagination (url: string, start: number, count: number, sort?: string) { 251function getVideosListPagination (url: string, start: number, count: number, sort?: string, skipCount?: boolean) {
252 const path = '/api/v1/videos' 252 const path = '/api/v1/videos'
253 253
254 const req = request(url) 254 const req = request(url)
@@ -257,6 +257,7 @@ function getVideosListPagination (url: string, start: number, count: number, sor
257 .query({ count: count }) 257 .query({ count: count })
258 258
259 if (sort) req.query({ sort }) 259 if (sort) req.query({ sort })
260 if (skipCount) req.query({ skipCount })
260 261
261 return req.set('Accept', 'application/json') 262 return req.set('Accept', 'application/json')
262 .expect(200) 263 .expect(200)