diff options
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/activitypub/actor.ts | 4 | ||||
-rw-r--r-- | server/lib/activitypub/process/process-update.ts | 2 | ||||
-rw-r--r-- | server/lib/activitypub/videos.ts | 24 | ||||
-rw-r--r-- | server/lib/emailer.ts | 7 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/activitypub-refresher.ts | 3 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/video-file.ts | 4 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/video-import.ts | 9 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/video-views.ts | 4 | ||||
-rw-r--r-- | server/lib/redis.ts | 9 | ||||
-rw-r--r-- | server/lib/schedulers/videos-redundancy-scheduler.ts | 4 |
10 files changed, 42 insertions, 28 deletions
diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts index 504263c99..bbe48833d 100644 --- a/server/lib/activitypub/actor.ts +++ b/server/lib/activitypub/actor.ts | |||
@@ -178,9 +178,7 @@ async function fetchAvatarIfExists (actorJSON: ActivityPubActor) { | |||
178 | const extension = IMAGE_MIMETYPE_EXT[actorJSON.icon.mediaType] | 178 | const extension = IMAGE_MIMETYPE_EXT[actorJSON.icon.mediaType] |
179 | 179 | ||
180 | const avatarName = uuidv4() + extension | 180 | const avatarName = uuidv4() + extension |
181 | const destPath = join(CONFIG.STORAGE.AVATARS_DIR, avatarName) | 181 | await downloadImage(actorJSON.icon.url, CONFIG.STORAGE.AVATARS_DIR, avatarName, AVATARS_SIZE) |
182 | |||
183 | await downloadImage(actorJSON.icon.url, destPath, AVATARS_SIZE) | ||
184 | 182 | ||
185 | return avatarName | 183 | return avatarName |
186 | } | 184 | } |
diff --git a/server/lib/activitypub/process/process-update.ts b/server/lib/activitypub/process/process-update.ts index 03831a00e..c6b42d846 100644 --- a/server/lib/activitypub/process/process-update.ts +++ b/server/lib/activitypub/process/process-update.ts | |||
@@ -51,7 +51,7 @@ async function processUpdateVideo (actor: ActorModel, activity: ActivityUpdate) | |||
51 | return undefined | 51 | return undefined |
52 | } | 52 | } |
53 | 53 | ||
54 | const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoObject.id }) | 54 | const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoObject.id, allowRefresh: false }) |
55 | const channelActor = await getOrCreateVideoChannelFromVideoObject(videoObject) | 55 | const channelActor = await getOrCreateVideoChannelFromVideoObject(videoObject) |
56 | 56 | ||
57 | const updateOptions = { | 57 | const updateOptions = { |
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts index 998f90330..3d17e6846 100644 --- a/server/lib/activitypub/videos.ts +++ b/server/lib/activitypub/videos.ts | |||
@@ -95,9 +95,8 @@ function fetchRemoteVideoStaticFile (video: VideoModel, path: string, reject: Fu | |||
95 | 95 | ||
96 | function generateThumbnailFromUrl (video: VideoModel, icon: ActivityIconObject) { | 96 | function generateThumbnailFromUrl (video: VideoModel, icon: ActivityIconObject) { |
97 | const thumbnailName = video.getThumbnailName() | 97 | const thumbnailName = video.getThumbnailName() |
98 | const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, thumbnailName) | ||
99 | 98 | ||
100 | return downloadImage(icon.url, thumbnailPath, THUMBNAILS_SIZE) | 99 | return downloadImage(icon.url, CONFIG.STORAGE.THUMBNAILS_DIR, thumbnailName, THUMBNAILS_SIZE) |
101 | } | 100 | } |
102 | 101 | ||
103 | function getOrCreateVideoChannelFromVideoObject (videoObject: VideoTorrentObject) { | 102 | function getOrCreateVideoChannelFromVideoObject (videoObject: VideoTorrentObject) { |
@@ -158,25 +157,30 @@ async function syncVideoExternalAttributes (video: VideoModel, fetchedVideo: Vid | |||
158 | async function getOrCreateVideoAndAccountAndChannel (options: { | 157 | async function getOrCreateVideoAndAccountAndChannel (options: { |
159 | videoObject: VideoTorrentObject | string, | 158 | videoObject: VideoTorrentObject | string, |
160 | syncParam?: SyncParam, | 159 | syncParam?: SyncParam, |
161 | fetchType?: VideoFetchByUrlType | 160 | fetchType?: VideoFetchByUrlType, |
161 | allowRefresh?: boolean // true by default | ||
162 | }) { | 162 | }) { |
163 | // Default params | 163 | // Default params |
164 | const syncParam = options.syncParam || { likes: true, dislikes: true, shares: true, comments: true, thumbnail: true, refreshVideo: false } | 164 | const syncParam = options.syncParam || { likes: true, dislikes: true, shares: true, comments: true, thumbnail: true, refreshVideo: false } |
165 | const fetchType = options.fetchType || 'all' | 165 | const fetchType = options.fetchType || 'all' |
166 | const allowRefresh = options.allowRefresh !== false | ||
166 | 167 | ||
167 | // Get video url | 168 | // Get video url |
168 | const videoUrl = getAPUrl(options.videoObject) | 169 | const videoUrl = getAPUrl(options.videoObject) |
169 | 170 | ||
170 | let videoFromDatabase = await fetchVideoByUrl(videoUrl, fetchType) | 171 | let videoFromDatabase = await fetchVideoByUrl(videoUrl, fetchType) |
171 | if (videoFromDatabase) { | 172 | if (videoFromDatabase) { |
172 | const refreshOptions = { | ||
173 | video: videoFromDatabase, | ||
174 | fetchedType: fetchType, | ||
175 | syncParam | ||
176 | } | ||
177 | 173 | ||
178 | if (syncParam.refreshVideo === true) videoFromDatabase = await refreshVideoIfNeeded(refreshOptions) | 174 | if (allowRefresh === true) { |
179 | else await JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video', videoUrl: videoFromDatabase.url } }) | 175 | const refreshOptions = { |
176 | video: videoFromDatabase, | ||
177 | fetchedType: fetchType, | ||
178 | syncParam | ||
179 | } | ||
180 | |||
181 | if (syncParam.refreshVideo === true) videoFromDatabase = await refreshVideoIfNeeded(refreshOptions) | ||
182 | else await JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video', videoUrl: videoFromDatabase.url } }) | ||
183 | } | ||
180 | 184 | ||
181 | return { video: videoFromDatabase } | 185 | return { video: videoFromDatabase } |
182 | } | 186 | } |
diff --git a/server/lib/emailer.ts b/server/lib/emailer.ts index 9327792fb..074d4ad44 100644 --- a/server/lib/emailer.ts +++ b/server/lib/emailer.ts | |||
@@ -14,6 +14,7 @@ class Emailer { | |||
14 | private static instance: Emailer | 14 | private static instance: Emailer |
15 | private initialized = false | 15 | private initialized = false |
16 | private transporter: Transporter | 16 | private transporter: Transporter |
17 | private enabled = false | ||
17 | 18 | ||
18 | private constructor () {} | 19 | private constructor () {} |
19 | 20 | ||
@@ -50,6 +51,8 @@ class Emailer { | |||
50 | tls, | 51 | tls, |
51 | auth | 52 | auth |
52 | }) | 53 | }) |
54 | |||
55 | this.enabled = true | ||
53 | } else { | 56 | } else { |
54 | if (!isTestInstance()) { | 57 | if (!isTestInstance()) { |
55 | logger.error('Cannot use SMTP server because of lack of configuration. PeerTube will not be able to send mails!') | 58 | logger.error('Cannot use SMTP server because of lack of configuration. PeerTube will not be able to send mails!') |
@@ -57,6 +60,10 @@ class Emailer { | |||
57 | } | 60 | } |
58 | } | 61 | } |
59 | 62 | ||
63 | isEnabled () { | ||
64 | return this.enabled | ||
65 | } | ||
66 | |||
60 | async checkConnectionOrDie () { | 67 | async checkConnectionOrDie () { |
61 | if (!this.transporter) return | 68 | if (!this.transporter) return |
62 | 69 | ||
diff --git a/server/lib/job-queue/handlers/activitypub-refresher.ts b/server/lib/job-queue/handlers/activitypub-refresher.ts index 7752b3b40..671b0f487 100644 --- a/server/lib/job-queue/handlers/activitypub-refresher.ts +++ b/server/lib/job-queue/handlers/activitypub-refresher.ts | |||
@@ -10,7 +10,8 @@ export type RefreshPayload = { | |||
10 | 10 | ||
11 | async function refreshAPObject (job: Bull.Job) { | 11 | async function refreshAPObject (job: Bull.Job) { |
12 | const payload = job.data as RefreshPayload | 12 | const payload = job.data as RefreshPayload |
13 | logger.info('Processing AP refresher in job %d.', job.id) | 13 | |
14 | logger.info('Processing AP refresher in job %d for video %s.', job.id, payload.videoUrl) | ||
14 | 15 | ||
15 | if (payload.type === 'video') return refreshAPVideo(payload.videoUrl) | 16 | if (payload.type === 'video') return refreshAPVideo(payload.videoUrl) |
16 | } | 17 | } |
diff --git a/server/lib/job-queue/handlers/video-file.ts b/server/lib/job-queue/handlers/video-file.ts index adc0a2a15..ddbf6d1c2 100644 --- a/server/lib/job-queue/handlers/video-file.ts +++ b/server/lib/job-queue/handlers/video-file.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import * as Bull from 'bull' | 1 | import * as Bull from 'bull' |
2 | import { VideoResolution, VideoState } from '../../../../shared' | 2 | import { VideoResolution, VideoState, Job } from '../../../../shared' |
3 | import { logger } from '../../../helpers/logger' | 3 | import { logger } from '../../../helpers/logger' |
4 | import { VideoModel } from '../../../models/video/video' | 4 | import { VideoModel } from '../../../models/video/video' |
5 | import { JobQueue } from '../job-queue' | 5 | import { JobQueue } from '../job-queue' |
@@ -111,7 +111,7 @@ async function onVideoFileOptimizerSuccess (video: VideoModel, isNewVideo: boole | |||
111 | ) | 111 | ) |
112 | 112 | ||
113 | if (resolutionsEnabled.length !== 0) { | 113 | if (resolutionsEnabled.length !== 0) { |
114 | const tasks: Bluebird<any>[] = [] | 114 | const tasks: Bluebird<Bull.Job<any>>[] = [] |
115 | 115 | ||
116 | for (const resolution of resolutionsEnabled) { | 116 | for (const resolution of resolutionsEnabled) { |
117 | const dataInput = { | 117 | const dataInput = { |
diff --git a/server/lib/job-queue/handlers/video-import.ts b/server/lib/job-queue/handlers/video-import.ts index 4de901c0c..51a0b5faf 100644 --- a/server/lib/job-queue/handlers/video-import.ts +++ b/server/lib/job-queue/handlers/video-import.ts | |||
@@ -7,7 +7,7 @@ import { getDurationFromVideoFile, getVideoFileFPS, getVideoFileResolution } fro | |||
7 | import { extname, join } from 'path' | 7 | import { extname, join } from 'path' |
8 | import { VideoFileModel } from '../../../models/video/video-file' | 8 | import { VideoFileModel } from '../../../models/video/video-file' |
9 | import { CONFIG, PREVIEWS_SIZE, sequelizeTypescript, THUMBNAILS_SIZE, VIDEO_IMPORT_TIMEOUT } from '../../../initializers' | 9 | import { CONFIG, PREVIEWS_SIZE, sequelizeTypescript, THUMBNAILS_SIZE, VIDEO_IMPORT_TIMEOUT } from '../../../initializers' |
10 | import { doRequestAndSaveToFile, downloadImage } from '../../../helpers/requests' | 10 | import { downloadImage } from '../../../helpers/requests' |
11 | import { VideoState } from '../../../../shared' | 11 | import { VideoState } from '../../../../shared' |
12 | import { JobQueue } from '../index' | 12 | import { JobQueue } from '../index' |
13 | import { federateVideoIfNeeded } from '../../activitypub' | 13 | import { federateVideoIfNeeded } from '../../activitypub' |
@@ -109,6 +109,7 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide | |||
109 | let tempVideoPath: string | 109 | let tempVideoPath: string |
110 | let videoDestFile: string | 110 | let videoDestFile: string |
111 | let videoFile: VideoFileModel | 111 | let videoFile: VideoFileModel |
112 | |||
112 | try { | 113 | try { |
113 | // Download video from youtubeDL | 114 | // Download video from youtubeDL |
114 | tempVideoPath = await downloader() | 115 | tempVideoPath = await downloader() |
@@ -144,8 +145,7 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide | |||
144 | // Process thumbnail | 145 | // Process thumbnail |
145 | if (options.downloadThumbnail) { | 146 | if (options.downloadThumbnail) { |
146 | if (options.thumbnailUrl) { | 147 | if (options.thumbnailUrl) { |
147 | const destThumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, videoImport.Video.getThumbnailName()) | 148 | await downloadImage(options.thumbnailUrl, CONFIG.STORAGE.THUMBNAILS_DIR, videoImport.Video.getThumbnailName(), THUMBNAILS_SIZE) |
148 | await downloadImage(options.thumbnailUrl, destThumbnailPath, THUMBNAILS_SIZE) | ||
149 | } else { | 149 | } else { |
150 | await videoImport.Video.createThumbnail(videoFile) | 150 | await videoImport.Video.createThumbnail(videoFile) |
151 | } | 151 | } |
@@ -156,8 +156,7 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide | |||
156 | // Process preview | 156 | // Process preview |
157 | if (options.downloadPreview) { | 157 | if (options.downloadPreview) { |
158 | if (options.thumbnailUrl) { | 158 | if (options.thumbnailUrl) { |
159 | const destPreviewPath = join(CONFIG.STORAGE.PREVIEWS_DIR, videoImport.Video.getPreviewName()) | 159 | await downloadImage(options.thumbnailUrl, CONFIG.STORAGE.PREVIEWS_DIR, videoImport.Video.getPreviewName(), PREVIEWS_SIZE) |
160 | await downloadImage(options.thumbnailUrl, destPreviewPath, PREVIEWS_SIZE) | ||
161 | } else { | 160 | } else { |
162 | await videoImport.Video.createPreview(videoFile) | 161 | await videoImport.Video.createPreview(videoFile) |
163 | } | 162 | } |
diff --git a/server/lib/job-queue/handlers/video-views.ts b/server/lib/job-queue/handlers/video-views.ts index 038ef43e2..fa1fd13b3 100644 --- a/server/lib/job-queue/handlers/video-views.ts +++ b/server/lib/job-queue/handlers/video-views.ts | |||
@@ -23,9 +23,7 @@ async function processVideosViews () { | |||
23 | for (const videoId of videoIds) { | 23 | for (const videoId of videoIds) { |
24 | try { | 24 | try { |
25 | const views = await Redis.Instance.getVideoViews(videoId, hour) | 25 | const views = await Redis.Instance.getVideoViews(videoId, hour) |
26 | if (isNaN(views)) { | 26 | if (views) { |
27 | logger.error('Cannot process videos views of video %d in hour %d: views number is NaN (%s).', videoId, hour, views) | ||
28 | } else { | ||
29 | logger.debug('Adding %d views to video %d in hour %d.', views, videoId, hour) | 27 | logger.debug('Adding %d views to video %d in hour %d.', views, videoId, hour) |
30 | 28 | ||
31 | try { | 29 | try { |
diff --git a/server/lib/redis.ts b/server/lib/redis.ts index abd75d512..3e25e6a2c 100644 --- a/server/lib/redis.ts +++ b/server/lib/redis.ts | |||
@@ -121,7 +121,14 @@ class Redis { | |||
121 | const key = this.generateVideoViewKey(videoId, hour) | 121 | const key = this.generateVideoViewKey(videoId, hour) |
122 | 122 | ||
123 | const valueString = await this.getValue(key) | 123 | const valueString = await this.getValue(key) |
124 | return parseInt(valueString, 10) | 124 | const valueInt = parseInt(valueString, 10) |
125 | |||
126 | if (isNaN(valueInt)) { | ||
127 | logger.error('Cannot get videos views of video %d in hour %d: views number is NaN (%s).', videoId, hour, valueString) | ||
128 | return undefined | ||
129 | } | ||
130 | |||
131 | return valueInt | ||
125 | } | 132 | } |
126 | 133 | ||
127 | async getVideosIdViewed (hour: number) { | 134 | async getVideosIdViewed (hour: number) { |
diff --git a/server/lib/schedulers/videos-redundancy-scheduler.ts b/server/lib/schedulers/videos-redundancy-scheduler.ts index 8b7f33539..2a99a665d 100644 --- a/server/lib/schedulers/videos-redundancy-scheduler.ts +++ b/server/lib/schedulers/videos-redundancy-scheduler.ts | |||
@@ -145,13 +145,13 @@ export class VideosRedundancyScheduler extends AbstractScheduler { | |||
145 | 145 | ||
146 | const tmpPath = await downloadWebTorrentVideo({ magnetUri }, VIDEO_IMPORT_TIMEOUT) | 146 | const tmpPath = await downloadWebTorrentVideo({ magnetUri }, VIDEO_IMPORT_TIMEOUT) |
147 | 147 | ||
148 | const destPath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename(file)) | 148 | const destPath = join(CONFIG.STORAGE.REDUNDANCY_DIR, video.getVideoFilename(file)) |
149 | await rename(tmpPath, destPath) | 149 | await rename(tmpPath, destPath) |
150 | 150 | ||
151 | const createdModel = await VideoRedundancyModel.create({ | 151 | const createdModel = await VideoRedundancyModel.create({ |
152 | expiresOn: this.buildNewExpiration(redundancy.minLifetime), | 152 | expiresOn: this.buildNewExpiration(redundancy.minLifetime), |
153 | url: getVideoCacheFileActivityPubUrl(file), | 153 | url: getVideoCacheFileActivityPubUrl(file), |
154 | fileUrl: video.getVideoFileUrl(file, CONFIG.WEBSERVER.URL), | 154 | fileUrl: video.getVideoRedundancyUrl(file, CONFIG.WEBSERVER.URL), |
155 | strategy: redundancy.strategy, | 155 | strategy: redundancy.strategy, |
156 | videoFileId: file.id, | 156 | videoFileId: file.id, |
157 | actorId: serverActor.id | 157 | actorId: serverActor.id |