class Channel(OSCBaseObject): def __init__(self, **kwargs): self.channel = kwargs.get('channel') kwargs.setdefault('osc_address', str(self.channel + 1)) super(Channel, self).__init__(**kwargs) self.register_signal('event') self.notes = ChildGroup(name='note', osc_parent_node=self.osc_node) self.controllers = ChildGroup(name='controller', osc_parent_node=self.osc_node) for i in range(128): n = self.notes.add_child(Note, note=i, channel=self, Index=i) n.bind(event=self.on_child_event) c = self.controllers.add_child(Controller, controller=i, channel=self) c.bind(event=self.on_child_event) def unlink(self): for n in self.notes.iteritems(): n.unlink() for c in self.controllers.iteritems(): c.unlink() super(Channel, self).unlink() def trigger_event(self, **kwargs): type = kwargs.get('type') attr = type + 's' if not hasattr(self, attr): return obj = getattr(self, attr).get(kwargs.get(type)) if not obj: return obj.trigger_event(**kwargs) def on_child_event(self, **kwargs): kwargs.setdefault('channel', self.channel) self.emit('event', **kwargs)
class PageMenu(OSCBaseObject): #button_size = dict(w=.2, h=.05) def __init__(self, **kwargs): self.iOsc = kwargs.get('iOsc') self.client = kwargs.get('client') self.current_page = None kwargs.setdefault('osc_parent_node', self.client.osc_node) kwargs.setdefault('osc_address', 'PageMenu') kwargs.setdefault('ParentEmissionThread', self.iOsc.ParentEmissionThread) super(PageMenu, self).__init__(**kwargs) self.x_offset = kwargs.get('x_offset', 0.) self.y_offset = kwargs.get('y_offset', 0.) #w = self.button_size['w'] * len(PAGES) self.button_size = dict(h=.05, w=1. / len(PAGES)) h = self.button_size['h'] bounds = [self.x_offset, self.y_offset, 1, h] self.topwidget = self.iOsc.add_widget( 'Label', name='PageMenu', bounds=bounds, osc_parent_node=self.osc_parent_node, client=self.client) self.btn_topwidget = self.topwidget.add_widget(widgets.Label, name='select_buttons', bounds=bounds) self.menu_buttons = ChildGroup(name='select_buttons', osc_parent_node=self.osc_node) for i, cls in enumerate(PAGES): btn = self.btn_topwidget.add_widget(MenuButton, Index=i, page_cls=cls, parent=self) self.menu_buttons.add_child(existing_object=btn) btn.bind(touch_state=self.on_menu_button_touch_state) def unlink(self): self.set_current_page(None) self.topwidget.remove() super(PageMenu, self).unlink() def set_current_page(self, cls): if self.current_page is not None: self.current_page.remove() self.current_page = None if cls is not None: self.current_page = cls(iOsc=self.iOsc, client=self.client, y_offset=self.y_offset + self.button_size['h'] + .01) def on_menu_button_touch_state(self, **kwargs): btn = kwargs.get('obj') state = kwargs.get('value') if state: self.set_current_page(btn.cls) for w in self.menu_buttons.itervalues(): if w != btn: w.touch_state = False
class PageMenu(OSCBaseObject): #button_size = dict(w=.2, h=.05) def __init__(self, **kwargs): self.iOsc = kwargs.get('iOsc') self.client = kwargs.get('client') self.current_page = None kwargs.setdefault('osc_parent_node', self.client.osc_node) kwargs.setdefault('osc_address', 'PageMenu') kwargs.setdefault('ParentEmissionThread', self.iOsc.ParentEmissionThread) super(PageMenu, self).__init__(**kwargs) self.x_offset = kwargs.get('x_offset', 0.) self.y_offset = kwargs.get('y_offset', 0.) #w = self.button_size['w'] * len(PAGES) self.button_size = dict(h=.05, w=1./len(PAGES)) h = self.button_size['h'] bounds = [self.x_offset, self.y_offset, 1, h] self.topwidget = self.iOsc.add_widget('Label', name='PageMenu', bounds=bounds, osc_parent_node=self.osc_parent_node, client=self.client) self.btn_topwidget = self.topwidget.add_widget(widgets.Label, name='select_buttons', bounds=bounds) self.menu_buttons = ChildGroup(name='select_buttons', osc_parent_node=self.osc_node) for i, cls in enumerate(PAGES): btn = self.btn_topwidget.add_widget(MenuButton, Index=i, page_cls=cls, parent=self) self.menu_buttons.add_child(existing_object=btn) btn.bind(touch_state=self.on_menu_button_touch_state) def unlink(self): self.set_current_page(None) self.topwidget.remove() super(PageMenu, self).unlink() def set_current_page(self, cls): if self.current_page is not None: self.current_page.remove() self.current_page = None if cls is not None: self.current_page = cls(iOsc=self.iOsc, client=self.client, y_offset=self.y_offset + self.button_size['h'] + .01) def on_menu_button_touch_state(self, **kwargs): btn = kwargs.get('obj') state = kwargs.get('value') if state: self.set_current_page(btn.cls) for w in self.menu_buttons.itervalues(): if w != btn: w.touch_state = False
class ArtBaseMsg(object): _fields = {1:'ID', 2:'OpCode'} def __init__(self, **kwargs): self.msg_type = kwargs.get('msg_type', self.__class__.__name__) cls = self.__class__ fields = {} while cls != ArtBaseMsg: fields.update(getattr(cls, '_fields', {})) cls = cls.__bases__[0] fields.update(ArtBaseMsg._fields) self.Fields = ChildGroup(name='Fields') for index, key in fields.iteritems(): fcls = getattr(FieldClasses, key, None) if fcls is not None: fobj = self.Fields.add_child(fcls, Index=index) for i in range(1, self._num_fields + 1): current = self.Fields.indexed_items.get(i) if current is not None: field = current else: if i <= field.Index + field.expected_length - 1: pass else: fobj = self.Fields.add_child(FieldClasses.Dummy, id='Dummy_%s' % (i), Index=i) #print 'added dummyobj: i=%s, current=%s, field=%s' % (i, current, field) self.init_msg(**kwargs) datastr = kwargs.get('from_string') if datastr: self._parse_success = True result = self.from_string(datastr) if result is False: self._parse_success = False else: for key, field in self.Fields.iteritems(): value = getattr(self, key, kwargs.get(key, FIELD_DEFAULTS.get(key))) if value is not None: field.value = value def init_msg(self, **kwargs): pass def from_string(self, string): if string is None: return False l, fmt = self.get_data() while len(string) < struct.calcsize(fmt): before = fmt fmt = fmt[:-1] #print 'fmt trunc: before=%s, after=%s' % (before, fmt) if len(string) > struct.calcsize(fmt): string = string[:struct.calcsize(fmt)] try: values = list(struct.unpack(fmt, string)) except: LOG.warning(self, 'could not unpack', struct.calcsize(fmt), len(string)) return False #print 'from_string: ', values for field in self.Fields.indexed_items.itervalues(): length = field.expected_length if length > len(values): #print 'not enough data for field: ', field.id break field.set_data(values[:length]) #print field.__class__.__name__, values[:length], values del values[:length] def get_data(self): l = [] #print 'getdata: ', self.msg_type for field in self.Fields.indexed_items.itervalues(): data = field.get_data() #print field.id, data l.extend(data) fmt = '=%s' % (''.join([type(item).struct_fmt for item in l])) return l, fmt def build_string(self): l, fmt = self.get_data() return struct.pack(fmt, *l) def copy(self): msg = self.__class__() for i, field in self.Fields.indexed_items.iteritems(): msg.Fields.indexed_items[i].value = field.value return msg def __str__(self): keys = sorted(self.Fields.indexed_items.keys()) fields = ', '.join([str(self.Fields.indexed_items[key]) for key in keys]) return ': '.join([self.msg_type, fields])
class Pipeline(Bin): _Properties = {'pipeline_state':dict(default='null')} base_class = 'Pipeline' def __init__(self, **kwargs): self.bin_data = kwargs.get('bin_data', []) if len(self.bin_data): kwargs['simple_links'] = False super(Pipeline, self).__init__(**kwargs) statekeys = ['NULL', 'PAUSED', 'PLAYING', 'READY', 'VOID_PENDING'] gststates = [int(getattr(self._gst_module, '_'.join(['STATE', key]))) for key in statekeys] self.gst_state_map = dict(zip(gststates, [key.lower() for key in statekeys])) self.Bins = ChildGroup(name='Bins', child_class=Bin) for bindata in self.bin_data: if isinstance(bindata, Bin): bindata = {'existing_object':bindata} self.add_bin(**bindata) self.link_bins() bus = self._pipeline.get_bus() bus.add_signal_watch() bus.connect('message', self.on_bus_message) self.bind(pipeline_state=self.on_pipeline_state) def on_pipeline_state(self, **kwargs): #print kwargs pass def init_instance(self, **kwargs): self._pipeline = self._gst_module.Pipeline(self.name) self.elem_container = self._pipeline def add_bin(self, **kwargs): bin = self.Bins.add_child(**kwargs) self.elem_container.add(bin.elem_container) def link_bins(self): if len(self.Bins) < 2: return for index, bin in self.Bins.indexed_items.iteritems(): nextbin = self.Bins.indexed_items.get(index+1) if nextbin is None: continue #print index, bin.name, nextbin.name try: bin.elem_container.link(nextbin.elem_container) except: print 'could not link %s with %s' % (bin.name, nextbin.name) continue # for i, src in enumerate(bin.GhostPads['src']): # if len(nextbin.GhostPads['sink']) <= i - 1: # print src.get_name(), ' linking to ', nextbin.GhostPads['sink'][i].get_name() # src.link(nextbin.GhostPads['sink'][i]) def on_bus_message(self, bus, message): self.pipeline_state = self.gst_state_map.get(int(self._pipeline.get_state()[1])) #print 'bus message: ', self.pipeline_state, self._pipeline.get_state() def start(self): self._pipeline.set_state(self._gst_module.STATE_PLAYING) def stop(self): self._pipeline.set_state(self._gst_module.STATE_NULL) self.pipeline_state = 'null'
class OSCSessionManager(BaseIO.BaseIO, Config): _confsection = 'OSC' _Properties = {'oscMaster':dict(type=str)} def __init__(self, **kwargs): self.Manager = kwargs.get('Manager') self.ioManager = self.Manager.ioManager self.comm = self.Manager.comm self.root_node = self.Manager.root_node self.osc_tree = self.Manager.osc_tree BaseIO.BaseIO.__init__(self, **kwargs) Config.__init__(self, **kwargs) self.register_signal('client_added', 'client_removed', 'new_master') #self.oscMaster = None self.bind(oscMaster=self._on_oscMaster_set) self.set_master_timeout = None self.master_takeover_timer = None self.check_master_attempts = None self.local_client = None self.clients = ChildGroup(name='clients', osc_address='CLIENTS', osc_parent_node=self.root_node, child_class=Client, ignore_index=True) self.clients_by_address = {} #self.root_node.addCallback('/getMaster', self.on_master_requested_by_osc) #self.root_node.addCallback('/setMaster', self.on_master_set_by_osc) #self.getMasterNode = self.root_node.add_child(name='getMaster') #self.getMasterNode.bind(message_received=self.on_master_requested_by_osc) #self.setMasterNode = self.root_node.add_child(name='setMaster') #self.setMasterNode.bind(message_received=self.on_master_set_by_osc) self.GLOBAL_CONFIG.bind(update=self.on_GLOBAL_CONFIG_update) if self.GLOBAL_CONFIG.get('osc_use_discovery', True): self.comm.ServiceConnector.connect('new_host', self.on_host_discovered) self.comm.ServiceConnector.connect('remove_host', self.on_host_removed) self.Manager.bind(master_priority=self._on_master_priority_set, session_name=self._on_session_name_set, ring_master=self._on_ring_master_set) @property def root_address(self): return self.Manager.root_address @property def local_name(self): if not self.local_client: return '-'.join([self.GLOBAL_CONFIG.get('app_name'), socket.gethostname()]) return self.local_client.name @property def isMaster(self): return self.oscMaster == self.local_name @property def isRingMaster(self): return self.Manager.ring_master == self.local_name @property def master_priority(self): return self.Manager.master_priority @master_priority.setter def master_priority(self, value): self.Manager.master_priority = value @property def discovered_sessions(self): return self.Manager.discovered_sessions @property def session_name(self): return self.Manager.session_name @session_name.setter def session_name(self, value): self.Manager.session_name = value def determine_ring_master(self): masters = {} for session in self.discovered_sessions.itervalues(): m = session.master if m is None: continue #key = int(''.join([s.rjust(3, '0') for s in m.address.split('.')])) key = ip_to_int(m.address) masters[key] = m if not len(masters): return False master = masters[min(masters.keys())] if master.name != self.Manager.ring_master: self.Manager.ring_master = master.name return master def do_connect(self): serv = self.comm.ServiceConnector.add_service(**self.build_zeroconf_data()) self.comm.ServiceConnector.add_listener(stype='_osc._udp') self.connected = True self.check_for_master() def do_disconnect(self, **kwargs): self.set_master(False) self.connected = False def add_to_session(self, **kwargs): ''' Adds a Client obj to a Session object which will handle master determination, etc. If the Session does not exist, one is created. ''' name = kwargs.get('name') if name is None: return client = kwargs.get('client') clients = kwargs.get('clients', []) if client is not None: clients.append(client) sessions = self.discovered_sessions session = sessions.get(name) if session: for c in clients: session.add_member(c) else: prebind = dict(master=self.on_session_master_set, members_update=self.on_session_members_update) session = sessions.add_child(name=name, members=clients, prebind=prebind) def remove_from_session(self, **kwargs): ''' Removes a Client object (or objects) from a Session object, if it exists. ''' name = kwargs.get('name') client = kwargs.get('client') clients = kwargs.get('clients', []) if client is not None: clients.append(client) sessions = self.discovered_sessions session = sessions.get(name) if not session: return for c in clients: session.del_member(c) def add_client(self, **kwargs): kwargs.setdefault('port', self.ioManager.hostdata['sendport']) kwargs.setdefault('app_address', self.Manager.app_address) #kwargs['osc_parent_node'] = self.client_osc_node if socket.gethostname() in kwargs.get('name', ''): kwargs['isLocalhost'] = True #kwargs['master_priority'] = self.master_priority client = self.clients.add_child(**kwargs) self.clients_by_address[client.address] = client if client.isLocalhost: self.local_client = client #client.master_priority = self.master_priority #print 'local_client session: ', client.session_name self.add_to_session(name=client.session_name, client=client) client.bind(property_changed=self.on_client_obj_property_changed) #if client.session_name is not None: # self.discovered_sessions.add(client.session_name) self.Manager.update_wildcards() #if self.check_master_attempts is None: # self.check_for_master(client=client.name) propkeys = client.Properties.keys() self.LOG.info('add_client:', dict(zip(propkeys, [client.Properties[key].value for key in propkeys]))) keys = ['name', 'address', 'port'] s_kwargs = dict(zip(keys, [getattr(client, key) for key in keys])) s_kwargs.update({'client':client}) self.emit('client_added', **s_kwargs) def remove_client(self, **kwargs): name = kwargs.get('name') client = self.clients.get(name) if client is None: return #self.remove_client_name(name, update_conf=False) #self.remove_client_address(addr, update_conf=False) client.unbind(self) self.clients.del_child(client) self.Manager.update_wildcards() self.LOG.info('remove_client:', name) self.emit('client_removed', name=name, client=client) if client.session_name is not None: self.remove_from_session(name=client.session_name, client=client) def on_session_master_set(self, **kwargs): session = kwargs.get('obj') value = kwargs.get('value') self.determine_ring_master() if session.name != self.session_name: return if session.master is None: m = self.determine_next_master() if m == self.local_client: self.set_master() if session.master.name == self.oscMaster: return if session.master != self.local_client: self.set_master(session.master.name) def on_session_members_update(self, **kwargs): session = kwargs.get('obj') mode = kwargs.get('mode') if mode == 'remove': if not len(session.members): session.unbind(self) self.discovered_sessions.del_child(session) def on_client_obj_property_changed(self, **kwargs): prop = kwargs.get('Property') old = kwargs.get('old') value = kwargs.get('value') client = kwargs.get('obj') if prop.name == 'isRingMaster' and value is True: if self.Manager.ring_master != client.name: self.Manager.ring_master = client.name elif prop.name == 'session_name' and value is not None: self.add_to_session(name=value, client=client) def build_zeroconf_data(self): d = dict(name=self.local_name, stype='_osc._udp', port=self.Manager.ioManager.hostdata['recvport']) txt = {'app_name':self.GLOBAL_CONFIG['app_name']} #session = self.GLOBAL_CONFIG.get('session_name') #if session: # txt['session_name'] = session d['text'] = txt return d def build_curly_wildcard(self, l): return '{%s}' % (','.join(list(l))) def _on_master_priority_set(self, **kwargs): value = kwargs.get('value') #if self.local_client is not None: # self.local_client.master_priority = value self.GLOBAL_CONFIG['master_priority'] = value self.update_conf(master_priority=value) #data = self.build_zeroconf_data() #self.comm.ServiceConnector.update_service(**data) def _on_session_name_set(self, **kwargs): value = kwargs.get('value') #if self.local_client is not None: # self.local_client.session_name = value # self.local_client.isMaster = False #data = self.build_zeroconf_data() #self.comm.ServiceConnector.update_service(**data) #self.select_new_master() if self.local_client is not None: self.add_to_session(name=value, client=self.local_client) #self.local_client.session_name = value master = self.discovered_sessions[value].master if master is not None: master = master.name self.set_master(master) self.GLOBAL_CONFIG['session_name'] = value def on_GLOBAL_CONFIG_update(self, **kwargs): keys = kwargs.get('keys') if not keys: keys = [kwargs.get('key')] for key in ['master_priority', 'session_name']: if key not in keys: continue value = self.GLOBAL_CONFIG.get(key) if value != getattr(self, key): setattr(self, key, value) def on_host_discovered(self, **kwargs): host = kwargs.get('host') if '.' not in host.address: return c_kwargs = host.hostdata.copy() c_kwargs.update({'discovered':True}) self.add_client(**c_kwargs) def on_host_removed(self, **kwargs): self.LOG.info('remove:', kwargs) id = kwargs.get('id') self.remove_client(name=id) def check_for_master(self, **kwargs): if self.connected and not self.isMaster: name = kwargs.get('name') #if self.check_master_attempts is None: # self.check_master_attempts = 0 #self.cancel_check_master_timer() self.set_master_timeout = threading.Timer(10.0, self.on_check_master_timeout) self.set_master_timeout.start() #new_kwargs = {}#{'address':'getMaster'} #if name: # new_kwargs.update({'client':name}) #element = self.getMasterNode.send_message(value=self.session_name, # all_sessions=True, # timetag=-1) #print 'sent getmaster: ', [str(element)] def on_check_master_timeout(self): self.set_master() return self.check_master_attempts += 1 if self.check_master_attempts == 3: self.check_master_attempts = None self.set_master() else: self.check_for_master() def set_master(self, name=None): self.cancel_check_master_timer() if self.master_takeover_timer: self.master_takeover_timer.cancel() if name is None: s = self.local_name elif name is False: s = None else: s = name if s != self.oscMaster: self.oscMaster = s if self.oscMaster is None: return lc = self.local_client if self.isMaster: if lc is not None: lc.isMaster = True else: if lc is not None: lc.isMaster = False m = self.determine_next_master() if m and m.isLocalhost and name is not False: self.LOG.info('master takeover in 10 seconds...') t = threading.Timer(10.0, self.on_master_takeover_timeout) self.master_takeover_timer = t t.start() self.LOG.info('master = ', self.oscMaster) self.determine_ring_master() self.emit('new_master', master=self.oscMaster, master_is_local=self.isMaster) def on_master_takeover_timeout(self): self.LOG.info('master takeover timer complete') self.master_takeover_timer = None m = self.determine_next_master() if not m: return if not self.isMaster and m.isLocalhost: self.set_master() def cancel_check_master_timer(self): if self.set_master_timeout and self.set_master_timeout.isAlive(): self.set_master_timeout.cancel() self.set_master_timeout = None def determine_next_master(self): session = self.discovered_sessions[self.session_name] d = {} for c in session.members.itervalues(): key = c.master_priority if key is None: continue if not (c.isSlave or c.isMaster or c.isLocalhost): continue if key in d and ip_to_int(c.address) > ip_to_int(d[key].address): continue d[key] = c self.LOG.info('clients by priority: ', d) if not len(d): return None return d[min(d)] def old_determine_next_master(self): d = {} for client in self.clients.itervalues(): if not client.isSameSession: continue key = client.master_priority if key is not None and (client.isSlave or client.isMaster or client.isLocalhost): if key in d: if d[key].name < client.name: d[key] = client else: d[key] = client self.LOG.info('clients by priority: ', d) if not len(d): return None return d[min(d)] def _on_ring_master_set(self, **kwargs): value = kwargs.get('value') self.LOG.info('RINGMASTER: ', value) self.local_client.isRingMaster = value == self.local_name self.Manager.ClockSync.isMaster = self.isRingMaster def _on_oscMaster_set(self, **kwargs): self.root_node.oscMaster = self.isMaster
class Bin(gstBase): base_class = 'Bin' def __init__(self, **kwargs): super(Bin, self).__init__(**kwargs) if not hasattr(self, 'element_data'): self.element_data = kwargs.get('element_data', []) self.simple_links = kwargs.get('simple_links', True) if self.base_class == 'Bin': self._bin = self._gst_module.Bin(self.name) self.elem_container = self._bin self.Elements = ChildGroup(name='Elements', child_class=Element) self.unlinked_elements = {} self.init_instance(**kwargs) self.build_elements() self.link_elements() if self.base_class == 'Bin': self.enable_ghost_pads = set(kwargs.get('enable_ghost_pads', ['src', 'sink'])) self.build_ghost_pads() def build_ghost_pads(self): padmap = {self._gst_module.PAD_SINK:'sink', self._gst_module.PAD_SRC:'src'} self.GhostPads = {'sink':[], 'src':[]} elems = {'sink':self.Elements.indexed_items.values()[0], 'src':self.Elements.indexed_items.values()[-1:][0]} for key, elem in elems.iteritems(): if key not in self.enable_ghost_pads: continue for p in elem._element.pads(): direction = padmap.get(p.get_direction()) if direction != key: continue name = ''.join(['Ghost', p.get_name()]) gpad = self._gst_module.GhostPad(name, p) self.elem_container.add_pad(gpad) self.GhostPads[key].append(gpad) def init_instance(self, **kwargs): pass def build_elements(self): for edata in self.element_data: if isinstance(edata, Element): edata = {'existing_object':edata} elif type(edata) == str: edata = {'gst_name':edata} self.add_element(**edata) def link_elements(self): if not self.simple_links or len(self.Elements) < 2: return for i, elem in self.Elements.indexed_items.iteritems(): nextelem = self.Elements.indexed_items.get(i+1) if nextelem is None: continue try: elem._element.link(nextelem._element) except: sigs = [] for e in [elem, nextelem]: sigs.append(e._element.connect('pad-added', self.on_element_pad_added, i)) self.unlinked_elements[i] = ((elem, nextelem), sigs) def add_element(self, **kwargs): element = self.Elements.add_child(**kwargs) self.elem_container.add(element._element) def on_element_pad_added(self, element, pad, index): if index not in self.unlinked_elements: return elems, gsignals = self.unlinked_elements.get(index) try: elems[0]._element.link(elems[1]._element) for e, sig in zip(elems, gsignals): e.disconnect(sig) del self.unlinked_elements[index] except: return
class Pipeline(Bin): _Properties = {'pipeline_state': dict(default='null')} base_class = 'Pipeline' def __init__(self, **kwargs): self.bin_data = kwargs.get('bin_data', []) if len(self.bin_data): kwargs['simple_links'] = False super(Pipeline, self).__init__(**kwargs) statekeys = ['NULL', 'PAUSED', 'PLAYING', 'READY', 'VOID_PENDING'] gststates = [ int(getattr(self._gst_module, '_'.join(['STATE', key]))) for key in statekeys ] self.gst_state_map = dict( zip(gststates, [key.lower() for key in statekeys])) self.Bins = ChildGroup(name='Bins', child_class=Bin) for bindata in self.bin_data: if isinstance(bindata, Bin): bindata = {'existing_object': bindata} self.add_bin(**bindata) self.link_bins() bus = self._pipeline.get_bus() bus.add_signal_watch() bus.connect('message', self.on_bus_message) self.bind(pipeline_state=self.on_pipeline_state) def on_pipeline_state(self, **kwargs): #print kwargs pass def init_instance(self, **kwargs): self._pipeline = self._gst_module.Pipeline(self.name) self.elem_container = self._pipeline def add_bin(self, **kwargs): bin = self.Bins.add_child(**kwargs) self.elem_container.add(bin.elem_container) def link_bins(self): if len(self.Bins) < 2: return for index, bin in self.Bins.indexed_items.iteritems(): nextbin = self.Bins.indexed_items.get(index + 1) if nextbin is None: continue #print index, bin.name, nextbin.name try: bin.elem_container.link(nextbin.elem_container) except: print 'could not link %s with %s' % (bin.name, nextbin.name) continue # for i, src in enumerate(bin.GhostPads['src']): # if len(nextbin.GhostPads['sink']) <= i - 1: # print src.get_name(), ' linking to ', nextbin.GhostPads['sink'][i].get_name() # src.link(nextbin.GhostPads['sink'][i]) def on_bus_message(self, bus, message): self.pipeline_state = self.gst_state_map.get( int(self._pipeline.get_state()[1])) #print 'bus message: ', self.pipeline_state, self._pipeline.get_state() def start(self): self._pipeline.set_state(self._gst_module.STATE_PLAYING) def stop(self): self._pipeline.set_state(self._gst_module.STATE_NULL) self.pipeline_state = 'null'
class OSCSessionManager(BaseIO.BaseIO, Config): _confsection = "OSC" _Properties = {"oscMaster": dict(type=str)} def __init__(self, **kwargs): self.Manager = kwargs.get("Manager") self.ioManager = self.Manager.ioManager self.comm = self.Manager.comm self.root_node = self.Manager.root_node self.osc_tree = self.Manager.osc_tree BaseIO.BaseIO.__init__(self, **kwargs) Config.__init__(self, **kwargs) self.register_signal("client_added", "client_removed", "new_master") # self.oscMaster = None self.bind(oscMaster=self._on_oscMaster_set) self.set_master_timeout = None self.master_takeover_timer = None self.check_master_attempts = None self.local_client = None self.clients = ChildGroup( name="clients", osc_address="CLIENTS", osc_parent_node=self.root_node, child_class=Client, ignore_index=True ) self.clients_by_address = {} # self.root_node.addCallback('/getMaster', self.on_master_requested_by_osc) # self.root_node.addCallback('/setMaster', self.on_master_set_by_osc) # self.getMasterNode = self.root_node.add_child(name='getMaster') # self.getMasterNode.bind(message_received=self.on_master_requested_by_osc) # self.setMasterNode = self.root_node.add_child(name='setMaster') # self.setMasterNode.bind(message_received=self.on_master_set_by_osc) self.GLOBAL_CONFIG.bind(update=self.on_GLOBAL_CONFIG_update) if self.GLOBAL_CONFIG.get("osc_use_discovery", True): self.comm.ServiceConnector.connect("new_host", self.on_host_discovered) self.comm.ServiceConnector.connect("remove_host", self.on_host_removed) self.Manager.bind( master_priority=self._on_master_priority_set, session_name=self._on_session_name_set, ring_master=self._on_ring_master_set, ) @property def root_address(self): return self.Manager.root_address @property def local_name(self): if not self.local_client: return "-".join([self.GLOBAL_CONFIG.get("app_name"), socket.gethostname()]) return self.local_client.name @property def isMaster(self): return self.oscMaster == self.local_name @property def isRingMaster(self): return self.Manager.ring_master == self.local_name @property def master_priority(self): return self.Manager.master_priority @master_priority.setter def master_priority(self, value): self.Manager.master_priority = value @property def discovered_sessions(self): return self.Manager.discovered_sessions @property def session_name(self): return self.Manager.session_name @session_name.setter def session_name(self, value): self.Manager.session_name = value def determine_ring_master(self): masters = {} for session in self.discovered_sessions.itervalues(): m = session.master if m is None: continue # key = int(''.join([s.rjust(3, '0') for s in m.address.split('.')])) key = ip_to_int(m.address) masters[key] = m if not len(masters): return False master = masters[min(masters.keys())] if master.name != self.Manager.ring_master: self.Manager.ring_master = master.name return master def do_connect(self): serv = self.comm.ServiceConnector.add_service(**self.build_zeroconf_data()) self.comm.ServiceConnector.add_listener(stype="_osc._udp") self.connected = True self.check_for_master() def do_disconnect(self, **kwargs): self.set_master(False) self.connected = False def add_to_session(self, **kwargs): """ Adds a Client obj to a Session object which will handle master determination, etc. If the Session does not exist, one is created. """ name = kwargs.get("name") if name is None: return client = kwargs.get("client") clients = kwargs.get("clients", []) if client is not None: clients.append(client) sessions = self.discovered_sessions session = sessions.get(name) if session: for c in clients: session.add_member(c) else: prebind = dict(master=self.on_session_master_set, members_update=self.on_session_members_update) session = sessions.add_child(name=name, members=clients, prebind=prebind) def remove_from_session(self, **kwargs): """ Removes a Client object (or objects) from a Session object, if it exists. """ name = kwargs.get("name") client = kwargs.get("client") clients = kwargs.get("clients", []) if client is not None: clients.append(client) sessions = self.discovered_sessions session = sessions.get(name) if not session: return for c in clients: session.del_member(c) def add_client(self, **kwargs): kwargs.setdefault("port", self.ioManager.hostdata["sendport"]) kwargs.setdefault("app_address", self.Manager.app_address) # kwargs['osc_parent_node'] = self.client_osc_node if socket.gethostname() in kwargs.get("name", ""): kwargs["isLocalhost"] = True # kwargs['master_priority'] = self.master_priority client = self.clients.add_child(**kwargs) self.clients_by_address[client.address] = client if client.isLocalhost: self.local_client = client # client.master_priority = self.master_priority # print 'local_client session: ', client.session_name self.add_to_session(name=client.session_name, client=client) client.bind(property_changed=self.on_client_obj_property_changed) # if client.session_name is not None: # self.discovered_sessions.add(client.session_name) self.Manager.update_wildcards() # if self.check_master_attempts is None: # self.check_for_master(client=client.name) propkeys = client.Properties.keys() self.LOG.info("add_client:", dict(zip(propkeys, [client.Properties[key].value for key in propkeys]))) keys = ["name", "address", "port"] s_kwargs = dict(zip(keys, [getattr(client, key) for key in keys])) s_kwargs.update({"client": client}) self.emit("client_added", **s_kwargs) def remove_client(self, **kwargs): name = kwargs.get("name") client = self.clients.get(name) if client is None: return # self.remove_client_name(name, update_conf=False) # self.remove_client_address(addr, update_conf=False) client.unbind(self) self.clients.del_child(client) self.Manager.update_wildcards() self.LOG.info("remove_client:", name) self.emit("client_removed", name=name, client=client) if client.session_name is not None: self.remove_from_session(name=client.session_name, client=client) def on_session_master_set(self, **kwargs): session = kwargs.get("obj") value = kwargs.get("value") self.determine_ring_master() if session.name != self.session_name: return if session.master is None: m = self.determine_next_master() if m == self.local_client: self.set_master() if session.master.name == self.oscMaster: return if session.master != self.local_client: self.set_master(session.master.name) def on_session_members_update(self, **kwargs): session = kwargs.get("obj") mode = kwargs.get("mode") if mode == "remove": if not len(session.members): session.unbind(self) self.discovered_sessions.del_child(session) def on_client_obj_property_changed(self, **kwargs): prop = kwargs.get("Property") old = kwargs.get("old") value = kwargs.get("value") client = kwargs.get("obj") if prop.name == "isRingMaster" and value is True: if self.Manager.ring_master != client.name: self.Manager.ring_master = client.name elif prop.name == "session_name" and value is not None: self.add_to_session(name=value, client=client) def build_zeroconf_data(self): d = dict(name=self.local_name, stype="_osc._udp", port=self.Manager.ioManager.hostdata["recvport"]) txt = {"app_name": self.GLOBAL_CONFIG["app_name"]} # session = self.GLOBAL_CONFIG.get('session_name') # if session: # txt['session_name'] = session d["text"] = txt return d def build_curly_wildcard(self, l): return "{%s}" % (",".join(list(l))) def _on_master_priority_set(self, **kwargs): value = kwargs.get("value") # if self.local_client is not None: # self.local_client.master_priority = value self.GLOBAL_CONFIG["master_priority"] = value self.update_conf(master_priority=value) # data = self.build_zeroconf_data() # self.comm.ServiceConnector.update_service(**data) def _on_session_name_set(self, **kwargs): value = kwargs.get("value") # if self.local_client is not None: # self.local_client.session_name = value # self.local_client.isMaster = False # data = self.build_zeroconf_data() # self.comm.ServiceConnector.update_service(**data) # self.select_new_master() if self.local_client is not None: self.add_to_session(name=value, client=self.local_client) # self.local_client.session_name = value master = self.discovered_sessions[value].master if master is not None: master = master.name self.set_master(master) self.GLOBAL_CONFIG["session_name"] = value def on_GLOBAL_CONFIG_update(self, **kwargs): keys = kwargs.get("keys") if not keys: keys = [kwargs.get("key")] for key in ["master_priority", "session_name"]: if key not in keys: continue value = self.GLOBAL_CONFIG.get(key) if value != getattr(self, key): setattr(self, key, value) def on_host_discovered(self, **kwargs): host = kwargs.get("host") if "." not in host.address: return c_kwargs = host.hostdata.copy() c_kwargs.update({"discovered": True}) self.add_client(**c_kwargs) def on_host_removed(self, **kwargs): self.LOG.info("remove:", kwargs) id = kwargs.get("id") self.remove_client(name=id) def check_for_master(self, **kwargs): if self.connected and not self.isMaster: name = kwargs.get("name") # if self.check_master_attempts is None: # self.check_master_attempts = 0 # self.cancel_check_master_timer() self.set_master_timeout = threading.Timer(10.0, self.on_check_master_timeout) self.set_master_timeout.start() # new_kwargs = {}#{'address':'getMaster'} # if name: # new_kwargs.update({'client':name}) # element = self.getMasterNode.send_message(value=self.session_name, # all_sessions=True, # timetag=-1) # print 'sent getmaster: ', [str(element)] def on_check_master_timeout(self): self.set_master() return self.check_master_attempts += 1 if self.check_master_attempts == 3: self.check_master_attempts = None self.set_master() else: self.check_for_master() def set_master(self, name=None): self.cancel_check_master_timer() if self.master_takeover_timer: self.master_takeover_timer.cancel() if name is None: s = self.local_name elif name is False: s = None else: s = name if s != self.oscMaster: self.oscMaster = s if self.oscMaster is None: return lc = self.local_client if self.isMaster: if lc is not None: lc.isMaster = True else: if lc is not None: lc.isMaster = False m = self.determine_next_master() if m and m.isLocalhost and name is not False: self.LOG.info("master takeover in 10 seconds...") t = threading.Timer(10.0, self.on_master_takeover_timeout) self.master_takeover_timer = t t.start() self.LOG.info("master = ", self.oscMaster) self.determine_ring_master() self.emit("new_master", master=self.oscMaster, master_is_local=self.isMaster) def on_master_takeover_timeout(self): self.LOG.info("master takeover timer complete") self.master_takeover_timer = None m = self.determine_next_master() if not m: return if not self.isMaster and m.isLocalhost: self.set_master() def cancel_check_master_timer(self): if self.set_master_timeout and self.set_master_timeout.isAlive(): self.set_master_timeout.cancel() self.set_master_timeout = None def determine_next_master(self): session = self.discovered_sessions[self.session_name] d = {} for c in session.members.itervalues(): key = c.master_priority if key is None: continue if not (c.isSlave or c.isMaster or c.isLocalhost): continue if key in d and ip_to_int(c.address) > ip_to_int(d[key].address): continue d[key] = c self.LOG.info("clients by priority: ", d) if not len(d): return None return d[min(d)] def old_determine_next_master(self): d = {} for client in self.clients.itervalues(): if not client.isSameSession: continue key = client.master_priority if key is not None and (client.isSlave or client.isMaster or client.isLocalhost): if key in d: if d[key].name < client.name: d[key] = client else: d[key] = client self.LOG.info("clients by priority: ", d) if not len(d): return None return d[min(d)] def _on_ring_master_set(self, **kwargs): value = kwargs.get("value") self.LOG.info("RINGMASTER: ", value) self.local_client.isRingMaster = value == self.local_name self.Manager.ClockSync.isMaster = self.isRingMaster def _on_oscMaster_set(self, **kwargs): self.root_node.oscMaster = self.isMaster