aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2022-01-19 14:58:16 +0100
committerChocobozzz <me@florianbigard.com>2022-01-19 14:58:16 +0100
commitd511df28906f84c7d25ecb24e41515ed549ff276 (patch)
treebc9caa33fae684e9971068011dd10243c7d0fe60
parent419b520ca4434d17f3505013174e195c3a316716 (diff)
downloadPeerTube-d511df28906f84c7d25ecb24e41515ed549ff276.tar.gz
PeerTube-d511df28906f84c7d25ecb24e41515ed549ff276.tar.zst
PeerTube-d511df28906f84c7d25ecb24e41515ed549ff276.zip
Add ability to filter my imports by target URL
-rw-r--r--server/controllers/api/users/me.ts12
-rw-r--r--server/lib/job-queue/handlers/video-import.ts8
-rw-r--r--server/models/video/video-import.ts20
-rw-r--r--server/tests/api/videos/video-imports.ts12
-rw-r--r--server/tests/cli/peertube.ts19
-rw-r--r--shared/server-commands/videos/imports-command.ts8
6 files changed, 59 insertions, 20 deletions
diff --git a/server/controllers/api/users/me.ts b/server/controllers/api/users/me.ts
index 878dd5a84..c2ad0b710 100644
--- a/server/controllers/api/users/me.ts
+++ b/server/controllers/api/users/me.ts
@@ -30,6 +30,7 @@ import { AccountVideoRateModel } from '../../../models/account/account-video-rat
30import { UserModel } from '../../../models/user/user' 30import { UserModel } from '../../../models/user/user'
31import { VideoModel } from '../../../models/video/video' 31import { VideoModel } from '../../../models/video/video'
32import { VideoImportModel } from '../../../models/video/video-import' 32import { VideoImportModel } from '../../../models/video/video-import'
33import { pick } from '@shared/core-utils'
33 34
34const auditLogger = auditLoggerFactory('users') 35const auditLogger = auditLoggerFactory('users')
35 36
@@ -133,12 +134,11 @@ async function getUserVideos (req: express.Request, res: express.Response) {
133 134
134async function getUserVideoImports (req: express.Request, res: express.Response) { 135async function getUserVideoImports (req: express.Request, res: express.Response) {
135 const user = res.locals.oauth.token.User 136 const user = res.locals.oauth.token.User
136 const resultList = await VideoImportModel.listUserVideoImportsForApi( 137 const resultList = await VideoImportModel.listUserVideoImportsForApi({
137 user.id, 138 userId: user.id,
138 req.query.start as number, 139
139 req.query.count as number, 140 ...pick(req.query, [ 'targetUrl', 'start', 'count', 'sort' ])
140 req.query.sort 141 })
141 )
142 142
143 return res.json(getFormattedObjects(resultList.data, resultList.total)) 143 return res.json(getFormattedObjects(resultList.data, resultList.total))
144} 144}
diff --git a/server/lib/job-queue/handlers/video-import.ts b/server/lib/job-queue/handlers/video-import.ts
index cb79725aa..1630ecabd 100644
--- a/server/lib/job-queue/handlers/video-import.ts
+++ b/server/lib/job-queue/handlers/video-import.ts
@@ -42,7 +42,7 @@ import { generateVideoMiniature } from '../../thumbnail'
42async function processVideoImport (job: Job) { 42async function processVideoImport (job: Job) {
43 const payload = job.data as VideoImportPayload 43 const payload = job.data as VideoImportPayload
44 44
45 const videoImport = await getVideoImportOrDie(payload.videoImportId) 45 const videoImport = await getVideoImportOrDie(payload)
46 if (videoImport.state === VideoImportState.CANCELLED) { 46 if (videoImport.state === VideoImportState.CANCELLED) {
47 logger.info('Do not process import since it has been cancelled', { payload }) 47 logger.info('Do not process import since it has been cancelled', { payload })
48 return 48 return
@@ -89,10 +89,10 @@ async function processYoutubeDLImport (job: Job, videoImport: MVideoImportDefaul
89 ) 89 )
90} 90}
91 91
92async function getVideoImportOrDie (videoImportId: number) { 92async function getVideoImportOrDie (payload: VideoImportPayload) {
93 const videoImport = await VideoImportModel.loadAndPopulateVideo(videoImportId) 93 const videoImport = await VideoImportModel.loadAndPopulateVideo(payload.videoImportId)
94 if (!videoImport || !videoImport.Video) { 94 if (!videoImport || !videoImport.Video) {
95 throw new Error('Cannot import video %s: the video import or video linked to this import does not exist anymore.') 95 throw new Error(`Cannot import video ${payload.videoImportId}: the video import or video linked to this import does not exist anymore.`)
96 } 96 }
97 97
98 return videoImport 98 return videoImport
diff --git a/server/models/video/video-import.ts b/server/models/video/video-import.ts
index c5c1a10f4..5d2b230e8 100644
--- a/server/models/video/video-import.ts
+++ b/server/models/video/video-import.ts
@@ -1,3 +1,4 @@
1import { WhereOptions } from 'sequelize'
1import { 2import {
2 AfterUpdate, 3 AfterUpdate,
3 AllowNull, 4 AllowNull,
@@ -125,7 +126,20 @@ export class VideoImportModel extends Model<Partial<AttributesOnly<VideoImportMo
125 return VideoImportModel.findByPk(id) 126 return VideoImportModel.findByPk(id)
126 } 127 }
127 128
128 static listUserVideoImportsForApi (userId: number, start: number, count: number, sort: string) { 129 static listUserVideoImportsForApi (options: {
130 userId: number
131 start: number
132 count: number
133 sort: string
134
135 targetUrl?: string
136 }) {
137 const { userId, start, count, sort, targetUrl } = options
138
139 const where: WhereOptions = { userId }
140
141 if (targetUrl) where['targetUrl'] = targetUrl
142
129 const query = { 143 const query = {
130 distinct: true, 144 distinct: true,
131 include: [ 145 include: [
@@ -138,9 +152,7 @@ export class VideoImportModel extends Model<Partial<AttributesOnly<VideoImportMo
138 offset: start, 152 offset: start,
139 limit: count, 153 limit: count,
140 order: getSort(sort), 154 order: getSort(sort),
141 where: { 155 where
142 userId
143 }
144 } 156 }
145 157
146 return VideoImportModel.findAndCountAll<MVideoImportDefault>(query) 158 return VideoImportModel.findAndCountAll<MVideoImportDefault>(query)
diff --git a/server/tests/api/videos/video-imports.ts b/server/tests/api/videos/video-imports.ts
index ba21ab17a..28da69e8e 100644
--- a/server/tests/api/videos/video-imports.ts
+++ b/server/tests/api/videos/video-imports.ts
@@ -219,6 +219,14 @@ describe('Test video imports', function () {
219 expect(videoImports[0].video.name).to.equal('你好 世界 720p.mp4') 219 expect(videoImports[0].video.name).to.equal('你好 世界 720p.mp4')
220 }) 220 })
221 221
222 it('Should filter my imports on target URL', async function () {
223 const { total, data: videoImports } = await servers[0].imports.getMyVideoImports({ targetUrl: FIXTURE_URLS.youtube })
224 expect(total).to.equal(1)
225 expect(videoImports).to.have.lengthOf(1)
226
227 expect(videoImports[0].targetUrl).to.equal(FIXTURE_URLS.youtube)
228 })
229
222 it('Should have the video listed on the two instances', async function () { 230 it('Should have the video listed on the two instances', async function () {
223 this.timeout(120_000) 231 this.timeout(120_000)
224 232
@@ -459,6 +467,10 @@ describe('Test video imports', function () {
459 const { data } = await server.imports.getMyVideoImports() 467 const { data } = await server.imports.getMyVideoImports()
460 expect(data).to.have.lengthOf(0) 468 expect(data).to.have.lengthOf(0)
461 }) 469 })
470
471 after(async function () {
472 await cleanupTests([ server ])
473 })
462 }) 474 })
463 475
464 describe('Auto update', function () { 476 describe('Auto update', function () {
diff --git a/server/tests/cli/peertube.ts b/server/tests/cli/peertube.ts
index 034d216e3..3aa24a0f8 100644
--- a/server/tests/cli/peertube.ts
+++ b/server/tests/cli/peertube.ts
@@ -136,9 +136,26 @@ describe('Test CLI wrapper', function () {
136 expect(videoDetails.channel.name).to.equal('user_channel') 136 expect(videoDetails.channel.name).to.equal('user_channel')
137 expect(videoDetails.support).to.equal('super support text') 137 expect(videoDetails.support).to.equal('super support text')
138 expect(videoDetails.nsfw).to.be.false 138 expect(videoDetails.nsfw).to.be.false
139 })
140
141 it('Should not import again the same video', async function () {
142 if (areHttpImportTestsDisabled()) return
143
144 this.timeout(60000)
145
146 const params = `--target-url ${FIXTURE_URLS.youtube} --channel-name user_channel`
147 await cliCommand.execWithEnv(`${cmd} import ${params}`)
148
149 await waitJobs([ server ])
150
151 const { total, data } = await server.videos.list()
152 expect(total).to.equal(2)
153
154 const videos = data.filter(v => v.name === 'small video - youtube')
155 expect(videos).to.have.lengthOf(1)
139 156
140 // So we can reimport it 157 // So we can reimport it
141 await server.videos.remove({ token: userAccessToken, id: video.id }) 158 await server.videos.remove({ token: userAccessToken, id: videos[0].id })
142 }) 159 })
143 160
144 it('Should import and override some imported attributes', async function () { 161 it('Should import and override some imported attributes', async function () {
diff --git a/shared/server-commands/videos/imports-command.ts b/shared/server-commands/videos/imports-command.ts
index f63ed5d4b..c931ac481 100644
--- a/shared/server-commands/videos/imports-command.ts
+++ b/shared/server-commands/videos/imports-command.ts
@@ -56,18 +56,16 @@ export class ImportsCommand extends AbstractCommand {
56 56
57 getMyVideoImports (options: OverrideCommandOptions & { 57 getMyVideoImports (options: OverrideCommandOptions & {
58 sort?: string 58 sort?: string
59 targetUrl?: string
59 } = {}) { 60 } = {}) {
60 const { sort } = options 61 const { sort, targetUrl } = options
61 const path = '/api/v1/users/me/videos/imports' 62 const path = '/api/v1/users/me/videos/imports'
62 63
63 const query = {}
64 if (sort) query['sort'] = sort
65
66 return this.getRequestBody<ResultList<VideoImport>>({ 64 return this.getRequestBody<ResultList<VideoImport>>({
67 ...options, 65 ...options,
68 66
69 path, 67 path,
70 query: { sort }, 68 query: { sort, targetUrl },
71 implicitToken: true, 69 implicitToken: true,
72 defaultExpectedStatus: HttpStatusCode.OK_200 70 defaultExpectedStatus: HttpStatusCode.OK_200
73 }) 71 })