diff options
-rw-r--r-- | server/controllers/api/videos/import.ts | 17 | ||||
-rw-r--r-- | server/controllers/api/videos/live.ts | 4 | ||||
-rw-r--r-- | server/controllers/api/videos/upload.ts | 3 | ||||
-rw-r--r-- | server/tests/fixtures/peertube-plugin-test/main.js | 15 | ||||
-rw-r--r-- | server/tests/plugins/filter-hooks.ts | 59 | ||||
-rw-r--r-- | shared/models/plugins/server/server-hook.model.ts | 6 |
6 files changed, 98 insertions, 6 deletions
diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts index eddb9b32d..52864bdfd 100644 --- a/server/controllers/api/videos/import.ts +++ b/server/controllers/api/videos/import.ts | |||
@@ -38,6 +38,7 @@ import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoIm | |||
38 | import { VideoModel } from '../../../models/video/video' | 38 | import { VideoModel } from '../../../models/video/video' |
39 | import { VideoCaptionModel } from '../../../models/video/video-caption' | 39 | import { VideoCaptionModel } from '../../../models/video/video-caption' |
40 | import { VideoImportModel } from '../../../models/video/video-import' | 40 | import { VideoImportModel } from '../../../models/video/video-import' |
41 | import { Hooks } from '@server/lib/plugins/hooks' | ||
41 | 42 | ||
42 | const auditLogger = auditLoggerFactory('video-imports') | 43 | const auditLogger = auditLoggerFactory('video-imports') |
43 | const videoImportsRouter = express.Router() | 44 | const videoImportsRouter = express.Router() |
@@ -94,7 +95,7 @@ async function addTorrentImport (req: express.Request, res: express.Response, to | |||
94 | videoName = result.name | 95 | videoName = result.name |
95 | } | 96 | } |
96 | 97 | ||
97 | const video = buildVideo(res.locals.videoChannel.id, body, { name: videoName }) | 98 | const video = await buildVideo(res.locals.videoChannel.id, body, { name: videoName }) |
98 | 99 | ||
99 | const thumbnailModel = await processThumbnail(req, video) | 100 | const thumbnailModel = await processThumbnail(req, video) |
100 | const previewModel = await processPreview(req, video) | 101 | const previewModel = await processPreview(req, video) |
@@ -151,7 +152,7 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response) | |||
151 | }) | 152 | }) |
152 | } | 153 | } |
153 | 154 | ||
154 | const video = buildVideo(res.locals.videoChannel.id, body, youtubeDLInfo) | 155 | const video = await buildVideo(res.locals.videoChannel.id, body, youtubeDLInfo) |
155 | 156 | ||
156 | // Process video thumbnail from request.files | 157 | // Process video thumbnail from request.files |
157 | let thumbnailModel = await processThumbnail(req, video) | 158 | let thumbnailModel = await processThumbnail(req, video) |
@@ -210,8 +211,8 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response) | |||
210 | return res.json(videoImport.toFormattedJSON()).end() | 211 | return res.json(videoImport.toFormattedJSON()).end() |
211 | } | 212 | } |
212 | 213 | ||
213 | function buildVideo (channelId: number, body: VideoImportCreate, importData: YoutubeDLInfo): MVideoThumbnail { | 214 | async function buildVideo (channelId: number, body: VideoImportCreate, importData: YoutubeDLInfo): Promise<MVideoThumbnail> { |
214 | const videoData = { | 215 | let videoData = { |
215 | name: body.name || importData.name || 'Unknown name', | 216 | name: body.name || importData.name || 'Unknown name', |
216 | remote: false, | 217 | remote: false, |
217 | category: body.category || importData.category, | 218 | category: body.category || importData.category, |
@@ -231,6 +232,14 @@ function buildVideo (channelId: number, body: VideoImportCreate, importData: You | |||
231 | ? new Date(body.originallyPublishedAt) | 232 | ? new Date(body.originallyPublishedAt) |
232 | : importData.originallyPublishedAt | 233 | : importData.originallyPublishedAt |
233 | } | 234 | } |
235 | |||
236 | videoData = await Hooks.wrapObject( | ||
237 | videoData, | ||
238 | body.targetUrl | ||
239 | ? 'filter:api.video.import-url.video-attribute.result' | ||
240 | : 'filter:api.video.import-torrent.video-attribute.result' | ||
241 | ) | ||
242 | |||
234 | const video = new VideoModel(videoData) | 243 | const video = new VideoModel(videoData) |
235 | video.url = getLocalVideoActivityPubUrl(video) | 244 | video.url = getLocalVideoActivityPubUrl(video) |
236 | 245 | ||
diff --git a/server/controllers/api/videos/live.ts b/server/controllers/api/videos/live.ts index e29615ff5..3e1480cf2 100644 --- a/server/controllers/api/videos/live.ts +++ b/server/controllers/api/videos/live.ts | |||
@@ -83,7 +83,9 @@ async function addLiveVideo (req: express.Request, res: express.Response) { | |||
83 | const videoInfo: LiveVideoCreate = req.body | 83 | const videoInfo: LiveVideoCreate = req.body |
84 | 84 | ||
85 | // Prepare data so we don't block the transaction | 85 | // Prepare data so we don't block the transaction |
86 | const videoData = buildLocalVideoFromReq(videoInfo, res.locals.videoChannel.id) | 86 | let videoData = buildLocalVideoFromReq(videoInfo, res.locals.videoChannel.id) |
87 | videoData = await Hooks.wrapObject(videoData, 'filter:api.video.live.video-attribute.result') | ||
88 | |||
87 | videoData.isLive = true | 89 | videoData.isLive = true |
88 | videoData.state = VideoState.WAITING_FOR_LIVE | 90 | videoData.state = VideoState.WAITING_FOR_LIVE |
89 | videoData.duration = 0 | 91 | videoData.duration = 0 |
diff --git a/server/controllers/api/videos/upload.ts b/server/controllers/api/videos/upload.ts index c827f6bf0..1be87f746 100644 --- a/server/controllers/api/videos/upload.ts +++ b/server/controllers/api/videos/upload.ts | |||
@@ -153,7 +153,8 @@ async function addVideo (options: { | |||
153 | const videoChannel = res.locals.videoChannel | 153 | const videoChannel = res.locals.videoChannel |
154 | const user = res.locals.oauth.token.User | 154 | const user = res.locals.oauth.token.User |
155 | 155 | ||
156 | const videoData = buildLocalVideoFromReq(videoInfo, videoChannel.id) | 156 | let videoData = buildLocalVideoFromReq(videoInfo, videoChannel.id) |
157 | videoData = await Hooks.wrapObject(videoData, 'filter:api.video.upload.video-attribute.result') | ||
157 | 158 | ||
158 | videoData.state = buildNextVideoState() | 159 | videoData.state = buildNextVideoState() |
159 | videoData.duration = videoPhysicalFile.duration // duration was added by a previous middleware | 160 | videoData.duration = videoPhysicalFile.duration // duration was added by a previous middleware |
diff --git a/server/tests/fixtures/peertube-plugin-test/main.js b/server/tests/fixtures/peertube-plugin-test/main.js index aba415d1e..04e059848 100644 --- a/server/tests/fixtures/peertube-plugin-test/main.js +++ b/server/tests/fixtures/peertube-plugin-test/main.js | |||
@@ -240,6 +240,21 @@ async function register ({ registerHook, registerSetting, settingsManager, stora | |||
240 | } | 240 | } |
241 | }) | 241 | }) |
242 | 242 | ||
243 | // Upload/import/live attributes | ||
244 | for (const target of [ | ||
245 | 'filter:api.video.upload.video-attribute.result', | ||
246 | 'filter:api.video.import-url.video-attribute.result', | ||
247 | 'filter:api.video.import-torrent.video-attribute.result', | ||
248 | 'filter:api.video.live.video-attribute.result' | ||
249 | ]) { | ||
250 | registerHook({ | ||
251 | target, | ||
252 | handler: (result) => { | ||
253 | return { ...result, description: result.description + ' - ' + target } | ||
254 | } | ||
255 | }) | ||
256 | } | ||
257 | |||
243 | { | 258 | { |
244 | const filterHooks = [ | 259 | const filterHooks = [ |
245 | 'filter:api.search.videos.local.list.params', | 260 | 'filter:api.search.videos.local.list.params', |
diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts index 80014566b..ff2afc56b 100644 --- a/server/tests/plugins/filter-hooks.ts +++ b/server/tests/plugins/filter-hooks.ts | |||
@@ -537,6 +537,65 @@ describe('Test plugin filter hooks', function () { | |||
537 | }) | 537 | }) |
538 | }) | 538 | }) |
539 | 539 | ||
540 | describe('Upload/import/live attributes filters', function () { | ||
541 | |||
542 | before(async function () { | ||
543 | await servers[0].config.enableLive({ transcoding: false, allowReplay: false }) | ||
544 | await servers[0].config.enableImports() | ||
545 | await servers[0].config.disableTranscoding() | ||
546 | }) | ||
547 | |||
548 | it('Should run filter:api.video.upload.video-attribute.result', async function () { | ||
549 | for (const mode of [ 'legacy' as 'legacy', 'resumable' as 'resumable' ]) { | ||
550 | const { id } = await servers[0].videos.upload({ attributes: { name: 'video', description: 'upload' }, mode }) | ||
551 | |||
552 | const video = await servers[0].videos.get({ id }) | ||
553 | expect(video.description).to.equal('upload - filter:api.video.upload.video-attribute.result') | ||
554 | } | ||
555 | }) | ||
556 | |||
557 | it('Should run filter:api.video.import-url.video-attribute.result', async function () { | ||
558 | const attributes = { | ||
559 | name: 'video', | ||
560 | description: 'import url', | ||
561 | channelId: servers[0].store.channel.id, | ||
562 | targetUrl: FIXTURE_URLS.goodVideo, | ||
563 | privacy: VideoPrivacy.PUBLIC | ||
564 | } | ||
565 | const { video: { id } } = await servers[0].imports.importVideo({ attributes }) | ||
566 | |||
567 | const video = await servers[0].videos.get({ id }) | ||
568 | expect(video.description).to.equal('import url - filter:api.video.import-url.video-attribute.result') | ||
569 | }) | ||
570 | |||
571 | it('Should run filter:api.video.import-torrent.video-attribute.result', async function () { | ||
572 | const attributes = { | ||
573 | name: 'video', | ||
574 | description: 'import torrent', | ||
575 | channelId: servers[0].store.channel.id, | ||
576 | magnetUri: FIXTURE_URLS.magnet, | ||
577 | privacy: VideoPrivacy.PUBLIC | ||
578 | } | ||
579 | const { video: { id } } = await servers[0].imports.importVideo({ attributes }) | ||
580 | |||
581 | const video = await servers[0].videos.get({ id }) | ||
582 | expect(video.description).to.equal('import torrent - filter:api.video.import-torrent.video-attribute.result') | ||
583 | }) | ||
584 | |||
585 | it('Should run filter:api.video.live.video-attribute.result', async function () { | ||
586 | const fields = { | ||
587 | name: 'live', | ||
588 | description: 'live', | ||
589 | channelId: servers[0].store.channel.id, | ||
590 | privacy: VideoPrivacy.PUBLIC | ||
591 | } | ||
592 | const { id } = await servers[0].live.create({ fields }) | ||
593 | |||
594 | const video = await servers[0].videos.get({ id }) | ||
595 | expect(video.description).to.equal('live - filter:api.video.live.video-attribute.result') | ||
596 | }) | ||
597 | }) | ||
598 | |||
540 | describe('Stats filters', function () { | 599 | describe('Stats filters', function () { |
541 | 600 | ||
542 | it('Should run filter:api.server.stats.get.result', async function () { | 601 | it('Should run filter:api.server.stats.get.result', async function () { |
diff --git a/shared/models/plugins/server/server-hook.model.ts b/shared/models/plugins/server/server-hook.model.ts index 7e344e003..056c41a7f 100644 --- a/shared/models/plugins/server/server-hook.model.ts +++ b/shared/models/plugins/server/server-hook.model.ts | |||
@@ -53,6 +53,12 @@ export const serverFilterHookObject = { | |||
53 | 'filter:api.video-thread.create.accept.result': true, | 53 | 'filter:api.video-thread.create.accept.result': true, |
54 | 'filter:api.video-comment-reply.create.accept.result': true, | 54 | 'filter:api.video-comment-reply.create.accept.result': true, |
55 | 55 | ||
56 | // Filter attributes when creating video object | ||
57 | 'filter:api.video.upload.video-attribute.result': true, | ||
58 | 'filter:api.video.import-url.video-attribute.result': true, | ||
59 | 'filter:api.video.import-torrent.video-attribute.result': true, | ||
60 | 'filter:api.video.live.video-attribute.result': true, | ||
61 | |||
56 | // Filter params/result used to list threads of a specific video | 62 | // Filter params/result used to list threads of a specific video |
57 | // (used by the video watch page) | 63 | // (used by the video watch page) |
58 | 'filter:api.video-threads.list.params': true, | 64 | 'filter:api.video-threads.list.params': true, |