def handle_iq(self, iq, payload): if not iq.with_attrs("from", type="set"): return False jid = JID(iq.get_attr("from")) if jid.bare() != self.room.jid.bare(): return False if not payload.named("start").with_attrs("id"): return False service_id = payload.get_attr("id") self._start(iq, jid, service_id, payload) return True
def _run(self): with self.xmpp.core.iq_handler(self.handle_iq, "start", SERVICE_NS): while True: elements = yield idiokit.next() for message in elements.named("message").with_attrs("from"): for end in message.children("end", SERVICE_NS).with_attrs("id"): jid = JID(message.get_attr("from")) session_id = end.get_attr("id") self._discard_session(jid, session_id) presences = elements.named("presence").with_attrs("from") for presence in presences: jid = JID(presence.get_attr("from")) if presence.with_attrs(type="unavailable"): self._discard_jid(jid, Unavailable()) else: self._update_catalogue(jid, presence.children())
def _encode_room_jid(jid): r""" Return a sanitized and normalized path name for a bare room JID. The a argument should be a unicode string, a byte string or an idiokit.xmpp.jid.JID instance. >>> _encode_room_jid(u"*****@*****.**") '*****@*****.**' >>> _encode_room_jid(u"*****@*****.**") '*****@*****.**' >>> _encode_room_jid(JID("*****@*****.**")) '*****@*****.**' The argument should be a "bare JID", i.e. contain only the node@domain part. Otherwise a ValueError will get raised. >>> _encode_room_jid("[email protected]/resource") Traceback (most recent call last): ... ValueError: given room JID does not match with the bare room JID Byte strings will be first converted to unicode with the default "ascii" encoding. UnicodeDecodeError will be raised on failure. >>> _encode_room_jid(u"room.caf\[email protected]") '*****@*****.**' >>> _encode_room_jid("room.caf\[email protected]") Traceback (most recent call last): ... UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 8: ordinal not in range(128) """ room_jid = JID(jid) if room_jid != room_jid.bare(): raise ValueError("given room JID does not match with the bare room JID") return urllib.quote(unicode(room_jid).encode("utf-8"), safe=" @")
def xmpp_to_log(self, own_jid, participants): in_room = set() for participant in participants: in_room.add(participant.name.resource) while True: elements = yield idiokit.next() for message in elements.with_attrs("from"): sender = JID(elements.get_attr("from")) if sender == own_jid or sender.resource is None: continue resource = sender.resource.encode("unicode-escape") bare = unicode(sender.bare()).encode("unicode-escape") type_ = message.get_attr("type", None) if type_ == "unavailable": if sender.resource in in_room: in_room.discard(sender.resource) self.log.info("* {0} left the room {1}.".format( resource, bare)) else: if sender.resource not in in_room: in_room.add(sender.resource) self.log.info("* {0} entered the room {1}.".format( resource, bare)) for body in message.children("body"): self.log.info("<{0}> {1}".format( unicode(sender).encode("unicode-escape"), body.text.encode("unicode-escape"))) if self.show_events: for event in events.Event.from_elements(message): self.log.info("<{0}> {1}".format( unicode(sender).encode("unicode-escape"), event))
def parse(self, db): queries = QuerySet() while True: next = idiokit.next() if queries: idiokit.pipe(self._timeout(0.0), next) try: elements = yield next except Timeout: pass else: for element in elements.with_attrs("from"): sender = JID(element.get_attr("from")) if element.named("presence").with_attrs( type="unavailable"): db.purge_jid(sender) queries.discard_jid(sender) for message in element.named("message"): if not message.with_attrs(type="groupchat"): continue for event in events.Event.from_elements(message): db.add_event(sender, event) for query in element.named("message").children(ns=NS): try: args = json.loads(query.text) except JSONDecodeError: self.log.error("Invalid query data from %r: %r", sender, query.text) continue if "id" not in args: self.log.error("Query without an ID from %r: %r", sender, args) continue id = args.get("id") if query.named("start"): start = args.get("start", None) end = args.get("end", None) queries.start(sender, id, db.query(start, end)) self.log.info("Start from %r: %r", sender, args) elif query.named("load"): if "size" in args: queries.load(sender, id, args.get("size")) self.log.debug("Load from %r: %r", sender, args) else: self.log.error( "Load without an ID from %r: %r", sender, args) elif query.named("histogram"): start = args.get("start", None) end = args.get("end", None) step = args.get("step", None) if None not in (start, end, step): element = db.histogram(id, start, end, step) self.xmpp.core.message(sender, element) self.log.debug("Histogram from %r: %r", sender, args) elif query.named("cancel"): queries.cancel(sender, id) self.log.info("Cancel from %r: %r", sender, args) for sender, element in queries: yield self.xmpp.core.message(sender, element)