def __init__(self, jid, password, room, nick): print('creating bot with {} {} {} {} '.format(jid, password, room, nick)) self.nick = nick self.room = room self.jid = JID(jid) self._presence_callbacks = [] self._message_callbacks = [] bot = ClientXMPP(jid, password) bot.add_event_handler('session_start', self.on_start) bot.add_event_handler('message', self.on_message) bot.add_event_handler('groupchat_presence', self.on_presence) bot.register_plugin('xep_0045') self._muc = bot.plugin['xep_0045'] bot.register_plugin('xep_0199') bot.plugin['xep_0199'].enable_keepalive(30, 30) self.unknown_command_callback = None def on_unknown_callback(message): if self.unknown_command_callback is not None: return self.unknown_command_callback(message) self.message_processor = MessageProcessor(on_unknown_callback) print('sb connect') if bot.connect(): print('sb process') bot.process() else: raise 'could not connect' self._bot = bot
class FoosBot(object): def __init__(self, jid, password): # we set this as an attribute instead of sublcassing because many # of ClientXMPP's attributes are named something we might accidentally # overrite (breaking ClientXMPP). it's happened to me quite a bit self.xmpp = ClientXMPP(jid, password) self.xmpp.add_event_handler("session_start", self._session_start_handler) self.xmpp.add_event_handler("message", self._message_handler) self.xmpp.register_plugin('xep_0030') # Service Discovery self.xmpp.register_plugin('xep_0199') # XMPP Ping self.match_requested = False self.active_players = {} self.match_players = [] self.state_machines = {} def start(self): self.xmpp.connect(('talk.google.com', 5222)) self.xmpp.process(block=True) def _session_start_handler(self, event): self.xmpp.send_presence() # Most get_*/set_* methods from plugins use Iq stanzas, which # can generate IqError and IqTimeout exceptions try: self.xmpp.get_roster() except IqError as err: logging.error('There was an error getting the roster') logging.error(err.iq['error']['condition']) self.xmpp.disconnect() except IqTimeout: logging.error('Server is taking too long to respond') self.xmpp.disconnect() def _message_handler(self, msg): if msg['type'] not in ('chat', 'normal'): # TODO Add logging return sender = str(msg["from"]).split("/")[0] body = str(msg["body"]).strip().lower() game_creator = self.state_machines.get(sender) if not game_creator: self.state_machines[sender] = GameCreator(sender) game_creator = self.state_machines.get(sender) reply = game_creator.handle_message(sender, body) if reply: self.send(sender, reply) def send(self, to, message): if not isinstance(to, (tuple, list)): to = [to] message = str(message) # evaluates Template, if it exists for player in to: self.xmpp.send_message(player, message)
def setup_xmpp_client(self, jid: str, password: str, proxy: Dict = None) -> ClientXMPP: """Setup XMPP client and return its instance. :param jid: JID provided by HipChat. :param password: Password provided by HipChat. :param proxy: Proxy setting in dictionary. :return: ClientXMPP instance """ client = ClientXMPP(jid, password) if proxy: client.use_proxy = True for key in ('host', 'port', 'username', 'password'): client.proxy_config[key] = proxy.get(key, None) # TODO check later # client.add_event_handler('ssl_invalid_cert', lambda cert: True) client.add_event_handler('session_start', self.session_start) client.add_event_handler('roster_update', self.join_rooms) client.add_event_handler('message', self.message) client.register_plugin('xep_0045') client.register_plugin('xep_0203') return client
class Connection(object): def __init__(self): settings = Settings('tellduslive.config') uuid = settings['uuid'] self.xmpp = ClientXMPP('*****@*****.**' % uuid, '%s:%s' % (self.getMacAddr(), Board.secret())) self.xmpp.add_event_handler("session_start", self.sessionStart) self.xmpp.add_event_handler("register", self.register) self.xmpp.register_plugin('xep_0030') # Service Discovery self.xmpp.register_plugin('xep_0077') # In-band registration self.shuttingDown = False # Connect is blocking. Do this in a separate thread threading.Thread(target=self.__start, name='XMPP connector').start() def register(self, form): del form # Unused resp = self.xmpp.Iq() resp['type'] = 'set' resp['register']['username'] = self.xmpp.boundjid.user resp['register']['password'] = self.xmpp.password try: resp.send(now=True) return except IqError as error: code = error.iq['error']['code'] if code == '409': # Already exists, this is ok return except IqTimeout: logging.warning("IQ timeout") logging.warning("Could not register, disconnect!") self.shutdown() def sessionStart(self, event): del event self.xmpp.send_presence() self.xmpp.get_roster() def shutdown(self): self.shuttingDown = True self.xmpp.disconnect() def __start(self): self.xmpp.connect() self.xmpp.process(block=False) if self.shuttingDown: self.xmpp.disconnect() @staticmethod def getMacAddr(): addrs = netifaces.ifaddresses(Board.networkInterface()) try: mac = addrs[netifaces.AF_LINK][0]['addr'] except (IndexError, KeyError): return '' return mac.upper().replace(':', '')
def _execute_xmpp(connected_callback): """Connects to the XMPP server and executes custom code :param connected_callback: function to execute after connecting :return: return value of the callback """ from indico_chat.plugin import ChatPlugin check_config() jid = ChatPlugin.settings.get('bot_jid') password = ChatPlugin.settings.get('bot_password') if '@' not in jid: jid = '{}@{}'.format(jid, ChatPlugin.settings.get('server')) result = [None, None] # result, exception app = current_app._get_current_object() # callback runs in another thread def _session_start(event): try: with app.app_context(): result[0] = connected_callback(xmpp) except Exception as e: result[1] = e if isinstance(e, IqError): current_plugin.logger.exception('XMPP callback failed: %s', e.condition) else: current_plugin.logger.exception('XMPP callback failed') finally: xmpp.disconnect(wait=0) xmpp = ClientXMPP(jid, password) xmpp.register_plugin('xep_0045') xmpp.register_plugin('xep_0004') xmpp.register_plugin('xep_0030') xmpp.add_event_handler('session_start', _session_start) try: xmpp.connect() except Exception: current_plugin.logger.exception('XMPP connection failed') xmpp.disconnect() raise try: xmpp.process(threaded=False) finally: xmpp.disconnect(wait=0) if result[1] is not None: raise result[1] return result[0]
def __init__(self, jid, password, room, nick, address=()): log.info('creating bot with {} {} {} {} {}' .format(jid, password, room, nick, address)) self.nick = nick self.room = room self.jid = JID(jid) self._presence_callbacks = [] self._message_callbacks = [] bot = ClientXMPP(jid, password) # disable ipv6 for now since we're getting errors using it bot.use_ipv6 = False # Fix certain Jabber clients not showing messages by giving them an ID bot.use_message_ids = True # Don't try to auto reconnect after disconnections (we'll restart the # process and retry that way) bot.auto_reconnect = False bot.add_event_handler('session_start', self.on_start) bot.add_event_handler('message', self.on_message) bot.add_event_handler('groupchat_presence', self.on_presence) bot.add_event_handler('groupchat_subject', self.on_room_joined) bot.add_event_handler('disconnected', self.on_disconnect) bot.register_plugin('xep_0045') self._muc = bot.plugin['xep_0045'] bot.register_plugin('xep_0199') bot.plugin['xep_0199'].enable_keepalive(5, 10) self.unknown_command_callback = None def on_unknown_callback(message): if self.unknown_command_callback is not None: return self.unknown_command_callback(message) self.message_processor = MessageProcessor(on_unknown_callback) log.info('sb connect') if bot.connect(address=address, reattempt=False): log.info('sb process') bot.process() else: log.error('failed to connect at first attempt') self.on_disconnect(None) self.add_presence_handler(self.rejoin_if_kicked) self._bot = bot
def make_xmpp_client(connection_info: LoginConfig): client = ClientXMPP('%s@%s' % (connection_info.user, connection_info.host), connection_info.password) client.use_signals() # TODO: Make sure all events are handled, and check if we should support other XEPs. client.register_plugin('xep_0030') # Service Discovery client.register_plugin('xep_0045') # Multi-User Chat client.register_plugin('xep_0085') # Chat State Notifications client.register_plugin('xep_0199') # XMPP Ping # TODO: Use XEP 0079 to add delivery failure notifications once the sleekxmpp plugin for this XEP is released. # client.register_plugin('xep_0079') # Advanced Message Processing return client
class XMPPConnection(Connection): def __init__(self, jid, password): self.connected = False self.client = ClientXMPP(jid, password, plugin_config={'feature_mechanisms': XMPP_FEATURE_MECHANISMS}) self.client.register_plugin('xep_0030') # Service Discovery self.client.register_plugin('xep_0045') # Multi-User Chat self.client.register_plugin('xep_0199') # XMPP Ping self.client.register_plugin('xep_0203') # XMPP Delayed messages self.client.add_event_handler("session_start", self.session_start) def send_message(self, mess): self.client.send_message(mto=mess.getTo(), mbody=mess.getBody(), mtype=mess.getType(), mhtml=mess.getHTML()) def session_start(self, event): self.client.send_presence() self.client.get_roster() def connect(self): if not self.connected: self.client.connect() self.connected = True return self def disconnect(self): self.client.disconnect(wait=True) self.connected = False def serve_forever(self): self.client.process(block=True) def add_event_handler(self, name, cb): self.client.add_event_handler(name, cb) def join_room(self, room, username, password): muc = self.client.plugin['xep_0045'] muc.joinMUC(room, username, password=password, wait=True) form = muc.getRoomForm(room) if form: muc.configureRoom(room, form) else: logging.error("Error configuring the MUC Room %s" % room)
def xmpp_connect(config): bot = ClientXMPP(config.username, config.password) bot.register_plugin('xep_0045') muc = bot.plugin['xep_0045'] bot.register_plugin('xep_0199') ping = bot.plugin['xep_0199'] ping.enable_keepalive(30, 30) bot.add_event_handler('session_start', join_rooms_on_connect_handler(bot, muc, config.muc_domain, config.chats, config.nickname)) bot.add_event_handler('message', on_message_handler(config)) if not bot.connect(): raise 'could not connect' # gevent should mean that we fall out of this method bot.process(block=True) return bot
def xmpp_connect(config): bot = ClientXMPP(config.username, config.password) bot.register_plugin('xep_0045') muc = bot.plugin['xep_0045'] bot.register_plugin('xep_0199') ping = bot.plugin['xep_0199'] ping.enable_keepalive(30, 30) bot.use_ipv6 = False bot.add_event_handler( 'session_start', join_rooms_on_connect_handler(bot, muc, config.muc_domain, config.chats, config.nickname)) bot.add_event_handler('message', on_message_handler(config)) if not bot.connect(): raise 'could not connect' return bot
def setup_connection(self, configuration): connection = ClientXMPP(configuration.jid, configuration.password) # xep_0045 MUC # xep_0199 XMPP Ping for plugin in ['xep_0045', 'xep_0199']: connection.register_plugin(plugin) for type_, handler in ( ('session_start', self.handle_start), ('groupchat_message', self.handle_message), ): connection.add_event_handler(type_, handler) connection_result = connection.connect(configuration.server) server = configuration.server if not connection_result: raise Exception('Unable to connect to %s' % (server,)) return connection
class XMPPConnection(object): def __init__(self, jid, password, feature=None, keepalive=None, ca_cert=None, server=None, use_ipv6=None, bot=None): if feature is None: feature = {} self._bot = bot self.connected = False self.server = server self.client = ClientXMPP(jid, password, plugin_config={'feature_mechanisms': feature}) self.client.register_plugin('xep_0030') # Service Discovery self.client.register_plugin('xep_0045') # Multi-User Chat self.client.register_plugin('xep_0199') # XMPP Ping self.client.register_plugin('xep_0203') # XMPP Delayed messages self.client.register_plugin('xep_0249') # XMPP direct MUC invites if keepalive is not None: self.client.whitespace_keepalive = True # Just in case SleekXMPP's default changes to False in the future self.client.whitespace_keepalive_interval = keepalive if use_ipv6 is not None: self.client.use_ipv6 = use_ipv6 self.client.ca_certs = ca_cert # Used for TLS certificate validation self.client.add_event_handler("session_start", self.session_start) def session_start(self, _): self.client.send_presence() self.client.get_roster() def connect(self): if not self.connected: if self.server is not None: self.client.connect(self.server) else: self.client.connect() self.connected = True return self def disconnect(self): self.client.disconnect(wait=True) self.connected = False def serve_forever(self): self.client.process(block=True) def add_event_handler(self, name, cb): self.client.add_event_handler(name, cb) def del_event_handler(self, name, cb): self.client.del_event_handler(name, cb)
def make_client(self): jid = 'admin@localhost' password = '******' client = ClientXMPP(jid, password) [client.register_plugin(plugin) for plugin in [ 'xep_0030', # Service discovery 'xep_0199', # XMPP Ping 'xep_0133', # Adhoc admin ]] client.connect(address=('localhost', self.port)) client.process(block=False) self.client = client return client
def make_client(self): jid = 'admin@localhost' password = '******' client = ClientXMPP(jid, password) [ client.register_plugin(plugin) for plugin in [ 'xep_0030', # Service discovery 'xep_0199', # XMPP Ping 'xep_0133', # Adhoc admin ] ] client.connect(address=('localhost', self.port)) client.process(block=False) self.client = client return client
class XMPPConnection(Connection): def __init__(self, jid, password): self.connected = False self.client = ClientXMPP( jid, password, plugin_config={'feature_mechanisms': XMPP_FEATURE_MECHANISMS}) self.client.register_plugin('xep_0030') # Service Discovery self.client.register_plugin('xep_0045') # Multi-User Chat self.client.register_plugin( 'old_0004' ) # Multi-User Chat backward compability (necessary for join room) self.client.register_plugin('xep_0199') # XMPP Ping self.client.register_plugin('xep_0203') # XMPP Delayed messages self.client.register_plugin('xep_0249') # XMPP direct MUC invites if XMPP_KEEPALIVE_INTERVAL is not None: self.client.whitespace_keepalive = True # Just in case SleekXMPP's default changes to False in the future self.client.whitespace_keepalive_interval = XMPP_KEEPALIVE_INTERVAL self.client.add_event_handler("session_start", self.session_start) self.client.add_event_handler("ssl_invalid_cert", self.ssl_invalid_cert) def send_message(self, mess): self.client.send_message(mto=mess.getTo(), mbody=mess.getBody(), mtype=mess.getType(), mhtml=mess.getHTML()) def session_start(self, _): self.client.send_presence() self.client.get_roster() def ssl_invalid_cert(self, _): # Special quirk for google domains verify_gtalk_cert(self.client) def connect(self): if not self.connected: self.client.connect() self.connected = True return self def disconnect(self): self.client.disconnect(wait=True) self.connected = False def serve_forever(self): self.client.process(block=True) def add_event_handler(self, name, cb): self.client.add_event_handler(name, cb) def join_room(self, room, username, password): muc = self.client.plugin['xep_0045'] muc.joinMUC(room, username, password=password, wait=True) form = muc.getRoomForm(room) if form: muc.configureRoom(room, form) else: logging.error("Error configuring the MUC Room %s" % room) def invite_in_room(self, room, jids_to_invite): muc = self.client.plugin['xep_0045'] for jid in jids_to_invite: logging.debug("Inviting %s to %s..." % (jid, room)) muc.invite(room, jid)
{ 'jid': And(str, len), Optional('password'): And(str, len) } ] } ) config = load_config('xmpp', schema) nickname = config.get('nickname', 'm5') client = ClientXMPP(config['jid'], config['password']) # Enable group chats client.register_plugin('xep_0045') # Group chat handlers def on_muc_online(stanza): if stanza['muc']['nick'] != nickname: LOG.info('{} joined the room!'.format(stanza['from'])) user = XMPPUser(client, stanza['from']) users[stanza['from'].full] = user dispatcher.fire('joined', StatusEventData(user)) role = stanza['muc']['affiliation'] if role in ['admin', 'owner']: permissions.grant(user.identity, permissions.SUPERUSER)
from contextlib import contextmanager from django.conf import settings from sleekxmpp import ClientXMPP from sleekxmpp.xmlstream import ET SERVER = settings.XMPP_SERVER ADMIN_USER = settings.XMPP_ADMIN_USER ADMIN_PASS = settings.XMPP_ADMIN_PASSWORD ADMIN_JID = '{}@{}'.format(ADMIN_USER, SERVER) ROOM_DOMAIN = 'conference.' + SERVER C = ClientXMPP(ADMIN_JID, ADMIN_PASS) C.connected = False C.register_plugin('xep_0133') C.register_plugin('old_0004') C.register_plugin('xep_0045') DROP_CONNECTIONS = False @contextmanager def xmpp(): try: if not C.connected or DROP_CONNECTIONS: C.connect() C.process() C.connected = True yield C finally: if DROP_CONNECTIONS:
class XmppFederationProtocol(FederationProtocol): """ Gestion des échanges sur le réseau fédéré avec le protocole XMPP Implémentation XMPP du FederationProtocol """ def __init__(self): """ PostConstruct """ self.configService = None self.appService = None self.xmpp = None self.messageHandler = None MonkeyPatch().patch_fromisoformat() def start(self): """ Démarre le service """ xmppDomain = self.configService.value("XMPP_DOMAIN_NAME") xmppUser = self.configService.value("XMPP_USERNAME") self.xmpp = ClientXMPP(xmppUser, self.configService.value("XMPP_PASSWORD")) # ajout des listeners et plugins self.xmpp.add_event_handler("session_start", self.session_start) self.xmpp.register_plugin('XmppMessagePlugin', module=xmpp) self.xmpp.register_handler( Callback( 'SEN1 Message', MatchXPath('{%s}message/{http://xmpp.rocks}Sen1Message' % self.xmpp.default_ns), self.receiveMessage)) register_stanza_plugin(Message, XmppMessageStanza) if (not self.xmpp.connect(address=(xmppDomain, 5222))): raise Exception("Cannot bind XMPP session to {}".format(xmppUser)) self.logger.info( "Start XMPP protocol : bind session {}...".format(xmppUser)) self.xmpp.process() def stop(self): """ Stoppe le service """ self.logger.info("Stop XMPP protocol...") self.xmpp.disconnect() def session_start(self, event): """ """ self.logger.info("XMPP session is started") self.xmpp.send_presence() self.xmpp.get_roster() def receiveMessage(self, stanza): """ Réception d'un message XMPP :param stanza: xmpp message """ self.logger.info("Receive SEN1 message from {}...".format( stanza['from'])) try: message = XmppMessageStanza.parse_xmpp_message(stanza) self.messageHandler.handle(message) except Exception as ex: self.logger.error("Receive SEN1 message : {}".format(ex)) def sendMessage(self, message): """ Envoi d'un message :param message: Message """ # vérifie la conformité du message avant envoi message.asserts() # recherche du JID de l'application destinataire app = self.appService.findByName(message.applicationDst) self.logger.info("Sending SEN1 message to {}...".format(app.jid)) # construction d'un message xmppMessage = self.xmpp.make_message(app.jid) XmppMessageStanza.build_xmpp_message(xmppMessage, message).send()
class XMPPConnection(Connection): def __init__(self, jid, password): self.connected = False self.client = ClientXMPP( jid, password, plugin_config={'feature_mechanisms': XMPP_FEATURE_MECHANISMS}) self.client.register_plugin('xep_0030') # Service Discovery self.client.register_plugin('xep_0045') # Multi-User Chat self.client.register_plugin( 'xep_0004' ) # Multi-User Chat backward compability (necessary for join room) self.client.register_plugin('xep_0199') # XMPP Ping self.client.register_plugin('xep_0203') # XMPP Delayed messages self.client.register_plugin('xep_0249') # XMPP direct MUC invites if XMPP_KEEPALIVE_INTERVAL is not None: self.client.whitespace_keepalive = True # Just in case SleekXMPP's default changes to False in the future self.client.whitespace_keepalive_interval = XMPP_KEEPALIVE_INTERVAL self.client.ca_certs = XMPP_CA_CERT_FILE # Used for TLS certificate validation self.client.add_event_handler("session_start", self.session_start) self.client.add_event_handler("ssl_invalid_cert", self.ssl_invalid_cert) def send_message(self, mess): self.client.send_message(mto=mess.getTo(), mbody=mess.getBody(), mtype=mess.getType(), mhtml=mess.getHTML()) def session_start(self, _): self.client.send_presence() self.client.get_roster() def ssl_invalid_cert(self, _): # Special quirk for google domains verify_gtalk_cert(self.client) def connect(self): if not self.connected: self.client.connect() self.connected = True return self def disconnect(self): self.client.disconnect(wait=True) self.connected = False def serve_forever(self): self.client.process(block=True) def add_event_handler(self, name, cb): self.client.add_event_handler(name, cb) def del_event_handler(self, name, cb): self.client.del_event_handler(name, cb) def join_room(self, room, username, password): """Attempt to join the given MUC""" muc = self.client.plugin['xep_0045'] muc.joinMUC(room, username, password=password, wait=True) # Room configuration can only be done once a MUC presence stanza # has been received from the server. This HAS to take place in a # separate thread because of how SleekXMPP processes these stanzas. t = Thread(target=self.configure_room, args=[room]) t.setDaemon(True) t.start() def configure_room(self, room): """ Configure the given MUC Currently this simply sets the default room configuration as received by the server. May be extended in the future to set a custom room configuration instead. """ muc = self.client.plugin['xep_0045'] affiliation = None while affiliation is None: sleep(0.5) affiliation = muc.getJidProperty(room=room, nick=muc.ourNicks[room], jidProperty='affiliation') if affiliation == "owner": logging.debug( "Configuring room {} because we have owner affiliation".format( room)) form = muc.getRoomConfig(room) muc.configureRoom(room, form) else: logging.debug( "Not configuring room {} because we don't have owner affiliation (affiliation={})" .format(room, affiliation)) def invite_in_room(self, room, jids_to_invite): muc = self.client.plugin['xep_0045'] for jid in jids_to_invite: logging.debug("Inviting %s to %s..." % (jid, room)) muc.invite(room, jid)
class XMPPConnection(object): def __init__(self, jid, password): self.connected = False self.client = ClientXMPP( str(jid), password, plugin_config={'feature_mechanisms': XMPP_FEATURE_MECHANISMS}) self.client.register_plugin('xep_0030') # Service Discovery self.client.register_plugin('xep_0045') # Multi-User Chat self.client.register_plugin( 'xep_0004' ) # Multi-User Chat backward compability (necessary for join room) self.client.register_plugin('xep_0199') # XMPP Ping self.client.register_plugin('xep_0203') # XMPP Delayed messages self.client.register_plugin('xep_0249') # XMPP direct MUC invites if XMPP_KEEPALIVE_INTERVAL is not None: self.client.whitespace_keepalive = True # Just in case SleekXMPP's default changes to False in the future self.client.whitespace_keepalive_interval = XMPP_KEEPALIVE_INTERVAL self.client.ca_certs = XMPP_CA_CERT_FILE # Used for TLS certificate validation self.client.add_event_handler("session_start", self.session_start) self.client.add_event_handler("ssl_invalid_cert", self.ssl_invalid_cert) def session_start(self, _): self.client.send_presence() self.client.get_roster() def ssl_invalid_cert(self, _): # Special quirk for google domains verify_gtalk_cert(self.client) def connect(self): if not self.connected: self.client.connect() self.connected = True return self def disconnect(self): self.client.disconnect(wait=True) self.connected = False def serve_forever(self): self.client.process(block=True) def add_event_handler(self, name, cb): self.client.add_event_handler(name, cb) def del_event_handler(self, name, cb): self.client.del_event_handler(name, cb) def join_room(self, room, username, password): """ Attempt to join the given MUC .. deprecated:: 2.2.0 Use the methods on :class:`XMPPMUCRoom` instead. """ warnings.warn( "Using join_room is deprecated, use join from the " "MUCRoom class instead.", DeprecationWarning) holder.bot.query_room(room).join(username=username, password=password) def configure_room(self, room): """ Configure the given MUC Currently this simply sets the default room configuration as received by the server. May be extended in the future to set a custom room configuration instead. .. deprecated:: 2.2.0 Use the methods on :class:`XMPPMUCRoom` instead. """ warnings.warn( "Using configure_room is deprecated, use configure from the " "MUCRoom class instead.", DeprecationWarning) holder.bot.query_room(room).configure() def invite_in_room(self, room, jids_to_invite): """ .. deprecated:: 2.2.0 Use the methods on :class:`XMPPMUCRoom` instead. """ warnings.warn( "Using invite_in_room is deprecated, use invite from the " "MUCRoom class instead.", DeprecationWarning, ) holder.bot.query_room(room).invite(jids_to_invite)
class XMPPConnection(Connection): def __init__(self, jid, password): self.connected = False self.client = ClientXMPP(jid, password, plugin_config={'feature_mechanisms': XMPP_FEATURE_MECHANISMS}) self.client.register_plugin('xep_0030') # Service Discovery self.client.register_plugin('xep_0045') # Multi-User Chat self.client.register_plugin('old_0004') # Multi-User Chat backward compability (necessary for join room) self.client.register_plugin('xep_0199') # XMPP Ping self.client.register_plugin('xep_0203') # XMPP Delayed messages self.client.register_plugin('xep_0249') # XMPP direct MUC invites if XMPP_KEEPALIVE_INTERVAL is not None: self.client.whitespace_keepalive = True # Just in case SleekXMPP's default changes to False in the future self.client.whitespace_keepalive_interval = XMPP_KEEPALIVE_INTERVAL self.client.ca_certs = XMPP_CA_CERT_FILE # Used for TLS certificate validation self.client.add_event_handler("session_start", self.session_start) self.client.add_event_handler("ssl_invalid_cert", self.ssl_invalid_cert) def send_message(self, mess): self.client.send_message(mto=mess.getTo(), mbody=mess.getBody(), mtype=mess.getType(), mhtml=mess.getHTML()) def session_start(self, _): self.client.send_presence() self.client.get_roster() def ssl_invalid_cert(self, _): # Special quirk for google domains verify_gtalk_cert(self.client) def connect(self): if not self.connected: self.client.connect() self.connected = True return self def disconnect(self): self.client.disconnect(wait=True) self.connected = False def serve_forever(self): self.client.process(block=True) def add_event_handler(self, name, cb): self.client.add_event_handler(name, cb) def join_room(self, room, username, password): muc = self.client.plugin['xep_0045'] muc.joinMUC(room, username, password=password, wait=True) form = muc.getRoomForm(room) if form: muc.configureRoom(room, form) else: logging.error("Error configuring the MUC Room %s" % room) def invite_in_room(self, room, jids_to_invite): muc = self.client.plugin['xep_0045'] for jid in jids_to_invite: logging.debug("Inviting %s to %s..." % (jid, room)) muc.invite(room, jid)
def send_chatroom_message(self, context, message): # Get context session = self.__get_session(context) res_id = context.reservation.reservation_id current_user = context.reservation.running_user admin_user, admin_password, api_server, api_port = self.__get_openfire_server_details( context, session) # Chatroom name is current sandbox name chatroom_name = session.GetReservationDetails( reservationId=res_id).ReservationDescription.Name # Chatroom ID is reservation id chatroom_id = res_id # Get XMPP domain value xmpp_domain = self.__get_xmpp_domain(server=api_server, port=api_port, user=admin_user, password=admin_password) # Construct full Jabber user id JID = "%s@%s" % (admin_user, xmpp_domain) session.WriteMessageToReservationOutput( context.reservation.reservation_id, "\nSending message to chat room \"%s\" as %s" % (chatroom_name, current_user)) xmpp = ClientXMPP(jid=JID, password=admin_password) xmpp.register_plugin('xep_0045') conn = xmpp.connect(use_ssl=False, use_tls=False, address=(api_server, '5222')) room = '%s@conference.%s' % (chatroom_id, xmpp_domain) # need to join chat room before sending message session.WriteMessageToReservationOutput( context.reservation.reservation_id, " Joining room") xmpp.plugin['xep_0045'].joinMUC( room, current_user, wait=True, ) # Send message to room xmpp.send_message(mtype='groupchat', mbody=message, mto=room, mnick=current_user) # Run commands above session.WriteMessageToReservationOutput( context.reservation.reservation_id, " Sending message \"%s\"" % message) session.WriteMessageToReservationOutput( context.reservation.reservation_id, "Completed") xmpp.process(block=False) # Ensure we have enough time to send the message before disconnecting time.sleep(5) xmpp.disconnect() pass
class LoginBot(object): def __init__(self, jid, pwd, mmongo_host, mong_db): self.jid = jid self.xmpp = ClientXMPP(jid, pwd) self.ehost = '127.0.0.1' self.eport = '5222' # data form self.xmpp.register_plugin('xep_0004') # service disvovery self.xmpp.register_plugin('xep_0030') # session manager self.xmpp.register_plugin('xep_0198') # ping self.xmpp.register_plugin('xep_0199') self.xmpp.add_event_handler('session_start', self.session_start) self.xmpp.add_event_handler("message", self.message) # ping schedule #self.xmpp.schedule('login ping', 120, self.login_ping) self.mobile_re = re.compile('\d{11}') self.token_re = re.compile('[-0-9a-z\ ]{0,100}') # signal ctrl-c to exit signal.signal(signal.SIGINT, self.exit_handle) # connect mongo connect(mdb, host=mhost) def exit_handle(self, signal, frame): logging.info("you press Ctrl-c, now the xmpp will exit.") self.xmpp.disconnect(wait=True) logging.info("=>>> now exit and close.") sys.exit(-1) def start(self): u""" 启动xmpp聊天机器人 """ if self.xmpp.connect((self.ehost, self.eport), use_tls=False): self.xmpp.process(block=True) else: raise Exception('connect fail') def session_start(self, event): self.xmpp.send_presence() #self.client.get_roster() def login_ping(self): pass def message(self, msg): u"login/logout/get_token处理" mtype = msg['type'] fjid = msg['from'] subject = msg['subject'] body = msg['body'] if mtype != 'chat': return mobile = JID(fjid).username if self.mobile_re.match(mobile) is None: return if body is not None and self.token_re.match(body) is None: body = None if subject == 'login': return self.login(fjid, body) elif subject == 'logout': return self.logout(fjid) elif subject == 'get_token': return self.get_token(fjid, body) def login(self, fjid, body): pass def logout(self, fjid): pass def get_token(self, fjid, body): pass
class XMPPConnection(object): def __init__(self, jid, password, feature=None, keepalive=None, ca_cert=None, server=None, bot=None): if feature is not None: feature = {} self._bot = bot self.connected = False self.server = server self.client = ClientXMPP(jid, password, plugin_config={'feature_mechanisms': feature}) self.client.register_plugin('xep_0030') # Service Discovery self.client.register_plugin('xep_0045') # Multi-User Chat self.client.register_plugin('xep_0004') # Multi-User Chat backward compability (necessary for join room) self.client.register_plugin('xep_0199') # XMPP Ping self.client.register_plugin('xep_0203') # XMPP Delayed messages self.client.register_plugin('xep_0249') # XMPP direct MUC invites if keepalive is not None: self.client.whitespace_keepalive = True # Just in case SleekXMPP's default changes to False in the future self.client.whitespace_keepalive_interval = keepalive self.client.ca_certs = ca_cert # Used for TLS certificate validation self.client.add_event_handler("session_start", self.session_start) self.client.add_event_handler("ssl_invalid_cert", self.ssl_invalid_cert) def session_start(self, _): self.client.send_presence() self.client.get_roster() def ssl_invalid_cert(self, _): # Special quirk for google domains verify_gtalk_cert(self.client) def connect(self): if not self.connected: if self.server is not None: self.client.connect(self.server) else: self.client.connect() self.connected = True return self def disconnect(self): self.client.disconnect(wait=True) self.connected = False def serve_forever(self): self.client.process(block=True) def add_event_handler(self, name, cb): self.client.add_event_handler(name, cb) def del_event_handler(self, name, cb): self.client.del_event_handler(name, cb) def join_room(self, room, username, password): """ Attempt to join the given MUC .. deprecated:: 2.2.0 Use the methods on :class:`XMPPMUCRoom` instead. """ warnings.warn( "Using join_room is deprecated, use join from the " "MUCRoom class instead.", DeprecationWarning ) self._bot.query_room(room).join(username=username, password=password) def configure_room(self, room): """ Configure the given MUC Currently this simply sets the default room configuration as received by the server. May be extended in the future to set a custom room configuration instead. .. deprecated:: 2.2.0 Use the methods on :class:`XMPPMUCRoom` instead. """ warnings.warn( "Using configure_room is deprecated, use configure from the " "MUCRoom class instead.", DeprecationWarning ) self._bot.query_room(room).configure() def invite_in_room(self, room, jids_to_invite): """ .. deprecated:: 2.2.0 Use the methods on :class:`XMPPMUCRoom` instead. """ warnings.warn( "Using invite_in_room is deprecated, use invite from the " "MUCRoom class instead.", DeprecationWarning, ) self._bot.query_room(room).invite(jids_to_invite)
def get(self, *args): self.finish() action = self.get_argument("action") def Roster(event): print("nuevo Amigo3") #msgLocations = {sleekxmpp.stanza.presence.Presence: "status", # sleekxmpp.stanza.message.Message: "body"} data = event.getStanzaValues() del data['roster']['ver'] print(data) json4 = {"action":"DeleteRoster"} json4 = json.dumps(json4) for c in cl: c.write_message(json4) for item in data['roster']['items']: json1 = {} print(str(item.jid)) print(str(data['roster']['items'][item]['ask'])) #data['roster']['items'][item] = str(data(item)) #if(str(data['roster']['items'][item]['ask']) == "subscribe"): #print("Friend Request") #json1 = {"action":"FriendRequest","friend": str(item.jid)} #else: json1 = {"action":"Roster","friend": str(item.jid)} json1 = json.dumps(json1) for c in cl: c.write_message(json1) resultat = [] for i in res: resultat.append(i) #print(i) data = {"value" : i[0], "sender": i[1]} data = json.dumps(data) for c in cl: c.write_message(data) for i in jsonPrecense: for c in cl: c.write_message(i) if(action == "connect"): user = self.get_argument("ussername") passw = self.get_argument("password") Client = ClientXMPP(user, passw) Client.register_plugin('xep_0030') # Service Discovery Client.register_plugin('xep_0004') # Data Forms Client.register_plugin('xep_0060') # PubSub Client.register_plugin('xep_0199') # XMPP Ping print(Client) Clientes.append(Client) conexion = Connect(Client) #xmpp = PingTest(user, passw, None) if(action =="disconnect"): print(Clientes[0]) Clientes[0].disconnect(wait = True) print("Primer") Clientes.remove(Clientes[0]) if(action == "getImportant"): print("importantes") conn = sqlite3.connect('important.db') c = conn.cursor() c.execute('select * from messages') res = c.fetchall() for resu in res: print(resu[2]) if(resu[2] == "1"): json1 = {"action":resu[3],"value":resu[1],"sender":resu[0]} json1 = json.dumps(json1) for c in cl: c.write_message(json1) else: json1 = {"action":resu[3],"value":resu[1],"sender":resu[0],"status":1} json1 = json.dumps(json1) for c in cl: c.write_message(json1) if(action == "saveImportant"): value = self.get_argument("value") valor = value.split(":") valor.append("newMessage") conn = sqlite3.connect('important.db') c = conn.cursor() print(sqlite3.paramstyle) c.execute("insert into messages values(? ,?, ?, ?)",valor) conn.commit() #c = conn.cursor() #c.execute('select * from messages') #res = c.fetchall() #c = conn.cursor() if(action =="send"): to = self.get_argument("to") message = self.get_argument("message") user = self.get_argument("ussername") mtype = self.get_argument("type"); print(message) Clientes[0].send_message(mto=to, mbody=message,mtype=mtype) urls = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', message) if urls: message = "<a href='"+urls[0]+"'>"+urls[0]+"</a>" data = {"action":"newMessage","value":message, "sender": to,"status":"1"} data = json.dumps(data) jsonMessages.append(data) for c in cl: if(mtype != "groupchat"): c.write_message(data) #Clientes.remove(Clientes[0]) if(action =="getMessages"): #conn = sqlite3.connect('database.db') #c = conn.cursor() #c.execute('select * from messages') #res = c.fetchall() #resultat = [] for i in jsonMessages : for c in cl: c.write_message(i) if(action =="Request"): friend = self.get_argument("value") status = self.get_argument("status") Clientes[0].send_presence(pto = friend, ptype = status) Clientes[0].get_roster(callback = Roster) if(action == "Presence"): presencia = self.get_argument("value") Clientes[0].sendPresence(ptype = presencia) if(action== "AddFriend"): friend = self.get_argument("friend") Clientes[0].send_presence(pto=friend, ptype='subscribe') Clientes[0].get_roster(callback = Roster) if(action == "DeleteFriend"): print("Whaat really") friend = self.get_argument("friend") Clientes[0].update_roster(friend,subscription='remove') Clientes[0].get_roster(callback = Roster) if(action == "JoinGroup"): print("What the f**k man") room = self.get_argument("room") nick = self.get_argument("nick") Clientes[0].plugin['xep_0045'].joinMUC(room,nick,wait=True)
class FoosBot(object): def __init__(self, jid, password): # we set this as an attribute instead of sublcassing because many # of ClientXMPP's attributes are named something we might accidentally # overrite (breaking ClientXMPP). it's happened to me quite a bit self.xmpp = ClientXMPP(jid, password) self.xmpp.add_event_handler("session_start", self._session_start_handler) self.xmpp.add_event_handler("message", self._message_handler) self.xmpp.register_plugin("xep_0030") # Service Discovery self.xmpp.register_plugin("xep_0199") # XMPP Ping self.match_requested = False self.active_players = {} self.match_players = [] self.state_machines = {} def start(self): self.xmpp.connect(("talk.google.com", 5222)) self.xmpp.process(block=True) def _session_start_handler(self, event): self.xmpp.send_presence() # Most get_*/set_* methods from plugins use Iq stanzas, which # can generate IqError and IqTimeout exceptions try: self.xmpp.get_roster() except IqError as err: logging.error("There was an error getting the roster") logging.error(err.iq["error"]["condition"]) self.xmpp.disconnect() except IqTimeout: logging.error("Server is taking too long to respond") self.xmpp.disconnect() def _message_handler(self, msg): if msg["type"] not in ("chat", "normal"): # TODO Add logging return sender = str(msg["from"]).split("/")[0] body = str(msg["body"]).strip().lower() game_creator = self.state_machines.get(sender) if not game_creator: self.state_machines[sender] = GameCreator(sender) game_creator = self.state_machines.get(sender) reply = game_creator.handle_message(sender, body) if reply: self.send(sender, reply) def send(self, to, message): if not isinstance(to, (tuple, list)): to = [to] message = str(message) # evaluates Template, if it exists for player in to: self.xmpp.send_message(player, message)
class JabberListener(Listener): listenerType = ListenerType.JABBER def __init__(self, config): super(JabberListener, self).__init__(config) self.name = config['name'] self.jid = config['jid'] self.password = config['password'] self.host = config['host'] self.port = config['port'] jid_parts = self.jid.split("@") self.nick = jid_parts[0] if "pm_list" in config: self.pm_list = config["pm_list"] self.pm_filter = True else: self.pm_list = [] self.pm_filter = False if "filter_list" in config: self.filter_list = config["filter_list"] self.filter = True else: self.filter_list = [] self.filter = False _log.info("{0} - Initializing Jabber client for: {1}".format( self.name, self.jid)) self.client = ClientXMPP(self.jid, self.password) self.client.add_event_handler("session_start", self.onConnect) self.client.add_event_handler("disconnected", self.onDisconnect) self.client.add_event_handler("message", self.parseMessage) self.client.register_plugin("xep_0045") # Multi-User Chat def run(self): _log.info("{0} - Connecting to: {1}:{2}".format( self.name, self.host, self.port)) try: self.client.connect((self.host, self.port)) except Exception as err: _log.error("{0} - Connection failed to: {1}:{2}".format( self.name, self.host, self.port)) return self.client.process(block=True) super(JabberListener, self).finished() def stop(self): _log.info("Stopping Jabber") self.autoreconnect = False self.client.disconnect(wait=True) def onConnect(self, event): self.client.sendPresence() _log.info("{0} - Connected to: {1}:{2}".format(self.name, self.host, self.port)) self.joinRooms() def joinRooms(self): if "channel_list" not in self.config: return rooms = self.config.get("channel_list") for r in rooms: room_addr = "{0}@{1}".format(r, self.host) _log.debug("{0} - Attempting to join {1} as {2}".format( self.name, room_addr, self.nick)) try: self.client.plugin['xep_0045'].joinMUC(room_addr, self.nick) except Exception: _log.exception("An error while joining room {} as {}".format( room_addr, self.nick)) def onDisconnect(self, event): _log.warning("{0} - Disconnected from: {1}:{2}".format( self.name, self.host, self.port)) def parseMessage(self, msg): try: _log.debug("{0} - Got message from Jabber: {1}".format( self.name, msg)) except Exception: _log.debug("{0} - Got message from Jabber: (Can't display)".format( self.name)) if self.messageHandler is None: return msgText = msg["body"] #Normal is default _log.debug("Message type is: {}".format(msg["type"])) msgType = msg.get("type", "normal") if msgType == "chat" or msgType == "normal": msgChannel = "Direct Message" msgFromParts = msg["from"].bare.split("@") msgFrom = msgFromParts[0] #PM filter if self.pm_filter: if msgFrom not in self.pm_list: _log.debug("{0} - Sender not in PM list, ignore".format( self.name)) return #text filter if not self.textFilter(msgText): _log.debug( "{0} - Message does not match a text filter, ignore". format(self.name)) return elif msgType == "groupchat": msgChannelParts = msg["mucroom"].split("@") msgChannel = msgChannelParts[0] msgFrom = msg["mucnick"] else: _log.warn( "{0} - Unknown message type from Jabber: {1}\n{2}".format( self.name, msg["type"], msg)) message = Message(self, msgText, msgFrom, msgChannel, self.host) self.relay_message(message) def textFilter(self, text): if not self.filter: return True for f in self.filter_list: filter_re = re.compile(f) if filter_re.search(text) is not None: return True return False
class XMPPConnection(Connection): def __init__(self, jid, password): self.connected = False self.client = ClientXMPP(jid, password, plugin_config={'feature_mechanisms': XMPP_FEATURE_MECHANISMS}) self.client.register_plugin('xep_0030') # Service Discovery self.client.register_plugin('xep_0045') # Multi-User Chat self.client.register_plugin('xep_0004') # Multi-User Chat backward compability (necessary for join room) self.client.register_plugin('xep_0199') # XMPP Ping self.client.register_plugin('xep_0203') # XMPP Delayed messages self.client.register_plugin('xep_0249') # XMPP direct MUC invites if XMPP_KEEPALIVE_INTERVAL is not None: self.client.whitespace_keepalive = True # Just in case SleekXMPP's default changes to False in the future self.client.whitespace_keepalive_interval = XMPP_KEEPALIVE_INTERVAL self.client.ca_certs = XMPP_CA_CERT_FILE # Used for TLS certificate validation self.client.add_event_handler("session_start", self.session_start) self.client.add_event_handler("ssl_invalid_cert", self.ssl_invalid_cert) def send_message(self, mess): self.client.send_message(mto=mess.getTo(), mbody=mess.getBody(), mtype=mess.getType(), mhtml=mess.getHTML()) def session_start(self, _): self.client.send_presence() self.client.get_roster() def ssl_invalid_cert(self, _): # Special quirk for google domains verify_gtalk_cert(self.client) def connect(self): if not self.connected: self.client.connect() self.connected = True return self def disconnect(self): self.client.disconnect(wait=True) self.connected = False def serve_forever(self): self.client.process(block=True) def add_event_handler(self, name, cb): self.client.add_event_handler(name, cb) def del_event_handler(self, name, cb): self.client.del_event_handler(name, cb) def join_room(self, room, username, password): """Attempt to join the given MUC""" muc = self.client.plugin['xep_0045'] muc.joinMUC(room, username, password=password, wait=True) # Room configuration can only be done once a MUC presence stanza # has been received from the server. This HAS to take place in a # separate thread because of how SleekXMPP processes these stanzas. t = Thread(target=self.configure_room, args=[room]) t.setDaemon(True) t.start() def configure_room(self, room): """ Configure the given MUC Currently this simply sets the default room configuration as received by the server. May be extended in the future to set a custom room configuration instead. """ muc = self.client.plugin['xep_0045'] affiliation = None while affiliation is None: sleep(0.5) affiliation = muc.getJidProperty( room=room, nick=muc.ourNicks[room], jidProperty='affiliation' ) if affiliation == "owner": logging.debug("Configuring room {} because we have owner affiliation".format(room)) form = muc.getRoomConfig(room) muc.configureRoom(room, form) else: logging.debug("Not configuring room {} because we don't have owner affiliation (affiliation={})" .format(room, affiliation)) def invite_in_room(self, room, jids_to_invite): muc = self.client.plugin['xep_0045'] for jid in jids_to_invite: logging.debug("Inviting %s to %s..." % (jid, room)) muc.invite(room, jid)
class XMPPConnection(object): def __init__(self, jid, password, feature=None, keepalive=None, ca_cert=None, server=None, bot=None): if feature is not None: feature = {} self._bot = bot self.connected = False self.server = server self.client = ClientXMPP(jid, password, plugin_config={'feature_mechanisms': feature}) self.client.register_plugin('xep_0030') # Service Discovery self.client.register_plugin('xep_0045') # Multi-User Chat self.client.register_plugin('xep_0199') # XMPP Ping self.client.register_plugin('xep_0203') # XMPP Delayed messages self.client.register_plugin('xep_0249') # XMPP direct MUC invites if keepalive is not None: self.client.whitespace_keepalive = True # Just in case SleekXMPP's default changes to False in the future self.client.whitespace_keepalive_interval = keepalive self.client.ca_certs = ca_cert # Used for TLS certificate validation self.client.add_event_handler("session_start", self.session_start) def session_start(self, _): self.client.send_presence() self.client.get_roster() def connect(self): if not self.connected: if self.server is not None: self.client.connect(self.server) else: self.client.connect() self.connected = True return self def disconnect(self): self.client.disconnect(wait=True) self.connected = False def serve_forever(self): self.client.process(block=True) def add_event_handler(self, name, cb): self.client.add_event_handler(name, cb) def del_event_handler(self, name, cb): self.client.del_event_handler(name, cb) def join_room(self, room, username, password): """ Attempt to join the given MUC .. deprecated:: 2.2.0 Use the methods on :class:`XMPPMUCRoom` instead. """ warnings.warn( "Using join_room is deprecated, use join from the " "MUCRoom class instead.", DeprecationWarning) self._bot.query_room(room).join(username=username, password=password) def configure_room(self, room): """ Configure the given MUC Currently this simply sets the default room configuration as received by the server. May be extended in the future to set a custom room configuration instead. .. deprecated:: 2.2.0 Use the methods on :class:`XMPPMUCRoom` instead. """ warnings.warn( "Using configure_room is deprecated, use configure from the " "MUCRoom class instead.", DeprecationWarning) self._bot.query_room(room).configure() def invite_in_room(self, room, jids_to_invite): """ .. deprecated:: 2.2.0 Use the methods on :class:`XMPPMUCRoom` instead. """ warnings.warn( "Using invite_in_room is deprecated, use invite from the " "MUCRoom class instead.", DeprecationWarning, ) self._bot.query_room(room).invite(jids_to_invite)
class XMPPCommunicator(Communicator): def __del__(self): self.disconnect() def __init__(self, jid, passwd, contacts, accept_from=None, greeting="XMPP communication established", verbosity = 2, answer=None): # also initialize ClientXMPP self.xmpp = ClientXMPP(jid, passwd) self.jid = jid self.passwd = passwd self.contacts = contacts self.greeting = greeting self.accept_from = accept_from self.verbosity = verbosity self.messages = [] self.xmpp.add_event_handler("session_start", self._start_xmpp) self.xmpp.add_event_handler("message", self._buffer_message) self.xmpp.register_plugin('xep_0030') # Service Discovery self.xmpp.register_plugin('xep_0199') # XMPP Ping if answer == None: self.answer = lambda daemon, comm, msg: None else: self.answer = answer def prepare(self, daemon): self.connect() self.process() def _start_xmpp(self, event): self.xmpp.send_presence() self.xmpp.get_roster() print "[jodaepy] " + self.greeting self.send_message(self.greeting) def _buffer_message(self, msg): if msg['type'] in ['normal', 'chat']: if self.accept_from == None or msg['from'] in self.accept_from: self.messages.append(msg['body']) def connect(self): return self.xmpp.connect() def disconnect(self): return self.xmpp.disconnect() def process(self): return self.xmpp.process(block=False) def send_message(self, mbody, contacts = None): contacts = self.contacts if not contacts else contacts for contact in contacts: self.xmpp.send_message( mto=contact, mbody=mbody, mtype='chat' ) def registration_failed(self, daemon, error): if self.verbosity > 1: self.send_message("Registration Failed: " + str(error) + "\n") def finalization_failed(self, daemon, job, error): if self.verbosity > 1: self.send_message("Finalization Failed (job %d): " % job.id + str(error) + "\n") def starting_failed(self, daemon, job, error): if self.verbosity > 1: self.send_message("Could not start job (job %d): " % job.id + str(error) + "\n") def postprocessing_failed(self, daemon, error): if self.verbosity > 1: self.send_message("Postprocessing failed: " + str(error) + "\n") def workspace_updated(self, deamon, files): if self.verbosity > 1: if files: self.send_message("Found files " + " ".join(files) + "\n") def scripts_updated(self, deamon, scripts): if self.verbosity > 1: if scripts: self.send_message("Found scripts " + " ".join(scripts) + "\n") def jobs_registered(self, daemon, jobs): if self.verbosity > 1: if jobs: msg = [] msg.append("Found jobs\n") for job in jobs: msg.append(" %5d '%s'\n" % (job.id, job.title) ) self.send_message(''.join(msg)) def jobs_started(self, daemon, jobs): if self.verbosity > 1: if jobs: msg = [] msg.append("Started jobs\n") for job in jobs: msg.append(" %5d, on '%s'\n" % (job.id, job.running_host) ) self.send_message(''.join(msg)) def jobs_returned(self, daemon, jobs): pass def jobs_finalized(self, daemon, jobs): if self.verbosity > 1: if jobs: msg = [] msg.append("Finalized jobs\n") for job in jobs: msg.append(" %5d (%s), %s -- %s\n" % \ (job.id, "fail" if job.failed() else "sucess", job.stime, job.ftime) ) self.send_message(''.join(msg)) def postprocessing_done(self, daemon, pp): if self.verbosity > 1: if pp: self.send_message("Postprocessing done\n") def host_unavailable(self, daemon, job): if self.verbosity > 1: self.send_message("Expected hosts %s for job %d are unavailable. Dropped this job\n" % (str(job.hosts), job.id) ) def job_updated(self, daemon, job, dpercs, doutfiles): perc_old, perc = dpercs outfiles_old, outfiles= doutfiles if self.verbosity < 3: return if self.verbosity == 3: if perc_old < 25 and perc > 25 or \ perc_old < 50 and perc > 50 or \ perc_old < 75 and perc > 75: self.send_message("Job %d: %d%% completed\n" % (job.id, perc) ) def communicate(self, daemon): for message in self.messages: self.answer(daemon, self, message) self.messages = [] def close(): self.disconnect()
class NefitCore(object): _accesskey_prefix = 'Ct7ZR03b_' _rrc_contact_prefix = 'rrccontact_' _rrc_gateway_prefix = 'rrcgateway_' _magic = bytearray.fromhex("58f18d70f667c9c79ef7de435bf0f9b1553bbb6e61816212ab80e5b0d351fbb1") serial_number = None access_key = None password = None jid = None _from = None _to = None client = None encryption = None event = None container = {} def __init__(self, serial_number, access_key, password, host="wa2-mz36-qrmzh6.bosch.de", sasl_mech="DIGEST-MD5"): """ :param serial_number: :param access_key: :param password: :param host: :param sasl_mech: """ serial_number = str(serial_number) self.serial_number = serial_number self.access_key = access_key self.password = password self.encryption = AESCipher(self._magic, access_key, password) identifier = serial_number + "@" + host self.jid = jid = self._from = self._rrc_contact_prefix + identifier self._to = self._rrc_gateway_prefix + identifier self.client = ClientXMPP(jid=jid, password=self._accesskey_prefix + access_key, sasl_mech=sasl_mech) self.client.add_event_handler("session_start", self.session_start) self.client.register_plugin('xep_0199') @staticmethod def set_verbose(): import logging logging.basicConfig(filename="debug.log", level=logging.DEBUG) def message(self, msg): if msg['type'] in ('chat', 'normal'): headers = msg['body'].split("\n")[:-1] body = msg['body'].split("\n")[-1:][0] if 'HTTP/1.0 400 Bad Request' in headers: return response = self.decrypt(body) if 'Content-Type: application/json' in headers: _LOGGER.debug("response='{}'".format(response)) response = response.strip() if len(response) > 1: response = json.loads(response.strip()) self.container[id(self.event)] = response self.event.set() def connect(self, block=False): self.client.connect() self.client.process(block=block) def session_start(self, event): self.client.send_presence() self.client.get_roster() def disconnect(self): self.client.disconnect() def get(self, uri, timeout=10): self.event = Event() self.client.add_event_handler("message", self.message) self.send("GET %s HTTP/1.1\rUser-Agent: NefitEasy\r\r" % uri) self.event.wait(timeout=timeout) self.client.del_event_handler("message", self.message) return self.container[id(self.event)] if id(self.event) in self.container.keys() else None def put(self, uri, data, timeout=10): data = data if isinstance(data, str) else json.dumps(data, separators=(',', ':')) encrypted_data = self.encrypt(data).decode("utf8") body = "\r".join([ 'PUT %s HTTP/1.1' % uri, 'Content-Type: application/json', 'Content-Length: %i' % len(encrypted_data), 'User-Agent: NefitEasy\r', encrypted_data ]) self.event = Event() self.client.add_event_handler("message", self.message) self.send(body) self.event.wait(timeout=timeout) self.client.del_event_handler("message", self.message) def send(self, body): # this horrible piece of code breaks xml syntax but does actually work... body = body.replace("\r", " \n") message = self.client.make_message(mto=self._to, mfrom=self._from, mbody=body) message['lang'] = None str_data = tostring(message.xml, xmlns=message.stream.default_ns, stream=message.stream, top_level=True) str_data = str_data.replace("&#13;", " ") return message.stream.send_raw(str_data) def encrypt(self, data): return self.encryption.encrypt(data) def decrypt(self, data): return self.encryption.decrypt(data) def get_display_code(self): return self.get('/system/appliance/displaycode') def get_status(self): return self.get('/ecus/rrc/uiStatus') def get_location(self): return self.get('/system/location/latitude'), self.get('/system/location/longitude') def get_outdoor(self): return self.get('/system/sensors/temperatures/outdoor_t1') def get_pressure(self): return self.get('/system/appliance/systemPressure') def get_program(self): return ( self.get('/ecus/rrc/userprogram/activeprogram'), self.get('/ecus/rrc/userprogram/program1'), self.get('/ecus/rrc/userprogram/program2'), ) def get_year_total(self): return self.get('/ecus/rrc/recordings/yearTotal') def set_temperature(self, temperature): self.put('/heatingCircuits/hc1/temperatureRoomManual', {'value': float(temperature)}) self.put('/heatingCircuits/hc1/manualTempOverride/status', {'value': 'on'}) self.put('/heatingCircuits/hc1/manualTempOverride/temperature', {'value': float(temperature)}) def get_actualSupplyTemperature(self): return self.get('/heatingCircuits/hc1/actualSupplyTemperature')
class XMPPService(ServiceHandler): """ Service handler for XMPP. Configuration options: type = XMPP jid = [email protected] password = the password ; Relay messages from these rooms. (Optional) receiver_rooms = [email protected] ; Broadcast messages to these rooms. (Optional) broadcaster_rooms = [email protected] ; Relay direct messages from these users or ALL. (Optional) receiver_jids = ALL ; Broadcast messages to these users. (Optional) broadcaster_jids = [email protected] """ def __init__(self, config): super().__init__(config) self.client = ClientXMPP(config["jid"], config["password"]) self.client.add_event_handler("session_start", self._xmpp_connected_event) self.client.add_event_handler("message", self._xmpp_msg_received_event) self.client.add_event_handler("groupchat_message", self._xmpp_muc_msg_received_event) self.client.register_plugin("xep_0045") # Multi-User Chat async def _on_stop(self): self.client.disconnect() async def _on_start(self): # This automatically runs in a seperate thread # TODO: Is this needed when we are asynchronous anyways? self.client.connect() self.client.process() async def _on_send_message(self, msg): for room in self.config.get("broadcaster_rooms", []): self.client.send_message(mto=room, mbody=msg, mtype="groupchat") for jid in self.config.get("broadcaster_jids", []): self.client.send_message(mto=jid, mbody=msg, mtype="chat") def _xmpp_msg_received_event(self, msg): # Ignore our own messages at all costs if msg["from"].bare == self.config["jid"] \ or msg.get("mucnick", "") == self.client.boundjid.username: return if msg["type"] == "chat": # If we do not receive from ALL and the JID is not in the list, ignore. if not ("ALL" in self.config.get("receiver_jids", []) or msg["from"].bare in self.config.get("receiver_jids", [])): return channel = "PM" author = msg["from"].bare elif msg["type"] == "groupchat": if msg["mucroom"] not in self.config.get("receiver_rooms", []): return channel = msg["mucroom"] author = msg["mucnick"] else: print("Received unknown XMPP message: %s" % msg) return future = super()._on_receive_message(msg=msg["body"], source_channel=channel, source_nick=author) asyncio.run_coroutine_threadsafe(future, self.loop) def _xmpp_muc_msg_received_event(self, msg): # Group messages also trigger the message event, so this might not be needed. pass def _xmpp_connected_event(self, event): self.client.send_presence() # self.client.get_roster() if self.is_receiver(): for room in self.config.get("receiver_rooms", []): print("Joining %s" % room) self.client.plugin["xep_0045"].joinMUC( room, self.client.boundjid.username, wait=True) if self.is_broadcaster(): for room in self.config.get("broadcaster_rooms", []): # Skip already joined rooms if room in self.client.plugin["xep_0045"].getJoinedRooms(): continue print("Joining %s" % room) self.client.plugin["xep_0045"].joinMUC( room, self.client.boundjid.username, wait=True) asyncio.run_coroutine_threadsafe(super()._on_started(), self.loop) @staticmethod def requested_config_values(): return { "jid": ConfigType(Subtype.LOGIN_INFO, required=True), "password": ConfigType(Subtype.LOGIN_INFO, required=True), "broadcaster_rooms": ConfigType(Subtype.BROADCAST_FILTER, multi_value=True), "receiver_rooms": ConfigType(Subtype.RECEIVE_FILTER, multi_value=True), "broadcaster_jids": ConfigType(Subtype.BROADCAST_FILTER, multi_value=True), "receiver_jids": ConfigType(Subtype.RECEIVE_FILTER, multi_value=True) }