def set_value(self, value): del self['value'] valXMLName = '{%s}value' % self.namespace if self._type == 'boolean': if value in self.true_values: valXML = ET.Element(valXMLName) valXML.text = '1' self.xml.append(valXML) else: valXML = ET.Element(valXMLName) valXML.text = '0' self.xml.append(valXML) elif self._type in self.multi_value_types or self._type in ('', None): if isinstance(value, bool): value = [value] if not isinstance(value, list): value = value.replace('\r', '') value = value.split('\n') for val in value: if self._type in ('', None) and val in self.true_values: val = '1' valXML = ET.Element(valXMLName) valXML.text = val self.xml.append(valXML) else: if isinstance(value, list): raise ValueError("Cannot add multiple values " + \ "to a %s field." % self._type) valXML = ET.Element(valXMLName) valXML.text = value self.xml.append(valXML)
def py2xml(*args): params = ET.Element("{%s}params" % _namespace) for x in args: param = ET.Element("{%s}param" % _namespace) param.append(_py2xml(x)) params.append(param) #<params><param>... return params
def setValue(self, value): self.delValue() valXMLName = '{%s}value' % self.namespace if self['type'] == 'boolean': if value in self.true_values: valXML = ET.Element(valXMLName) valXML.text = '1' self.xml.append(valXML) else: valXML = ET.Element(valXMLName) valXML.text = '0' self.xml.append(valXML) elif self['type'] in self.multi_value_types or self['type'] in [ '', None ]: if self['type'] in self.multi_line_types and isinstance( value, str): value = value.split('\n') if not isinstance(value, list): value = [value] for val in value: if self['type'] in ['', None] and val in self.true_values: val = '1' valXML = ET.Element(valXMLName) valXML.text = val self.xml.append(valXML) else: if isinstance(value, list): raise ValueError("Cannot add multiple values to a %s field." % self['type']) valXML = ET.Element(valXMLName) valXML.text = value self.xml.append(valXML)
def joinMUC(self, room, nick, maxhistory="0", password='', wait=False, pstatus=None, pshow=None, pfrom=None): """ Join the specified room, requesting 'maxhistory' lines of history. """ stanza = self.xmpp.makePresence(pto="%s/%s" % (room, nick), pstatus=pstatus, pshow=pshow, pfrom=pfrom) x = ET.Element('{http://jabber.org/protocol/muc}x') if password: passelement = ET.Element('{http://jabber.org/protocol/muc}password') passelement.text = password x.append(passelement) if maxhistory: history = ET.Element('{http://jabber.org/protocol/muc}history') if maxhistory == "0": history.attrib['maxchars'] = maxhistory else: history.attrib['maxstanzas'] = maxhistory x.append(history) stanza.append(x) if not wait: self.xmpp.send(stanza) else: #wait for our own room presence back expect = ET.Element("{%s}presence" % self.xmpp.default_ns, {'from':"%s/%s" % (room, nick)}) self.xmpp.send(stanza, expect) self.rooms[room] = {} self.ourNicks[room] = nick
def setAffiliation(self, room, jid=None, nick=None, affiliation='member', ifrom=None): """ Change room affiliation.""" if affiliation not in ('outcast', 'member', 'admin', 'owner', 'none'): raise TypeError query = ET.Element('{http://jabber.org/protocol/muc#admin}query') if nick is not None: item = ET.Element('{http://jabber.org/protocol/muc#admin}item', { 'affiliation': affiliation, 'nick': nick }) else: item = ET.Element('{http://jabber.org/protocol/muc#admin}item', { 'affiliation': affiliation, 'jid': jid }) query.append(item) iq = self.xmpp.makeIqSet(query) iq['to'] = room iq['from'] = ifrom # For now, swallow errors to preserve existing API try: result = iq.send() except IqError: return False except IqTimeout: return False return True
def set_items(self, items): """ Set the roster entries in the <roster> stanza. Uses a dictionary using JIDs as keys, where each entry is itself a dictionary that contains: name -- An alias or nickname for the JID. subscription -- The subscription type. Can be one of 'to', 'from', 'both', 'none', or 'remove'. groups -- A list of group names to which the JID has been assigned. Arguments: items -- A dictionary of roster entries. """ self.del_items() for jid in items: ijid = str(jid) item = ET.Element('{jabber:iq:roster}item', {'jid': ijid}) if 'subscription' in items[jid]: item.attrib['subscription'] = items[jid]['subscription'] if 'name' in items[jid]: name = items[jid]['name'] if name is not None: item.attrib['name'] = name if 'groups' in items[jid]: for group in items[jid]['groups']: groupxml = ET.Element('{jabber:iq:roster}group') groupxml.text = group item.append(groupxml) self.xml.append(item) return self
def cancelConfig(self, room, ifrom=None): query = ET.Element('{http://jabber.org/protocol/muc#owner}query') x = ET.Element('{jabber:x:data}x', type='cancel') query.append(x) iq = self.xmpp.makeIqSet(query) iq['to'] = room iq['from'] = ifrom iq.send()
def to_xml(self): ctl = ET.Element('ctl', {'td': self.name}) for key, value in self.args.items(): if type(value) is dict: inner = ET.Element(key, value) ctl.append(inner) else: ctl.set(key, value) return ctl
def getUsersByAffiliation(cls, room, affiliation='member', ifrom=None): if affiliation not in ('outcast', 'member', 'admin', 'owner', 'none'): raise TypeError query = ET.Element('{http://jabber.org/protocol/muc#admin}query') item = ET.Element('{http://jabber.org/protocol/muc#admin}item', {'affiliation': affiliation}) query.append(item) iq = cls.xmpp.Iq(sto=room, sfrom=ifrom, stype='get') iq.append(query) return iq.send()
def add_item(self, values): item = ET.Element('{%s}item' % self.namespace) self.xml.append(item) for var in self['reported']: field_xml = ET.Element('{%s}field' % self.namespace) item.append(field_xml) field = FormField(xml=field_xml) field['var'] = var field['value'] = str(values.get(var, ''))
def set_users(self, values): users = self.xml.find('{%s}users' % self.namespace) if users is None: users = ET.Element('{%s}users' % self.namespace) self.xml.append(users) for resource in values: res = ET.Element('{%s}resource' % self.namespace) res.text = resource users.append(res)
def add_item(self, values): itemXML = ET.Element('{%s}item' % self.namespace) self.xml.append(itemXML) reported_vars = self['reported'].keys() for var in reported_vars: fieldXML = ET.Element('{%s}field' % FormField.namespace) itemXML.append(fieldXML) field = FormField(xml=fieldXML) field['var'] = var field['value'] = values.get(var, None)
def copy_dialog_id(self, origin_message, new_message): """ Copy a dialog_id from a received message to a replay message """ dialog_id_in = origin_message.xml.find('{jabber:client}extraParams/{jabber:client}dialog_id') if dialog_id_in is not None: extra_params_out = ET.Element('{jabber:client}extraParams') dialog_id_out = ET.Element('{}dialog_id') dialog_id_out.text = dialog_id_in.text extra_params_out.append(dialog_id_out) new_message.append(extra_params_out)
def prepRSM(page): rsm = ET.Element("{%s}set" % RSM_NS) max = ET.Element("max") max.text = str(RPP) rsm.append(max) index = ET.Element("index") index.text = str(page * RPP) rsm.append(index) return rsm
def invite(self, room, jid, reason='', mfrom=''): """ Invite a jid to a room.""" msg = self.xmpp.makeMessage(room) msg['from'] = mfrom x = ET.Element('{http://jabber.org/protocol/muc#user}x') invite = ET.Element('{http://jabber.org/protocol/muc#user}invite', {'to': jid}) if reason: rxml = ET.Element('{http://jabber.org/protocol/muc#user}reason') rxml.text = reason invite.append(rxml) x.append(invite) msg.append(x) self.xmpp.send(msg)
def send_command(self, device, command): """Send a simple command to the Harmony Hub. Args: device_id (str): Device ID from Harmony Hub configuration to control command (str): Command from Harmony Hub configuration to control Returns: None if successful """ iq_cmd = self.Iq() iq_cmd['type'] = 'get' iq_cmd['id'] = '5e518d07-bcc2-4634-ba3d-c20f338d8927-2' action_cmd = ET.Element('oa') action_cmd.attrib['xmlns'] = 'connect.logitech.com' action_cmd.attrib['mime'] = ( 'vnd.logitech.harmony/vnd.logitech.harmony.engine?holdAction') action_cmd.text = 'action={"type"::"IRCommand","deviceId"::"' + device + '","command"::"' + command + '"}:status=press' iq_cmd.set_payload(action_cmd) result = iq_cmd.send(block=False) action_cmd.attrib['mime'] = ( 'vnd.logitech.harmony/vnd.logitech.harmony.engine?holdAction') action_cmd.text = 'action={"type"::"IRCommand","deviceId"::"' + device + '","command"::"' + command + '"}:status=release' iq_cmd.set_payload(action_cmd) result = iq_cmd.send(block=False) return result
def fault2xml(fault): value = dict() value['faultCode'] = fault['code'] value['faultString'] = fault['string'] fault = ET.Element("fault", {'xmlns': _namespace}) fault.append(_py2xml((value))) return fault
def del_chat_state(self): parent = self.parent() for state in self.states: state_xml = parent.find('{%s}%s' % (self.namespace, state)) if state_xml is not None: self.xml = ET.Element('') parent.xml.remove(state_xml)
def change_channel(self, channel): """Changes a channel. Args: channel: Channel number Returns: An HTTP 200 response (hopefully) """ iq_cmd = self.Iq() iq_cmd['type'] = 'get' action_cmd = ET.Element('oa') action_cmd.attrib['xmlns'] = 'connect.logitech.com' action_cmd.attrib['mime'] = ('harmony.engine?changeChannel') cmd = 'channel=' + str(channel) + ':timestamp=0' action_cmd.text = cmd iq_cmd.set_payload(action_cmd) try: result = iq_cmd.send(block=True) except Exception: logger.info('XMPP timeout, reattempting') result = iq_cmd.send(block=True) payload = result.get_payload() assert len(payload) == 1 action_cmd = payload[0] if action_cmd.text == None: return True else: return False
def get_config(self): """Retrieves the Harmony device configuration. Returns: A nested dictionary containing activities, devices, etc. """ iq_cmd = self.Iq() iq_cmd['type'] = 'get' action_cmd = ET.Element('oa') action_cmd.attrib['xmlns'] = 'connect.logitech.com' action_cmd.attrib['mime'] = ( 'vnd.logitech.harmony/vnd.logitech.harmony.engine?config') iq_cmd.set_payload(action_cmd) retries = 3 attempt = 0 for _ in range(retries): try: result = iq_cmd.send(block=True) break except Exception: logger.critical('XMPP timeout, reattempting') attempt += 1 pass if attempt == 3: raise ValueError('XMPP timeout with hub') payload = result.get_payload() assert len(payload) == 1 action_cmd = payload[0] assert action_cmd.attrib['errorcode'] == '200' device_list = action_cmd.text return json.loads(device_list)
def add_item( self, player, rating, highest_rating=0, # pylint: disable=too-many-arguments rank=0, total_games_played=0, wins=0, losses=0): """Add an item to the extension. Arguments: player (str): Name of the player rating (int): Current rating of the player highest_rating (int): Highest rating the player had rank (int): Rank of the player total_games_played (int): Total number of games the player played wins (int): Number of won games the player had losses (int): Number of lost games the player had """ item_xml = ET.Element( 'profile', { 'player': player, 'rating': str(rating), 'highestRating': str(highest_rating), 'rank': str(rank), 'totalGamesPlayed': str(total_games_played), 'wins': str(wins), 'losses': str(losses) }) self.xml.append(item_xml)
def add_identity(self, category, itype, name=None, lang=None): """ Add a new identity element. Each identity must be unique in terms of all four identity components. Multiple, identical category/type pairs are allowed only if the xml:lang values are different. Likewise, multiple category/type/xml:lang pairs are allowed so long as the names are different. In any case, a category and type are required. Arguments: category -- The general category to which the agent belongs. itype -- A more specific designation with the category. name -- Optional human readable name for this identity. lang -- Optional standard xml:lang value. """ identity = (category, itype, lang) if identity not in self._identities: self._identities.add(identity) id_xml = ET.Element('{%s}identity' % self.namespace) id_xml.attrib['category'] = category id_xml.attrib['type'] = itype if lang: id_xml.attrib['{%s}lang' % self.xml_ns] = lang if name: id_xml.attrib['name'] = name self.xml.append(id_xml) return True return False
def set_items(self, values): self.del_items() for jid in values: if jid: item = ET.Element('{%s}item' % self.namespace) item.attrib['jid'] = JID(jid).full self.xml.append(item)
def get_current_activity(self): """Retrieves the current activity ID. Returns: A int with the current activity ID. """ iq_cmd = self.Iq() iq_cmd['type'] = 'get' action_cmd = ET.Element('oa') action_cmd.attrib['xmlns'] = 'connect.logitech.com' action_cmd.attrib['mime'] = ( 'vnd.logitech.harmony/vnd.logitech.harmony.engine?getCurrentActivity' ) iq_cmd.set_payload(action_cmd) try: result = iq_cmd.send(block=True) except Exception: logger.info('XMPP timeout, reattempting') result = iq_cmd.send(block=True) payload = result.get_payload() assert len(payload) == 1 action_cmd = payload[0] assert action_cmd.attrib['errorcode'] == '200' activity = action_cmd.text.split("=") return int(activity[1])
def set_binval(self, value): self.del_binval() parent = self.parent() if value: xml = ET.Element('{%s}BINVAL' % self.namespace) xml.text = bytes(base64.b64encode(value)).decode('utf-8') parent.append(xml)
def _handle_bind_resource(self, xml): """ Handle requesting a specific resource. Arguments: xml -- The bind feature element. """ log.debug("Requesting resource: %s" % self.boundjid.resource) xml.clear() iq = self.Iq(stype='set') if self.boundjid.resource: res = ET.Element('resource') res.text = self.boundjid.resource xml.append(res) iq.append(xml) response = iq.send() bind_ns = 'urn:ietf:params:xml:ns:xmpp-bind' self.set_jid( response.xml.find('{%s}bind/{%s}jid' % (bind_ns, bind_ns)).text) self.bound = True log.info("Node set to: %s" % self.boundjid.fulljid) session_ns = 'urn:ietf:params:xml:ns:xmpp-session' if "{%s}session" % session_ns not in self.features or self.bindfail: log.debug("Established Session") self.sessionstarted = True self.session_started_event.set() self.event("session_start")
def get_config(self): """Retrieves the Harmony device configuration. Returns: A nested dictionary containing activities, devices, etc. """ iq_cmd = self.Iq() iq_cmd['type'] = 'get' action_cmd = ET.Element('oa') action_cmd.attrib['xmlns'] = 'connect.logitech.com' action_cmd.attrib['mime'] = ( 'vnd.logitech.harmony/vnd.logitech.harmony.engine?config') iq_cmd.set_payload(action_cmd) result = iq_cmd.send(block=True) payload = result.get_payload() assert len(payload) == 1 action_cmd = payload[0] assert action_cmd.attrib['errorcode'] == '200' device_list = action_cmd.text config_dict = json.loads(device_list) s = '' for activity in config_dict['activity']: if 'activityOrder' in activity: s += 'Activity: ' + activity['label'] + ', #' + repr( activity['activityOrder'] ) + ', id: ' + activity['id'] + '\n' else: s += 'Activity: ' + activity['label'] + ', id: ' + activity[ 'id'] + '\n' for device in config_dict['device']: s += 'Device: ' + device['label'] + ', id: ' + device['id'] + '\n' return s
def add_reported(self, var, ftype=None, label='', desc='', **kwargs): kwtype = kwargs.get('type', None) if kwtype is None: kwtype = ftype reported = self.xml.find('{%s}reported' % self.namespace) if reported is None: reported = ET.Element('{%s}reported' % self.namespace) self.xml.append(reported) fieldXML = ET.Element('{%s}field' % FormField.namespace) reported.append(fieldXML) field = FormField(xml=fieldXML) field['var'] = var field['type'] = kwtype field['label'] = label field['desc'] = desc return field
def add_game(self, data): """Add a game to the extension. Arguments: data (dict): game data to add """ self.xml.append(ET.Element('game', data))
def start_activity(self, activity_id): """Starts an activity. Args: activity_id: An int or string identifying the activity to start Returns: True if activity started, otherwise False """ iq_cmd = self.Iq() iq_cmd['type'] = 'get' action_cmd = ET.Element('oa') action_cmd.attrib['xmlns'] = 'connect.logitech.com' action_cmd.attrib['mime'] = ('harmony.engine?startactivity') cmd = 'activityId=' + str(activity_id) + ':timestamp=0' action_cmd.text = cmd iq_cmd.set_payload(action_cmd) try: result = iq_cmd.send(block=True) except Exception: logger.info('XMPP timeout, reattempting') result = iq_cmd.send(block=True) payload = result.get_payload() assert len(payload) == 1 action_cmd = payload[0] if action_cmd.text == None: return True else: return False