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 join_muc(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.make_presence(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.our_nicks[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.make_iq_set(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_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 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.make_iq_set(query) iq['to'] = room iq['from'] = ifrom iq.send()
def set_types(self, value): del self['types'] for type_ in value: if type_ == 'emphasis': self.xml.append(ET.Element('{urn:xmpp:markup:0}emphasis')) elif type_ == 'code': self.xml.append(ET.Element('{urn:xmpp:markup:0}code')) elif type_ == 'deleted': self.xml.append(ET.Element('{urn:xmpp:markup:0}deleted'))
def get_users_by_affiliation(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 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 invite(self, room, jid, reason='', mfrom=''): """ Invite a jid to a room.""" msg = self.xmpp.make_message(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)
async def publish(self, server, node, entry): iq = self.Iq(stype="set", sto=server) iq['pubsub']['publish']['node'] = node item = pubsub.Item() # character / is causing a bug in movim. replacing : and , with - in id. It provides nicer urls. rex = re.compile(r'[:,\/]') item['id'] = rex.sub('-', str(entry.id)) ent = ET.Element("entry") ent.set('xmlns', NS_ATOM) title = ET.SubElement(ent, "title") title.text = entry.title updated = ET.SubElement(ent, "updated") updated.text = entry.updated if hasattr(entry.content[0], 'type'): content = ET.SubElement(ent, "content") content.set('type', entry.content[0].type) content.text = entry.content[0].value if hasattr(entry, 'links'): for l in entry.links: link = ET.SubElement(ent, "link") link.set('href', l['href']) link.set('type', l['type']) link.set('rel', l['rel']) if hasattr(entry, 'tags'): for t in entry.tags: tag = ET.SubElement(ent, "category") tag.set('term', t.term) if hasattr(entry, 'authors'): author = ET.SubElement(ent, "author") name = ET.SubElement(author, "name") name.text = entry.authors[0].name if hasattr(entry.authors[0], 'href'): uri = ET.SubElement(author, "uri") uri.text = entry.authors[0].href item['payload'] = ent iq['pubsub']['publish'].append(item) task = iq.send(timeout=5) try: await task except (IqError, IqTimeout) as e: print(e) pass
async def send_request(self, mime, command=None, block=True): iq_cmd = self.Iq() iq_cmd['type'] = 'get' action_cmd = ET.Element('oa') action_cmd.attrib['xmlns'] = XMLNS action_cmd.attrib['mime'] = mime if command is not None: action_cmd.text = command iq_cmd.set_payload(action_cmd) try: if block: result = await iq_cmd.send() else: iq_cmd.send() except (IqError, IqTimeout): raise HarmonyException('Error sending command to hub') if block: payload = result.get_payload() if len(payload) != 1: raise HarmonyException('Bad payload from hub') response = payload[0] result_code = response.attrib['errorcode'] if result_code != '200': raise HarmonyException( 'Bad response code from hub: {0}'.format(result_code) ) return response.text
def testGetItems(self): """Test retrieving items from a roster stanza.""" xml_string = """ <iq> <query xmlns="jabber:iq:roster"> <item jid="*****@*****.**" name="User" subscription="both"> <group>Friends</group> <group>Coworkers</group> </item> <item jid="*****@*****.**" name="Other User" subscription="both" /> </query> </iq> """ iq = self.Iq(ET.fromstring(xml_string)) expected = { '*****@*****.**': { 'name': 'User', 'subscription': 'both', 'ask': '', 'approved': '', 'groups': ['Friends', 'Coworkers']}, '*****@*****.**': { 'name': 'Other User', 'subscription': 'both', 'ask': '', 'approved': '', 'groups': []}} debug = "Roster items don't match after retrieval." debug += "\nReturned: %s" % str(iq['roster']['items']) debug += "\nExpected: %s" % str(expected) self.assertTrue(iq['roster']['items'] == expected, debug)
def publish(self): payload = ET.fromstring("<test xmlns='test'>%s</test>" % self.data) try: result = yield from self['xep_0060'].publish(self.pubsub_server, self.node, payload=payload) logging.info('Published at item id: %s', result['pubsub']['publish']['item']['id']) except XMPPError as error: logging.error('Could not publish to %s: %s', self.node, error.format())
def fault2xml(code: int, message: str) -> ET.Element: value: Dict[str, Any] = dict() value["faultCode"] = code value["faultString"] = message fault = ET.Element("fault", {"xmlns": _namespace}) fault.append(_py2xml((value, ))) return fault
def set_item_attr(self, attr, value: str): item = self.xml.find(f'{{{NS_USER}}}item') if item is None: item = ET.Element(f'{{{NS_USER}}}item') self.xml.append(item) item.attrib[attr] = value return item
def testGetItems(self): """Test retrieving items from a roster stanza.""" xml_string = """ <iq> <query xmlns="jabber:iq:roster"> <item jid="*****@*****.**" name="User" subscription="both"> <group>Friends</group> <group>Coworkers</group> </item> <item jid="*****@*****.**" name="Other User" subscription="both" /> </query> </iq> """ iq = self.Iq(ET.fromstring(xml_string)) expected = { '*****@*****.**': { 'name': 'User', 'subscription': 'both', 'ask': '', 'approved': '', 'groups': ['Friends', 'Coworkers'] }, '*****@*****.**': { 'name': 'Other User', 'subscription': 'both', 'ask': '', 'approved': '', 'groups': [] } } debug = "Roster items don't match after retrieval." debug += "\nReturned: %s" % str(iq['roster']['items']) debug += "\nExpected: %s" % str(expected) self.failUnless(iq['roster']['items'] == expected, debug)
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 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
async def hub_send(self, command, iq_type='get', params=None, msgid=None) -> \ Optional[str]: """Send a payload request to Harmony Hub and return json response.""" # Make sure we're connected. if not await self.hub_connect(): return def result_callback(future_result): # This is done to ensure that any time out exceptions are # captured try: future_result.result() except IqTimeout: pass if not msgid: msgid = str(uuid4()) if iq_type == 'query': iq_stanza = self.make_iq_query() elif iq_type == 'set': iq_stanza = self.make_iq_set() elif iq_type == 'result': iq_stanza = self.make_iq_result() elif iq_type == 'error': iq_stanza = self.make_iq_error(id=msgid) else: iq_stanza = self.make_iq_get() iq_stanza['id'] = msgid payload = ET.Element('oa') payload.attrib['xmlns'] = DEFAULT_NS payload.attrib['mime'] = command payload_text = None for key in params: if payload_text is None: payload_text = key + '=' + str(params[key]) else: payload_text = payload_text + ':' + \ key + '=' + str(params[key]) payload.text = payload_text iq_stanza.set_payload(payload) _LOGGER.debug("%s: Sending payload: %s %s", self._ip_address, payload.attrib, payload.text) result = iq_stanza.send(timeout=1) # Add done callback to capture any timeout exceptions. result.add_done_callback(result_callback) return msgid
async def get_token(self): """Called when the XMPP session has been initialized.""" 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.connect/vnd.logitech.pair' action_cmd.text = 'method=pair:name={0}'.format('pyharmony#iOS10.1#iPhone') iq_cmd.set_payload(action_cmd) result = await iq_cmd.send() payload = result.get_payload() if len(payload) != 1: raise HarmonyException('Bad payload from hub') response = payload[0] result_code = response.attrib['errorcode'] if result_code != '200': raise HarmonyException( 'Bad response code from hub: {0}'.format(result_code) ) match = re.search(r'identity=(?P<uuid>[\w-]+):status', response.text) if not match: raise HarmonyException( 'Token not found in response' ) return match.group('uuid')
async def publish(self): payload = ET.fromstring("<test xmlns='test'>%s</test>" % self.data) try: result = await self['xep_0060'].publish(self.pubsub_server, self.node, payload=payload) logging.info('Published at item id: %s', result['pubsub']['publish']['item']['id']) except XMPPError as error: logging.error('Could not publish to %s: %s', self.node, error.format())
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 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.insert(0, id_xml) return True return False
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 set_item_attr(self, attr, value): item = self.xml.find('{http://jabber.org/protocol/muc#user}item') if item is None: item = ET.Element('{http://jabber.org/protocol/muc#user}item') self.xml.append(item) item.attrib[attr] = value return item
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 setRole(self, room, nick, role): """ Change role property of a nick in a room. Typically, roles are temporary (they last only as long as you are in the room), whereas affiliations are permanent (they last across groupchat sessions). """ if role not in ('moderator', 'participant', 'visitor', 'none'): raise TypeError query = ET.Element('{http://jabber.org/protocol/muc#admin}query') item = ET.Element('item', {'role': role, 'nick': nick}) query.append(item) iq = self.xmpp.make_iq_set(query) iq['to'] = room result = iq.send() if result is False or result['type'] != 'result': raise ValueError return True
def set_chat_state(self, state): self.del_chat_state() parent = self.parent() if state in self.states: self.xml = ET.Element('{%s}%s' % (self.namespace, state)) parent.append(self.xml) elif state not in [None, '']: raise ValueError('Invalid chat state')
def peer_forward_msg(self, plugin, peer, msg, timeout=None): distribution = pkg_resources.get_distribution( plugin.__class__.__module__) iq = self.make_iq_set(ito=peer.jid) query = ET.Element("{%s}query" % PeerCommand.namespace) plugin_et = ET.Element("plugin") plugin_et.set('name', distribution.project_name) plugin_et.set('version', distribution.version) query.append(plugin_et) command_et = ET.Element("command") command_et.set('from', msg['mucnick']) command_et.text = msg['body'] query.append(command_et) iq.xml.append(query) return asyncio.ensure_future(iq.send(timeout=timeout))
def set_room_config(self, room, config, ifrom=''): query = ET.Element('{http://jabber.org/protocol/muc#owner}query') config['type'] = 'submit' query.append(config) iq = self.xmpp.make_iq_set(query) iq['to'] = room iq['from'] = ifrom iq.send()
def setRoomConfig(self, room, config, ifrom=''): query = ET.Element('{http://jabber.org/protocol/muc#owner}query') x = config.getXML('submit') query.append(x) iq = self.xmpp.make_iq_set(query) iq['to'] = room iq['from'] = ifrom iq.send()
def set_mechanisms(self, values): """ """ self.del_mechanisms() for val in values: mech = ET.Element('{%s}mechanism' % self.namespace) mech.text = val self.append(mech)
def testMailBox(self): """Testing reading from Gmail mailbox result""" # Use the example from Google's documentation at # http://code.google.com/apis/talk/jep_extensions/gmail.html#notifications xml = ET.fromstring(""" <iq type="result"> <mailbox xmlns="google:mail:notify" result-time='1118012394209' url='http://mail.google.com/mail' total-matched='95' total-estimate='0'> <mail-thread-info tid='1172320964060972012' participation='1' messages='28' date='1118012394209' url='http://mail.google.com/mail?view=cv'> <senders> <sender name='Me' address='*****@*****.**' originator='1' /> <sender name='Benvolio' address='*****@*****.**' /> <sender name='Mercutio' address='*****@*****.**' unread='1'/> </senders> <labels>act1scene3</labels> <subject>Put thy rapier up.</subject> <snippet>Ay, ay, a scratch, a scratch; marry, 'tis enough.</snippet> </mail-thread-info> </mailbox> </iq> """) iq = self.Iq(xml=xml) mailbox = iq['mailbox'] self.assertTrue(mailbox['result-time'] == '1118012394209', "result-time doesn't match") self.assertTrue(mailbox['url'] == 'http://mail.google.com/mail', "url doesn't match") self.assertTrue(mailbox['matched'] == '95', "total-matched incorrect") self.assertTrue(mailbox['estimate'] == False, "total-estimate incorrect") self.assertTrue(len(mailbox['threads']) == 1, "could not extract message threads") thread = mailbox['threads'][0] self.assertTrue(thread['tid'] == '1172320964060972012', "thread tid doesn't match") self.assertTrue(thread['participation'] == '1', "thread participation incorrect") self.assertTrue(thread['messages'] == '28', "thread message count incorrect") self.assertTrue(thread['date'] == '1118012394209', "thread date doesn't match") self.assertTrue(thread['url'] == 'http://mail.google.com/mail?view=cv', "thread url doesn't match") self.assertTrue(thread['labels'] == 'act1scene3', "thread labels incorrect") self.assertTrue(thread['subject'] == 'Put thy rapier up.', "thread subject doesn't match") self.assertTrue(thread['snippet'] == "Ay, ay, a scratch, a scratch; marry, 'tis enough.", "snippet doesn't match") self.assertTrue(len(thread['senders']) == 3, "could not extract senders") sender1 = thread['senders'][0] self.assertTrue(sender1['name'] == 'Me', "sender name doesn't match") self.assertTrue(sender1['address'] == '*****@*****.**', "sender address doesn't match") self.assertTrue(sender1['originator'] == True, "sender originator incorrect") self.assertTrue(sender1['unread'] == False, "sender unread incorrectly True") sender2 = thread['senders'][2] self.assertTrue(sender2['unread'] == True, "sender unread incorrectly False")
def set_body(self, content, lang=None): if lang is None: lang = self.get_lang() self.del_body(lang) if lang == '*': for sublang, subcontent in content.items(): self.set_body(subcontent, sublang) else: if isinstance(content, type(ET.Element('test'))): content = unicode(ET.tostring(content)) else: content = unicode(content) header = '<body xmlns="%s"' % XHTML_NS if lang: header = '%s xml:lang="%s"' % (header, lang) content = '%s>%s</body>' % (header, content) xhtml = ET.fromstring(content) self.xml.append(xhtml)
def testGetBeforeVal(self): xml_string = """ <set xmlns="http://jabber.org/protocol/rsm"> <before>id</before> </set> """ s = Set(ET.fromstring(xml_string)) expected = 'id' self.assertTrue(s['before'] == expected)
def testGetBefore(self): xml_string = """ <set xmlns="http://jabber.org/protocol/rsm"> <before /> </set> """ s = Set(ET.fromstring(xml_string)) expected = True self.failUnless(s['before'] == expected)
def testGetFirstIndex(self): xml_string = """ <set xmlns="http://jabber.org/protocol/rsm"> <first index="10">id</first> </set> """ s = Set(ET.fromstring(xml_string)) expected = '10' self.assertTrue(s['first_index'] == expected)
def publish(self): payload = ET.fromstring("<test xmlns='test'>%s</test>" % self.data) future, callback = make_callback() try: self["xep_0060"].publish(self.pubsub_server, self.node, payload=payload, callback=callback) result = yield from future id = result["pubsub"]["publish"]["item"]["id"] print("Published at item id: %s" % id) except: logging.error("Could not publish to: %s" % self.node)
def testGetBeforeVal(self): xml_string = """ <set xmlns="http://jabber.org/protocol/rsm"> <before>id</before> </set> """ s = Set(ET.fromstring(xml_string)) del s['before'] self.check(s, """ <set xmlns="http://jabber.org/protocol/rsm"> </set> """)
def xhtml_to_poezio_colors(xml, force=False, tmp_dir=None, extract_images=None): if isinstance(xml, str): xml = xml.encode('utf8') elif not isinstance(xml, bytes): xml = ET.tostring(xml) handler = XHTMLHandler(force_ns=force, tmp_dir=tmp_dir, extract_images=extract_images) parser = sax.make_parser() parser.setFeature(sax.handler.feature_namespaces, True) parser.setContentHandler(handler) parser.parse(BytesIO(xml)) return handler.result
def testDelFirstIndex(self): xml_string = """ <set xmlns="http://jabber.org/protocol/rsm"> <first index="10">id</first> </set> """ s = Set(ET.fromstring(xml_string)) del s['first_index'] self.check(s, """ <set xmlns="http://jabber.org/protocol/rsm"> <first>id</first> </set> """)
def testInvalidBase64PrefixEqual(self): """ Test detecting invalid base64 data with = as a prefix to the character data. """ iq = Iq(xml=ET.fromstring(""" <iq type="set" id="0" to="tester@localhost"> <data xmlns="http://jabber.org/protocol/ibb" seq="0"> =ABCDEFGH </data> </iq> """)) errored = False try: data = iq['ibb_data']['data'] except XMPPError: errored = True self.assertTrue(errored, "=ABCDEFGH did not raise base64 error")
def parse_xml(self, xml_string): try: xml = ET.fromstring(xml_string) return xml except (SyntaxError, ExpatError) as e: msg = e.msg if hasattr(e, 'msg') else e.message if 'unbound' in msg: known_prefixes = { 'stream': 'http://etherx.jabber.org/streams'} prefix = xml_string.split('<')[1].split(':')[0] if prefix in known_prefixes: xml_string = '<fixns xmlns:%s="%s">%s</fixns>' % ( prefix, known_prefixes[prefix], xml_string) xml = self.parse_xml(xml_string) xml = list(xml)[0] return xml else: self.fail("XML data was mal-formed:\n%s" % xml_string)
def testInvalidBase64Alphabet(self): """ Test detecting invalid base64 data with characters outside of the base64 alphabet. """ iq = Iq(xml=ET.fromstring(""" <iq type="set" id="0" to="tester@localhost"> <data xmlns="http://jabber.org/protocol/ibb" seq="0"> ABCD?EFGH </data> </iq> """)) errored = False try: data = iq['ibb_data']['data'] except XMPPError: errored = True self.assertTrue(errored, "ABCD?EFGH did not raise base64 error")
def testDelItems(self): """Test clearing items from a roster stanza.""" xml_string = """ <iq> <query xmlns="jabber:iq:roster"> <item jid="*****@*****.**" name="User" subscription="both"> <group>Friends</group> <group>Coworkers</group> </item> <item jid="*****@*****.**" name="Other User" subscription="both" /> </query> </iq> """ iq = self.Iq(ET.fromstring(xml_string)) del iq['roster']['items'] self.check(iq, """ <iq> <query xmlns="jabber:iq:roster" /> </iq> """)
def to_xhtml_im(self, body, markup_elem): chunks = self._split_first_level(body, markup_elem) final = [] stack = [] for chunk in chunks: if isinstance(chunk, str): chunk = (chunk.replace("&", '&') .replace('<', '<') .replace('>', '>') .replace('"', '"') .replace("'", ''') .replace('\n', '<br/>')) final.append(chunk) continue num_end = 0 for elem in chunk: if isinstance(elem, End): num_end += 1 for i in range(num_end): stack_top = stack.pop() for elem in chunk: if not isinstance(elem, End): continue elem = elem.elem if elem is stack_top: if isinstance(elem, Span): final.append('</span>') elif isinstance(elem, BlockCode): final.append('</code></pre>') elif isinstance(elem, List): final.append('</ul>') elif isinstance(elem, Li): final.append('</li>') elif isinstance(elem, BlockQuote): final.append('</blockquote>') break else: assert False for elem in chunk: if not isinstance(elem, Start): continue elem = elem.elem stack.append(elem) if isinstance(elem, Span): style = [] for type_ in elem['types']: if type_ == 'emphasis': style.append('font-style: italic;') if type_ == 'code': style.append('font-family: monospace;') if type_ == 'deleted': style.append('text-decoration: line-through;') final.append("<span style='%s'>" % ' '.join(style)) elif isinstance(elem, BlockCode): final.append('<pre><code>') elif isinstance(elem, List): final.append('<ul>') elif isinstance(elem, Li): final.append('<li>') elif isinstance(elem, BlockQuote): final.append('<blockquote>') p = "<p xmlns='http://www.w3.org/1999/xhtml'>%s</p>" % ''.join(final) p2 = ET.fromstring(p) print('coucou', p, tostring(p2)) xhtml_im = XHTML_IM() xhtml_im['body'] = p2 return xhtml_im
def _extract_method(self, stanza): xml = ET.fromstring("%s" % stanza) return xml.find("./methodCall/methodName").text
def __init__(self): keyfile = config.get('keyfile') certfile = config.get('certfile') device_id = config.get('device_id') if not device_id: rng = random.SystemRandom() device_id = base64.urlsafe_b64encode( rng.getrandbits(24).to_bytes(3, 'little')).decode('ascii') config.set_and_save('device_id', device_id) if config.get('jid'): # Field used to know if we are anonymous or not. # many features will be handled differently # depending on this setting self.anon = False jid = config.get('jid') password = config.get('password') eval_password = config.get('eval_password') if not password and not eval_password and not (keyfile and certfile): password = getpass.getpass() elif not password and not (keyfile and certfile): sys.stderr.write( "No password or certificates provided, using the eval_password command.\n" ) process = subprocess.Popen( ['sh', '-c', eval_password], stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True) code = process.wait() if code != 0: sys.stderr.write( 'The eval_password command (%s) returned a ' 'nonzero status code: %s.\n' % (eval_password, code)) sys.stderr.write('Poezio will now exit\n') sys.exit(code) password = process.stdout.readline().decode('utf-8').strip( '\n') else: # anonymous auth self.anon = True jid = config.get('server') password = None jid = safeJID(jid) jid.resource = '%s-%s' % ( jid.resource, device_id) if jid.resource else 'poezio-%s' % device_id # TODO: use the system language slixmpp.ClientXMPP.__init__( self, jid, password, lang=config.get('lang')) force_encryption = config.get('force_encryption') if force_encryption: self['feature_mechanisms'].unencrypted_plain = False self['feature_mechanisms'].unencrypted_digest = False self['feature_mechanisms'].unencrypted_cram = False self['feature_mechanisms'].unencrypted_scram = False self.keyfile = config.get('keyfile') self.certfile = config.get('certfile') if keyfile and not certfile: log.error( 'keyfile is present in configuration file without certfile') elif certfile and not keyfile: log.error( 'certfile is present in configuration file without keyfile') self.core = None self.auto_reconnect = config.get('auto_reconnect') self.auto_authorize = None # prosody defaults, lowest is AES128-SHA, it should be a minimum # for anything that came out after 2002 self.ciphers = config.get( 'ciphers', 'HIGH+kEDH:HIGH+kEECDH:HIGH:!PSK' ':!SRP:!3DES:!aNULL') self.ca_certs = config.get('ca_cert_path') or None interval = config.get('whitespace_interval') if int(interval) > 0: self.whitespace_keepalive_interval = int(interval) else: self.whitespace_keepalive = False self.register_plugin('xep_0004') self.register_plugin('xep_0012') # Must be loaded before 0030. self.register_plugin( 'xep_0115', { 'caps_node': 'https://poez.io', 'cache': FileSystemCache( str(xdg.CACHE_HOME), 'caps', encode=str, decode=lambda x: DiscoInfo(ET.fromstring(x))), }) self.register_plugin('xep_0030') self.register_plugin('xep_0045') self.register_plugin('xep_0048') self.register_plugin('xep_0050') self.register_plugin('xep_0054') self.register_plugin('xep_0060') self.register_plugin('xep_0066') self.register_plugin('xep_0070') self.register_plugin('xep_0071') self.register_plugin('xep_0077') self.plugin['xep_0077'].create_account = False self.register_plugin('xep_0084') self.register_plugin('xep_0085') self.register_plugin('xep_0153') # monkey-patch xep_0184 to avoid requesting receipts for messages # without a body XEP_0184._filter_add_receipt_request = fixes._filter_add_receipt_request self.register_plugin('xep_0184') self.plugin['xep_0184'].auto_ack = config.get('ack_message_receipts') self.plugin['xep_0184'].auto_request = config.get( 'request_message_receipts') self.register_plugin('xep_0191') if config.get('enable_smacks'): self.register_plugin('xep_0198') self.register_plugin('xep_0199') if config.get('enable_user_tune'): self.register_plugin('xep_0118') if config.get('enable_user_nick'): self.register_plugin('xep_0172') if config.get('enable_user_mood'): self.register_plugin('xep_0107') if config.get('enable_user_activity'): self.register_plugin('xep_0108') if config.get('enable_user_gaming'): self.register_plugin('xep_0196') if config.get('send_poezio_info'): info = {'name': 'poezio', 'version': options.version} if config.get('send_os_info'): info['os'] = common.get_os_info() self.plugin['xep_0030'].set_identities(identities={('client', 'console', None, 'Poezio')}) else: info = {'name': '', 'version': ''} self.plugin['xep_0030'].set_identities(identities={('client', 'console', None, '')}) self.register_plugin('xep_0092', pconfig=info) if config.get('send_time'): self.register_plugin('xep_0202') self.register_plugin('xep_0224') self.register_plugin('xep_0231') self.register_plugin('xep_0249') self.register_plugin('xep_0257') self.register_plugin('xep_0280') self.register_plugin('xep_0297') self.register_plugin('xep_0308') self.register_plugin('xep_0319') self.register_plugin('xep_0334') self.register_plugin('xep_0352') try: self.register_plugin('xep_0363') except SyntaxError: log.error('Failed to load HTTP File Upload plugin, it can only be ' 'used on Python 3.5+') except slixmpp.plugins.base.PluginNotFound: log.error('Failed to load HTTP File Upload plugin, it can only be ' 'used with aiohttp installed') self.register_plugin('xep_0380') self.init_plugins()