diff options
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/activitypub/actor.ts | 2 | ||||
-rw-r--r-- | server/lib/activitypub/videos.ts | 3 | ||||
-rw-r--r-- | server/lib/hls.ts | 11 | ||||
-rw-r--r-- | server/lib/moderation.ts | 5 | ||||
-rw-r--r-- | server/lib/plugins/plugin-helpers-builder.ts | 8 | ||||
-rw-r--r-- | server/lib/schedulers/remove-dangling-resumable-uploads-scheduler.ts | 61 | ||||
-rw-r--r-- | server/lib/video.ts | 3 |
7 files changed, 83 insertions, 10 deletions
diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts index eec951d4e..5fe7381c9 100644 --- a/server/lib/activitypub/actor.ts +++ b/server/lib/activitypub/actor.ts | |||
@@ -165,6 +165,8 @@ async function updateActorInstance (actorInstance: ActorModel, attributes: Activ | |||
165 | actorInstance.followersUrl = attributes.followers | 165 | actorInstance.followersUrl = attributes.followers |
166 | actorInstance.followingUrl = attributes.following | 166 | actorInstance.followingUrl = attributes.following |
167 | 167 | ||
168 | if (attributes.published) actorInstance.remoteCreatedAt = new Date(attributes.published) | ||
169 | |||
168 | if (attributes.endpoints?.sharedInbox) { | 170 | if (attributes.endpoints?.sharedInbox) { |
169 | actorInstance.sharedInboxUrl = attributes.endpoints.sharedInbox | 171 | actorInstance.sharedInboxUrl = attributes.endpoints.sharedInbox |
170 | } | 172 | } |
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts index 506204674..15726f90b 100644 --- a/server/lib/activitypub/videos.ts +++ b/server/lib/activitypub/videos.ts | |||
@@ -697,6 +697,9 @@ async function createVideo (videoObject: VideoObject, channel: MChannelAccountLi | |||
697 | videoCreated.VideoLive = await videoLive.save({ transaction: t }) | 697 | videoCreated.VideoLive = await videoLive.save({ transaction: t }) |
698 | } | 698 | } |
699 | 699 | ||
700 | // We added a video in this channel, set it as updated | ||
701 | await channel.setAsUpdated(t) | ||
702 | |||
700 | const autoBlacklisted = await autoBlacklistVideoIfNeeded({ | 703 | const autoBlacklisted = await autoBlacklistVideoIfNeeded({ |
701 | video: videoCreated, | 704 | video: videoCreated, |
702 | user: undefined, | 705 | user: undefined, |
diff --git a/server/lib/hls.ts b/server/lib/hls.ts index 84539e2c1..05be403f3 100644 --- a/server/lib/hls.ts +++ b/server/lib/hls.ts | |||
@@ -50,13 +50,12 @@ async function updateMasterHLSPlaylist (video: MVideoWithFile) { | |||
50 | let line = `#EXT-X-STREAM-INF:${bandwidth},${resolution}` | 50 | let line = `#EXT-X-STREAM-INF:${bandwidth},${resolution}` |
51 | if (file.fps) line += ',FRAME-RATE=' + file.fps | 51 | if (file.fps) line += ',FRAME-RATE=' + file.fps |
52 | 52 | ||
53 | const videoCodec = await getVideoStreamCodec(videoFilePath) | 53 | const codecs = await Promise.all([ |
54 | line += `,CODECS="${videoCodec}` | 54 | getVideoStreamCodec(videoFilePath), |
55 | getAudioStreamCodec(videoFilePath) | ||
56 | ]) | ||
55 | 57 | ||
56 | const audioCodec = await getAudioStreamCodec(videoFilePath) | 58 | line += `,CODECS="${codecs.filter(c => !!c).join(',')}"` |
57 | if (audioCodec) line += `,${audioCodec}` | ||
58 | |||
59 | line += '"' | ||
60 | 59 | ||
61 | masterPlaylists.push(line) | 60 | masterPlaylists.push(line) |
62 | masterPlaylists.push(VideoStreamingPlaylistModel.getHlsPlaylistFilename(file.resolution)) | 61 | masterPlaylists.push(VideoStreamingPlaylistModel.getHlsPlaylistFilename(file.resolution)) |
diff --git a/server/lib/moderation.ts b/server/lib/moderation.ts index 5180b3299..925d64902 100644 --- a/server/lib/moderation.ts +++ b/server/lib/moderation.ts | |||
@@ -1,6 +1,8 @@ | |||
1 | import { VideoUploadFile } from 'express' | ||
1 | import { PathLike } from 'fs-extra' | 2 | import { PathLike } from 'fs-extra' |
2 | import { Transaction } from 'sequelize/types' | 3 | import { Transaction } from 'sequelize/types' |
3 | import { AbuseAuditView, auditLoggerFactory } from '@server/helpers/audit-logger' | 4 | import { AbuseAuditView, auditLoggerFactory } from '@server/helpers/audit-logger' |
5 | import { afterCommitIfTransaction } from '@server/helpers/database-utils' | ||
4 | import { logger } from '@server/helpers/logger' | 6 | import { logger } from '@server/helpers/logger' |
5 | import { AbuseModel } from '@server/models/abuse/abuse' | 7 | import { AbuseModel } from '@server/models/abuse/abuse' |
6 | import { VideoAbuseModel } from '@server/models/abuse/video-abuse' | 8 | import { VideoAbuseModel } from '@server/models/abuse/video-abuse' |
@@ -28,7 +30,6 @@ import { VideoModel } from '../models/video/video' | |||
28 | import { VideoCommentModel } from '../models/video/video-comment' | 30 | import { VideoCommentModel } from '../models/video/video-comment' |
29 | import { sendAbuse } from './activitypub/send/send-flag' | 31 | import { sendAbuse } from './activitypub/send/send-flag' |
30 | import { Notifier } from './notifier' | 32 | import { Notifier } from './notifier' |
31 | import { afterCommitIfTransaction } from '@server/helpers/database-utils' | ||
32 | 33 | ||
33 | export type AcceptResult = { | 34 | export type AcceptResult = { |
34 | accepted: boolean | 35 | accepted: boolean |
@@ -38,7 +39,7 @@ export type AcceptResult = { | |||
38 | // Can be filtered by plugins | 39 | // Can be filtered by plugins |
39 | function isLocalVideoAccepted (object: { | 40 | function isLocalVideoAccepted (object: { |
40 | videoBody: VideoCreate | 41 | videoBody: VideoCreate |
41 | videoFile: Express.Multer.File & { duration?: number } | 42 | videoFile: VideoUploadFile |
42 | user: UserModel | 43 | user: UserModel |
43 | }): AcceptResult { | 44 | }): AcceptResult { |
44 | return { accepted: true } | 45 | return { accepted: true } |
diff --git a/server/lib/plugins/plugin-helpers-builder.ts b/server/lib/plugins/plugin-helpers-builder.ts index d57c69ef0..f1bc24d8b 100644 --- a/server/lib/plugins/plugin-helpers-builder.ts +++ b/server/lib/plugins/plugin-helpers-builder.ts | |||
@@ -17,6 +17,7 @@ import { VideoBlacklistCreate } from '@shared/models' | |||
17 | import { addAccountInBlocklist, addServerInBlocklist, removeAccountFromBlocklist, removeServerFromBlocklist } from '../blocklist' | 17 | import { addAccountInBlocklist, addServerInBlocklist, removeAccountFromBlocklist, removeServerFromBlocklist } from '../blocklist' |
18 | import { getServerConfig } from '../config' | 18 | import { getServerConfig } from '../config' |
19 | import { blacklistVideo, unblacklistVideo } from '../video-blacklist' | 19 | import { blacklistVideo, unblacklistVideo } from '../video-blacklist' |
20 | import { UserModel } from '@server/models/account/user' | ||
20 | 21 | ||
21 | function buildPluginHelpers (pluginModel: MPlugin, npmName: string): PeerTubeHelpers { | 22 | function buildPluginHelpers (pluginModel: MPlugin, npmName: string): PeerTubeHelpers { |
22 | const logger = buildPluginLogger(npmName) | 23 | const logger = buildPluginLogger(npmName) |
@@ -163,6 +164,11 @@ function buildPluginRelatedHelpers (plugin: MPlugin, npmName: string) { | |||
163 | 164 | ||
164 | function buildUserHelpers () { | 165 | function buildUserHelpers () { |
165 | return { | 166 | return { |
166 | getAuthUser: (res: express.Response) => res.locals.oauth?.token?.User | 167 | getAuthUser: (res: express.Response) => { |
168 | const user = res.locals.oauth?.token?.User | ||
169 | if (!user) return undefined | ||
170 | |||
171 | return UserModel.loadByIdFull(user.id) | ||
172 | } | ||
167 | } | 173 | } |
168 | } | 174 | } |
diff --git a/server/lib/schedulers/remove-dangling-resumable-uploads-scheduler.ts b/server/lib/schedulers/remove-dangling-resumable-uploads-scheduler.ts new file mode 100644 index 000000000..1acea7998 --- /dev/null +++ b/server/lib/schedulers/remove-dangling-resumable-uploads-scheduler.ts | |||
@@ -0,0 +1,61 @@ | |||
1 | import * as bluebird from 'bluebird' | ||
2 | import { readdir, remove, stat } from 'fs-extra' | ||
3 | import { logger, loggerTagsFactory } from '@server/helpers/logger' | ||
4 | import { getResumableUploadPath } from '@server/helpers/upload' | ||
5 | import { SCHEDULER_INTERVALS_MS } from '@server/initializers/constants' | ||
6 | import { METAFILE_EXTNAME } from '@uploadx/core' | ||
7 | import { AbstractScheduler } from './abstract-scheduler' | ||
8 | |||
9 | const lTags = loggerTagsFactory('scheduler', 'resumable-upload', 'cleaner') | ||
10 | |||
11 | export class RemoveDanglingResumableUploadsScheduler extends AbstractScheduler { | ||
12 | |||
13 | private static instance: AbstractScheduler | ||
14 | private lastExecutionTimeMs: number | ||
15 | |||
16 | protected schedulerIntervalMs = SCHEDULER_INTERVALS_MS.removeDanglingResumableUploads | ||
17 | |||
18 | private constructor () { | ||
19 | super() | ||
20 | |||
21 | this.lastExecutionTimeMs = new Date().getTime() | ||
22 | } | ||
23 | |||
24 | protected async internalExecute () { | ||
25 | const path = getResumableUploadPath() | ||
26 | const files = await readdir(path) | ||
27 | |||
28 | const metafiles = files.filter(f => f.endsWith(METAFILE_EXTNAME)) | ||
29 | |||
30 | if (metafiles.length === 0) return | ||
31 | |||
32 | logger.debug('Reading resumable video upload folder %s with %d files', path, metafiles.length, lTags()) | ||
33 | |||
34 | try { | ||
35 | await bluebird.map(metafiles, metafile => { | ||
36 | return this.deleteIfOlderThan(metafile, this.lastExecutionTimeMs) | ||
37 | }, { concurrency: 5 }) | ||
38 | } catch (error) { | ||
39 | logger.error('Failed to handle file during resumable video upload folder cleanup', { error, ...lTags() }) | ||
40 | } finally { | ||
41 | this.lastExecutionTimeMs = new Date().getTime() | ||
42 | } | ||
43 | } | ||
44 | |||
45 | private async deleteIfOlderThan (metafile: string, olderThan: number) { | ||
46 | const metafilePath = getResumableUploadPath(metafile) | ||
47 | const statResult = await stat(metafilePath) | ||
48 | |||
49 | // Delete uploads that started since a long time | ||
50 | if (statResult.ctimeMs < olderThan) { | ||
51 | await remove(metafilePath) | ||
52 | |||
53 | const datafile = metafilePath.replace(new RegExp(`${METAFILE_EXTNAME}$`), '') | ||
54 | await remove(datafile) | ||
55 | } | ||
56 | } | ||
57 | |||
58 | static get Instance () { | ||
59 | return this.instance || (this.instance = new this()) | ||
60 | } | ||
61 | } | ||
diff --git a/server/lib/video.ts b/server/lib/video.ts index 9469b8178..21e4b7ff2 100644 --- a/server/lib/video.ts +++ b/server/lib/video.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | import { UploadFiles } from 'express' | ||
1 | import { Transaction } from 'sequelize/types' | 2 | import { Transaction } from 'sequelize/types' |
2 | import { DEFAULT_AUDIO_RESOLUTION, JOB_PRIORITY } from '@server/initializers/constants' | 3 | import { DEFAULT_AUDIO_RESOLUTION, JOB_PRIORITY } from '@server/initializers/constants' |
3 | import { sequelizeTypescript } from '@server/initializers/database' | 4 | import { sequelizeTypescript } from '@server/initializers/database' |
@@ -32,7 +33,7 @@ function buildLocalVideoFromReq (videoInfo: VideoCreate, channelId: number): Fil | |||
32 | 33 | ||
33 | async function buildVideoThumbnailsFromReq (options: { | 34 | async function buildVideoThumbnailsFromReq (options: { |
34 | video: MVideoThumbnail | 35 | video: MVideoThumbnail |
35 | files: { [fieldname: string]: Express.Multer.File[] } | Express.Multer.File[] | 36 | files: UploadFiles |
36 | fallback: (type: ThumbnailType) => Promise<MThumbnail> | 37 | fallback: (type: ThumbnailType) => Promise<MThumbnail> |
37 | automaticallyGenerated?: boolean | 38 | automaticallyGenerated?: boolean |
38 | }) { | 39 | }) { |