Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion meteor/__mocks__/defaultCollectionObjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export function defaultStudio(_id: StudioId): DBStudio {
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
previewContainerIds: [],
thumbnailContainerIds: [],
peripheralDeviceSettings: {
Expand Down
2 changes: 1 addition & 1 deletion meteor/server/api/rest/v1/typeConversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ export async function studioFrom(apiStudio: APIStudio, existingId?: StudioId): P
routeSetsWithOverrides: wrapDefaultObject({}),
_rundownVersionHash: '',
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
previewContainerIds: [],
thumbnailContainerIds: [],
peripheralDeviceSettings: {
Expand Down
2 changes: 1 addition & 1 deletion meteor/server/api/studio/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export async function insertStudioInner(organizationId: OrganizationId | null, n
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
thumbnailContainerIds: [],
previewContainerIds: [],
peripheralDeviceSettings: {
Expand Down
2 changes: 1 addition & 1 deletion meteor/server/migration/0_1_0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ export const addSteps = addMigrationSteps('0.1.0', [
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
thumbnailContainerIds: [],
previewContainerIds: [],
peripheralDeviceSettings: {
Expand Down
49 changes: 48 additions & 1 deletion meteor/server/migration/X_X_X.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { addMigrationSteps } from './databaseMigration'
import { CURRENT_SYSTEM_VERSION } from './currentSystemVersion'
import { Studios } from '../collections'
import { convertObjectIntoOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'
import { StudioRouteSet, StudioRouteSetExclusivityGroup } from '@sofie-automation/corelib/dist/dataModel/Studio'
import {
StudioRouteSet,
StudioRouteSetExclusivityGroup,
StudioPackageContainer,
} from '@sofie-automation/corelib/dist/dataModel/Studio'

/*
* **************************************************************************************
Expand Down Expand Up @@ -99,4 +103,47 @@ export const addSteps = addMigrationSteps(CURRENT_SYSTEM_VERSION, [
}
},
},
{
id: `convert packageContainers to ObjectWithOverrides`,
canBeRunAutomatically: true,
validate: async () => {
const studios = await Studios.findFetchAsync({
packageContainers: { $exists: true },
packageContainersWithOverrides: { $exists: false },
})

for (const studio of studios) {
// @ts-expect-error packageContainers is typed as Record<string, StudioPackageContainer>
if (studio.packageContainers) {
return 'packageContainers must be converted to an ObjectWithOverrides'
}
}

return false
},
migrate: async () => {
const studios = await Studios.findFetchAsync({
packageContainers: { $exists: true },
packageContainersWithOverrides: { $exists: false },
})

for (const studio of studios) {
// @ts-expect-error packageContainers is typed as Record<string, StudioPackageContainer>
const oldPackageContainers = studio.packageContainers

const newPackageContainers = convertObjectIntoOverrides<StudioPackageContainer>(
oldPackageContainers || {}
)

await Studios.updateAsync(studio._id, {
$set: {
packageContainersWithOverrides: newPackageContainers,
},
$unset: {
packageContainers: 1,
},
})
}
},
},
])
6 changes: 3 additions & 3 deletions meteor/server/migration/__tests__/migrations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ describe('Migrations', () => {
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
previewContainerIds: [],
thumbnailContainerIds: [],
peripheralDeviceSettings: {
Expand Down Expand Up @@ -170,7 +170,7 @@ describe('Migrations', () => {
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
previewContainerIds: [],
thumbnailContainerIds: [],
peripheralDeviceSettings: {
Expand Down Expand Up @@ -208,7 +208,7 @@ describe('Migrations', () => {
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
previewContainerIds: [],
thumbnailContainerIds: [],
peripheralDeviceSettings: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export async function updateCollectionForExpectedPackageIds(
contentCache: ReadonlyDeep<ExpectedPackagesContentCache>,
studio: Pick<DBStudio, StudioFields>,
layerNameToDeviceIds: Map<string, PeripheralDeviceId[]>,
packageContainers: Record<string, StudioPackageContainer>,
collection: CustomPublishCollection<PackageManagerExpectedPackage>,
filterPlayoutDeviceIds: ReadonlyDeep<PeripheralDeviceId[]> | undefined,
regenerateIds: Set<ExpectedPackageId>
Expand Down Expand Up @@ -66,7 +67,8 @@ export async function updateCollectionForExpectedPackageIds(
},
deviceId,
null,
Priorities.OTHER // low priority
Priorities.OTHER, // low priority
packageContainers
)

updatedDocIds.add(routedPackage._id)
Expand Down Expand Up @@ -99,6 +101,7 @@ export async function updateCollectionForPieceInstanceIds(
contentCache: ReadonlyDeep<ExpectedPackagesContentCache>,
studio: Pick<DBStudio, StudioFields>,
layerNameToDeviceIds: Map<string, PeripheralDeviceId[]>,
packageContainers: Record<string, StudioPackageContainer>,
collection: CustomPublishCollection<PackageManagerExpectedPackage>,
filterPlayoutDeviceIds: ReadonlyDeep<PeripheralDeviceId[]> | undefined,
regenerateIds: Set<PieceInstanceId>
Expand Down Expand Up @@ -140,7 +143,8 @@ export async function updateCollectionForPieceInstanceIds(
},
deviceId,
pieceInstanceId,
Priorities.OTHER // low priority
Priorities.OTHER, // low priority
packageContainers
)

updatedDocIds.add(routedPackage._id)
Expand Down Expand Up @@ -172,17 +176,21 @@ enum Priorities {
}

function generateExpectedPackageForDevice(
studio: Pick<StudioLight, '_id' | 'packageContainers' | 'previewContainerIds' | 'thumbnailContainerIds'>,
studio: Pick<
StudioLight,
'_id' | 'packageContainersWithOverrides' | 'previewContainerIds' | 'thumbnailContainerIds'
>,
expectedPackage: PackageManagerExpectedPackageBase,
deviceId: PeripheralDeviceId,
pieceInstanceId: PieceInstanceId | null,
priority: Priorities
priority: Priorities,
packageContainers: Record<string, StudioPackageContainer>
): PackageManagerExpectedPackage {
// Lookup Package sources:
const combinedSources: PackageContainerOnPackage[] = []

for (const packageSource of expectedPackage.sources) {
const lookedUpSource = studio.packageContainers[packageSource.containerId]
const lookedUpSource = packageContainers[packageSource.containerId]
if (lookedUpSource) {
combinedSources.push(calculateCombinedSource(packageSource, lookedUpSource))
} else {
Expand All @@ -199,7 +207,7 @@ function generateExpectedPackageForDevice(
}

// Lookup Package targets:
const combinedTargets = calculateCombinedTargets(studio, expectedPackage, deviceId)
const combinedTargets = calculateCombinedTargets(expectedPackage, deviceId, packageContainers)

if (!combinedSources.length && expectedPackage.sources.length !== 0) {
logger.warn(`Pub.expectedPackagesForDevice: No sources found for "${expectedPackage._id}"`)
Expand Down Expand Up @@ -253,14 +261,14 @@ function calculateCombinedSource(
return combinedSource
}
function calculateCombinedTargets(
studio: Pick<StudioLight, '_id' | 'packageContainers'>,
expectedPackage: PackageManagerExpectedPackageBase,
deviceId: PeripheralDeviceId
deviceId: PeripheralDeviceId,
packageContainers: Record<string, StudioPackageContainer>
): PackageContainerOnPackage[] {
const mappingDeviceId = unprotectString(deviceId)

let packageContainerId: string | undefined
for (const [containerId, packageContainer] of Object.entries<StudioPackageContainer>(studio.packageContainers)) {
for (const [containerId, packageContainer] of Object.entries<StudioPackageContainer>(packageContainers)) {
if (packageContainer.deviceIds.includes(mappingDeviceId)) {
// TODO: how to handle if a device has multiple containers?
packageContainerId = containerId
Expand All @@ -270,7 +278,7 @@ function calculateCombinedTargets(

const combinedTargets: PackageContainerOnPackage[] = []
if (packageContainerId) {
const lookedUpTarget = studio.packageContainers[packageContainerId]
const lookedUpTarget = packageContainers[packageContainerId]
if (lookedUpTarget) {
// Todo: should the be any combination of properties here?
combinedTargets.push({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Meteor } from 'meteor/meteor'
import { PeripheralDeviceReadAccess } from '../../../security/peripheralDevice'
import { DBStudio } from '@sofie-automation/corelib/dist/dataModel/Studio'
import { DBStudio, StudioPackageContainer } from '@sofie-automation/corelib/dist/dataModel/Studio'
import {
TriggerUpdate,
meteorCustomPublish,
Expand Down Expand Up @@ -48,6 +48,7 @@ interface ExpectedPackagesPublicationUpdateProps {
interface ExpectedPackagesPublicationState {
studio: Pick<DBStudio, StudioFields> | undefined
layerNameToDeviceIds: Map<string, PeripheralDeviceId[]>
packageContainers: Record<string, StudioPackageContainer>

contentCache: ReadonlyDeep<ExpectedPackagesContentCache>
}
Expand All @@ -56,14 +57,14 @@ export type StudioFields =
| '_id'
| 'routeSetsWithOverrides'
| 'mappingsWithOverrides'
| 'packageContainers'
| 'packageContainersWithOverrides'
| 'previewContainerIds'
| 'thumbnailContainerIds'
const studioFieldSpecifier = literal<MongoFieldSpecifierOnesStrict<Pick<DBStudio, StudioFields>>>({
_id: 1,
routeSetsWithOverrides: 1,
mappingsWithOverrides: 1,
packageContainers: 1,
packageContainersWithOverrides: 1,
previewContainerIds: 1,
thumbnailContainerIds: 1,
})
Expand Down Expand Up @@ -122,6 +123,7 @@ async function manipulateExpectedPackagesPublicationData(
const invalidateAllItems = !updateProps || updateProps.newCache || updateProps.invalidateStudio

if (!state.layerNameToDeviceIds) state.layerNameToDeviceIds = new Map()
if (!state.packageContainers) state.packageContainers = {}

if (invalidateAllItems) {
// Everything is invalid, reset everything
Expand All @@ -141,12 +143,14 @@ async function manipulateExpectedPackagesPublicationData(
if (!state.studio) {
logger.warn(`Pub.expectedPackagesForDevice: studio "${args.studioId}" not found!`)
state.layerNameToDeviceIds = new Map()
state.packageContainers = {}
} else {
const studioMappings = applyAndValidateOverrides(state.studio.mappingsWithOverrides).obj
state.layerNameToDeviceIds = buildMappingsToDeviceIdMap(
applyAndValidateOverrides(state.studio.routeSetsWithOverrides).obj,
studioMappings
)
state.packageContainers = applyAndValidateOverrides(state.studio.packageContainersWithOverrides).obj
}
}

Expand All @@ -173,6 +177,7 @@ async function manipulateExpectedPackagesPublicationData(
state.contentCache,
state.studio,
state.layerNameToDeviceIds,
state.packageContainers,
collection,
args.filterPlayoutDeviceIds,
regenerateExpectedPackageIds
Expand All @@ -181,6 +186,7 @@ async function manipulateExpectedPackagesPublicationData(
state.contentCache,
state.studio,
state.layerNameToDeviceIds,
state.packageContainers,
collection,
args.filterPlayoutDeviceIds,
regeneratePieceInstanceIds
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ import {
PeripheralDevicePubSub,
PeripheralDevicePubSubCollectionsNames,
} from '@sofie-automation/shared-lib/dist/pubsub/peripheralDevice'
import { applyAndValidateOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'

type StudioFields = '_id' | 'packageContainers'
type StudioFields = '_id' | 'packageContainersWithOverrides'
const studioFieldSpecifier = literal<MongoFieldSpecifierOnesStrict<Pick<DBStudio, StudioFields>>>({
_id: 1,
packageContainers: 1,
packageContainersWithOverrides: 1,
})

interface PackageManagerPackageContainersArgs {
Expand Down Expand Up @@ -68,8 +69,9 @@ async function manipulateExpectedPackagesPublicationData(

const packageContainers: { [containerId: string]: PackageContainer } = {}
if (studio) {
const studioPackageContainers = applyAndValidateOverrides(studio.packageContainersWithOverrides).obj
for (const [containerId, studioPackageContainer] of Object.entries<StudioPackageContainer>(
studio.packageContainers
studioPackageContainers
)) {
packageContainers[containerId] = studioPackageContainer.container
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
getMediaObjectMediaId,
PieceContentStreamInfo,
checkPieceContentStatusAndDependencies,
PieceContentStatusStudio,
} from '../checkPieceContentStatus'
import {
PackageInfo,
Expand All @@ -31,12 +32,10 @@ import {
MediaStream,
MediaStreamType,
} from '@sofie-automation/shared-lib/dist/core/model/MediaObjects'
import { UIStudio } from '@sofie-automation/meteor-lib/dist/api/studios'
import { defaultStudio } from '../../../../__mocks__/defaultCollectionObjects'
import { testInFiber } from '../../../../__mocks__/helpers/jest'
import { MediaObjects } from '../../../collections'
import { PieceDependencies } from '../common'
import { DBStudio } from '@sofie-automation/corelib/dist/dataModel/Studio'
import { DEFAULT_MINIMUM_TAKE_SPAN } from '@sofie-automation/shared-lib/dist/core/constants'

const mockMediaObjectsCollection = MongoMock.getInnerMockCollection<MediaObject>(MediaObjects)
Expand Down Expand Up @@ -174,17 +173,14 @@ describe('lib/mediaObjects', () => {
}

const mockDefaultStudio = defaultStudio(protectString('studio0'))
const mockStudio: Complete<
Pick<DBStudio, '_id' | 'settings' | 'packageContainers' | 'previewContainerIds' | 'thumbnailContainerIds'> &
Pick<UIStudio, 'mappings' | 'routeSets'>
> = {
const mockStudio: Complete<PieceContentStatusStudio> = {
_id: mockDefaultStudio._id,
settings: mockStudioSettings,
packageContainers: mockDefaultStudio.packageContainers,
previewContainerIds: ['previews0'],
thumbnailContainerIds: ['thumbnails0'],
routeSets: applyAndValidateOverrides(mockDefaultStudio.routeSetsWithOverrides).obj,
mappings: applyAndValidateOverrides(mockDefaultStudio.mappingsWithOverrides).obj,
packageContainers: applyAndValidateOverrides(mockDefaultStudio.packageContainersWithOverrides).obj,
}

mockMediaObjectsCollection.insert(
Expand Down
Loading