Skip to content

Commit

Permalink
feat: configure Core system/studio settings via blueprints
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Nov 20, 2024
1 parent 8c78ed2 commit 6c13921
Show file tree
Hide file tree
Showing 115 changed files with 2,397 additions and 1,369 deletions.
4 changes: 2 additions & 2 deletions meteor/__mocks__/defaultCollectionObjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@ export function defaultStudio(_id: StudioId): DBStudio {
mappingsWithOverrides: wrapDefaultObject({}),
supportedShowStyleBase: [],
blueprintConfigWithOverrides: wrapDefaultObject({}),
settings: {
settingsWithOverrides: wrapDefaultObject({
frameRate: 25,
mediaPreviewsUrl: '',
minimumTakeSpan: DEFAULT_MINIMUM_TAKE_SPAN,
fallbackPartDuration: DEFAULT_FALLBACK_PART_DURATION,
},
}),
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
Expand Down
19 changes: 19 additions & 0 deletions meteor/__mocks__/helpers/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,25 @@ export async function setupMockCore(doc?: Partial<ICoreSystem>): Promise<ICoreSy
version: '0.0.0',
previousVersion: '0.0.0',
serviceMessages: {},
settingsWithOverrides: wrapDefaultObject({
cron: {
casparCGRestart: {
enabled: true,
},
storeRundownSnapshots: {
enabled: false,
},
},
support: {
message: '',
},
evaluationsMessage: {
enabled: false,
heading: '',
message: '',
},
}),
lastBlueprintConfig: undefined,
}
const coreSystem = _.extend(defaultCore, doc)
await CoreSystem.removeAsync(SYSTEM_ID)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '@sofie-automation/meteor-lib/dist/collections/CoreSystem'
import { CoreSystem } from '../../../collections'
import { SupressLogMessages } from '../../../../__mocks__/suppressLogging'
import { wrapDefaultObject } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'

function convertExternalToServiceMessage(message: ExternalServiceMessage): ServiceMessage {
return {
Expand Down Expand Up @@ -42,6 +43,8 @@ const fakeCoreSystem: ICoreSystem = {
version: '3',
previousVersion: null,
serviceMessages: {},
settingsWithOverrides: wrapDefaultObject({} as any),
lastBlueprintConfig: undefined,
}

describe('Service messages internal API', () => {
Expand Down
4 changes: 3 additions & 1 deletion meteor/server/api/evaluations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { sendSlackMessageToWebhook } from './integration/slack'
import { OrganizationId, UserId } from '@sofie-automation/corelib/dist/dataModel/Ids'
import { DBRundownPlaylist } from '@sofie-automation/corelib/dist/dataModel/RundownPlaylist'
import { Evaluations, RundownPlaylists } from '../collections'
import { applyAndValidateOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'

export async function saveEvaluation(
credentials: {
Expand All @@ -33,8 +34,9 @@ export async function saveEvaluation(
deferAsync(async () => {
const studio = await fetchStudioLight(evaluation.studioId)
if (!studio) throw new Meteor.Error(500, `Studio ${evaluation.studioId} not found!`)
const studioSettings = applyAndValidateOverrides(studio.settingsWithOverrides).obj

const webhookUrls = _.compact((studio.settings.slackEvaluationUrls || '').split(','))
const webhookUrls = _.compact((studioSettings.slackEvaluationUrls || '').split(','))

if (webhookUrls.length) {
// Only send notes if not everything is OK
Expand Down
10 changes: 7 additions & 3 deletions meteor/server/api/rest/v1/typeConversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import {
DEFAULT_FALLBACK_PART_DURATION,
} from '@sofie-automation/shared-lib/dist/core/constants'
import { Bucket } from '@sofie-automation/meteor-lib/dist/collections/Buckets'
import { ForceQuickLoopAutoNext } from '@sofie-automation/corelib/dist/dataModel/RundownPlaylist'
import { ForceQuickLoopAutoNext } from '@sofie-automation/shared-lib/dist/core/model/StudioSettings'

/*
This file contains functions that convert between the internal Sofie-Core types and types exposed to the external API.
Expand Down Expand Up @@ -307,13 +307,17 @@ export async function studioFrom(apiStudio: APIStudio, existingId?: StudioId): P
: convertObjectIntoOverrides(await StudioBlueprintConfigFromAPI(apiStudio, blueprintManifest))
}

const studioSettings = studioSettingsFrom(apiStudio.settings)

return {
_id: existingId ?? getRandomId(),
name: apiStudio.name,
blueprintId: blueprint?._id,
blueprintConfigPresetId: apiStudio.blueprintConfigPresetId,
blueprintConfigWithOverrides: blueprintConfig,
settings: studioSettingsFrom(apiStudio.settings),
settingsWithOverrides: studio
? updateOverrides(studio.settingsWithOverrides, studioSettings)
: wrapDefaultObject(studioSettings),
supportedShowStyleBase: apiStudio.supportedShowStyleBase?.map((id) => protectString<ShowStyleBaseId>(id)) ?? [],
organizationId: null,
mappingsWithOverrides: wrapDefaultObject({}),
Expand All @@ -334,7 +338,7 @@ export async function studioFrom(apiStudio: APIStudio, existingId?: StudioId): P
}

export async function APIStudioFrom(studio: DBStudio): Promise<APIStudio> {
const studioSettings = APIStudioSettingsFrom(studio.settings)
const studioSettings = APIStudioSettingsFrom(applyAndValidateOverrides(studio.settingsWithOverrides).obj)

return {
name: studio.name,
Expand Down
4 changes: 2 additions & 2 deletions meteor/server/api/studio/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ export async function insertStudioInner(organizationId: OrganizationId | null, n
supportedShowStyleBase: [],
blueprintConfigWithOverrides: wrapDefaultObject({}),
// testToolsConfig?: ITestToolsConfig
settings: {
settingsWithOverrides: wrapDefaultObject({
frameRate: 25,
mediaPreviewsUrl: '',
minimumTakeSpan: DEFAULT_MINIMUM_TAKE_SPAN,
},
}),
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
Expand Down
5 changes: 2 additions & 3 deletions meteor/server/collections/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,13 @@ export const CoreSystem = createAsyncOnlyMongoCollection<ICoreSystem>(Collection
if (!access.update) return logNotAllowed('CoreSystem', access.reason)

return allowOnlyFields(doc, fields, [
'support',
'systemInfo',
'name',
'logLevel',
'apm',
'cron',
'logo',
'evaluations',
'blueprintId',
'settingsWithOverrides',
])
},
})
Expand Down
25 changes: 20 additions & 5 deletions meteor/server/coreSystem/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import { getEnvLogLevel, logger, LogLevel, setLogLevel } from '../logging'
const PackageInfo = require('../../package.json')
import Agent from 'meteor/julusian:meteor-elastic-apm'
import { profiler } from '../api/profiler'
import { TMP_TSR_VERSION } from '@sofie-automation/blueprints-integration'
import { ICoreSystemSettings, TMP_TSR_VERSION } from '@sofie-automation/blueprints-integration'
import { getAbsolutePath } from '../lib'
import * as fs from 'fs/promises'
import path from 'path'
import { checkDatabaseVersions } from './checkDatabaseVersions'
import PLazy from 'p-lazy'
import { getCoreSystemAsync } from './collection'
import { wrapDefaultObject } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'

export { PackageInfo }

Expand Down Expand Up @@ -60,11 +61,25 @@ async function initializeCoreSystem() {
enabled: false,
transactionSampleRate: -1,
},
cron: {
casparCGRestart: {
enabled: true,
settingsWithOverrides: wrapDefaultObject<ICoreSystemSettings>({
cron: {
casparCGRestart: {
enabled: true,
},
storeRundownSnapshots: {
enabled: false,
},
},
},
support: {
message: '',
},
evaluationsMessage: {
enabled: false,
heading: '',
message: '',
},
}),
lastBlueprintConfig: undefined,
})

if (!isRunningInJest()) {
Expand Down
21 changes: 12 additions & 9 deletions meteor/server/cronjobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ import { deferAsync, normalizeArrayToMap } from '@sofie-automation/corelib/dist/
import { getCoreSystemAsync } from './coreSystem/collection'
import { cleanupOldDataInner } from './api/cleanup'
import { CollectionCleanupResult } from '@sofie-automation/meteor-lib/dist/api/system'
import { ICoreSystem } from '@sofie-automation/meteor-lib/dist/collections/CoreSystem'
import { ICoreSystemSettings } from '@sofie-automation/shared-lib/dist/core/model/CoreSystemSettings'
import { executePeripheralDeviceFunctionWithCustomTimeout } from './api/peripheralDevice/executeFunction'
import {
interpollateTranslation,
isTranslatableMessage,
translateMessage,
} from '@sofie-automation/corelib/dist/TranslatableMessage'
import { applyAndValidateOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'

const lowPrioFcn = (fcn: () => any) => {
// Do it at a random time in the future:
Expand All @@ -49,15 +50,17 @@ export async function nightlyCronjobInner(): Promise<void> {
logger.info('Nightly cronjob: starting...')
const system = await getCoreSystemAsync()

const systemSettings = system && applyAndValidateOverrides(system.settingsWithOverrides).obj

await Promise.allSettled([
cleanupOldDataCronjob().catch((error) => {
logger.error(`Cronjob: Error when cleaning up old data: ${stringifyError(error)}`)
logger.error(error)
}),
restartCasparCG(system, previousLastNightlyCronjob).catch((e) => {
restartCasparCG(systemSettings, previousLastNightlyCronjob).catch((e) => {
logger.error(`Cron: Restart CasparCG error: ${stringifyError(e)}`)
}),
storeSnapshots(system).catch((e) => {
storeSnapshots(systemSettings).catch((e) => {
logger.error(`Cron: Rundown Snapshots error: ${stringifyError(e)}`)
}),
])
Expand All @@ -81,8 +84,8 @@ async function cleanupOldDataCronjob() {

const CASPARCG_LAST_SEEN_PERIOD_MS = 3 * 60 * 1000 // Note: this must be higher than the ping interval used by playout-gateway

async function restartCasparCG(system: ICoreSystem | undefined, previousLastNightlyCronjob: number) {
if (!system?.cron?.casparCGRestart?.enabled) return
async function restartCasparCG(systemSettings: ICoreSystemSettings | undefined, previousLastNightlyCronjob: number) {
if (!systemSettings?.cron?.casparCGRestart?.enabled) return

let shouldRetryAttempt = false
const ps: Array<Promise<any>> = []
Expand Down Expand Up @@ -176,10 +179,10 @@ async function restartCasparCG(system: ICoreSystem | undefined, previousLastNigh
}
}

async function storeSnapshots(system: ICoreSystem | undefined) {
if (system?.cron?.storeRundownSnapshots?.enabled) {
const filter = system.cron.storeRundownSnapshots.rundownNames?.length
? { name: { $in: system.cron.storeRundownSnapshots.rundownNames } }
async function storeSnapshots(systemSettings: ICoreSystemSettings | undefined) {
if (systemSettings?.cron?.storeRundownSnapshots?.enabled) {
const filter = systemSettings.cron.storeRundownSnapshots.rundownNames?.length
? { name: { $in: systemSettings.cron.storeRundownSnapshots.rundownNames } }
: {}

const playlists = await RundownPlaylists.findFetchAsync(filter)
Expand Down
2 changes: 1 addition & 1 deletion meteor/server/logo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ logoRouter.get('/', async (ctx) => {
const logo = core?.logo ?? SofieLogo.Default

const paths: Record<SofieLogo, string> = {
[SofieLogo.Default]: '/images/sofie-logo.svg',
[SofieLogo.Default]: '/images/sofie-logo-default.svg',
[SofieLogo.Pride]: '/images/sofie-logo-pride.svg',
[SofieLogo.Norway]: '/images/sofie-logo-norway.svg',
[SofieLogo.Christmas]: '/images/sofie-logo-christmas.svg',
Expand Down
Loading

0 comments on commit 6c13921

Please sign in to comment.