diff options
Diffstat (limited to 'server/lib')
44 files changed, 525 insertions, 453 deletions
diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts index 5fe7381c9..1bcee7ef9 100644 --- a/server/lib/activitypub/actor.ts +++ b/server/lib/activitypub/actor.ts | |||
@@ -20,8 +20,8 @@ import { getUrlFromWebfinger } from '../../helpers/webfinger' | |||
20 | import { MIMETYPES, WEBSERVER } from '../../initializers/constants' | 20 | import { MIMETYPES, WEBSERVER } from '../../initializers/constants' |
21 | import { sequelizeTypescript } from '../../initializers/database' | 21 | import { sequelizeTypescript } from '../../initializers/database' |
22 | import { AccountModel } from '../../models/account/account' | 22 | import { AccountModel } from '../../models/account/account' |
23 | import { ActorImageModel } from '../../models/account/actor-image' | 23 | import { ActorModel } from '../../models/actor/actor' |
24 | import { ActorModel } from '../../models/activitypub/actor' | 24 | import { ActorImageModel } from '../../models/actor/actor-image' |
25 | import { ServerModel } from '../../models/server/server' | 25 | import { ServerModel } from '../../models/server/server' |
26 | import { VideoChannelModel } from '../../models/video/video-channel' | 26 | import { VideoChannelModel } from '../../models/video/video-channel' |
27 | import { | 27 | import { |
@@ -132,12 +132,11 @@ async function getOrCreateActorAndServerAndModel ( | |||
132 | return actorRefreshed | 132 | return actorRefreshed |
133 | } | 133 | } |
134 | 134 | ||
135 | function buildActorInstance (type: ActivityPubActorType, url: string, preferredUsername: string, uuid?: string) { | 135 | function buildActorInstance (type: ActivityPubActorType, url: string, preferredUsername: string) { |
136 | return new ActorModel({ | 136 | return new ActorModel({ |
137 | type, | 137 | type, |
138 | url, | 138 | url, |
139 | preferredUsername, | 139 | preferredUsername, |
140 | uuid, | ||
141 | publicKey: null, | 140 | publicKey: null, |
142 | privateKey: null, | 141 | privateKey: null, |
143 | followersCount: 0, | 142 | followersCount: 0, |
diff --git a/server/lib/activitypub/audience.ts b/server/lib/activitypub/audience.ts index 2986714d3..d0558f191 100644 --- a/server/lib/activitypub/audience.ts +++ b/server/lib/activitypub/audience.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { Transaction } from 'sequelize' | 1 | import { Transaction } from 'sequelize' |
2 | import { ActivityAudience } from '../../../shared/models/activitypub' | 2 | import { ActivityAudience } from '../../../shared/models/activitypub' |
3 | import { ACTIVITY_PUB } from '../../initializers/constants' | 3 | import { ACTIVITY_PUB } from '../../initializers/constants' |
4 | import { ActorModel } from '../../models/activitypub/actor' | 4 | import { ActorModel } from '../../models/actor/actor' |
5 | import { VideoModel } from '../../models/video/video' | 5 | import { VideoModel } from '../../models/video/video' |
6 | import { VideoShareModel } from '../../models/video/video-share' | 6 | import { VideoShareModel } from '../../models/video/video-share' |
7 | import { MActorFollowersUrl, MActorLight, MActorUrl, MCommentOwner, MCommentOwnerVideo, MVideoId } from '../../types/models' | 7 | import { MActorFollowersUrl, MActorLight, MActorUrl, MCommentOwner, MCommentOwnerVideo, MVideoId } from '../../types/models' |
diff --git a/server/lib/activitypub/process/process-accept.ts b/server/lib/activitypub/process/process-accept.ts index 1799829f8..8ad470cf4 100644 --- a/server/lib/activitypub/process/process-accept.ts +++ b/server/lib/activitypub/process/process-accept.ts | |||
@@ -1,8 +1,8 @@ | |||
1 | import { ActivityAccept } from '../../../../shared/models/activitypub' | 1 | import { ActivityAccept } from '../../../../shared/models/activitypub' |
2 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | 2 | import { ActorFollowModel } from '../../../models/actor/actor-follow' |
3 | import { addFetchOutboxJob } from '../actor' | ||
4 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' | 3 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' |
5 | import { MActorDefault, MActorSignature } from '../../../types/models' | 4 | import { MActorDefault, MActorSignature } from '../../../types/models' |
5 | import { addFetchOutboxJob } from '../actor' | ||
6 | 6 | ||
7 | async function processAcceptActivity (options: APProcessorOptions<ActivityAccept>) { | 7 | async function processAcceptActivity (options: APProcessorOptions<ActivityAccept>) { |
8 | const { byActor: targetActor, inboxActor } = options | 8 | const { byActor: targetActor, inboxActor } = options |
diff --git a/server/lib/activitypub/process/process-delete.ts b/server/lib/activitypub/process/process-delete.ts index 88a968318..20214246c 100644 --- a/server/lib/activitypub/process/process-delete.ts +++ b/server/lib/activitypub/process/process-delete.ts | |||
@@ -2,7 +2,7 @@ import { ActivityDelete } from '../../../../shared/models/activitypub' | |||
2 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 2 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
3 | import { logger } from '../../../helpers/logger' | 3 | import { logger } from '../../../helpers/logger' |
4 | import { sequelizeTypescript } from '../../../initializers/database' | 4 | import { sequelizeTypescript } from '../../../initializers/database' |
5 | import { ActorModel } from '../../../models/activitypub/actor' | 5 | import { ActorModel } from '../../../models/actor/actor' |
6 | import { VideoModel } from '../../../models/video/video' | 6 | import { VideoModel } from '../../../models/video/video' |
7 | import { VideoCommentModel } from '../../../models/video/video-comment' | 7 | import { VideoCommentModel } from '../../../models/video/video-comment' |
8 | import { VideoPlaylistModel } from '../../../models/video/video-playlist' | 8 | import { VideoPlaylistModel } from '../../../models/video/video-playlist' |
diff --git a/server/lib/activitypub/process/process-follow.ts b/server/lib/activitypub/process/process-follow.ts index 38d684512..9009c6469 100644 --- a/server/lib/activitypub/process/process-follow.ts +++ b/server/lib/activitypub/process/process-follow.ts | |||
@@ -1,17 +1,17 @@ | |||
1 | import { getServerActor } from '@server/models/application/application' | ||
1 | import { ActivityFollow } from '../../../../shared/models/activitypub' | 2 | import { ActivityFollow } from '../../../../shared/models/activitypub' |
3 | import { getAPId } from '../../../helpers/activitypub' | ||
2 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 4 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
3 | import { logger } from '../../../helpers/logger' | 5 | import { logger } from '../../../helpers/logger' |
4 | import { sequelizeTypescript } from '../../../initializers/database' | ||
5 | import { ActorModel } from '../../../models/activitypub/actor' | ||
6 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | ||
7 | import { sendAccept, sendReject } from '../send' | ||
8 | import { Notifier } from '../../notifier' | ||
9 | import { getAPId } from '../../../helpers/activitypub' | ||
10 | import { CONFIG } from '../../../initializers/config' | 6 | import { CONFIG } from '../../../initializers/config' |
7 | import { sequelizeTypescript } from '../../../initializers/database' | ||
8 | import { ActorModel } from '../../../models/actor/actor' | ||
9 | import { ActorFollowModel } from '../../../models/actor/actor-follow' | ||
11 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' | 10 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' |
12 | import { MActorFollowActors, MActorSignature } from '../../../types/models' | 11 | import { MActorFollowActors, MActorSignature } from '../../../types/models' |
12 | import { Notifier } from '../../notifier' | ||
13 | import { autoFollowBackIfNeeded } from '../follow' | 13 | import { autoFollowBackIfNeeded } from '../follow' |
14 | import { getServerActor } from '@server/models/application/application' | 14 | import { sendAccept, sendReject } from '../send' |
15 | 15 | ||
16 | async function processFollowActivity (options: APProcessorOptions<ActivityFollow>) { | 16 | async function processFollowActivity (options: APProcessorOptions<ActivityFollow>) { |
17 | const { activity, byActor } = options | 17 | const { activity, byActor } = options |
diff --git a/server/lib/activitypub/process/process-reject.ts b/server/lib/activitypub/process/process-reject.ts index 03b669fd9..7f7ab305f 100644 --- a/server/lib/activitypub/process/process-reject.ts +++ b/server/lib/activitypub/process/process-reject.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { ActivityReject } from '../../../../shared/models/activitypub/activity' | 1 | import { ActivityReject } from '../../../../shared/models/activitypub/activity' |
2 | import { sequelizeTypescript } from '../../../initializers/database' | 2 | import { sequelizeTypescript } from '../../../initializers/database' |
3 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | 3 | import { ActorFollowModel } from '../../../models/actor/actor-follow' |
4 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' | 4 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' |
5 | import { MActor } from '../../../types/models' | 5 | import { MActor } from '../../../types/models' |
6 | 6 | ||
diff --git a/server/lib/activitypub/process/process-undo.ts b/server/lib/activitypub/process/process-undo.ts index e520c2f0d..9f031b528 100644 --- a/server/lib/activitypub/process/process-undo.ts +++ b/server/lib/activitypub/process/process-undo.ts | |||
@@ -4,8 +4,8 @@ import { retryTransactionWrapper } from '../../../helpers/database-utils' | |||
4 | import { logger } from '../../../helpers/logger' | 4 | import { logger } from '../../../helpers/logger' |
5 | import { sequelizeTypescript } from '../../../initializers/database' | 5 | import { sequelizeTypescript } from '../../../initializers/database' |
6 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' | 6 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' |
7 | import { ActorModel } from '../../../models/activitypub/actor' | 7 | import { ActorModel } from '../../../models/actor/actor' |
8 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | 8 | import { ActorFollowModel } from '../../../models/actor/actor-follow' |
9 | import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy' | 9 | import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy' |
10 | import { VideoShareModel } from '../../../models/video/video-share' | 10 | import { VideoShareModel } from '../../../models/video/video-share' |
11 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' | 11 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' |
diff --git a/server/lib/activitypub/process/process-update.ts b/server/lib/activitypub/process/process-update.ts index 6df9b93b2..6cd9d0fba 100644 --- a/server/lib/activitypub/process/process-update.ts +++ b/server/lib/activitypub/process/process-update.ts | |||
@@ -1,23 +1,23 @@ | |||
1 | import { isRedundancyAccepted } from '@server/lib/redundancy' | ||
2 | import { ActorImageType } from '@shared/models' | ||
1 | import { ActivityUpdate, CacheFileObject, VideoObject } from '../../../../shared/models/activitypub' | 3 | import { ActivityUpdate, CacheFileObject, VideoObject } from '../../../../shared/models/activitypub' |
2 | import { ActivityPubActor } from '../../../../shared/models/activitypub/activitypub-actor' | 4 | import { ActivityPubActor } from '../../../../shared/models/activitypub/activitypub-actor' |
5 | import { PlaylistObject } from '../../../../shared/models/activitypub/objects/playlist-object' | ||
6 | import { isCacheFileObjectValid } from '../../../helpers/custom-validators/activitypub/cache-file' | ||
7 | import { sanitizeAndCheckVideoTorrentObject } from '../../../helpers/custom-validators/activitypub/videos' | ||
3 | import { resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers/database-utils' | 8 | import { resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers/database-utils' |
4 | import { logger } from '../../../helpers/logger' | 9 | import { logger } from '../../../helpers/logger' |
5 | import { sequelizeTypescript } from '../../../initializers/database' | 10 | import { sequelizeTypescript } from '../../../initializers/database' |
6 | import { AccountModel } from '../../../models/account/account' | 11 | import { AccountModel } from '../../../models/account/account' |
7 | import { ActorModel } from '../../../models/activitypub/actor' | 12 | import { ActorModel } from '../../../models/actor/actor' |
8 | import { VideoChannelModel } from '../../../models/video/video-channel' | 13 | import { VideoChannelModel } from '../../../models/video/video-channel' |
14 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' | ||
15 | import { MAccountIdActor, MActorSignature } from '../../../types/models' | ||
9 | import { getImageInfoIfExists, updateActorImageInstance, updateActorInstance } from '../actor' | 16 | import { getImageInfoIfExists, updateActorImageInstance, updateActorInstance } from '../actor' |
10 | import { getOrCreateVideoAndAccountAndChannel, getOrCreateVideoChannelFromVideoObject, updateVideoFromAP } from '../videos' | ||
11 | import { sanitizeAndCheckVideoTorrentObject } from '../../../helpers/custom-validators/activitypub/videos' | ||
12 | import { isCacheFileObjectValid } from '../../../helpers/custom-validators/activitypub/cache-file' | ||
13 | import { createOrUpdateCacheFile } from '../cache-file' | 17 | import { createOrUpdateCacheFile } from '../cache-file' |
14 | import { forwardVideoRelatedActivity } from '../send/utils' | ||
15 | import { PlaylistObject } from '../../../../shared/models/activitypub/objects/playlist-object' | ||
16 | import { createOrUpdateVideoPlaylist } from '../playlist' | 18 | import { createOrUpdateVideoPlaylist } from '../playlist' |
17 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' | 19 | import { forwardVideoRelatedActivity } from '../send/utils' |
18 | import { MActorSignature, MAccountIdActor } from '../../../types/models' | 20 | import { getOrCreateVideoAndAccountAndChannel, getOrCreateVideoChannelFromVideoObject, updateVideoFromAP } from '../videos' |
19 | import { isRedundancyAccepted } from '@server/lib/redundancy' | ||
20 | import { ActorImageType } from '@shared/models' | ||
21 | 21 | ||
22 | async function processUpdateActivity (options: APProcessorOptions<ActivityUpdate>) { | 22 | async function processUpdateActivity (options: APProcessorOptions<ActivityUpdate>) { |
23 | const { activity, byActor } = options | 23 | const { activity, byActor } = options |
diff --git a/server/lib/activitypub/send/send-delete.ts b/server/lib/activitypub/send/send-delete.ts index e0acced18..d31f8c10b 100644 --- a/server/lib/activitypub/send/send-delete.ts +++ b/server/lib/activitypub/send/send-delete.ts | |||
@@ -2,7 +2,7 @@ import { Transaction } from 'sequelize' | |||
2 | import { getServerActor } from '@server/models/application/application' | 2 | import { getServerActor } from '@server/models/application/application' |
3 | import { ActivityAudience, ActivityDelete } from '../../../../shared/models/activitypub' | 3 | import { ActivityAudience, ActivityDelete } from '../../../../shared/models/activitypub' |
4 | import { logger } from '../../../helpers/logger' | 4 | import { logger } from '../../../helpers/logger' |
5 | import { ActorModel } from '../../../models/activitypub/actor' | 5 | import { ActorModel } from '../../../models/actor/actor' |
6 | import { VideoCommentModel } from '../../../models/video/video-comment' | 6 | import { VideoCommentModel } from '../../../models/video/video-comment' |
7 | import { VideoShareModel } from '../../../models/video/video-share' | 7 | import { VideoShareModel } from '../../../models/video/video-share' |
8 | import { MActorUrl } from '../../../types/models' | 8 | import { MActorUrl } from '../../../types/models' |
diff --git a/server/lib/activitypub/send/send-view.ts b/server/lib/activitypub/send/send-view.ts index 9254dc7c5..153e94295 100644 --- a/server/lib/activitypub/send/send-view.ts +++ b/server/lib/activitypub/send/send-view.ts | |||
@@ -2,7 +2,7 @@ import { Transaction } from 'sequelize' | |||
2 | import { MActorAudience, MVideoImmutable, MVideoUrl } from '@server/types/models' | 2 | import { MActorAudience, MVideoImmutable, MVideoUrl } from '@server/types/models' |
3 | import { ActivityAudience, ActivityView } from '../../../../shared/models/activitypub' | 3 | import { ActivityAudience, ActivityView } from '../../../../shared/models/activitypub' |
4 | import { logger } from '../../../helpers/logger' | 4 | import { logger } from '../../../helpers/logger' |
5 | import { ActorModel } from '../../../models/activitypub/actor' | 5 | import { ActorModel } from '../../../models/actor/actor' |
6 | import { audiencify, getAudience } from '../audience' | 6 | import { audiencify, getAudience } from '../audience' |
7 | import { getLocalVideoViewActivityPubUrl } from '../url' | 7 | import { getLocalVideoViewActivityPubUrl } from '../url' |
8 | import { sendVideoRelatedActivity } from './utils' | 8 | import { sendVideoRelatedActivity } from './utils' |
diff --git a/server/lib/activitypub/send/utils.ts b/server/lib/activitypub/send/utils.ts index 85a9f009d..db0e91b71 100644 --- a/server/lib/activitypub/send/utils.ts +++ b/server/lib/activitypub/send/utils.ts | |||
@@ -1,14 +1,14 @@ | |||
1 | import { Transaction } from 'sequelize' | 1 | import { Transaction } from 'sequelize' |
2 | import { getServerActor } from '@server/models/application/application' | ||
3 | import { ContextType } from '@shared/models/activitypub/context' | ||
2 | import { Activity, ActivityAudience } from '../../../../shared/models/activitypub' | 4 | import { Activity, ActivityAudience } from '../../../../shared/models/activitypub' |
5 | import { afterCommitIfTransaction } from '../../../helpers/database-utils' | ||
3 | import { logger } from '../../../helpers/logger' | 6 | import { logger } from '../../../helpers/logger' |
4 | import { ActorModel } from '../../../models/activitypub/actor' | 7 | import { ActorModel } from '../../../models/actor/actor' |
5 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | 8 | import { ActorFollowModel } from '../../../models/actor/actor-follow' |
9 | import { MActor, MActorId, MActorLight, MActorWithInboxes, MVideoAccountLight, MVideoId, MVideoImmutable } from '../../../types/models' | ||
6 | import { JobQueue } from '../../job-queue' | 10 | import { JobQueue } from '../../job-queue' |
7 | import { getActorsInvolvedInVideo, getAudienceFromFollowersOf, getRemoteVideoAudience } from '../audience' | 11 | import { getActorsInvolvedInVideo, getAudienceFromFollowersOf, getRemoteVideoAudience } from '../audience' |
8 | import { afterCommitIfTransaction } from '../../../helpers/database-utils' | ||
9 | import { MActor, MActorId, MActorLight, MActorWithInboxes, MVideoAccountLight, MVideoId, MVideoImmutable } from '../../../types/models' | ||
10 | import { getServerActor } from '@server/models/application/application' | ||
11 | import { ContextType } from '@shared/models/activitypub/context' | ||
12 | 12 | ||
13 | async function sendVideoRelatedActivity (activityBuilder: (audience: ActivityAudience) => Activity, options: { | 13 | async function sendVideoRelatedActivity (activityBuilder: (audience: ActivityAudience) => Activity, options: { |
14 | byActor: MActorLight | 14 | byActor: MActorLight |
diff --git a/server/lib/auth/oauth-model.ts b/server/lib/auth/oauth-model.ts index b9c69eb2d..ae728d080 100644 --- a/server/lib/auth/oauth-model.ts +++ b/server/lib/auth/oauth-model.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { AccessDeniedError } from 'oauth2-server' | 2 | import { AccessDeniedError } from 'oauth2-server' |
3 | import { PluginManager } from '@server/lib/plugins/plugin-manager' | 3 | import { PluginManager } from '@server/lib/plugins/plugin-manager' |
4 | import { ActorModel } from '@server/models/activitypub/actor' | 4 | import { ActorModel } from '@server/models/actor/actor' |
5 | import { MOAuthClient } from '@server/types/models' | 5 | import { MOAuthClient } from '@server/types/models' |
6 | import { MOAuthTokenUser } from '@server/types/models/oauth/oauth-token' | 6 | import { MOAuthTokenUser } from '@server/types/models/oauth/oauth-token' |
7 | import { MUser } from '@server/types/models/user/user' | 7 | import { MUser } from '@server/types/models/user/user' |
@@ -9,7 +9,7 @@ import { UserAdminFlag } from '@shared/models/users/user-flag.model' | |||
9 | import { UserRole } from '@shared/models/users/user-role' | 9 | import { UserRole } from '@shared/models/users/user-role' |
10 | import { logger } from '../../helpers/logger' | 10 | import { logger } from '../../helpers/logger' |
11 | import { CONFIG } from '../../initializers/config' | 11 | import { CONFIG } from '../../initializers/config' |
12 | import { UserModel } from '../../models/account/user' | 12 | import { UserModel } from '../../models/user/user' |
13 | import { OAuthClientModel } from '../../models/oauth/oauth-client' | 13 | import { OAuthClientModel } from '../../models/oauth/oauth-client' |
14 | import { OAuthTokenModel } from '../../models/oauth/oauth-token' | 14 | import { OAuthTokenModel } from '../../models/oauth/oauth-token' |
15 | import { createUserAccountAndChannelAndPlaylist } from '../user' | 15 | import { createUserAccountAndChannelAndPlaylist } from '../user' |
diff --git a/server/lib/client-html.ts b/server/lib/client-html.ts index 203bd3893..3c09332b5 100644 --- a/server/lib/client-html.ts +++ b/server/lib/client-html.ts | |||
@@ -2,12 +2,14 @@ import * as express from 'express' | |||
2 | import { readFile } from 'fs-extra' | 2 | import { readFile } from 'fs-extra' |
3 | import { join } from 'path' | 3 | import { join } from 'path' |
4 | import validator from 'validator' | 4 | import validator from 'validator' |
5 | import { escapeHTML } from '@shared/core-utils/renderer' | ||
6 | import { HTMLServerConfig } from '@shared/models' | ||
5 | import { buildFileLocale, getDefaultLocale, is18nLocale, POSSIBLE_LOCALES } from '../../shared/core-utils/i18n/i18n' | 7 | import { buildFileLocale, getDefaultLocale, is18nLocale, POSSIBLE_LOCALES } from '../../shared/core-utils/i18n/i18n' |
6 | import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' | 8 | import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' |
7 | import { VideoPlaylistPrivacy, VideoPrivacy } from '../../shared/models/videos' | 9 | import { VideoPlaylistPrivacy, VideoPrivacy } from '../../shared/models/videos' |
8 | import { isTestInstance, sha256 } from '../helpers/core-utils' | 10 | import { isTestInstance, sha256 } from '../helpers/core-utils' |
9 | import { escapeHTML } from '@shared/core-utils/renderer' | ||
10 | import { logger } from '../helpers/logger' | 11 | import { logger } from '../helpers/logger' |
12 | import { mdToPlainText } from '../helpers/markdown' | ||
11 | import { CONFIG } from '../initializers/config' | 13 | import { CONFIG } from '../initializers/config' |
12 | import { | 14 | import { |
13 | ACCEPT_HEADERS, | 15 | ACCEPT_HEADERS, |
@@ -24,7 +26,7 @@ import { VideoChannelModel } from '../models/video/video-channel' | |||
24 | import { getActivityStreamDuration } from '../models/video/video-format-utils' | 26 | import { getActivityStreamDuration } from '../models/video/video-format-utils' |
25 | import { VideoPlaylistModel } from '../models/video/video-playlist' | 27 | import { VideoPlaylistModel } from '../models/video/video-playlist' |
26 | import { MAccountActor, MChannelActor } from '../types/models' | 28 | import { MAccountActor, MChannelActor } from '../types/models' |
27 | import { mdToPlainText } from '../helpers/markdown' | 29 | import { ServerConfigManager } from './server-config-manager' |
28 | 30 | ||
29 | type Tags = { | 31 | type Tags = { |
30 | ogType: string | 32 | ogType: string |
@@ -196,11 +198,22 @@ class ClientHtml { | |||
196 | } | 198 | } |
197 | 199 | ||
198 | static async getAccountHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { | 200 | static async getAccountHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { |
199 | return this.getAccountOrChannelHTMLPage(() => AccountModel.loadByNameWithHost(nameWithHost), req, res) | 201 | const accountModelPromise = AccountModel.loadByNameWithHost(nameWithHost) |
202 | return this.getAccountOrChannelHTMLPage(() => accountModelPromise, req, res) | ||
200 | } | 203 | } |
201 | 204 | ||
202 | static async getVideoChannelHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { | 205 | static async getVideoChannelHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { |
203 | return this.getAccountOrChannelHTMLPage(() => VideoChannelModel.loadByNameWithHostAndPopulateAccount(nameWithHost), req, res) | 206 | const videoChannelModelPromise = VideoChannelModel.loadByNameWithHostAndPopulateAccount(nameWithHost) |
207 | return this.getAccountOrChannelHTMLPage(() => videoChannelModelPromise, req, res) | ||
208 | } | ||
209 | |||
210 | static async getActorHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { | ||
211 | const [ account, channel ] = await Promise.all([ | ||
212 | AccountModel.loadByNameWithHost(nameWithHost), | ||
213 | VideoChannelModel.loadByNameWithHostAndPopulateAccount(nameWithHost) | ||
214 | ]) | ||
215 | |||
216 | return this.getAccountOrChannelHTMLPage(() => Promise.resolve(account || channel), req, res) | ||
204 | } | 217 | } |
205 | 218 | ||
206 | static async getEmbedHTML () { | 219 | static async getEmbedHTML () { |
@@ -209,11 +222,14 @@ class ClientHtml { | |||
209 | if (!isTestInstance() && ClientHtml.htmlCache[path]) return ClientHtml.htmlCache[path] | 222 | if (!isTestInstance() && ClientHtml.htmlCache[path]) return ClientHtml.htmlCache[path] |
210 | 223 | ||
211 | const buffer = await readFile(path) | 224 | const buffer = await readFile(path) |
225 | const serverConfig = await ServerConfigManager.Instance.getHTMLServerConfig() | ||
212 | 226 | ||
213 | let html = buffer.toString() | 227 | let html = buffer.toString() |
214 | html = await ClientHtml.addAsyncPluginCSS(html) | 228 | html = await ClientHtml.addAsyncPluginCSS(html) |
215 | html = ClientHtml.addCustomCSS(html) | 229 | html = ClientHtml.addCustomCSS(html) |
216 | html = ClientHtml.addTitleTag(html) | 230 | html = ClientHtml.addTitleTag(html) |
231 | html = ClientHtml.addDescriptionTag(html) | ||
232 | html = ClientHtml.addServerConfig(html, serverConfig) | ||
217 | 233 | ||
218 | ClientHtml.htmlCache[path] = html | 234 | ClientHtml.htmlCache[path] = html |
219 | 235 | ||
@@ -275,6 +291,7 @@ class ClientHtml { | |||
275 | if (!isTestInstance() && ClientHtml.htmlCache[path]) return ClientHtml.htmlCache[path] | 291 | if (!isTestInstance() && ClientHtml.htmlCache[path]) return ClientHtml.htmlCache[path] |
276 | 292 | ||
277 | const buffer = await readFile(path) | 293 | const buffer = await readFile(path) |
294 | const serverConfig = await ServerConfigManager.Instance.getHTMLServerConfig() | ||
278 | 295 | ||
279 | let html = buffer.toString() | 296 | let html = buffer.toString() |
280 | 297 | ||
@@ -283,6 +300,7 @@ class ClientHtml { | |||
283 | html = ClientHtml.addFaviconContentHash(html) | 300 | html = ClientHtml.addFaviconContentHash(html) |
284 | html = ClientHtml.addLogoContentHash(html) | 301 | html = ClientHtml.addLogoContentHash(html) |
285 | html = ClientHtml.addCustomCSS(html) | 302 | html = ClientHtml.addCustomCSS(html) |
303 | html = ClientHtml.addServerConfig(html, serverConfig) | ||
286 | html = await ClientHtml.addAsyncPluginCSS(html) | 304 | html = await ClientHtml.addAsyncPluginCSS(html) |
287 | 305 | ||
288 | ClientHtml.htmlCache[path] = html | 306 | ClientHtml.htmlCache[path] = html |
@@ -355,6 +373,13 @@ class ClientHtml { | |||
355 | return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.CUSTOM_CSS, styleTag) | 373 | return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.CUSTOM_CSS, styleTag) |
356 | } | 374 | } |
357 | 375 | ||
376 | private static addServerConfig (htmlStringPage: string, serverConfig: HTMLServerConfig) { | ||
377 | const serverConfigString = JSON.stringify(serverConfig) | ||
378 | const configScriptTag = `<script type="application/javascript">window.PeerTubeServerConfig = '${serverConfigString}'</script>` | ||
379 | |||
380 | return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.SERVER_CONFIG, configScriptTag) | ||
381 | } | ||
382 | |||
358 | private static async addAsyncPluginCSS (htmlStringPage: string) { | 383 | private static async addAsyncPluginCSS (htmlStringPage: string) { |
359 | const globalCSSContent = await readFile(PLUGIN_GLOBAL_CSS_PATH) | 384 | const globalCSSContent = await readFile(PLUGIN_GLOBAL_CSS_PATH) |
360 | if (globalCSSContent.byteLength === 0) return htmlStringPage | 385 | if (globalCSSContent.byteLength === 0) return htmlStringPage |
diff --git a/server/lib/config.ts b/server/lib/config.ts deleted file mode 100644 index b4c4c9299..000000000 --- a/server/lib/config.ts +++ /dev/null | |||
@@ -1,255 +0,0 @@ | |||
1 | import { isSignupAllowed, isSignupAllowedForCurrentIP } from '@server/helpers/signup' | ||
2 | import { getServerCommit } from '@server/helpers/utils' | ||
3 | import { CONFIG, isEmailEnabled } from '@server/initializers/config' | ||
4 | import { CONSTRAINTS_FIELDS, DEFAULT_THEME_NAME, PEERTUBE_VERSION } from '@server/initializers/constants' | ||
5 | import { RegisteredExternalAuthConfig, RegisteredIdAndPassAuthConfig, ServerConfig } from '@shared/models' | ||
6 | import { Hooks } from './plugins/hooks' | ||
7 | import { PluginManager } from './plugins/plugin-manager' | ||
8 | import { getThemeOrDefault } from './plugins/theme-utils' | ||
9 | import { getEnabledResolutions } from './video-transcoding' | ||
10 | import { VideoTranscodingProfilesManager } from './video-transcoding-profiles' | ||
11 | |||
12 | let serverCommit: string | ||
13 | |||
14 | async function getServerConfig (ip?: string): Promise<ServerConfig> { | ||
15 | if (serverCommit === undefined) serverCommit = await getServerCommit() | ||
16 | |||
17 | const { allowed } = await Hooks.wrapPromiseFun( | ||
18 | isSignupAllowed, | ||
19 | { | ||
20 | ip | ||
21 | }, | ||
22 | 'filter:api.user.signup.allowed.result' | ||
23 | ) | ||
24 | |||
25 | const allowedForCurrentIP = isSignupAllowedForCurrentIP(ip) | ||
26 | const defaultTheme = getThemeOrDefault(CONFIG.THEME.DEFAULT, DEFAULT_THEME_NAME) | ||
27 | |||
28 | return { | ||
29 | instance: { | ||
30 | name: CONFIG.INSTANCE.NAME, | ||
31 | shortDescription: CONFIG.INSTANCE.SHORT_DESCRIPTION, | ||
32 | isNSFW: CONFIG.INSTANCE.IS_NSFW, | ||
33 | defaultNSFWPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY, | ||
34 | defaultClientRoute: CONFIG.INSTANCE.DEFAULT_CLIENT_ROUTE, | ||
35 | customizations: { | ||
36 | javascript: CONFIG.INSTANCE.CUSTOMIZATIONS.JAVASCRIPT, | ||
37 | css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS | ||
38 | } | ||
39 | }, | ||
40 | search: { | ||
41 | remoteUri: { | ||
42 | users: CONFIG.SEARCH.REMOTE_URI.USERS, | ||
43 | anonymous: CONFIG.SEARCH.REMOTE_URI.ANONYMOUS | ||
44 | }, | ||
45 | searchIndex: { | ||
46 | enabled: CONFIG.SEARCH.SEARCH_INDEX.ENABLED, | ||
47 | url: CONFIG.SEARCH.SEARCH_INDEX.URL, | ||
48 | disableLocalSearch: CONFIG.SEARCH.SEARCH_INDEX.DISABLE_LOCAL_SEARCH, | ||
49 | isDefaultSearch: CONFIG.SEARCH.SEARCH_INDEX.IS_DEFAULT_SEARCH | ||
50 | } | ||
51 | }, | ||
52 | plugin: { | ||
53 | registered: getRegisteredPlugins(), | ||
54 | registeredExternalAuths: getExternalAuthsPlugins(), | ||
55 | registeredIdAndPassAuths: getIdAndPassAuthPlugins() | ||
56 | }, | ||
57 | theme: { | ||
58 | registered: getRegisteredThemes(), | ||
59 | default: defaultTheme | ||
60 | }, | ||
61 | email: { | ||
62 | enabled: isEmailEnabled() | ||
63 | }, | ||
64 | contactForm: { | ||
65 | enabled: CONFIG.CONTACT_FORM.ENABLED | ||
66 | }, | ||
67 | serverVersion: PEERTUBE_VERSION, | ||
68 | serverCommit, | ||
69 | signup: { | ||
70 | allowed, | ||
71 | allowedForCurrentIP, | ||
72 | requiresEmailVerification: CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION | ||
73 | }, | ||
74 | transcoding: { | ||
75 | hls: { | ||
76 | enabled: CONFIG.TRANSCODING.HLS.ENABLED | ||
77 | }, | ||
78 | webtorrent: { | ||
79 | enabled: CONFIG.TRANSCODING.WEBTORRENT.ENABLED | ||
80 | }, | ||
81 | enabledResolutions: getEnabledResolutions('vod'), | ||
82 | profile: CONFIG.TRANSCODING.PROFILE, | ||
83 | availableProfiles: VideoTranscodingProfilesManager.Instance.getAvailableProfiles('vod') | ||
84 | }, | ||
85 | live: { | ||
86 | enabled: CONFIG.LIVE.ENABLED, | ||
87 | |||
88 | allowReplay: CONFIG.LIVE.ALLOW_REPLAY, | ||
89 | maxDuration: CONFIG.LIVE.MAX_DURATION, | ||
90 | maxInstanceLives: CONFIG.LIVE.MAX_INSTANCE_LIVES, | ||
91 | maxUserLives: CONFIG.LIVE.MAX_USER_LIVES, | ||
92 | |||
93 | transcoding: { | ||
94 | enabled: CONFIG.LIVE.TRANSCODING.ENABLED, | ||
95 | enabledResolutions: getEnabledResolutions('live'), | ||
96 | profile: CONFIG.LIVE.TRANSCODING.PROFILE, | ||
97 | availableProfiles: VideoTranscodingProfilesManager.Instance.getAvailableProfiles('live') | ||
98 | }, | ||
99 | |||
100 | rtmp: { | ||
101 | port: CONFIG.LIVE.RTMP.PORT | ||
102 | } | ||
103 | }, | ||
104 | import: { | ||
105 | videos: { | ||
106 | http: { | ||
107 | enabled: CONFIG.IMPORT.VIDEOS.HTTP.ENABLED | ||
108 | }, | ||
109 | torrent: { | ||
110 | enabled: CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED | ||
111 | } | ||
112 | } | ||
113 | }, | ||
114 | autoBlacklist: { | ||
115 | videos: { | ||
116 | ofUsers: { | ||
117 | enabled: CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED | ||
118 | } | ||
119 | } | ||
120 | }, | ||
121 | avatar: { | ||
122 | file: { | ||
123 | size: { | ||
124 | max: CONSTRAINTS_FIELDS.ACTORS.IMAGE.FILE_SIZE.max | ||
125 | }, | ||
126 | extensions: CONSTRAINTS_FIELDS.ACTORS.IMAGE.EXTNAME | ||
127 | } | ||
128 | }, | ||
129 | banner: { | ||
130 | file: { | ||
131 | size: { | ||
132 | max: CONSTRAINTS_FIELDS.ACTORS.IMAGE.FILE_SIZE.max | ||
133 | }, | ||
134 | extensions: CONSTRAINTS_FIELDS.ACTORS.IMAGE.EXTNAME | ||
135 | } | ||
136 | }, | ||
137 | video: { | ||
138 | image: { | ||
139 | extensions: CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME, | ||
140 | size: { | ||
141 | max: CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max | ||
142 | } | ||
143 | }, | ||
144 | file: { | ||
145 | extensions: CONSTRAINTS_FIELDS.VIDEOS.EXTNAME | ||
146 | } | ||
147 | }, | ||
148 | videoCaption: { | ||
149 | file: { | ||
150 | size: { | ||
151 | max: CONSTRAINTS_FIELDS.VIDEO_CAPTIONS.CAPTION_FILE.FILE_SIZE.max | ||
152 | }, | ||
153 | extensions: CONSTRAINTS_FIELDS.VIDEO_CAPTIONS.CAPTION_FILE.EXTNAME | ||
154 | } | ||
155 | }, | ||
156 | user: { | ||
157 | videoQuota: CONFIG.USER.VIDEO_QUOTA, | ||
158 | videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY | ||
159 | }, | ||
160 | trending: { | ||
161 | videos: { | ||
162 | intervalDays: CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS, | ||
163 | algorithms: { | ||
164 | enabled: CONFIG.TRENDING.VIDEOS.ALGORITHMS.ENABLED, | ||
165 | default: CONFIG.TRENDING.VIDEOS.ALGORITHMS.DEFAULT | ||
166 | } | ||
167 | } | ||
168 | }, | ||
169 | tracker: { | ||
170 | enabled: CONFIG.TRACKER.ENABLED | ||
171 | }, | ||
172 | |||
173 | followings: { | ||
174 | instance: { | ||
175 | autoFollowIndex: { | ||
176 | indexUrl: CONFIG.FOLLOWINGS.INSTANCE.AUTO_FOLLOW_INDEX.INDEX_URL | ||
177 | } | ||
178 | } | ||
179 | }, | ||
180 | |||
181 | broadcastMessage: { | ||
182 | enabled: CONFIG.BROADCAST_MESSAGE.ENABLED, | ||
183 | message: CONFIG.BROADCAST_MESSAGE.MESSAGE, | ||
184 | level: CONFIG.BROADCAST_MESSAGE.LEVEL, | ||
185 | dismissable: CONFIG.BROADCAST_MESSAGE.DISMISSABLE | ||
186 | } | ||
187 | } | ||
188 | } | ||
189 | |||
190 | function getRegisteredThemes () { | ||
191 | return PluginManager.Instance.getRegisteredThemes() | ||
192 | .map(t => ({ | ||
193 | name: t.name, | ||
194 | version: t.version, | ||
195 | description: t.description, | ||
196 | css: t.css, | ||
197 | clientScripts: t.clientScripts | ||
198 | })) | ||
199 | } | ||
200 | |||
201 | function getRegisteredPlugins () { | ||
202 | return PluginManager.Instance.getRegisteredPlugins() | ||
203 | .map(p => ({ | ||
204 | name: p.name, | ||
205 | version: p.version, | ||
206 | description: p.description, | ||
207 | clientScripts: p.clientScripts | ||
208 | })) | ||
209 | } | ||
210 | |||
211 | // --------------------------------------------------------------------------- | ||
212 | |||
213 | export { | ||
214 | getServerConfig, | ||
215 | getRegisteredThemes, | ||
216 | getRegisteredPlugins | ||
217 | } | ||
218 | |||
219 | // --------------------------------------------------------------------------- | ||
220 | |||
221 | function getIdAndPassAuthPlugins () { | ||
222 | const result: RegisteredIdAndPassAuthConfig[] = [] | ||
223 | |||
224 | for (const p of PluginManager.Instance.getIdAndPassAuths()) { | ||
225 | for (const auth of p.idAndPassAuths) { | ||
226 | result.push({ | ||
227 | npmName: p.npmName, | ||
228 | name: p.name, | ||
229 | version: p.version, | ||
230 | authName: auth.authName, | ||
231 | weight: auth.getWeight() | ||
232 | }) | ||
233 | } | ||
234 | } | ||
235 | |||
236 | return result | ||
237 | } | ||
238 | |||
239 | function getExternalAuthsPlugins () { | ||
240 | const result: RegisteredExternalAuthConfig[] = [] | ||
241 | |||
242 | for (const p of PluginManager.Instance.getExternalAuths()) { | ||
243 | for (const auth of p.externalAuths) { | ||
244 | result.push({ | ||
245 | npmName: p.npmName, | ||
246 | name: p.name, | ||
247 | version: p.version, | ||
248 | authName: auth.authName, | ||
249 | authDisplayName: auth.authDisplayName() | ||
250 | }) | ||
251 | } | ||
252 | } | ||
253 | |||
254 | return result | ||
255 | } | ||
diff --git a/server/lib/job-queue/handlers/activitypub-follow.ts b/server/lib/job-queue/handlers/activitypub-follow.ts index 82c95be80..ec8df8969 100644 --- a/server/lib/job-queue/handlers/activitypub-follow.ts +++ b/server/lib/job-queue/handlers/activitypub-follow.ts | |||
@@ -1,18 +1,18 @@ | |||
1 | import * as Bull from 'bull' | 1 | import * as Bull from 'bull' |
2 | import { logger } from '../../../helpers/logger' | 2 | import { getLocalActorFollowActivityPubUrl } from '@server/lib/activitypub/url' |
3 | import { REMOTE_SCHEME, WEBSERVER } from '../../../initializers/constants' | 3 | import { ActivitypubFollowPayload } from '@shared/models' |
4 | import { sendFollow } from '../../activitypub/send' | ||
5 | import { sanitizeHost } from '../../../helpers/core-utils' | 4 | import { sanitizeHost } from '../../../helpers/core-utils' |
6 | import { loadActorUrlOrGetFromWebfinger } from '../../../helpers/webfinger' | ||
7 | import { getOrCreateActorAndServerAndModel } from '../../activitypub/actor' | ||
8 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 5 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
9 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | 6 | import { logger } from '../../../helpers/logger' |
10 | import { ActorModel } from '../../../models/activitypub/actor' | 7 | import { loadActorUrlOrGetFromWebfinger } from '../../../helpers/webfinger' |
11 | import { Notifier } from '../../notifier' | 8 | import { REMOTE_SCHEME, WEBSERVER } from '../../../initializers/constants' |
12 | import { sequelizeTypescript } from '../../../initializers/database' | 9 | import { sequelizeTypescript } from '../../../initializers/database' |
10 | import { ActorModel } from '../../../models/actor/actor' | ||
11 | import { ActorFollowModel } from '../../../models/actor/actor-follow' | ||
13 | import { MActor, MActorFollowActors, MActorFull } from '../../../types/models' | 12 | import { MActor, MActorFollowActors, MActorFull } from '../../../types/models' |
14 | import { ActivitypubFollowPayload } from '@shared/models' | 13 | import { getOrCreateActorAndServerAndModel } from '../../activitypub/actor' |
15 | import { getLocalActorFollowActivityPubUrl } from '@server/lib/activitypub/url' | 14 | import { sendFollow } from '../../activitypub/send' |
15 | import { Notifier } from '../../notifier' | ||
16 | 16 | ||
17 | async function processActivityPubFollow (job: Bull.Job) { | 17 | async function processActivityPubFollow (job: Bull.Job) { |
18 | const payload = job.data as ActivitypubFollowPayload | 18 | const payload = job.data as ActivitypubFollowPayload |
diff --git a/server/lib/job-queue/handlers/activitypub-refresher.ts b/server/lib/job-queue/handlers/activitypub-refresher.ts index 666e56868..c09b1bcc8 100644 --- a/server/lib/job-queue/handlers/activitypub-refresher.ts +++ b/server/lib/job-queue/handlers/activitypub-refresher.ts | |||
@@ -1,12 +1,12 @@ | |||
1 | import * as Bull from 'bull' | 1 | import * as Bull from 'bull' |
2 | import { refreshVideoPlaylistIfNeeded } from '@server/lib/activitypub/playlist' | ||
3 | import { RefreshPayload } from '@shared/models' | ||
2 | import { logger } from '../../../helpers/logger' | 4 | import { logger } from '../../../helpers/logger' |
3 | import { fetchVideoByUrl } from '../../../helpers/video' | 5 | import { fetchVideoByUrl } from '../../../helpers/video' |
6 | import { ActorModel } from '../../../models/actor/actor' | ||
7 | import { VideoPlaylistModel } from '../../../models/video/video-playlist' | ||
4 | import { refreshActorIfNeeded } from '../../activitypub/actor' | 8 | import { refreshActorIfNeeded } from '../../activitypub/actor' |
5 | import { refreshVideoIfNeeded } from '../../activitypub/videos' | 9 | import { refreshVideoIfNeeded } from '../../activitypub/videos' |
6 | import { ActorModel } from '../../../models/activitypub/actor' | ||
7 | import { VideoPlaylistModel } from '../../../models/video/video-playlist' | ||
8 | import { RefreshPayload } from '@shared/models' | ||
9 | import { refreshVideoPlaylistIfNeeded } from '@server/lib/activitypub/playlist' | ||
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 |
diff --git a/server/lib/job-queue/handlers/actor-keys.ts b/server/lib/job-queue/handlers/actor-keys.ts index 125307843..3eef565d0 100644 --- a/server/lib/job-queue/handlers/actor-keys.ts +++ b/server/lib/job-queue/handlers/actor-keys.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import * as Bull from 'bull' | 1 | import * as Bull from 'bull' |
2 | import { generateAndSaveActorKeys } from '@server/lib/activitypub/actor' | 2 | import { generateAndSaveActorKeys } from '@server/lib/activitypub/actor' |
3 | import { ActorModel } from '@server/models/activitypub/actor' | 3 | import { ActorModel } from '@server/models/actor/actor' |
4 | import { ActorKeysPayload } from '@shared/models' | 4 | import { ActorKeysPayload } from '@shared/models' |
5 | import { logger } from '../../../helpers/logger' | 5 | import { logger } from '../../../helpers/logger' |
6 | 6 | ||
diff --git a/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts b/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts index e8a91450d..37e7c1fad 100644 --- a/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts +++ b/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts | |||
@@ -1,10 +1,10 @@ | |||
1 | import { buildDigest } from '@server/helpers/peertube-crypto' | ||
2 | import { getServerActor } from '@server/models/application/application' | ||
3 | import { ContextType } from '@shared/models/activitypub/context' | ||
1 | import { buildSignedActivity } from '../../../../helpers/activitypub' | 4 | import { buildSignedActivity } from '../../../../helpers/activitypub' |
2 | import { ActorModel } from '../../../../models/activitypub/actor' | ||
3 | import { ACTIVITY_PUB, HTTP_SIGNATURE } from '../../../../initializers/constants' | 5 | import { ACTIVITY_PUB, HTTP_SIGNATURE } from '../../../../initializers/constants' |
6 | import { ActorModel } from '../../../../models/actor/actor' | ||
4 | import { MActor } from '../../../../types/models' | 7 | import { MActor } from '../../../../types/models' |
5 | import { getServerActor } from '@server/models/application/application' | ||
6 | import { buildDigest } from '@server/helpers/peertube-crypto' | ||
7 | import { ContextType } from '@shared/models/activitypub/context' | ||
8 | 8 | ||
9 | type Payload <T> = { body: T, contextType?: ContextType, signatureActorId?: number } | 9 | type Payload <T> = { body: T, contextType?: ContextType, signatureActorId?: number } |
10 | 10 | ||
diff --git a/server/lib/job-queue/handlers/video-file-import.ts b/server/lib/job-queue/handlers/video-file-import.ts index 71f2cafcd..8297a1571 100644 --- a/server/lib/job-queue/handlers/video-file-import.ts +++ b/server/lib/job-queue/handlers/video-file-import.ts | |||
@@ -3,7 +3,7 @@ import { copy, stat } from 'fs-extra' | |||
3 | import { extname } from 'path' | 3 | import { extname } from 'path' |
4 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' | 4 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' |
5 | import { generateVideoFilename, getVideoFilePath } from '@server/lib/video-paths' | 5 | import { generateVideoFilename, getVideoFilePath } from '@server/lib/video-paths' |
6 | import { UserModel } from '@server/models/account/user' | 6 | import { UserModel } from '@server/models/user/user' |
7 | import { MVideoFullLight } from '@server/types/models' | 7 | import { MVideoFullLight } from '@server/types/models' |
8 | import { VideoFileImportPayload } from '@shared/models' | 8 | import { VideoFileImportPayload } from '@shared/models' |
9 | import { getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils' | 9 | import { getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils' |
diff --git a/server/lib/job-queue/handlers/video-import.ts b/server/lib/job-queue/handlers/video-import.ts index ed2c5eac0..d71053e87 100644 --- a/server/lib/job-queue/handlers/video-import.ts +++ b/server/lib/job-queue/handlers/video-import.ts | |||
@@ -2,8 +2,10 @@ import * as Bull from 'bull' | |||
2 | import { move, remove, stat } from 'fs-extra' | 2 | import { move, remove, stat } from 'fs-extra' |
3 | import { extname } from 'path' | 3 | import { extname } from 'path' |
4 | import { retryTransactionWrapper } from '@server/helpers/database-utils' | 4 | import { retryTransactionWrapper } from '@server/helpers/database-utils' |
5 | import { YoutubeDL } from '@server/helpers/youtube-dl' | ||
5 | import { isPostImportVideoAccepted } from '@server/lib/moderation' | 6 | import { isPostImportVideoAccepted } from '@server/lib/moderation' |
6 | import { Hooks } from '@server/lib/plugins/hooks' | 7 | import { Hooks } from '@server/lib/plugins/hooks' |
8 | import { ServerConfigManager } from '@server/lib/server-config-manager' | ||
7 | import { isAbleToUploadVideo } from '@server/lib/user' | 9 | import { isAbleToUploadVideo } from '@server/lib/user' |
8 | import { addOptimizeOrMergeAudioJob } from '@server/lib/video' | 10 | import { addOptimizeOrMergeAudioJob } from '@server/lib/video' |
9 | import { generateVideoFilename, getVideoFilePath } from '@server/lib/video-paths' | 11 | import { generateVideoFilename, getVideoFilePath } from '@server/lib/video-paths' |
@@ -23,7 +25,6 @@ import { getDurationFromVideoFile, getVideoFileFPS, getVideoFileResolution } fro | |||
23 | import { logger } from '../../../helpers/logger' | 25 | import { logger } from '../../../helpers/logger' |
24 | import { getSecureTorrentName } from '../../../helpers/utils' | 26 | import { getSecureTorrentName } from '../../../helpers/utils' |
25 | import { createTorrentAndSetInfoHash, downloadWebTorrentVideo } from '../../../helpers/webtorrent' | 27 | import { createTorrentAndSetInfoHash, downloadWebTorrentVideo } from '../../../helpers/webtorrent' |
26 | import { downloadYoutubeDLVideo } from '../../../helpers/youtube-dl' | ||
27 | import { CONFIG } from '../../../initializers/config' | 28 | import { CONFIG } from '../../../initializers/config' |
28 | import { VIDEO_IMPORT_TIMEOUT } from '../../../initializers/constants' | 29 | import { VIDEO_IMPORT_TIMEOUT } from '../../../initializers/constants' |
29 | import { sequelizeTypescript } from '../../../initializers/database' | 30 | import { sequelizeTypescript } from '../../../initializers/database' |
@@ -75,8 +76,10 @@ async function processYoutubeDLImport (job: Bull.Job, payload: VideoImportYoutub | |||
75 | videoImportId: videoImport.id | 76 | videoImportId: videoImport.id |
76 | } | 77 | } |
77 | 78 | ||
79 | const youtubeDL = new YoutubeDL(videoImport.targetUrl, ServerConfigManager.Instance.getEnabledResolutions('vod')) | ||
80 | |||
78 | return processFile( | 81 | return processFile( |
79 | () => downloadYoutubeDLVideo(videoImport.targetUrl, payload.fileExt, VIDEO_IMPORT_TIMEOUT), | 82 | () => youtubeDL.downloadYoutubeDLVideo(payload.fileExt, VIDEO_IMPORT_TIMEOUT), |
80 | videoImport, | 83 | videoImport, |
81 | options | 84 | options |
82 | ) | 85 | ) |
diff --git a/server/lib/job-queue/handlers/video-live-ending.ts b/server/lib/job-queue/handlers/video-live-ending.ts index d57202ca5..517b90abc 100644 --- a/server/lib/job-queue/handlers/video-live-ending.ts +++ b/server/lib/job-queue/handlers/video-live-ending.ts | |||
@@ -5,9 +5,9 @@ import { ffprobePromise, getAudioStream, getDurationFromVideoFile, getVideoFileR | |||
5 | import { VIDEO_LIVE } from '@server/initializers/constants' | 5 | import { VIDEO_LIVE } from '@server/initializers/constants' |
6 | import { LiveManager } from '@server/lib/live-manager' | 6 | import { LiveManager } from '@server/lib/live-manager' |
7 | import { generateVideoMiniature } from '@server/lib/thumbnail' | 7 | import { generateVideoMiniature } from '@server/lib/thumbnail' |
8 | import { generateHlsPlaylistResolutionFromTS } from '@server/lib/transcoding/video-transcoding' | ||
8 | import { publishAndFederateIfNeeded } from '@server/lib/video' | 9 | import { publishAndFederateIfNeeded } from '@server/lib/video' |
9 | import { getHLSDirectory } from '@server/lib/video-paths' | 10 | import { getHLSDirectory } from '@server/lib/video-paths' |
10 | import { generateHlsPlaylistResolutionFromTS } from '@server/lib/video-transcoding' | ||
11 | import { VideoModel } from '@server/models/video/video' | 11 | import { VideoModel } from '@server/models/video/video' |
12 | import { VideoFileModel } from '@server/models/video/video-file' | 12 | import { VideoFileModel } from '@server/models/video/video-file' |
13 | import { VideoLiveModel } from '@server/models/video/video-live' | 13 | import { VideoLiveModel } from '@server/models/video/video-live' |
diff --git a/server/lib/job-queue/handlers/video-transcoding.ts b/server/lib/job-queue/handlers/video-transcoding.ts index 010b95b05..8d659daa6 100644 --- a/server/lib/job-queue/handlers/video-transcoding.ts +++ b/server/lib/job-queue/handlers/video-transcoding.ts | |||
@@ -2,7 +2,7 @@ import * as Bull from 'bull' | |||
2 | import { TranscodeOptionsType } from '@server/helpers/ffmpeg-utils' | 2 | import { TranscodeOptionsType } from '@server/helpers/ffmpeg-utils' |
3 | import { getTranscodingJobPriority, publishAndFederateIfNeeded } from '@server/lib/video' | 3 | import { getTranscodingJobPriority, publishAndFederateIfNeeded } from '@server/lib/video' |
4 | import { getVideoFilePath } from '@server/lib/video-paths' | 4 | import { getVideoFilePath } from '@server/lib/video-paths' |
5 | import { UserModel } from '@server/models/account/user' | 5 | import { UserModel } from '@server/models/user/user' |
6 | import { MUser, MUserId, MVideoFullLight, MVideoUUID, MVideoWithFile } from '@server/types/models' | 6 | import { MUser, MUserId, MVideoFullLight, MVideoUUID, MVideoWithFile } from '@server/types/models' |
7 | import { | 7 | import { |
8 | HLSTranscodingPayload, | 8 | HLSTranscodingPayload, |
@@ -24,7 +24,7 @@ import { | |||
24 | mergeAudioVideofile, | 24 | mergeAudioVideofile, |
25 | optimizeOriginalVideofile, | 25 | optimizeOriginalVideofile, |
26 | transcodeNewWebTorrentResolution | 26 | transcodeNewWebTorrentResolution |
27 | } from '../../video-transcoding' | 27 | } from '../../transcoding/video-transcoding' |
28 | import { JobQueue } from '../job-queue' | 28 | import { JobQueue } from '../job-queue' |
29 | 29 | ||
30 | type HandlerFunction = (job: Bull.Job, payload: VideoTranscodingPayload, video: MVideoFullLight, user: MUser) => Promise<any> | 30 | type HandlerFunction = (job: Bull.Job, payload: VideoTranscodingPayload, video: MVideoFullLight, user: MUser) => Promise<any> |
diff --git a/server/lib/job-queue/handlers/video-views.ts b/server/lib/job-queue/handlers/video-views.ts index 897235ec0..86d0a271f 100644 --- a/server/lib/job-queue/handlers/video-views.ts +++ b/server/lib/job-queue/handlers/video-views.ts | |||
@@ -36,8 +36,8 @@ async function processVideosViews () { | |||
36 | } | 36 | } |
37 | 37 | ||
38 | await VideoViewModel.create({ | 38 | await VideoViewModel.create({ |
39 | startDate, | 39 | startDate: new Date(startDate), |
40 | endDate, | 40 | endDate: new Date(endDate), |
41 | views, | 41 | views, |
42 | videoId | 42 | videoId |
43 | }) | 43 | }) |
diff --git a/server/lib/live-manager.ts b/server/lib/live-manager.ts index 66b5d119b..563ba2578 100644 --- a/server/lib/live-manager.ts +++ b/server/lib/live-manager.ts | |||
@@ -8,10 +8,10 @@ import { basename, join } from 'path' | |||
8 | import { isTestInstance } from '@server/helpers/core-utils' | 8 | import { isTestInstance } from '@server/helpers/core-utils' |
9 | import { getLiveMuxingCommand, getLiveTranscodingCommand } from '@server/helpers/ffmpeg-utils' | 9 | import { getLiveMuxingCommand, getLiveTranscodingCommand } from '@server/helpers/ffmpeg-utils' |
10 | import { computeResolutionsToTranscode, getVideoFileFPS, getVideoFileResolution } from '@server/helpers/ffprobe-utils' | 10 | import { computeResolutionsToTranscode, getVideoFileFPS, getVideoFileResolution } from '@server/helpers/ffprobe-utils' |
11 | import { logger } from '@server/helpers/logger' | 11 | import { logger, loggerTagsFactory } from '@server/helpers/logger' |
12 | import { CONFIG, registerConfigChangedHandler } from '@server/initializers/config' | 12 | import { CONFIG, registerConfigChangedHandler } from '@server/initializers/config' |
13 | import { MEMOIZE_TTL, P2P_MEDIA_LOADER_PEER_VERSION, VIDEO_LIVE, VIEW_LIFETIME, WEBSERVER } from '@server/initializers/constants' | 13 | import { MEMOIZE_TTL, P2P_MEDIA_LOADER_PEER_VERSION, VIDEO_LIVE, VIEW_LIFETIME, WEBSERVER } from '@server/initializers/constants' |
14 | import { UserModel } from '@server/models/account/user' | 14 | import { UserModel } from '@server/models/user/user' |
15 | import { VideoModel } from '@server/models/video/video' | 15 | import { VideoModel } from '@server/models/video/video' |
16 | import { VideoFileModel } from '@server/models/video/video-file' | 16 | import { VideoFileModel } from '@server/models/video/video-file' |
17 | import { VideoLiveModel } from '@server/models/video/video-live' | 17 | import { VideoLiveModel } from '@server/models/video/video-live' |
@@ -23,9 +23,9 @@ import { buildSha256Segment } from './hls' | |||
23 | import { JobQueue } from './job-queue' | 23 | import { JobQueue } from './job-queue' |
24 | import { cleanupLive } from './job-queue/handlers/video-live-ending' | 24 | import { cleanupLive } from './job-queue/handlers/video-live-ending' |
25 | import { PeerTubeSocket } from './peertube-socket' | 25 | import { PeerTubeSocket } from './peertube-socket' |
26 | import { VideoTranscodingProfilesManager } from './transcoding/video-transcoding-profiles' | ||
26 | import { isAbleToUploadVideo } from './user' | 27 | import { isAbleToUploadVideo } from './user' |
27 | import { getHLSDirectory } from './video-paths' | 28 | import { getHLSDirectory } from './video-paths' |
28 | import { VideoTranscodingProfilesManager } from './video-transcoding-profiles' | ||
29 | 29 | ||
30 | import memoizee = require('memoizee') | 30 | import memoizee = require('memoizee') |
31 | const NodeRtmpSession = require('node-media-server/node_rtmp_session') | 31 | const NodeRtmpSession = require('node-media-server/node_rtmp_session') |
@@ -48,6 +48,8 @@ const config = { | |||
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | const lTags = loggerTagsFactory('live') | ||
52 | |||
51 | class LiveManager { | 53 | class LiveManager { |
52 | 54 | ||
53 | private static instance: LiveManager | 55 | private static instance: LiveManager |
@@ -75,20 +77,20 @@ class LiveManager { | |||
75 | init () { | 77 | init () { |
76 | const events = this.getContext().nodeEvent | 78 | const events = this.getContext().nodeEvent |
77 | events.on('postPublish', (sessionId: string, streamPath: string) => { | 79 | events.on('postPublish', (sessionId: string, streamPath: string) => { |
78 | logger.debug('RTMP received stream', { id: sessionId, streamPath }) | 80 | logger.debug('RTMP received stream', { id: sessionId, streamPath, ...lTags(sessionId) }) |
79 | 81 | ||
80 | const splittedPath = streamPath.split('/') | 82 | const splittedPath = streamPath.split('/') |
81 | if (splittedPath.length !== 3 || splittedPath[1] !== VIDEO_LIVE.RTMP.BASE_PATH) { | 83 | if (splittedPath.length !== 3 || splittedPath[1] !== VIDEO_LIVE.RTMP.BASE_PATH) { |
82 | logger.warn('Live path is incorrect.', { streamPath }) | 84 | logger.warn('Live path is incorrect.', { streamPath, ...lTags(sessionId) }) |
83 | return this.abortSession(sessionId) | 85 | return this.abortSession(sessionId) |
84 | } | 86 | } |
85 | 87 | ||
86 | this.handleSession(sessionId, streamPath, splittedPath[2]) | 88 | this.handleSession(sessionId, streamPath, splittedPath[2]) |
87 | .catch(err => logger.error('Cannot handle sessions.', { err })) | 89 | .catch(err => logger.error('Cannot handle sessions.', { err, ...lTags(sessionId) })) |
88 | }) | 90 | }) |
89 | 91 | ||
90 | events.on('donePublish', sessionId => { | 92 | events.on('donePublish', sessionId => { |
91 | logger.info('Live session ended.', { sessionId }) | 93 | logger.info('Live session ended.', { sessionId, ...lTags(sessionId) }) |
92 | }) | 94 | }) |
93 | 95 | ||
94 | registerConfigChangedHandler(() => { | 96 | registerConfigChangedHandler(() => { |
@@ -104,13 +106,13 @@ class LiveManager { | |||
104 | 106 | ||
105 | // Cleanup broken lives, that were terminated by a server restart for example | 107 | // Cleanup broken lives, that were terminated by a server restart for example |
106 | this.handleBrokenLives() | 108 | this.handleBrokenLives() |
107 | .catch(err => logger.error('Cannot handle broken lives.', { err })) | 109 | .catch(err => logger.error('Cannot handle broken lives.', { err, ...lTags() })) |
108 | 110 | ||
109 | setInterval(() => this.updateLiveViews(), VIEW_LIFETIME.LIVE) | 111 | setInterval(() => this.updateLiveViews(), VIEW_LIFETIME.LIVE) |
110 | } | 112 | } |
111 | 113 | ||
112 | run () { | 114 | run () { |
113 | logger.info('Running RTMP server on port %d', config.rtmp.port) | 115 | logger.info('Running RTMP server on port %d', config.rtmp.port, lTags()) |
114 | 116 | ||
115 | this.rtmpServer = createServer(socket => { | 117 | this.rtmpServer = createServer(socket => { |
116 | const session = new NodeRtmpSession(config, socket) | 118 | const session = new NodeRtmpSession(config, socket) |
@@ -119,14 +121,14 @@ class LiveManager { | |||
119 | }) | 121 | }) |
120 | 122 | ||
121 | this.rtmpServer.on('error', err => { | 123 | this.rtmpServer.on('error', err => { |
122 | logger.error('Cannot run RTMP server.', { err }) | 124 | logger.error('Cannot run RTMP server.', { err, ...lTags() }) |
123 | }) | 125 | }) |
124 | 126 | ||
125 | this.rtmpServer.listen(CONFIG.LIVE.RTMP.PORT) | 127 | this.rtmpServer.listen(CONFIG.LIVE.RTMP.PORT) |
126 | } | 128 | } |
127 | 129 | ||
128 | stop () { | 130 | stop () { |
129 | logger.info('Stopping RTMP server.') | 131 | logger.info('Stopping RTMP server.', lTags()) |
130 | 132 | ||
131 | this.rtmpServer.close() | 133 | this.rtmpServer.close() |
132 | this.rtmpServer = undefined | 134 | this.rtmpServer = undefined |
@@ -185,7 +187,7 @@ class LiveManager { | |||
185 | 187 | ||
186 | return readFile(segmentPath) | 188 | return readFile(segmentPath) |
187 | .then(data => appendFile(dest, data)) | 189 | .then(data => appendFile(dest, data)) |
188 | .catch(err => logger.error('Cannot copy segment %s to repay directory.', segmentPath, { err })) | 190 | .catch(err => logger.error('Cannot copy segment %s to replay directory.', segmentPath, { err, ...lTags() })) |
189 | } | 191 | } |
190 | 192 | ||
191 | buildConcatenatedName (segmentOrPlaylistPath: string) { | 193 | buildConcatenatedName (segmentOrPlaylistPath: string) { |
@@ -202,7 +204,7 @@ class LiveManager { | |||
202 | if (videoLive.saveReplay) { | 204 | if (videoLive.saveReplay) { |
203 | await this.addSegmentToReplay(hlsVideoPath, previousSegment) | 205 | await this.addSegmentToReplay(hlsVideoPath, previousSegment) |
204 | } | 206 | } |
205 | }).catch(err => logger.error('Cannot process segments in %s', hlsVideoPath, { err })) | 207 | }).catch(err => logger.error('Cannot process segments in %s', hlsVideoPath, { err, ...lTags(videoUUID) })) |
206 | } | 208 | } |
207 | 209 | ||
208 | private getContext () { | 210 | private getContext () { |
@@ -226,13 +228,13 @@ class LiveManager { | |||
226 | private async handleSession (sessionId: string, streamPath: string, streamKey: string) { | 228 | private async handleSession (sessionId: string, streamPath: string, streamKey: string) { |
227 | const videoLive = await VideoLiveModel.loadByStreamKey(streamKey) | 229 | const videoLive = await VideoLiveModel.loadByStreamKey(streamKey) |
228 | if (!videoLive) { | 230 | if (!videoLive) { |
229 | logger.warn('Unknown live video with stream key %s.', streamKey) | 231 | logger.warn('Unknown live video with stream key %s.', streamKey, lTags(sessionId)) |
230 | return this.abortSession(sessionId) | 232 | return this.abortSession(sessionId) |
231 | } | 233 | } |
232 | 234 | ||
233 | const video = videoLive.Video | 235 | const video = videoLive.Video |
234 | if (video.isBlacklisted()) { | 236 | if (video.isBlacklisted()) { |
235 | logger.warn('Video is blacklisted. Refusing stream %s.', streamKey) | 237 | logger.warn('Video is blacklisted. Refusing stream %s.', streamKey, lTags(sessionId, video.uuid)) |
236 | return this.abortSession(sessionId) | 238 | return this.abortSession(sessionId) |
237 | } | 239 | } |
238 | 240 | ||
@@ -262,7 +264,10 @@ class LiveManager { | |||
262 | 264 | ||
263 | const allResolutions = resolutionsEnabled.concat([ session.videoHeight ]) | 265 | const allResolutions = resolutionsEnabled.concat([ session.videoHeight ]) |
264 | 266 | ||
265 | logger.info('Will mux/transcode live video of original resolution %d.', session.videoHeight, { allResolutions }) | 267 | logger.info( |
268 | 'Will mux/transcode live video of original resolution %d.', session.videoHeight, | ||
269 | { allResolutions, ...lTags(sessionId, video.uuid) } | ||
270 | ) | ||
266 | 271 | ||
267 | const [ videoStreamingPlaylist ] = await VideoStreamingPlaylistModel.upsert({ | 272 | const [ videoStreamingPlaylist ] = await VideoStreamingPlaylistModel.upsert({ |
268 | videoId: video.id, | 273 | videoId: video.id, |
@@ -317,7 +322,7 @@ class LiveManager { | |||
317 | }) | 322 | }) |
318 | 323 | ||
319 | VideoFileModel.customUpsert(file, 'streaming-playlist', null) | 324 | VideoFileModel.customUpsert(file, 'streaming-playlist', null) |
320 | .catch(err => logger.error('Cannot create file for live streaming.', { err })) | 325 | .catch(err => logger.error('Cannot create file for live streaming.', { err, ...lTags(sessionId, videoLive.Video.uuid) })) |
321 | } | 326 | } |
322 | 327 | ||
323 | const outPath = getHLSDirectory(videoLive.Video) | 328 | const outPath = getHLSDirectory(videoLive.Video) |
@@ -342,7 +347,7 @@ class LiveManager { | |||
342 | }) | 347 | }) |
343 | : getLiveMuxingCommand(rtmpUrl, outPath) | 348 | : getLiveMuxingCommand(rtmpUrl, outPath) |
344 | 349 | ||
345 | logger.info('Running live muxing/transcoding for %s.', videoUUID) | 350 | logger.info('Running live muxing/transcoding for %s.', videoUUID, lTags(sessionId, videoUUID)) |
346 | this.transSessions.set(sessionId, ffmpegExec) | 351 | this.transSessions.set(sessionId, ffmpegExec) |
347 | 352 | ||
348 | const tsWatcher = chokidar.watch(outPath + '/*.ts') | 353 | const tsWatcher = chokidar.watch(outPath + '/*.ts') |
@@ -351,7 +356,7 @@ class LiveManager { | |||
351 | const playlistIdMatcher = /^([\d+])-/ | 356 | const playlistIdMatcher = /^([\d+])-/ |
352 | 357 | ||
353 | const addHandler = segmentPath => { | 358 | const addHandler = segmentPath => { |
354 | logger.debug('Live add handler of %s.', segmentPath) | 359 | logger.debug('Live add handler of %s.', segmentPath, lTags(sessionId, videoUUID)) |
355 | 360 | ||
356 | const playlistId = basename(segmentPath).match(playlistIdMatcher)[0] | 361 | const playlistId = basename(segmentPath).match(playlistIdMatcher)[0] |
357 | 362 | ||
@@ -363,7 +368,9 @@ class LiveManager { | |||
363 | if (this.hasClientSocketsInBadHealthWithCache(sessionId)) { | 368 | if (this.hasClientSocketsInBadHealthWithCache(sessionId)) { |
364 | logger.error( | 369 | logger.error( |
365 | 'Too much data in client socket stream (ffmpeg is too slow to transcode the video).' + | 370 | 'Too much data in client socket stream (ffmpeg is too slow to transcode the video).' + |
366 | ' Stopping session of video %s.', videoUUID) | 371 | ' Stopping session of video %s.', videoUUID, |
372 | lTags(sessionId, videoUUID) | ||
373 | ) | ||
367 | 374 | ||
368 | this.stopSessionOf(videoLive.videoId) | 375 | this.stopSessionOf(videoLive.videoId) |
369 | return | 376 | return |
@@ -371,7 +378,7 @@ class LiveManager { | |||
371 | 378 | ||
372 | // Duration constraint check | 379 | // Duration constraint check |
373 | if (this.isDurationConstraintValid(startStreamDateTime) !== true) { | 380 | if (this.isDurationConstraintValid(startStreamDateTime) !== true) { |
374 | logger.info('Stopping session of %s: max duration exceeded.', videoUUID) | 381 | logger.info('Stopping session of %s: max duration exceeded.', videoUUID, lTags(sessionId, videoUUID)) |
375 | 382 | ||
376 | this.stopSessionOf(videoLive.videoId) | 383 | this.stopSessionOf(videoLive.videoId) |
377 | return | 384 | return |
@@ -386,12 +393,12 @@ class LiveManager { | |||
386 | .then(() => this.isQuotaConstraintValid(user, videoLive)) | 393 | .then(() => this.isQuotaConstraintValid(user, videoLive)) |
387 | .then(quotaValid => { | 394 | .then(quotaValid => { |
388 | if (quotaValid !== true) { | 395 | if (quotaValid !== true) { |
389 | logger.info('Stopping session of %s: user quota exceeded.', videoUUID) | 396 | logger.info('Stopping session of %s: user quota exceeded.', videoUUID, lTags(sessionId, videoUUID)) |
390 | 397 | ||
391 | this.stopSessionOf(videoLive.videoId) | 398 | this.stopSessionOf(videoLive.videoId) |
392 | } | 399 | } |
393 | }) | 400 | }) |
394 | .catch(err => logger.error('Cannot stat %s or check quota of %d.', segmentPath, user.id, { err })) | 401 | .catch(err => logger.error('Cannot stat %s or check quota of %d.', segmentPath, user.id, { err, ...lTags(sessionId, videoUUID) })) |
395 | } | 402 | } |
396 | } | 403 | } |
397 | 404 | ||
@@ -411,21 +418,21 @@ class LiveManager { | |||
411 | 418 | ||
412 | setTimeout(() => { | 419 | setTimeout(() => { |
413 | federateVideoIfNeeded(video, false) | 420 | federateVideoIfNeeded(video, false) |
414 | .catch(err => logger.error('Cannot federate live video %s.', video.url, { err })) | 421 | .catch(err => logger.error('Cannot federate live video %s.', video.url, { err, ...lTags(sessionId, videoUUID) })) |
415 | 422 | ||
416 | PeerTubeSocket.Instance.sendVideoLiveNewState(video) | 423 | PeerTubeSocket.Instance.sendVideoLiveNewState(video) |
417 | }, VIDEO_LIVE.SEGMENT_TIME_SECONDS * 1000 * VIDEO_LIVE.EDGE_LIVE_DELAY_SEGMENTS_NOTIFICATION) | 424 | }, VIDEO_LIVE.SEGMENT_TIME_SECONDS * 1000 * VIDEO_LIVE.EDGE_LIVE_DELAY_SEGMENTS_NOTIFICATION) |
418 | 425 | ||
419 | } catch (err) { | 426 | } catch (err) { |
420 | logger.error('Cannot save/federate live video %d.', videoLive.videoId, { err }) | 427 | logger.error('Cannot save/federate live video %d.', videoLive.videoId, { err, ...lTags(sessionId, videoUUID) }) |
421 | } finally { | 428 | } finally { |
422 | masterWatcher.close() | 429 | masterWatcher.close() |
423 | .catch(err => logger.error('Cannot close master watcher of %s.', outPath, { err })) | 430 | .catch(err => logger.error('Cannot close master watcher of %s.', outPath, { err, ...lTags(sessionId, videoUUID) })) |
424 | } | 431 | } |
425 | }) | 432 | }) |
426 | 433 | ||
427 | const onFFmpegEnded = () => { | 434 | const onFFmpegEnded = () => { |
428 | logger.info('RTMP transmuxing for video %s ended. Scheduling cleanup', rtmpUrl) | 435 | logger.info('RTMP transmuxing for video %s ended. Scheduling cleanup', rtmpUrl, lTags(sessionId, videoUUID)) |
429 | 436 | ||
430 | this.transSessions.delete(sessionId) | 437 | this.transSessions.delete(sessionId) |
431 | 438 | ||
@@ -446,10 +453,15 @@ class LiveManager { | |||
446 | this.processSegments(outPath, videoUUID, videoLive, segmentsToProcessPerPlaylist[key]) | 453 | this.processSegments(outPath, videoUUID, videoLive, segmentsToProcessPerPlaylist[key]) |
447 | } | 454 | } |
448 | }) | 455 | }) |
449 | .catch(err => logger.error('Cannot close watchers of %s or process remaining hash segments.', outPath, { err })) | 456 | .catch(err => { |
457 | logger.error( | ||
458 | 'Cannot close watchers of %s or process remaining hash segments.', outPath, | ||
459 | { err, ...lTags(sessionId, videoUUID) } | ||
460 | ) | ||
461 | }) | ||
450 | 462 | ||
451 | this.onEndTransmuxing(videoLive.Video.id) | 463 | this.onEndTransmuxing(videoLive.Video.id) |
452 | .catch(err => logger.error('Error in closed transmuxing.', { err })) | 464 | .catch(err => logger.error('Error in closed transmuxing.', { err, ...lTags(sessionId, videoUUID) })) |
453 | }, 1000) | 465 | }, 1000) |
454 | } | 466 | } |
455 | 467 | ||
@@ -459,7 +471,7 @@ class LiveManager { | |||
459 | // Don't care that we killed the ffmpeg process | 471 | // Don't care that we killed the ffmpeg process |
460 | if (err?.message?.includes('Exiting normally')) return | 472 | if (err?.message?.includes('Exiting normally')) return |
461 | 473 | ||
462 | logger.error('Live transcoding error.', { err, stdout, stderr }) | 474 | logger.error('Live transcoding error.', { err, stdout, stderr, ...lTags(sessionId, videoUUID) }) |
463 | 475 | ||
464 | this.abortSession(sessionId) | 476 | this.abortSession(sessionId) |
465 | }) | 477 | }) |
@@ -469,12 +481,12 @@ class LiveManager { | |||
469 | ffmpegExec.run() | 481 | ffmpegExec.run() |
470 | } | 482 | } |
471 | 483 | ||
472 | private async onEndTransmuxing (videoId: number, cleanupNow = false) { | 484 | private async onEndTransmuxing (videoUUID: string, cleanupNow = false) { |
473 | try { | 485 | try { |
474 | const fullVideo = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoId) | 486 | const fullVideo = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoUUID) |
475 | if (!fullVideo) return | 487 | if (!fullVideo) return |
476 | 488 | ||
477 | const live = await VideoLiveModel.loadByVideoId(videoId) | 489 | const live = await VideoLiveModel.loadByVideoId(fullVideo.id) |
478 | 490 | ||
479 | if (!live.permanentLive) { | 491 | if (!live.permanentLive) { |
480 | JobQueue.Instance.createJob({ | 492 | JobQueue.Instance.createJob({ |
@@ -495,13 +507,13 @@ class LiveManager { | |||
495 | 507 | ||
496 | await federateVideoIfNeeded(fullVideo, false) | 508 | await federateVideoIfNeeded(fullVideo, false) |
497 | } catch (err) { | 509 | } catch (err) { |
498 | logger.error('Cannot save/federate new video state of live streaming of video id %d.', videoId, { err }) | 510 | logger.error('Cannot save/federate new video state of live streaming of video %d.', videoUUID, { err, ...lTags(videoUUID) }) |
499 | } | 511 | } |
500 | } | 512 | } |
501 | 513 | ||
502 | private async addSegmentSha (videoUUID: string, segmentPath: string) { | 514 | private async addSegmentSha (videoUUID: string, segmentPath: string) { |
503 | const segmentName = basename(segmentPath) | 515 | const segmentName = basename(segmentPath) |
504 | logger.debug('Adding live sha segment %s.', segmentPath) | 516 | logger.debug('Adding live sha segment %s.', segmentPath, lTags(videoUUID)) |
505 | 517 | ||
506 | const shaResult = await buildSha256Segment(segmentPath) | 518 | const shaResult = await buildSha256Segment(segmentPath) |
507 | 519 | ||
@@ -516,16 +528,16 @@ class LiveManager { | |||
516 | private removeSegmentSha (videoUUID: string, segmentPath: string) { | 528 | private removeSegmentSha (videoUUID: string, segmentPath: string) { |
517 | const segmentName = basename(segmentPath) | 529 | const segmentName = basename(segmentPath) |
518 | 530 | ||
519 | logger.debug('Removing live sha segment %s.', segmentPath) | 531 | logger.debug('Removing live sha segment %s.', segmentPath, lTags(videoUUID)) |
520 | 532 | ||
521 | const filesMap = this.segmentsSha256.get(videoUUID) | 533 | const filesMap = this.segmentsSha256.get(videoUUID) |
522 | if (!filesMap) { | 534 | if (!filesMap) { |
523 | logger.warn('Unknown files map to remove sha for %s.', videoUUID) | 535 | logger.warn('Unknown files map to remove sha for %s.', videoUUID, lTags(videoUUID)) |
524 | return | 536 | return |
525 | } | 537 | } |
526 | 538 | ||
527 | if (!filesMap.has(segmentName)) { | 539 | if (!filesMap.has(segmentName)) { |
528 | logger.warn('Unknown segment in files map for video %s and segment %s.', videoUUID, segmentPath) | 540 | logger.warn('Unknown segment in files map for video %s and segment %s.', videoUUID, segmentPath, lTags(videoUUID)) |
529 | return | 541 | return |
530 | } | 542 | } |
531 | 543 | ||
@@ -547,7 +559,7 @@ class LiveManager { | |||
547 | const rtmpSession = this.getContext().sessions.get(sessionId) | 559 | const rtmpSession = this.getContext().sessions.get(sessionId) |
548 | 560 | ||
549 | if (!rtmpSession) { | 561 | if (!rtmpSession) { |
550 | logger.warn('Cannot get session %s to check players socket health.', sessionId) | 562 | logger.warn('Cannot get session %s to check players socket health.', sessionId, lTags(sessionId)) |
551 | return | 563 | return |
552 | } | 564 | } |
553 | 565 | ||
@@ -555,7 +567,7 @@ class LiveManager { | |||
555 | const playerSession = this.getContext().sessions.get(playerSessionId) | 567 | const playerSession = this.getContext().sessions.get(playerSessionId) |
556 | 568 | ||
557 | if (!playerSession) { | 569 | if (!playerSession) { |
558 | logger.error('Cannot get player session %s to check socket health.', playerSession) | 570 | logger.error('Cannot get player session %s to check socket health.', playerSession, lTags(sessionId)) |
559 | continue | 571 | continue |
560 | } | 572 | } |
561 | 573 | ||
@@ -576,7 +588,7 @@ class LiveManager { | |||
576 | private async updateLiveViews () { | 588 | private async updateLiveViews () { |
577 | if (!this.isRunning()) return | 589 | if (!this.isRunning()) return |
578 | 590 | ||
579 | if (!isTestInstance()) logger.info('Updating live video views.') | 591 | if (!isTestInstance()) logger.info('Updating live video views.', lTags()) |
580 | 592 | ||
581 | for (const videoId of this.watchersPerVideo.keys()) { | 593 | for (const videoId of this.watchersPerVideo.keys()) { |
582 | const notBefore = new Date().getTime() - VIEW_LIFETIME.LIVE | 594 | const notBefore = new Date().getTime() - VIEW_LIFETIME.LIVE |
@@ -597,15 +609,15 @@ class LiveManager { | |||
597 | const newWatchers = watchers.filter(w => w > notBefore) | 609 | const newWatchers = watchers.filter(w => w > notBefore) |
598 | this.watchersPerVideo.set(videoId, newWatchers) | 610 | this.watchersPerVideo.set(videoId, newWatchers) |
599 | 611 | ||
600 | logger.debug('New live video views for %s is %d.', video.url, numWatchers) | 612 | logger.debug('New live video views for %s is %d.', video.url, numWatchers, lTags()) |
601 | } | 613 | } |
602 | } | 614 | } |
603 | 615 | ||
604 | private async handleBrokenLives () { | 616 | private async handleBrokenLives () { |
605 | const videoIds = await VideoModel.listPublishedLiveIds() | 617 | const videoUUIDs = await VideoModel.listPublishedLiveUUIDs() |
606 | 618 | ||
607 | for (const id of videoIds) { | 619 | for (const uuid of videoUUIDs) { |
608 | await this.onEndTransmuxing(id, true) | 620 | await this.onEndTransmuxing(uuid, true) |
609 | } | 621 | } |
610 | } | 622 | } |
611 | 623 | ||
diff --git a/server/lib/moderation.ts b/server/lib/moderation.ts index 925d64902..0cefe1648 100644 --- a/server/lib/moderation.ts +++ b/server/lib/moderation.ts | |||
@@ -23,9 +23,9 @@ import { ActivityCreate } from '../../shared/models/activitypub' | |||
23 | import { VideoObject } from '../../shared/models/activitypub/objects' | 23 | import { VideoObject } from '../../shared/models/activitypub/objects' |
24 | import { VideoCommentObject } from '../../shared/models/activitypub/objects/video-comment-object' | 24 | import { VideoCommentObject } from '../../shared/models/activitypub/objects/video-comment-object' |
25 | import { LiveVideoCreate, VideoCreate, VideoImportCreate } from '../../shared/models/videos' | 25 | import { LiveVideoCreate, VideoCreate, VideoImportCreate } from '../../shared/models/videos' |
26 | import { VideoCommentCreate } from '../../shared/models/videos/video-comment.model' | 26 | import { VideoCommentCreate } from '../../shared/models/videos/comment/video-comment.model' |
27 | import { UserModel } from '../models/account/user' | 27 | import { ActorModel } from '../models/actor/actor' |
28 | import { ActorModel } from '../models/activitypub/actor' | 28 | import { UserModel } from '../models/user/user' |
29 | import { VideoModel } from '../models/video/video' | 29 | import { VideoModel } from '../models/video/video' |
30 | import { VideoCommentModel } from '../models/video/video-comment' | 30 | import { VideoCommentModel } from '../models/video/video-comment' |
31 | import { sendAbuse } from './activitypub/send/send-flag' | 31 | import { sendAbuse } from './activitypub/send/send-flag' |
diff --git a/server/lib/notifier.ts b/server/lib/notifier.ts index da7f7cc05..1f9ff16df 100644 --- a/server/lib/notifier.ts +++ b/server/lib/notifier.ts | |||
@@ -17,8 +17,8 @@ import { VideoPrivacy, VideoState } from '../../shared/models/videos' | |||
17 | import { logger } from '../helpers/logger' | 17 | import { logger } from '../helpers/logger' |
18 | import { CONFIG } from '../initializers/config' | 18 | import { CONFIG } from '../initializers/config' |
19 | import { AccountBlocklistModel } from '../models/account/account-blocklist' | 19 | import { AccountBlocklistModel } from '../models/account/account-blocklist' |
20 | import { UserModel } from '../models/account/user' | 20 | import { UserModel } from '../models/user/user' |
21 | import { UserNotificationModel } from '../models/account/user-notification' | 21 | import { UserNotificationModel } from '../models/user/user-notification' |
22 | import { MAbuseFull, MAbuseMessage, MAccountServer, MActorFollowFull, MApplication, MPlugin } from '../types/models' | 22 | import { MAbuseFull, MAbuseMessage, MAccountServer, MActorFollowFull, MApplication, MPlugin } from '../types/models' |
23 | import { MCommentOwnerVideo, MVideoAccountLight, MVideoFullLight } from '../types/models/video' | 23 | import { MCommentOwnerVideo, MVideoAccountLight, MVideoFullLight } from '../types/models/video' |
24 | import { isBlockedByServerOrAccount } from './blocklist' | 24 | import { isBlockedByServerOrAccount } from './blocklist' |
diff --git a/server/lib/plugins/hooks.ts b/server/lib/plugins/hooks.ts index aa92f03cc..5e97b52a0 100644 --- a/server/lib/plugins/hooks.ts +++ b/server/lib/plugins/hooks.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { ServerActionHookName, ServerFilterHookName } from '../../../shared/models/plugins/server-hook.model' | ||
2 | import { PluginManager } from './plugin-manager' | ||
3 | import { logger } from '../../helpers/logger' | ||
4 | import * as Bluebird from 'bluebird' | 1 | import * as Bluebird from 'bluebird' |
2 | import { ServerActionHookName, ServerFilterHookName } from '../../../shared/models' | ||
3 | import { logger } from '../../helpers/logger' | ||
4 | import { PluginManager } from './plugin-manager' | ||
5 | 5 | ||
6 | type PromiseFunction <U, T> = (params: U) => Promise<T> | Bluebird<T> | 6 | type PromiseFunction <U, T> = (params: U) => Promise<T> | Bluebird<T> |
7 | type RawFunction <U, T> = (params: U) => T | 7 | type RawFunction <U, T> = (params: U) => T |
diff --git a/server/lib/plugins/plugin-helpers-builder.ts b/server/lib/plugins/plugin-helpers-builder.ts index f1bc24d8b..8487672ba 100644 --- a/server/lib/plugins/plugin-helpers-builder.ts +++ b/server/lib/plugins/plugin-helpers-builder.ts | |||
@@ -15,9 +15,9 @@ import { MPlugin } from '@server/types/models' | |||
15 | import { PeerTubeHelpers } from '@server/types/plugins' | 15 | import { PeerTubeHelpers } from '@server/types/plugins' |
16 | import { VideoBlacklistCreate } from '@shared/models' | 16 | 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 { ServerConfigManager } from '../server-config-manager' |
19 | import { blacklistVideo, unblacklistVideo } from '../video-blacklist' | 19 | import { blacklistVideo, unblacklistVideo } from '../video-blacklist' |
20 | import { UserModel } from '@server/models/account/user' | 20 | import { UserModel } from '@server/models/user/user' |
21 | 21 | ||
22 | function buildPluginHelpers (pluginModel: MPlugin, npmName: string): PeerTubeHelpers { | 22 | function buildPluginHelpers (pluginModel: MPlugin, npmName: string): PeerTubeHelpers { |
23 | const logger = buildPluginLogger(npmName) | 23 | const logger = buildPluginLogger(npmName) |
@@ -147,7 +147,7 @@ function buildConfigHelpers () { | |||
147 | }, | 147 | }, |
148 | 148 | ||
149 | getServerConfig () { | 149 | getServerConfig () { |
150 | return getServerConfig() | 150 | return ServerConfigManager.Instance.getServerConfig() |
151 | } | 151 | } |
152 | } | 152 | } |
153 | } | 153 | } |
diff --git a/server/lib/plugins/plugin-index.ts b/server/lib/plugins/plugin-index.ts index 165bc91b3..119cee8e0 100644 --- a/server/lib/plugins/plugin-index.ts +++ b/server/lib/plugins/plugin-index.ts | |||
@@ -1,16 +1,16 @@ | |||
1 | import { sanitizeUrl } from '@server/helpers/core-utils' | 1 | import { sanitizeUrl } from '@server/helpers/core-utils' |
2 | import { ResultList } from '../../../shared/models' | 2 | import { logger } from '@server/helpers/logger' |
3 | import { PeertubePluginIndexList } from '../../../shared/models/plugins/peertube-plugin-index-list.model' | 3 | import { doJSONRequest } from '@server/helpers/requests' |
4 | import { PeerTubePluginIndex } from '../../../shared/models/plugins/peertube-plugin-index.model' | 4 | import { CONFIG } from '@server/initializers/config' |
5 | import { PEERTUBE_VERSION } from '@server/initializers/constants' | ||
6 | import { PluginModel } from '@server/models/server/plugin' | ||
5 | import { | 7 | import { |
8 | PeerTubePluginIndex, | ||
9 | PeertubePluginIndexList, | ||
6 | PeertubePluginLatestVersionRequest, | 10 | PeertubePluginLatestVersionRequest, |
7 | PeertubePluginLatestVersionResponse | 11 | PeertubePluginLatestVersionResponse, |
8 | } from '../../../shared/models/plugins/peertube-plugin-latest-version.model' | 12 | ResultList |
9 | import { logger } from '../../helpers/logger' | 13 | } from '@shared/models' |
10 | import { doJSONRequest } from '../../helpers/requests' | ||
11 | import { CONFIG } from '../../initializers/config' | ||
12 | import { PEERTUBE_VERSION } from '../../initializers/constants' | ||
13 | import { PluginModel } from '../../models/server/plugin' | ||
14 | import { PluginManager } from './plugin-manager' | 14 | import { PluginManager } from './plugin-manager' |
15 | 15 | ||
16 | async function listAvailablePluginsFromIndex (options: PeertubePluginIndexList) { | 16 | async function listAvailablePluginsFromIndex (options: PeertubePluginIndexList) { |
diff --git a/server/lib/plugins/plugin-manager.ts b/server/lib/plugins/plugin-manager.ts index ba9814383..6b9a255a4 100644 --- a/server/lib/plugins/plugin-manager.ts +++ b/server/lib/plugins/plugin-manager.ts | |||
@@ -4,16 +4,11 @@ import { createReadStream, createWriteStream } from 'fs' | |||
4 | import { ensureDir, outputFile, readJSON } from 'fs-extra' | 4 | import { ensureDir, outputFile, readJSON } from 'fs-extra' |
5 | import { basename, join } from 'path' | 5 | import { basename, join } from 'path' |
6 | import { MOAuthTokenUser, MUser } from '@server/types/models' | 6 | import { MOAuthTokenUser, MUser } from '@server/types/models' |
7 | import { RegisterServerHookOptions } from '@shared/models/plugins/register-server-hook.model' | 7 | import { getCompleteLocale } from '@shared/core-utils' |
8 | import { ClientScript, PluginPackageJson, PluginTranslation, PluginTranslationPaths, RegisterServerHookOptions } from '@shared/models' | ||
8 | import { getHookType, internalRunHook } from '../../../shared/core-utils/plugins/hooks' | 9 | import { getHookType, internalRunHook } from '../../../shared/core-utils/plugins/hooks' |
9 | import { | ||
10 | ClientScript, | ||
11 | PluginPackageJson, | ||
12 | PluginTranslationPaths as PackagePluginTranslations | ||
13 | } from '../../../shared/models/plugins/plugin-package-json.model' | ||
14 | import { PluginTranslation } from '../../../shared/models/plugins/plugin-translation.model' | ||
15 | import { PluginType } from '../../../shared/models/plugins/plugin.type' | 10 | import { PluginType } from '../../../shared/models/plugins/plugin.type' |
16 | import { ServerHook, ServerHookName } from '../../../shared/models/plugins/server-hook.model' | 11 | import { ServerHook, ServerHookName } from '../../../shared/models/plugins/server/server-hook.model' |
17 | import { isLibraryCodeValid, isPackageJSONValid } from '../../helpers/custom-validators/plugins' | 12 | import { isLibraryCodeValid, isPackageJSONValid } from '../../helpers/custom-validators/plugins' |
18 | import { logger } from '../../helpers/logger' | 13 | import { logger } from '../../helpers/logger' |
19 | import { CONFIG } from '../../initializers/config' | 14 | import { CONFIG } from '../../initializers/config' |
@@ -23,7 +18,6 @@ import { PluginLibrary, RegisterServerAuthExternalOptions, RegisterServerAuthPas | |||
23 | import { ClientHtml } from '../client-html' | 18 | import { ClientHtml } from '../client-html' |
24 | import { RegisterHelpers } from './register-helpers' | 19 | import { RegisterHelpers } from './register-helpers' |
25 | import { installNpmPlugin, installNpmPluginFromDisk, removeNpmPlugin } from './yarn' | 20 | import { installNpmPlugin, installNpmPluginFromDisk, removeNpmPlugin } from './yarn' |
26 | import { getCompleteLocale } from '@shared/core-utils' | ||
27 | 21 | ||
28 | export interface RegisteredPlugin { | 22 | export interface RegisteredPlugin { |
29 | npmName: string | 23 | npmName: string |
@@ -443,7 +437,7 @@ export class PluginManager implements ServerHook { | |||
443 | 437 | ||
444 | // ###################### Translations ###################### | 438 | // ###################### Translations ###################### |
445 | 439 | ||
446 | private async addTranslations (plugin: PluginModel, npmName: string, translationPaths: PackagePluginTranslations) { | 440 | private async addTranslations (plugin: PluginModel, npmName: string, translationPaths: PluginTranslationPaths) { |
447 | for (const locale of Object.keys(translationPaths)) { | 441 | for (const locale of Object.keys(translationPaths)) { |
448 | const path = translationPaths[locale] | 442 | const path = translationPaths[locale] |
449 | const json = await readJSON(join(this.getPluginPath(plugin.name, plugin.type), path)) | 443 | const json = await readJSON(join(this.getPluginPath(plugin.name, plugin.type), path)) |
diff --git a/server/lib/plugins/register-helpers.ts b/server/lib/plugins/register-helpers.ts index aa69ca2a2..f5b573370 100644 --- a/server/lib/plugins/register-helpers.ts +++ b/server/lib/plugins/register-helpers.ts | |||
@@ -26,10 +26,10 @@ import { | |||
26 | PluginVideoLicenceManager, | 26 | PluginVideoLicenceManager, |
27 | PluginVideoPrivacyManager, | 27 | PluginVideoPrivacyManager, |
28 | RegisterServerHookOptions, | 28 | RegisterServerHookOptions, |
29 | RegisterServerSettingOptions | 29 | RegisterServerSettingOptions, |
30 | serverHookObject | ||
30 | } from '@shared/models' | 31 | } from '@shared/models' |
31 | import { serverHookObject } from '@shared/models/plugins/server-hook.model' | 32 | import { VideoTranscodingProfilesManager } from '../transcoding/video-transcoding-profiles' |
32 | import { VideoTranscodingProfilesManager } from '../video-transcoding-profiles' | ||
33 | import { buildPluginHelpers } from './plugin-helpers-builder' | 33 | import { buildPluginHelpers } from './plugin-helpers-builder' |
34 | 34 | ||
35 | type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy' | 35 | type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy' |
diff --git a/server/lib/redundancy.ts b/server/lib/redundancy.ts index da620b607..2a9241249 100644 --- a/server/lib/redundancy.ts +++ b/server/lib/redundancy.ts | |||
@@ -1,12 +1,12 @@ | |||
1 | import { VideoRedundancyModel } from '../models/redundancy/video-redundancy' | ||
2 | import { sendUndoCacheFile } from './activitypub/send' | ||
3 | import { Transaction } from 'sequelize' | 1 | import { Transaction } from 'sequelize' |
4 | import { MActorSignature, MVideoRedundancyVideo } from '@server/types/models' | ||
5 | import { CONFIG } from '@server/initializers/config' | ||
6 | import { logger } from '@server/helpers/logger' | 2 | import { logger } from '@server/helpers/logger' |
7 | import { ActorFollowModel } from '@server/models/activitypub/actor-follow' | 3 | import { CONFIG } from '@server/initializers/config' |
8 | import { Activity } from '@shared/models' | 4 | import { ActorFollowModel } from '@server/models/actor/actor-follow' |
9 | import { getServerActor } from '@server/models/application/application' | 5 | import { getServerActor } from '@server/models/application/application' |
6 | import { MActorSignature, MVideoRedundancyVideo } from '@server/types/models' | ||
7 | import { Activity } from '@shared/models' | ||
8 | import { VideoRedundancyModel } from '../models/redundancy/video-redundancy' | ||
9 | import { sendUndoCacheFile } from './activitypub/send' | ||
10 | 10 | ||
11 | async function removeVideoRedundancy (videoRedundancy: MVideoRedundancyVideo, t?: Transaction) { | 11 | async function removeVideoRedundancy (videoRedundancy: MVideoRedundancyVideo, t?: Transaction) { |
12 | const serverActor = await getServerActor() | 12 | const serverActor = await getServerActor() |
diff --git a/server/lib/schedulers/actor-follow-scheduler.ts b/server/lib/schedulers/actor-follow-scheduler.ts index 598c0211f..1b80316e9 100644 --- a/server/lib/schedulers/actor-follow-scheduler.ts +++ b/server/lib/schedulers/actor-follow-scheduler.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | import { isTestInstance } from '../../helpers/core-utils' | 1 | import { isTestInstance } from '../../helpers/core-utils' |
2 | import { logger } from '../../helpers/logger' | 2 | import { logger } from '../../helpers/logger' |
3 | import { ActorFollowModel } from '../../models/activitypub/actor-follow' | ||
4 | import { AbstractScheduler } from './abstract-scheduler' | ||
5 | import { ACTOR_FOLLOW_SCORE, SCHEDULER_INTERVALS_MS } from '../../initializers/constants' | 3 | import { ACTOR_FOLLOW_SCORE, SCHEDULER_INTERVALS_MS } from '../../initializers/constants' |
4 | import { ActorFollowModel } from '../../models/actor/actor-follow' | ||
6 | import { ActorFollowScoreCache } from '../files-cache' | 5 | import { ActorFollowScoreCache } from '../files-cache' |
6 | import { AbstractScheduler } from './abstract-scheduler' | ||
7 | 7 | ||
8 | export class ActorFollowScheduler extends AbstractScheduler { | 8 | export class ActorFollowScheduler extends AbstractScheduler { |
9 | 9 | ||
diff --git a/server/lib/schedulers/auto-follow-index-instances.ts b/server/lib/schedulers/auto-follow-index-instances.ts index 0b8cd1389..aaa5feed5 100644 --- a/server/lib/schedulers/auto-follow-index-instances.ts +++ b/server/lib/schedulers/auto-follow-index-instances.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { chunk } from 'lodash' | 1 | import { chunk } from 'lodash' |
2 | import { doJSONRequest } from '@server/helpers/requests' | 2 | import { doJSONRequest } from '@server/helpers/requests' |
3 | import { JobQueue } from '@server/lib/job-queue' | 3 | import { JobQueue } from '@server/lib/job-queue' |
4 | import { ActorFollowModel } from '@server/models/activitypub/actor-follow' | 4 | import { ActorFollowModel } from '@server/models/actor/actor-follow' |
5 | import { getServerActor } from '@server/models/application/application' | 5 | import { getServerActor } from '@server/models/application/application' |
6 | import { logger } from '../../helpers/logger' | 6 | import { logger } from '../../helpers/logger' |
7 | import { CONFIG } from '../../initializers/config' | 7 | import { CONFIG } from '../../initializers/config' |
diff --git a/server/lib/schedulers/remove-old-history-scheduler.ts b/server/lib/schedulers/remove-old-history-scheduler.ts index 17a42b2c4..225669ea2 100644 --- a/server/lib/schedulers/remove-old-history-scheduler.ts +++ b/server/lib/schedulers/remove-old-history-scheduler.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { logger } from '../../helpers/logger' | 1 | import { logger } from '../../helpers/logger' |
2 | import { AbstractScheduler } from './abstract-scheduler' | 2 | import { AbstractScheduler } from './abstract-scheduler' |
3 | import { SCHEDULER_INTERVALS_MS } from '../../initializers/constants' | 3 | import { SCHEDULER_INTERVALS_MS } from '../../initializers/constants' |
4 | import { UserVideoHistoryModel } from '../../models/account/user-video-history' | 4 | import { UserVideoHistoryModel } from '../../models/user/user-video-history' |
5 | import { CONFIG } from '../../initializers/config' | 5 | import { CONFIG } from '../../initializers/config' |
6 | 6 | ||
7 | export class RemoveOldHistoryScheduler extends AbstractScheduler { | 7 | export class RemoveOldHistoryScheduler extends AbstractScheduler { |
diff --git a/server/lib/schedulers/youtube-dl-update-scheduler.ts b/server/lib/schedulers/youtube-dl-update-scheduler.ts index aefe6aba4..898691c13 100644 --- a/server/lib/schedulers/youtube-dl-update-scheduler.ts +++ b/server/lib/schedulers/youtube-dl-update-scheduler.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { AbstractScheduler } from './abstract-scheduler' | 1 | import { YoutubeDL } from '@server/helpers/youtube-dl' |
2 | import { SCHEDULER_INTERVALS_MS } from '../../initializers/constants' | 2 | import { SCHEDULER_INTERVALS_MS } from '../../initializers/constants' |
3 | import { updateYoutubeDLBinary } from '../../helpers/youtube-dl' | 3 | import { AbstractScheduler } from './abstract-scheduler' |
4 | 4 | ||
5 | export class YoutubeDlUpdateScheduler extends AbstractScheduler { | 5 | export class YoutubeDlUpdateScheduler extends AbstractScheduler { |
6 | 6 | ||
@@ -13,7 +13,7 @@ export class YoutubeDlUpdateScheduler extends AbstractScheduler { | |||
13 | } | 13 | } |
14 | 14 | ||
15 | protected internalExecute () { | 15 | protected internalExecute () { |
16 | return updateYoutubeDLBinary() | 16 | return YoutubeDL.updateYoutubeDLBinary() |
17 | } | 17 | } |
18 | 18 | ||
19 | static get Instance () { | 19 | static get Instance () { |
diff --git a/server/lib/server-config-manager.ts b/server/lib/server-config-manager.ts new file mode 100644 index 000000000..25a770c6b --- /dev/null +++ b/server/lib/server-config-manager.ts | |||
@@ -0,0 +1,304 @@ | |||
1 | import { isSignupAllowed, isSignupAllowedForCurrentIP } from '@server/helpers/signup' | ||
2 | import { getServerCommit } from '@server/helpers/utils' | ||
3 | import { CONFIG, isEmailEnabled } from '@server/initializers/config' | ||
4 | import { CONSTRAINTS_FIELDS, DEFAULT_THEME_NAME, PEERTUBE_VERSION } from '@server/initializers/constants' | ||
5 | import { ActorCustomPageModel } from '@server/models/account/actor-custom-page' | ||
6 | import { HTMLServerConfig, RegisteredExternalAuthConfig, RegisteredIdAndPassAuthConfig, ServerConfig } from '@shared/models' | ||
7 | import { Hooks } from './plugins/hooks' | ||
8 | import { PluginManager } from './plugins/plugin-manager' | ||
9 | import { getThemeOrDefault } from './plugins/theme-utils' | ||
10 | import { VideoTranscodingProfilesManager } from './transcoding/video-transcoding-profiles' | ||
11 | |||
12 | /** | ||
13 | * | ||
14 | * Used to send the server config to clients (using REST/API or plugins API) | ||
15 | * We need a singleton class to manage config state depending on external events (to build menu entries etc) | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | class ServerConfigManager { | ||
20 | |||
21 | private static instance: ServerConfigManager | ||
22 | |||
23 | private serverCommit: string | ||
24 | |||
25 | private homepageEnabled = false | ||
26 | |||
27 | private constructor () {} | ||
28 | |||
29 | async init () { | ||
30 | const instanceHomepage = await ActorCustomPageModel.loadInstanceHomepage() | ||
31 | |||
32 | this.updateHomepageState(instanceHomepage?.content) | ||
33 | } | ||
34 | |||
35 | updateHomepageState (content: string) { | ||
36 | this.homepageEnabled = !!content | ||
37 | } | ||
38 | |||
39 | async getHTMLServerConfig (): Promise<HTMLServerConfig> { | ||
40 | if (this.serverCommit === undefined) this.serverCommit = await getServerCommit() | ||
41 | |||
42 | const defaultTheme = getThemeOrDefault(CONFIG.THEME.DEFAULT, DEFAULT_THEME_NAME) | ||
43 | |||
44 | return { | ||
45 | instance: { | ||
46 | name: CONFIG.INSTANCE.NAME, | ||
47 | shortDescription: CONFIG.INSTANCE.SHORT_DESCRIPTION, | ||
48 | isNSFW: CONFIG.INSTANCE.IS_NSFW, | ||
49 | defaultNSFWPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY, | ||
50 | defaultClientRoute: CONFIG.INSTANCE.DEFAULT_CLIENT_ROUTE, | ||
51 | customizations: { | ||
52 | javascript: CONFIG.INSTANCE.CUSTOMIZATIONS.JAVASCRIPT, | ||
53 | css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS | ||
54 | } | ||
55 | }, | ||
56 | search: { | ||
57 | remoteUri: { | ||
58 | users: CONFIG.SEARCH.REMOTE_URI.USERS, | ||
59 | anonymous: CONFIG.SEARCH.REMOTE_URI.ANONYMOUS | ||
60 | }, | ||
61 | searchIndex: { | ||
62 | enabled: CONFIG.SEARCH.SEARCH_INDEX.ENABLED, | ||
63 | url: CONFIG.SEARCH.SEARCH_INDEX.URL, | ||
64 | disableLocalSearch: CONFIG.SEARCH.SEARCH_INDEX.DISABLE_LOCAL_SEARCH, | ||
65 | isDefaultSearch: CONFIG.SEARCH.SEARCH_INDEX.IS_DEFAULT_SEARCH | ||
66 | } | ||
67 | }, | ||
68 | plugin: { | ||
69 | registered: this.getRegisteredPlugins(), | ||
70 | registeredExternalAuths: this.getExternalAuthsPlugins(), | ||
71 | registeredIdAndPassAuths: this.getIdAndPassAuthPlugins() | ||
72 | }, | ||
73 | theme: { | ||
74 | registered: this.getRegisteredThemes(), | ||
75 | default: defaultTheme | ||
76 | }, | ||
77 | email: { | ||
78 | enabled: isEmailEnabled() | ||
79 | }, | ||
80 | contactForm: { | ||
81 | enabled: CONFIG.CONTACT_FORM.ENABLED | ||
82 | }, | ||
83 | serverVersion: PEERTUBE_VERSION, | ||
84 | serverCommit: this.serverCommit, | ||
85 | transcoding: { | ||
86 | hls: { | ||
87 | enabled: CONFIG.TRANSCODING.HLS.ENABLED | ||
88 | }, | ||
89 | webtorrent: { | ||
90 | enabled: CONFIG.TRANSCODING.WEBTORRENT.ENABLED | ||
91 | }, | ||
92 | enabledResolutions: this.getEnabledResolutions('vod'), | ||
93 | profile: CONFIG.TRANSCODING.PROFILE, | ||
94 | availableProfiles: VideoTranscodingProfilesManager.Instance.getAvailableProfiles('vod') | ||
95 | }, | ||
96 | live: { | ||
97 | enabled: CONFIG.LIVE.ENABLED, | ||
98 | |||
99 | allowReplay: CONFIG.LIVE.ALLOW_REPLAY, | ||
100 | maxDuration: CONFIG.LIVE.MAX_DURATION, | ||
101 | maxInstanceLives: CONFIG.LIVE.MAX_INSTANCE_LIVES, | ||
102 | maxUserLives: CONFIG.LIVE.MAX_USER_LIVES, | ||
103 | |||
104 | transcoding: { | ||
105 | enabled: CONFIG.LIVE.TRANSCODING.ENABLED, | ||
106 | enabledResolutions: this.getEnabledResolutions('live'), | ||
107 | profile: CONFIG.LIVE.TRANSCODING.PROFILE, | ||
108 | availableProfiles: VideoTranscodingProfilesManager.Instance.getAvailableProfiles('live') | ||
109 | }, | ||
110 | |||
111 | rtmp: { | ||
112 | port: CONFIG.LIVE.RTMP.PORT | ||
113 | } | ||
114 | }, | ||
115 | import: { | ||
116 | videos: { | ||
117 | http: { | ||
118 | enabled: CONFIG.IMPORT.VIDEOS.HTTP.ENABLED | ||
119 | }, | ||
120 | torrent: { | ||
121 | enabled: CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED | ||
122 | } | ||
123 | } | ||
124 | }, | ||
125 | autoBlacklist: { | ||
126 | videos: { | ||
127 | ofUsers: { | ||
128 | enabled: CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED | ||
129 | } | ||
130 | } | ||
131 | }, | ||
132 | avatar: { | ||
133 | file: { | ||
134 | size: { | ||
135 | max: CONSTRAINTS_FIELDS.ACTORS.IMAGE.FILE_SIZE.max | ||
136 | }, | ||
137 | extensions: CONSTRAINTS_FIELDS.ACTORS.IMAGE.EXTNAME | ||
138 | } | ||
139 | }, | ||
140 | banner: { | ||
141 | file: { | ||
142 | size: { | ||
143 | max: CONSTRAINTS_FIELDS.ACTORS.IMAGE.FILE_SIZE.max | ||
144 | }, | ||
145 | extensions: CONSTRAINTS_FIELDS.ACTORS.IMAGE.EXTNAME | ||
146 | } | ||
147 | }, | ||
148 | video: { | ||
149 | image: { | ||
150 | extensions: CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME, | ||
151 | size: { | ||
152 | max: CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max | ||
153 | } | ||
154 | }, | ||
155 | file: { | ||
156 | extensions: CONSTRAINTS_FIELDS.VIDEOS.EXTNAME | ||
157 | } | ||
158 | }, | ||
159 | videoCaption: { | ||
160 | file: { | ||
161 | size: { | ||
162 | max: CONSTRAINTS_FIELDS.VIDEO_CAPTIONS.CAPTION_FILE.FILE_SIZE.max | ||
163 | }, | ||
164 | extensions: CONSTRAINTS_FIELDS.VIDEO_CAPTIONS.CAPTION_FILE.EXTNAME | ||
165 | } | ||
166 | }, | ||
167 | user: { | ||
168 | videoQuota: CONFIG.USER.VIDEO_QUOTA, | ||
169 | videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY | ||
170 | }, | ||
171 | trending: { | ||
172 | videos: { | ||
173 | intervalDays: CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS, | ||
174 | algorithms: { | ||
175 | enabled: CONFIG.TRENDING.VIDEOS.ALGORITHMS.ENABLED, | ||
176 | default: CONFIG.TRENDING.VIDEOS.ALGORITHMS.DEFAULT | ||
177 | } | ||
178 | } | ||
179 | }, | ||
180 | tracker: { | ||
181 | enabled: CONFIG.TRACKER.ENABLED | ||
182 | }, | ||
183 | |||
184 | followings: { | ||
185 | instance: { | ||
186 | autoFollowIndex: { | ||
187 | indexUrl: CONFIG.FOLLOWINGS.INSTANCE.AUTO_FOLLOW_INDEX.INDEX_URL | ||
188 | } | ||
189 | } | ||
190 | }, | ||
191 | |||
192 | broadcastMessage: { | ||
193 | enabled: CONFIG.BROADCAST_MESSAGE.ENABLED, | ||
194 | message: CONFIG.BROADCAST_MESSAGE.MESSAGE, | ||
195 | level: CONFIG.BROADCAST_MESSAGE.LEVEL, | ||
196 | dismissable: CONFIG.BROADCAST_MESSAGE.DISMISSABLE | ||
197 | }, | ||
198 | |||
199 | homepage: { | ||
200 | enabled: this.homepageEnabled | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | |||
205 | async getServerConfig (ip?: string): Promise<ServerConfig> { | ||
206 | const { allowed } = await Hooks.wrapPromiseFun( | ||
207 | isSignupAllowed, | ||
208 | { | ||
209 | ip | ||
210 | }, | ||
211 | 'filter:api.user.signup.allowed.result' | ||
212 | ) | ||
213 | |||
214 | const allowedForCurrentIP = isSignupAllowedForCurrentIP(ip) | ||
215 | |||
216 | const signup = { | ||
217 | allowed, | ||
218 | allowedForCurrentIP, | ||
219 | minimumAge: CONFIG.SIGNUP.MINIMUM_AGE, | ||
220 | requiresEmailVerification: CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION | ||
221 | } | ||
222 | |||
223 | const htmlConfig = await this.getHTMLServerConfig() | ||
224 | |||
225 | return { ...htmlConfig, signup } | ||
226 | } | ||
227 | |||
228 | getRegisteredThemes () { | ||
229 | return PluginManager.Instance.getRegisteredThemes() | ||
230 | .map(t => ({ | ||
231 | name: t.name, | ||
232 | version: t.version, | ||
233 | description: t.description, | ||
234 | css: t.css, | ||
235 | clientScripts: t.clientScripts | ||
236 | })) | ||
237 | } | ||
238 | |||
239 | getRegisteredPlugins () { | ||
240 | return PluginManager.Instance.getRegisteredPlugins() | ||
241 | .map(p => ({ | ||
242 | name: p.name, | ||
243 | version: p.version, | ||
244 | description: p.description, | ||
245 | clientScripts: p.clientScripts | ||
246 | })) | ||
247 | } | ||
248 | |||
249 | getEnabledResolutions (type: 'vod' | 'live') { | ||
250 | const transcoding = type === 'vod' | ||
251 | ? CONFIG.TRANSCODING | ||
252 | : CONFIG.LIVE.TRANSCODING | ||
253 | |||
254 | return Object.keys(transcoding.RESOLUTIONS) | ||
255 | .filter(key => transcoding.ENABLED && transcoding.RESOLUTIONS[key] === true) | ||
256 | .map(r => parseInt(r, 10)) | ||
257 | } | ||
258 | |||
259 | private getIdAndPassAuthPlugins () { | ||
260 | const result: RegisteredIdAndPassAuthConfig[] = [] | ||
261 | |||
262 | for (const p of PluginManager.Instance.getIdAndPassAuths()) { | ||
263 | for (const auth of p.idAndPassAuths) { | ||
264 | result.push({ | ||
265 | npmName: p.npmName, | ||
266 | name: p.name, | ||
267 | version: p.version, | ||
268 | authName: auth.authName, | ||
269 | weight: auth.getWeight() | ||
270 | }) | ||
271 | } | ||
272 | } | ||
273 | |||
274 | return result | ||
275 | } | ||
276 | |||
277 | private getExternalAuthsPlugins () { | ||
278 | const result: RegisteredExternalAuthConfig[] = [] | ||
279 | |||
280 | for (const p of PluginManager.Instance.getExternalAuths()) { | ||
281 | for (const auth of p.externalAuths) { | ||
282 | result.push({ | ||
283 | npmName: p.npmName, | ||
284 | name: p.name, | ||
285 | version: p.version, | ||
286 | authName: auth.authName, | ||
287 | authDisplayName: auth.authDisplayName() | ||
288 | }) | ||
289 | } | ||
290 | } | ||
291 | |||
292 | return result | ||
293 | } | ||
294 | |||
295 | static get Instance () { | ||
296 | return this.instance || (this.instance = new this()) | ||
297 | } | ||
298 | } | ||
299 | |||
300 | // --------------------------------------------------------------------------- | ||
301 | |||
302 | export { | ||
303 | ServerConfigManager | ||
304 | } | ||
diff --git a/server/lib/stat-manager.ts b/server/lib/stat-manager.ts index 09ba208bd..25ed21927 100644 --- a/server/lib/stat-manager.ts +++ b/server/lib/stat-manager.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { CONFIG } from '@server/initializers/config' | 1 | import { CONFIG } from '@server/initializers/config' |
2 | import { UserModel } from '@server/models/account/user' | 2 | import { UserModel } from '@server/models/user/user' |
3 | import { ActorFollowModel } from '@server/models/activitypub/actor-follow' | 3 | import { ActorFollowModel } from '@server/models/actor/actor-follow' |
4 | import { VideoRedundancyModel } from '@server/models/redundancy/video-redundancy' | 4 | import { VideoRedundancyModel } from '@server/models/redundancy/video-redundancy' |
5 | import { VideoModel } from '@server/models/video/video' | 5 | import { VideoModel } from '@server/models/video/video' |
6 | import { VideoChannelModel } from '@server/models/video/video-channel' | 6 | import { VideoChannelModel } from '@server/models/video/video-channel' |
diff --git a/server/lib/video-transcoding-profiles.ts b/server/lib/transcoding/video-transcoding-profiles.ts index 81f5e1962..c5ea72a5f 100644 --- a/server/lib/video-transcoding-profiles.ts +++ b/server/lib/transcoding/video-transcoding-profiles.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { logger } from '@server/helpers/logger' | 1 | import { logger } from '@server/helpers/logger' |
2 | import { AvailableEncoders, EncoderOptionsBuilder, getTargetBitrate, VideoResolution } from '../../shared/models/videos' | 2 | import { AvailableEncoders, EncoderOptionsBuilder, getTargetBitrate, VideoResolution } from '../../../shared/models/videos' |
3 | import { buildStreamSuffix, resetSupportedEncoders } from '../helpers/ffmpeg-utils' | 3 | import { buildStreamSuffix, resetSupportedEncoders } from '../../helpers/ffmpeg-utils' |
4 | import { | 4 | import { |
5 | canDoQuickAudioTranscode, | 5 | canDoQuickAudioTranscode, |
6 | ffprobePromise, | 6 | ffprobePromise, |
@@ -8,8 +8,8 @@ import { | |||
8 | getMaxAudioBitrate, | 8 | getMaxAudioBitrate, |
9 | getVideoFileBitrate, | 9 | getVideoFileBitrate, |
10 | getVideoStreamFromFile | 10 | getVideoStreamFromFile |
11 | } from '../helpers/ffprobe-utils' | 11 | } from '../../helpers/ffprobe-utils' |
12 | import { VIDEO_TRANSCODING_FPS } from '../initializers/constants' | 12 | import { VIDEO_TRANSCODING_FPS } from '../../initializers/constants' |
13 | 13 | ||
14 | /** | 14 | /** |
15 | * | 15 | * |
diff --git a/server/lib/video-transcoding.ts b/server/lib/transcoding/video-transcoding.ts index c949dca2e..5df192575 100644 --- a/server/lib/video-transcoding.ts +++ b/server/lib/transcoding/video-transcoding.ts | |||
@@ -3,17 +3,17 @@ import { copyFile, ensureDir, move, remove, stat } from 'fs-extra' | |||
3 | import { basename, extname as extnameUtil, join } from 'path' | 3 | import { basename, extname as extnameUtil, join } from 'path' |
4 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' | 4 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' |
5 | import { MStreamingPlaylistFilesVideo, MVideoFile, MVideoFullLight } from '@server/types/models' | 5 | import { MStreamingPlaylistFilesVideo, MVideoFile, MVideoFullLight } from '@server/types/models' |
6 | import { VideoResolution } from '../../shared/models/videos' | 6 | import { VideoResolution } from '../../../shared/models/videos' |
7 | import { VideoStreamingPlaylistType } from '../../shared/models/videos/video-streaming-playlist.type' | 7 | import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type' |
8 | import { transcode, TranscodeOptions, TranscodeOptionsType } from '../helpers/ffmpeg-utils' | 8 | import { transcode, TranscodeOptions, TranscodeOptionsType } from '../../helpers/ffmpeg-utils' |
9 | import { canDoQuickTranscode, getDurationFromVideoFile, getMetadataFromFile, getVideoFileFPS } from '../helpers/ffprobe-utils' | 9 | import { canDoQuickTranscode, getDurationFromVideoFile, getMetadataFromFile, getVideoFileFPS } from '../../helpers/ffprobe-utils' |
10 | import { logger } from '../helpers/logger' | 10 | import { logger } from '../../helpers/logger' |
11 | import { CONFIG } from '../initializers/config' | 11 | import { CONFIG } from '../../initializers/config' |
12 | import { HLS_STREAMING_PLAYLIST_DIRECTORY, P2P_MEDIA_LOADER_PEER_VERSION, WEBSERVER } from '../initializers/constants' | 12 | import { HLS_STREAMING_PLAYLIST_DIRECTORY, P2P_MEDIA_LOADER_PEER_VERSION, WEBSERVER } from '../../initializers/constants' |
13 | import { VideoFileModel } from '../models/video/video-file' | 13 | import { VideoFileModel } from '../../models/video/video-file' |
14 | import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-playlist' | 14 | import { VideoStreamingPlaylistModel } from '../../models/video/video-streaming-playlist' |
15 | import { updateMasterHLSPlaylist, updateSha256VODSegments } from './hls' | 15 | import { updateMasterHLSPlaylist, updateSha256VODSegments } from '../hls' |
16 | import { generateVideoFilename, generateVideoStreamingPlaylistName, getVideoFilePath } from './video-paths' | 16 | import { generateVideoFilename, generateVideoStreamingPlaylistName, getVideoFilePath } from '../video-paths' |
17 | import { VideoTranscodingProfilesManager } from './video-transcoding-profiles' | 17 | import { VideoTranscodingProfilesManager } from './video-transcoding-profiles' |
18 | 18 | ||
19 | /** | 19 | /** |
@@ -215,16 +215,6 @@ function generateHlsPlaylistResolution (options: { | |||
215 | }) | 215 | }) |
216 | } | 216 | } |
217 | 217 | ||
218 | function getEnabledResolutions (type: 'vod' | 'live') { | ||
219 | const transcoding = type === 'vod' | ||
220 | ? CONFIG.TRANSCODING | ||
221 | : CONFIG.LIVE.TRANSCODING | ||
222 | |||
223 | return Object.keys(transcoding.RESOLUTIONS) | ||
224 | .filter(key => transcoding.ENABLED && transcoding.RESOLUTIONS[key] === true) | ||
225 | .map(r => parseInt(r, 10)) | ||
226 | } | ||
227 | |||
228 | // --------------------------------------------------------------------------- | 218 | // --------------------------------------------------------------------------- |
229 | 219 | ||
230 | export { | 220 | export { |
@@ -232,8 +222,7 @@ export { | |||
232 | generateHlsPlaylistResolutionFromTS, | 222 | generateHlsPlaylistResolutionFromTS, |
233 | optimizeOriginalVideofile, | 223 | optimizeOriginalVideofile, |
234 | transcodeNewWebTorrentResolution, | 224 | transcodeNewWebTorrentResolution, |
235 | mergeAudioVideofile, | 225 | mergeAudioVideofile |
236 | getEnabledResolutions | ||
237 | } | 226 | } |
238 | 227 | ||
239 | // --------------------------------------------------------------------------- | 228 | // --------------------------------------------------------------------------- |
diff --git a/server/lib/user.ts b/server/lib/user.ts index 9b0a0a2f1..8a6fcebc7 100644 --- a/server/lib/user.ts +++ b/server/lib/user.ts | |||
@@ -1,14 +1,15 @@ | |||
1 | import { Transaction } from 'sequelize/types' | 1 | import { Transaction } from 'sequelize/types' |
2 | import { v4 as uuidv4 } from 'uuid' | 2 | import { v4 as uuidv4 } from 'uuid' |
3 | import { UserModel } from '@server/models/account/user' | 3 | import { UserModel } from '@server/models/user/user' |
4 | import { MActorDefault } from '@server/types/models/actor' | ||
4 | import { ActivityPubActorType } from '../../shared/models/activitypub' | 5 | import { ActivityPubActorType } from '../../shared/models/activitypub' |
5 | import { UserNotificationSetting, UserNotificationSettingValue } from '../../shared/models/users' | 6 | import { UserNotificationSetting, UserNotificationSettingValue } from '../../shared/models/users' |
6 | import { SERVER_ACTOR_NAME, WEBSERVER } from '../initializers/constants' | 7 | import { SERVER_ACTOR_NAME, WEBSERVER } from '../initializers/constants' |
7 | import { sequelizeTypescript } from '../initializers/database' | 8 | import { sequelizeTypescript } from '../initializers/database' |
8 | import { AccountModel } from '../models/account/account' | 9 | import { AccountModel } from '../models/account/account' |
9 | import { UserNotificationSettingModel } from '../models/account/user-notification-setting' | 10 | import { ActorModel } from '../models/actor/actor' |
10 | import { ActorModel } from '../models/activitypub/actor' | 11 | import { UserNotificationSettingModel } from '../models/user/user-notification-setting' |
11 | import { MAccountDefault, MActorDefault, MChannelActor } from '../types/models' | 12 | import { MAccountDefault, MChannelActor } from '../types/models' |
12 | import { MUser, MUserDefault, MUserId } from '../types/models/user' | 13 | import { MUser, MUserDefault, MUserId } from '../types/models/user' |
13 | import { buildActorInstance, generateAndSaveActorKeys } from './activitypub/actor' | 14 | import { buildActorInstance, generateAndSaveActorKeys } from './activitypub/actor' |
14 | import { getLocalAccountActivityPubUrl } from './activitypub/url' | 15 | import { getLocalAccountActivityPubUrl } from './activitypub/url' |
diff --git a/server/lib/video-channel.ts b/server/lib/video-channel.ts index 0476cb2d5..d57e832fe 100644 --- a/server/lib/video-channel.ts +++ b/server/lib/video-channel.ts | |||
@@ -1,5 +1,4 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import { v4 as uuidv4 } from 'uuid' | ||
3 | import { VideoChannelCreate } from '../../shared/models' | 2 | import { VideoChannelCreate } from '../../shared/models' |
4 | import { VideoModel } from '../models/video/video' | 3 | import { VideoModel } from '../models/video/video' |
5 | import { VideoChannelModel } from '../models/video/video-channel' | 4 | import { VideoChannelModel } from '../models/video/video-channel' |
@@ -9,9 +8,8 @@ import { getLocalVideoChannelActivityPubUrl } from './activitypub/url' | |||
9 | import { federateVideoIfNeeded } from './activitypub/videos' | 8 | import { federateVideoIfNeeded } from './activitypub/videos' |
10 | 9 | ||
11 | async function createLocalVideoChannel (videoChannelInfo: VideoChannelCreate, account: MAccountId, t: Sequelize.Transaction) { | 10 | async function createLocalVideoChannel (videoChannelInfo: VideoChannelCreate, account: MAccountId, t: Sequelize.Transaction) { |
12 | const uuid = uuidv4() | ||
13 | const url = getLocalVideoChannelActivityPubUrl(videoChannelInfo.name) | 11 | const url = getLocalVideoChannelActivityPubUrl(videoChannelInfo.name) |
14 | const actorInstance = buildActorInstance('Group', url, videoChannelInfo.name, uuid) | 12 | const actorInstance = buildActorInstance('Group', url, videoChannelInfo.name) |
15 | 13 | ||
16 | const actorInstanceCreated = await actorInstance.save({ transaction: t }) | 14 | const actorInstanceCreated = await actorInstance.save({ transaction: t }) |
17 | 15 | ||
diff --git a/server/lib/video-comment.ts b/server/lib/video-comment.ts index 736ebb2f8..51a9c747e 100644 --- a/server/lib/video-comment.ts +++ b/server/lib/video-comment.ts | |||
@@ -3,7 +3,7 @@ import * as Sequelize from 'sequelize' | |||
3 | import { logger } from '@server/helpers/logger' | 3 | import { logger } from '@server/helpers/logger' |
4 | import { sequelizeTypescript } from '@server/initializers/database' | 4 | import { sequelizeTypescript } from '@server/initializers/database' |
5 | import { ResultList } from '../../shared/models' | 5 | import { ResultList } from '../../shared/models' |
6 | import { VideoCommentThreadTree } from '../../shared/models/videos/video-comment.model' | 6 | import { VideoCommentThreadTree } from '../../shared/models/videos/comment/video-comment.model' |
7 | import { VideoCommentModel } from '../models/video/video-comment' | 7 | import { VideoCommentModel } from '../models/video/video-comment' |
8 | import { MAccountDefault, MComment, MCommentOwnerVideo, MCommentOwnerVideoReply, MVideoFullLight } from '../types/models' | 8 | import { MAccountDefault, MComment, MCommentOwnerVideo, MCommentOwnerVideoReply, MVideoFullLight } from '../types/models' |
9 | import { sendCreateVideoComment, sendDeleteVideoComment } from './activitypub/send' | 9 | import { sendCreateVideoComment, sendDeleteVideoComment } from './activitypub/send' |
diff --git a/server/lib/video.ts b/server/lib/video.ts index 21e4b7ff2..d26cf85cd 100644 --- a/server/lib/video.ts +++ b/server/lib/video.ts | |||
@@ -28,6 +28,8 @@ function buildLocalVideoFromReq (videoInfo: VideoCreate, channelId: number): Fil | |||
28 | privacy: videoInfo.privacy || VideoPrivacy.PRIVATE, | 28 | privacy: videoInfo.privacy || VideoPrivacy.PRIVATE, |
29 | channelId: channelId, | 29 | channelId: channelId, |
30 | originallyPublishedAt: videoInfo.originallyPublishedAt | 30 | originallyPublishedAt: videoInfo.originallyPublishedAt |
31 | ? new Date(videoInfo.originallyPublishedAt) | ||
32 | : null | ||
31 | } | 33 | } |
32 | } | 34 | } |
33 | 35 | ||