def request_session(self): """Request an IM session.""" stream=self.get_stream() if not stream.version: need_session=False elif not stream.features: need_session=False else: ctxt = stream.doc_in.xpathNewContext() ctxt.setContextNode(stream.features) ctxt.xpathRegisterNs("sess","urn:ietf:params:xml:ns:xmpp-session") # jabberd2 hack ctxt.xpathRegisterNs("jsess","http://jabberd.jabberstudio.org/ns/session/1.0") sess_n=None try: sess_n=ctxt.xpathEval("sess:session or jsess:session") finally: ctxt.xpathFreeContext() if sess_n: need_session=True else: need_session=False if not need_session: self.state_changed.acquire() self.session_established=1 self.state_changed.notify() self.state_changed.release() self._session_started() else: iq=Iq(stanza_type="set") iq.new_query("urn:ietf:params:xml:ns:xmpp-session","session") stream.set_response_handlers(iq, self.__session_result,self.__session_error,self.__session_timeout) stream.send(iq)
def configure_room(self, form): """ Configure the room using the provided data. Do nothing if the provided form is of type 'cancel'. :Parameters: - `form`: the configuration parameters. Should be a 'submit' form made by filling-in the configuration form retireved using `self.request_configuration_form` or a 'cancel' form. :Types: - `form`: `Form` :return: id of the request stanza or `None` if a 'cancel' form was provieded. :returntype: `unicode` """ if form.type == "cancel": return None elif form.type != "submit": raise ValueError, "A 'submit' form required to configure a room" iq = Iq(to_jid=self.room_jid.bare(), stanza_type="set") query = iq.new_query(MUC_OWNER_NS, "query") form.as_xml(query) self.manager.stream.set_response_handlers( iq, self.process_configuration_success, self.process_configuration_error) self.manager.stream.send(iq) return iq.get_id()
def query_get(self, jid, handler): stream = self.client.get_stream() iq = Iq(to_jid=jid, stanza_type="get") q = iq.new_query(VCARD_NS, "vCard") stream.set_response_handlers(iq, self.on_get_result, self.on_get_error) stream.send(iq) self.handler = handler
def configure_room(self, form): """ Configure the room using the provided data. Do nothing if the provided form is of type 'cancel'. :Parameters: - `form`: the configuration parameters. Should be a 'submit' form made by filling-in the configuration form retireved using `self.request_configuration_form` or a 'cancel' form. :Types: - `form`: `Form` :return: id of the request stanza or `None` if a 'cancel' form was provieded. :returntype: `unicode` """ if form.type == "cancel": return None elif form.type != "submit": raise ValueError, "A 'submit' form required to configure a room" iq = Iq(to_jid = self.room_jid.bare(), stanza_type = "set") query = iq.new_query(MUC_OWNER_NS, "query") form.as_xml(query) self.manager.stream.set_response_handlers( iq, self.process_configuration_success, self.process_configuration_error) self.manager.stream.send(iq) return iq.get_id()
def make_push(self, digsby_protocol): 'Creates a set stanza.' iq=Iq(stanza_type="set") iq.set_to(digsby_protocol.jid.domain) self.as_xml(parent=iq.get_node()) return iq
def __init__(self,xmlnode=None,from_jid=None,to_jid=None,stanza_type=None,stanza_id=None, error=None,error_cond=None): """Initialize an `Iq` object. :Parameters: - `xmlnode`: XML node to_jid be wrapped into the `Iq` object or other Iq object to be copied. If not given then new presence stanza is created using following parameters. - `from_jid`: sender JID. - `to_jid`: recipient JID. - `stanza_type`: staza type: one of: "get", "set", "result" or "error". - `stanza_id`: stanza id -- value of stanza's "id" attribute. If not given, then unique for the session value is generated. - `error_cond`: error condition name. Ignored if `stanza_type` is not "error". :Types: - `xmlnode`: `unicode` or `libxml2.xmlNode` or `Iq` - `from_jid`: `JID` - `to_jid`: `JID` - `stanza_type`: `unicode` - `stanza_id`: `unicode` - `error_cond`: `unicode`""" MucStanzaExt.__init__(self) Iq.__init__(self,xmlnode,from_jid=from_jid,to_jid=to_jid, stanza_type=stanza_type,stanza_id=stanza_id, error=error,error_cond=error_cond)
def query_get(self, jid, handler) : stream = self.client.get_stream() iq = Iq(to_jid=jid, stanza_type="get") q=iq.new_query(VCARD_NS, "vCard") stream.set_response_handlers(iq, self.on_get_result, self.on_get_error) stream.send(iq) self.handler = handler
def test_get_lang_class_from_node(self): iq = Iq(from_jid = "*****@*****.**", \ to_jid = "*****@*****.**", \ stanza_type = "get") iq_node = iq.get_node() iq_node.setLang("fr") lang = self.lang.get_lang_class_from_node(iq_node) self.assertEquals(lang, Lang.fr)
def query_get_server(self): stream = self.client.get_stream() discoIq = Iq(None, self.client.jid, self.client.jid.domain, "get", stream.generate_id()) discoIq.new_query('http://jabber.org/protocol/disco#info') stream.set_response_handlers(discoIq, self.on_get_result, self.on_get_error) stream.send(discoIq)
def query_set(self, vcard) : stream = self.client.get_stream() new_id = stream.generate_id() iq = Iq(None, None, None, "set", new_id) node=iq.new_query(VCARD_NS, "vCard") vcard.as_xml(node) stream.set_response_handlers(iq, self.on_set_result, self.on_set_error) stream.send(iq)
def query_set(self, vcard): stream = self.client.get_stream() new_id = stream.generate_id() iq = Iq(None, None, None, "set", new_id) node = iq.new_query(VCARD_NS, "vCard") vcard.as_xml(node) stream.set_response_handlers(iq, self.on_set_result, self.on_set_error) stream.send(iq)
def make_roster_push(self): """ Make "roster push" IQ stanza from the item representing roster update request. """ iq=Iq(stanza_type="set") q=iq.new_query(ROSTER_NS) self.as_xml(parent=q, doc=common_doc) return iq
def request_roster(self): """Request the user's roster.""" stream=self.get_stream() iq=Iq(stanza_type="get") iq.new_query("jabber:iq:roster") stream.set_response_handlers(iq, self.__roster_result,self.__roster_error,self.__roster_timeout) stream.set_iq_set_handler("query","jabber:iq:roster",self.__roster_push) stream.send(iq)
def make_roster_push(self): """ Make "roster push" IQ stanza from the item representing roster update request. """ iq = Iq(stanza_type="set") q = iq.new_query(ROSTER_NS) self.as_xml(parent=q, doc=common_doc) return iq
def fetch(self): """Initialize the Service Discovery process.""" from pyxmpp.iq import Iq jid, node = self.address iq = Iq(to_jid=jid, stanza_type="get") disco = self.disco_class(node) iq.add_content(disco.xmlnode) self.stream.set_response_handlers(iq, self.__response, self.__error, self.__timeout) self.stream.send(iq)
def fetch(self): """Initialize the Service Discovery process.""" from pyxmpp.iq import Iq jid,node = self.address iq = Iq(to_jid = jid, stanza_type = "get") disco = self.disco_class(node) iq.add_content(disco.xmlnode) self.stream.set_response_handlers(iq,self.__response, self.__error, self.__timeout) self.stream.send(iq)
def _plain_auth_stage2(self, _unused): """Do the second stage (<iq type='set'/>) of legacy "plain" authentication. [client only]""" iq = Iq(stanza_type="set") q = iq.new_query("jabber:iq:auth") q.newTextChild(None, "username", to_utf8(self.my_jid.node)) q.newTextChild(None, "resource", to_utf8(self.my_jid.resource)) q.newTextChild(None, "password", to_utf8(self.password)) self.send(iq) self.set_response_handlers(iq, self.auth_finish, self.auth_error) iq.free()
def _auth_stage1(self): """Do the first stage (<iq type='get'/>) of legacy ("plain" or "digest") authentication. [client only]""" iq=Iq(stanza_type="get") q=iq.new_query("jabber:iq:auth") q.newTextChild(None,"username",to_utf8(self.my_jid.node)) q.newTextChild(None,"resource",to_utf8(self.my_jid.resource)) self.send(iq) self.set_response_handlers(iq,self.auth_stage2,self.auth_error, self.auth_timeout,timeout=60) iq.free()
def query_set(self, ns, element, data, handler=None): stream = self.client.get_stream() new_id = stream.generate_id() iq = Iq(None, None, None, "set", new_id) node = iq.new_query('jabber:iq:private') enode = node.newChild(None, to_utf8(element), None) ns = enode.newNs(ns, None) enode.setNs(ns) enode.addContent(data) stream.set_response_handlers(iq, self.on_set_result, self.on_set_error) stream.send(iq) if handler: self.handlers[new_id] = handler
def _plain_auth_stage2(self, _unused): """Do the second stage (<iq type='set'/>) of legacy "plain" authentication. [client only]""" iq=Iq(stanza_type="set") q=iq.new_query("jabber:iq:auth") q.newTextChild(None,"username",to_utf8(self.my_jid.node)) q.newTextChild(None,"resource",to_utf8(self.my_jid.resource)) q.newTextChild(None,"password",to_utf8(self.password)) self.send(iq) self.set_response_handlers(iq,self.auth_finish,self.auth_error) iq.free()
def _auth_stage1(self): """Do the first stage (<iq type='get'/>) of legacy ("plain" or "digest") authentication. [client only]""" iq = Iq(stanza_type="get") q = iq.new_query("jabber:iq:auth") q.newTextChild(None, "username", to_utf8(self.my_jid.node)) q.newTextChild(None, "resource", to_utf8(self.my_jid.resource)) self.send(iq) self.set_response_handlers(iq, self.auth_stage2, self.auth_error, self.auth_timeout, timeout=60) iq.free()
def _digest_auth_stage2(self, _unused): """Do the second stage (<iq type='set'/>) of legacy "digest" authentication. [client only]""" iq=Iq(stanza_type="set") q=iq.new_query("jabber:iq:auth") q.newTextChild(None,"username",to_utf8(self.my_jid.node)) q.newTextChild(None,"resource",to_utf8(self.my_jid.resource)) digest = hashlib.sha1(to_utf8(self.stream_id)+to_utf8(self.password)).hexdigest() q.newTextChild(None,"digest",digest) self.send(iq) self.set_response_handlers(iq,self.auth_finish,self.auth_error) iq.free()
def request_configuration_form(self): """ Request a configuration form for the room. When the form is received `self.handler.configuration_form_received` will be called. When an error response is received then `self.handler.error` will be called. :return: id of the request stanza. :returntype: `unicode` """ iq = Iq(to_jid = self.room_jid.bare(), stanza_type = "get") iq.new_query(MUC_OWNER_NS, "query") self.manager.stream.set_response_handlers( iq, self.process_configuration_form_success, self.process_configuration_form_error) self.manager.stream.send(iq) return iq.get_id()
def _post_connect(self): """Initialize authentication when the connection is established and we are the initiator.""" if not self.initiator: if "plain" in self.auth_methods or "digest" in self.auth_methods: self.set_iq_get_handler("query","jabber:iq:auth", self.auth_in_stage1) self.set_iq_set_handler("query","jabber:iq:auth", self.auth_in_stage2) elif self.registration_callback: iq = Iq(stanza_type = "get") iq.set_content(Register()) self.set_response_handlers(iq, self.registration_form_received, self.registration_error) self.send(iq) return ClientStream._post_connect(self)
def setUp(self, tables=[]): tables += [POP3Account, IMAPAccount, GlobalSMTPAccount, AbstractSMTPAccount, SMTPAccount, MailAccount, MockIMAPAccount, User, Account, PresenceAccount] JCLTestCase.setUp(self, tables=tables) self.config_file = tempfile.mktemp(".conf", "jmctest", jcl.tests.DB_DIR) self.config = ConfigParser() self.config.read(self.config_file) self.comp = MailComponent("jmc.test.com", "password", "localhost", "5347", self.config, self.config_file) self.comp.set_admins(["*****@*****.**"]) self.command_manager = MailCommandManager(self.comp, self.comp.account_manager) self.comp.account_manager.account_classes = (POP3Account, IMAPAccount, GlobalSMTPAccount, AbstractSMTPAccount, SMTPAccount, MockIMAPAccount) self.user1 = User(jid="*****@*****.**") self.account11 = MockIMAPAccount(user=self.user1, name="account11", jid="account11@" + unicode(self.comp.jid)) self.account12 = MockIMAPAccount(user=self.user1, name="account12", jid="account12@" + unicode(self.comp.jid)) self.user2 = User(jid="*****@*****.**") self.account21 = MockIMAPAccount(user=self.user2, name="account21", jid="account21@" + unicode(self.comp.jid)) self.account22 = MockIMAPAccount(user=self.user2, name="account11", jid="account11@" + unicode(self.comp.jid)) self.user3 = User(jid="*****@*****.**") self.account31 = MockIMAPAccount(user=self.user3, name="account31", jid="account31@" + unicode(self.comp.jid)) self.account32 = MockIMAPAccount(user=self.user3, name="account32", jid="account32@" + unicode(self.comp.jid)) self.info_query = Iq(stanza_type="set", from_jid="*****@*****.**", to_jid=self.comp.jid) self.command_node = self.info_query.set_new_content(command.COMMAND_NS, "command") class MockFeederHandler(Feeder): def __init__(self, component): Feeder.__init__(self, component) self.checked_accounts = [] def feed(self, _account): self.checked_accounts.append(_account) assert((int(time.time()) - _account.lastcheck \ >= (_account.interval * self.component.time_unit))) return [] self.comp.tick_handlers[0].feeder = MockFeederHandler(self.comp)
def _post_connect(self): """Initialize authentication when the connection is established and we are the initiator.""" if not self.initiator: if "plain" in self.auth_methods or "digest" in self.auth_methods: self.set_iq_get_handler("query", "jabber:iq:auth", self.auth_in_stage1) self.set_iq_set_handler("query", "jabber:iq:auth", self.auth_in_stage2) elif self.registration_callback: iq = Iq(stanza_type="get") iq.set_content(Register()) self.set_response_handlers(iq, self.registration_form_received, self.registration_error) self.send(iq) return ClientStream._post_connect(self)
def send_close_request(self, session) : ''' <iq type='set' from='[email protected]/orchard' to='[email protected]/balcony' id='inband_2'> <close xmlns='http://jabber.org/protocol/ibb' sid='mySID'/> </iq> ''' stream = self.client.get_stream() new_id = stream.generate_id() iq = Iq(None, session.jid, session.to_jid, "set", new_id) node = iq.add_new_content(IBB_NS, 'close') node.setProp('sid', session.sid) stream.set_response_handlers(iq, self.received_close_success, self.received_close_error) stream.send(iq) self.active_sessions[new_id] = session
def _digest_auth_stage2(self, _unused): """Do the second stage (<iq type='set'/>) of legacy "digest" authentication. [client only]""" iq = Iq(stanza_type="set") q = iq.new_query("jabber:iq:auth") q.newTextChild(None, "username", to_utf8(self.my_jid.node)) q.newTextChild(None, "resource", to_utf8(self.my_jid.resource)) digest = hashlib.sha1( to_utf8(self.stream_id) + to_utf8(self.password)).hexdigest() q.newTextChild(None, "digest", digest) self.send(iq) self.set_response_handlers(iq, self.auth_finish, self.auth_error) iq.free()
def request_configuration_form(self): """ Request a configuration form for the room. When the form is received `self.handler.configuration_form_received` will be called. When an error response is received then `self.handler.error` will be called. :return: id of the request stanza. :returntype: `unicode` """ iq = Iq(to_jid=self.room_jid.bare(), stanza_type="get") iq.new_query(MUC_OWNER_NS, "query") self.manager.stream.set_response_handlers( iq, self.process_configuration_form_success, self.process_configuration_form_error) self.manager.stream.send(iq) return iq.get_id()
def query_get(self, ns=None, element=None, handler=None): stream = self.client.get_stream() new_id = stream.generate_id() iq = Iq(None, None, None, "get", new_id) node = iq.new_query('jabber:iq:private') if element: enode = node.newChild(None, to_utf8(element), None) if ns: ns = enode.newNs(ns, None) enode.setNs(ns) # # if handler: self.handlers[new_id] = handler stream.set_response_handlers(iq, self.on_get_result, self.on_get_error) stream.send(iq)
def send_si_request(self, session) : ''' <iq type='set' id='offer1' to='[email protected]/resource'> <si xmlns='http://jabber.org/protocol/si' id='a0' mime-type='text/plain' profile='http://jabber.org/protocol/si/profile/file-transfer'> <file xmlns='http://jabber.org/protocol/si/profile/file-transfer' name='test.txt' size='1022' hash='552da749930852c69ae5d2141d3766b1' date='1969-07-21T02:56:15Z'> <desc>This is a test. If this were a real file...</desc> </file> <feature xmlns='http://jabber.org/protocol/feature-neg'> <x xmlns='jabber:x:data' type='form'> <field var='stream-method' type='list-single'> <option><value>>>http://jabber.org/protocol/bytestreams</value></option> <option><value>>>http://jabber.org/protocol/ibb</value></option> </field> </x> </feature> </si> </iq> ''' stream = self.client.get_stream() #new_id = stream.generate_id() iq = Iq(None, session.jid, session.to_jid, "set", session.sid) si_node = iq.add_new_content(SI_NS, 'si') si_node.setProp("id", session.sid) si_node.setProp("mime-type", 'application/octet-stream') si_node.setProp("profile", FILE_TRANSFER_NS) file_node = si_node.newChild(None,"file",None) file_node.setProp("xmlns", FILE_TRANSFER_NS) file_node.setProp("name", to_utf8(session.file_name)) file_node.setProp("size", to_utf8(session.file_size)) feature_node = si_node.newChild(None, "feature", None) feature_node.setProp("xmlns", FEATURE_NS) form = Form() form.add_field( name = 'stream-method', field_type = 'list-single', #options = [Option('http://jabber.org/protocol/bytestreams', None), Option('http://jabber.org/protocol/ibb', None)]) options = [Option('http://jabber.org/protocol/ibb', None)]) form.as_xml(feature_node) stream.set_response_handlers(iq, self.received_si_success, self.received_si_error) stream.send(iq) self.sessions[session.sid] = session
def on_succ(self, num_tries_taken, sock): host_used = self.hosts_bytestreams.hosts[num_tries_taken-1].jid self.my_sock = sock i2 = Iq(to_jid=self.from_, stanza_type="result", stanza_id = self.respond_id) b = ByteStreams() b.host_used = JID(host_used) b.as_xml(i2.get_node()) self.my_sock.found_terminator = self.close self.my_sock.collect_incoming_data = self.collect_incoming_data self.my_sock.set_terminator(self.si_ft.file.size) self.my_sock.bind_event("socket_closed", self.closed) self.my_sock.bind_event("socket_error", self.stream_error) self.j.send(i2) self.log.info("S5BFileXferHandler connect succeeded to %s", host_used) self.event("stream_connected")
def fetch(self): """Initialize the Service Discovery process.""" from pyxmpp.iq import Iq jid, node = self.address iq = Iq(to_jid=jid, stanza_type="get") disco = self.disco_class(node) disco.as_xml(iq.xmlnode) #only line that was changed self.stream.set_response_handlers(iq, self.__response, self.__error, self.__timeout) self.stream.send(iq) """Cache fetcher for ByteStreams."""
def send_data_request(self, session, data) : ''' <iq from='[email protected]/orchard' to='[email protected]/balcony' type='set' id='ibb1'> <data xmlns='http://jabber.org/protocol/ibb' sid='mySID' seq='0'> qANQR1DBwU4DX7jmYZnncmUQB/9KuKBddzQH+tZ1ZywKK0yHKnq57kWq+RFtQdCJ WpdWpR0uQsuJe7+vh3NWn59/gTc5MDlX8dS9p0ovStmNcyLhxVgmqS8ZKhsblVeu IpQ0JgavABqibJolc3BKrVtVV1igKiX/N7Pi8RtY1K18toaMDhdEfhBRzO/XB0+P AQhYlRjNacGcslkhXqNjK5Va4tuOAPy2n1Q8UUrHbUd0g+xJ9Bm0G0LZXyvCWyKH kuNEHFQiLuCY6Iv0myq6iX6tjuHehZlFSh80b5BVV9tNLwNR5Eqz1klxMhoghJOA </data> </iq> ''' stream = self.client.get_stream() new_id = stream.generate_id() iq = Iq(None, session.jid, session.to_jid, "set", new_id) node = iq.add_new_content(IBB_NS, 'data') node.setProp('sid', session.sid) node.setProp('seq', str(session.seq)) node.setContent(base64.b64encode(data)) stream.set_response_handlers(iq, self.received_data_success, self.received_data_error) stream.send(iq) self.active_sessions[new_id] = session
def submit_registration_form(self, form): """Submit a registration form. [client only] :Parameters: - `form`: the filled-in form. When form is `None` or its type is "cancel" the registration is to be canceled. :Types: - `form`: `pyxmpp.jabber.dataforms.Form`""" self.lock.acquire() try: if form and form.type!="cancel": self.registration_form = form iq = Iq(stanza_type = "set") iq.set_content(self.__register.submit_form(form)) self.set_response_handlers(iq, self.registration_success, self.registration_error) self.send(iq) else: self.__register = None finally: self.lock.release()
def __init__(self, xmlnode=None, from_jid=None, to_jid=None, stanza_type=None, stanza_id=None, error=None, error_cond=None): """Initialize an `Iq` object. :Parameters: - `xmlnode`: XML node to_jid be wrapped into the `Iq` object or other Iq object to be copied. If not given then new presence stanza is created using following parameters. - `from_jid`: sender JID. - `to_jid`: recipient JID. - `stanza_type`: staza type: one of: "get", "set", "result" or "error". - `stanza_id`: stanza id -- value of stanza's "id" attribute. If not given, then unique for the session value is generated. - `error_cond`: error condition name. Ignored if `stanza_type` is not "error". :Types: - `xmlnode`: `unicode` or `libxml2.xmlNode` or `Iq` - `from_jid`: `JID` - `to_jid`: `JID` - `stanza_type`: `unicode` - `stanza_id`: `unicode` - `error_cond`: `unicode`""" MucStanzaExt.__init__(self) Iq.__init__(self, xmlnode, from_jid=from_jid, to_jid=to_jid, stanza_type=stanza_type, stanza_id=stanza_id, error=error, error_cond=error_cond)
def submit_registration_form(self, form): """Submit a registration form. [client only] :Parameters: - `form`: the filled-in form. When form is `None` or its type is "cancel" the registration is to be canceled. :Types: - `form`: `pyxmpp.jabber.dataforms.Form`""" self.lock.acquire() try: if form and form.type != "cancel": self.registration_form = form iq = Iq(stanza_type="set") iq.set_content(self.__register.submit_form(form)) self.set_response_handlers(iq, self.registration_success, self.registration_error) self.send(iq) else: self.__register = None finally: self.lock.release()
def make_get(gtalk_protocol): iq = Iq(stanza_type="get") _q = iq.new_query(GOOGLE_MAIL_NOTIFY_NS) return iq
def make_get(gtalk_protocol): iq = Iq(stanza_type="get") q = iq.new_query(SHARED_STATUS_NS) q.setProp("version", '2') return iq
def make_get(gtalk_protocol): iq = Iq(stanza_type="get") q = iq.new_query(SHARED_STATUS_NS) q.setProp("version", "2") return iq
def make_get(digsby_protocol): iq = Iq(stanza_type="get") iq.set_to(digsby_protocol.jid.domain) q = iq.new_query(DIGSBY_WIDGETS_NS) return iq
def parse_stanza(self, xml): doc = libxml2.parseDoc(xml) root = doc.getRootElement() iq = Iq(root) register = iq.get_query() return Register(register)
def make_get(self, digsby_protocol): iq = Iq(stanza_type="get") iq.set_to(digsby_protocol.jid.domain) self.as_xml(parent=iq.get_node()) return iq
def make_set(self, to): iq = Iq(stanza_type="set") iq.set_to(to) self.as_xml(parent=iq.get_node()) return iq
def on_fail(self): self.log.warning("S5BFileXferHandler connect failed") i = Iq(to_jid=self.from_, from_jid = self.to_, stanza_type="error", stanza_id = self.respond_id, error_cond=u"item-not-found") self.j.send(i) self.event("stream_connect_failed")
def query_get_server(self) : stream = self.client.get_stream() discoIq = Iq(None, self.client.jid, self.client.jid.domain, "get", stream.generate_id()) discoIq.new_query('http://jabber.org/protocol/disco#info') stream.set_response_handlers(discoIq, self.on_get_result, self.on_get_error) stream.send(discoIq)
def free(self): """Free the data associated with this `MucIq` object.""" self.muc_free() Iq.free(self)
def make_push(acct, digsby_protocol): iq=Iq(stanza_type="set") iq.set_to(digsby_protocol.jid.domain) q = iq.new_query(DIGSBY_ACCOUNTS_NS) acct.as_xml(parent=q) return iq