diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/IoT_TestDevice.py | 202 | ||||
-rwxr-xr-x | examples/custom_stanzas/custom_stanza_provider.py | 2 | ||||
-rwxr-xr-x | examples/ibb_transfer/ibb_receiver.py | 10 | ||||
-rw-r--r-- | examples/migrate_roster.py | 117 | ||||
-rwxr-xr-x | examples/ping.py | 22 | ||||
-rw-r--r-- | examples/register_account.py | 8 |
6 files changed, 342 insertions, 19 deletions
diff --git a/examples/IoT_TestDevice.py b/examples/IoT_TestDevice.py new file mode 100644 index 00000000..c754cfb4 --- /dev/null +++ b/examples/IoT_TestDevice.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python + +""" + SleekXMPP: The Sleek XMPP Library + Implementation of xeps for Internet of Things + http://wiki.xmpp.org/web/Tech_pages/IoT_systems + Copyright (C) 2013 Sustainable Innovation, Joachim.lindborg@sust.se + This file is part of SleekXMPP. + + See the file LICENSE for copying permission. +""" + +import os +import sys +# This can be used when you are in a test environment and need to make paths right +sys.path=['/Users/jocke/Dropbox/06_dev/SleekXMPP']+sys.path + +import logging +import unittest +import distutils.core +import datetime + +from glob import glob +from os.path import splitext, basename, join as pjoin +from optparse import OptionParser +from urllib import urlopen + +import sleekxmpp +# Python versions before 3.0 do not use UTF-8 encoding +# by default. To ensure that Unicode is handled properly +# throughout SleekXMPP, we will set the default encoding +# ourselves to UTF-8. +if sys.version_info < (3, 0): + from sleekxmpp.util.misc_ops import setdefaultencoding + setdefaultencoding('utf8') +else: + raw_input = input + +from sleekxmpp.plugins.xep_0323.device import Device + +#from sleekxmpp.exceptions import IqError, IqTimeout + +class IoT_TestDevice(sleekxmpp.ClientXMPP): + + """ + A simple IoT device that can act as server or client + """ + def __init__(self, jid, password): + sleekxmpp.ClientXMPP.__init__(self, jid, password) + self.add_event_handler("session_start", self.session_start) + self.add_event_handler("message", self.message) + self.device=None + self.releaseMe=False + self.beServer=True + self.clientJID=None + + def datacallback(self,from_jid,result,nodeId=None,timestamp=None,fields=None,error_msg=None): + """ + This method will be called when you ask another IoT device for data with the xep_0323 + se script below for the registration of the callback + """ + logging.debug("we got data %s from %s",str(result),from_jid) + + def beClientOrServer(self,server=True,clientJID=None ): + if server: + self.beServer=True + self.clientJID=None + else: + self.beServer=False + self.clientJID=clientJID + + def testForRelease(self): + # todo thread safe + return self.releaseMe + + def doReleaseMe(self): + # todo thread safe + self.releaseMe=True + + def addDevice(self, device): + self.device=device + + def session_start(self, event): + self.send_presence() + self.get_roster() + # tell your preffered friend that you are alive + self.send_message(mto='jocke@jabber.sust.se', mbody=self.boundjid.bare +' is now online use xep_323 stanza to talk to me') + + if not(self.beServer): + session=self['xep_0323'].request_data(self.boundjid.full,self.clientJID,self.datacallback) + + def message(self, msg): + if msg['type'] in ('chat', 'normal'): + logging.debug("got normal chat message" + str(msg)) + ip=urlopen('http://icanhazip.com').read() + msg.reply("Hi I am " + self.boundjid.full + " and I am on IP " + ip).send() + else: + logging.debug("got unknown message type %s", str(msg['type'])) + +class TheDevice(Device): + """ + This is the actual device object that you will use to get information from your real hardware + You will be called in the refresh method when someone is requesting information from you + """ + def __init__(self,nodeId): + Device.__init__(self,nodeId) + self.counter=0 + + def refresh(self,fields): + """ + the implementation of the refresh method + """ + self._set_momentary_timestamp(self._get_timestamp()) + self.counter+=self.counter + self._add_field_momentary_data(self, "Temperature", self.counter) + +if __name__ == '__main__': + + # Setup the command line arguments. + # + # This script can act both as + # "server" an IoT device that can provide sensorinformation + # python IoT_TestDevice.py -j "serverjid@yourdomain.com" -p "password" -n "TestIoT" --debug + # + # "client" an IoT device or other party that would like to get data from another device + + optp = OptionParser() + + # Output verbosity options. + optp.add_option('-q', '--quiet', help='set logging to ERROR', + action='store_const', dest='loglevel', + const=logging.ERROR, default=logging.INFO) + optp.add_option('-d', '--debug', help='set logging to DEBUG', + action='store_const', dest='loglevel', + const=logging.DEBUG, default=logging.INFO) + optp.add_option('-v', '--verbose', help='set logging to COMM', + action='store_const', dest='loglevel', + const=5, default=logging.INFO) + optp.add_option('-t', '--pingto', help='set jid to ping', + action='store', type='string', dest='pingjid', + default=None) + + # JID and password options. + optp.add_option("-j", "--jid", dest="jid", + help="JID to use") + optp.add_option("-p", "--password", dest="password", + help="password to use") + + # IoT test + optp.add_option("-c", "--sensorjid", dest="sensorjid", + help="Another device to call for data on", default=None) + optp.add_option("-n", "--nodeid", dest="nodeid", + help="I am a device get ready to be called", default=None) + + opts, args = optp.parse_args() + + # Setup logging. + logging.basicConfig(level=opts.loglevel, + format='%(levelname)-8s %(message)s') + + if opts.jid is None: + opts.jid = raw_input("Username: ") + if opts.password is None: + opts.password = getpass.getpass("Password: ") + + + xmpp = IoT_TestDevice(opts.jid,opts.password) + xmpp.register_plugin('xep_0030') + #xmpp['xep_0030'].add_feature(feature='urn:xmpp:iot:sensordata', + # node=None, + # jid=None) + xmpp.register_plugin('xep_0323') + xmpp.register_plugin('xep_0325') + + if opts.nodeid: + + # xmpp['xep_0030'].add_feature(feature='urn:xmpp:sn', + # node=opts.nodeid, + # jid=xmpp.boundjid.full) + + myDevice = TheDevice(opts.nodeid); + # myDevice._add_field(name="Relay", typename="numeric", unit="Bool"); + myDevice._add_field(name="Temperature", typename="numeric", unit="C"); + myDevice._set_momentary_timestamp("2013-03-07T16:24:30") + myDevice._add_field_momentary_data("Temperature", "23.4", flags={"automaticReadout": "true"}); + + xmpp['xep_0323'].register_node(nodeId=opts.nodeid, device=myDevice, commTimeout=10); + xmpp.beClientOrServer(server=True) + while not(xmpp.testForRelease()): + xmpp.connect() + xmpp.process(block=True) + logging.debug("lost connection") + if opts.sensorjid: + logging.debug("will try to call another device for data") + xmpp.beClientOrServer(server=False,clientJID=opts.sensorjid) + xmpp.connect() + xmpp.process(block=True) + logging.debug("ready ending") + + else: + print "noopp didn't happen" + diff --git a/examples/custom_stanzas/custom_stanza_provider.py b/examples/custom_stanzas/custom_stanza_provider.py index b0e00247..0ebdb77e 100755 --- a/examples/custom_stanzas/custom_stanza_provider.py +++ b/examples/custom_stanzas/custom_stanza_provider.py @@ -51,7 +51,7 @@ class ActionBot(sleekxmpp.ClientXMPP): # our roster. self.add_event_handler("session_start", self.start) - self.registerHandler( + self.register_handler( Callback('Some custom iq', StanzaPath('iq@type=set/action'), self._handle_action)) diff --git a/examples/ibb_transfer/ibb_receiver.py b/examples/ibb_transfer/ibb_receiver.py index 0169d63d..6aba98e3 100755 --- a/examples/ibb_transfer/ibb_receiver.py +++ b/examples/ibb_transfer/ibb_receiver.py @@ -38,7 +38,7 @@ class IBBReceiver(sleekxmpp.ClientXMPP): self.register_plugin('xep_0030') # Service Discovery self.register_plugin('xep_0047', { - 'accept_stream': self.accept_stream + 'auto_accept': True }) # In-band Bytestreams # The session_start event will be triggered when @@ -48,7 +48,7 @@ class IBBReceiver(sleekxmpp.ClientXMPP): # our roster. self.add_event_handler("session_start", self.start) - self.add_event_handler("ibb_stream_start", self.stream_opened) + self.add_event_handler("ibb_stream_start", self.stream_opened, threaded=True) self.add_event_handler("ibb_stream_data", self.stream_data) def start(self, event): @@ -69,7 +69,7 @@ class IBBReceiver(sleekxmpp.ClientXMPP): def accept_stream(self, iq): """ - Check that it is ok to accept a stream request. + Check that it is ok to accept a stream request. Controlling stream acceptance can be done via either: - setting 'auto_accept' to False in the plugin @@ -83,9 +83,7 @@ class IBBReceiver(sleekxmpp.ClientXMPP): return True def stream_opened(self, stream): - # NOTE: IBB streams are bi-directional, so the original sender is - # now the opened stream's receiver. - print('Stream opened: %s from %s' % (stream.sid, stream.receiver)) + print('Stream opened: %s from %s' % (stream.sid, stream.peer_jid)) # You could run a loop reading from the stream using stream.recv(), # or use the ibb_stream_data event. diff --git a/examples/migrate_roster.py b/examples/migrate_roster.py new file mode 100644 index 00000000..a93bdecd --- /dev/null +++ b/examples/migrate_roster.py @@ -0,0 +1,117 @@ +import sys +import logging +import getpass +from optparse import OptionParser + +import sleekxmpp + +# Python versions before 3.0 do not use UTF-8 encoding +# by default. To ensure that Unicode is handled properly +# throughout SleekXMPP, we will set the default encoding +# ourselves to UTF-8. +if sys.version_info < (3, 0): + from sleekxmpp.util.misc_ops import setdefaultencoding + setdefaultencoding('utf8') +else: + raw_input = input + + +# Setup the command line arguments. +optp = OptionParser() + +# Output verbosity options. +optp.add_option('-q', '--quiet', help='set logging to ERROR', + action='store_const', dest='loglevel', + const=logging.ERROR, default=logging.INFO) +optp.add_option('-d', '--debug', help='set logging to DEBUG', + action='store_const', dest='loglevel', + const=logging.DEBUG, default=logging.INFO) +optp.add_option('-v', '--verbose', help='set logging to COMM', + action='store_const', dest='loglevel', + const=5, default=logging.INFO) + +# JID and password options. +optp.add_option("--oldjid", dest="old_jid", + help="JID of the old account") +optp.add_option("--oldpassword", dest="old_password", + help="password of the old account") + +optp.add_option("--newjid", dest="new_jid", + help="JID of the old account") +optp.add_option("--newpassword", dest="new_password", + help="password of the old account") + + +opts, args = optp.parse_args() + +# Setup logging. +logging.basicConfig(level=opts.loglevel, + format='%(levelname)-8s %(message)s') + +if opts.old_jid is None: + opts.old_jid = raw_input("Old JID: ") +if opts.old_password is None: + opts.old_password = getpass.getpass("Old Password: ") + +if opts.new_jid is None: + opts.new_jid = raw_input("New JID: ") +if opts.new_password is None: + opts.new_password = getpass.getpass("New Password: ") + + +old_xmpp = sleekxmpp.ClientXMPP(opts.old_jid, opts.old_password) + +# If you are connecting to Facebook and wish to use the +# X-FACEBOOK-PLATFORM authentication mechanism, you will need +# your API key and an access token. Then you'll set: +# xmpp.credentials['api_key'] = 'THE_API_KEY' +# xmpp.credentials['access_token'] = 'THE_ACCESS_TOKEN' + +# If you are connecting to MSN, then you will need an +# access token, and it does not matter what JID you +# specify other than that the domain is 'messenger.live.com', +# so '_@messenger.live.com' will work. You can specify +# the access token as so: +# xmpp.credentials['access_token'] = 'THE_ACCESS_TOKEN' + +# If you are working with an OpenFire server, you may need +# to adjust the SSL version used: +# xmpp.ssl_version = ssl.PROTOCOL_SSLv3 + +# If you want to verify the SSL certificates offered by a server: +# xmpp.ca_certs = "path/to/ca/cert" + +roster = [] + +def on_session(event): + roster.append(old_xmpp.get_roster()) + old_xmpp.disconnect() +old_xmpp.add_event_handler('session_start', on_session) + +if old_xmpp.connect(): + old_xmpp.process(block=True) + +if not roster: + print('No roster to migrate') + sys.exit() + +new_xmpp = sleekxmpp.ClientXMPP(opts.new_jid, opts.new_password) +def on_session2(event): + new_xmpp.get_roster() + new_xmpp.send_presence() + + logging.info(roster[0]) + data = roster[0]['roster']['items'] + logging.info(data) + + for jid, item in data.items(): + if item['subscription'] != 'none': + new_xmpp.send_presence(ptype='subscribe', pto=jid) + new_xmpp.update_roster(jid, + name = item['name'], + groups = item['groups']) + new_xmpp.disconnect() +new_xmpp.add_event_handler('session_start', on_session2) + +if new_xmpp.connect(): + new_xmpp.process(block=True) diff --git a/examples/ping.py b/examples/ping.py index 0e53b1dd..8fbb5655 100755 --- a/examples/ping.py +++ b/examples/ping.py @@ -62,16 +62,18 @@ class PingTest(sleekxmpp.ClientXMPP): """ self.send_presence() self.get_roster() - result = self['xep_0199'].send_ping(self.pingjid, - timeout=10, - errorfalse=True) - logging.info("Pinging...") - if result is False: - logging.info("Couldn't ping.") - self.disconnect() - sys.exit(1) - else: - logging.info("Success! RTT: %s", str(result)) + + try: + rtt = self['xep_0199'].ping(self.pingjid, + timeout=10) + logging.info("Success! RTT: %s", rtt) + except IqError as e: + logging.info("Error pinging %s: %s", + self.pingjid, + e.iq['error']['condition']) + except IqTimeout: + logging.info("No response from %s", self.pingjid) + finally: self.disconnect() diff --git a/examples/register_account.py b/examples/register_account.py index bd9b1160..422e5602 100644 --- a/examples/register_account.py +++ b/examples/register_account.py @@ -51,7 +51,7 @@ class RegisterBot(sleekxmpp.ClientXMPP): # The register event provides an Iq result stanza with # a registration form from the server. This may include - # the basic registration fields, a data form, an + # the basic registration fields, a data form, an # out-of-band URL, or any combination. For more advanced # cases, you will need to examine the fields provided # and respond accordingly. SleekXMPP provides plugins @@ -104,7 +104,7 @@ class RegisterBot(sleekxmpp.ClientXMPP): resp.send(now=True) logging.info("Account created for %s!" % self.boundjid) except IqError as e: - logging.error("Could not register account: %s" % + logging.error("Could not register account: %s" % e.iq['error']['text']) self.disconnect() except IqTimeout: @@ -153,6 +153,10 @@ if __name__ == '__main__': xmpp.register_plugin('xep_0066') # Out-of-band Data xmpp.register_plugin('xep_0077') # In-band Registration + # Some servers don't advertise support for inband registration, even + # though they allow it. If this applies to your server, use: + xmpp['xep_0077'].force_registration = True + # If you are working with an OpenFire server, you may need # to adjust the SSL version used: # xmpp.ssl_version = ssl.PROTOCOL_SSLv3 |