class ChatClient(JabberClient): def __init__(self, jid, password, nick): self.nick = nick self.jid = jid if jid.resource else JID(jid.node, jid.domain, "Robot-"+self.nick) tls = TLSSettings(require=True, verify_peer=False) JabberClient.__init__(self, self.jid, password, disco_name="chatbot", disco_type="user", tls_settings=tls, auth_methods=['sasl:PLAIN']) self.disco_info.add_feature("jabber:iq:version") def message(self,stanza): raise NotImplementedError('Need to override "message" callback function') def session_started(self): raise NotImplementedError('Need to override "session_started" callback function') def _session_started_helper(self,bot,muc_jid): '''Pass this an instance of your bot (that subclasses MucRoomHandler) and a MUC room JID''' JabberClient.session_started(self) self.stream.set_iq_get_handler("query","jabber:iq:version",self.get_version) self.stream.set_message_handler("normal",self.message) self.muc_manager = MucRoomManager(self.stream) self.muc_state = self.muc_manager.join(muc_jid,self.nick,bot,history_maxchars=0) self.muc_manager.set_handlers() def get_version(self,iq): iq=iq.make_result_response() q=iq.new_query("jabber:iq:version") q.newTextChild(q.ns(),"name",self.nick) q.newTextChild(q.ns(),"version","1.0") self.stream.send(iq) return True def print_roster_item(self,item): name = item.name if item.name else item.jid print ' %s (group%s: %s)' % (name, '' if len(item.groups) == 1 else 's', ','.join(item.groups)) def roster_updated(self,item=None): if not item: print colorize('U',"My roster:") for item in self.roster.get_items(): self.print_roster_item(item) else: print "Roster item updated:" self.print_roster_item(item)
class Client(JabberClient): """Simple bot (client) example. Uses `pyxmpp.jabber.client.JabberClient` class as base. That class provides basic stream setup (including authentication) and Service Discovery server. It also does server address and port discovery based on the JID provided.""" def __init__(self, jid, password): # if bare JID is provided add a resource -- it is required if not jid.resource: print(jid.resource) jid=JID(jid.node, jid.domain, "Echobot") # setup client with provided connection information # and identity data JabberClient.__init__(self, jid, password, disco_name="PyXMPP example: echo bot", disco_type="bot", keepalive=10) # register features to be announced via Service Discovery self.disco_info.add_feature("jabber:iq:version") self.muc = [] def stream_state_changed(self,state,arg): """This one is called when the state of stream connecting the component to a server changes. This will usually be used to let the user know what is going on.""" print("*** State changed: %s %r ***" % (state,arg)) def session_started(self): """This is called when the IM session is successfully started (after all the neccessery negotiations, authentication and authorizasion). That is the best place to setup various handlers for the stream. Do not forget about calling the session_started() method of the base class!""" JabberClient.session_started(self) # set up handlers for supported <iq/> queries self.stream.set_iq_get_handler( "query","jabber:iq:version",self.get_version) # set up handlers for <presence/> stanzas self.stream.set_presence_handler("available",self.presence) self.stream.set_presence_handler("subscribe",self.presence_control) self.stream.set_presence_handler("subscribed",self.presence_control) self.stream.set_presence_handler("unsubscribe",self.presence_control) self.stream.set_presence_handler("unsubscribed",self.presence_control) # set up handler for <message stanza> self.stream.set_message_handler("normal",self.message) print(self.stream) print(u"joining...") self.roommgr = MucRoomManager(self.stream) self.roommgr.set_handlers() nick = self.jid.node + '-' + self.jid.resource #['*****@*****.**','*****@*****.**']: for loc in options.channels: roomjid = JID(loc, options.muc) print("\t %s" % roomjid.as_unicode()) h = RoomHandler() self.muc.append(h) mucstate = self.roommgr.join(roomjid, nick, h) h.assign_state(mucstate) def get_version(self,iq): """Handler for jabber:iq:version queries. jabber:iq:version queries are not supported directly by PyXMPP, so the XML node is accessed directly through the libxml2 API. This should be used very carefully!""" iq=iq.make_result_response() q=iq.new_query("jabber:iq:version") q.newTextChild(q.ns(),"name","Echo component") q.newTextChild(q.ns(),"version","1.0") self.stream.send(iq) return True def message(self,stanza): """Message handler for the component. Echoes the message back if its type is not 'error' or 'headline', also sets own presence status to the message body. Please note that all message types but 'error' will be passed to the handler for 'normal' message unless some dedicated handler process them. :returns: `True` to indicate, that the stanza should not be processed any further.""" subject=stanza.get_subject() body=stanza.get_body() t=stanza.get_type() print(u'Message from %s received.' % (unicode(stanza.get_from(),))) return True def presence(self,stanza): """Handle 'available' (without 'type') and 'unavailable' <presence/>.""" msg=u"%s has become " % (stanza.get_from()) t=stanza.get_type() if t=="unavailable": msg+=u"unavailable" else: msg+=u"available" show=stanza.get_show() if show: msg+=u"(%s)" % (show,) status=stanza.get_status() if status: msg+=u": "+status print(msg) def presence_control(self,stanza): """Handle subscription control <presence/> stanzas -- acknowledge them.""" msg=unicode(stanza.get_from()) t=stanza.get_type() if t=="subscribe": msg+=u" has requested presence subscription." elif t=="subscribed": msg+=u" has accepted our presence subscription request." elif t=="unsubscribe": msg+=u" has canceled his subscription of our." elif t=="unsubscribed": msg+=u" has canceled our subscription of his presence." print(msg) p=stanza.make_accept_response() self.stream.send(p) return True def print_roster_item(self,item): if item.name: name=item.name else: name=u"" print(u'%s "%s" subscription=%s groups=%s' % (unicode(item.jid), name, item.subscription, u",".join(item.groups)) ) def roster_updated(self,item=None): if not item: print(u"My roster:") for item in self.roster.get_items(): self.print_roster_item(item) return print(u"Roster item updated:") self.print_roster_item(item)
class Client(JabberClient): """Simple bot (client) example. Uses `pyxmpp.jabber.client.JabberClient` class as base. That class provides basic stream setup (including authentication) and Service Discovery server. It also does server address and port discovery based on the JID provided.""" def __init__(self, jid, password): # if bare JID is provided add a resource -- it is required if not jid.resource: print(jid.resource) jid=JID(jid.node, jid.domain, "Echobot") # setup client with provided connection information # and identity data JabberClient.__init__(self, jid, password, disco_name="PyXMPP example: echo bot", disco_type="bot", keepalive=10) # register features to be announced via Service Discovery self.disco_info.add_feature("jabber:iq:version") self.muc = [] def stream_state_changed(self,state,arg): """This one is called when the state of stream connecting the component to a server changes. This will usually be used to let the user know what is going on.""" print "*** State changed: %s %r ***" % (state,arg) def session_started(self): """This is called when the IM session is successfully started (after all the neccessery negotiations, authentication and authorizasion). That is the best place to setup various handlers for the stream. Do not forget about calling the session_started() method of the base class!""" JabberClient.session_started(self) # set up handlers for supported <iq/> queries self.stream.set_iq_get_handler("query","jabber:iq:version",self.get_version) # set up handlers for <presence/> stanzas self.stream.set_presence_handler("available",self.presence) self.stream.set_presence_handler("subscribe",self.presence_control) self.stream.set_presence_handler("subscribed",self.presence_control) self.stream.set_presence_handler("unsubscribe",self.presence_control) self.stream.set_presence_handler("unsubscribed",self.presence_control) # set up handler for <message stanza> self.stream.set_message_handler("normal",self.message) print(self.stream) print u"joining..." self.roommgr = MucRoomManager(self.stream) self.roommgr.set_handlers() nick = self.jid.node + '-' + self.jid.resource for loc in options.channels: #['*****@*****.**','*****@*****.**']: roomjid = JID(loc, options.muc) print("\t %s" % roomjid.as_unicode()) h = RoomHandler() self.muc.append(h) mucstate = self.roommgr.join(roomjid, nick, h) h.assign_state(mucstate) def get_version(self,iq): """Handler for jabber:iq:version queries. jabber:iq:version queries are not supported directly by PyXMPP, so the XML node is accessed directly through the libxml2 API. This should be used very carefully!""" iq=iq.make_result_response() q=iq.new_query("jabber:iq:version") q.newTextChild(q.ns(),"name","Echo component") q.newTextChild(q.ns(),"version","1.0") self.stream.send(iq) return True def message(self,stanza): """Message handler for the component. Echoes the message back if its type is not 'error' or 'headline', also sets own presence status to the message body. Please note that all message types but 'error' will be passed to the handler for 'normal' message unless some dedicated handler process them. :returns: `True` to indicate, that the stanza should not be processed any further.""" subject=stanza.get_subject() body=stanza.get_body() t=stanza.get_type() print u'Message from %s received.' % (unicode(stanza.get_from(),)), return True def presence(self,stanza): """Handle 'available' (without 'type') and 'unavailable' <presence/>.""" msg=u"%s has become " % (stanza.get_from()) t=stanza.get_type() if t=="unavailable": msg+=u"unavailable" else: msg+=u"available" show=stanza.get_show() if show: msg+=u"(%s)" % (show,) status=stanza.get_status() if status: msg+=u": "+status print msg def presence_control(self,stanza): """Handle subscription control <presence/> stanzas -- acknowledge them.""" msg=unicode(stanza.get_from()) t=stanza.get_type() if t=="subscribe": msg+=u" has requested presence subscription." elif t=="subscribed": msg+=u" has accepted our presence subscription request." elif t=="unsubscribe": msg+=u" has canceled his subscription of our." elif t=="unsubscribed": msg+=u" has canceled our subscription of his presence." print msg p=stanza.make_accept_response() self.stream.send(p) return True def print_roster_item(self,item): if item.name: name=item.name else: name=u"" print (u'%s "%s" subscription=%s groups=%s' % (unicode(item.jid), name, item.subscription, u",".join(item.groups)) ) def roster_updated(self,item=None): if not item: print u"My roster:" for item in self.roster.get_items(): self.print_roster_item(item) return print u"Roster item updated:" self.print_roster_item(item)
class Core(JabberClient): """Core of the framework, handles connections and dispatches messages to the corresponding Conversation""" def __init__(self, config_path): """Initializes the bot with data from a configuration file jid (node@domain) and it's password. starter and starter_params are the class of the first controller to be used and it's params. If none is provided a default controller will be used. user_control is a function to determine if a user should be accepted if he requests so with a suscribe presence stanza. Must return True/False """ self.initialize_logger() self.config = configparser.Config(config_path) self.conversations = {} self.user_control = self.config.user_control self.jid = self.create_jid(self.config.jid) self.nick = self.config.nick self.__starter = self.config.starter self.__starter_params = self.config.starter_params self.rooms_to_join = self.config.rooms_to_join self.start_on_user_connect = self.config.start_on_user_connect JabberClient.__init__(self, self.jid, self.config.password) def initialize_logger(self): """Initializes logger""" self.logger = logging.getLogger("logger") self.logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) self.logger.addHandler(ch) def create_jid(self, jid): """Creates an apropiate jid""" jid_ = JID(jid) if not jid_.resource: return JID(jid_.node, jid_.domain, self.__class__.__name__) return jid_ def session_started(self): """Triggered when the session starts. Sets some event handlers and connects to indicated rooms """ JabberClient.session_started(self) self.stream.set_message_handler("chat", self.chat_received) self.stream.set_message_handler("error", self.error_received) self.stream.set_presence_handler(None, self.presence_received) self.stream.set_presence_handler("unavailable", self.unavailable_received) self.stream.set_presence_handler("subscribe", self.subscription_received) self.stream.set_presence_handler("unsubscribe", self.subscription_received) self.stream.set_presence_handler("subscribed", self.subscription_received) self.stream.set_presence_handler("unsubscribed", self.subscription_received) self.logger.info("Session started") self.mucman = MucRoomManager(self.stream) self.mucman.set_handlers() for room in self.rooms_to_join: self.join_room(JID(room)) def join_room(self, jid): """Joins the room jid, starting a new thread for its messages""" room_jid = JID(jid) handler = RoomHandler(self) self.mucman.join(room_jid, self.nick, handler) room_state = handler.room_state self.start_conversation(room_jid, "groupchat", room_state) def start_conversation(self, jid, type="chat", room_state=None): """Spans a new thread for a new conversation, which is associated to jid Checks if the jid is allowed to use the application using user_control """ if not self.user_control(jid): self.send( Message(to_jid=jid, stanza_type=type, from_jid=self.jid, body="You are not allowed to talk with me")) return False queue_out = Queue.Queue(5) queue_in = Queue.Queue(5) self.conversations[jid] = ConversationQueues(queue_in, queue_out) Conversation(jid, self.__starter, self.__starter_params, ConversationQueues(queue_out, queue_in), type, room_state).start() self.logger.info("Started new conversation with %s@%s", jid.node, jid.domain) self.logger.debug("Thread list: %s", threading.enumerate()) return True def chat_received(self, stanza): """Handler for chat messages""" self.logger.info("Received %s ", stanza.serialize()) if not stanza.get_body(): self.logger.info("Message was empty") return if stanza.get_from() not in self.conversations.keys(): if not self.start_conversation(stanza.get_from()): return self.conversations[stanza.get_from()].queue_out.put( messagetypes.StanzaMessage(stanza.copy())) def groupchat_received(self, user, stanza): """Handler for groupchat messages""" self.logger.info("Received %s message from %s", stanza.get_type(), stanza.get_from().as_string()) if not stanza.get_body(): self.logger.info("Message was empty") return self.conversations[stanza.get_from().bare()].queue_out.put( messagetypes.StanzaMessage(stanza.copy())) def process_conversation_message(self, ans): """Process any kind of message stanza coming from a conversation""" if ans.__class__ == messagetypes.EndMessage: self.send(ans.stanza) del self.conversations[ans.stanza.get_to()] self.logger.info("Conversation with %s@%s/%s ended", ans.stanza.get_to().node, ans.stanza.get_to().domain, ans.stanza.get_to().resource) elif ans.__class__ == messagetypes.NoMessage: return else: self.send(ans.stanza) def check_for_messages(self): """Checks if messages from conversations are available. If so calls process_received to process them """ for jid, queues in self.conversations.items(): try: ans = queues.queue_in.get(False) if ans: self.process_conversation_message(ans) except Queue.Empty: pass def subscription_received(self, stanza): """Handler for subscription stanzas""" self.logger.info("Received %s request from %s", stanza.get_type(), stanza.get_from()) if self.user_control(stanza.get_from()): self.send(stanza.make_accept_response()) else: self.send(stanza.make_deny_response()) def presence_received(self, stanza): """Handler for initial presence received from users""" if stanza.get_from() in self.conversations: return if not self.start_on_user_connect: return if not self.start_conversation(stanza.get_from()): return self.conversations[stanza.get_from()].queue_out.put( messagetypes.UserConnected()) def unavailable_received(self, stanza): """Handler for unavailable presence received from users""" if not stanza.get_from() in self.conversations: return self.conversations[stanza.get_from()].queue_out.put( messagetypes.UserDisconnected()) def error_received(self, stanza): """Handler for error messages""" print stanza.get_body() def send(self, stanza): """Replies to a stanza""" self.logger.debug("stanza to send: %s", stanza.serialize()) self.stream.send(stanza) def start(self): """Connects to the server and starts waiting for input""" self.connect() self.loop() def loop(self, timeout=1): """Loop method, waits for client input and reacts to it""" while 1: stream = self.get_stream() if not stream: break act = stream.loop_iter(timeout) self.check_for_messages() if not act: self.idle()
class Core(JabberClient): """Core of the framework, handles connections and dispatches messages to the corresponding Conversation""" def __init__(self, config_path): """Initializes the bot with data from a configuration file jid (node@domain) and it's password. starter and starter_params are the class of the first controller to be used and it's params. If none is provided a default controller will be used. user_control is a function to determine if a user should be accepted if he requests so with a suscribe presence stanza. Must return True/False """ self.initialize_logger() self.config = configparser.Config(config_path) self.conversations = {} self.user_control = self.config.user_control self.jid = self.create_jid(self.config.jid) self.nick = self.config.nick self.__starter = self.config.starter self.__starter_params = self.config.starter_params self.rooms_to_join = self.config.rooms_to_join self.start_on_user_connect = self.config.start_on_user_connect JabberClient.__init__(self, self.jid, self.config.password) def initialize_logger(self): """Initializes logger""" self.logger = logging.getLogger("logger") self.logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) self.logger.addHandler(ch) def create_jid(self, jid): """Creates an apropiate jid""" jid_ = JID(jid) if not jid_.resource: return JID(jid_.node, jid_.domain, self.__class__.__name__) return jid_ def session_started(self): """Triggered when the session starts. Sets some event handlers and connects to indicated rooms """ JabberClient.session_started(self) self.stream.set_message_handler("chat", self.chat_received) self.stream.set_message_handler("error", self.error_received) self.stream.set_presence_handler(None,self.presence_received) self.stream.set_presence_handler("unavailable",self.unavailable_received) self.stream.set_presence_handler("subscribe",self.subscription_received) self.stream.set_presence_handler("unsubscribe",self.subscription_received) self.stream.set_presence_handler("subscribed",self.subscription_received) self.stream.set_presence_handler("unsubscribed",self.subscription_received) self.logger.info("Session started") self.mucman = MucRoomManager(self.stream) self.mucman.set_handlers() for room in self.rooms_to_join: self.join_room(JID(room)) def join_room(self, jid): """Joins the room jid, starting a new thread for its messages""" room_jid=JID(jid) handler = RoomHandler(self) self.mucman.join(room_jid, self.nick, handler) room_state = handler.room_state self.start_conversation(room_jid, "groupchat", room_state) def start_conversation(self, jid, type="chat", room_state = None): """Spans a new thread for a new conversation, which is associated to jid Checks if the jid is allowed to use the application using user_control """ if not self.user_control(jid): self.send(Message(to_jid=jid, stanza_type=type, from_jid=self.jid, body="You are not allowed to talk with me")) return False queue_out = Queue.Queue(5) queue_in = Queue.Queue(5) self.conversations[jid] = ConversationQueues(queue_in, queue_out) Conversation(jid, self.__starter, self.__starter_params, ConversationQueues(queue_out, queue_in), type, room_state ).start() self.logger.info("Started new conversation with %s@%s", jid.node, jid.domain) self.logger.debug("Thread list: %s", threading.enumerate()) return True def chat_received(self, stanza): """Handler for chat messages""" self.logger.info("Received %s ",stanza.serialize()) if not stanza.get_body(): self.logger.info("Message was empty") return if stanza.get_from() not in self.conversations.keys(): if not self.start_conversation(stanza.get_from()): return self.conversations[stanza.get_from()].queue_out.put(messagetypes.StanzaMessage(stanza.copy())) def groupchat_received(self, user, stanza): """Handler for groupchat messages""" self.logger.info("Received %s message from %s", stanza.get_type(), stanza.get_from().as_string()) if not stanza.get_body(): self.logger.info("Message was empty") return self.conversations[stanza.get_from().bare()].queue_out.put(messagetypes.StanzaMessage(stanza.copy())) def process_conversation_message(self, ans): """Process any kind of message stanza coming from a conversation""" if ans.__class__ == messagetypes.EndMessage: self.send(ans.stanza) del self.conversations[ans.stanza.get_to()] self.logger.info("Conversation with %s@%s/%s ended", ans.stanza.get_to().node, ans.stanza.get_to().domain, ans.stanza.get_to().resource) elif ans.__class__ == messagetypes.NoMessage: return else: self.send(ans.stanza) def check_for_messages(self): """Checks if messages from conversations are available. If so calls process_received to process them """ for jid, queues in self.conversations.items(): try: ans = queues.queue_in.get(False) if ans: self.process_conversation_message(ans) except Queue.Empty: pass def subscription_received(self, stanza): """Handler for subscription stanzas""" self.logger.info("Received %s request from %s", stanza.get_type(), stanza.get_from()) if self.user_control(stanza.get_from()): self.send(stanza.make_accept_response()) else: self.send(stanza.make_deny_response()) def presence_received(self, stanza): """Handler for initial presence received from users""" if stanza.get_from() in self.conversations: return if not self.start_on_user_connect: return if not self.start_conversation(stanza.get_from()): return self.conversations[stanza.get_from()].queue_out.put(messagetypes.UserConnected()) def unavailable_received(self, stanza): """Handler for unavailable presence received from users""" if not stanza.get_from() in self.conversations: return self.conversations[stanza.get_from()].queue_out.put(messagetypes.UserDisconnected()) def error_received(self, stanza): """Handler for error messages""" print stanza.get_body() def send(self, stanza): """Replies to a stanza""" self.logger.debug("stanza to send: %s", stanza.serialize()) self.stream.send(stanza) def start(self): """Connects to the server and starts waiting for input""" self.connect() self.loop() def loop(self, timeout=1): """Loop method, waits for client input and reacts to it""" while 1: stream = self.get_stream() if not stream: break act = stream.loop_iter(timeout) self.check_for_messages() if not act: self.idle()
class Client(JabberClient): ''' Simple bot (client) example. Uses `pyxmpp.jabber.client.JabberClient` class as base. That class provides basic stream setup (including authentication) and Service Discovery server. It also does server address and port discovery based on the JID provided. ''' def __init__(self, jid, password, server, port=5222, channel=None, tls_cacerts=None, listener=None): self._jid = jid self._server = server self._port = port self._channel = channel self._listener = listener # if bare JID is provided add a resource -- it is required if not self._jid.resource: self._jid = JID(self._jid.node, self._jid.domain, "Echobot") if tls_cacerts: if tls_cacerts == 'tls_noverify': tls_settings = TLSSettings(require=True, verify_peer=False) else: tls_settings = TLSSettings(require=True, cacert_file=tls_cacerts) else: tls_settings = None # setup client with provided connection information # and identity data JabberClient.__init__(self, jid=self._jid, password=password, disco_name="Datenverarbeitungseinheit Z45", disco_type="z45", tls_settings=tls_settings) ''' JabberClient.__init__(self, jid, password, disco_name="Datenverarbeitungseinheit Z45", disco_type="z45", tls_settings = tls_settings) ''' # add the separate components self.interface_providers = [ VersionHandler(self), EchoHandler(self), ] def session_started(self): """Handle session started event. May be overriden in derived classes. This one requests the user's roster and sends the initial presence.""" print u'SESSION STARTED' self.request_roster() p = Presence() self.stream.send(p) print u'ConnectToParty' if self._channel: self.connectToMUC() def connectToMUC(self): self._roomManager = MucRoomManager(self.stream) self._roomHandler = ChatHandler( JID(self._channel, self._server, self._jid.node), self._listener) self._roomState = self._roomManager.join(room=JID(self._channel + "@" + self._server), nick='z45', handler=self._roomHandler, history_maxchars=0, password=None) self._roomManager.set_handlers() #self._roomState.send_message("Sending this Message") def stream_state_changed(self, state, arg): ''' This one is called when the state of stream connecting the component to a server changes. This will usually be used to let the user know what is going on. ''' print "*** State changed: %s %r ***" % (state, arg) def print_roster_item(self, item): if item.name: name = item.name else: name = u"" print(u'%s "%s" subscription=%s groups=%s' % (unicode( item.jid), name, item.subscription, u",".join(item.groups))) def roster_updated(self, item=None): if not item: print(u"My roster:") for item in self.roster.get_items(): self.print_roster_item(item) return print u"Roster item updated:" self.print_roster_item(item)
class IAJabberBot(JabberClient): def __init__(self, conf): # Various config file bits we'll need jid_node = conf.get('login', 'nick') jid_domain = conf.get('jabber', 'domain') jabber_server = conf.get('jabber', 'server') jabber_port = conf.getint('jabber', 'port') # Game config game_product = conf.getint('game', 'productid') game_instance = conf.getint('game', 'instanceid') game_maplist = conf.get('game', 'maplist') game_maprotation = conf.get('game', 'maprotation') game_port = conf.getint('game', 'port') game_mode = conf.get('game', 'mode') game_timelimit = conf.getint('game', 'timelimit') game_scorelimit = conf.getint('game', 'scorelimit') game_autostart = conf.getboolean('game', 'autostart') game_tournament = conf.getboolean('game', 'tournament') game_lt = conf.getboolean('game', 'lt') game_grenades = conf.getboolean('game', 'grenades') # Listener options listen_pid = conf.getint('listener', 'pid') listen_tcpip = conf.getboolean('listener', 'tcpip') listen_ip = conf.get('listener', 'ip') listen_port = conf.getint('listener', 'port') # Stats config stats_enabled = conf.getboolean('stats', 'enabled') stats_urls = conf.get('stats', 'urls') stats_retry = conf.getint('stats', 'retry') stats_db = conf.get('stats', 'db') # Login config username = conf.get('login', 'username') password = conf.get('login', 'password') nickname = conf.get('login', 'nick') login_cache = conf.get('login', 'cache') browser_agent = conf.get('browser', 'agent') homepage_url = conf.get('browser', 'homepage') login_url = conf.get('browser', 'login') # Party config self.party_allowinvites = conf.getboolean('party', 'allowinvites') self.party_maxusers = conf.getint('party', 'maxusers') self.party_membersonly = conf.getboolean('party', 'membersonly') self.party_autoload = conf.getboolean('party', 'autoload') self.party_domain = conf.get('jabber', 'parties') self.party_gamesdomain = conf.get('jabber', 'games') self.party_gamename = conf.get('jabber', 'gamename') party_admins_conf = conf.get('party', 'admins') self.party_admins = party_admins_conf.lower().split(' ') # Generate us some randomish things we'll be needing self.ia_clientresource = u'%s_%d' % ( ''.join([random.choice('0123456789abcdef') for x in range(32)]), time.time()) self.ia_partyresource = u'%s%s%d' % ( nickname, ''.join([random.choice('0123456789abcdef') for x in range(32)]), time.time()) # Need a ticket with our login details ia_login = IALogin(browser_agent, homepage_url, login_url, login_cache) ticket = ia_login.login(username, password) # Setup the client jid = JID(jid_node, jid_domain, self.ia_clientresource) JabberClient.__init__( self, jid, ticket, server=jabber_server, port=jabber_port, auth_methods=('sasl:PLAIN',), keepalive=10) self.stream_class = ClientStreamAsyncore # games JID self.game_jid = JID(u'%s/game' % unicode(self.jid)) self.gamelist_jid = JID( u'%s@%s/%s' % (jid_node, self.party_gamesdomain, self.party_gamename)) # add the separate components self.interface_providers = [ GameHandler(self), MessageHandler(self), ] # Game handler deals with the game messages and game status self.game_handler = IAGameHandler(self.message_from_shazbot) # Register maps and map rotation with the handler maps = csv.reader(open(game_maplist)) for i in maps: self.game_handler.register_map(i[0], i[1], int(i[2])) map_rotation = csv.reader(open(game_maprotation)) for i in map_rotation: self.game_handler.add_rotation(i[0], int(i[1]), int(i[2])) # Start up the stats thread if enabled, register with the game handler if stats_enabled: stats_urllist = stats_urls.split(' ') self.stats_thread = StatsThread(stats_db, stats_urllist, stats_retry) self.stats_thread.start() else: self.stats_thread = None self.game_handler.stats_thread = self.stats_thread # Other game settings self.game_handler.port = game_port self.game_handler.login = nickname self.game_handler.mode_name = game_mode self.game_handler.timelimit = game_timelimit self.game_handler.scorelimit = game_scorelimit self.game_handler.autostart = game_autostart self.game_handler.tournament = game_tournament self.game_handler.lt = game_lt self.game_handler.grenades = game_grenades # Game listener accepts connections for the game handler self.game_listener = IAGameListener( game_handler=self.game_handler, product=game_product, instance=game_instance) if listen_tcpip: self.game_listener.setup_tcpip((listen_ip, listen_port)) else: # Auto detect pid if -1 is given, only useful to specify if game runs under another uid if listen_pid == -1: self.game_listener.setup_unix() else: self.game_listener.setup_unix(listen_pid) def stream_state_changed(self, state, arg): print "*** State changed: %s %r ***" % (state, arg) def print_roster_item(self, item): if item.name: name = item.name else: name = u"" print '%s "%s" subscription=%s groups=%s' % ( unicode(item.jid), name, item.subscription, u",".join(item.groups)) def roster_updated(self, item=None): if not item: print u"My roster:" for item in self.roster.get_items(): self.print_roster_item(item) return print u"Roster item updated:" self.print_roster_item(item) def session_started(self): JabberClient.session_started(self) self.room_manager = MucRoomManager(self.stream) self.room_manager.set_handlers() self.ia_party = ShazbotParty( bot=self, game_handler=self.game_handler, game_jid=self.game_jid, gamelist_jid=self.gamelist_jid, bot_nick=self.jid.node, autoload=self.party_autoload, allow_invites=self.party_allowinvites, size_limit=self.party_maxusers) self.ia_party.commands.admins = self.party_admins room_id = JID(self.ia_partyresource, self.party_domain) self.ia_shazbotjid = room_id new_party = self.room_manager.join(room_id, self.jid.node, self.ia_party) new_party.request_configuration_form() # Iq response goes directly to the game def game_iq_success(self, stanza): self.message_to_shazbot(stanza) # Iq response goes directly to the game def game_iq_error(self, stanza): self.message_to_shazbot(stanza) # Outgoing messages to shazbots def message_to_shazbot(self, stanza): def clean_node(node): node.setNs(None) for i in xmlextra.xml_node_iter(node.children): clean_node(i) # Simplify the to JID if stanza.get_to_jid() == self.game_jid: stanza.set_to(u'game') # This cleans up all the extra junk nsdefs clean_node(stanza.xmlnode) stanza.xmlnode.removeNsDef(None) s = xmlextra.safe_serialize(stanza.xmlnode) self.game_handler.send_badfood(s) # Incoming messages from shazbots def message_from_shazbot(self, data): doc = libxml2.parseDoc(data) node = doc.getRootElement() # Change the from to the full JID stanza = stanza_factory(node) stanza.set_from(self.game_jid) stream = self.get_stream() # Have to register Iq stanzas or we'll lose the reply if stanza.stanza_type == 'iq': if stanza.get_type() in ('get', 'set'): stream.set_response_handlers(stanza, self.game_iq_success, self.game_iq_error) stream.send(stanza) doc.freeDoc() # Extending idle with whatever extra bits we need to do def idle(self): JabberClient.idle(self) if self.game_handler.countdown: self.game_handler.countdown_step()
class Client(JabberClient): ''' Simple bot (client) example. Uses `pyxmpp.jabber.client.JabberClient` class as base. That class provides basic stream setup (including authentication) and Service Discovery server. It also does server address and port discovery based on the JID provided. ''' def __init__(self, jid, password, server, port=5222, channel=None, tls_cacerts=None, listener=None): self._jid = jid self._server = server self._port = port self._channel = channel self._listener = listener # if bare JID is provided add a resource -- it is required if not self._jid.resource: self._jid=JID(self._jid.node, self._jid.domain, "Echobot") if tls_cacerts: if tls_cacerts == 'tls_noverify': tls_settings = TLSSettings(require = True, verify_peer = False) else: tls_settings = TLSSettings(require = True, cacert_file = tls_cacerts) else: tls_settings = None # setup client with provided connection information # and identity data JabberClient.__init__(self, jid=self._jid, password=password, disco_name="Datenverarbeitungseinheit Z45", disco_type="z45", tls_settings=tls_settings) ''' JabberClient.__init__(self, jid, password, disco_name="Datenverarbeitungseinheit Z45", disco_type="z45", tls_settings = tls_settings) ''' # add the separate components self.interface_providers = [ VersionHandler(self), EchoHandler(self), ] def session_started(self): """Handle session started event. May be overriden in derived classes. This one requests the user's roster and sends the initial presence.""" print u'SESSION STARTED' self.request_roster() p=Presence() self.stream.send(p) print u'ConnectToParty' if self._channel: self.connectToMUC() def connectToMUC(self): self._roomManager = MucRoomManager(self.stream); self._roomHandler = ChatHandler(JID(self._channel, self._server, self._jid.node), self._listener) self._roomState = self._roomManager.join( room=JID(self._channel + "@" + self._server), nick='z45', handler=self._roomHandler, history_maxchars=0, password = None) self._roomManager.set_handlers() #self._roomState.send_message("Sending this Message") def stream_state_changed(self,state,arg): ''' This one is called when the state of stream connecting the component to a server changes. This will usually be used to let the user know what is going on. ''' print "*** State changed: %s %r ***" % (state,arg) def print_roster_item(self,item): if item.name: name=item.name else: name=u"" print (u'%s "%s" subscription=%s groups=%s' % (unicode(item.jid), name, item.subscription, u",".join(item.groups)) ) def roster_updated(self,item=None): if not item: print(u"My roster:") for item in self.roster.get_items(): self.print_roster_item(item) return print u"Roster item updated:" self.print_roster_item(item)
class Client(JabberClient): def __init__(self, jid, password, tls_cacerts = None): if tls_cacerts is None: tls_cacerts = 'tls_noverify' # if bare JID is provided add a resource -- it is required if not jid.resource: jid=JID(jid.node, jid.domain, "Echobot") if tls_cacerts: if tls_cacerts == 'tls_noverify': tls_settings = TLSSettings(require = True, verify_peer = False) else: tls_settings = TLSSettings(require = True, cacert_file = tls_cacerts) else: tls_settings = None # setup client with provided connection information # and identity data JabberClient.__init__(self, jid, password, disco_name="PyXMPP example: echo bot", disco_type="bot", tls_settings = tls_settings) # add the separate components # self.interface_providers = [ # VersionHandler(self), # EchoHandler(self), # ] def session_started(self): """Handle session started event. May be overriden in derived classes. This one requests the user's roster and sends the initial presence.""" print u'SESSION STARTED' self.request_roster() print u'ConnectToParty' self.connectToMUC() def stream_state_changed(self,state,arg): """This one is called when the state of stream connecting the component to a server changes. This will usually be used to let the user know what is going on.""" print "*** State changed: %s %r ***" % (state,arg) def print_roster_item(self,item): if item.name: name=item.name else: name=u"" print (u'%s "%s" subscription=%s groups=%s' % (unicode(item.jid), name, item.subscription, u",".join(item.groups)) ) def roster_updated(self,item=None): if not item: print u"My roster:" for item in self.roster.get_items(): self.print_roster_item(item) return print u"Roster item updated:" self.print_roster_item(item) def connectToMUC(self): self.roomManager = MucRoomManager(self.stream); self.roomHandler = MucRoomHandler() self.roomState = self.roomManager.join( room=JID('*****@*****.**'), nick='mindcat', handler=self.roomHandler, history_maxchars=0, password = None) self.roomManager.set_handlers() self.roomState.send_message("喵喵喵喵!")
class AsyncJabberClient(JabberClient): def __init__(self, jid, password, **options): if not isinstance(jid, JID): jid = JID(jid) self.jid = jid self.rooms = {} kwargs = { 'tls_settings': streamtls.TLSSettings(require=True, verify_peer=False), 'auth_methods': ('sasl:PLAIN',), 'disco_name': "pyjirc", 'disco_type': "bot" } kwargs.update(options) JabberClient.__init__(self, jid, password, **kwargs) self.disco_info.add_feature("jabber:iq:version") def tick(self, timeout=1): stream = self.get_stream() if not stream: return -1 ret = stream.loop_iter(timeout) if not ret: self.idle() def session_started(self): JabberClient.session_started(self) self.room_manager = MucRoomManager(self.stream) handle_presence = getattr(self, 'handle_presence', None) if callable(handle_presence): self.stream.set_presence_handler(None, handle_presence) #self.stream.set_presence_handler('subscribed', handle_presence) #self.stream.set_presence_handler('unsubscribe', handle_presence) #self.stream.set_presence_handler('unsubscribed', handle_presence) handle_message = getattr(self, 'handle_message', None) if callable(handle_message): self.stream.set_message_handler('normal', handle_message) handle_connect = getattr(self, 'handle_connect', None) if callable(handle_connect): handle_connect() def handle_presence(self, stanza): if stanza.get_type() in ('subscribe','subscribed','unsubscribe','unsubscribed'): self.stream.send(stanza.make_accept_response()) return True return False def handle_message(self, stanza): return True def handle_connect(self): return True def join_room(self, jid, nick=None, handler=None, **options): if not isinstance(jid, JID): jid = JID(jid) if nick is None: nick = self.jid.node kwargs = { 'history_maxchars': 0, } kwargs.update(options) if jid in self.rooms: return if handler is None: handler = MucRoomHandler() self.rooms[jid] = self.room_manager.join(jid, nick, handler, **kwargs)