From d511df28906f84c7d25ecb24e41515ed549ff276 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 19 Jan 2022 14:58:16 +0100 Subject: [PATCH] Add ability to filter my imports by target URL --- server/controllers/api/users/me.ts | 12 +++++------ server/lib/job-queue/handlers/video-import.ts | 8 ++++---- server/models/video/video-import.ts | 20 +++++++++++++++---- server/tests/api/videos/video-imports.ts | 12 +++++++++++ server/tests/cli/peertube.ts | 19 +++++++++++++++++- .../server-commands/videos/imports-command.ts | 8 +++----- 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 import { UserModel } from '../../../models/user/user' import { VideoModel } from '../../../models/video/video' import { VideoImportModel } from '../../../models/video/video-import' +import { pick } from '@shared/core-utils' const auditLogger = auditLoggerFactory('users') @@ -133,12 +134,11 @@ async function getUserVideos (req: express.Request, res: express.Response) { async function getUserVideoImports (req: express.Request, res: express.Response) { const user = res.locals.oauth.token.User - const resultList = await VideoImportModel.listUserVideoImportsForApi( - user.id, - req.query.start as number, - req.query.count as number, - req.query.sort - ) + const resultList = await VideoImportModel.listUserVideoImportsForApi({ + userId: user.id, + + ...pick(req.query, [ 'targetUrl', 'start', 'count', 'sort' ]) + }) return res.json(getFormattedObjects(resultList.data, resultList.total)) } 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' async function processVideoImport (job: Job) { const payload = job.data as VideoImportPayload - const videoImport = await getVideoImportOrDie(payload.videoImportId) + const videoImport = await getVideoImportOrDie(payload) if (videoImport.state === VideoImportState.CANCELLED) { logger.info('Do not process import since it has been cancelled', { payload }) return @@ -89,10 +89,10 @@ async function processYoutubeDLImport (job: Job, videoImport: MVideoImportDefaul ) } -async function getVideoImportOrDie (videoImportId: number) { - const videoImport = await VideoImportModel.loadAndPopulateVideo(videoImportId) +async function getVideoImportOrDie (payload: VideoImportPayload) { + const videoImport = await VideoImportModel.loadAndPopulateVideo(payload.videoImportId) if (!videoImport || !videoImport.Video) { - throw new Error('Cannot import video %s: the video import or video linked to this import does not exist anymore.') + throw new Error(`Cannot import video ${payload.videoImportId}: the video import or video linked to this import does not exist anymore.`) } 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 @@ +import { WhereOptions } from 'sequelize' import { AfterUpdate, AllowNull, @@ -125,7 +126,20 @@ export class VideoImportModel extends Model(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 () { expect(videoImports[0].video.name).to.equal('你好 世界 720p.mp4') }) + it('Should filter my imports on target URL', async function () { + const { total, data: videoImports } = await servers[0].imports.getMyVideoImports({ targetUrl: FIXTURE_URLS.youtube }) + expect(total).to.equal(1) + expect(videoImports).to.have.lengthOf(1) + + expect(videoImports[0].targetUrl).to.equal(FIXTURE_URLS.youtube) + }) + it('Should have the video listed on the two instances', async function () { this.timeout(120_000) @@ -459,6 +467,10 @@ describe('Test video imports', function () { const { data } = await server.imports.getMyVideoImports() expect(data).to.have.lengthOf(0) }) + + after(async function () { + await cleanupTests([ server ]) + }) }) 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 () { expect(videoDetails.channel.name).to.equal('user_channel') expect(videoDetails.support).to.equal('super support text') expect(videoDetails.nsfw).to.be.false + }) + + it('Should not import again the same video', async function () { + if (areHttpImportTestsDisabled()) return + + this.timeout(60000) + + const params = `--target-url ${FIXTURE_URLS.youtube} --channel-name user_channel` + await cliCommand.execWithEnv(`${cmd} import ${params}`) + + await waitJobs([ server ]) + + const { total, data } = await server.videos.list() + expect(total).to.equal(2) + + const videos = data.filter(v => v.name === 'small video - youtube') + expect(videos).to.have.lengthOf(1) // So we can reimport it - await server.videos.remove({ token: userAccessToken, id: video.id }) + await server.videos.remove({ token: userAccessToken, id: videos[0].id }) }) 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 { getMyVideoImports (options: OverrideCommandOptions & { sort?: string + targetUrl?: string } = {}) { - const { sort } = options + const { sort, targetUrl } = options const path = '/api/v1/users/me/videos/imports' - const query = {} - if (sort) query['sort'] = sort - return this.getRequestBody>({ ...options, path, - query: { sort }, + query: { sort, targetUrl }, implicitToken: true, defaultExpectedStatus: HttpStatusCode.OK_200 })