cuemsutils 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cuemsutils/cues/Cue.py ADDED
@@ -0,0 +1,251 @@
1
+ from time import sleep
2
+ from threading import Thread
3
+
4
+ from cuemsutils.log import logged
5
+ from cuemsutils.CTimecode import CTimecode
6
+
7
+ class Cue(dict):
8
+ def __init__(self, init_dict = None):
9
+ if init_dict:
10
+ super().__init__(init_dict)
11
+
12
+ self._target_object = None
13
+ self._conf = None
14
+ self._armed_list = None
15
+ self._start_mtc = CTimecode()
16
+ self._end_mtc = CTimecode()
17
+ self._end_reached = False
18
+ self._go_thread = None
19
+ self._stop_requested = False
20
+ self._local = False
21
+
22
+ @property
23
+ def uuid(self):
24
+ return super().__getitem__('uuid')
25
+
26
+ @uuid.setter
27
+ def uuid(self, uuid):
28
+ super().__setitem__('uuid', uuid)
29
+
30
+ @property
31
+ def id(self):
32
+ return super().__getitem__('id')
33
+
34
+ @id.setter
35
+ def id(self, id):
36
+ super().__setitem__('id', id)
37
+
38
+ @property
39
+ def name(self):
40
+ return super().__getitem__('name')
41
+
42
+ @name.setter
43
+ def name(self, name):
44
+ super().__setitem__('name', name)
45
+
46
+ @property
47
+ def description(self):
48
+ return super().__getitem__('description')
49
+
50
+ @description.setter
51
+ def description(self, description):
52
+ super().__setitem__('description', description)
53
+
54
+ @property
55
+ def enabled(self):
56
+ return super().__getitem__('enabled')
57
+
58
+ @enabled.setter
59
+ def enabled(self, enabled):
60
+ super().__setitem__('enabled', enabled)
61
+
62
+ @property
63
+ def loaded(self):
64
+ return super().__getitem__('loaded')
65
+
66
+ @loaded.setter
67
+ def loaded(self, loaded):
68
+ super().__setitem__('loaded', loaded)
69
+
70
+ @property
71
+ def timecode(self):
72
+ return super().__getitem__('timecode')
73
+
74
+ @timecode.setter
75
+ def timecode(self, timecode):
76
+ super().__setitem__('timecode', timecode)
77
+
78
+ @property
79
+ def offset(self):
80
+ return super().__getitem__('offset')
81
+
82
+ @offset.setter
83
+ def offset(self, offset):
84
+ self.__setitem__('offset', offset)
85
+
86
+ @property
87
+ def loop(self):
88
+ return super().__getitem__('loop')
89
+
90
+ @loop.setter
91
+ def loop(self, loop):
92
+ super().__setitem__('loop', loop)
93
+
94
+ @property
95
+ def prewait(self):
96
+ return super().__getitem__('prewait')
97
+
98
+ @prewait.setter
99
+ def prewait(self, prewait):
100
+ super().__setitem__('prewait', prewait)
101
+
102
+ @property
103
+ def postwait(self):
104
+ return super().__getitem__('postwait')
105
+
106
+ @postwait.setter
107
+ def postwait(self, postwait):
108
+ super().__setitem__('postwait', postwait)
109
+
110
+ @property
111
+ def post_go(self):
112
+ return super().__getitem__('post_go')
113
+
114
+ @post_go.setter
115
+ def post_go(self, post_go):
116
+ super().__setitem__('post_go', post_go)
117
+
118
+ @property
119
+ def target(self):
120
+ return super().__getitem__('target')
121
+
122
+ @target.setter
123
+ def target(self, target):
124
+ super().__setitem__('target', target)
125
+
126
+ @property
127
+ def ui_properties(self):
128
+ return super().__getitem__('ui_properties')
129
+
130
+ @ui_properties.setter
131
+ def ui_properties(self, ui_properties):
132
+ super().__setitem__('ui_properties', ui_properties)
133
+
134
+ @property
135
+ def media(self):
136
+ return super().__getitem__('Media')
137
+
138
+ @media.setter
139
+ def media(self, media):
140
+ super().__setitem__('Media', media)
141
+
142
+ def target_object(self, target_object):
143
+ self._target_object = target_object
144
+
145
+ def type(self):
146
+ return type(self)
147
+
148
+ def __setitem__(self, key, value):
149
+ if (key in ['offset', 'prewait', 'postwait']) and (value not in (None, "")):
150
+ if isinstance(value, CTimecode):
151
+ ctime_value = value
152
+ else:
153
+ if isinstance(value, (int, float)):
154
+ ctime_value = CTimecode(start_seconds = value)
155
+ ctime_value.frames = ctime_value.frames + 1
156
+ elif isinstance(value, str):
157
+ ctime_value = CTimecode(value)
158
+ elif isinstance(value, dict):
159
+ dict_timecode = value.pop('CTimecode', None)
160
+ if dict_timecode is None:
161
+ ctime_value = CTimecode()
162
+ elif isinstance(dict_timecode, int):
163
+ ctime_value = CTimecode(start_seconds = dict_timecode)
164
+ else:
165
+ ctime_value = CTimecode(dict_timecode)
166
+
167
+ super().__setitem__(key, ctime_value)
168
+
169
+ else:
170
+ super().__setitem__(key, value)
171
+
172
+ def arm(self, conf, ossia, armed_list, init = False):
173
+ self._conf = conf
174
+ self._armed_list = armed_list
175
+
176
+ if not self.enabled:
177
+ if self.loaded and self in self._armed_list:
178
+ self.disarm(ossia)
179
+ return False
180
+ elif self.loaded and not init:
181
+ if not self in self._armed_list:
182
+ self._armed_list.append(self)
183
+ return True
184
+
185
+ if self.post_go == 'go':
186
+ self._target_object.arm(self._conf, ossia, self._armed_list, init)
187
+
188
+ return True
189
+
190
+ @logged
191
+ def go(self, ossia, mtc):
192
+ if not self.loaded:
193
+ raise Exception(f'{self.__class__.__name__} {self.uuid} not loaded to go')
194
+
195
+ else:
196
+ # THREADED GO
197
+ thread = Thread(
198
+ name = f'GO:{self.__class__.__name__}:{self.uuid}',
199
+ target = self.go_thread,
200
+ args = [ossia, mtc]
201
+ )
202
+ thread.start()
203
+
204
+ def go_thread(self, ossia, mtc):
205
+ # ARM NEXT TARGET
206
+ if self._target_object:
207
+ self._target_object.arm(self._conf, ossia, self._armed_list)
208
+
209
+ # PREWAIT
210
+ if self.prewait > 0:
211
+ sleep(self.prewait.milliseconds / 1000)
212
+
213
+ # PLAY WHATEVER A SIMPLE CUE WOULD PLAY
214
+
215
+ # POSTWAIT
216
+ if self.postwait > 0:
217
+ sleep(self.postwait.milliseconds / 1000)
218
+
219
+ # POST-GO GO
220
+ if self.post_go == 'go':
221
+ self._target_object.go(ossia, mtc)
222
+
223
+ if self in self._armed_list:
224
+ self.disarm(ossia)
225
+
226
+
227
+ def disarm(self, ossia = None):
228
+ if self.loaded is True:
229
+ self.loaded = False
230
+
231
+ if self in self._armed_list:
232
+ self._armed_list.remove(self)
233
+
234
+ return True
235
+ else:
236
+ return False
237
+
238
+ def get_next_cue(self):
239
+ if self.target:
240
+ if self.post_go == 'pause':
241
+ return self._target_object
242
+ else:
243
+ return self._target_object.get_next_cue()
244
+ else:
245
+ return None
246
+
247
+ def check_mappings(self, settings):
248
+ return True
249
+
250
+ def stop(self):
251
+ pass
@@ -0,0 +1,160 @@
1
+ from time import sleep
2
+ from threading import Thread
3
+ from Cue import Cue
4
+ from cuemsutils.log import logged, Logger
5
+
6
+ class CueList(Cue):
7
+ def __init__(self, init_dict = None):
8
+ super().__init__(init_dict)
9
+
10
+ @property
11
+ def contents(self):
12
+ return super().__getitem__('contents')
13
+
14
+ @contents.setter
15
+ def contents(self, contents):
16
+ super().__setitem__('contents', contents)
17
+
18
+ @property
19
+ def uuid(self):
20
+ return super().__getitem__('uuid')
21
+
22
+ def __add__(self, other):
23
+ new_contents = self['contents'].copy()
24
+ new_contents.append(other)
25
+ return new_contents
26
+
27
+ def __iadd__(self, other):
28
+ self['contents'].__iadd__(other)
29
+ return self
30
+
31
+ def times(self):
32
+ timelist = list()
33
+ for item in self['contents']:
34
+ timelist.append(item.offset)
35
+ return timelist
36
+
37
+ def find(self, uuid):
38
+ if self.uuid == uuid:
39
+ return self
40
+ else:
41
+ for item in self.contents:
42
+ if item.uuid == uuid:
43
+ return item
44
+ elif isinstance(item, CueList):
45
+ recursive = item.find(uuid)
46
+ if recursive != None:
47
+ return recursive
48
+
49
+ return None
50
+
51
+ def get_media(self):
52
+ media_dict = dict()
53
+ for item in self.contents:
54
+ if isinstance(item, CueList):
55
+ media_dict.update( item.get_media() )
56
+ else:
57
+ try:
58
+ if item.media:
59
+ media_dict[item.uuid] = [item.media.file_name, item.__class__.__name__]
60
+ except KeyError:
61
+ media_dict[item.uuid] = {'media' : None, 'type' : item.__class__.__name__}
62
+
63
+ return media_dict
64
+
65
+ def arm(self, conf, ossia_server, armed_list, init = False):
66
+ self.conf = conf
67
+ self.armed_list = armed_list
68
+
69
+ if self.enabled and self.loaded == init:
70
+ if not self in armed_list:
71
+ self.contents[0].arm(self.conf, ossia_server, self.armed_list, init)
72
+
73
+ self.loaded = True
74
+
75
+ armed_list.append(self)
76
+
77
+ if self.post_go == 'go':
78
+ self._target_object.arm(self.conf, ossia_server, self.armed_list, init)
79
+
80
+ return True
81
+ else:
82
+ return False
83
+
84
+ @logged
85
+ def go(self, ossia, mtc):
86
+ if not self.loaded:
87
+ raise Exception(f'{self.__class__.__name__} {self.uuid} not loaded to go')
88
+ else:
89
+ # THREADED GO
90
+ thread = Thread(name = f'GO:{self.__class__.__name__}:{self.uuid}', target = self.go_thread, args = [ossia, mtc])
91
+ thread.start()
92
+
93
+ @logged
94
+ def go_thread(self, ossia, mtc):
95
+ # ARM NEXT TARGET
96
+ if self._target_object:
97
+ self._target_object.arm(self.conf, ossia, self.armed_list)
98
+
99
+ # PREWAIT
100
+ if self.prewait > 0:
101
+ sleep(self.prewait.milliseconds / 1000)
102
+
103
+ # PLAY : specific go the first cue in the list
104
+ try:
105
+ if self.contents:
106
+ self.contents[0].go(ossia, mtc)
107
+ except Exception as e:
108
+ Logger.log_error(
109
+ f'GO failed for content {self.contents[0].uuid}: {e}',
110
+ extra = {"caller": self.__class__.__name__}
111
+ )
112
+
113
+ # POSTWAIT
114
+ if self.postwait > 0:
115
+ sleep(self.postwait.milliseconds / 1000)
116
+
117
+ if self.post_go == 'go':
118
+ self._target_object.go(ossia, mtc)
119
+
120
+ '''
121
+ if self.post_go == 'go_at_end':
122
+ self._target_object.go(ossia, mtc)
123
+ '''
124
+
125
+ if self in self.armed_list:
126
+ self.disarm(ossia)
127
+
128
+ def disarm(self):
129
+ try:
130
+ if self in self.armed_list:
131
+ self.armed_list.remove(self)
132
+ except:
133
+ pass
134
+
135
+ self.loaded = False
136
+
137
+ def get_next_cue(self):
138
+ cue_to_return = None
139
+ if self.contents:
140
+ if self.contents[0].post_go == 'pause':
141
+ cue_to_return = self.contents[0]._target_object
142
+ else:
143
+ cue_to_return = self.contents[0].get_next_cue()
144
+
145
+ if cue_to_return:
146
+ return cue_to_return
147
+
148
+ if self.target:
149
+ if self.post_go == 'pause':
150
+ return self._target_object
151
+ else:
152
+ return self._target_object.get_next_cue()
153
+ else:
154
+ return None
155
+
156
+ def check_mappings(self, settings):
157
+ # By now let's presume all CueList objects are _local
158
+ self._local = True
159
+
160
+ return True
@@ -0,0 +1,13 @@
1
+ class CueOutput(dict):
2
+ def __init__(self, init_dict = None):
3
+ if init_dict:
4
+ super().__init__(init_dict)
5
+
6
+ class AudioCueOutput(CueOutput):
7
+ pass
8
+
9
+ class VideoCueOutput(CueOutput):
10
+ pass
11
+
12
+ class DmxCueOutput(CueOutput):
13
+ pass
@@ -0,0 +1,124 @@
1
+ from cuemsutils.log import logged
2
+ from CueList import CueList
3
+
4
+ class CuemsScript(dict):
5
+ def __init__(self, init_dict = None):
6
+ if init_dict:
7
+ super().__init__(init_dict)
8
+
9
+ @property
10
+ def uuid(self):
11
+ return super().__getitem__('uuid')
12
+
13
+ @uuid.setter
14
+ def uuid(self, uuid):
15
+ super().__setitem__('uuid', uuid)
16
+
17
+ @property
18
+ def unix_name(self):
19
+ return super().__getitem__('unix_name')
20
+
21
+ @unix_name.setter
22
+ def unix_name(self, unix_name):
23
+ super().__setitem__('unix_name', unix_name)
24
+
25
+ @property
26
+ def name(self):
27
+ return super().__getitem__('name')
28
+
29
+ @name.setter
30
+ def name(self, name):
31
+ super().__setitem__('name', name)
32
+
33
+ @property
34
+ def description(self):
35
+ return super().__getitem__('description')
36
+
37
+ @description.setter
38
+ def description(self, description):
39
+ super().__setitem__('description', description)
40
+
41
+ @property
42
+ def created(self):
43
+ return super().__getitem__('created')
44
+
45
+ @created.setter
46
+ def created(self, created):
47
+ super().__setitem__('created', created)
48
+
49
+ @property
50
+ def modified(self):
51
+ return super().__getitem__('modified')
52
+
53
+ @modified.setter
54
+ def modified(self, modified):
55
+ super().__setitem__('modified', modified)
56
+
57
+ @property
58
+ def cuelist(self):
59
+ return super().__getitem__('cuelist')
60
+
61
+ @cuelist.setter
62
+ def cuelist(self, cuelist):
63
+ if isinstance(cuelist, CueList):
64
+ super().__setitem__('cuelist', cuelist)
65
+ else:
66
+ raise NotImplementedError
67
+
68
+ # returns a dict of UNIQUE media (no duplicates)
69
+
70
+ @logged
71
+ def get_media(self, cuelist = None):
72
+ '''Gets all the media files list present on a cuelist.'''
73
+ media_dict = dict()
74
+
75
+ # If no cuelist is specified we are looking inside our own
76
+ # script object, so our cuelist is our self cuelist
77
+ if not cuelist:
78
+ cuelist = self.cuelist
79
+
80
+ if cuelist.contents:
81
+ for cue in cuelist.contents:
82
+ if type(cue)==CueList:
83
+ # If the cue is a cuelist, let's recurse
84
+ media_dict.update(self.get_media(cuelist=cue))
85
+ else:
86
+ try:
87
+ if cue.media:
88
+ media_dict[cue.media.file_name] = cue
89
+ except KeyError:
90
+ pass
91
+ # logger.debug("cue with no media")
92
+ return media_dict
93
+
94
+ @logged
95
+ def get_own_media(self, cuelist = None, config = None):
96
+ '''Gets the media files list present on the script which are
97
+ related to the specified node uuid, usually our local UUID,
98
+ as we are looking for our own needed media files'''
99
+
100
+ media_dict = dict()
101
+
102
+ # If no cuelist is specified we are looking inside our own
103
+ # script object, so our cuelist is our self cuelist
104
+ if not cuelist:
105
+ cuelist = self.cuelist
106
+
107
+ if cuelist.contents:
108
+ for cue in cuelist.contents:
109
+ if type(cue)==CueList:
110
+ # If the cue is a cuelist, let's recurse
111
+ media_dict.update(self.get_own_media(cuelist=cue, config=config))
112
+ else:
113
+ try:
114
+ if cue.media:
115
+ cue.check_mappings(config)
116
+ if cue._local:
117
+ media_dict[cue.media.file_name] = cue
118
+ except KeyError:
119
+ pass
120
+ # logger.debug("cue with no media")
121
+ return media_dict
122
+
123
+ def find(self, uuid):
124
+ return self.cuelist.find(uuid)