tmp: '/var/www/peertube/storage/tmp/' # Used to download data (imports etc), store uploaded files before processing...
avatars: '/var/www/peertube/storage/avatars/'
videos: '/var/www/peertube/storage/videos/'
- playlists: '/var/www/peertube/storage/playlists/'
+ streaming_playlists: '/var/www/peertube/storage/streaming-playlists/'
redundancy: '/var/www/peertube/storage/videos/'
logs: '/var/www/peertube/storage/logs/'
previews: '/var/www/peertube/storage/previews/'
tmp: 'test1/tmp/'
avatars: 'test1/avatars/'
videos: 'test1/videos/'
- playlists: 'test1/playlists/'
+ streaming_playlists: 'test1/streaming-playlists/'
redundancy: 'test1/redundancy/'
logs: 'test1/logs/'
previews: 'test1/previews/'
tmp: 'test2/tmp/'
avatars: 'test2/avatars/'
videos: 'test2/videos/'
- playlists: 'test2/playlists/'
+ streaming_playlists: 'test2/streaming-playlists/'
redundancy: 'test2/redundancy/'
logs: 'test2/logs/'
previews: 'test2/previews/'
tmp: 'test3/tmp/'
avatars: 'test3/avatars/'
videos: 'test3/videos/'
- playlists: 'test3/playlists/'
+ streaming_playlists: 'test3/streaming-playlists/'
redundancy: 'test3/redundancy/'
logs: 'test3/logs/'
previews: 'test3/previews/'
tmp: 'test4/tmp/'
avatars: 'test4/avatars/'
videos: 'test4/videos/'
- playlists: 'test4/playlists/'
+ streaming_playlists: 'test4/streaming-playlists/'
redundancy: 'test4/redundancy/'
logs: 'test4/logs/'
previews: 'test4/previews/'
tmp: 'test5/tmp/'
avatars: 'test5/avatars/'
videos: 'test5/videos/'
- playlists: 'test5/playlists/'
+ streaming_playlists: 'test5/streaming-playlists/'
redundancy: 'test5/redundancy/'
logs: 'test5/logs/'
previews: 'test5/previews/'
tmp: 'test6/tmp/'
avatars: 'test6/avatars/'
videos: 'test6/videos/'
- playlists: 'test6/playlists/'
+ streaming_playlists: 'test6/streaming-playlists/'
redundancy: 'test6/redundancy/'
logs: 'test6/logs/'
previews: 'test6/previews/'
async function actorPlaylists (req: express.Request, account: AccountModel) {
const handler = (start: number, count: number) => {
- return VideoPlaylistModel.listUrlsOfForAP(account.id, start, count)
+ return VideoPlaylistModel.listPublicUrlsOfForAP(account.id, start, count)
}
return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.path, handler, req.query.page)
// ---------------------------------------------------------------------------
async function doVideosInPlaylistExist (req: express.Request, res: express.Response) {
- const videoIds = req.query.videoIds as number[]
+ const videoIds = req.query.videoIds.map(i => parseInt(i + '', 10))
const user = res.locals.oauth.token.User as UserModel
const results = await VideoPlaylistModel.listPlaylistIdsOf(user.Account.id, videoIds)
import { logger } from '../../../helpers/logger'
import { UserModel } from '../../../models/account/user'
import { areValidationErrors } from '../utils'
-import { isVideoExist, isVideoFileInfoHashValid, isVideoImage } from '../../../helpers/custom-validators/videos'
+import { isVideoExist, isVideoImage } from '../../../helpers/custom-validators/videos'
import { CONSTRAINTS_FIELDS } from '../../../initializers'
-import { isArrayOf, isIdOrUUIDValid, isIdValid, isUUIDValid, toArray, toValueOrNull, toIntArray } from '../../../helpers/custom-validators/misc'
+import { isArrayOf, isIdOrUUIDValid, isIdValid, isUUIDValid, toIntArray, toValueOrNull } from '../../../helpers/custom-validators/misc'
import {
isVideoPlaylistDescriptionValid,
isVideoPlaylistExist,
import { authenticatePromiseIfNeeded } from '../../oauth'
import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
-import { areValidActorHandles } from '../../../helpers/custom-validators/activitypub/actor'
const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
})
}
- static listUrlsOfForAP (accountId: number, start: number, count: number) {
+ static listPublicUrlsOfForAP (accountId: number, start: number, count: number) {
const query = {
attributes: [ 'url' ],
offset: start,
limit: count,
where: {
- ownerAccountId: accountId
+ ownerAccountId: accountId,
+ privacy: VideoPlaylistPrivacy.PUBLIC
}
}
})
})
+ describe('When checking exists in playlist endpoint', function () {
+ const path = '/api/v1/users/me/video-playlists/videos-exist'
+
+ it('Should fail with an unauthenticated user', async function () {
+ await makeGetRequest({
+ url: server.url,
+ path,
+ query: { videoIds: [ 1, 2 ] },
+ statusCodeExpected: 401
+ })
+ })
+
+ it('Should fail with invalid video ids', async function () {
+ await makeGetRequest({
+ url: server.url,
+ token: server.accessToken,
+ path,
+ query: { videoIds: 'toto' }
+ })
+
+ await makeGetRequest({
+ url: server.url,
+ token: server.accessToken,
+ path,
+ query: { videoIds: [ 'toto' ] }
+ })
+
+ await makeGetRequest({
+ url: server.url,
+ token: server.accessToken,
+ path,
+ query: { videoIds: [ 1, 'toto' ] }
+ })
+ })
+
+ it('Should succeed with the correct params', async function () {
+ await makeGetRequest({
+ url: server.url,
+ token: server.accessToken,
+ path,
+ query: { videoIds: [ 1, 2 ] },
+ statusCodeExpected: 200
+ })
+ })
+ })
+
describe('When deleting an element in a playlist', function () {
const getBase = (wrapper: any = {}) => {
return Object.assign({
expect(redundancy.baseUrl).to.equal(servers[0].url + '/static/redundancy/hls/' + videoUUID)
}
- const baseUrlPlaylist = servers[1].url + '/static/playlists/hls'
+ const baseUrlPlaylist = servers[1].url + '/static/streaming-playlists/hls'
const baseUrlSegment = servers[0].url + '/static/redundancy/hls'
const res = await getVideo(servers[0].url, videoUUID)
await checkSegmentHash(baseUrlPlaylist, baseUrlSegment, videoUUID, resolution, hlsPlaylist)
}
- for (const directory of [ 'test1/redundancy/hls', 'test2/playlists/hls' ]) {
+ for (const directory of [ 'test1/redundancy/hls', 'test2/streaming-playlists/hls' ]) {
const files = await readdir(join(root(), directory, videoUUID))
expect(files).to.have.length.at.least(4)
{
for (const resolution of resolutions) {
- const res2 = await getPlaylist(`http://localhost:9001/static/playlists/hls/${videoUUID}/${resolution}.m3u8`)
+ const res2 = await getPlaylist(`http://localhost:9001/static/streaming-playlists/hls/${videoUUID}/${resolution}.m3u8`)
const subPlaylist = res2.text
expect(subPlaylist).to.contain(`${videoUUID}-${resolution}-fragmented.mp4`)
}
{
- const baseUrl = 'http://localhost:9001/static/playlists/hls'
+ const baseUrl = 'http://localhost:9001/static/streaming-playlists/hls'
for (const resolution of resolutions) {
await checkSegmentHash(baseUrl, baseUrl, videoUUID, resolution, hlsPlaylist)
it('Should have the playlists/segment deleted from the disk', async function () {
for (const server of servers) {
await checkDirectoryIsEmpty(server, 'videos')
- await checkDirectoryIsEmpty(server, join('playlists', 'hls'))
+ await checkDirectoryIsEmpty(server, join('streaming-playlists', 'hls'))
}
})
createVideoPlaylist,
deleteVideoChannel,
deleteVideoPlaylist,
- doubleFollow,
+ doubleFollow, doVideosExistInMyPlaylist,
flushAndRunMultipleServers,
flushTests,
getAccountPlaylistsList,
import { VideoPlaylist } from '../../../../shared/models/videos/playlist/video-playlist.model'
import { Video } from '../../../../shared/models/videos'
import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
+import { VideoExistInPlaylist } from '../../../../shared/models/videos/playlist/video-exist-in-playlist.model'
const expect = chai.expect
}
})
+ it('Should check videos existence in my playlist', async function () {
+ const videoIds = [
+ servers[0].videos[0].id,
+ 42000,
+ servers[0].videos[3].id,
+ 43000,
+ servers[0].videos[4].id
+ ]
+ const res = await doVideosExistInMyPlaylist(servers[ 0 ].url, servers[ 0 ].accessToken, videoIds)
+ const obj = res.body as VideoExistInPlaylist
+
+ {
+ const elem = obj[servers[0].videos[0].id]
+ expect(elem).to.have.lengthOf(1)
+ expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id)
+ expect(elem[ 0 ].startTimestamp).to.equal(15)
+ expect(elem[ 0 ].stopTimestamp).to.equal(28)
+ }
+
+ {
+ const elem = obj[servers[0].videos[3].id]
+ expect(elem).to.have.lengthOf(1)
+ expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id)
+ expect(elem[ 0 ].startTimestamp).to.equal(1)
+ expect(elem[ 0 ].stopTimestamp).to.equal(35)
+ }
+
+ {
+ const elem = obj[servers[0].videos[4].id]
+ expect(elem).to.have.lengthOf(1)
+ expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id)
+ expect(elem[ 0 ].startTimestamp).to.equal(45)
+ expect(elem[ 0 ].stopTimestamp).to.equal(null)
+ }
+
+ expect(obj[42000]).to.have.lengthOf(0)
+ expect(obj[43000]).to.have.lengthOf(0)
+ })
+
it('Should delete some elements', async function () {
this.timeout(30000)
})
}
+function doVideosExistInMyPlaylist (url: string, token: string, videoIds: number[]) {
+ const path = '/api/v1/users/me/video-playlists/videos-exist'
+
+ return makeGetRequest({
+ url,
+ token,
+ path,
+ query: { videoIds },
+ statusCodeExpected: 200
+ })
+}
+
// ---------------------------------------------------------------------------
export {
reorderVideosPlaylist,
- checkPlaylistFilesWereRemoved
+ checkPlaylistFilesWereRemoved,
+
+ doVideosExistInMyPlaylist
}