class WylioServer: def __init__(self): self.connection = None log("WylioServer initialised") def connected(self,event): log("WylioServer connected") def disconnected(self,event): log("WylioServer disconnected") def failed_auth(self,event): log("WylioServer failed authentification") def message(self, event): log("WylioServer message received") print event def connect(self,jid,password): if self.connection == None: self.connection = ClientXMPP(jid, password) register_stanza_plugin (Message, WylioStanza) self.connection.add_event_handler("connected", self.connected) self.connection.add_event_handler("disconnected", self.disconnected) self.connection.add_event_handler("failed_auth", self.failed_auth) self.connection.add_event_handler("session_start", self.start) self.connection.add_event_handler("message", self.message) print "connect" self.connection.connect() self.connection.process(block=True) print "connected" def start(self,event): log("WylioServer started") self.connection.send_presence() print "presence sent" self.connection.get_roster()
class Orkiv(App): def __init__(self): super(Orkiv, self).__init__() self.xmpp = None def connect_to_jabber(self, jabber_id, password): self.xmpp = ClientXMPP(jabber_id, password) #~ self.xmpp.connect() self.xmpp.reconnect_max_attempts = 1 connected = self.xmpp.connect() if not connected: raise XMPPError("unable to connect") self.xmpp.process() self.xmpp.send_presence() self.xmpp.get_roster() def disconnect_xmpp(self): if self.xmpp and self.xmpp.state.ensure("connected"): self.xmpp.abort() self.xmpp = None def on_stop(self): self.disconnect_xmpp()
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)
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 Orkiv(App): icon = 'customicon.png' def __init__(self, root_dir): super(Orkiv, self).__init__() self.root_dir = root_dir self.xmpp = None def connect_to_jabber(self, jabber_id, password): self.xmpp = ClientXMPP(jabber_id, password) self.xmpp.reconnect_max_attempts = 1 connected = self.xmpp.connect() if not connected: raise XMPPError("Vyanse kwikonecta") self.xmpp.process() self.xmpp.send_presence() self.xmpp.get_roster() self.xmpp.add_event_handler('message', self.root.handle_xmpp_message) def disconnect_xmpp(self): if self.xmpp and self.xmpp.state.ensure("connected"): self.xmpp.abort() self.xmpp = None def on_stop(self): self.disconnect_xmpp()
class XMPPNotifier(BaseNotifier): regex = re.compile('^xmpp:([^:@\s]+@[^:@\s]+)$') def __init__(self, config): self.config = config self.started = False self.xmpp = ClientXMPP( self.config['username'], self.config['password'] ) self.xmpp.add_event_handler('session_start', self.start) self.xmpp.connect(address=self.config['server'], use_tls=True) self.xmpp.process() def start(self, event): self.xmpp.send_presence() self.xmpp.get_roster() self.started = True def notify(self, contact, node): msg = node.format_infotext(self.config['text']) receipient = self.regex.match(contact).group(1) self.xmpp.send_message(mto=receipient, mbody=msg, mtype='chat') return True def quit(self): while not self.started: sleep(0.5) self.xmpp.disconnect(wait=True)
class Orkiv(App): def connect_to_jabber(self, jabber_id, password): self.xmpp = ClientXMPP(jabber_id, password) self.xmpp.connect() self.xmpp.process() self.xmpp.send_presence() self.xmpp.get_roster()
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(':', '')
class Orkiv(App): def connect_to_jabber(self,jabber_id,password): self.xmpp = ClientXMPP(jabber_id,password) self.xmpp.reconnect_max_attempt = 1 connected=self.xmpp.connect() if not connected: raise XMPPError('unable to connect') self.xmpp.process() self.xmpp.send_presence() self.xmpp.get_roster()
class WylioXMPP: def __init__(self): self.connection = None self.jid = "" def connect(self, jid, password): self.jid = jid if self.connection == None: self.connection = ClientXMPP(jid, password) register_stanza_plugin(Message, WylioStanza) register_stanza_plugin(WylioStanza, ValueStanza) self.connection.add_event_handler("connected", self.connected) self.connection.add_event_handler("session_start", self.start) self.connection.add_event_handler("failed_auth", self.failed) self.connection.add_event_handler("disconnected", self.disconnected) self.connection.add_event_handler("message", self.message) self.connection.connect(('talk.google.com', 5222)) self.connection.process() def connected(self, event): log("WylioXMPP connected") def start(self, event): log("WylioXMPP start") self.connection.send_presence() log("Wylio presence") self.run_program("source", "[email protected]/raspy") def message(self, event): print event def failed(self, event): log("WylioXMPP failed") def disconnected(self, event): log("WylioXMPP disconnected") def run_program(self, name, jid): print "fsdafasd" msg = self.connection.Message(sto=jid, stype="normal") print msg msg["wylio"]["run"] = name #msg["wylio"]["value"]="4082374" msg["wylio"]["value"]["timestamp"] = "4082374" msg["wylio"]["value"]["signal"] = "some name" msg["wylio"]["value"]["value"] = "478923" print "message" print msg msg.send()
class WylioXMPP: def __init__(self): self.connection = None self.jid = "" def connect(self, jid, password): self.jid = jid if self.connection == None: self.connection = ClientXMPP(jid, password) register_stanza_plugin(Message, WylioStanza) register_stanza_plugin(WylioStanza, ValueStanza) self.connection.add_event_handler("connected", self.connected) self.connection.add_event_handler("session_start", self.start) self.connection.add_event_handler("failed_auth", self.failed) self.connection.add_event_handler("disconnected", self.disconnected) self.connection.add_event_handler("message", self.message) self.connection.connect(("talk.google.com", 5222)) self.connection.process() def connected(self, event): log("WylioXMPP connected") def start(self, event): log("WylioXMPP start") self.connection.send_presence() log("Wylio presence") self.run_program("source", "[email protected]/raspy") def message(self, event): print event def failed(self, event): log("WylioXMPP failed") def disconnected(self, event): log("WylioXMPP disconnected") def run_program(self, name, jid): print "fsdafasd" msg = self.connection.Message(sto=jid, stype="normal") print msg msg["wylio"]["run"] = name # msg["wylio"]["value"]="4082374" msg["wylio"]["value"]["timestamp"] = "4082374" msg["wylio"]["value"]["signal"] = "some name" msg["wylio"]["value"]["value"] = "478923" print "message" print msg msg.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_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)
class WylioServer: def __init__(self): self.connection = None log("WylioServer initialised") def connected(self, event): log("WylioServer connected") def disconnected(self, event): log("WylioServer disconnected") def failed_auth(self, event): log("WylioServer failed authentification") def message(self, event): log("WylioServer message received") print event def connect(self, jid, password): if self.connection == None: self.connection = ClientXMPP(jid, password) register_stanza_plugin(Message, WylioStanza) self.connection.add_event_handler("connected", self.connected) self.connection.add_event_handler("disconnected", self.disconnected) self.connection.add_event_handler("failed_auth", self.failed_auth) self.connection.add_event_handler("session_start", self.start) self.connection.add_event_handler("message", self.message) print "connect" self.connection.connect() self.connection.process(block=True) print "connected" def start(self, event): log("WylioServer started") self.connection.send_presence() print "presence sent" self.connection.get_roster()
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(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)
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 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)
class WylioServer: def __init__(self): self.connection = None log("WylioServer initialised") def connected(self,event): log("WylioServer connected") def disconnected(self,event): log("WylioServer disconnected") def failed_auth(self,event): log("WylioServer failed authentification") def message(self, event): log("WylioServer message received") print event def send_value_signal(self,jid,timestamp,name,value): msg = self.connection.Message (sto=jid, stype="normal") msg["wylio"]["value"]["timestamp"]=timestamp msg["wylio"]["value"]["signal"]=name msg["wylio"]["value"]["value"]=value #print "message" #print msg msg.send() def send_signal_out(self,jid,value): msg = self.connection.Message (sto=jid, stype="normal") msg["wylio"]["out"]=value #print "message" #print msg msg.send() def send_signal_err(self,jid,value): msg = self.connection.Message (sto=jid, stype="normal") msg["wylio"]["err"]=value #print "message" #print msg msg.send() def message_wylio(self, event): global program try: log("WylioServer message wylio received") print event['wylio'] if event['wylio']['run']: #print "run in wylio" code = event['wylio']['run'] file = open('received_program.py', 'w') file.write(code) file.close() if program != None: program.stop() program = Program(1,'received_program.py') try: thread.start_new_thread(program.run,(self,event['from'])) print "created thread" except: traceback.print_exc() log("Error creating thread") if event['wylio']['value']: signal = event['wylio']['value']['signal'] value = event['wylio']['value']['value'] if program != None: program.sendSensorInput(signal,value) except: traceback.print_exc() def connect(self,jid,password): if self.connection == None: self.connection = ClientXMPP(jid, password) register_stanza_plugin (Message, WylioStanza) register_stanza_plugin (WylioStanza, ValueStanza) self.connection.add_event_handler("connected", self.connected) self.connection.add_event_handler("disconnected", self.disconnected) self.connection.add_event_handler("failed_auth", self.failed_auth) self.connection.add_event_handler("session_start", self.start) self.connection.add_event_handler("message", self.message) self.connection.register_handler(Callback("Wylio", StanzaPath("message/wylio"), self.message_wylio)) print "connect" self.connection.connect() self.connection.process(block=True) print "connected" def start(self,event): log("WylioServer started") self.connection.send_presence() print "presence sent" self.connection.get_roster()
class XmppBot: """ Interfaces with Jabber and identifies bosses by JID and resource. """ def __init__(self, connect_cfg): "Initialize XMPP bot" # (Sender JID, [local resource]) -> callback self.dispatch_map = {} self.jid = connect_cfg.jid self.connect(connect_cfg) def connect(self, config): "Connect to XMPP server" socks_cfg = config.get('socks_proxy', required=False) self.client = ClientXMPP(self.jid, config.password) proxy_cfg = config.get('http_proxy', required=False) if proxy_cfg is not None: self.client.use_proxy = True self.client.proxy_config = { 'host': proxy_cfg.host, 'port': proxy_cfg.get('port', assert_type=int), 'username': proxy_cfg.get('username', required=False), 'password': proxy_cfg.get('password', required=False), } print("Configured proxy", self.client.proxy_config) use_tls = config.get('tls', default=True) # Events self.client.add_event_handler("session_start", self._session_start) self.client.add_event_handler("message", self.message_dispatch) log.info("Initializing connection to XMPP") ip = config.get('ip', required=False) if ip is not None: print("port", config.port) port = config.get('port', default=5222, assert_type=int) self.client.connect((ip, port), use_tls=use_tls) else: self.client.connect(use_tls=use_tls) def _session_start(self, event): log.info('Starting XMPP session') self.client.send_presence() def add_dispatch(self, sender_jid, resource, callback): """ Register callback to handle incoming messages from sender_jid directed to a given resource (can be None to mean "any"). """ key = (sender_jid, resource) if key in self.dispatch_map: raise Exception("Sender JID duplicated: %s" % sender_jid) self.dispatch_map[key] = callback def message_dispatch(self, msg): "Dispatch incoming message depending on the sender" if msg['type'] not in ('chat', 'normal'): log.warning('Unknown message type: %r %r', msg, msg['type']) return to_jid = msg.get_to() from_jid = msg.get_from() resource = to_jid.resource def respond(response): "Closure to simplify responding" self.send_message(from_jid, response) log.debug("Got message:") log.debug("From: %s, to: %s", from_jid, to_jid) log.debug("Body: %r", msg) # Dispatch direct (to resource) or generic (to JID) callback = self.dispatch_map.get((from_jid.bare, resource), None) if callback is None: callback = self.dispatch_map.get((from_jid.bare, None), None) # If unknown - ignore if callback is None: respond(language.get('DONT_KNOW')) return # Construct a Message using bot-generic API message = Message(msg['body'], from_jid.full, respond) callback(message) message.finish() def send_message(self, jid, message): "Send a message" self.client.send_message(jid, message) def close(self): "Disconnect / close threads" self.client.abort()
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 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 WylioXMPP: def __init__(self, email, db): self.connection = None self.email = email self.db = db self.jid = "" def connect(self, jid, password): self.jid = jid if self.connection == None: self.connection = ClientXMPP(jid, password) register_stanza_plugin(Message, WylioStanza) register_stanza_plugin(WylioStanza, ValueStanza) self.connection.add_event_handler("connected", self.connected) self.connection.add_event_handler("session_start", self.start) self.connection.add_event_handler("failed_auth", self.failed) self.connection.add_event_handler("disconnected", self.disconnected) self.connection.add_event_handler("message", self.message) self.connection.register_handler( Callback("Wylio", StanzaPath("message/wylio"), self.message_wylio)) self.connection.connect(('talk.google.com', 5222)) self.connection.process() def connected(self, event): log("WylioXMPP connected") def start(self, event): log("WylioXMPP start") self.connection.send_presence() log("Wylio presence") #self.run_program ("source", "[email protected]/raspy") def disconnect(self): self.connection.disconnect() def message_wylio(self, msg): if msg["wylio"]["value"]: #print msg signal = msg["wylio"]["value"]["signal"] value = nr(msg["wylio"]["value"]["value"]) #print signal, " ", value print self.email if self.db.values.find({ "email": self.email, "signal": signal }).count() == 0: print "insert" self.db.values.insert({ "email": self.email, "signal": signal, "values": [value] }) else: try: self.db.values.update( { "email": self.email, "signal": signal }, {"$push": { "values": value }}) print "update" except: traceback.print_exc() def message(self, event): print event def failed(self, event): log("WylioXMPP failed") def disconnected(self, event): log("WylioXMPP disconnected") def send_value(self, signal, value, jid): msg = self.connection.Message(sto=jid, stype="normal") msg["wylio"]["value"]["signal"] = signal msg["wylio"]["value"]["value"] = value print msg msg.send() def run_source(self, source, jid): print "fsdafasd" msg = self.connection.Message(sto=jid, stype="normal") print msg msg["wylio"]["run"] = source #msg["wylio"]["value"]="4082374" #msg["wylio"]["value"]["timestamp"]="4082374" #msg["wylio"]["value"]["signal"]="some name" #msg["wylio"]["value"]["value"]="478923" print "message" print msg msg.send()
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)
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(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 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 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) }