diff options
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/activitypub/playlist.ts | 14 | ||||
-rw-r--r-- | server/lib/activitypub/video-comments.ts | 3 | ||||
-rw-r--r-- | server/lib/activitypub/videos.ts | 34 | ||||
-rw-r--r-- | server/lib/files-cache/abstract-video-static-file-cache.ts | 18 | ||||
-rw-r--r-- | server/lib/files-cache/videos-caption-cache.ts | 9 | ||||
-rw-r--r-- | server/lib/files-cache/videos-preview-cache.ts | 6 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/video-import.ts | 20 | ||||
-rw-r--r-- | server/lib/oauth-model.ts | 2 | ||||
-rw-r--r-- | server/lib/thumbnail.ts | 26 |
9 files changed, 63 insertions, 69 deletions
diff --git a/server/lib/activitypub/playlist.ts b/server/lib/activitypub/playlist.ts index 721c19603..36a91faec 100644 --- a/server/lib/activitypub/playlist.ts +++ b/server/lib/activitypub/playlist.ts | |||
@@ -16,7 +16,8 @@ import { VideoPlaylistElementModel } from '../../models/video/video-playlist-ele | |||
16 | import { VideoModel } from '../../models/video/video' | 16 | import { VideoModel } from '../../models/video/video' |
17 | import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model' | 17 | import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model' |
18 | import { sequelizeTypescript } from '../../initializers/database' | 18 | import { sequelizeTypescript } from '../../initializers/database' |
19 | import { createPlaylistThumbnailFromUrl } from '../thumbnail' | 19 | import { createPlaylistMiniatureFromUrl } from '../thumbnail' |
20 | import { FilteredModelAttributes } from '../../typings/sequelize' | ||
20 | 21 | ||
21 | function playlistObjectToDBAttributes (playlistObject: PlaylistObject, byAccount: AccountModel, to: string[]) { | 22 | function playlistObjectToDBAttributes (playlistObject: PlaylistObject, byAccount: AccountModel, to: string[]) { |
22 | const privacy = to.indexOf(ACTIVITY_PUB.PUBLIC) !== -1 ? VideoPlaylistPrivacy.PUBLIC : VideoPlaylistPrivacy.UNLISTED | 23 | const privacy = to.indexOf(ACTIVITY_PUB.PUBLIC) !== -1 ? VideoPlaylistPrivacy.PUBLIC : VideoPlaylistPrivacy.UNLISTED |
@@ -86,8 +87,7 @@ async function createOrUpdateVideoPlaylist (playlistObject: PlaylistObject, byAc | |||
86 | } | 87 | } |
87 | } | 88 | } |
88 | 89 | ||
89 | // FIXME: sequelize typings | 90 | const [ playlist ] = await VideoPlaylistModel.upsert<VideoPlaylistModel>(playlistAttributes, { returning: true }) |
90 | const [ playlist ] = (await VideoPlaylistModel.upsert<VideoPlaylistModel>(playlistAttributes, { returning: true }) as any) | ||
91 | 91 | ||
92 | let accItems: string[] = [] | 92 | let accItems: string[] = [] |
93 | await crawlCollectionPage<string>(playlistObject.id, items => { | 93 | await crawlCollectionPage<string>(playlistObject.id, items => { |
@@ -100,10 +100,8 @@ async function createOrUpdateVideoPlaylist (playlistObject: PlaylistObject, byAc | |||
100 | 100 | ||
101 | if (playlistObject.icon) { | 101 | if (playlistObject.icon) { |
102 | try { | 102 | try { |
103 | const thumbnailModel = await createPlaylistThumbnailFromUrl(playlistObject.icon.url, refreshedPlaylist) | 103 | const thumbnailModel = await createPlaylistMiniatureFromUrl(playlistObject.icon.url, refreshedPlaylist) |
104 | thumbnailModel.videoPlaylistId = refreshedPlaylist.id | 104 | await refreshedPlaylist.setAndSaveThumbnail(thumbnailModel, undefined) |
105 | |||
106 | refreshedPlaylist.setThumbnail(await thumbnailModel.save()) | ||
107 | } catch (err) { | 105 | } catch (err) { |
108 | logger.warn('Cannot generate thumbnail of %s.', playlistObject.id, { err }) | 106 | logger.warn('Cannot generate thumbnail of %s.', playlistObject.id, { err }) |
109 | } | 107 | } |
@@ -156,7 +154,7 @@ export { | |||
156 | // --------------------------------------------------------------------------- | 154 | // --------------------------------------------------------------------------- |
157 | 155 | ||
158 | async function resetVideoPlaylistElements (elementUrls: string[], playlist: VideoPlaylistModel) { | 156 | async function resetVideoPlaylistElements (elementUrls: string[], playlist: VideoPlaylistModel) { |
159 | const elementsToCreate: object[] = [] // FIXME: sequelize typings | 157 | const elementsToCreate: FilteredModelAttributes<VideoPlaylistElementModel>[] = [] |
160 | 158 | ||
161 | await Bluebird.map(elementUrls, async elementUrl => { | 159 | await Bluebird.map(elementUrls, async elementUrl => { |
162 | try { | 160 | try { |
diff --git a/server/lib/activitypub/video-comments.ts b/server/lib/activitypub/video-comments.ts index cb67bf9a4..18f44d50e 100644 --- a/server/lib/activitypub/video-comments.ts +++ b/server/lib/activitypub/video-comments.ts | |||
@@ -73,8 +73,7 @@ async function addVideoComment (videoInstance: VideoModel, commentUrl: string) { | |||
73 | const entry = await videoCommentActivityObjectToDBAttributes(videoInstance, actor, body) | 73 | const entry = await videoCommentActivityObjectToDBAttributes(videoInstance, actor, body) |
74 | if (!entry) return { created: false } | 74 | if (!entry) return { created: false } |
75 | 75 | ||
76 | // FIXME: sequelize typings | 76 | const [ comment, created ] = await VideoCommentModel.upsert<VideoCommentModel>(entry, { returning: true }) |
77 | const [ comment, created ] = (await VideoCommentModel.upsert<VideoCommentModel>(entry, { returning: true }) as any) | ||
78 | comment.Account = actor.Account | 77 | comment.Account = actor.Account |
79 | comment.Video = videoInstance | 78 | comment.Video = videoInstance |
80 | 79 | ||
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts index 5a56942a9..63bb07ec1 100644 --- a/server/lib/activitypub/videos.ts +++ b/server/lib/activitypub/videos.ts | |||
@@ -49,10 +49,11 @@ import { AccountVideoRateModel } from '../../models/account/account-video-rate' | |||
49 | import { VideoShareModel } from '../../models/video/video-share' | 49 | import { VideoShareModel } from '../../models/video/video-share' |
50 | import { VideoCommentModel } from '../../models/video/video-comment' | 50 | import { VideoCommentModel } from '../../models/video/video-comment' |
51 | import { sequelizeTypescript } from '../../initializers/database' | 51 | import { sequelizeTypescript } from '../../initializers/database' |
52 | import { createPlaceholderThumbnail, createVideoThumbnailFromUrl } from '../thumbnail' | 52 | import { createPlaceholderThumbnail, createVideoMiniatureFromUrl } from '../thumbnail' |
53 | import { ThumbnailModel } from '../../models/video/thumbnail' | 53 | import { ThumbnailModel } from '../../models/video/thumbnail' |
54 | import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type' | 54 | import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type' |
55 | import { join } from 'path' | 55 | import { join } from 'path' |
56 | import { FilteredModelAttributes } from '../../typings/sequelize' | ||
56 | 57 | ||
57 | async function federateVideoIfNeeded (video: VideoModel, isNewVideo: boolean, transaction?: sequelize.Transaction) { | 58 | async function federateVideoIfNeeded (video: VideoModel, isNewVideo: boolean, transaction?: sequelize.Transaction) { |
58 | // If the video is not private and is published, we federate it | 59 | // If the video is not private and is published, we federate it |
@@ -247,7 +248,7 @@ async function updateVideoFromAP (options: { | |||
247 | let thumbnailModel: ThumbnailModel | 248 | let thumbnailModel: ThumbnailModel |
248 | 249 | ||
249 | try { | 250 | try { |
250 | thumbnailModel = await createVideoThumbnailFromUrl(options.videoObject.icon.url, options.video, ThumbnailType.THUMBNAIL) | 251 | thumbnailModel = await createVideoMiniatureFromUrl(options.videoObject.icon.url, options.video, ThumbnailType.MINIATURE) |
251 | } catch (err) { | 252 | } catch (err) { |
252 | logger.warn('Cannot generate thumbnail of %s.', options.videoObject.id, { err }) | 253 | logger.warn('Cannot generate thumbnail of %s.', options.videoObject.id, { err }) |
253 | } | 254 | } |
@@ -288,16 +289,12 @@ async function updateVideoFromAP (options: { | |||
288 | 289 | ||
289 | await options.video.save(sequelizeOptions) | 290 | await options.video.save(sequelizeOptions) |
290 | 291 | ||
291 | if (thumbnailModel) { | 292 | if (thumbnailModel) if (thumbnailModel) await options.video.addAndSaveThumbnail(thumbnailModel, t) |
292 | thumbnailModel.videoId = options.video.id | ||
293 | options.video.addThumbnail(await thumbnailModel.save({ transaction: t })) | ||
294 | } | ||
295 | 293 | ||
296 | // FIXME: use icon URL instead | 294 | // FIXME: use icon URL instead |
297 | const previewUrl = buildRemoteBaseUrl(options.video, join(STATIC_PATHS.PREVIEWS, options.video.getPreview().filename)) | 295 | const previewUrl = buildRemoteBaseUrl(options.video, join(STATIC_PATHS.PREVIEWS, options.video.getPreview().filename)) |
298 | const previewModel = createPlaceholderThumbnail(previewUrl, options.video, ThumbnailType.PREVIEW, PREVIEWS_SIZE) | 296 | const previewModel = createPlaceholderThumbnail(previewUrl, options.video, ThumbnailType.PREVIEW, PREVIEWS_SIZE) |
299 | 297 | await options.video.addAndSaveThumbnail(previewModel, t) | |
300 | options.video.addThumbnail(await previewModel.save({ transaction: t })) | ||
301 | 298 | ||
302 | { | 299 | { |
303 | const videoFileAttributes = videoFileActivityUrlToDBAttributes(options.video, options.videoObject) | 300 | const videoFileAttributes = videoFileActivityUrlToDBAttributes(options.video, options.videoObject) |
@@ -311,7 +308,7 @@ async function updateVideoFromAP (options: { | |||
311 | 308 | ||
312 | // Update or add other one | 309 | // Update or add other one |
313 | const upsertTasks = videoFileAttributes.map(a => { | 310 | const upsertTasks = videoFileAttributes.map(a => { |
314 | return (VideoFileModel.upsert<VideoFileModel>(a, { returning: true, transaction: t }) as any) // FIXME: sequelize typings | 311 | return VideoFileModel.upsert<VideoFileModel>(a, { returning: true, transaction: t }) |
315 | .then(([ file ]) => file) | 312 | .then(([ file ]) => file) |
316 | }) | 313 | }) |
317 | 314 | ||
@@ -334,8 +331,7 @@ async function updateVideoFromAP (options: { | |||
334 | 331 | ||
335 | // Update or add other one | 332 | // Update or add other one |
336 | const upsertTasks = streamingPlaylistAttributes.map(a => { | 333 | const upsertTasks = streamingPlaylistAttributes.map(a => { |
337 | // FIXME: sequelize typings | 334 | return VideoStreamingPlaylistModel.upsert<VideoStreamingPlaylistModel>(a, { returning: true, transaction: t }) |
338 | return (VideoStreamingPlaylistModel.upsert<VideoStreamingPlaylistModel>(a, { returning: true, transaction: t }) as any) | ||
339 | .then(([ streamingPlaylist ]) => streamingPlaylist) | 335 | .then(([ streamingPlaylist ]) => streamingPlaylist) |
340 | }) | 336 | }) |
341 | 337 | ||
@@ -464,7 +460,7 @@ async function createVideo (videoObject: VideoTorrentObject, channelActor: Actor | |||
464 | const videoData = await videoActivityObjectToDBAttributes(channelActor.VideoChannel, videoObject, videoObject.to) | 460 | const videoData = await videoActivityObjectToDBAttributes(channelActor.VideoChannel, videoObject, videoObject.to) |
465 | const video = VideoModel.build(videoData) | 461 | const video = VideoModel.build(videoData) |
466 | 462 | ||
467 | const promiseThumbnail = createVideoThumbnailFromUrl(videoObject.icon.url, video, ThumbnailType.THUMBNAIL) | 463 | const promiseThumbnail = createVideoMiniatureFromUrl(videoObject.icon.url, video, ThumbnailType.MINIATURE) |
468 | 464 | ||
469 | let thumbnailModel: ThumbnailModel | 465 | let thumbnailModel: ThumbnailModel |
470 | if (waitThumbnail === true) { | 466 | if (waitThumbnail === true) { |
@@ -477,18 +473,12 @@ async function createVideo (videoObject: VideoTorrentObject, channelActor: Actor | |||
477 | const videoCreated = await video.save(sequelizeOptions) | 473 | const videoCreated = await video.save(sequelizeOptions) |
478 | videoCreated.VideoChannel = channelActor.VideoChannel | 474 | videoCreated.VideoChannel = channelActor.VideoChannel |
479 | 475 | ||
480 | if (thumbnailModel) { | 476 | if (thumbnailModel) await videoCreated.addAndSaveThumbnail(thumbnailModel, t) |
481 | thumbnailModel.videoId = videoCreated.id | ||
482 | |||
483 | videoCreated.addThumbnail(await thumbnailModel.save({ transaction: t })) | ||
484 | } | ||
485 | 477 | ||
486 | // FIXME: use icon URL instead | 478 | // FIXME: use icon URL instead |
487 | const previewUrl = buildRemoteBaseUrl(videoCreated, join(STATIC_PATHS.PREVIEWS, video.generatePreviewName())) | 479 | const previewUrl = buildRemoteBaseUrl(videoCreated, join(STATIC_PATHS.PREVIEWS, video.generatePreviewName())) |
488 | const previewModel = createPlaceholderThumbnail(previewUrl, video, ThumbnailType.PREVIEW, PREVIEWS_SIZE) | 480 | const previewModel = createPlaceholderThumbnail(previewUrl, video, ThumbnailType.PREVIEW, PREVIEWS_SIZE) |
489 | previewModel.videoId = videoCreated.id | 481 | if (thumbnailModel) await videoCreated.addAndSaveThumbnail(previewModel, t) |
490 | |||
491 | videoCreated.addThumbnail(await previewModel.save({ transaction: t })) | ||
492 | 482 | ||
493 | // Process files | 483 | // Process files |
494 | const videoFileAttributes = videoFileActivityUrlToDBAttributes(videoCreated, videoObject) | 484 | const videoFileAttributes = videoFileActivityUrlToDBAttributes(videoCreated, videoObject) |
@@ -594,7 +584,7 @@ function videoFileActivityUrlToDBAttributes (video: VideoModel, videoObject: Vid | |||
594 | throw new Error('Cannot find video files for ' + video.url) | 584 | throw new Error('Cannot find video files for ' + video.url) |
595 | } | 585 | } |
596 | 586 | ||
597 | const attributes: object[] = [] // FIXME: add typings | 587 | const attributes: FilteredModelAttributes<VideoFileModel>[] = [] |
598 | for (const fileUrl of fileUrls) { | 588 | for (const fileUrl of fileUrls) { |
599 | // Fetch associated magnet uri | 589 | // Fetch associated magnet uri |
600 | const magnet = videoObject.url.find(u => { | 590 | const magnet = videoObject.url.find(u => { |
@@ -629,7 +619,7 @@ function streamingPlaylistActivityUrlToDBAttributes (video: VideoModel, videoObj | |||
629 | const playlistUrls = videoObject.url.filter(u => isAPStreamingPlaylistUrlObject(u)) as ActivityPlaylistUrlObject[] | 619 | const playlistUrls = videoObject.url.filter(u => isAPStreamingPlaylistUrlObject(u)) as ActivityPlaylistUrlObject[] |
630 | if (playlistUrls.length === 0) return [] | 620 | if (playlistUrls.length === 0) return [] |
631 | 621 | ||
632 | const attributes: object[] = [] // FIXME: add typings | 622 | const attributes: FilteredModelAttributes<VideoStreamingPlaylistModel>[] = [] |
633 | for (const playlistUrlObject of playlistUrls) { | 623 | for (const playlistUrlObject of playlistUrls) { |
634 | const segmentsSha256UrlObject = playlistUrlObject.tag | 624 | const segmentsSha256UrlObject = playlistUrlObject.tag |
635 | .find(t => { | 625 | .find(t => { |
diff --git a/server/lib/files-cache/abstract-video-static-file-cache.ts b/server/lib/files-cache/abstract-video-static-file-cache.ts index 61837e0f8..84ed74c98 100644 --- a/server/lib/files-cache/abstract-video-static-file-cache.ts +++ b/server/lib/files-cache/abstract-video-static-file-cache.ts | |||
@@ -4,24 +4,28 @@ import { VideoModel } from '../../models/video/video' | |||
4 | import { fetchRemoteVideoStaticFile } from '../activitypub' | 4 | import { fetchRemoteVideoStaticFile } from '../activitypub' |
5 | import * as memoizee from 'memoizee' | 5 | import * as memoizee from 'memoizee' |
6 | 6 | ||
7 | type GetFilePathResult = { isOwned: boolean, path: string } | undefined | ||
8 | |||
7 | export abstract class AbstractVideoStaticFileCache <T> { | 9 | export abstract class AbstractVideoStaticFileCache <T> { |
8 | 10 | ||
9 | getFilePath: (params: T) => Promise<string> | 11 | getFilePath: (params: T) => Promise<GetFilePathResult> |
10 | 12 | ||
11 | abstract getFilePathImpl (params: T): Promise<string> | 13 | abstract getFilePathImpl (params: T): Promise<GetFilePathResult> |
12 | 14 | ||
13 | // Load and save the remote file, then return the local path from filesystem | 15 | // Load and save the remote file, then return the local path from filesystem |
14 | protected abstract loadRemoteFile (key: string): Promise<string> | 16 | protected abstract loadRemoteFile (key: string): Promise<GetFilePathResult> |
15 | 17 | ||
16 | init (max: number, maxAge: number) { | 18 | init (max: number, maxAge: number) { |
17 | this.getFilePath = memoizee(this.getFilePathImpl, { | 19 | this.getFilePath = memoizee(this.getFilePathImpl, { |
18 | maxAge, | 20 | maxAge, |
19 | max, | 21 | max, |
20 | promise: true, | 22 | promise: true, |
21 | dispose: (value: string) => { | 23 | dispose: (result: GetFilePathResult) => { |
22 | remove(value) | 24 | if (result.isOwned !== true) { |
23 | .then(() => logger.debug('%s evicted from %s', value, this.constructor.name)) | 25 | remove(result.path) |
24 | .catch(err => logger.error('Cannot remove %s from cache %s.', value, this.constructor.name, { err })) | 26 | .then(() => logger.debug('%s removed from %s', result.path, this.constructor.name)) |
27 | .catch(err => logger.error('Cannot remove %s from cache %s.', result.path, this.constructor.name, { err })) | ||
28 | } | ||
25 | } | 29 | } |
26 | }) | 30 | }) |
27 | } | 31 | } |
diff --git a/server/lib/files-cache/videos-caption-cache.ts b/server/lib/files-cache/videos-caption-cache.ts index d4a0a3345..305e39c35 100644 --- a/server/lib/files-cache/videos-caption-cache.ts +++ b/server/lib/files-cache/videos-caption-cache.ts | |||
@@ -4,6 +4,7 @@ import { VideoModel } from '../../models/video/video' | |||
4 | import { VideoCaptionModel } from '../../models/video/video-caption' | 4 | import { VideoCaptionModel } from '../../models/video/video-caption' |
5 | import { AbstractVideoStaticFileCache } from './abstract-video-static-file-cache' | 5 | import { AbstractVideoStaticFileCache } from './abstract-video-static-file-cache' |
6 | import { CONFIG } from '../../initializers/config' | 6 | import { CONFIG } from '../../initializers/config' |
7 | import { logger } from '../../helpers/logger' | ||
7 | 8 | ||
8 | type GetPathParam = { videoId: string, language: string } | 9 | type GetPathParam = { videoId: string, language: string } |
9 | 10 | ||
@@ -24,13 +25,15 @@ class VideosCaptionCache extends AbstractVideoStaticFileCache <GetPathParam> { | |||
24 | const videoCaption = await VideoCaptionModel.loadByVideoIdAndLanguage(params.videoId, params.language) | 25 | const videoCaption = await VideoCaptionModel.loadByVideoIdAndLanguage(params.videoId, params.language) |
25 | if (!videoCaption) return undefined | 26 | if (!videoCaption) return undefined |
26 | 27 | ||
27 | if (videoCaption.isOwned()) return join(CONFIG.STORAGE.CAPTIONS_DIR, videoCaption.getCaptionName()) | 28 | if (videoCaption.isOwned()) return { isOwned: true, path: join(CONFIG.STORAGE.CAPTIONS_DIR, videoCaption.getCaptionName()) } |
28 | 29 | ||
29 | const key = params.videoId + VideosCaptionCache.KEY_DELIMITER + params.language | 30 | const key = params.videoId + VideosCaptionCache.KEY_DELIMITER + params.language |
30 | return this.loadRemoteFile(key) | 31 | return this.loadRemoteFile(key) |
31 | } | 32 | } |
32 | 33 | ||
33 | protected async loadRemoteFile (key: string) { | 34 | protected async loadRemoteFile (key: string) { |
35 | logger.debug('Loading remote caption file %s.', key) | ||
36 | |||
34 | const [ videoId, language ] = key.split(VideosCaptionCache.KEY_DELIMITER) | 37 | const [ videoId, language ] = key.split(VideosCaptionCache.KEY_DELIMITER) |
35 | 38 | ||
36 | const videoCaption = await VideoCaptionModel.loadByVideoIdAndLanguage(videoId, language) | 39 | const videoCaption = await VideoCaptionModel.loadByVideoIdAndLanguage(videoId, language) |
@@ -46,7 +49,9 @@ class VideosCaptionCache extends AbstractVideoStaticFileCache <GetPathParam> { | |||
46 | const remoteStaticPath = videoCaption.getCaptionStaticPath() | 49 | const remoteStaticPath = videoCaption.getCaptionStaticPath() |
47 | const destPath = join(FILES_CACHE.VIDEO_CAPTIONS.DIRECTORY, videoCaption.getCaptionName()) | 50 | const destPath = join(FILES_CACHE.VIDEO_CAPTIONS.DIRECTORY, videoCaption.getCaptionName()) |
48 | 51 | ||
49 | return this.saveRemoteVideoFileAndReturnPath(video, remoteStaticPath, destPath) | 52 | const path = await this.saveRemoteVideoFileAndReturnPath(video, remoteStaticPath, destPath) |
53 | |||
54 | return { isOwned: false, path } | ||
50 | } | 55 | } |
51 | } | 56 | } |
52 | 57 | ||
diff --git a/server/lib/files-cache/videos-preview-cache.ts b/server/lib/files-cache/videos-preview-cache.ts index fc0d92c78..c117ae426 100644 --- a/server/lib/files-cache/videos-preview-cache.ts +++ b/server/lib/files-cache/videos-preview-cache.ts | |||
@@ -20,7 +20,7 @@ class VideosPreviewCache extends AbstractVideoStaticFileCache <string> { | |||
20 | const video = await VideoModel.loadByUUIDWithFile(videoUUID) | 20 | const video = await VideoModel.loadByUUIDWithFile(videoUUID) |
21 | if (!video) return undefined | 21 | if (!video) return undefined |
22 | 22 | ||
23 | if (video.isOwned()) return join(CONFIG.STORAGE.PREVIEWS_DIR, video.getPreview().filename) | 23 | if (video.isOwned()) return { isOwned: true, path: join(CONFIG.STORAGE.PREVIEWS_DIR, video.getPreview().filename) } |
24 | 24 | ||
25 | return this.loadRemoteFile(videoUUID) | 25 | return this.loadRemoteFile(videoUUID) |
26 | } | 26 | } |
@@ -35,7 +35,9 @@ class VideosPreviewCache extends AbstractVideoStaticFileCache <string> { | |||
35 | const remoteStaticPath = join(STATIC_PATHS.PREVIEWS, video.getPreview().filename) | 35 | const remoteStaticPath = join(STATIC_PATHS.PREVIEWS, video.getPreview().filename) |
36 | const destPath = join(FILES_CACHE.PREVIEWS.DIRECTORY, video.getPreview().filename) | 36 | const destPath = join(FILES_CACHE.PREVIEWS.DIRECTORY, video.getPreview().filename) |
37 | 37 | ||
38 | return this.saveRemoteVideoFileAndReturnPath(video, remoteStaticPath, destPath) | 38 | const path = await this.saveRemoteVideoFileAndReturnPath(video, remoteStaticPath, destPath) |
39 | |||
40 | return { isOwned: false, path } | ||
39 | } | 41 | } |
40 | } | 42 | } |
41 | 43 | ||
diff --git a/server/lib/job-queue/handlers/video-import.ts b/server/lib/job-queue/handlers/video-import.ts index 3fa0dd65d..1650916a6 100644 --- a/server/lib/job-queue/handlers/video-import.ts +++ b/server/lib/job-queue/handlers/video-import.ts | |||
@@ -18,7 +18,7 @@ import { Notifier } from '../../notifier' | |||
18 | import { CONFIG } from '../../../initializers/config' | 18 | import { CONFIG } from '../../../initializers/config' |
19 | import { sequelizeTypescript } from '../../../initializers/database' | 19 | import { sequelizeTypescript } from '../../../initializers/database' |
20 | import { ThumbnailModel } from '../../../models/video/thumbnail' | 20 | import { ThumbnailModel } from '../../../models/video/thumbnail' |
21 | import { createVideoThumbnailFromUrl, generateVideoThumbnail } from '../../thumbnail' | 21 | import { createVideoMiniatureFromUrl, generateVideoMiniature } from '../../thumbnail' |
22 | import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' | 22 | import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' |
23 | 23 | ||
24 | type VideoImportYoutubeDLPayload = { | 24 | type VideoImportYoutubeDLPayload = { |
@@ -150,17 +150,17 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide | |||
150 | // Process thumbnail | 150 | // Process thumbnail |
151 | let thumbnailModel: ThumbnailModel | 151 | let thumbnailModel: ThumbnailModel |
152 | if (options.downloadThumbnail && options.thumbnailUrl) { | 152 | if (options.downloadThumbnail && options.thumbnailUrl) { |
153 | thumbnailModel = await createVideoThumbnailFromUrl(options.thumbnailUrl, videoImport.Video, ThumbnailType.THUMBNAIL) | 153 | thumbnailModel = await createVideoMiniatureFromUrl(options.thumbnailUrl, videoImport.Video, ThumbnailType.MINIATURE) |
154 | } else if (options.generateThumbnail || options.downloadThumbnail) { | 154 | } else if (options.generateThumbnail || options.downloadThumbnail) { |
155 | thumbnailModel = await generateVideoThumbnail(videoImport.Video, videoFile, ThumbnailType.THUMBNAIL) | 155 | thumbnailModel = await generateVideoMiniature(videoImport.Video, videoFile, ThumbnailType.MINIATURE) |
156 | } | 156 | } |
157 | 157 | ||
158 | // Process preview | 158 | // Process preview |
159 | let previewModel: ThumbnailModel | 159 | let previewModel: ThumbnailModel |
160 | if (options.downloadPreview && options.thumbnailUrl) { | 160 | if (options.downloadPreview && options.thumbnailUrl) { |
161 | previewModel = await createVideoThumbnailFromUrl(options.thumbnailUrl, videoImport.Video, ThumbnailType.PREVIEW) | 161 | previewModel = await createVideoMiniatureFromUrl(options.thumbnailUrl, videoImport.Video, ThumbnailType.PREVIEW) |
162 | } else if (options.generatePreview || options.downloadPreview) { | 162 | } else if (options.generatePreview || options.downloadPreview) { |
163 | previewModel = await generateVideoThumbnail(videoImport.Video, videoFile, ThumbnailType.PREVIEW) | 163 | previewModel = await generateVideoMiniature(videoImport.Video, videoFile, ThumbnailType.PREVIEW) |
164 | } | 164 | } |
165 | 165 | ||
166 | // Create torrent | 166 | // Create torrent |
@@ -180,14 +180,8 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide | |||
180 | video.state = CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED | 180 | video.state = CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED |
181 | await video.save({ transaction: t }) | 181 | await video.save({ transaction: t }) |
182 | 182 | ||
183 | if (thumbnailModel) { | 183 | if (thumbnailModel) await video.addAndSaveThumbnail(thumbnailModel, t) |
184 | thumbnailModel.videoId = video.id | 184 | if (previewModel) await video.addAndSaveThumbnail(previewModel, t) |
185 | video.addThumbnail(await thumbnailModel.save({ transaction: t })) | ||
186 | } | ||
187 | if (previewModel) { | ||
188 | previewModel.videoId = video.id | ||
189 | video.addThumbnail(await previewModel.save({ transaction: t })) | ||
190 | } | ||
191 | 185 | ||
192 | // Now we can federate the video (reload from database, we need more attributes) | 186 | // Now we can federate the video (reload from database, we need more attributes) |
193 | const videoForFederation = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t) | 187 | const videoForFederation = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t) |
diff --git a/server/lib/oauth-model.ts b/server/lib/oauth-model.ts index eb0e63bc8..45ac3e7c4 100644 --- a/server/lib/oauth-model.ts +++ b/server/lib/oauth-model.ts | |||
@@ -39,6 +39,8 @@ function clearCacheByToken (token: string) { | |||
39 | function getAccessToken (bearerToken: string) { | 39 | function getAccessToken (bearerToken: string) { |
40 | logger.debug('Getting access token (bearerToken: ' + bearerToken + ').') | 40 | logger.debug('Getting access token (bearerToken: ' + bearerToken + ').') |
41 | 41 | ||
42 | if (!bearerToken) return Bluebird.resolve(undefined) | ||
43 | |||
42 | if (accessTokenCache[bearerToken] !== undefined) return Bluebird.resolve(accessTokenCache[bearerToken]) | 44 | if (accessTokenCache[bearerToken] !== undefined) return Bluebird.resolve(accessTokenCache[bearerToken]) |
43 | 45 | ||
44 | return OAuthTokenModel.getByTokenAndPopulateUser(bearerToken) | 46 | return OAuthTokenModel.getByTokenAndPopulateUser(bearerToken) |
diff --git a/server/lib/thumbnail.ts b/server/lib/thumbnail.ts index 344c28566..8ad82ee80 100644 --- a/server/lib/thumbnail.ts +++ b/server/lib/thumbnail.ts | |||
@@ -12,37 +12,37 @@ import { VideoPlaylistModel } from '../models/video/video-playlist' | |||
12 | 12 | ||
13 | type ImageSize = { height: number, width: number } | 13 | type ImageSize = { height: number, width: number } |
14 | 14 | ||
15 | function createPlaylistThumbnailFromExisting (inputPath: string, playlist: VideoPlaylistModel, keepOriginal = false, size?: ImageSize) { | 15 | function createPlaylistMiniatureFromExisting (inputPath: string, playlist: VideoPlaylistModel, keepOriginal = false, size?: ImageSize) { |
16 | const { filename, outputPath, height, width, existingThumbnail } = buildMetadataFromPlaylist(playlist, size) | 16 | const { filename, outputPath, height, width, existingThumbnail } = buildMetadataFromPlaylist(playlist, size) |
17 | const type = ThumbnailType.THUMBNAIL | 17 | const type = ThumbnailType.MINIATURE |
18 | 18 | ||
19 | const thumbnailCreator = () => processImage({ path: inputPath }, outputPath, { width, height }, keepOriginal) | 19 | const thumbnailCreator = () => processImage({ path: inputPath }, outputPath, { width, height }, keepOriginal) |
20 | return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail }) | 20 | return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail }) |
21 | } | 21 | } |
22 | 22 | ||
23 | function createPlaylistThumbnailFromUrl (url: string, playlist: VideoPlaylistModel, size?: ImageSize) { | 23 | function createPlaylistMiniatureFromUrl (url: string, playlist: VideoPlaylistModel, size?: ImageSize) { |
24 | const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromPlaylist(playlist, size) | 24 | const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromPlaylist(playlist, size) |
25 | const type = ThumbnailType.THUMBNAIL | 25 | const type = ThumbnailType.MINIATURE |
26 | 26 | ||
27 | const thumbnailCreator = () => downloadImage(url, basePath, filename, { width, height }) | 27 | const thumbnailCreator = () => downloadImage(url, basePath, filename, { width, height }) |
28 | return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, url }) | 28 | return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, url }) |
29 | } | 29 | } |
30 | 30 | ||
31 | function createVideoThumbnailFromUrl (url: string, video: VideoModel, type: ThumbnailType, size?: ImageSize) { | 31 | function createVideoMiniatureFromUrl (url: string, video: VideoModel, type: ThumbnailType, size?: ImageSize) { |
32 | const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size) | 32 | const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size) |
33 | const thumbnailCreator = () => downloadImage(url, basePath, filename, { width, height }) | 33 | const thumbnailCreator = () => downloadImage(url, basePath, filename, { width, height }) |
34 | 34 | ||
35 | return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, url }) | 35 | return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, url }) |
36 | } | 36 | } |
37 | 37 | ||
38 | function createVideoThumbnailFromExisting (inputPath: string, video: VideoModel, type: ThumbnailType, size?: ImageSize) { | 38 | function createVideoMiniatureFromExisting (inputPath: string, video: VideoModel, type: ThumbnailType, size?: ImageSize) { |
39 | const { filename, outputPath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size) | 39 | const { filename, outputPath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size) |
40 | const thumbnailCreator = () => processImage({ path: inputPath }, outputPath, { width, height }) | 40 | const thumbnailCreator = () => processImage({ path: inputPath }, outputPath, { width, height }) |
41 | 41 | ||
42 | return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail }) | 42 | return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail }) |
43 | } | 43 | } |
44 | 44 | ||
45 | function generateVideoThumbnail (video: VideoModel, videoFile: VideoFileModel, type: ThumbnailType) { | 45 | function generateVideoMiniature (video: VideoModel, videoFile: VideoFileModel, type: ThumbnailType) { |
46 | const input = video.getVideoFilePath(videoFile) | 46 | const input = video.getVideoFilePath(videoFile) |
47 | 47 | ||
48 | const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type) | 48 | const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type) |
@@ -68,12 +68,12 @@ function createPlaceholderThumbnail (url: string, video: VideoModel, type: Thumb | |||
68 | // --------------------------------------------------------------------------- | 68 | // --------------------------------------------------------------------------- |
69 | 69 | ||
70 | export { | 70 | export { |
71 | generateVideoThumbnail, | 71 | generateVideoMiniature, |
72 | createVideoThumbnailFromUrl, | 72 | createVideoMiniatureFromUrl, |
73 | createVideoThumbnailFromExisting, | 73 | createVideoMiniatureFromExisting, |
74 | createPlaceholderThumbnail, | 74 | createPlaceholderThumbnail, |
75 | createPlaylistThumbnailFromUrl, | 75 | createPlaylistMiniatureFromUrl, |
76 | createPlaylistThumbnailFromExisting | 76 | createPlaylistMiniatureFromExisting |
77 | } | 77 | } |
78 | 78 | ||
79 | function buildMetadataFromPlaylist (playlist: VideoPlaylistModel, size: ImageSize) { | 79 | function buildMetadataFromPlaylist (playlist: VideoPlaylistModel, size: ImageSize) { |
@@ -95,7 +95,7 @@ function buildMetadataFromVideo (video: VideoModel, type: ThumbnailType, size?: | |||
95 | ? video.Thumbnails.find(t => t.type === type) | 95 | ? video.Thumbnails.find(t => t.type === type) |
96 | : undefined | 96 | : undefined |
97 | 97 | ||
98 | if (type === ThumbnailType.THUMBNAIL) { | 98 | if (type === ThumbnailType.MINIATURE) { |
99 | const filename = video.generateThumbnailName() | 99 | const filename = video.generateThumbnailName() |
100 | const basePath = CONFIG.STORAGE.THUMBNAILS_DIR | 100 | const basePath = CONFIG.STORAGE.THUMBNAILS_DIR |
101 | 101 | ||