aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib
diff options
context:
space:
mode:
Diffstat (limited to 'server/lib')
-rw-r--r--server/lib/activitypub/actor.ts4
-rw-r--r--server/lib/activitypub/process/process-update.ts2
-rw-r--r--server/lib/activitypub/videos.ts24
-rw-r--r--server/lib/emailer.ts7
-rw-r--r--server/lib/job-queue/handlers/activitypub-refresher.ts3
-rw-r--r--server/lib/job-queue/handlers/video-file.ts4
-rw-r--r--server/lib/job-queue/handlers/video-import.ts9
-rw-r--r--server/lib/job-queue/handlers/video-views.ts4
-rw-r--r--server/lib/redis.ts9
-rw-r--r--server/lib/schedulers/videos-redundancy-scheduler.ts4
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
96function generateThumbnailFromUrl (video: VideoModel, icon: ActivityIconObject) { 96function 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
103function getOrCreateVideoChannelFromVideoObject (videoObject: VideoTorrentObject) { 102function getOrCreateVideoChannelFromVideoObject (videoObject: VideoTorrentObject) {
@@ -158,25 +157,30 @@ async function syncVideoExternalAttributes (video: VideoModel, fetchedVideo: Vid
158async function getOrCreateVideoAndAccountAndChannel (options: { 157async 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
11async function refreshAPObject (job: Bull.Job) { 11async 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 @@
1import * as Bull from 'bull' 1import * as Bull from 'bull'
2import { VideoResolution, VideoState } from '../../../../shared' 2import { VideoResolution, VideoState, Job } from '../../../../shared'
3import { logger } from '../../../helpers/logger' 3import { logger } from '../../../helpers/logger'
4import { VideoModel } from '../../../models/video/video' 4import { VideoModel } from '../../../models/video/video'
5import { JobQueue } from '../job-queue' 5import { 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
7import { extname, join } from 'path' 7import { extname, join } from 'path'
8import { VideoFileModel } from '../../../models/video/video-file' 8import { VideoFileModel } from '../../../models/video/video-file'
9import { CONFIG, PREVIEWS_SIZE, sequelizeTypescript, THUMBNAILS_SIZE, VIDEO_IMPORT_TIMEOUT } from '../../../initializers' 9import { CONFIG, PREVIEWS_SIZE, sequelizeTypescript, THUMBNAILS_SIZE, VIDEO_IMPORT_TIMEOUT } from '../../../initializers'
10import { doRequestAndSaveToFile, downloadImage } from '../../../helpers/requests' 10import { downloadImage } from '../../../helpers/requests'
11import { VideoState } from '../../../../shared' 11import { VideoState } from '../../../../shared'
12import { JobQueue } from '../index' 12import { JobQueue } from '../index'
13import { federateVideoIfNeeded } from '../../activitypub' 13import { 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