@@ -17,13 +17,12 @@ import {
17
17
} from '@mos-connection/connector'
18
18
import { diffLists , ListEntry , OperationType } from './mosDiff'
19
19
import * as crypto from 'crypto'
20
+ import { convertFromSofieSnapshot } from './convertFromSofieSnapshot'
20
21
21
22
console . log ( 'Starting Quick-MOS' )
22
23
23
24
const DELAY_TIME = 300 // ms
24
25
25
- // const tsr = new TSRHandler(console.log)
26
-
27
26
const watcher = chokidar . watch ( 'input/**' , { ignored : / ^ \. / , persistent : true } )
28
27
29
28
const simulateFrequentEditing = false
@@ -80,31 +79,15 @@ function triggerReload() {
80
79
}
81
80
} , DELAY_TIME )
82
81
}
83
- function loadFile ( requirePath : string ) {
82
+ function loadFile ( requirePath : string ) : any {
84
83
delete require . cache [ require . resolve ( requirePath ) ]
85
84
// eslint-disable-next-line @typescript-eslint/no-var-requires
86
- const mosData = require ( requirePath )
87
- if ( mosData . runningOrder ?. EditorialStart && ! mosTypes . mosTime . is ( mosData . runningOrder . EditorialStart ) ) {
88
- mosData . runningOrder . EditorialStart = mosTypes . mosTime . create ( mosData . runningOrder . EditorialStart . _time )
89
- }
90
-
91
- if ( mosData . runningOrder ?. EditorialDuration && ! mosTypes . mosDuration . is ( mosData . runningOrder . EditorialDuration ) ) {
92
- let s = mosData . runningOrder . EditorialDuration . _duration
93
- const hh = Math . floor ( s / 3600 )
94
- s -= hh * 3600
95
-
96
- const mm = Math . floor ( s / 60 )
97
- s -= mm * 60
98
-
99
- const ss = Math . floor ( s )
100
-
101
- mosData . runningOrder . EditorialDuration = mosTypes . mosDuration . create ( hh + ':' + mm + ':' + ss )
102
- }
85
+ const content = require ( requirePath )
103
86
104
- return mosData
87
+ return content
105
88
}
106
89
const monitors : { [ id : string ] : MOSMonitor } = { }
107
- const runningOrderIds : { [ id : string ] : number } = { }
90
+ const runningOrderIds : { [ id : string ] : string } = { }
108
91
109
92
async function reloadInner ( ) {
110
93
const newConfig : Config = loadFile ( '../input/config.ts' ) . config
@@ -133,7 +116,7 @@ async function reloadInner() {
133
116
mos . mosConnection . onConnection ( ( mosDevice : MosDevice ) => {
134
117
console . log ( 'new mos connection' , mosDevice . ID )
135
118
136
- mosDevice . onGetMachineInfo ( async ( ) => {
119
+ mosDevice . onRequestMachineInfo ( async ( ) => {
137
120
const machineInfo : IMOSListMachInfo = {
138
121
manufacturer : mosTypes . mosString128 . create ( '<<<Mock Manufacturer>>>' ) ,
139
122
model : mosTypes . mosString128 . create ( '<<<Mock model>>>' ) ,
@@ -196,13 +179,14 @@ async function reloadInner() {
196
179
// mosDevice.onMosReqSearchableSchema((username: string) => Promise<IMOSSearchableSchema>): void;
197
180
// mosDevice.onMosReqObjectList((objList: IMosRequestObjectList) => Promise<IMosObjectList>): void;
198
181
// mosDevice.onMosReqObjectAction((action: string, obj: IMOSObject) => Promise<IMOSAck>): void;
199
- mosDevice . onROReqAll ( async ( ) => {
182
+ mosDevice . onRequestAllRunningOrders ( async ( ) => {
200
183
const ros = fetchRunningOrders ( )
201
- return Promise . resolve ( ros . map ( ( r ) => r . ro ) )
184
+ if ( ! ros ) return [ ]
185
+ return ros . map ( ( r ) => r . ro )
202
186
} )
203
187
mosDevice . onRequestRunningOrder ( async ( roId ) => {
204
- const ro = monitors [ mosId ] . resendRunningOrder ( roId as any as string )
205
- return Promise . resolve ( ro )
188
+ const ro = monitors [ mosId ] . resendRunningOrder ( mosTypes . mosString128 . stringify ( roId ) )
189
+ return ro
206
190
} )
207
191
// mosDevice.onROStory((story: IMOSROFullStory) => Promise<IMOSROAck>): void;
208
192
setTimeout ( ( ) => {
@@ -222,57 +206,84 @@ async function reloadInner() {
222
206
}
223
207
function refreshFiles ( ) {
224
208
// Check data
225
- const t = Date . now ( )
226
- _ . each ( fetchRunningOrders ( ) , ( r ) => {
209
+ const timestamp = ` ${ Date . now ( ) } `
210
+ for ( const r of fetchRunningOrders ( ) || [ ] ) {
227
211
const runningOrder = r . ro
228
212
const stories = r . stories
229
213
const readyToAir = r . readyToAir
230
214
231
215
const id = mosTypes . mosString128 . stringify ( runningOrder . ID )
232
- runningOrderIds [ id ] = t
216
+ runningOrderIds [ id ] = timestamp
233
217
if ( _ . isEmpty ( monitors ) ) {
234
218
fakeOnUpdatedRunningOrder ( runningOrder , stories )
235
219
} else {
236
220
_ . each ( monitors , ( monitor ) => {
237
221
monitor . onUpdatedRunningOrder ( runningOrder , stories , readyToAir )
238
222
} )
239
223
}
240
- } )
241
- _ . each ( runningOrderIds , ( oldT , id ) => {
242
- if ( oldT !== t ) {
224
+ }
225
+ for ( const [ oldT , id ] of Object . entries < string > ( runningOrderIds ) ) {
226
+ if ( oldT !== timestamp ) {
243
227
_ . each ( monitors , ( monitor ) => {
244
228
monitor . onDeletedRunningOrder ( id )
245
229
} )
246
230
}
247
- } )
231
+ }
248
232
}
249
233
function fetchRunningOrders ( ) {
250
234
const runningOrders : { ro : IMOSRunningOrder ; stories : IMOSROFullStory [ ] ; readyToAir : boolean } [ ] = [ ]
251
- _ . each ( getAllFilesInDirectory ( 'input/runningorders' ) , ( filePath ) => {
235
+ for ( const filePath of getAllFilesInDirectory ( 'input/runningorders' ) ) {
252
236
const requirePath = '../' + filePath . replace ( / \\ / g, '/' )
253
237
try {
254
238
if (
255
239
requirePath . match ( / [ / \\ ] _ / ) || // ignore and folders files that begin with "_"
256
240
requirePath . match ( / [ / \\ ] l i b \. t s / ) // ignore lib files
257
241
) {
258
- return
242
+ continue
259
243
}
260
244
if ( filePath . match ( / ( \. t s | .j s o n ) $ / ) ) {
261
245
const fileContents = loadFile ( requirePath )
262
- const ro : IMOSRunningOrder = fileContents . runningOrder
263
- ro . ID = mosTypes . mosString128 . create ( filePath . replace ( / \W / g, '_' ) )
264
246
265
- runningOrders . push ( {
266
- ro,
267
- stories : fileContents . fullStories ,
268
- readyToAir : fileContents . READY_TO_AIR ,
269
- } )
247
+ if ( fileContents . runningOrder ) {
248
+ const ro = fileContents . runningOrder
249
+ ro . ID = mosTypes . mosString128 . create ( filePath . replace ( / \W / g, '_' ) )
250
+
251
+ if ( ro . EditorialStart && ! mosTypes . mosTime . is ( ro . EditorialStart ) ) {
252
+ ro . EditorialStart = mosTypes . mosTime . create ( ro . EditorialStart . _time )
253
+ }
254
+
255
+ if (
256
+ ro . EditorialDuration &&
257
+ ! mosTypes . mosDuration . is ( ro . EditorialDuration ) &&
258
+ typeof ro . EditorialDuration . _duration === 'number'
259
+ ) {
260
+ ro . EditorialDuration = mosTypes . mosDuration . create ( ro . EditorialDuration . _duration )
261
+ }
262
+
263
+ runningOrders . push ( {
264
+ ro,
265
+ stories : fileContents . stories ,
266
+ readyToAir : fileContents . READY_TO_AIR ,
267
+ } )
268
+ } else if ( fileContents . snapshot && fileContents . snapshot . type === 'rundownplaylist' ) {
269
+ // Is a Sofie snapshot
270
+ convertFromSofieSnapshot ( filePath , fileContents ) . forEach ( ( { ro, stories, readyToAir } ) => {
271
+ runningOrders . push ( {
272
+ ro,
273
+ stories,
274
+ readyToAir,
275
+ } )
276
+ } )
277
+ } else {
278
+ throw new Error ( 'Unsupported file' )
279
+ }
270
280
}
271
281
} catch ( err ) {
272
282
console . log ( `Error when parsing file "${ requirePath } "` )
273
283
throw err
274
284
}
275
- } )
285
+ }
286
+
276
287
return runningOrders
277
288
}
278
289
function getAllFilesInDirectory ( dir : string ) : string [ ] {
@@ -372,7 +383,10 @@ class MOSMonitor {
372
383
this . triggerCheckQueue ( )
373
384
} , 100 )
374
385
return local . ro
375
- } else throw new Error ( `ro ${ roId } not found` )
386
+ } else {
387
+ console . log ( 'ros' , Object . keys ( this . ros ) )
388
+ throw new Error ( `ro ${ roId } not found` )
389
+ }
376
390
}
377
391
onUpdatedRunningOrder ( ro : IMOSRunningOrder , fullStories : IMOSROFullStory [ ] , readyToAir : boolean | undefined ) : void {
378
392
// compare with
0 commit comments