diff options
-rw-r--r-- | server/controllers/api/users/me.ts | 12 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/video-import.ts | 8 | ||||
-rw-r--r-- | server/models/video/video-import.ts | 20 | ||||
-rw-r--r-- | server/tests/api/videos/video-imports.ts | 12 | ||||
-rw-r--r-- | server/tests/cli/peertube.ts | 19 | ||||
-rw-r--r-- | shared/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 | |||
30 | import { UserModel } from '../../../models/user/user' | 30 | import { UserModel } from '../../../models/user/user' |
31 | import { VideoModel } from '../../../models/video/video' | 31 | import { VideoModel } from '../../../models/video/video' |
32 | import { VideoImportModel } from '../../../models/video/video-import' | 32 | import { VideoImportModel } from '../../../models/video/video-import' |
33 | import { pick } from '@shared/core-utils' | ||
33 | 34 | ||
34 | const auditLogger = auditLoggerFactory('users') | 35 | const auditLogger = auditLoggerFactory('users') |
35 | 36 | ||
@@ -133,12 +134,11 @@ async function getUserVideos (req: express.Request, res: express.Response) { | |||
133 | 134 | ||
134 | async function getUserVideoImports (req: express.Request, res: express.Response) { | 135 | async 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' | |||
42 | async function processVideoImport (job: Job) { | 42 | async 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 | ||
92 | async function getVideoImportOrDie (videoImportId: number) { | 92 | async 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 @@ | |||
1 | import { WhereOptions } from 'sequelize' | ||
1 | import { | 2 | import { |
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 | }) |