summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--INSTALL5
-rw-r--r--MANIFEST.in3
-rw-r--r--README.rst106
-rw-r--r--docs/Makefile8
-rw-r--r--docs/_static/nature.css68
-rw-r--r--docs/_static/sphinxdoc.css2
-rw-r--r--docs/api/basexmpp.rst2
-rw-r--r--docs/api/clientxmpp.rst2
-rw-r--r--docs/api/componentxmpp.rst2
-rw-r--r--docs/api/exceptions.rst4
-rw-r--r--docs/api/stanza/iq.rst8
-rw-r--r--docs/api/stanza/message.rst7
-rw-r--r--docs/api/stanza/presence.rst8
-rw-r--r--docs/api/stanza/rootstanza.rst8
-rw-r--r--docs/api/xmlstream/filesocket.rst12
-rw-r--r--docs/api/xmlstream/handler.rst10
-rw-r--r--docs/api/xmlstream/jid.rst2
-rw-r--r--docs/api/xmlstream/matcher.rst10
-rw-r--r--docs/api/xmlstream/scheduler.rst11
-rw-r--r--docs/api/xmlstream/stanzabase.rst20
-rw-r--r--docs/api/xmlstream/tostring.rst13
-rw-r--r--docs/api/xmlstream/xmlstream.rst4
-rw-r--r--docs/architecture.rst129
-rw-r--r--docs/conf.py14
-rw-r--r--docs/create_plugin.rst115
-rw-r--r--docs/differences.rst47
-rw-r--r--docs/event_index.rst169
-rw-r--r--docs/getting_started/component.rst32
-rw-r--r--docs/getting_started/echobot.rst119
-rw-r--r--docs/getting_started/iq.rst62
-rw-r--r--docs/getting_started/muc.rst32
-rw-r--r--docs/getting_started/proxy.rst12
-rw-r--r--docs/getting_started/sendlogout.rst32
-rw-r--r--docs/glossary.rst17
-rw-r--r--docs/guide_xep_0030.rst17
-rw-r--r--docs/index.rst112
-rw-r--r--docs/license.rst2
-rw-r--r--docs/make.bat4
-rw-r--r--docs/using_asyncio.rst148
-rw-r--r--docs/xeps.rst6
-rw-r--r--docs/xmpp_tdg.rst46
-rwxr-xr-xexamples/IoT_TestDevice.py97
-rwxr-xr-xexamples/adhoc_provider.py89
-rwxr-xr-xexamples/adhoc_user.py105
-rwxr-xr-xexamples/admin_commands.py101
-rwxr-xr-xexamples/custom_stanzas/custom_stanza_provider.py106
-rwxr-xr-xexamples/custom_stanzas/custom_stanza_user.py111
-rw-r--r--examples/custom_stanzas/stanza.py16
-rwxr-xr-xexamples/disco_browser.py135
-rwxr-xr-xexamples/download_avatars.py133
-rwxr-xr-xexamples/echo_client.py102
-rwxr-xr-xexamples/echo_component.py101
-rwxr-xr-xexamples/gtalk_custom_domain.py92
-rw-r--r--examples/http_over_xmpp.py34
-rwxr-xr-xexamples/ibb_transfer/ibb_receiver.py135
-rwxr-xr-xexamples/ibb_transfer/ibb_sender.py144
-rwxr-xr-xexamples/migrate_roster.py79
-rwxr-xr-xexamples/muc.py98
-rwxr-xr-xexamples/ping.py103
-rwxr-xr-xexamples/proxy_echo_client.py133
-rwxr-xr-xexamples/pubsub_client.py207
-rwxr-xr-xexamples/pubsub_events.py88
-rwxr-xr-xexamples/register_account.py97
-rwxr-xr-xexamples/roster_browser.py120
-rwxr-xr-xexamples/rpc_async.py10
-rwxr-xr-xexamples/rpc_client_side.py8
-rwxr-xr-xexamples/rpc_server_side.py8
-rwxr-xr-xexamples/s5b_transfer/s5b_receiver.py90
-rwxr-xr-xexamples/s5b_transfer/s5b_sender.py124
-rwxr-xr-xexamples/send_client.py111
-rwxr-xr-xexamples/set_avatar.py154
-rwxr-xr-xexamples/thirdparty_auth.py97
-rwxr-xr-xexamples/user_location.py72
-rwxr-xr-xexamples/user_tune.py68
-rw-r--r--ez_setup.py233
-rwxr-xr-xrun_tests.py69
-rwxr-xr-xsetup.py183
-rw-r--r--sleekxmpp/__init__.py30
-rw-r--r--sleekxmpp/features/feature_bind/__init__.py19
-rw-r--r--sleekxmpp/features/feature_mechanisms/__init__.py22
-rw-r--r--sleekxmpp/features/feature_mechanisms/stanza/__init__.py16
-rw-r--r--sleekxmpp/features/feature_preapproval/__init__.py15
-rw-r--r--sleekxmpp/features/feature_rosterver/__init__.py19
-rw-r--r--sleekxmpp/features/feature_session/__init__.py19
-rw-r--r--sleekxmpp/features/feature_starttls/__init__.py19
-rw-r--r--sleekxmpp/jid.py632
-rw-r--r--sleekxmpp/plugins/google/__init__.py47
-rw-r--r--sleekxmpp/plugins/google/auth/__init__.py10
-rw-r--r--sleekxmpp/plugins/google/auth/auth.py52
-rw-r--r--sleekxmpp/plugins/google/gmail/__init__.py10
-rw-r--r--sleekxmpp/plugins/google/gmail/stanza.py101
-rw-r--r--sleekxmpp/plugins/google/nosave/__init__.py10
-rw-r--r--sleekxmpp/plugins/google/nosave/nosave.py83
-rw-r--r--sleekxmpp/plugins/google/settings/__init__.py10
-rw-r--r--sleekxmpp/plugins/google/settings/stanza.py110
-rw-r--r--sleekxmpp/plugins/xep_0004/__init__.py22
-rw-r--r--sleekxmpp/plugins/xep_0004/stanza/__init__.py10
-rw-r--r--sleekxmpp/plugins/xep_0009/__init__.py20
-rw-r--r--sleekxmpp/plugins/xep_0009/stanza/__init__.py9
-rw-r--r--sleekxmpp/plugins/xep_0012/__init__.py19
-rw-r--r--sleekxmpp/plugins/xep_0013/__init__.py15
-rw-r--r--sleekxmpp/plugins/xep_0016/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0016/privacy.py110
-rw-r--r--sleekxmpp/plugins/xep_0020/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0027/__init__.py15
-rw-r--r--sleekxmpp/plugins/xep_0030/__init__.py23
-rw-r--r--sleekxmpp/plugins/xep_0030/stanza/__init__.py10
-rw-r--r--sleekxmpp/plugins/xep_0033/__init__.py20
-rw-r--r--sleekxmpp/plugins/xep_0047/__init__.py21
-rw-r--r--sleekxmpp/plugins/xep_0047/stream.py148
-rw-r--r--sleekxmpp/plugins/xep_0048/__init__.py15
-rw-r--r--sleekxmpp/plugins/xep_0049/__init__.py15
-rw-r--r--sleekxmpp/plugins/xep_0050/__init__.py19
-rw-r--r--sleekxmpp/plugins/xep_0054/__init__.py15
-rw-r--r--sleekxmpp/plugins/xep_0059/__init__.py18
-rw-r--r--sleekxmpp/plugins/xep_0060/__init__.py19
-rw-r--r--sleekxmpp/plugins/xep_0060/stanza/__init__.py12
-rw-r--r--sleekxmpp/plugins/xep_0065/__init__.py7
-rw-r--r--sleekxmpp/plugins/xep_0066/__init__.py20
-rw-r--r--sleekxmpp/plugins/xep_0071/__init__.py15
-rw-r--r--sleekxmpp/plugins/xep_0077/__init__.py19
-rw-r--r--sleekxmpp/plugins/xep_0078/__init__.py20
-rw-r--r--sleekxmpp/plugins/xep_0080/__init__.py15
-rw-r--r--sleekxmpp/plugins/xep_0084/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0085/__init__.py19
-rw-r--r--sleekxmpp/plugins/xep_0086/__init__.py19
-rw-r--r--sleekxmpp/plugins/xep_0091/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0092/__init__.py20
-rw-r--r--sleekxmpp/plugins/xep_0095/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0096/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0107/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0108/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0115/__init__.py20
-rw-r--r--sleekxmpp/plugins/xep_0118/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0122/__init__.py11
-rw-r--r--sleekxmpp/plugins/xep_0122/data_validation.py19
-rw-r--r--sleekxmpp/plugins/xep_0128/__init__.py19
-rw-r--r--sleekxmpp/plugins/xep_0131/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0152/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0153/__init__.py15
-rw-r--r--sleekxmpp/plugins/xep_0172/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0184/__init__.py19
-rw-r--r--sleekxmpp/plugins/xep_0186/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0191/__init__.py15
-rw-r--r--sleekxmpp/plugins/xep_0196/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0198/__init__.py20
-rw-r--r--sleekxmpp/plugins/xep_0199/__init__.py20
-rw-r--r--sleekxmpp/plugins/xep_0202/__init__.py20
-rw-r--r--sleekxmpp/plugins/xep_0203/__init__.py19
-rw-r--r--sleekxmpp/plugins/xep_0221/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0224/__init__.py20
-rw-r--r--sleekxmpp/plugins/xep_0231/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0235/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0249/__init__.py19
-rw-r--r--sleekxmpp/plugins/xep_0257/__init__.py17
-rw-r--r--sleekxmpp/plugins/xep_0257/client_cert_management.py65
-rw-r--r--sleekxmpp/plugins/xep_0258/__init__.py18
-rw-r--r--sleekxmpp/plugins/xep_0279/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0280/__init__.py17
-rw-r--r--sleekxmpp/plugins/xep_0297/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0308/__init__.py15
-rw-r--r--sleekxmpp/plugins/xep_0313/__init__.py15
-rw-r--r--sleekxmpp/plugins/xep_0319/__init__.py16
-rw-r--r--sleekxmpp/plugins/xep_0332/stanza/__init__.py13
-rw-r--r--sleekxmpp/roster/__init__.py11
-rw-r--r--sleekxmpp/stanza/__init__.py15
-rw-r--r--sleekxmpp/stanza/htmlim.py21
-rw-r--r--sleekxmpp/stanza/nick.py23
-rw-r--r--sleekxmpp/test/__init__.py11
-rw-r--r--sleekxmpp/thirdparty/__init__.py13
-rw-r--r--sleekxmpp/thirdparty/ordereddict.py127
-rw-r--r--sleekxmpp/thirdparty/socks.py387
-rw-r--r--sleekxmpp/thirdparty/statemachine.py294
-rw-r--r--sleekxmpp/util/__init__.py48
-rw-r--r--sleekxmpp/xmlstream/__init__.py19
-rw-r--r--sleekxmpp/xmlstream/filesocket.py54
-rw-r--r--sleekxmpp/xmlstream/handler/__init__.py15
-rw-r--r--sleekxmpp/xmlstream/jid.py5
-rw-r--r--sleekxmpp/xmlstream/matcher/__init__.py17
-rw-r--r--sleekxmpp/xmlstream/scheduler.py250
-rw-r--r--sleekxmpp/xmlstream/xmlstream.py1817
-rw-r--r--slixmpp/__init__.py26
-rw-r--r--slixmpp/api.py (renamed from sleekxmpp/api.py)2
-rw-r--r--slixmpp/basexmpp.py (renamed from sleekxmpp/basexmpp.py)164
-rw-r--r--slixmpp/clientxmpp.py (renamed from sleekxmpp/clientxmpp.py)89
-rw-r--r--slixmpp/componentxmpp.py (renamed from sleekxmpp/componentxmpp.py)53
-rw-r--r--slixmpp/exceptions.py (renamed from sleekxmpp/exceptions.py)24
-rw-r--r--slixmpp/features/__init__.py (renamed from sleekxmpp/features/__init__.py)4
-rw-r--r--slixmpp/features/feature_bind/__init__.py19
-rw-r--r--slixmpp/features/feature_bind/bind.py (renamed from sleekxmpp/features/feature_bind/bind.py)26
-rw-r--r--slixmpp/features/feature_bind/stanza.py (renamed from sleekxmpp/features/feature_bind/stanza.py)6
-rw-r--r--slixmpp/features/feature_mechanisms/__init__.py22
-rw-r--r--slixmpp/features/feature_mechanisms/mechanisms.py (renamed from sleekxmpp/features/feature_mechanisms/mechanisms.py)39
-rw-r--r--slixmpp/features/feature_mechanisms/stanza/__init__.py16
-rw-r--r--slixmpp/features/feature_mechanisms/stanza/abort.py (renamed from sleekxmpp/features/feature_mechanisms/stanza/abort.py)6
-rw-r--r--slixmpp/features/feature_mechanisms/stanza/auth.py (renamed from sleekxmpp/features/feature_mechanisms/stanza/auth.py)8
-rw-r--r--slixmpp/features/feature_mechanisms/stanza/challenge.py (renamed from sleekxmpp/features/feature_mechanisms/stanza/challenge.py)8
-rw-r--r--slixmpp/features/feature_mechanisms/stanza/failure.py (renamed from sleekxmpp/features/feature_mechanisms/stanza/failure.py)6
-rw-r--r--slixmpp/features/feature_mechanisms/stanza/mechanisms.py (renamed from sleekxmpp/features/feature_mechanisms/stanza/mechanisms.py)6
-rw-r--r--slixmpp/features/feature_mechanisms/stanza/response.py (renamed from sleekxmpp/features/feature_mechanisms/stanza/response.py)8
-rw-r--r--slixmpp/features/feature_mechanisms/stanza/success.py (renamed from sleekxmpp/features/feature_mechanisms/stanza/success.py)8
-rw-r--r--slixmpp/features/feature_preapproval/__init__.py15
-rw-r--r--slixmpp/features/feature_preapproval/preapproval.py (renamed from sleekxmpp/features/feature_preapproval/preapproval.py)12
-rw-r--r--slixmpp/features/feature_preapproval/stanza.py (renamed from sleekxmpp/features/feature_preapproval/stanza.py)6
-rw-r--r--slixmpp/features/feature_rosterver/__init__.py19
-rw-r--r--slixmpp/features/feature_rosterver/rosterver.py (renamed from sleekxmpp/features/feature_rosterver/rosterver.py)12
-rw-r--r--slixmpp/features/feature_rosterver/stanza.py (renamed from sleekxmpp/features/feature_rosterver/stanza.py)6
-rw-r--r--slixmpp/features/feature_session/__init__.py19
-rw-r--r--slixmpp/features/feature_session/session.py (renamed from sleekxmpp/features/feature_session/session.py)16
-rw-r--r--slixmpp/features/feature_session/stanza.py (renamed from sleekxmpp/features/feature_session/stanza.py)6
-rw-r--r--slixmpp/features/feature_starttls/__init__.py19
-rw-r--r--slixmpp/features/feature_starttls/stanza.py (renamed from sleekxmpp/features/feature_starttls/stanza.py)6
-rw-r--r--slixmpp/features/feature_starttls/starttls.py (renamed from sleekxmpp/features/feature_starttls/starttls.py)21
-rw-r--r--slixmpp/jid.py449
-rw-r--r--slixmpp/plugins/__init__.py (renamed from sleekxmpp/plugins/__init__.py)8
-rw-r--r--slixmpp/plugins/base.py (renamed from sleekxmpp/plugins/base.py)34
-rw-r--r--slixmpp/plugins/gmail_notify.py (renamed from sleekxmpp/plugins/gmail_notify.py)16
-rw-r--r--slixmpp/plugins/google/auth/stanza.py (renamed from sleekxmpp/plugins/google/auth/stanza.py)8
-rw-r--r--slixmpp/plugins/google/gmail/notifications.py (renamed from sleekxmpp/plugins/google/gmail/notifications.py)38
-rw-r--r--slixmpp/plugins/google/nosave/stanza.py (renamed from sleekxmpp/plugins/google/nosave/stanza.py)8
-rw-r--r--slixmpp/plugins/google/settings/settings.py (renamed from sleekxmpp/plugins/google/settings/settings.py)24
-rw-r--r--slixmpp/plugins/xep_0004/__init__.py22
-rw-r--r--slixmpp/plugins/xep_0004/dataforms.py (renamed from sleekxmpp/plugins/xep_0004/dataforms.py)18
-rw-r--r--slixmpp/plugins/xep_0004/stanza/__init__.py10
-rw-r--r--slixmpp/plugins/xep_0004/stanza/field.py (renamed from sleekxmpp/plugins/xep_0004/stanza/field.py)6
-rw-r--r--slixmpp/plugins/xep_0004/stanza/form.py (renamed from sleekxmpp/plugins/xep_0004/stanza/form.py)16
-rw-r--r--slixmpp/plugins/xep_0009/__init__.py20
-rw-r--r--slixmpp/plugins/xep_0009/binding.py (renamed from sleekxmpp/plugins/xep_0009/binding.py)14
-rw-r--r--slixmpp/plugins/xep_0009/remote.py (renamed from sleekxmpp/plugins/xep_0009/remote.py)35
-rw-r--r--slixmpp/plugins/xep_0009/rpc.py (renamed from sleekxmpp/plugins/xep_0009/rpc.py)441
-rw-r--r--slixmpp/plugins/xep_0009/stanza/RPC.py (renamed from sleekxmpp/plugins/xep_0009/stanza/RPC.py)6
-rw-r--r--slixmpp/plugins/xep_0009/stanza/__init__.py9
-rw-r--r--slixmpp/plugins/xep_0012/__init__.py19
-rw-r--r--slixmpp/plugins/xep_0012/last_activity.py (renamed from sleekxmpp/plugins/xep_0012/last_activity.py)313
-rw-r--r--slixmpp/plugins/xep_0012/stanza.py (renamed from sleekxmpp/plugins/xep_0012/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0013/__init__.py15
-rw-r--r--slixmpp/plugins/xep_0013/offline.py (renamed from sleekxmpp/plugins/xep_0013/offline.py)86
-rw-r--r--slixmpp/plugins/xep_0013/stanza.py (renamed from sleekxmpp/plugins/xep_0013/stanza.py)8
-rw-r--r--slixmpp/plugins/xep_0016/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0016/privacy.py127
-rw-r--r--slixmpp/plugins/xep_0016/stanza.py (renamed from sleekxmpp/plugins/xep_0016/stanza.py)2
-rw-r--r--slixmpp/plugins/xep_0020/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0020/feature_negotiation.py (renamed from sleekxmpp/plugins/xep_0020/feature_negotiation.py)18
-rw-r--r--slixmpp/plugins/xep_0020/stanza.py (renamed from sleekxmpp/plugins/xep_0020/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0027/__init__.py15
-rw-r--r--slixmpp/plugins/xep_0027/gpg.py (renamed from sleekxmpp/plugins/xep_0027/gpg.py)21
-rw-r--r--slixmpp/plugins/xep_0027/stanza.py (renamed from sleekxmpp/plugins/xep_0027/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0030/__init__.py22
-rw-r--r--slixmpp/plugins/xep_0030/disco.py (renamed from sleekxmpp/plugins/xep_0030/disco.py)53
-rw-r--r--slixmpp/plugins/xep_0030/stanza/__init__.py10
-rw-r--r--slixmpp/plugins/xep_0030/stanza/info.py (renamed from sleekxmpp/plugins/xep_0030/stanza/info.py)10
-rw-r--r--slixmpp/plugins/xep_0030/stanza/items.py (renamed from sleekxmpp/plugins/xep_0030/stanza/items.py)10
-rw-r--r--slixmpp/plugins/xep_0030/static.py (renamed from sleekxmpp/plugins/xep_0030/static.py)20
-rw-r--r--slixmpp/plugins/xep_0033/__init__.py20
-rw-r--r--slixmpp/plugins/xep_0033/addresses.py (renamed from sleekxmpp/plugins/xep_0033/addresses.py)12
-rw-r--r--slixmpp/plugins/xep_0033/stanza.py (renamed from sleekxmpp/plugins/xep_0033/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0045.py (renamed from sleekxmpp/plugins/xep_0045.py)50
-rw-r--r--slixmpp/plugins/xep_0047/__init__.py21
-rw-r--r--slixmpp/plugins/xep_0047/ibb.py (renamed from sleekxmpp/plugins/xep_0047/ibb.py)110
-rw-r--r--slixmpp/plugins/xep_0047/stanza.py (renamed from sleekxmpp/plugins/xep_0047/stanza.py)13
-rw-r--r--slixmpp/plugins/xep_0047/stream.py128
-rw-r--r--slixmpp/plugins/xep_0048/__init__.py15
-rw-r--r--slixmpp/plugins/xep_0048/bookmarks.py (renamed from sleekxmpp/plugins/xep_0048/bookmarks.py)18
-rw-r--r--slixmpp/plugins/xep_0048/stanza.py (renamed from sleekxmpp/plugins/xep_0048/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0049/__init__.py15
-rw-r--r--slixmpp/plugins/xep_0049/private_storage.py (renamed from sleekxmpp/plugins/xep_0049/private_storage.py)28
-rw-r--r--slixmpp/plugins/xep_0049/stanza.py (renamed from sleekxmpp/plugins/xep_0049/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0050/__init__.py19
-rw-r--r--slixmpp/plugins/xep_0050/adhoc.py (renamed from sleekxmpp/plugins/xep_0050/adhoc.py)96
-rw-r--r--slixmpp/plugins/xep_0050/stanza.py (renamed from sleekxmpp/plugins/xep_0050/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0054/__init__.py15
-rw-r--r--slixmpp/plugins/xep_0054/stanza.py (renamed from sleekxmpp/plugins/xep_0054/stanza.py)23
-rw-r--r--slixmpp/plugins/xep_0054/vcard_temp.py (renamed from sleekxmpp/plugins/xep_0054/vcard_temp.py)39
-rw-r--r--slixmpp/plugins/xep_0059/__init__.py18
-rw-r--r--slixmpp/plugins/xep_0059/rsm.py (renamed from sleekxmpp/plugins/xep_0059/rsm.py)16
-rw-r--r--slixmpp/plugins/xep_0059/stanza.py (renamed from sleekxmpp/plugins/xep_0059/stanza.py)8
-rw-r--r--slixmpp/plugins/xep_0060/__init__.py19
-rw-r--r--slixmpp/plugins/xep_0060/pubsub.py (renamed from sleekxmpp/plugins/xep_0060/pubsub.py)169
-rw-r--r--slixmpp/plugins/xep_0060/stanza/__init__.py12
-rw-r--r--slixmpp/plugins/xep_0060/stanza/base.py (renamed from sleekxmpp/plugins/xep_0060/stanza/base.py)6
-rw-r--r--slixmpp/plugins/xep_0060/stanza/pubsub.py (renamed from sleekxmpp/plugins/xep_0060/stanza/pubsub.py)12
-rw-r--r--slixmpp/plugins/xep_0060/stanza/pubsub_errors.py (renamed from sleekxmpp/plugins/xep_0060/stanza/pubsub_errors.py)8
-rw-r--r--slixmpp/plugins/xep_0060/stanza/pubsub_event.py (renamed from sleekxmpp/plugins/xep_0060/stanza/pubsub_event.py)12
-rw-r--r--slixmpp/plugins/xep_0060/stanza/pubsub_owner.py (renamed from sleekxmpp/plugins/xep_0060/stanza/pubsub_owner.py)16
-rw-r--r--slixmpp/plugins/xep_0065/__init__.py8
-rw-r--r--slixmpp/plugins/xep_0065/proxy.py (renamed from sleekxmpp/plugins/xep_0065/proxy.py)223
-rw-r--r--slixmpp/plugins/xep_0065/socks5.py265
-rw-r--r--slixmpp/plugins/xep_0065/stanza.py (renamed from sleekxmpp/plugins/xep_0065/stanza.py)4
-rw-r--r--slixmpp/plugins/xep_0066/__init__.py20
-rw-r--r--slixmpp/plugins/xep_0066/oob.py (renamed from sleekxmpp/plugins/xep_0066/oob.py)18
-rw-r--r--slixmpp/plugins/xep_0066/stanza.py (renamed from sleekxmpp/plugins/xep_0066/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0071/__init__.py15
-rw-r--r--slixmpp/plugins/xep_0071/stanza.py (renamed from sleekxmpp/plugins/xep_0071/stanza.py)12
-rw-r--r--slixmpp/plugins/xep_0071/xhtml_im.py (renamed from sleekxmpp/plugins/xep_0071/xhtml_im.py)12
-rw-r--r--slixmpp/plugins/xep_0077/__init__.py19
-rw-r--r--slixmpp/plugins/xep_0077/register.py (renamed from sleekxmpp/plugins/xep_0077/register.py)27
-rw-r--r--slixmpp/plugins/xep_0077/stanza.py (renamed from sleekxmpp/plugins/xep_0077/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0078/__init__.py20
-rw-r--r--slixmpp/plugins/xep_0078/legacyauth.py (renamed from sleekxmpp/plugins/xep_0078/legacyauth.py)46
-rw-r--r--slixmpp/plugins/xep_0078/stanza.py (renamed from sleekxmpp/plugins/xep_0078/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0079/__init__.py (renamed from sleekxmpp/plugins/xep_0079/__init__.py)10
-rw-r--r--slixmpp/plugins/xep_0079/amp.py (renamed from sleekxmpp/plugins/xep_0079/amp.py)16
-rw-r--r--slixmpp/plugins/xep_0079/stanza.py (renamed from sleekxmpp/plugins/xep_0079/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0080/__init__.py15
-rw-r--r--slixmpp/plugins/xep_0080/geoloc.py (renamed from sleekxmpp/plugins/xep_0080/geoloc.py)34
-rw-r--r--slixmpp/plugins/xep_0080/stanza.py (renamed from sleekxmpp/plugins/xep_0080/stanza.py)8
-rw-r--r--slixmpp/plugins/xep_0082.py (renamed from sleekxmpp/plugins/xep_0082.py)8
-rw-r--r--slixmpp/plugins/xep_0084/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0084/avatar.py (renamed from sleekxmpp/plugins/xep_0084/avatar.py)51
-rw-r--r--slixmpp/plugins/xep_0084/stanza.py (renamed from sleekxmpp/plugins/xep_0084/stanza.py)17
-rw-r--r--slixmpp/plugins/xep_0085/__init__.py19
-rw-r--r--slixmpp/plugins/xep_0085/chat_states.py (renamed from sleekxmpp/plugins/xep_0085/chat_states.py)18
-rw-r--r--slixmpp/plugins/xep_0085/stanza.py (renamed from sleekxmpp/plugins/xep_0085/stanza.py)8
-rw-r--r--slixmpp/plugins/xep_0086/__init__.py19
-rw-r--r--slixmpp/plugins/xep_0086/legacy_error.py (renamed from sleekxmpp/plugins/xep_0086/legacy_error.py)92
-rw-r--r--slixmpp/plugins/xep_0086/stanza.py (renamed from sleekxmpp/plugins/xep_0086/stanza.py)8
-rw-r--r--slixmpp/plugins/xep_0091/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0091/legacy_delay.py (renamed from sleekxmpp/plugins/xep_0091/legacy_delay.py)12
-rw-r--r--slixmpp/plugins/xep_0091/stanza.py (renamed from sleekxmpp/plugins/xep_0091/stanza.py)10
-rw-r--r--slixmpp/plugins/xep_0092/__init__.py20
-rw-r--r--slixmpp/plugins/xep_0092/stanza.py (renamed from sleekxmpp/plugins/xep_0092/stanza.py)8
-rw-r--r--slixmpp/plugins/xep_0092/version.py (renamed from sleekxmpp/plugins/xep_0092/version.py)30
-rw-r--r--slixmpp/plugins/xep_0095/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0095/stanza.py (renamed from sleekxmpp/plugins/xep_0095/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0095/stream_initiation.py (renamed from sleekxmpp/plugins/xep_0095/stream_initiation.py)19
-rw-r--r--slixmpp/plugins/xep_0096/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0096/file_transfer.py (renamed from sleekxmpp/plugins/xep_0096/file_transfer.py)16
-rw-r--r--slixmpp/plugins/xep_0096/stanza.py (renamed from sleekxmpp/plugins/xep_0096/stanza.py)8
-rw-r--r--slixmpp/plugins/xep_0106.py (renamed from sleekxmpp/plugins/xep_0106.py)6
-rw-r--r--slixmpp/plugins/xep_0107/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0107/stanza.py (renamed from sleekxmpp/plugins/xep_0107/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0107/user_mood.py (renamed from sleekxmpp/plugins/xep_0107/user_mood.py)54
-rw-r--r--slixmpp/plugins/xep_0108/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0108/stanza.py (renamed from sleekxmpp/plugins/xep_0108/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0108/user_activity.py (renamed from sleekxmpp/plugins/xep_0108/user_activity.py)46
-rw-r--r--slixmpp/plugins/xep_0115/__init__.py20
-rw-r--r--slixmpp/plugins/xep_0115/caps.py (renamed from sleekxmpp/plugins/xep_0115/caps.py)49
-rw-r--r--slixmpp/plugins/xep_0115/stanza.py (renamed from sleekxmpp/plugins/xep_0115/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0115/static.py (renamed from sleekxmpp/plugins/xep_0115/static.py)12
-rw-r--r--slixmpp/plugins/xep_0118/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0118/stanza.py (renamed from sleekxmpp/plugins/xep_0118/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0118/user_tune.py (renamed from sleekxmpp/plugins/xep_0118/user_tune.py)28
-rw-r--r--slixmpp/plugins/xep_0122/__init__.py11
-rw-r--r--slixmpp/plugins/xep_0122/data_validation.py19
-rw-r--r--slixmpp/plugins/xep_0122/stanza.py (renamed from sleekxmpp/plugins/xep_0122/stanza.py)3
-rw-r--r--slixmpp/plugins/xep_0128/__init__.py19
-rw-r--r--slixmpp/plugins/xep_0128/extended_disco.py (renamed from sleekxmpp/plugins/xep_0128/extended_disco.py)20
-rw-r--r--slixmpp/plugins/xep_0128/static.py (renamed from sleekxmpp/plugins/xep_0128/static.py)8
-rw-r--r--slixmpp/plugins/xep_0131/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0131/headers.py (renamed from sleekxmpp/plugins/xep_0131/headers.py)14
-rw-r--r--slixmpp/plugins/xep_0131/stanza.py (renamed from sleekxmpp/plugins/xep_0131/stanza.py)8
-rw-r--r--slixmpp/plugins/xep_0133.py (renamed from sleekxmpp/plugins/xep_0133.py)11
-rw-r--r--slixmpp/plugins/xep_0138.py (renamed from sleekxmpp/plugins/xep_0138.py)17
-rw-r--r--slixmpp/plugins/xep_0152/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0152/reachability.py (renamed from sleekxmpp/plugins/xep_0152/reachability.py)31
-rw-r--r--slixmpp/plugins/xep_0152/stanza.py (renamed from sleekxmpp/plugins/xep_0152/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0153/__init__.py15
-rw-r--r--slixmpp/plugins/xep_0153/stanza.py (renamed from sleekxmpp/plugins/xep_0153/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0153/vcard_avatar.py (renamed from sleekxmpp/plugins/xep_0153/vcard_avatar.py)84
-rw-r--r--slixmpp/plugins/xep_0163.py (renamed from sleekxmpp/plugins/xep_0163.py)33
-rw-r--r--slixmpp/plugins/xep_0172/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0172/stanza.py (renamed from sleekxmpp/plugins/xep_0172/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0172/user_nick.py (renamed from sleekxmpp/plugins/xep_0172/user_nick.py)53
-rw-r--r--slixmpp/plugins/xep_0184/__init__.py19
-rw-r--r--slixmpp/plugins/xep_0184/receipt.py (renamed from sleekxmpp/plugins/xep_0184/receipt.py)18
-rw-r--r--slixmpp/plugins/xep_0184/stanza.py (renamed from sleekxmpp/plugins/xep_0184/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0186/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0186/invisible_command.py (renamed from sleekxmpp/plugins/xep_0186/invisible_command.py)20
-rw-r--r--slixmpp/plugins/xep_0186/stanza.py (renamed from sleekxmpp/plugins/xep_0186/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0191/__init__.py15
-rw-r--r--slixmpp/plugins/xep_0191/blocking.py (renamed from sleekxmpp/plugins/xep_0191/blocking.py)34
-rw-r--r--slixmpp/plugins/xep_0191/stanza.py (renamed from sleekxmpp/plugins/xep_0191/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0196/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0196/stanza.py (renamed from sleekxmpp/plugins/xep_0196/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0196/user_gaming.py (renamed from sleekxmpp/plugins/xep_0196/user_gaming.py)46
-rw-r--r--slixmpp/plugins/xep_0198/__init__.py20
-rw-r--r--slixmpp/plugins/xep_0198/stanza.py (renamed from sleekxmpp/plugins/xep_0198/stanza.py)8
-rw-r--r--slixmpp/plugins/xep_0198/stream_management.py (renamed from sleekxmpp/plugins/xep_0198/stream_management.py)25
-rw-r--r--slixmpp/plugins/xep_0199/__init__.py20
-rw-r--r--slixmpp/plugins/xep_0199/ping.py (renamed from sleekxmpp/plugins/xep_0199/ping.py)43
-rw-r--r--slixmpp/plugins/xep_0199/stanza.py (renamed from sleekxmpp/plugins/xep_0199/stanza.py)8
-rw-r--r--slixmpp/plugins/xep_0202/__init__.py20
-rw-r--r--slixmpp/plugins/xep_0202/stanza.py (renamed from sleekxmpp/plugins/xep_0202/stanza.py)10
-rw-r--r--slixmpp/plugins/xep_0202/time.py (renamed from sleekxmpp/plugins/xep_0202/time.py)198
-rw-r--r--slixmpp/plugins/xep_0203/__init__.py19
-rw-r--r--slixmpp/plugins/xep_0203/delay.py (renamed from sleekxmpp/plugins/xep_0203/delay.py)12
-rw-r--r--slixmpp/plugins/xep_0203/stanza.py (renamed from sleekxmpp/plugins/xep_0203/stanza.py)10
-rw-r--r--slixmpp/plugins/xep_0221/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0221/media.py (renamed from sleekxmpp/plugins/xep_0221/media.py)12
-rw-r--r--slixmpp/plugins/xep_0221/stanza.py (renamed from sleekxmpp/plugins/xep_0221/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0222.py (renamed from sleekxmpp/plugins/xep_0222.py)23
-rw-r--r--slixmpp/plugins/xep_0223.py (renamed from sleekxmpp/plugins/xep_0223.py)46
-rw-r--r--slixmpp/plugins/xep_0224/__init__.py20
-rw-r--r--slixmpp/plugins/xep_0224/attention.py (renamed from sleekxmpp/plugins/xep_0224/attention.py)16
-rw-r--r--slixmpp/plugins/xep_0224/stanza.py (renamed from sleekxmpp/plugins/xep_0224/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0231/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0231/bob.py (renamed from sleekxmpp/plugins/xep_0231/bob.py)29
-rw-r--r--slixmpp/plugins/xep_0231/stanza.py (renamed from sleekxmpp/plugins/xep_0231/stanza.py)12
-rw-r--r--slixmpp/plugins/xep_0235/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0235/oauth.py (renamed from sleekxmpp/plugins/xep_0235/oauth.py)12
-rw-r--r--slixmpp/plugins/xep_0235/stanza.py (renamed from sleekxmpp/plugins/xep_0235/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0242.py (renamed from sleekxmpp/plugins/xep_0242.py)6
-rw-r--r--slixmpp/plugins/xep_0249/__init__.py19
-rw-r--r--slixmpp/plugins/xep_0249/invite.py (renamed from sleekxmpp/plugins/xep_0249/invite.py)18
-rw-r--r--slixmpp/plugins/xep_0249/stanza.py (renamed from sleekxmpp/plugins/xep_0249/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0256.py (renamed from sleekxmpp/plugins/xep_0256.py)14
-rw-r--r--slixmpp/plugins/xep_0257/__init__.py17
-rw-r--r--slixmpp/plugins/xep_0257/client_cert_management.py70
-rw-r--r--slixmpp/plugins/xep_0257/stanza.py (renamed from sleekxmpp/plugins/xep_0257/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0258/__init__.py18
-rw-r--r--slixmpp/plugins/xep_0258/security_labels.py (renamed from sleekxmpp/plugins/xep_0258/security_labels.py)16
-rw-r--r--slixmpp/plugins/xep_0258/stanza.py (renamed from sleekxmpp/plugins/xep_0258/stanza.py)8
-rw-r--r--slixmpp/plugins/xep_0270.py (renamed from sleekxmpp/plugins/xep_0270.py)6
-rw-r--r--slixmpp/plugins/xep_0279/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0279/ipcheck.py (renamed from sleekxmpp/plugins/xep_0279/ipcheck.py)18
-rw-r--r--slixmpp/plugins/xep_0279/stanza.py (renamed from sleekxmpp/plugins/xep_0279/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0280/__init__.py17
-rw-r--r--slixmpp/plugins/xep_0280/carbons.py (renamed from sleekxmpp/plugins/xep_0280/carbons.py)30
-rw-r--r--slixmpp/plugins/xep_0280/stanza.py (renamed from sleekxmpp/plugins/xep_0280/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0297/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0297/forwarded.py (renamed from sleekxmpp/plugins/xep_0297/forwarded.py)16
-rw-r--r--slixmpp/plugins/xep_0297/stanza.py (renamed from sleekxmpp/plugins/xep_0297/stanza.py)8
-rw-r--r--slixmpp/plugins/xep_0302.py (renamed from sleekxmpp/plugins/xep_0302.py)6
-rw-r--r--slixmpp/plugins/xep_0308/__init__.py15
-rw-r--r--slixmpp/plugins/xep_0308/correction.py (renamed from sleekxmpp/plugins/xep_0308/correction.py)18
-rw-r--r--slixmpp/plugins/xep_0308/stanza.py (renamed from sleekxmpp/plugins/xep_0308/stanza.py)6
-rw-r--r--slixmpp/plugins/xep_0313/__init__.py15
-rw-r--r--slixmpp/plugins/xep_0313/mam.py (renamed from sleekxmpp/plugins/xep_0313/mam.py)43
-rw-r--r--slixmpp/plugins/xep_0313/stanza.py (renamed from sleekxmpp/plugins/xep_0313/stanza.py)10
-rw-r--r--slixmpp/plugins/xep_0319/__init__.py16
-rw-r--r--slixmpp/plugins/xep_0319/idle.py (renamed from sleekxmpp/plugins/xep_0319/idle.py)16
-rw-r--r--slixmpp/plugins/xep_0319/stanza.py (renamed from sleekxmpp/plugins/xep_0319/stanza.py)8
-rw-r--r--slixmpp/plugins/xep_0323/__init__.py (renamed from sleekxmpp/plugins/xep_0323/__init__.py)10
-rw-r--r--slixmpp/plugins/xep_0323/device.py (renamed from sleekxmpp/plugins/xep_0323/device.py)6
-rw-r--r--slixmpp/plugins/xep_0323/sensordata.py (renamed from sleekxmpp/plugins/xep_0323/sensordata.py)48
-rw-r--r--slixmpp/plugins/xep_0323/stanza/__init__.py (renamed from sleekxmpp/plugins/xep_0325/stanza/__init__.py)6
-rw-r--r--slixmpp/plugins/xep_0323/stanza/base.py (renamed from sleekxmpp/plugins/xep_0323/stanza/base.py)6
-rw-r--r--slixmpp/plugins/xep_0323/stanza/sensordata.py (renamed from sleekxmpp/plugins/xep_0323/stanza/sensordata.py)8
-rw-r--r--slixmpp/plugins/xep_0323/timerreset.py (renamed from sleekxmpp/plugins/xep_0323/timerreset.py)4
-rw-r--r--slixmpp/plugins/xep_0325/__init__.py (renamed from sleekxmpp/plugins/xep_0325/__init__.py)10
-rw-r--r--slixmpp/plugins/xep_0325/control.py (renamed from sleekxmpp/plugins/xep_0325/control.py)73
-rw-r--r--slixmpp/plugins/xep_0325/device.py (renamed from sleekxmpp/plugins/xep_0325/device.py)4
-rw-r--r--slixmpp/plugins/xep_0325/stanza/__init__.py (renamed from sleekxmpp/plugins/xep_0323/stanza/__init__.py)6
-rw-r--r--slixmpp/plugins/xep_0325/stanza/base.py (renamed from sleekxmpp/plugins/xep_0325/stanza/base.py)6
-rw-r--r--slixmpp/plugins/xep_0325/stanza/control.py (renamed from sleekxmpp/plugins/xep_0325/stanza/control.py)9
-rw-r--r--slixmpp/plugins/xep_0332/__init__.py (renamed from sleekxmpp/plugins/xep_0332/__init__.py)10
-rw-r--r--slixmpp/plugins/xep_0332/http.py (renamed from sleekxmpp/plugins/xep_0332/http.py)18
-rw-r--r--slixmpp/plugins/xep_0332/stanza/__init__.py13
-rw-r--r--slixmpp/plugins/xep_0332/stanza/data.py (renamed from sleekxmpp/plugins/xep_0332/stanza/data.py)6
-rw-r--r--slixmpp/plugins/xep_0332/stanza/request.py (renamed from sleekxmpp/plugins/xep_0332/stanza/request.py)6
-rw-r--r--slixmpp/plugins/xep_0332/stanza/response.py (renamed from sleekxmpp/plugins/xep_0332/stanza/response.py)6
-rw-r--r--slixmpp/roster/__init__.py11
-rw-r--r--slixmpp/roster/item.py (renamed from sleekxmpp/roster/item.py)8
-rw-r--r--slixmpp/roster/multi.py (renamed from sleekxmpp/roster/multi.py)16
-rw-r--r--slixmpp/roster/single.py (renamed from sleekxmpp/roster/single.py)22
-rw-r--r--slixmpp/stanza/__init__.py15
-rw-r--r--slixmpp/stanza/atom.py (renamed from sleekxmpp/stanza/atom.py)6
-rw-r--r--slixmpp/stanza/error.py (renamed from sleekxmpp/stanza/error.py)16
-rw-r--r--slixmpp/stanza/htmlim.py14
-rw-r--r--slixmpp/stanza/iq.py (renamed from sleekxmpp/stanza/iq.py)184
-rw-r--r--slixmpp/stanza/message.py (renamed from sleekxmpp/stanza/message.py)85
-rw-r--r--slixmpp/stanza/nick.py17
-rw-r--r--slixmpp/stanza/presence.py (renamed from sleekxmpp/stanza/presence.py)68
-rw-r--r--slixmpp/stanza/rootstanza.py (renamed from sleekxmpp/stanza/rootstanza.py)54
-rw-r--r--slixmpp/stanza/roster.py (renamed from sleekxmpp/stanza/roster.py)16
-rw-r--r--slixmpp/stanza/stream_error.py (renamed from sleekxmpp/stanza/stream_error.py)8
-rw-r--r--slixmpp/stanza/stream_features.py (renamed from sleekxmpp/stanza/stream_features.py)8
-rw-r--r--slixmpp/stringprep.py121
-rw-r--r--slixmpp/stringprep.pyx89
-rw-r--r--slixmpp/test/__init__.py11
-rw-r--r--slixmpp/test/livesocket.py (renamed from sleekxmpp/test/livesocket.py)7
-rw-r--r--slixmpp/test/mocksocket.py (renamed from sleekxmpp/test/mocksocket.py)100
-rw-r--r--slixmpp/test/slixtest.py (renamed from sleekxmpp/test/sleektest.py)162
-rw-r--r--slixmpp/thirdparty/__init__.py7
-rw-r--r--slixmpp/thirdparty/gnupg.py (renamed from sleekxmpp/thirdparty/gnupg.py)0
-rw-r--r--slixmpp/thirdparty/mini_dateutil.py (renamed from sleekxmpp/thirdparty/mini_dateutil.py)0
-rw-r--r--slixmpp/thirdparty/orderedset.py (renamed from sleekxmpp/thirdparty/orderedset.py)0
-rw-r--r--slixmpp/util/__init__.py15
-rw-r--r--slixmpp/util/misc_ops.py (renamed from sleekxmpp/util/misc_ops.py)44
-rw-r--r--slixmpp/util/sasl/__init__.py (renamed from sleekxmpp/util/sasl/__init__.py)8
-rw-r--r--slixmpp/util/sasl/client.py (renamed from sleekxmpp/util/sasl/client.py)6
-rw-r--r--slixmpp/util/sasl/mechanisms.py (renamed from sleekxmpp/util/sasl/mechanisms.py)16
-rw-r--r--slixmpp/util/stringprep_profiles.py (renamed from sleekxmpp/util/stringprep_profiles.py)6
-rw-r--r--slixmpp/version.py (renamed from sleekxmpp/version.py)8
-rw-r--r--slixmpp/xmlstream/__init__.py17
-rw-r--r--slixmpp/xmlstream/asyncio.py50
-rw-r--r--slixmpp/xmlstream/cert.py (renamed from sleekxmpp/xmlstream/cert.py)0
-rw-r--r--slixmpp/xmlstream/handler/__init__.py16
-rw-r--r--slixmpp/xmlstream/handler/base.py (renamed from sleekxmpp/xmlstream/handler/base.py)19
-rw-r--r--slixmpp/xmlstream/handler/callback.py (renamed from sleekxmpp/xmlstream/handler/callback.py)18
-rw-r--r--slixmpp/xmlstream/handler/collector.py (renamed from sleekxmpp/xmlstream/handler/collector.py)16
-rw-r--r--slixmpp/xmlstream/handler/coroutine_callback.py84
-rw-r--r--slixmpp/xmlstream/handler/waiter.py (renamed from sleekxmpp/xmlstream/handler/waiter.py)18
-rw-r--r--slixmpp/xmlstream/handler/xmlcallback.py (renamed from sleekxmpp/xmlstream/handler/xmlcallback.py)6
-rw-r--r--slixmpp/xmlstream/handler/xmlwaiter.py (renamed from sleekxmpp/xmlstream/handler/xmlwaiter.py)6
-rw-r--r--slixmpp/xmlstream/matcher/__init__.py17
-rw-r--r--slixmpp/xmlstream/matcher/base.py (renamed from sleekxmpp/xmlstream/matcher/base.py)4
-rw-r--r--slixmpp/xmlstream/matcher/id.py (renamed from sleekxmpp/xmlstream/matcher/id.py)8
-rw-r--r--slixmpp/xmlstream/matcher/idsender.py (renamed from sleekxmpp/xmlstream/matcher/idsender.py)8
-rw-r--r--slixmpp/xmlstream/matcher/many.py (renamed from sleekxmpp/xmlstream/matcher/many.py)6
-rw-r--r--slixmpp/xmlstream/matcher/stanzapath.py (renamed from sleekxmpp/xmlstream/matcher/stanzapath.py)12
-rw-r--r--slixmpp/xmlstream/matcher/xmlmask.py (renamed from sleekxmpp/xmlstream/matcher/xmlmask.py)12
-rw-r--r--slixmpp/xmlstream/matcher/xpath.py (renamed from sleekxmpp/xmlstream/matcher/xpath.py)12
-rw-r--r--slixmpp/xmlstream/resolver.py (renamed from sleekxmpp/xmlstream/resolver.py)209
-rw-r--r--slixmpp/xmlstream/stanzabase.py (renamed from sleekxmpp/xmlstream/stanzabase.py)79
-rw-r--r--slixmpp/xmlstream/tostring.py (renamed from sleekxmpp/xmlstream/tostring.py)41
-rw-r--r--slixmpp/xmlstream/xmlstream.py943
-rwxr-xr-xtestall.py67
-rw-r--r--tests/live_multiple_streams.py8
-rw-r--r--tests/live_test.py4
-rw-r--r--tests/test_events.py16
-rw-r--r--tests/test_jid.py124
-rw-r--r--tests/test_overall.py9
-rw-r--r--tests/test_plugins.py4
-rw-r--r--tests/test_stanza_base.py8
-rw-r--r--tests/test_stanza_element.py22
-rw-r--r--tests/test_stanza_error.py4
-rw-r--r--tests/test_stanza_gmail.py10
-rw-r--r--tests/test_stanza_iq.py10
-rw-r--r--tests/test_stanza_message.py16
-rw-r--r--tests/test_stanza_presence.py8
-rw-r--r--tests/test_stanza_roster.py8
-rw-r--r--tests/test_stanza_xep_0004.py12
-rw-r--r--tests/test_stanza_xep_0009.py22
-rw-r--r--tests/test_stanza_xep_0030.py10
-rw-r--r--tests/test_stanza_xep_0033.py10
-rw-r--r--tests/test_stanza_xep_0047.py16
-rw-r--r--tests/test_stanza_xep_0050.py10
-rw-r--r--tests/test_stanza_xep_0059.py8
-rw-r--r--tests/test_stanza_xep_0060.py22
-rw-r--r--tests/test_stanza_xep_0085.py10
-rw-r--r--tests/test_stanza_xep_0122.py64
-rw-r--r--tests/test_stanza_xep_0184.py10
-rw-r--r--tests/test_stanza_xep_0323.py7
-rw-r--r--tests/test_stanza_xep_0325.py11
-rw-r--r--tests/test_stream.py25
-rw-r--r--tests/test_stream_exceptions.py85
-rw-r--r--tests/test_stream_filters.py8
-rw-r--r--tests/test_stream_handlers.py86
-rw-r--r--tests/test_stream_presence.py17
-rw-r--r--tests/test_stream_roster.py65
-rw-r--r--tests/test_stream_xep_0030.py30
-rw-r--r--tests/test_stream_xep_0047.py44
-rw-r--r--tests/test_stream_xep_0050.py21
-rw-r--r--tests/test_stream_xep_0059.py163
-rw-r--r--tests/test_stream_xep_0060.py131
-rw-r--r--tests/test_stream_xep_0066.py21
-rw-r--r--tests/test_stream_xep_0085.py6
-rw-r--r--tests/test_stream_xep_0092.py22
-rw-r--r--tests/test_stream_xep_0128.py4
-rw-r--r--tests/test_stream_xep_0249.py10
-rw-r--r--tests/test_stream_xep_0323.py71
-rw-r--r--tests/test_stream_xep_0325.py32
-rw-r--r--tests/test_tostring.py10
-rw-r--r--tox.ini4
556 files changed, 9208 insertions, 12917 deletions
diff --git a/.gitignore b/.gitignore
index 628d1337..c15723d1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,7 +6,7 @@ docs/_build/
*.swp
.tox/
.coverage
-sleekxmpp.egg-info/
+slixmpp.egg-info/
.ropeproject/
4913
*~
diff --git a/INSTALL b/INSTALL
index 82f87123..3e45700d 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,5 +1,6 @@
Pre-requisites:
-- Python 3.1 or 2.6
+- Python 3.4
+- Cython 0.22 and libidn, optionally (making JID faster by compiling the stringprep module)
Install:
> python3 setup.py install
@@ -9,4 +10,4 @@ Root install:
To test:
> cd examples
-> python echo_client.py -v -j [USER@example.com] -p [PASSWORD]
+> python3 echo_client.py -d -j [USER@example.com] -p [PASSWORD]
diff --git a/MANIFEST.in b/MANIFEST.in
index f439bbd5..41263ee4 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,6 +1,7 @@
include README.rst
include LICENSE
-include testall.py
+include run_tests.py
+include slixmpp/stringprep.pyx
recursive-include docs Makefile *.bat *.py *.rst *.css *.ttf *.png
recursive-include examples *.py
recursive-include tests *.py
diff --git a/README.rst b/README.rst
index 3c142c9b..55edbc4b 100644
--- a/README.rst
+++ b/README.rst
@@ -1,77 +1,12 @@
-SleekXMPP
+Slixmpp
#########
-SleekXMPP is an MIT licensed XMPP library for Python 2.6/3.1+,
-and is featured in examples in
-`XMPP: The Definitive Guide <http://oreilly.com/catalog/9780596521271>`_
-by Kevin Smith, Remko Tronçon, and Peter Saint-Andre. If you've arrived
-here from reading the Definitive Guide, please see the notes on updating
-the examples to the latest version of SleekXMPP.
-
-SleekXMPP's design goals and philosphy are:
-
-**Low number of dependencies**
- Installing and using SleekXMPP should be as simple as possible, without
- having to deal with long dependency chains.
-
- As part of reducing the number of dependencies, some third party
- modules are included with SleekXMPP in the ``thirdparty`` directory.
- Imports from this module first try to import an existing installed
- version before loading the packaged version, when possible.
-
-**Every XEP as a plugin**
- Following Python's "batteries included" approach, the goal is to
- provide support for all currently active XEPs (final and draft). Since
- adding XEP support is done through easy to create plugins, the hope is
- to also provide a solid base for implementing and creating experimental
- XEPs.
-
-**Rewarding to work with**
- As much as possible, SleekXMPP should allow things to "just work" using
- sensible defaults and appropriate abstractions. XML can be ugly to work
- with, but it doesn't have to be that way.
-
-
-Get the Code
-------------
-
-Get the latest stable version from PyPI::
-
- pip install sleekxmpp
-
-The latest source code for SleekXMPP may be found on `Github
-<http://github.com/fritzy/SleekXMPP>`_. Releases can be found in the
-``master`` branch, while the latest development version is in the
-``develop`` branch.
-
-**Latest Release**
- - `1.3.1 <http://github.com/fritzy/SleekXMPP/zipball/1.3.1>`_
-
-**Develop Releases**
- - `Latest Develop Version <http://github.com/fritzy/SleekXMPP/zipball/develop>`_
-
-
-Installing DNSPython
---------------------
-If you are using Python3 and wish to use dnspython, you will have to checkout and
-install the ``python3`` branch::
-
- git clone http://github.com/rthalley/dnspython
- cd dnspython
- git checkout python3
- python3 setup.py install
-
-Discussion
-----------
-A mailing list and XMPP chat room are available for discussing and getting
-help with SleekXMPP.
-
-**Mailing List**
- `SleekXMPP Discussion on Google Groups <http://groups.google.com/group/sleekxmpp-discussion>`_
-
-**Chat**
- `sleek@conference.jabber.org <xmpp:sleek@conference.jabber.org?join>`_
+Slixmpp is an MIT licensed XMPP library for Python 3.4+. It is a fork of
+SleekXMPP.
+Slixmpp's goals is to only rewrite the core of the library (the low level
+socket handling, the timers, the events dispatching) in order to remove all
+threads.
Documentation and Testing
-------------------------
@@ -83,22 +18,22 @@ be in ``docs/_build/html``::
make html
open _build/html/index.html
-To run the test suite for SleekXMPP::
+To run the test suite for Slixmpp::
- python testall.py
+ python run_tests.py
-The SleekXMPP Boilerplate
+The Slixmpp Boilerplate
-------------------------
-Projects using SleekXMPP tend to follow a basic pattern for setting up client/component
-connections and configuration. Here is the gist of the boilerplate needed for a SleekXMPP
+Projects using Slixmpp tend to follow a basic pattern for setting up client/component
+connections and configuration. Here is the gist of the boilerplate needed for a Slixmpp
based project. See the documetation or examples directory for more detailed archetypes for
-SleekXMPP projects::
+Slixmpp projects::
import logging
- from sleekxmpp import ClientXMPP
- from sleekxmpp.exceptions import IqError, IqTimeout
+ from slixmpp import ClientXMPP
+ from slixmpp.exceptions import IqError, IqTimeout
class EchoBot(ClientXMPP):
@@ -152,11 +87,18 @@ SleekXMPP projects::
xmpp = EchoBot('somejid@example.com', 'use_getpass')
xmpp.connect()
- xmpp.process(block=True)
+ xmpp.process(forever=True)
+
+
+Slixmpp Credits
+---------------
+
+**Maintainer of the slixmpp fork:** Florent Le Coz
+ `louiz@louiz.org <xmpp:louiz@louiz.org?message>`_,
+Credits (SleekXMPP)
+-------------------
-Credits
--------
**Main Author:** Nathan Fritz
`fritzy@netflint.net <xmpp:fritzy@netflint.net?message>`_,
`@fritzy <http://twitter.com/fritzy>`_
diff --git a/docs/Makefile b/docs/Makefile
index a520f6a1..d44cd8a4 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -72,17 +72,17 @@ qthelp:
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SleekXMPP.qhcp"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Slixmpp.qhcp"
@echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SleekXMPP.qhc"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Slixmpp.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/SleekXMPP"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/SleekXMPP"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/Slixmpp"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Slixmpp"
@echo "# devhelp"
epub:
diff --git a/docs/_static/nature.css b/docs/_static/nature.css
index 52b328ea..b271ec97 100644
--- a/docs/_static/nature.css
+++ b/docs/_static/nature.css
@@ -8,11 +8,11 @@
* :license: BSD, see LICENSE for details.
*
*/
-
+
@import url("basic.css");
-
+
/* -- page layout ----------------------------------------------------------- */
-
+
body {
font-family: Arial, sans-serif;
font-size: 100%;
@@ -34,18 +34,18 @@ div.bodywrapper {
hr {
border: 1px solid #B1B4B6;
}
-
+
div.document {
background-color: #eee;
}
-
+
div.body {
background-color: #ffffff;
color: #3E4349;
padding: 0 30px 30px 30px;
font-size: 0.9em;
}
-
+
div.footer {
color: #555;
width: 100%;
@@ -53,12 +53,12 @@ div.footer {
text-align: center;
font-size: 75%;
}
-
+
div.footer a {
color: #444;
text-decoration: underline;
}
-
+
div.related {
background-color: #6BA81E;
line-height: 32px;
@@ -66,11 +66,11 @@ div.related {
text-shadow: 0px 1px 0 #444;
font-size: 0.9em;
}
-
+
div.related a {
color: #E2F3CC;
}
-
+
div.sphinxsidebar {
font-size: 0.75em;
line-height: 1.5em;
@@ -79,7 +79,7 @@ div.sphinxsidebar {
div.sphinxsidebarwrapper{
padding: 20px 0;
}
-
+
div.sphinxsidebar h3,
div.sphinxsidebar h4 {
font-family: Arial, sans-serif;
@@ -95,30 +95,30 @@ div.sphinxsidebar h4 {
div.sphinxsidebar h4{
font-size: 1.1em;
}
-
+
div.sphinxsidebar h3 a {
color: #444;
}
-
-
+
+
div.sphinxsidebar p {
color: #888;
padding: 5px 20px;
}
-
+
div.sphinxsidebar p.topless {
}
-
+
div.sphinxsidebar ul {
margin: 10px 20px;
padding: 0;
color: #000;
}
-
+
div.sphinxsidebar a {
color: #444;
}
-
+
div.sphinxsidebar input {
border: 1px solid #ccc;
font-family: sans-serif;
@@ -128,19 +128,19 @@ div.sphinxsidebar input {
div.sphinxsidebar input[type=text]{
margin-left: 20px;
}
-
+
/* -- body styles ----------------------------------------------------------- */
-
+
a {
color: #005B81;
text-decoration: none;
}
-
+
a:hover {
color: #E32E00;
text-decoration: underline;
}
-
+
div.body h1,
div.body h2,
div.body h3,
@@ -155,30 +155,30 @@ div.body h6 {
padding: 5px 0 5px 10px;
text-shadow: 0px 1px 0 white
}
-
+
div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; }
div.body h2 { font-size: 150%; background-color: #C8D5E3; }
div.body h3 { font-size: 120%; background-color: #D8DEE3; }
div.body h4 { font-size: 110%; background-color: #D8DEE3; }
div.body h5 { font-size: 100%; background-color: #D8DEE3; }
div.body h6 { font-size: 100%; background-color: #D8DEE3; }
-
+
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
}
-
+
a.headerlink:hover {
background-color: #c60f0f;
color: white;
}
-
+
div.body p, div.body dd, div.body li {
line-height: 1.5em;
}
-
+
div.admonition p.admonition-title + p {
display: inline;
}
@@ -191,29 +191,29 @@ div.note {
background-color: #eee;
border: 1px solid #ccc;
}
-
+
div.seealso {
background-color: #ffc;
border: 1px solid #ff6;
}
-
+
div.topic {
background-color: #eee;
}
-
+
div.warning {
background-color: #ffe4e4;
border: 1px solid #f66;
}
-
+
p.admonition-title {
display: inline;
}
-
+
p.admonition-title:after {
content: ":";
}
-
+
pre {
padding: 10px;
background-color: White;
@@ -225,7 +225,7 @@ pre {
-webkit-box-shadow: 1px 1px 1px #d8d8d8;
-moz-box-shadow: 1px 1px 1px #d8d8d8;
}
-
+
tt {
background-color: #ecf0f3;
color: #222;
diff --git a/docs/_static/sphinxdoc.css b/docs/_static/sphinxdoc.css
index 0a428074..55c574f6 100644
--- a/docs/_static/sphinxdoc.css
+++ b/docs/_static/sphinxdoc.css
@@ -134,7 +134,7 @@ div.footer a {
/* -- body styles ----------------------------------------------------------- */
-p {
+p {
margin: 0.8em 0 0.5em 0;
}
diff --git a/docs/api/basexmpp.rst b/docs/api/basexmpp.rst
index fa96322e..df05bb0b 100644
--- a/docs/api/basexmpp.rst
+++ b/docs/api/basexmpp.rst
@@ -2,7 +2,7 @@
BaseXMPP
========
-.. module:: sleekxmpp.basexmpp
+.. module:: slixmpp.basexmpp
.. autoclass:: BaseXMPP
:members:
diff --git a/docs/api/clientxmpp.rst b/docs/api/clientxmpp.rst
index a6f32c43..232c37c3 100644
--- a/docs/api/clientxmpp.rst
+++ b/docs/api/clientxmpp.rst
@@ -2,7 +2,7 @@
ClientXMPP
==========
-.. module:: sleekxmpp.clientxmpp
+.. module:: slixmpp.clientxmpp
.. autoclass:: ClientXMPP
:members:
diff --git a/docs/api/componentxmpp.rst b/docs/api/componentxmpp.rst
index 989120c2..9c6366aa 100644
--- a/docs/api/componentxmpp.rst
+++ b/docs/api/componentxmpp.rst
@@ -2,7 +2,7 @@
ComponentXMPP
=============
-.. module:: sleekxmpp.componentxmpp
+.. module:: slixmpp.componentxmpp
.. autoclass:: ComponentXMPP
:members:
diff --git a/docs/api/exceptions.rst b/docs/api/exceptions.rst
index 7bc72ce5..51e2e170 100644
--- a/docs/api/exceptions.rst
+++ b/docs/api/exceptions.rst
@@ -1,9 +1,9 @@
Exceptions
==========
-.. module:: sleekxmpp.exceptions
+.. module:: slixmpp.exceptions
+
-
.. autoexception:: XMPPError
:members:
diff --git a/docs/api/stanza/iq.rst b/docs/api/stanza/iq.rst
new file mode 100644
index 00000000..0a7d7ffb
--- /dev/null
+++ b/docs/api/stanza/iq.rst
@@ -0,0 +1,8 @@
+IQ Stanza
+=========
+
+.. module:: slixmpp.stanza
+
+.. autoclass:: Iq
+ :members:
+
diff --git a/docs/api/stanza/message.rst b/docs/api/stanza/message.rst
new file mode 100644
index 00000000..f01c62a7
--- /dev/null
+++ b/docs/api/stanza/message.rst
@@ -0,0 +1,7 @@
+Message Stanza
+==============
+
+.. module:: slixmpp.stanza
+
+.. autoclass:: Message
+ :members:
diff --git a/docs/api/stanza/presence.rst b/docs/api/stanza/presence.rst
new file mode 100644
index 00000000..15ac7bf9
--- /dev/null
+++ b/docs/api/stanza/presence.rst
@@ -0,0 +1,8 @@
+Presence Stanza
+===============
+
+.. module:: slixmpp.stanza
+
+.. autoclass:: Presence
+ :members:
+
diff --git a/docs/api/stanza/rootstanza.rst b/docs/api/stanza/rootstanza.rst
new file mode 100644
index 00000000..83d9f49b
--- /dev/null
+++ b/docs/api/stanza/rootstanza.rst
@@ -0,0 +1,8 @@
+Root Stanza
+===========
+
+.. module:: slixmpp.stanza.rootstanza
+
+.. autoclass:: RootStanza
+ :members:
+
diff --git a/docs/api/xmlstream/filesocket.rst b/docs/api/xmlstream/filesocket.rst
deleted file mode 100644
index 35f44019..00000000
--- a/docs/api/xmlstream/filesocket.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-.. module:: sleekxmpp.xmlstream.filesocket
-
-.. _filesocket:
-
-Python 2.6 File Socket Shims
-============================
-
-.. autoclass:: FileSocket
- :members:
-
-.. autoclass:: Socket26
- :members:
diff --git a/docs/api/xmlstream/handler.rst b/docs/api/xmlstream/handler.rst
index 33c0bf42..9d2f5aba 100644
--- a/docs/api/xmlstream/handler.rst
+++ b/docs/api/xmlstream/handler.rst
@@ -3,22 +3,26 @@ Stanza Handlers
The Basic Handler
-----------------
-.. module:: sleekxmpp.xmlstream.handler.base
+.. module:: slixmpp.xmlstream.handler.base
.. autoclass:: BaseHandler
:members:
Callback
--------
-.. module:: sleekxmpp.xmlstream.handler.callback
+.. module:: slixmpp.xmlstream.handler
.. autoclass:: Callback
:members:
+CoroutineCallback
+-----------------
+
+.. autoclass:: CoroutineCallback
+ :members:
Waiter
------
-.. module:: sleekxmpp.xmlstream.handler.waiter
.. autoclass:: Waiter
:members:
diff --git a/docs/api/xmlstream/jid.rst b/docs/api/xmlstream/jid.rst
index 22a2db45..2f0c65d0 100644
--- a/docs/api/xmlstream/jid.rst
+++ b/docs/api/xmlstream/jid.rst
@@ -1,7 +1,7 @@
Jabber IDs (JID)
=================
-.. module:: sleekxmpp.xmlstream.jid
+.. module:: slixmpp.jid
.. autoclass:: JID
:members:
diff --git a/docs/api/xmlstream/matcher.rst b/docs/api/xmlstream/matcher.rst
index df3591bc..793059f2 100644
--- a/docs/api/xmlstream/matcher.rst
+++ b/docs/api/xmlstream/matcher.rst
@@ -3,7 +3,7 @@ Stanza Matchers
The Basic Matcher
-----------------
-.. module:: sleekxmpp.xmlstream.matcher.base
+.. module:: slixmpp.xmlstream.matcher.base
.. autoclass:: MatcherBase
:members:
@@ -11,7 +11,7 @@ The Basic Matcher
ID Matching
-----------
-.. module:: sleekxmpp.xmlstream.matcher.id
+.. module:: slixmpp.xmlstream.matcher.id
.. autoclass:: MatcherId
:members:
@@ -19,7 +19,7 @@ ID Matching
Stanza Path Matching
--------------------
-.. module:: sleekxmpp.xmlstream.matcher.stanzapath
+.. module:: slixmpp.xmlstream.matcher.stanzapath
.. autoclass:: StanzaPath
:members:
@@ -27,7 +27,7 @@ Stanza Path Matching
XPath
-----
-.. module:: sleekxmpp.xmlstream.matcher.xpath
+.. module:: slixmpp.xmlstream.matcher.xpath
.. autoclass:: MatchXPath
:members:
@@ -35,7 +35,7 @@ XPath
XMLMask
-------
-.. module:: sleekxmpp.xmlstream.matcher.xmlmask
+.. module:: slixmpp.xmlstream.matcher.xmlmask
.. autoclass:: MatchXMLMask
:members:
diff --git a/docs/api/xmlstream/scheduler.rst b/docs/api/xmlstream/scheduler.rst
deleted file mode 100644
index ff91701e..00000000
--- a/docs/api/xmlstream/scheduler.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-=========
-Scheduler
-=========
-
-.. module:: sleekxmpp.xmlstream.scheduler
-
-.. autoclass:: Task
- :members:
-
-.. autoclass:: Scheduler
- :members:
diff --git a/docs/api/xmlstream/stanzabase.rst b/docs/api/xmlstream/stanzabase.rst
index f575299e..ad43a44a 100644
--- a/docs/api/xmlstream/stanzabase.rst
+++ b/docs/api/xmlstream/stanzabase.rst
@@ -4,9 +4,9 @@
Stanza Objects
==============
-.. module:: sleekxmpp.xmlstream.stanzabase
+.. module:: slixmpp.xmlstream.stanzabase
-The :mod:`~sleekmxpp.xmlstream.stanzabase` module provides a wrapper for the
+The :mod:`~slixmpp.xmlstream.stanzabase` module provides a wrapper for the
standard :mod:`~xml.etree.ElementTree` module that makes working with XML
less painful. Instead of having to manually move up and down an element
tree and insert subelements and attributes, you can interact with an object
@@ -52,17 +52,17 @@ elements of the original XML chunk.
.. seealso::
:ref:`create-stanza-interfaces`.
-Because the :mod:`~sleekxmpp.xmlstream.stanzabase` module was developed
+Because the :mod:`~slixmpp.xmlstream.stanzabase` module was developed
as part of an `XMPP <http://xmpp.org>`_ library, these chunks of XML are
-referred to as :term:`stanzas <stanza>`, and in SleekXMPP we refer to a
+referred to as :term:`stanzas <stanza>`, and in Slixmpp we refer to a
subclass of :class:`ElementBase` which defines the interfaces needed for
interacting with a given :term:`stanza` a :term:`stanza object`.
To make dealing with more complicated and nested :term:`stanzas <stanza>`
or XML chunks easier, :term:`stanza objects <stanza object>` can be
composed in two ways: as iterable child objects or as plugins. Iterable
-child stanzas, or :term:`substanzas`, are accessible through a special
-``'substanzas'`` interface. This option is useful for stanzas which
+child stanzas, or :term:`substanzas <substanza>`, are accessible through a
+special ``'substanzas'`` interface. This option is useful for stanzas which
may contain more than one of the same kind of element. When there is
only one child element, the plugin method is more useful. For plugins,
a parent stanza object delegates one of its XML child elements to the
@@ -72,7 +72,7 @@ plugin stanza object. Here is an example:
<iq type="result">
<query xmlns="http://jabber.org/protocol/disco#info">
- <identity category="client" type="bot" name="SleekXMPP Bot" />
+ <identity category="client" type="bot" name="Slixmpp Bot" />
</query>
</iq>
@@ -84,13 +84,13 @@ we can access the plugin as so::
>>> iq['disco_info']
'<query xmlns="http://jabber.org/protocol/disco#info">
- <identity category="client" type="bot" name="SleekXMPP Bot" />
+ <identity category="client" type="bot" name="Slixmpp Bot" />
</query>'
We can then drill down through the plugin object's interfaces as desired::
>>> iq['disco_info']['identities']
- [('client', 'bot', 'SleekXMPP Bot')]
+ [('client', 'bot', 'Slixmpp Bot')]
Plugins may also add new interfaces to the parent stanza object as if they
had been defined by the parent directly, and can also override the behaviour
@@ -101,7 +101,7 @@ of an interface defined by the parent.
- :ref:`create-stanza-plugins`
- :ref:`create-extension-plugins`
- :ref:`override-parent-interfaces`
-
+
Registering Stanza Plugins
--------------------------
diff --git a/docs/api/xmlstream/tostring.rst b/docs/api/xmlstream/tostring.rst
index 82a8c2a5..68abbdb6 100644
--- a/docs/api/xmlstream/tostring.rst
+++ b/docs/api/xmlstream/tostring.rst
@@ -1,18 +1,18 @@
-.. module:: sleekxmpp.xmlstream.tostring
+.. module:: slixmpp.xmlstream.tostring
.. _tostring:
XML Serialization
=================
-Since the XML layer of SleekXMPP is based on :mod:`~xml.etree.ElementTree`,
+Since the XML layer of Slixmpp is based on :mod:`~xml.etree.ElementTree`,
why not just use the built-in :func:`~xml.etree.ElementTree.tostring`
method? The answer is that using that method produces ugly results when
using namespaces. The :func:`tostring()` method used here intelligently
hides namespaces when able and does not introduce excessive namespace
prefixes::
- >>> from sleekxmpp.xmlstream.tostring import tostring
+ >>> from slixmpp.xmlstream.tostring import tostring
>>> from xml.etree import cElementTree as ET
>>> xml = ET.fromstring('<foo xmlns="bar"><baz /></foo>')
>>> ET.tostring(xml)
@@ -25,10 +25,10 @@ produce unexpected results depending on how the :func:`tostring()` method
is invoked. For example, when sending XML on the wire, the main XMPP
stanzas with their namespace of ``jabber:client`` will not include the
namespace because that is already declared by the stream header. But, if
-you create a :class:`~sleekxmpp.stanza.message.Message` instance and dump
+you create a :class:`~slixmpp.stanza.message.Message` instance and dump
it to the terminal, the ``jabber:client`` namespace will appear.
-.. autofunction:: tostring
+.. autofunction:: slixmpp.xmlstream.tostring
Escaping Special Characters
---------------------------
@@ -43,4 +43,5 @@ In the future, the use of CDATA sections may be allowed to reduce the
size of escaped text or for when other XMPP processing agents do not
undertand these entities.
-.. autofunction:: xml_escape
+..
+ autofunction:: xml_escape
diff --git a/docs/api/xmlstream/xmlstream.rst b/docs/api/xmlstream/xmlstream.rst
index 90a7a6af..539e03ca 100644
--- a/docs/api/xmlstream/xmlstream.rst
+++ b/docs/api/xmlstream/xmlstream.rst
@@ -2,9 +2,7 @@
XML Stream
==========
-.. module:: sleekxmpp.xmlstream.xmlstream
-
-.. autoexception:: RestartStream
+.. module:: slixmpp.xmlstream.xmlstream
.. autoclass:: XMLStream
:members:
diff --git a/docs/architecture.rst b/docs/architecture.rst
index a2e0a27d..75b70c8a 100644
--- a/docs/architecture.rst
+++ b/docs/architecture.rst
@@ -1,9 +1,9 @@
.. index:: XMLStream, BaseXMPP, ClientXMPP, ComponentXMPP
-SleekXMPP Architecture
+Slixmpp Architecture
======================
-The core of SleekXMPP is contained in four classes: ``XMLStream``,
+The core of Slixmpp is contained in four classes: ``XMLStream``,
``BaseXMPP``, ``ClientXMPP``, and ``ComponentXMPP``. Along side this
stack is a library for working with XML objects that eliminates most
of the tedium of creating/manipulating XML.
@@ -17,28 +17,27 @@ of the tedium of creating/manipulating XML.
The Foundation: XMLStream
-------------------------
-:class:`~sleekxmpp.xmlstream.xmlstream.XMLStream` is a mostly XMPP-agnostic
+:class:`~slixmpp.xmlstream.xmlstream.XMLStream` is a mostly XMPP-agnostic
class whose purpose is to read and write from a bi-directional XML stream.
It also allows for callback functions to execute when XML matching given
patterns is received; these callbacks are also referred to as :term:`stream
handlers <stream handler>`. The class also provides a basic eventing system
which can be triggered either manually or on a timed schedule.
-The Main Threads
-~~~~~~~~~~~~~~~~
-:class:`~sleekxmpp.xmlstream.xmlstream.XMLStream` instances run using at
-least three background threads: the send thread, the read thread, and the
-scheduler thread. The send thread is in charge of monitoring the send queue
-and writing text to the outgoing XML stream. The read thread pulls text off
-of the incoming XML stream and stores the results in an event queue. The
-scheduler thread is used to emit events after a given period of time.
+The event loop
+~~~~~~~~~~~~~~
+:class:`~slixmpp.xmlstream.xmlstream.XMLStream` instances inherit the
+:class:`asyncio.BaseProtocol` class, and therefore do not have to handle
+reads and writes directly, but receive data through
+:meth:`~slixmpp.xmlstream.xmlstream.XMLStream.data_received` and write
+data in the socket transport.
-Additionally, the main event processing loop may be executed in its
-own thread if SleekXMPP is being used in the background for another
-application.
+Upon receiving data, :term:`stream handlers <stream handler>` are run
+immediately, except if they are coroutines, in which case they are
+scheduled using :meth:`asyncio.async`.
-Short-lived threads may also be spawned as requested for threaded
-:term:`event handlers <event handler>`.
+:term:`Event handlers <event handler>` (which are called inside
+:term:`stream handlers <stream handler>`) work the same way.
How XML Text is Turned into Action
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -53,7 +52,7 @@ when this bit of XML is received (with an assumed namespace of
</message>
-1. **Convert XML strings into objects.**
+#. **Convert XML strings into objects.**
Incoming text is parsed and converted into XML objects (using
ElementTree) which are then wrapped into what are referred to as
@@ -61,95 +60,69 @@ when this bit of XML is received (with an assumed namespace of
new object is determined using a map of namespaced element names to
classes.
- Our incoming XML is thus turned into a :class:`~sleekxmpp.stanza.Message`
+ Our incoming XML is thus turned into a :class:`~slixmpp.stanza.Message`
:term:`stanza object` because the namespaced element name
``{jabber:client}message`` is associated with the class
- :class:`~sleekxmpp.stanza.Message`.
+ :class:`~slixmpp.stanza.Message`.
-2. **Match stanza objects to callbacks.**
+#. **Match stanza objects to callbacks.**
These objects are then compared against the stored patterns associated
- with the registered callback handlers. For each match, a copy of the
- :term:`stanza object` is paired with a reference to the handler and
- placed into the event queue.
+ with the registered callback handlers.
- Our :class:`~sleekxmpp.stanza.Message` object is thus paired with the message stanza handler
- :meth:`BaseXMPP._handle_message` to create the tuple::
+ Each handler matching our :term:`stanza object` is then added to a list.
- ('stanza', stanza_obj, handler)
+#. **Processing callbacks**
-3. **Process the event queue.**
+ Every handler in the list is then called with the :term:`stanza object`
+ as a parameter; if the handler is a
+ :class:`~slixmpp.xmlstream.handler.CoroutineCallback`
+ then it will be scheduled in the event loop using :meth:`asyncio.async`
+ instead of run.
- The event queue is the heart of SleekXMPP. Nearly every action that
- takes place is first inserted into this queue, whether that be received
- stanzas, custom events, or scheduled events.
-
- When the stanza is pulled out of the event queue with an associated
- callback, the callback function is executed with the stanza as its only
- parameter.
-
- .. warning::
- The callback, aka :term:`stream handler`, is executed in the main event
- processing thread. If the handler blocks, event processing will also
- block.
-
-4. **Raise Custom Events**
+#. **Raise Custom Events**
Since a :term:`stream handler` shouldn't block, if extensive processing
for a stanza is required (such as needing to send and receive an
- :class:`~sleekxmpp.stanza.Iq` stanza), then custom events must be used.
+ :class:`~slixmpp.stanza.Iq` stanza), then custom events must be used.
These events are not explicitly tied to the incoming XML stream and may
- be raised at any time. Importantly, these events may be handled in their
- own thread.
+ be raised at any time.
- When the event is raised, a copy of the stanza is created for each
- handler registered for the event. In contrast to :term:`stream handlers
- <stream handler>`, these functions are referred to as :term:`event
- handlers <event handler>`. Each stanza/handler pair is then put into the
- event queue.
-
- .. note::
- It is possible to skip the event queue and process an event immediately
- by using ``direct=True`` when raising the event.
+ In contrast to :term:`stream handlers <stream handler>`, these functions
+ are referred to as :term:`event handlers <event handler>`.
The code for :meth:`BaseXMPP._handle_message` follows this pattern, and
- raises a ``'message'`` event::
-
- self.event('message', msg)
+ raises a ``'message'`` event
- The event call then places the message object back into the event queue
- paired with an :term:`event handler`::
+ .. code-block:: python
- ('event', 'message', msg_copy1, custom_event_handler_1)
- ('event', 'message', msg_copy2, custom_evetn_handler_2)
+ self.event('message', msg)
-5. **Process Custom Events**
+#. **Process Custom Events**
- The stanza and :term:`event handler` are then pulled from the event
- queue, and the handler is executed, passing the stanza as its only
- argument. If the handler was registered as threaded, then a new thread
- will be spawned for it.
+ The :term:`event handlers <event handler>` are then executed, passing
+ the stanza as the only argument.
.. note::
- Events may be raised without needing :term:`stanza objects <stanza object>`.
- For example, you could use ``self.event('custom', {'a': 'b'})``.
- You don't even need any arguments: ``self.event('no_parameters')``.
+ Events may be raised without needing :term:`stanza objects <stanza object>`.
+ For example, you could use ``self.event('custom', {'a': 'b'})``.
+ You don't even need any arguments: ``self.event('no_parameters')``.
However, every event handler MUST accept at least one argument.
Finally, after a long trek, our message is handed off to the user's
custom handler in order to do awesome stuff::
- msg.reply()
- msg['body'] = "Hey! This is awesome!"
- msg.send()
+ reply = msg.reply()
+ reply['body'] = "Hey! This is awesome!"
+ reply.send()
.. index:: BaseXMPP, XMLStream
Raising XMPP Awareness: BaseXMPP
--------------------------------
-While :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream` attempts to shy away
-from anything too XMPP specific, :class:`~sleekxmpp.basexmpp.BaseXMPP`'s
+While :class:`~slixmpp.xmlstream.xmlstream.XMLStream` attempts to shy away
+from anything too XMPP specific, :class:`~slixmpp.basexmpp.BaseXMPP`'s
sole purpose is to provide foundational support for sending and receiving
XMPP stanzas. This support includes registering the basic message,
presence, and iq stanzas, methods for creating and sending stanzas, and
@@ -157,14 +130,14 @@ default handlers for incoming messages and keeping track of presence
notifications.
The plugin system for adding new XEP support is also maintained by
-:class:`~sleekxmpp.basexmpp.BaseXMPP`.
+:class:`~slixmpp.basexmpp.BaseXMPP`.
.. index:: ClientXMPP, BaseXMPP
ClientXMPP
----------
-:class:`~sleekxmpp.clientxmpp.ClientXMPP` extends
-:class:`~sleekxmpp.clientxmpp.BaseXMPP` with additional logic for connecting
+:class:`~slixmpp.clientxmpp.ClientXMPP` extends
+:class:`~slixmpp.clientxmpp.BaseXMPP` with additional logic for connecting
to an XMPP server by performing DNS lookups. It also adds support for stream
features such as STARTTLS and SASL.
@@ -172,6 +145,6 @@ features such as STARTTLS and SASL.
ComponentXMPP
-------------
-:class:`~sleekxmpp.componentxmpp.ComponentXMPP` is only a thin layer on top of
-:class:`~sleekxmpp.basexmpp.BaseXMPP` that implements the component handshake
+:class:`~slixmpp.componentxmpp.ComponentXMPP` is only a thin layer on top of
+:class:`~slixmpp.basexmpp.BaseXMPP` that implements the component handshake
protocol.
diff --git a/docs/conf.py b/docs/conf.py
index 72e39d0f..898d00cd 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
-# SleekXMPP documentation build configuration file, created by
+# Slixmpp documentation build configuration file, created by
# sphinx-quickstart on Tue Aug 9 22:27:06 2011.
#
# This file is execfile()d with the current directory set to its containing dir.
@@ -40,7 +40,7 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
-project = u'SleekXMPP'
+project = u'Slixmpp'
copyright = u'2011, Nathan Fritz, Lance Stout'
# The version info for the project you're documenting, acts as replacement for
@@ -105,7 +105,7 @@ html_theme = 'haiku'
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
-html_title = 'SleekXMPP'
+html_title = 'slixmpp'
# A shorter title for the navigation bar. Default is the same as html_title.
html_short_title = '%s Documentation' % release
@@ -168,7 +168,7 @@ html_additional_pages = {
#html_file_suffix = None
# Output file base name for HTML help builder.
-htmlhelp_basename = 'SleekXMPPdoc'
+htmlhelp_basename = 'Slixmppdoc'
# -- Options for LaTeX output --------------------------------------------------
@@ -182,7 +182,7 @@ htmlhelp_basename = 'SleekXMPPdoc'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
- ('index', 'SleekXMPP.tex', u'SleekXMPP Documentation',
+ ('index', 'Slixmpp.tex', u'Slixmpp Documentation',
u'Nathan Fritz, Lance Stout', 'manual'),
]
@@ -215,8 +215,8 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
- ('index', 'sleekxmpp', u'SleekXMPP Documentation',
+ ('index', 'slixmpp', u'Slixmpp Documentation',
[u'Nathan Fritz, Lance Stout'], 1)
]
-intersphinx_mapping = {'python': ('http://docs.python.org/3.2', 'python-objects.inv')}
+intersphinx_mapping = {'python': ('http://docs.python.org/3.4', 'python-objects.inv')}
diff --git a/docs/create_plugin.rst b/docs/create_plugin.rst
index 2b0514b8..9bfb053f 100644
--- a/docs/create_plugin.rst
+++ b/docs/create_plugin.rst
@@ -1,10 +1,10 @@
.. _create-plugin:
-Creating a SleekXMPP Plugin
+Creating a Slixmpp Plugin
===========================
-One of the goals of SleekXMPP is to provide support for every draft or final
-XMPP extension (`XEP <http://xmpp.org/extensions/>`_). To do this, SleekXMPP has a
+One of the goals of Slixmpp is to provide support for every draft or final
+XMPP extension (`XEP <http://xmpp.org/extensions/>`_). To do this, Slixmpp has a
plugin mechanism for adding the functionalities required by each XEP. But even
though plugins were made to quickly implement and prototype the official XMPP
extensions, there is no reason you can't create your own plugin to implement
@@ -14,11 +14,11 @@ This guide will help walk you through the steps to
implement a rudimentary version of `XEP-0077 In-band
Registration <http://xmpp.org/extensions/xep-0077.html>`_. In-band registration
was implemented in example 14-6 (page 223) of `XMPP: The Definitive
-Guide <http://oreilly.com/catalog/9780596521271>`_ because there was no SleekXMPP
+Guide <http://oreilly.com/catalog/9780596521271>`_ because there was no Slixmpp
plugin for XEP-0077 at the time of writing. We will partially fix that issue
here by turning the example implementation from *XMPP: The Definitive Guide*
into a plugin. Again, note that this will not a complete implementation, and a
-different, more robust, official plugin for XEP-0077 may be added to SleekXMPP
+different, more robust, official plugin for XEP-0077 may be added to Slixmpp
in the future.
.. note::
@@ -29,10 +29,10 @@ in the future.
First Steps
-----------
-Every plugin inherits from the class :mod:`base_plugin <sleekxmpp.plugins.base.base_plugin>`,
+Every plugin inherits from the class :mod:`BasePlugin <slixmpp.plugins.base.BasePlugin`,
and must include a ``plugin_init`` method. While the
-plugins distributed with SleekXMPP must be placed in the plugins directory
-``sleekxmpp/plugins`` to be loaded, custom plugins may be loaded from any
+plugins distributed with Slixmpp must be placed in the plugins directory
+``slixmpp/plugins`` to be loaded, custom plugins may be loaded from any
module. To do so, use the following form when registering the plugin:
.. code-block:: python
@@ -40,9 +40,9 @@ module. To do so, use the following form when registering the plugin:
self.register_plugin('myplugin', module=mod_containing_my_plugin)
The plugin name must be the same as the plugin's class name.
-
+
Now, we can open our favorite text editors and create ``xep_0077.py`` in
-``SleekXMPP/sleekxmpp/plugins``. We want to do some basic house-keeping and
+``Slixmpp/slixmpp/plugins``. We want to do some basic house-keeping and
declare the name and description of the XEP we are implementing. If you
are creating your own custom plugin, you don't need to include the ``xep``
attribute.
@@ -50,15 +50,15 @@ attribute.
.. code-block:: python
"""
- Creating a SleekXMPP Plugin
+ Creating a Slixmpp Plugin
This is a minimal implementation of XEP-0077 to serve
- as a tutorial for creating SleekXMPP plugins.
+ as a tutorial for creating Slixmpp plugins.
"""
- from sleekxmpp.plugins.base import base_plugin
+ from slixmpp.plugins.base import BasePlugin
- class xep_0077(base_plugin):
+ class xep_0077(BasePlugin):
"""
XEP-0077 In-Band Registration
"""
@@ -68,7 +68,7 @@ attribute.
self.xep = "0077"
Now that we have a basic plugin, we need to edit
-``sleekxmpp/plugins/__init__.py`` to include our new plugin by adding
+``slixmpp/plugins/__init__.py`` to include our new plugin by adding
``'xep_0077'`` to the ``__all__`` declaration.
Interacting with Other Plugins
@@ -81,20 +81,20 @@ call in a method named ``post_init`` which will be called once the plugin has
been loaded; by doing so we advertise that we can do registrations only after we
finish activating the plugin.
-The ``post_init`` method needs to call ``base_plugin.post_init(self)``
+The ``post_init`` method needs to call ``BasePlugin.post_init(self)``
which will mark that ``post_init`` has been called for the plugin. Once the
-SleekXMPP object begins processing, ``post_init`` will be called on any plugins
+Slixmpp object begins processing, ``post_init`` will be called on any plugins
that have not already run ``post_init``. This allows you to register plugins and
their dependencies without needing to worry about the order in which you do so.
**Note:** by adding this call we have introduced a dependency on the XEP-0030
-plugin. Be sure to register ``'xep_0030'`` as well as ``'xep_0077'``. SleekXMPP
+plugin. Be sure to register ``'xep_0030'`` as well as ``'xep_0077'``. Slixmpp
does not automatically load plugin dependencies for you.
.. code-block:: python
def post_init(self):
- base_plugin.post_init(self)
+ BasePlugin.post_init(self)
self.xmpp['xep_0030'].add_feature("jabber:iq:register")
Creating Custom Stanza Objects
@@ -141,7 +141,7 @@ behaviour:
**Note:** The accessor methods currently use title case, and not camel case.
Thus if you need to access an item named ``"methodName"`` you will need to
use ``getMethodname``. This naming convention might change to full camel
- case in a future version of SleekXMPP.
+ case in a future version of Slixmpp.
* ``sub_interfaces``
A subset of ``interfaces``, but these keys map to the text of any
@@ -156,8 +156,8 @@ behaviour:
.. code-block:: python
- from sleekxmpp.xmlstream import ElementBase, ET, JID, register_stanza_plugin
- from sleekxmpp import Iq
+ from slixmpp.xmlstream import ElementBase, ET, JID, register_stanza_plugin
+ from slixmpp import Iq
class Registration(ElementBase):
namespace = 'jabber:iq:register'
@@ -209,7 +209,7 @@ registration to our ``plugin_init`` method.
Also, we need to associate our ``Registration`` class with IQ stanzas;
that requires the use of the ``register_stanza_plugin`` function (in
-``sleekxmpp.xmlstream.stanzabase``) which takes the class of a parent stanza
+``slixmpp.xmlstream.stanzabase``) which takes the class of a parent stanza
type followed by the substanza type. In our case, the parent stanza is an IQ
stanza, and the substanza is our registration query.
@@ -347,7 +347,7 @@ method ``setForm`` which will take the names of the fields we wish to include.
# Add a blank field
reg.addField(field)
- iq.reply().setPayload(reg.xml)
+ iq.reply().set_payload(reg.xml)
iq.send()
Note how we are able to access our ``Registration`` stanza object with
@@ -421,7 +421,7 @@ to the IQ reply.
...
def _sendError(self, iq, code, error_type, name, text=''):
- iq.reply().setPayload(iq['register'].xml)
+ iq.reply().set_payload(iq['register'].xml)
iq.error()
iq['error']['code'] = code
iq['error']['type'] = error_type
@@ -464,7 +464,7 @@ component examples below for how to respond to this event.
if self.backend.register(iq['from'].bare, iq['register']):
# Successful registration
self.xmpp.event('registered_user', iq)
- iq.reply().setPayload(iq['register'].xml)
+ iq.reply().set_payload(iq['register'].xml)
iq.send()
else:
# Conflicting registration
@@ -484,15 +484,15 @@ and that we specified the form fields we wish to use with
.. code-block:: python
- import sleekxmpp.componentxmpp
+ import slixmpp.componentxmpp
- class Example(sleekxmpp.componentxmpp.ComponentXMPP):
+ class Example(slixmpp.componentxmpp.ComponentXMPP):
def __init__(self, jid, password):
- sleekxmpp.componentxmpp.ComponentXMPP.__init__(self, jid, password, 'localhost', 8888)
+ slixmpp.componentxmpp.ComponentXMPP.__init__(self, jid, password, 'localhost', 8888)
- self.registerPlugin('xep_0030')
- self.registerPlugin('xep_0077')
+ self.register_plugin('xep_0030')
+ self.register_plugin('xep_0077')
self.plugin['xep_0077'].setForm('username', 'password')
self.add_event_handler("registered_user", self.reg)
@@ -500,11 +500,11 @@ and that we specified the form fields we wish to use with
def reg(self, iq):
msg = "Welcome! %s" % iq['register']['username']
- self.sendMessage(iq['from'], msg, mfrom=self.fulljid)
+ self.send_message(iq['from'], msg, mfrom=self.fulljid)
def unreg(self, iq):
msg = "Bye! %s" % iq['register']['username']
- self.sendMessage(iq['from'], msg, mfrom=self.fulljid)
+ self.send_message(iq['from'], msg, mfrom=self.fulljid)
**Congratulations!** We now have a basic, functioning implementation of
XEP-0077.
@@ -517,17 +517,17 @@ with some additional registration fields implemented.
.. code-block:: python
"""
- Creating a SleekXMPP Plugin
+ Creating a Slixmpp Plugin
This is a minimal implementation of XEP-0077 to serve
- as a tutorial for creating SleekXMPP plugins.
+ as a tutorial for creating Slixmpp plugins.
"""
- from sleekxmpp.plugins.base import base_plugin
- from sleekxmpp.xmlstream.handler.callback import Callback
- from sleekxmpp.xmlstream.matcher.xpath import MatchXPath
- from sleekxmpp.xmlstream import ElementBase, ET, JID, register_stanza_plugin
- from sleekxmpp import Iq
+ from slixmpp.plugins.base import BasePlugin
+ from slixmpp.xmlstream.handler.callback import Callback
+ from slixmpp.xmlstream.matcher.xpath import MatchXPath
+ from slixmpp.xmlstream import ElementBase, ET, JID, register_stanza_plugin
+ from slixmpp import Iq
import copy
@@ -535,9 +535,9 @@ with some additional registration fields implemented.
namespace = 'jabber:iq:register'
name = 'query'
plugin_attrib = 'register'
- interfaces = set(('username', 'password', 'email', 'nick', 'name',
- 'first', 'last', 'address', 'city', 'state', 'zip',
- 'phone', 'url', 'date', 'misc', 'text', 'key',
+ interfaces = set(('username', 'password', 'email', 'nick', 'name',
+ 'first', 'last', 'address', 'city', 'state', 'zip',
+ 'phone', 'url', 'date', 'misc', 'text', 'key',
'registered', 'remove', 'instructions'))
sub_interfaces = interfaces
@@ -589,7 +589,7 @@ with some additional registration fields implemented.
def unregister(self, jid):
del self.users[jid]
- class xep_0077(base_plugin):
+ class xep_0077(BasePlugin):
"""
XEP-0077 In-Band Registration
"""
@@ -608,7 +608,7 @@ with some additional registration fields implemented.
register_stanza_plugin(Iq, Registration)
def post_init(self):
- base_plugin.post_init(self)
+ BasePlugin.post_init(self)
self.xmpp['xep_0030'].add_feature("jabber:iq:register")
def __handleRegistration(self, iq):
@@ -634,8 +634,9 @@ with some additional registration fields implemented.
if self.backend.register(iq['from'].bare, iq['register']):
# Successful registration
self.xmpp.event('registered_user', iq)
- iq.reply().setPayload(iq['register'].xml)
- iq.send()
+ reply = iq.reply()
+ reply.set_payload(iq['register'].xml)
+ reply.send()
else:
# Conflicting registration
self._sendError(iq, '409', 'cancel', 'conflict',
@@ -666,14 +667,16 @@ with some additional registration fields implemented.
# Add a blank field
reg.addField(field)
- iq.reply().setPayload(reg.xml)
- iq.send()
+ reply = iq.reply()
+ reply.set_payload(reg.xml)
+ reply.send()
def _sendError(self, iq, code, error_type, name, text=''):
- iq.reply().setPayload(iq['register'].xml)
- iq.error()
- iq['error']['code'] = code
- iq['error']['type'] = error_type
- iq['error']['condition'] = name
- iq['error']['text'] = text
- iq.send()
+ reply = iq.reply()
+ reply.set_payload(iq['register'].xml)
+ reply.error()
+ reply['error']['code'] = code
+ reply['error']['type'] = error_type
+ reply['error']['condition'] = name
+ reply['error']['text'] = text
+ reply.send()
diff --git a/docs/differences.rst b/docs/differences.rst
new file mode 100644
index 00000000..f6e005b5
--- /dev/null
+++ b/docs/differences.rst
@@ -0,0 +1,47 @@
+.. _differences:
+
+Differences from SleekXMPP
+==========================
+
+**Python 3.4+ only**
+ slixmpp will only work on python 3.4 and above.
+
+**Stanza copies**
+ The same stanza object is given through all the handlers; a handler that
+ edits the stanza object should make its own copy.
+
+**Replies**
+ Because stanzas are not copied anymore,
+ :meth:`Stanza.reply() <.StanzaBase.reply>` calls
+ (for :class:`IQs <.Iq>`, :class:`Messages <.Message>`, etc)
+ now return a new object instead of editing the stanza object
+ in-place.
+
+**Block and threaded arguments**
+ All the functions that had a ``threaded=`` or ``block=`` argument
+ do not have it anymore. Also, :meth:`.Iq.send` **does not block
+ anymore**.
+
+**Coroutine facilities**
+ **See** :ref:`using_asyncio`
+
+ If an event handler is a coroutine, it will be called asynchronously
+ in the event loop instead of inside the event caller.
+
+ A CoroutineCallback class has been added to create coroutine stream
+ handlers, which will be also handled in the event loop.
+
+ The :class:`~.slixmpp.stanza.Iq` object’s :meth:`~.slixmpp.stanza.Iq.send`
+ method now **always** return a :class:`~.asyncio.Future` which result will be set
+ to the IQ reply when it is received, or to ``None`` if the IQ is not of
+ type ``get`` or ``set``.
+
+ Many plugins (WIP) calls which retrieve information also return the same
+ future.
+
+**Architectural differences**
+ slixmpp does not have an event queue anymore, and instead processes
+ handlers directly after receiving the XML stanza.
+
+.. note::
+ If you find something that doesn’t work but should, please report it.
diff --git a/docs/event_index.rst b/docs/event_index.rst
index ee8f5a95..07a4fbd0 100644
--- a/docs/event_index.rst
+++ b/docs/event_index.rst
@@ -6,33 +6,33 @@ Event Index
connected
- **Data:** ``{}``
- - **Source:** :py:class:`~sleekxmpp.xmlstream.XMLstream`
+ - **Source:** :py:class:`~slixmpp.xmlstream.XMLstream`
Signal that a connection has been made with the XMPP server, but a session
has not yet been established.
connection_failed
- **Data:** ``{}`` or ``Failure Stanza`` if available
- - **Source:** :py:class:`~sleekxmpp.xmlstream.XMLstream`
+ - **Source:** :py:class:`~slixmpp.xmlstream.XMLstream`
Signal that a connection can not be established after number of attempts.
changed_status
- - **Data:** :py:class:`~sleekxmpp.Presence`
- - **Source:** :py:class:`~sleekxmpp.roster.item.RosterItem`
+ - **Data:** :py:class:`~slixmpp.Presence`
+ - **Source:** :py:class:`~slixmpp.roster.item.RosterItem`
Triggered when a presence stanza is received from a JID with a show type
different than the last presence stanza from the same JID.
changed_subscription
- - **Data:** :py:class:`~sleekxmpp.Presence`
- - **Source:** :py:class:`~sleekxmpp.BaseXMPP`
+ - **Data:** :py:class:`~slixmpp.Presence`
+ - **Source:** :py:class:`~slixmpp.BaseXMPP`
Triggered whenever a presence stanza with a type of ``subscribe``,
``subscribed``, ``unsubscribe``, or ``unsubscribed`` is received.
Note that if the values ``xmpp.auto_authorize`` and ``xmpp.auto_subscribe``
- are set to ``True`` or ``False``, and not ``None``, then SleekXMPP will
+ are set to ``True`` or ``False``, and not ``None``, then Slixmpp will
either accept or reject all subscription requests before your event handlers
are called. Set these values to ``None`` if you wish to make more complex
subscription decisions.
@@ -58,20 +58,20 @@ Event Index
- **Source:**
disco_info
- - **Data:** :py:class:`~sleekxmpp.plugins.xep_0030.stanza.DiscoInfo`
- - **Source:** :py:class:`~sleekxmpp.plugins.xep_0030.disco.xep_0030`
-
+ - **Data:** :py:class:`~slixmpp.plugins.xep_0030.stanza.DiscoInfo`
+ - **Source:** :py:class:`~slixmpp.plugins.xep_0030.disco.xep_0030`
+
Triggered whenever a ``disco#info`` result stanza is received.
disco_items
- - **Data:** :py:class:`~sleekxmpp.plugins.xep_0030.stanza.DiscoItems`
- - **Source:** :py:class:`~sleekxmpp.plugins.xep_0030.disco.xep_0030`
-
+ - **Data:** :py:class:`~slixmpp.plugins.xep_0030.stanza.DiscoItems`
+ - **Source:** :py:class:`~slixmpp.plugins.xep_0030.disco.xep_0030`
+
Triggered whenever a ``disco#items`` result stanza is received.
disconnected
- **Data:** ``{}``
- - **Source:** :py:class:`~sleekxmpp.xmlstream.XMLstream`
+ - **Source:** :py:class:`~slixmpp.xmlstream.XMLstream`
Signal that the connection with the XMPP server has been lost.
@@ -81,33 +81,33 @@ Event Index
failed_auth
- **Data:** ``{}``
- - **Source:** :py:class:`~sleekxmpp.ClientXMPP`, :py:class:`~sleekxmpp.plugins.xep_0078.xep_0078`
+ - **Source:** :py:class:`~slixmpp.ClientXMPP`, :py:class:`~slixmpp.plugins.xep_0078.xep_0078`
Signal that the server has rejected the provided login credentials.
gmail_notify
- **Data:** ``{}``
- - **Source:** :py:class:`~sleekxmpp.plugins.gmail_notify.gmail_notify`
-
+ - **Source:** :py:class:`~slixmpp.plugins.gmail_notify.gmail_notify`
+
Signal that there are unread emails for the Gmail account associated with the current XMPP account.
gmail_messages
- - **Data:** :py:class:`~sleekxmpp.Iq`
- - **Source:** :py:class:`~sleekxmpp.plugins.gmail_notify.gmail_notify`
-
+ - **Data:** :py:class:`~slixmpp.Iq`
+ - **Source:** :py:class:`~slixmpp.plugins.gmail_notify.gmail_notify`
+
Signal that there are unread emails for the Gmail account associated with the current XMPP account.
got_online
- - **Data:** :py:class:`~sleekxmpp.Presence`
- - **Source:** :py:class:`~sleekxmpp.roster.item.RosterItem`
+ - **Data:** :py:class:`~slixmpp.Presence`
+ - **Source:** :py:class:`~slixmpp.roster.item.RosterItem`
If a presence stanza is received from a JID which was previously marked as
offline, and the presence has a show type of '``chat``', '``dnd``', '``away``',
or '``xa``', then this event is triggered as well.
got_offline
- - **Data:** :py:class:`~sleekxmpp.Presence`
- - **Source:** :py:class:`~sleekxmpp.roster.item.RosterItem`
+ - **Data:** :py:class:`~slixmpp.Presence`
+ - **Source:** :py:class:`~slixmpp.roster.item.RosterItem`
Signal that an unavailable presence stanza has been received from a JID.
@@ -116,25 +116,25 @@ Event Index
- **Source:**
groupchat_direct_invite
- - **Data:** :py:class:`~sleekxmpp.Message`
- - **Source:** :py:class:`~sleekxmpp.plugins.xep_0249.direct`
+ - **Data:** :py:class:`~slixmpp.Message`
+ - **Source:** :py:class:`~slixmpp.plugins.xep_0249.direct`
groupchat_message
- - **Data:** :py:class:`~sleekxmpp.Message`
- - **Source:** :py:class:`~sleekxmpp.plugins.xep_0045.xep_0045`
-
+ - **Data:** :py:class:`~slixmpp.Message`
+ - **Source:** :py:class:`~slixmpp.plugins.xep_0045.xep_0045`
+
Triggered whenever a message is received from a multi-user chat room.
groupchat_presence
- - **Data:** :py:class:`~sleekxmpp.Presence`
- - **Source:** :py:class:`~sleekxmpp.plugins.xep_0045.xep_0045`
-
+ - **Data:** :py:class:`~slixmpp.Presence`
+ - **Source:** :py:class:`~slixmpp.plugins.xep_0045.xep_0045`
+
Triggered whenever a presence stanza is received from a user in a multi-user chat room.
groupchat_subject
- - **Data:** :py:class:`~sleekxmpp.Message`
- - **Source:** :py:class:`~sleekxmpp.plugins.xep_0045.xep_0045`
-
+ - **Data:** :py:class:`~slixmpp.Message`
+ - **Source:** :py:class:`~slixmpp.plugins.xep_0045.xep_0045`
+
Triggered whenever the subject of a multi-user chat room is changed, or announced when joining a room.
killed
@@ -146,21 +146,28 @@ Event Index
- **Source:**
message
- - **Data:** :py:class:`~sleekxmpp.Message`
- - **Source:** :py:class:`BaseXMPP <sleekxmpp.BaseXMPP>`
-
+ - **Data:** :py:class:`~slixmpp.Message`
+ - **Source:** :py:class:`BaseXMPP <slixmpp.BaseXMPP>`
+
Makes the contents of message stanzas available whenever one is received. Be
sure to check the message type in order to handle error messages.
+ message_error
+ - **Data:** :py:class:`~slixmpp.Message`
+ - **Source:** :py:class:`BaseXMPP <slixmpp.BaseXMPP>`
+
+ Makes the contents of message stanzas available whenever one is received.
+ Only handler messages with an ``error`` type.
+
message_form
- - **Data:** :py:class:`~sleekxmpp.plugins.xep_0004.Form`
- - **Source:** :py:class:`~sleekxmpp.plugins.xep_0004.xep_0004`
+ - **Data:** :py:class:`~slixmpp.plugins.xep_0004.Form`
+ - **Source:** :py:class:`~slixmpp.plugins.xep_0004.xep_0004`
Currently the same as :term:`message_xform`.
message_xform
- - **Data:** :py:class:`~sleekxmpp.plugins.xep_0004.Form`
- - **Source:** :py:class:`~sleekxmpp.plugins.xep_0004.xep_0004`
+ - **Data:** :py:class:`~slixmpp.plugins.xep_0004.Form`
+ - **Source:** :py:class:`~slixmpp.plugins.xep_0004.xep_0004`
Triggered whenever a data form is received inside a message.
@@ -181,74 +188,74 @@ Event Index
- **Source:**
presence_available
- - **Data:** :py:class:`~sleekxmpp.Presence`
- - **Source:** :py:class:`~sleekxmpp.BaseXMPP`
-
+ - **Data:** :py:class:`~slixmpp.Presence`
+ - **Source:** :py:class:`~slixmpp.BaseXMPP`
+
A presence stanza with a type of '``available``' is received.
presence_error
- - **Data:** :py:class:`~sleekxmpp.Presence`
- - **Source:** :py:class:`~sleekxmpp.BaseXMPP`
-
+ - **Data:** :py:class:`~slixmpp.Presence`
+ - **Source:** :py:class:`~slixmpp.BaseXMPP`
+
A presence stanza with a type of '``error``' is received.
presence_form
- - **Data:** :py:class:`~sleekxmpp.plugins.xep_0004.Form`
- - **Source:** :py:class:`~sleekxmpp.plugins.xep_0004.xep_0004`
-
+ - **Data:** :py:class:`~slixmpp.plugins.xep_0004.Form`
+ - **Source:** :py:class:`~slixmpp.plugins.xep_0004.xep_0004`
+
This event is present in the XEP-0004 plugin code, but is currently not used.
presence_probe
- - **Data:** :py:class:`~sleekxmpp.Presence`
- - **Source:** :py:class:`~sleekxmpp.BaseXMPP`
-
+ - **Data:** :py:class:`~slixmpp.Presence`
+ - **Source:** :py:class:`~slixmpp.BaseXMPP`
+
A presence stanza with a type of '``probe``' is received.
presence_subscribe
- - **Data:** :py:class:`~sleekxmpp.Presence`
- - **Source:** :py:class:`~sleekxmpp.BaseXMPP`
-
+ - **Data:** :py:class:`~slixmpp.Presence`
+ - **Source:** :py:class:`~slixmpp.BaseXMPP`
+
A presence stanza with a type of '``subscribe``' is received.
presence_subscribed
- - **Data:** :py:class:`~sleekxmpp.Presence`
- - **Source:** :py:class:`~sleekxmpp.BaseXMPP`
-
+ - **Data:** :py:class:`~slixmpp.Presence`
+ - **Source:** :py:class:`~slixmpp.BaseXMPP`
+
A presence stanza with a type of '``subscribed``' is received.
presence_unavailable
- - **Data:** :py:class:`~sleekxmpp.Presence`
- - **Source:** :py:class:`~sleekxmpp.BaseXMPP`
-
+ - **Data:** :py:class:`~slixmpp.Presence`
+ - **Source:** :py:class:`~slixmpp.BaseXMPP`
+
A presence stanza with a type of '``unavailable``' is received.
presence_unsubscribe
- - **Data:** :py:class:`~sleekxmpp.Presence`
- - **Source:** :py:class:`~sleekxmpp.BaseXMPP`
-
+ - **Data:** :py:class:`~slixmpp.Presence`
+ - **Source:** :py:class:`~slixmpp.BaseXMPP`
+
A presence stanza with a type of '``unsubscribe``' is received.
presence_unsubscribed
- - **Data:** :py:class:`~sleekxmpp.Presence`
- - **Source:** :py:class:`~sleekxmpp.BaseXMPP`
-
+ - **Data:** :py:class:`~slixmpp.Presence`
+ - **Source:** :py:class:`~slixmpp.BaseXMPP`
+
A presence stanza with a type of '``unsubscribed``' is received.
roster_update
- - **Data:** :py:class:`~sleekxmpp.stanza.Roster`
- - **Source:** :py:class:`~sleekxmpp.ClientXMPP`
-
+ - **Data:** :py:class:`~slixmpp.stanza.Roster`
+ - **Source:** :py:class:`~slixmpp.ClientXMPP`
+
An IQ result containing roster entries is received.
sent_presence
- **Data:** ``{}``
- - **Source:** :py:class:`~sleekxmpp.roster.multi.Roster`
-
+ - **Source:** :py:class:`~slixmpp.roster.multi.Roster`
+
Signal that an initial presence stanza has been written to the XML stream.
session_end
- **Data:** ``{}``
- - **Source:** :py:class:`~sleekxmpp.xmlstream.XMLstream`
+ - **Source:** :py:class:`~slixmpp.xmlstream.XMLstream`
Signal that a connection to the XMPP server has been lost and the current
stream session has ended. Currently equivalent to :term:`disconnected`, but
@@ -260,16 +267,16 @@ Event Index
session_start
- **Data:** ``{}``
- - **Source:** :py:class:`ClientXMPP <sleekxmpp.ClientXMPP>`,
- :py:class:`ComponentXMPP <sleekxmpp.ComponentXMPP>`
- :py:class:`XEP-0078 <sleekxmpp.plugins.xep_0078>`
+ - **Source:** :py:class:`ClientXMPP <slixmpp.ClientXMPP>`,
+ :py:class:`ComponentXMPP <slixmpp.ComponentXMPP>`
+ :py:class:`XEP-0078 <slixmpp.plugins.xep_0078>`
Signal that a connection to the XMPP server has been made and a session has been established.
socket_error
- **Data:** ``Socket`` exception object
- - **Source:** :py:class:`~sleekxmpp.xmlstream.XMLstream`
+ - **Source:** :py:class:`~slixmpp.xmlstream.XMLstream`
stream_error
- - **Data:** :py:class:`~sleekxmpp.stanza.StreamError`
- - **Source:** :py:class:`~sleekxmpp.BaseXMPP`
+ - **Data:** :py:class:`~slixmpp.stanza.StreamError`
+ - **Source:** :py:class:`~slixmpp.BaseXMPP`
diff --git a/docs/getting_started/component.rst b/docs/getting_started/component.rst
index ce548ba4..34aeda26 100644
--- a/docs/getting_started/component.rst
+++ b/docs/getting_started/component.rst
@@ -5,24 +5,16 @@ Create and Run a Server Component
=================================
.. note::
-
- If you have any issues working through this quickstart guide
- or the other tutorials here, please either send a message to the
- `mailing list <http://groups.google.com/group/sleekxmpp-discussion>`_
- or join the chat room at `sleek@conference.jabber.org
- <xmpp:sleek@conference.jabber.org?join>`_.
-
-If you have not yet installed SleekXMPP, do so now by either checking out a version
-from `Github <http://github.com/fritzy/SleekXMPP>`_, or installing it using ``pip``
-or ``easy_install``.
-.. code-block:: sh
-
- pip install sleekxmpp # Or: easy_install sleekxmpp
+ If you have any issues working through this quickstart guide
+ join the chat room at `slixmpp@muc.poez.io
+ <xmpp:slixmpp@muc.poez.io?join>`_.
+If you have not yet installed Slixmpp, do so now by either checking out a version
+with `Git <http://git.poez.io/slixmpp>`_.
-Many XMPP applications eventually graduate to requiring to run as a server
-component in order to meet scalability requirements. To demonstrate how to
+Many XMPP applications eventually graduate to requiring to run as a server
+component in order to meet scalability requirements. To demonstrate how to
turn an XMPP client bot into a component, we'll turn the echobot example
(:ref:`echobot`) into a component version.
@@ -30,7 +22,7 @@ The first difference is that we will add an additional import statement:
.. code-block:: python
- from sleekxmpp.componentxmpp import ComponentXMPP
+ from slixmpp.componentxmpp import ComponentXMPP
Likewise, we will change the bot's class definition to match:
@@ -48,7 +40,7 @@ a MUC component, the following could be used:
.. code-block:: python
- muc = ComponentXMPP('muc.sleekxmpp.com', '******', 'sleekxmpp.com', 5555)
+ muc = ComponentXMPP('muc.slixmpp.com', '******', 'slixmpp.com', 5555)
.. note::
@@ -62,10 +54,10 @@ with presence.
The other, main difference with components is that the
``'from'`` value for every stanza must be explicitly set, since
components may send stanzas from multiple JIDs. To do so,
-the :meth:`~sleekxmpp.basexmpp.BaseXMPP.send_message()` and
-:meth:`~sleekxmpp.basexmpp.BaseXMPP.send_presence()` accept the parameters
+the :meth:`~slixmpp.basexmpp.BaseXMPP.send_message()` and
+:meth:`~slixmpp.basexmpp.BaseXMPP.send_presence()` accept the parameters
``mfrom`` and ``pfrom``, respectively. For any method that uses
-:class:`~sleekxmpp.stanza.iq.Iq` stanzas, ``ifrom`` may be used.
+:class:`~slixmpp.stanza.iq.Iq` stanzas, ``ifrom`` may be used.
Final Product
diff --git a/docs/getting_started/echobot.rst b/docs/getting_started/echobot.rst
index 7d29ec58..bb40a0b5 100644
--- a/docs/getting_started/echobot.rst
+++ b/docs/getting_started/echobot.rst
@@ -1,25 +1,17 @@
.. _echobot:
===============================
-SleekXMPP Quickstart - Echo Bot
+Slixmpp Quickstart - Echo Bot
===============================
.. note::
-
- If you have any issues working through this quickstart guide
- or the other tutorials here, please either send a message to the
- `mailing list <http://groups.google.com/group/sleekxmpp-discussion>`_
- or join the chat room at `sleek@conference.jabber.org
- <xmpp:sleek@conference.jabber.org?join>`_.
-
-If you have not yet installed SleekXMPP, do so now by either checking out a version
-from `Github <http://github.com/fritzy/SleekXMPP>`_, or installing it using ``pip``
-or ``easy_install``.
-
-.. code-block:: sh
- pip install sleekxmpp # Or: easy_install sleekxmpp
+ If you have any issues working through this quickstart guide
+ join the chat room at `slixmpp@muc.poez.io
+ <xmpp:slixmpp@muc.poez.io?join>`_.
+If you have not yet installed Slixmpp, do so now by either checking out a version
+with `Git <http://git.poez.io/slixmpp>`_.
As a basic starting project, we will create an echo bot which will reply to any
messages sent to it. We will also go through adding some basic command line configuration
@@ -44,11 +36,12 @@ To get started, here is a brief outline of the structure that the final project
# -*- coding: utf-8 -*-
import sys
+ import asyncio
import logging
import getpass
from optparse import OptionParser
- import sleekxmpp
+ import slixmpp
'''Here we will create out echo bot class'''
@@ -59,24 +52,6 @@ To get started, here is a brief outline of the structure that the final project
'''Finally, we connect the bot and start listening for messages'''
-Default Encoding
-----------------
-XMPP requires support for UTF-8 and so SleekXMPP must use UTF-8 as well. In
-Python3 this is simple because Unicode is the default string type. For Python2.6+
-the situation is not as easy because standard strings are simply byte arrays and
-use ASCII. We can get Python to use UTF-8 as the default encoding by including:
-
-.. code-block:: python
-
- if sys.version_info < (3, 0):
- from sleekxmpp.util.misc_ops import setdefaultencoding
- setdefaultencoding('utf8')
-
-.. warning::
-
- Until we are able to ensure that SleekXMPP will always use Unicode in Python2.6+, this
- may cause issues embedding SleekXMPP into other applications which assume ASCII encoding.
-
Creating the EchoBot Class
--------------------------
@@ -85,15 +60,15 @@ clients. Since our echo bot will only be responding to a few people, and won't n
to remember thousands of users, we will use a client connection. A client connection
is the same type that you use with your standard IM client such as Pidgin or Psi.
-SleekXMPP comes with a :class:`ClientXMPP <sleekxmpp.clientxmpp.ClientXMPP>` class
-which we can extend to add our message echoing feature. :class:`ClientXMPP <sleekxmpp.clientxmpp.ClientXMPP>`
+Slixmpp comes with a :class:`ClientXMPP <slixmpp.clientxmpp.ClientXMPP>` class
+which we can extend to add our message echoing feature. :class:`ClientXMPP <slixmpp.clientxmpp.ClientXMPP>`
requires the parameters ``jid`` and ``password``, so we will let our ``EchoBot`` class accept those
as well.
.. code-block:: python
- class EchoBot(sleekxmpp.ClientXMPP):
-
+ class EchoBot(slixmpp.ClientXMPP):
+
def __init__(self, jid, password):
super(EchoBot, self).__init__(jid, password)
@@ -102,7 +77,7 @@ Handling Session Start
The XMPP spec requires clients to broadcast its presence and retrieve its roster (buddy list) once
it connects and establishes a session with the XMPP server. Until these two tasks are completed,
some servers may not deliver or send messages or presence notifications to the client. So we now
-need to be sure that we retrieve our roster and send an initial presence once the session has
+need to be sure that we retrieve our roster and send an initial presence once the session has
started. To do that, we will register an event handler for the :term:`session_start` event.
.. code-block:: python
@@ -132,8 +107,8 @@ Our event handler, like every event handler, accepts a single parameter which ty
that was received that caused the event. In this case, ``event`` will just be an empty dictionary since
there is no associated data.
-Our first task of sending an initial presence is done using :meth:`send_presence <sleekxmpp.basexmpp.BaseXMPP.send_presence>`.
-Calling :meth:`send_presence <sleekxmpp.basexmpp.BaseXMPP.send_presence>` without any arguments will send the simplest
+Our first task of sending an initial presence is done using :meth:`send_presence <slixmpp.basexmpp.BaseXMPP.send_presence>`.
+Calling :meth:`send_presence <slixmpp.basexmpp.BaseXMPP.send_presence>` without any arguments will send the simplest
stanza allowed in XMPP:
.. code-block:: xml
@@ -141,17 +116,17 @@ stanza allowed in XMPP:
<presence />
-The second requirement is fulfilled using :meth:`get_roster <sleekxmpp.clientxmpp.ClientXMPP.get_roster>`, which
+The second requirement is fulfilled using :meth:`get_roster <slixmpp.clientxmpp.ClientXMPP.get_roster>`, which
will send an IQ stanza requesting the roster to the server and then wait for the response. You may be wondering
-what :meth:`get_roster <sleekxmpp.clientxmpp.ClientXMPP.get_roster>` returns since we are not saving any return
+what :meth:`get_roster <slixmpp.clientxmpp.ClientXMPP.get_roster>` returns since we are not saving any return
value. The roster data is saved by an internal handler to ``self.roster``, and in the case of a :class:`ClientXMPP
-<sleekxmpp.clientxmpp.ClientXMPP>` instance to ``self.client_roster``. (The difference between ``self.roster`` and
+<slixmpp.clientxmpp.ClientXMPP>` instance to ``self.client_roster``. (The difference between ``self.roster`` and
``self.client_roster`` is that ``self.roster`` supports storing roster information for multiple JIDs, which is useful
for components, whereas ``self.client_roster`` stores roster data for just the client's JID.)
It is possible for a timeout to occur while waiting for the server to respond, which can happen if the
network is excessively slow or the server is no longer responding. In that case, an :class:`IQTimeout
-<sleekxmpp.exceptions.IQTimeout>` is raised. Similarly, an :class:`IQError <sleekxmpp.exceptions.IQError>` exception can
+<slixmpp.exceptions.IQTimeout>` is raised. Similarly, an :class:`IQError <slixmpp.exceptions.IQError>` exception can
be raised if the request contained bad data or requested the roster for the wrong user. In either case, you can wrap the
``get_roster()`` call in a ``try``/``except`` block to retry the roster retrieval process.
@@ -198,10 +173,10 @@ or ``chat``. (Other potential types are ``error``, ``headline``, and ``groupchat
Let's take a closer look at the ``.reply()`` method used above. For message stanzas,
``.reply()`` accepts the parameter ``body`` (also as the first positional argument),
-which is then used as the value of the ``<body />`` element of the message.
+which is then used as the value of the ``<body />`` element of the message.
Setting the appropriate ``to`` JID is also handled by ``.reply()``.
-Another way to have sent the reply message would be to use :meth:`send_message <sleekxmpp.basexmpp.BaseXMPP.send_message>`,
+Another way to have sent the reply message would be to use :meth:`send_message <slixmpp.basexmpp.BaseXMPP.send_message>`,
which is a convenience method for generating and sending a message based on the values passed to it. If we were to use
this method, the above code would look as so:
@@ -229,20 +204,20 @@ Whichever method you choose to use, the results in action will look like this:
XMPP does not require stanzas sent by a client to include a ``from`` attribute, and
leaves that responsibility to the XMPP server. However, if a sent stanza does
include a ``from`` attribute, it must match the full JID of the client or some
- servers will reject it. SleekXMPP thus leaves out the ``from`` attribute when replying
+ servers will reject it. Slixmpp thus leaves out the ``from`` attribute when replying
using a client connection.
Command Line Arguments and Logging
----------------------------------
-While this isn't part of SleekXMPP itself, we do want our echo bot program to be able
+While this isn't part of Slixmpp itself, we do want our echo bot program to be able
to accept a JID and password from the command line instead of hard coding them. We will
use the ``optparse`` module for this, though there are several alternative methods, including
the newer ``argparse`` module.
We want to accept three parameters: the JID for the echo bot, its password, and a flag for
displaying the debugging logs. We also want these to be optional parameters, since passing
-a password directly through the command line can be a security risk.
+a password directly through the command line can be a security risk.
.. code-block:: python
@@ -303,21 +278,21 @@ the ``EchoBot.__init__`` method instead.
.. note::
- If you are using the OpenFire server, you will need to include an additional
+ If you are using the OpenFire server, you will need to include an additional
configuration step. OpenFire supports a different version of SSL than what
- most servers and SleekXMPP support.
+ most servers and Slixmpp support.
.. code-block:: python
-
+
import ssl
xmpp.ssl_version = ssl.PROTOCOL_SSLv3
Now we're ready to connect and begin echoing messages. If you have the package
-``dnspython`` installed, then the :meth:`sleekxmpp.clientxmpp.ClientXMPP` method
+``aiodns`` installed, then the :meth:`slixmpp.clientxmpp.ClientXMPP` method
will perform a DNS query to find the appropriate server to connect to for the
-given JID. If you do not have ``dnspython``, then SleekXMPP will attempt to
+given JID. If you do not have ``aiodns``, then Slixmpp will attempt to
connect to the hostname used by the JID, unless an address tuple is supplied
-to :meth:`sleekxmpp.clientxmpp.ClientXMPP`.
+to :meth:`slixmpp.clientxmpp.ClientXMPP`.
.. code-block:: python
@@ -330,35 +305,19 @@ to :meth:`sleekxmpp.clientxmpp.ClientXMPP`.
else:
print('Unable to connect')
-.. note::
-
- For Google Talk users withouth ``dnspython`` installed, the above code
- should look like:
-
- .. code-block:: python
-
- if __name__ == '__main__':
-
- # .. option parsing & echo bot configuration
-
- if xmpp.connect(('talk.google.com', 5222)):
- xmpp.process(block=True)
- else:
- print('Unable to connect')
-
-To begin responding to messages, you'll see we called :meth:`sleekxmpp.basexmpp.BaseXMPP.process`
+To begin responding to messages, you'll see we called :meth:`slixmpp.basexmpp.BaseXMPP.process`
which will start the event handling, send queue, and XML reader threads. It will also call
-the :meth:`sleekxmpp.plugins.base.base_plugin.post_init` method on all registered plugins. By
-passing ``block=True`` to :meth:`sleekxmpp.basexmpp.BaseXMPP.process` we are running the
-main processing loop in the main thread of execution. The :meth:`sleekxmpp.basexmpp.BaseXMPP.process`
-call will not return until after SleekXMPP disconnects. If you need to run the client in the background
+the :meth:`slixmpp.plugins.base.BasePlugin.post_init` method on all registered plugins. By
+passing ``block=True`` to :meth:`slixmpp.basexmpp.BaseXMPP.process` we are running the
+main processing loop in the main thread of execution. The :meth:`slixmpp.basexmpp.BaseXMPP.process`
+call will not return until after Slixmpp disconnects. If you need to run the client in the background
for another program, use ``block=False`` to spawn the processing loop in its own thread.
-.. note::
+.. note::
- Before 1.0, controlling the blocking behaviour of :meth:`sleekxmpp.basexmpp.BaseXMPP.process` was
+ Before 1.0, controlling the blocking behaviour of :meth:`slixmpp.basexmpp.BaseXMPP.process` was
done via the ``threaded`` argument. This arrangement was a source of confusion because some users
- interpreted that as controlling whether or not SleekXMPP used threads at all, instead of how
+ interpreted that as controlling whether or not Slixmpp used threads at all, instead of how
the processing loop itself was spawned.
The statements ``xmpp.process(threaded=False)`` and ``xmpp.process(block=True)`` are equivalent.
@@ -370,7 +329,7 @@ The Final Product
-----------------
Here then is what the final result should look like after working through the guide above. The code
-can also be found in the SleekXMPP `examples directory <http://github.com/fritzy/SleekXMPP/tree/master/examples>`_.
+can also be found in the Slixmpp `examples directory <http://github.com/fritzy/Slixmpp/tree/master/examples>`_.
.. compound::
diff --git a/docs/getting_started/iq.rst b/docs/getting_started/iq.rst
index 98e0bdaf..be15e170 100644
--- a/docs/getting_started/iq.rst
+++ b/docs/getting_started/iq.rst
@@ -1,17 +1,17 @@
Send/Receive IQ Stanzas
=======================
-Unlike :class:`~sleekxmpp.stanza.message.Message` and
-:class:`~sleekxmpp.stanza.presence.Presence` stanzas which only use
-text data for basic usage, :class:`~sleekxmpp.stanza.iq.Iq` stanzas
+Unlike :class:`~slixmpp.stanza.message.Message` and
+:class:`~slixmpp.stanza.presence.Presence` stanzas which only use
+text data for basic usage, :class:`~slixmpp.stanza.iq.Iq` stanzas
require using XML payloads, and generally entail creating a new
-SleekXMPP plugin to provide the necessary convenience methods to
+Slixmpp plugin to provide the necessary convenience methods to
make working with them easier.
Basic Use
---------
-XMPP's use of :class:`~sleekxmpp.stanza.iq.Iq` stanzas is built around
+XMPP's use of :class:`~slixmpp.stanza.iq.Iq` stanzas is built around
namespaced ``<query />`` elements. For clients, just sending the
empty ``<query />`` element will suffice for retrieving information. For
example, a very basic implementation of service discovery would just
@@ -26,18 +26,18 @@ need to be able to send:
Creating Iq Stanzas
~~~~~~~~~~~~~~~~~~~
-SleekXMPP provides built-in support for creating basic :class:`~sleekxmpp.stanza.iq.Iq`
+Slixmpp provides built-in support for creating basic :class:`~slixmpp.stanza.iq.Iq`
stanzas this way. The relevant methods are:
-* :meth:`~sleekxmpp.basexmpp.BaseXMPP.make_iq`
-* :meth:`~sleekxmpp.basexmpp.BaseXMPP.make_iq_get`
-* :meth:`~sleekxmpp.basexmpp.BaseXMPP.make_iq_set`
-* :meth:`~sleekxmpp.basexmpp.BaseXMPP.make_iq_result`
-* :meth:`~sleekxmpp.basexmpp.BaseXMPP.make_iq_error`
-* :meth:`~sleekxmpp.basexmpp.BaseXMPP.make_iq_query`
+* :meth:`~slixmpp.basexmpp.BaseXMPP.make_iq`
+* :meth:`~slixmpp.basexmpp.BaseXMPP.make_iq_get`
+* :meth:`~slixmpp.basexmpp.BaseXMPP.make_iq_set`
+* :meth:`~slixmpp.basexmpp.BaseXMPP.make_iq_result`
+* :meth:`~slixmpp.basexmpp.BaseXMPP.make_iq_error`
+* :meth:`~slixmpp.basexmpp.BaseXMPP.make_iq_query`
-These methods all follow the same pattern: create or modify an existing
-:class:`~sleekxmpp.stanza.iq.Iq` stanza, set the ``'type'`` value based
+These methods all follow the same pattern: create or modify an existing
+:class:`~slixmpp.stanza.iq.Iq` stanza, set the ``'type'`` value based
on the method name, and finally add a ``<query />`` element with the given
namespace. For example, to produce the query above, you would use:
@@ -50,14 +50,14 @@ namespace. For example, to produce the query above, you would use:
Sending Iq Stanzas
~~~~~~~~~~~~~~~~~~
-Once an :class:`~sleekxmpp.stanza.iq.Iq` stanza is created, sending it
-over the wire is done using its :meth:`~sleekxmpp.stanza.iq.Iq.send()`
+Once an :class:`~slixmpp.stanza.iq.Iq` stanza is created, sending it
+over the wire is done using its :meth:`~slixmpp.stanza.iq.Iq.send()`
method, like any other stanza object. However, there are a few extra
options to control how to wait for the query's response.
These options are:
-* ``block``: The default behaviour is that :meth:`~sleekxmpp.stanza.iq.Iq.send()`
+* ``block``: The default behaviour is that :meth:`~slixmpp.stanza.iq.Iq.send()`
will block until a response is received and the response stanza will be the
return value. Setting ``block`` to ``False`` will cause the call to return
immediately. In which case, you will need to arrange some way to capture
@@ -74,7 +74,7 @@ These options are:
To change the timeout for a single call, the ``timeout`` parameter works:
.. code-block:: python
-
+
iq.send(timeout=60)
* ``callback``: When not using a blocking call, using the ``callback``
@@ -85,16 +85,16 @@ These options are:
.. code-block:: python
- cb_name = iq.send(callback=self.a_callback)
+ cb_name = iq.send(callback=self.a_callback)
# ... later if we need to cancel
self.remove_handler(cb_name)
-Properly working with :class:`~sleekxmpp.stanza.iq.Iq` stanzas requires
+Properly working with :class:`~slixmpp.stanza.iq.Iq` stanzas requires
handling the intended, normal flow, error responses, and timed out
requests. To make this easier, two exceptions may be thrown by
-:meth:`~sleekxmpp.stanza.iq.Iq.send()`: :exc:`~sleekxmpp.exceptions.IqError`
-and :exc:`~sleekxmpp.exceptions.IqTimeout`. These exceptions only
+:meth:`~slixmpp.stanza.iq.Iq.send()`: :exc:`~slixmpp.exceptions.IqError`
+and :exc:`~slixmpp.exceptions.IqTimeout`. These exceptions only
apply to the default, blocking calls.
.. code-block:: python
@@ -110,7 +110,7 @@ apply to the default, blocking calls.
pass
If you do not care to distinguish between errors and timeouts, then you
-can combine both cases with a generic :exc:`~sleekxmpp.exceptions.XMPPError`
+can combine both cases with a generic :exc:`~slixmpp.exceptions.XMPPError`
exception:
.. code-block:: python
@@ -124,24 +124,24 @@ exception:
Advanced Use
------------
-Going beyond the basics provided by SleekXMPP requires building at least a
-rudimentary SleekXMPP plugin to create a :term:`stanza object` for
-interfacting with the :class:`~sleekxmpp.stanza.iq.Iq` payload.
+Going beyond the basics provided by Slixmpp requires building at least a
+rudimentary Slixmpp plugin to create a :term:`stanza object` for
+interfacting with the :class:`~slixmpp.stanza.iq.Iq` payload.
.. seealso::
* :ref:`create-plugin`
* :ref:`work-with-stanzas`
* :ref:`using-handlers-matchers`
-
-The typical way to respond to :class:`~sleekxmpp.stanza.iq.Iq` requests is
+
+The typical way to respond to :class:`~slixmpp.stanza.iq.Iq` requests is
to register stream handlers. As an example, suppose we create a stanza class
named ``CustomXEP`` which uses the XML element ``<query xmlns="custom-xep" />``,
-and has a :attr:`~sleekxmpp.xmlstream.stanzabase.ElementBase.plugin_attrib` value
+and has a :attr:`~slixmpp.xmlstream.stanzabase.ElementBase.plugin_attrib` value
of ``custom_xep``.
-There are two types of incoming :class:`~sleekxmpp.stanza.iq.Iq` requests:
+There are two types of incoming :class:`~slixmpp.stanza.iq.Iq` requests:
``get`` and ``set``. You can register a handler that will accept both and then
filter by type as needed, as so:
@@ -167,7 +167,7 @@ filter by type as needed, as so:
If you want to filter out query types beforehand, you can adjust the matching
filter by using ``@type=get`` or ``@type=set`` if you are using the recommended
-:class:`~sleekxmpp.xmlstream.matcher.stanzapath.StanzaPath` matcher.
+:class:`~slixmpp.xmlstream.matcher.stanzapath.StanzaPath` matcher.
.. code-block:: python
diff --git a/docs/getting_started/muc.rst b/docs/getting_started/muc.rst
index 26e1fa57..4dd1ff93 100644
--- a/docs/getting_started/muc.rst
+++ b/docs/getting_started/muc.rst
@@ -7,21 +7,13 @@ Mulit-User Chat (MUC) Bot
.. note::
If you have any issues working through this quickstart guide
- or the other tutorials here, please either send a message to the
- `mailing list <http://groups.google.com/group/sleekxmpp-discussion>`_
- or join the chat room at `sleek@conference.jabber.org
- <xmpp:sleek@conference.jabber.org?join>`_.
+ join the chat room at `slixmpp@muc.poez.io
+ <xmpp:slixmpp@muc.poez.io?join>`_.
-If you have not yet installed SleekXMPP, do so now by either checking out a version
-from `Github <http://github.com/fritzy/SleekXMPP>`_, or installing it using ``pip``
-or ``easy_install``.
+If you have not yet installed Slixmpp, do so now by either checking out a version
+from `Git <http://git.poez.io/slixmpp>`_.
-.. code-block:: sh
-
- pip install sleekxmpp # Or: easy_install sleekxmpp
-
-
-Now that you've got the basic gist of using SleekXMPP by following the
+Now that you've got the basic gist of using Slixmpp by following the
echobot example (:ref:`echobot`), we can use one of the bundled plugins
to create a very popular XMPP starter project: a `Multi-User Chat`_
(MUC) bot. Our bot will login to an XMPP server, join an MUC chat room
@@ -36,7 +28,7 @@ Joining The Room
As usual, our code will be based on the pattern explained in :ref:`echobot`.
To start, we create an ``MUCBot`` class based on
-:class:`ClientXMPP <sleekxmpp.clientxmpp.ClientXMPP>` and which accepts
+:class:`ClientXMPP <slixmpp.clientxmpp.ClientXMPP>` and which accepts
parameters for the JID of the MUC room to join, and the nick that the
bot will use inside the chat room. We also register an
:term:`event handler` for the :term:`session_start` event.
@@ -44,12 +36,12 @@ bot will use inside the chat room. We also register an
.. code-block:: python
- import sleekxmpp
+ import slixmpp
- class MUCBot(sleekxmpp.ClientXMPP):
+ class MUCBot(slixmpp.ClientXMPP):
def __init__(self, jid, password, room, nick):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
self.room = room
self.nick = nick
@@ -81,7 +73,7 @@ the roster. Next, we want to join the group chat, so we call the
.. note::
- The :attr:`plugin <sleekxmpp.basexmpp.BaseXMPP.plugin>` attribute is
+ The :attr:`plugin <slixmpp.basexmpp.BaseXMPP.plugin>` attribute is
dictionary that maps to instances of plugins that we have previously
registered, by their names.
@@ -115,7 +107,7 @@ event inside the bot's ``__init__`` function.
.. code-block:: python
def __init__(self, jid, password, room, nick):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
self.room = room
self.nick = nick
@@ -159,7 +151,7 @@ event so it's a good idea to register an event handler for it.
.. code-block:: python
def __init__(self, jid, password, room, nick):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
self.room = room
self.nick = nick
diff --git a/docs/getting_started/proxy.rst b/docs/getting_started/proxy.rst
index 60d521c5..22439d4e 100644
--- a/docs/getting_started/proxy.rst
+++ b/docs/getting_started/proxy.rst
@@ -5,19 +5,17 @@ Enable HTTP Proxy Support
=========================
.. note::
-
+
If you have any issues working through this quickstart guide
- or the other tutorials here, please either send a message to the
- `mailing list <http://groups.google.com/group/sleekxmpp-discussion>`_
- or join the chat room at `sleek@conference.jabber.org
- <xmpp:sleek@conference.jabber.org?join>`_.
+ join the chat room at `slixmpp@muc.poez.io
+ <xmpp:slixmpp@muc.poez.io?join>`_.
In some instances, you may wish to route XMPP traffic through
an HTTP proxy, probably to get around restrictive firewalls.
-SleekXMPP provides support for basic HTTP proxying with DIGEST
+Slixmpp provides support for basic HTTP proxying with DIGEST
authentication.
-Enabling proxy support is done in two steps. The first is to instruct SleekXMPP
+Enabling proxy support is done in two steps. The first is to instruct Slixmpp
to use a proxy, and the second is to configure the proxy details:
.. code-block:: python
diff --git a/docs/getting_started/sendlogout.rst b/docs/getting_started/sendlogout.rst
index a1352db9..d5882c42 100644
--- a/docs/getting_started/sendlogout.rst
+++ b/docs/getting_started/sendlogout.rst
@@ -2,29 +2,27 @@ Sign in, Send a Message, and Disconnect
=======================================
.. note::
-
+
If you have any issues working through this quickstart guide
- or the other tutorials here, please either send a message to the
- `mailing list <http://groups.google.com/group/sleekxmpp-discussion>`_
- or join the chat room at `sleek@conference.jabber.org
- <xmpp:sleek@conference.jabber.org?join>`_.
+ join the chat room at `slixmpp@muc.poez.io
+ <xmpp:slixmpp@muc.poez.io?join>`_.
-A common use case for SleekXMPP is to send one-off messages from
-time to time. For example, one use case could be sending out a notice when
+A common use case for Slixmpp is to send one-off messages from
+time to time. For example, one use case could be sending out a notice when
a shell script finishes a task.
We will create our one-shot bot based on the pattern explained in :ref:`echobot`. To
-start, we create a client class based on :class:`ClientXMPP <sleekxmpp.clientxmpp.ClientXMPP>` and
+start, we create a client class based on :class:`ClientXMPP <slixmpp.clientxmpp.ClientXMPP>` and
register a handler for the :term:`session_start` event. We will also accept parameters
for the JID that will receive our message, and the string content of the message.
.. code-block:: python
- import sleekxmpp
+ import slixmpp
+
+ class SendMsgBot(slixmpp.ClientXMPP):
- class SendMsgBot(sleekxmpp.ClientXMPP):
-
def __init__(self, jid, password, recipient, msg):
super(SendMsgBot, self).__init__(jid, password)
@@ -38,7 +36,7 @@ for the JID that will receive our message, and the string content of the message
self.get_roster()
Note that as in :ref:`echobot`, we need to include send an initial presence and request
-the roster. Next, we want to send our message, and to do that we will use :meth:`send_message <sleekxmpp.basexmpp.BaseXMPP.send_message>`.
+the roster. Next, we want to send our message, and to do that we will use :meth:`send_message <slixmpp.basexmpp.BaseXMPP.send_message>`.
.. code-block:: python
@@ -48,12 +46,12 @@ the roster. Next, we want to send our message, and to do that we will use :meth:
self.send_message(mto=self.recipient, mbody=self.msg)
-Finally, we need to disconnect the client using :meth:`disconnect <sleekxmpp.xmlstream.XMLStream.disconnect>`.
+Finally, we need to disconnect the client using :meth:`disconnect <slixmpp.xmlstream.XMLStream.disconnect>`.
Now, sent stanzas are placed in a queue to pass them to the send thread. If we were to call
-:meth:`disconnect <sleekxmpp.xmlstream.XMLStream.disconnect>` without any parameters, then it is possible
+:meth:`disconnect <slixmpp.xmlstream.XMLStream.disconnect>` without any parameters, then it is possible
for the client to disconnect before the send queue is processed and the message is actually
-sent on the wire. To ensure that our message is processed, we use
-:meth:`disconnect(wait=True) <sleekxmpp.xmlstream.XMLStream.disconnect>`.
+sent on the wire. To ensure that our message is processed, we use
+:meth:`disconnect(wait=True) <slixmpp.xmlstream.XMLStream.disconnect>`.
.. code-block:: python
@@ -68,7 +66,7 @@ sent on the wire. To ensure that our message is processed, we use
.. warning::
If you happen to be adding stanzas to the send queue faster than the send thread
- can process them, then :meth:`disconnect(wait=True) <sleekxmpp.xmlstream.XMLStream.disconnect>`
+ can process them, then :meth:`disconnect(wait=True) <slixmpp.xmlstream.XMLStream.disconnect>`
will block and not disconnect.
Final Product
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 35d2dc86..435df102 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -9,21 +9,20 @@ Glossary
stream handler
A callback function that accepts stanza objects pulled directly
from the XML stream. A stream handler is encapsulated in a
- object that includes a :term:`Matcher` object, and which provides
- additional semantics. For example, the ``Waiter`` handler wrapper
- blocks thread execution until a matching stanza is received.
+ object that includes a :class:`Matcher <.MatcherBase>` object, and
+ which provides additional semantics. For example, the
+ :class:`.Waiter` handler wrapper blocks thread execution until a
+ matching stanza is received.
event handler
A callback function that responds to events raised by
- ``XMLStream.event``. An event handler may be marked as
- threaded, allowing it to execute outside of the main processing
- loop.
+ :meth:`.XMLStream.event`.
stanza object
- Informally may refer both to classes which extend ``ElementBase``
- or ``StanzaBase``, and to objects of such classes.
+ Informally may refer both to classes which extend :class:`.ElementBase`
+ or :class:`.StanzaBase`, and to objects of such classes.
- A stanza object is a wrapper for an XML object which exposes ``dict``
+ A stanza object is a wrapper for an XML object which exposes :class:`dict`
like interfaces which may be assigned to, read from, or deleted.
stanza plugin
diff --git a/docs/guide_xep_0030.rst b/docs/guide_xep_0030.rst
index 857f7ff1..8d98e3bd 100644
--- a/docs/guide_xep_0030.rst
+++ b/docs/guide_xep_0030.rst
@@ -18,7 +18,7 @@ Working with service discovery is about creating and querying these nodes.
According to XEP-0030, a node may contain three types of information:
identities, features, and items. (Further, extensible, information types are
defined in `XEP-0128 <http://xmpp.org/extensions/xep-0128.html>`_, but they are
-not yet implemented by SleekXMPP.) SleekXMPP provides methods to configure each
+not yet implemented by Slixmpp.) Slixmpp provides methods to configure each
of these node attributes.
Configuring Service Discovery
@@ -119,7 +119,7 @@ the same order as expected using positional arguments.
xmpp['xep_0030'].add_identity(category='client',
itype='bot',
- name='Sleek',
+ name='Slixmpp',
node='foo',
jid=xmpp.boundjid.full,
lang='no')
@@ -159,7 +159,7 @@ item itself, and the JID and node that will own the item.
.. note::
In this case, the owning JID and node are provided with the
- parameters ``ijid`` and ``node``.
+ parameters ``ijid`` and ``node``.
Performing Disco Queries
-----------------------
@@ -172,11 +172,10 @@ the `XEP-0059 <http://xmpp.org/extensions/xep-0059.html>`_ plug-in.
.. code-block:: python
- info = self['xep_0030'].get_info(jid='foo@example.com',
- node='bar',
- ifrom='baz@mycomponent.example.com',
- block=True,
- timeout=30)
+ info = yield from self['xep_0030'].get_info(jid='foo@example.com',
+ node='bar',
+ ifrom='baz@mycomponent.example.com',
+ timeout=30)
items = self['xep_0030'].get_info(jid='foo@example.com',
node='bar',
@@ -197,5 +196,5 @@ a full Iq stanza.
info = self['xep_0030'].get_info(node='foo', local=True)
items = self['xep_0030'].get_items(jid='somejid@mycomponent.example.com',
- node='bar',
+ node='bar',
local=True)
diff --git a/docs/index.rst b/docs/index.rst
index 6f6d8913..92e17eec 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,49 +1,36 @@
-SleekXMPP
+Slixmpp
#########
.. sidebar:: Get the Code
- .. code-block:: sh
+ The latest source code for Slixmpp may be found on the `Git repo
+ <http://git.poez.io/slixmpp>`_. ::
- pip install sleekxmpp
+ git clone git://git.poez.io/slixmpp
- The latest source code for SleekXMPP may be found on `Github
- <http://github.com/fritzy/SleekXMPP>`_. Releases can be found in the
- ``master`` branch, while the latest development version is in the
- ``develop`` branch.
-
- **Latest Stable Release**
- - `1.0 <http://github.com/fritzy/SleekXMPP/zipball/1.0>`_
-
- **Develop Releases**
- - `Latest Develop Version <http://github.com/fritzy/SleekXMPP/zipball/develop>`_
-
-
- A mailing list and XMPP chat room are available for discussing and getting
- help with SleekXMPP.
-
- **Mailing List**
- `SleekXMPP Discussion on Google Groups <http://groups.google.com/group/sleekxmpp-discussion>`_
+ An XMPP chat room is available for discussing and getting help with slixmpp.
**Chat**
- `sleek@conference.jabber.org <xmpp:sleek@conference.jabber.org?join>`_
+ `slixmpp@muc.poez.io <xmpp:slixmpp@muc.poez.io?join>`_
+ **Reporting bugs**
+ You can report bugs at http://dev.louiz.org/projects/slixmpp/issues.
-SleekXMPP is an :ref:`MIT licensed <license>` XMPP library for Python 2.6/3.1+,
-and is featured in examples in
-`XMPP: The Definitive Guide <http://oreilly.com/catalog/9780596521271>`_
-by Kevin Smith, Remko Tronçon, and Peter Saint-Andre. If you've arrived
-here from reading the Definitive Guide, please see the notes on updating
-the examples to the latest version of SleekXMPP.
+.. note::
+ slixmpp is a friendly fork of `SleekXMPP <https://github.com/fritzy/SleekXMPP>`_
+ which goal is to use asyncio instead of threads to handle networking. See
+ :ref:`differences`.
-SleekXMPP's design goals and philosphy are:
+Slixmpp is an :ref:`MIT licensed <license>` XMPP library for Python 3.4+,
+
+Slixmpp's design goals and philosphy are:
**Low number of dependencies**
- Installing and using SleekXMPP should be as simple as possible, without
+ Installing and using Slixmpp should be as simple as possible, without
having to deal with long dependency chains.
As part of reducing the number of dependencies, some third party
- modules are included with SleekXMPP in the ``thirdparty`` directory.
+ modules are included with Slixmpp in the ``thirdparty`` directory.
Imports from this module first try to import an existing installed
version before loading the packaged version, when possible.
@@ -55,19 +42,20 @@ SleekXMPP's design goals and philosphy are:
XEPs.
**Rewarding to work with**
- As much as possible, SleekXMPP should allow things to "just work" using
+ As much as possible, Slixmpp should allow things to "just work" using
sensible defaults and appropriate abstractions. XML can be ugly to work
with, but it doesn't have to be that way.
-Here's your first SleekXMPP Bot:
+
+Here's your first Slixmpp Bot:
--------------------------------
.. code-block:: python
+ import asyncio
import logging
- from sleekxmpp import ClientXMPP
- from sleekxmpp.exceptions import IqError, IqTimeout
+ from slixmpp import ClientXMPP
class EchoBot(ClientXMPP):
@@ -85,27 +73,13 @@ Here's your first SleekXMPP Bot:
# Here's how to access plugins once you've registered them:
# self['xep_0030'].add_feature('echo_demo')
- # If you are working with an OpenFire server, you will
- # need to use a different SSL version:
- # import ssl
- # self.ssl_version = ssl.PROTOCOL_SSLv3
-
def session_start(self, event):
self.send_presence()
self.get_roster()
# Most get_*/set_* methods from plugins use Iq stanzas, which
- # can generate IqError and IqTimeout exceptions
- #
- # try:
- # self.get_roster()
- # except IqError as err:
- # logging.error('There was an error getting the roster')
- # logging.error(err.iq['error']['condition'])
- # self.disconnect()
- # except IqTimeout:
- # logging.error('Server is taking too long to respond')
- # self.disconnect()
+ # are sent asynchronously. You can almost always provide a
+ # callback that will be executed when the reply is received.
def message(self, msg):
if msg['type'] in ('chat', 'normal'):
@@ -113,7 +87,7 @@ Here's your first SleekXMPP Bot:
if __name__ == '__main__':
- # Ideally use optparse or argparse to get JID,
+ # Ideally use optparse or argparse to get JID,
# password, and log level.
logging.basicConfig(level=logging.DEBUG,
@@ -121,15 +95,24 @@ Here's your first SleekXMPP Bot:
xmpp = EchoBot('somejid@example.com', 'use_getpass')
xmpp.connect()
- xmpp.process(block=True)
+ xmpp.process()
+
+
+To read if you come from SleekXMPP
+----------------------------------
+.. toctree::
+ :maxdepth: 1
+
+ differences
+ using_asyncio
Getting Started (with Examples)
-------------------------------
.. toctree::
:maxdepth: 1
-
+
getting_started/echobot
getting_started/sendlogout
getting_started/component
@@ -144,8 +127,7 @@ Tutorials, FAQs, and How To Guides
----------------------------------
.. toctree::
:maxdepth: 1
-
- faq
+
xeps
xmpp_tdg
howto/stanzas
@@ -156,12 +138,12 @@ Tutorials, FAQs, and How To Guides
Plugin Guides
~~~~~~~~~~~~~
-.. toctree::
+.. toctree::
:maxdepth: 1
guide_xep_0030
-SleekXMPP Architecture and Design
+Slixmpp Architecture and Design
---------------------------------
.. toctree::
:maxdepth: 3
@@ -173,7 +155,7 @@ API Reference
-------------
.. toctree::
:maxdepth: 2
-
+
event_index
api/clientxmpp
api/componentxmpp
@@ -184,9 +166,7 @@ API Reference
api/xmlstream/handler
api/xmlstream/matcher
api/xmlstream/xmlstream
- api/xmlstream/scheduler
api/xmlstream/tostring
- api/xmlstream/filesocket
Core Stanzas
~~~~~~~~~~~~
@@ -197,8 +177,6 @@ Core Stanzas
api/stanza/message
api/stanza/presence
api/stanza/iq
- api/stanza/error
- api/stanza/stream_error
Plugins
~~~~~~~
@@ -220,8 +198,14 @@ Additional Info
* :ref:`modindex`
* :ref:`search`
-Credits
--------
+SleekXMPP Credits
+-----------------
+
+.. note::
+ Those people made SleekXMPP, so you should not bother them if
+ you have an issue with slixmpp. But it’s still fair to credit
+ them for their work.
+
**Main Author:** `Nathan Fritz <http://andyet.net/team/fritzy>`_
`fritzy@netflint.net <xmpp:fritzy@netflint.net?message>`_,
diff --git a/docs/license.rst b/docs/license.rst
index cbcf5c11..d9505344 100644
--- a/docs/license.rst
+++ b/docs/license.rst
@@ -1,4 +1,4 @@
-.. _license:
+.. _license:
License (MIT)
=============
diff --git a/docs/make.bat b/docs/make.bat
index d97407a6..33fda62b 100644
--- a/docs/make.bat
+++ b/docs/make.bat
@@ -95,9 +95,9 @@ if "%1" == "qthelp" (
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
- echo.^> qcollectiongenerator %BUILDDIR%\qthelp\SleekXMPP.qhcp
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Slixmpp.qhcp
echo.To view the help file:
- echo.^> assistant -collectionFile %BUILDDIR%\qthelp\SleekXMPP.ghc
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Slixmpp.ghc
goto end
)
diff --git a/docs/using_asyncio.rst b/docs/using_asyncio.rst
new file mode 100644
index 00000000..55ed7679
--- /dev/null
+++ b/docs/using_asyncio.rst
@@ -0,0 +1,148 @@
+.. _using_asyncio:
+
+=============
+Using asyncio
+=============
+
+Block on IQ sending
+~~~~~~~~~~~~~~~~~~~
+
+:meth:`.Iq.send` now returns a :class:`~.Future` so you can easily block with:
+
+.. code-block:: python
+
+ result = yield from iq.send()
+
+.. warning::
+
+ If the reply is an IQ with an ``error`` type, this will raise an
+ :class:`.IqError`, and if it timeouts, it will raise an
+ :class:`.IqTimeout`. Don't forget to catch it.
+
+You can still use callbacks instead.
+
+XEP plugin integration
+~~~~~~~~~~~~~~~~~~~~~~
+
+The same changes from the SleekXMPP API apply, so you can do:
+
+.. code-block:: python
+
+ iq_info = yield from self.xmpp['xep_0030'].get_info(jid)
+
+But the following will only return a Future:
+
+.. code-block:: python
+
+ iq_info = self.xmpp['xep_0030'].get_info(jid)
+
+
+Callbacks, Event Handlers, and Stream Handlers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+IQ callbacks and :term:`Event Handlers <event handler>` can be coroutine
+functions; in this case, they will be scheduled in the event loop using
+:meth:`.asyncio.async` and not ran immediately.
+
+A :class:`.CoroutineCallback` class has been added as well for
+:term:`Stream Handlers <stream handler>`, which will use
+:meth:`.asyncio.async` to schedule the callback.
+
+Running the event loop
+~~~~~~~~~~~~~~~~~~~~~~
+
+:meth:`.XMLStream.process` is only a thin wrapper on top of
+``loop.run_forever()`` (if ``timeout`` is provided then it will
+only run for this amount of time, and if ``forever`` is False it will
+run until disconnection).
+
+Therefore you can handle the event loop in any way you like
+instead of using ``process()``.
+
+
+Examples
+~~~~~~~~
+
+Blocking until the session is established
+-----------------------------------------
+
+This code blocks until the XMPP session is fully established, which
+can be useful to make sure external events aren’t triggering XMPP
+callbacks while everything is not ready.
+
+.. code-block:: python
+
+ import asyncio, slixmpp
+
+ client = slixmpp.ClientXMPP('jid@example', 'password')
+ client.connected_event = asyncio.Event()
+ callback = lambda _: client.connected_event.set()
+ client.add_event_handler('session_start', callback)
+ client.connect()
+ loop.run_until_complete(event.wait())
+ # do some other stuff before running the event loop, e.g.
+ # loop.run_until_complete(httpserver.init())
+ client.process()
+
+
+Use with other asyncio-based libraries
+--------------------------------------
+
+This code interfaces with aiohttp to retrieve two pages asynchronously
+when the session is established, and then send the HTML content inside
+a simple <message>.
+
+.. code-block:: python
+
+ import asyncio, aiohttp, slixmpp
+
+ @asyncio.coroutine
+ def get_pythonorg(event):
+ req = yield from aiohttp.request('get', 'http://www.python.org')
+ text = yield from req.text
+ client.send_message(mto='jid2@example', mbody=text)
+
+ @asyncio.coroutine
+ def get_asyncioorg(event):
+ req = yield from aiohttp.request('get', 'http://www.asyncio.org')
+ text = yield from req.text
+ client.send_message(mto='jid3@example', mbody=text)
+
+ client = slixmpp.ClientXMPP('jid@example', 'password')
+ client.add_event_handler('session_start', get_pythonorg)
+ client.add_event_handler('session_start', get_asyncioorg)
+ client.connect()
+ client.process()
+
+
+Blocking Iq
+-----------
+
+This client checks (via XEP-0092) the software used by every entity it
+receives a message from. After this, it sends a message to a specific
+JID indicating its findings.
+
+.. code-block:: python
+
+ import asyncio, slixmpp
+
+ class ExampleClient(slixmpp.ClientXMPP):
+ def __init__(self, *args, **kwargs):
+ slixmpp.ClientXMPP.__init__(self, *args, **kwargs)
+ self.register_plugin('xep_0092')
+ self.add_event_handler('message', self.on_message)
+
+ @asyncio.coroutine
+ def on_message(self, event):
+ # You should probably handle IqError and IqTimeout exceptions here
+ # but this is an example.
+ version = yield from self['xep_0092'].get_version(message['from'])
+ text = "%s sent me a message, he runs %s" % (message['from'],
+ version['software_version']['name'])
+ self.send_message(mto='master@example.tld', mbody=text)
+
+ client = ExampleClient('jid@example', 'password')
+ client.connect()
+ client.process()
+
+
diff --git a/docs/xeps.rst b/docs/xeps.rst
index 3653d10a..c5b4592d 100644
--- a/docs/xeps.rst
+++ b/docs/xeps.rst
@@ -4,9 +4,9 @@ Supported XEPS
======= ============================= ================
XEP Description Notes
======= ============================= ================
-`0004`_ Data forms
-`0009`_ Jabber RPC
-`0012`_ Last Activity
+`0004`_ Data forms
+`0009`_ Jabber RPC
+`0012`_ Last Activity
`0030`_ Service Discovery
`0033`_ Extended Stanza Addressing
`0045`_ Multi-User Chat (MUC) Client-side only
diff --git a/docs/xmpp_tdg.rst b/docs/xmpp_tdg.rst
index 3d12b1b6..b14fd9e1 100644
--- a/docs/xmpp_tdg.rst
+++ b/docs/xmpp_tdg.rst
@@ -1,20 +1,20 @@
Following *XMPP: The Definitive Guide*
======================================
-SleekXMPP was featured in the first edition of the O'Reilly book
+Slixmpp was featured in the first edition of the O'Reilly book
`XMPP: The Definitive Guide <http://oreilly.com/catalog/9780596521271/>`_
by Peter Saint-Andre, Kevin Smith, and Remko Tronçon. The original source code
for the book's examples can be found at http://github.com/remko/xmpp-tdg. An
updated version of the source code, maintained to stay current with the latest
-SleekXMPP release, is available at http://github.com/legastero/xmpp-tdg.
+Slixmpp release, is available at http://github.com/legastero/xmpp-tdg.
-However, since publication, SleekXMPP has advanced from version 0.2.1 to version
+However, since publication, Slixmpp has advanced from version 0.2.1 to version
1.0 and there have been several major API changes. The most notable is the
introduction of :term:`stanza objects <stanza object>` which have simplified and
standardized interactions with the XMPP XML stream.
What follows is a walk-through of *The Definitive Guide* highlighting the
-changes needed to make the code examples work with version 1.0 of SleekXMPP.
+changes needed to make the code examples work with version 1.0 of Slixmpp.
These changes have been kept to a minimum to preserve the correlation with
the book's explanations, so be aware that some code may not use current best
practices.
@@ -36,7 +36,7 @@ Updated Code
.. code-block:: python
def handleIncomingMessage(self, message):
- self.xmpp.sendMessage(message["from"], message["body"])
+ self.xmpp.send_message(message["from"], message["body"])
`View full source <http://github.com/legastero/xmpp-tdg/blob/master/code/EchoBot/EchoBot.py>`_ |
`View original code <http://github.com/remko/xmpp-tdg/blob/master/code/EchoBot/EchoBot.py>`_
@@ -47,7 +47,7 @@ Example 14-1. (Page 215)
**CheshiR IM bot implementation.**
The main event handling method in the Bot class is meant to process both message
-events and presence update events. With the new changes in SleekXMPP 1.0,
+events and presence update events. With the new changes in Slixmpp 1.0,
extracting a CheshiR status "message" from both types of stanzas
requires accessing different attributes. In the case of a message stanza, the
``"body"`` attribute would contain the CheshiR message. For a presence event,
@@ -72,21 +72,21 @@ Updated Code
.. code-block:: python
def handleIncomingXMPPEvent(self, event):
- msgLocations = {sleekxmpp.stanza.presence.Presence: "status",
- sleekxmpp.stanza.message.Message: "body"}
+ msgLocations = {slixmpp.stanza.presence.Presence: "status",
+ slixmpp.stanza.message.Message: "body"}
message = event[msgLocations[type(event)]]
user = self.backend.getUserFromJID(event["from"].jid)
if user is not None:
self.backend.addMessageFromUser(message, user)
-
+
def handleMessageAddedToBackend(self, message) :
body = message.user + ": " + message.text
htmlBody = "<p><a href='%(uri)s'>%(user)s</a>: %(message)s</p>" % {
"uri": self.url + "/" + message.user,
"user" : message.user, "message" : message.text }
for subscriberJID in self.backend.getSubscriberJIDs(message.user) :
- self.xmpp.sendMessage(subscriberJID, body, mhtml=htmlBody)
+ self.xmpp.send_message(subscriberJID, body, mhtml=htmlBody)
`View full source <http://github.com/legastero/xmpp-tdg/blob/master/code/CheshiR/Bot.py>`_ |
`View original code <http://github.com/remko/xmpp-tdg/blob/master/code/CheshiR/Bot.py>`_
@@ -102,7 +102,7 @@ Example 14-3. (Page 217)
The main difference for the configurable IM bot is the handling for the
data form in ``handleConfigurationCommand``. The test for equality
-with the string ``"1"`` is no longer required; SleekXMPP converts
+with the string ``"1"`` is no longer required; Slixmpp converts
boolean data form fields to the values ``True`` and ``False``
automatically.
@@ -145,7 +145,7 @@ Example 14-4. (Page 220)
Like several previous examples, a needed change is to replace
``subscription["from"]`` with ``subscription["from"].jid`` because the
-``BaseXMPP`` method ``makePresence`` requires the JID to be a string.
+``BaseXMPP`` method ``make_presence`` requires the JID to be a string.
A correction needs to be made in ``handleXMPPPresenceProbe`` because a line was
left out of the original implementation; the variable ``user`` is undefined. The
@@ -154,7 +154,7 @@ JID of the user can be extracted from the presence stanza's ``from`` attribute.
Since this implementation of CheshiR uses an XMPP component, it must
include a ``from`` attribute in all messages that it sends. Adding the
``from`` attribute is done by including ``mfrom=self.xmpp.jid`` in calls to
-``self.xmpp.sendMessage``.
+``self.xmpp.send_message``.
Updated Code
~~~~~~~~~~~~
@@ -162,19 +162,19 @@ Updated Code
.. code-block:: python
def handleXMPPPresenceProbe(self, event) :
- self.xmpp.sendPresence(pto = event["from"])
+ self.xmpp.send_presence(pto = event["from"])
def handleXMPPPresenceSubscription(self, subscription) :
if subscription["type"] == "subscribe" :
userJID = subscription["from"].jid
- self.xmpp.sendPresenceSubscription(pto=userJID, ptype="subscribed")
- self.xmpp.sendPresence(pto = userJID)
- self.xmpp.sendPresenceSubscription(pto=userJID, ptype="subscribe")
+ self.xmpp.send_presence_subscription(pto=userJID, ptype="subscribed")
+ self.xmpp.send_presence(pto = userJID)
+ self.xmpp.send_presence_subscription(pto=userJID, ptype="subscribe")
def handleMessageAddedToBackend(self, message) :
body = message.user + ": " + message.text
for subscriberJID in self.backend.getSubscriberJIDs(message.user) :
- self.xmpp.sendMessage(subscriberJID, body, mfrom=self.xmpp.jid)
+ self.xmpp.send_message(subscriberJID, body, mfrom=self.xmpp.jid)
`View full source <http://github.com/legastero/xmpp-tdg/blob/master/code/CheshiR/SimpleComponent.py>`_ |
`View original code <http://github.com/remko/xmpp-tdg/blob/master/code/CheshiR/SimpleComponent.py>`_
@@ -192,7 +192,7 @@ After applying the changes from Example 14-4 above, the registrable component
implementation should work correctly.
.. tip::
- To see how to implement in-band registration as a SleekXMPP plugin,
+ To see how to implement in-band registration as a Slixmpp plugin,
see the tutorial :ref:`tutorial-create-plugin`.
`View full source <http://github.com/legastero/xmpp-tdg/blob/master/code/CheshiR/RegistrableComponent.py>`_ |
@@ -203,13 +203,13 @@ Example 14-7. (Page 225)
**Extended CheshiR IM server component implementation.**
.. note::
- Since the CheshiR examples build on each other, see previous
+ Since the CheshiR examples build on each other, see previous
sections for corrections to code that is not marked as new in the book
example.
While the final code example can look daunting with all of the changes
made, it requires very few modifications to work with the latest version of
-SleekXMPP. Most differences are the result of CheshiR's backend functions
+Slixmpp. Most differences are the result of CheshiR's backend functions
expecting JIDs to be strings so that they can be stripped to bare JIDs. To
resolve these, use the ``jid`` attribute of the JID objects. Also,
references to ``"message"`` and ``"jid"`` attributes need to
@@ -239,11 +239,11 @@ Updated Code
userJID = subscription["from"].jid
user = self.backend.getUserFromJID(userJID)
contactJID = subscription["to"]
- self.xmpp.sendPresenceSubscription(
+ self.xmpp.send_presence_subscription(
pfrom=contactJID, pto=userJID, ptype="subscribed", pnick=user)
self.sendPresenceOfContactToUser(contactJID=contactJID, userJID=userJID)
if contactJID == self.componentDomain :
self.sendAllContactSubscriptionRequestsToUser(userJID)
`View full source <http://github.com/legastero/xmpp-tdg/blob/master/code/CheshiR/Component.py>`_ |
-`View original code <http://github.com/remko/xmpp-tdg/blob/master/code/CheshiR/Component.py>`_
+`View original code <http://github.com/remko/xmpp-tdg/blob/master/code/CheshiR/Component.py>`_
diff --git a/examples/IoT_TestDevice.py b/examples/IoT_TestDevice.py
index b85a0b7c..b9546017 100755
--- a/examples/IoT_TestDevice.py
+++ b/examples/IoT_TestDevice.py
@@ -1,43 +1,35 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import getpass
import logging
-import sys
-from optparse import OptionParser
+from os.path import basename, join as pjoin
+from argparse import ArgumentParser
from urllib import urlopen
+from getpass import getpass
-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
+import slixmpp
+from slixmpp.plugins.xep_0323.device import Device
-from sleekxmpp.plugins.xep_0323.device import Device
+#from slixmpp.exceptions import IqError, IqTimeout
-class IoT_TestDevice(sleekxmpp.ClientXMPP):
+class IoT_TestDevice(slixmpp.ClientXMPP):
"""
A simple IoT device that can act as server or client
"""
def __init__(self, jid, password):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
self.add_event_handler("session_start", self.session_start)
self.add_event_handler("message", self.message)
self.device=None
@@ -115,47 +107,44 @@ if __name__ == '__main__':
#
# "client" an IoT device or other party that would like to get data from another device
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
+ parser.add_argument("-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")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-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)
+ parser.add_argument("-c", "--sensorjid", dest="sensorjid",
+ help="Another device to call for data on", default=None)
+ parser.add_argument("-n", "--nodeid", dest="nodeid",
+ help="I am a device get ready to be called", default=None)
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
- xmpp = IoT_TestDevice(opts.jid,opts.password)
+ xmpp = IoT_TestDevice(args.jid,args.password)
xmpp.register_plugin('xep_0030')
#xmpp['xep_0030'].add_feature(feature='urn:xmpp:iot:sensordata',
# node=None,
@@ -163,31 +152,31 @@ if __name__ == '__main__':
xmpp.register_plugin('xep_0323')
xmpp.register_plugin('xep_0325')
- if opts.nodeid:
+ if args.nodeid:
# xmpp['xep_0030'].add_feature(feature='urn:xmpp:sn',
- # node=opts.nodeid,
+ # node=args.nodeid,
# jid=xmpp.boundjid.full)
- myDevice = TheDevice(opts.nodeid)
+ myDevice = TheDevice(args.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['xep_0323'].register_node(nodeId=args.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:
+ if args.sensorjid:
logging.debug("will try to call another device for data")
- xmpp.beClientOrServer(server=False,clientJID=opts.sensorjid)
+ xmpp.beClientOrServer(server=False,clientJID=args.sensorjid)
xmpp.connect()
xmpp.process(block=True)
logging.debug("ready ending")
else:
- print "noopp didn't happen"
+ print("noopp didn't happen")
diff --git a/examples/adhoc_provider.py b/examples/adhoc_provider.py
index 86a575c9..72259555 100755
--- a/examples/adhoc_provider.py
+++ b/examples/adhoc_provider.py
@@ -1,41 +1,30 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
+import slixmpp
-# 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
-
-class CommandBot(sleekxmpp.ClientXMPP):
+class CommandBot(slixmpp.ClientXMPP):
"""
- A simple SleekXMPP bot that provides a basic
+ A simple Slixmpp bot that provides a basic
adhoc command.
"""
def __init__(self, jid, password):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
# The session_start event will be triggered when
# the bot establishes its connection with the server
@@ -143,62 +132,42 @@ class CommandBot(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
# Setup the CommandBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
- xmpp = CommandBot(opts.jid, opts.password)
+ xmpp = CommandBot(args.jid, args.password)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0004') # Data Forms
xmpp.register_plugin('xep_0050') # Adhoc Commands
xmpp.register_plugin('xep_0199', {'keepalive': True, 'frequency':15})
- # 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"
-
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/adhoc_user.py b/examples/adhoc_user.py
index 7df9f793..91e2e1ac 100755
--- a/examples/adhoc_user.py
+++ b/examples/adhoc_user.py
@@ -1,41 +1,30 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
+import slixmpp
-# 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
-
-class CommandUserBot(sleekxmpp.ClientXMPP):
+class CommandUserBot(slixmpp.ClientXMPP):
"""
- A simple SleekXMPP bot that uses the adhoc command
+ A simple Slixmpp bot that uses the adhoc command
provided by the adhoc_provider.py example.
"""
def __init__(self, jid, password, other, greeting):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
self.command_provider = other
self.greeting = greeting
@@ -142,69 +131,49 @@ class CommandUserBot(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
- optp.add_option("-o", "--other", dest="other",
- help="JID providing commands")
- optp.add_option("-g", "--greeting", dest="greeting",
- help="Greeting")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("-o", "--other", dest="other",
+ help="JID providing commands")
+ parser.add_argument("-g", "--greeting", dest="greeting",
+ help="Greeting")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
- if opts.other is None:
- opts.other = raw_input("JID Providing Commands: ")
- if opts.greeting is None:
- opts.greeting = raw_input("Greeting: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+ if args.other is None:
+ args.other = input("JID Providing Commands: ")
+ if args.greeting is None:
+ args.greeting = input("Greeting: ")
# Setup the CommandBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
- xmpp = CommandUserBot(opts.jid, opts.password, opts.other, opts.greeting)
+ xmpp = CommandUserBot(args.jid, args.password, args.other, args.greeting)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0004') # Data Forms
xmpp.register_plugin('xep_0050') # Adhoc Commands
- # 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"
-
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/admin_commands.py b/examples/admin_commands.py
index 5d9bf841..72577f87 100755
--- a/examples/admin_commands.py
+++ b/examples/admin_commands.py
@@ -1,41 +1,30 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
+import slixmpp
-# 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
-
-class AdminCommands(sleekxmpp.ClientXMPP):
+class AdminCommands(slixmpp.ClientXMPP):
"""
- A simple SleekXMPP bot that uses admin commands to
+ A simple Slixmpp bot that uses admin commands to
add a new user to a server.
"""
def __init__(self, jid, password, command):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
self.command = command
@@ -81,13 +70,13 @@ class AdminCommands(sleekxmpp.ClientXMPP):
for var, field in form['fields'].items():
if var != 'FORM_TYPE':
if field['type'] == 'boolean':
- answers[var] = raw_input('%s (y/n): ' % field['label'])
+ answers[var] = input('%s (y/n): ' % field['label'])
if answers[var].lower() in ('1', 'true', 'y', 'yes'):
answers[var] = '1'
else:
answers[var] = '0'
else:
- answers[var] = raw_input('%s: ' % field['label'])
+ answers[var] = input('%s: ' % field['label'])
else:
answers['FORM_TYPE'] = field['value']
form['type'] = 'submit'
@@ -116,63 +105,43 @@ class AdminCommands(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
- optp.add_option("-c", "--command", dest="command",
- help="admin command to use")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("-c", "--command", dest="command",
+ help="admin command to use")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
- if opts.command is None:
- opts.command = raw_input("Admin command: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+ if args.command is None:
+ args.command = input("Admin command: ")
# Setup the CommandBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
- xmpp = AdminCommands(opts.jid, opts.password, opts.command)
+ xmpp = AdminCommands(args.jid, args.password, args.command)
xmpp.register_plugin('xep_0133') # Service Administration
- # 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"
-
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/custom_stanzas/custom_stanza_provider.py b/examples/custom_stanzas/custom_stanza_provider.py
index 0ebdb77e..9927c449 100755
--- a/examples/custom_stanzas/custom_stanza_provider.py
+++ b/examples/custom_stanzas/custom_stanza_provider.py
@@ -1,48 +1,37 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
+import slixmpp
-from sleekxmpp import ClientXMPP, Iq
-from sleekxmpp.exceptions import IqError, IqTimeout, XMPPError
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
+from slixmpp import ClientXMPP, Iq
+from slixmpp.exceptions import IqError, IqTimeout, XMPPError
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
from stanza import Action
-# 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
-
-class ActionBot(sleekxmpp.ClientXMPP):
+class ActionBot(slixmpp.ClientXMPP):
"""
- A simple SleekXMPP bot that receives a custom stanza
+ A simple Slixmpp bot that receives a custom stanza
from another client.
"""
def __init__(self, jid, password):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
# The session_start event will be triggered when
# the bot establishes its connection with the server
@@ -57,8 +46,7 @@ class ActionBot(sleekxmpp.ClientXMPP):
self._handle_action))
self.add_event_handler('custom_action',
- self._handle_action_event,
- threaded=True)
+ self._handle_action_event)
register_stanza_plugin(Iq, Action)
@@ -88,10 +76,6 @@ class ActionBot(sleekxmpp.ClientXMPP):
def _handle_action_event(self, iq):
"""
Respond to the custom action event.
-
- Since one of the actions is to disconnect, this
- event handler needs to be run in threaded mode, by
- using `threaded=True` in the `add_event_handler` call.
"""
method = iq['action']['method']
param = iq['action']['param']
@@ -112,62 +96,42 @@ class ActionBot(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
# Setup the CommandBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
- xmpp = ActionBot(opts.jid, opts.password)
+ xmpp = ActionBot(args.jid, args.password)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0004') # Data Forms
xmpp.register_plugin('xep_0050') # Adhoc Commands
xmpp.register_plugin('xep_0199', {'keepalive': True, 'frequency':15})
- # 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"
-
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/custom_stanzas/custom_stanza_user.py b/examples/custom_stanzas/custom_stanza_user.py
index 418e3218..c5630584 100755
--- a/examples/custom_stanzas/custom_stanza_user.py
+++ b/examples/custom_stanzas/custom_stanza_user.py
@@ -1,46 +1,35 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
-from sleekxmpp import Iq
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.xmlstream import register_stanza_plugin
+import slixmpp
+from slixmpp import Iq
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream import register_stanza_plugin
from stanza import Action
-# 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
-
-class ActionUserBot(sleekxmpp.ClientXMPP):
+class ActionUserBot(slixmpp.ClientXMPP):
"""
- A simple SleekXMPP bot that sends a custom action stanza
+ A simple Slixmpp bot that sends a custom action stanza
to another client.
"""
def __init__(self, jid, password, other):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
self.action_provider = other
@@ -49,7 +38,7 @@ class ActionUserBot(sleekxmpp.ClientXMPP):
# and the XML streams are ready for use. We want to
# listen for this event so that we we can initialize
# our roster.
- self.add_event_handler("session_start", self.start, threaded=True)
+ self.add_event_handler("session_start", self.start)
self.add_event_handler("message", self.message)
register_stanza_plugin(Iq, Action)
@@ -93,10 +82,8 @@ class ActionUserBot(sleekxmpp.ClientXMPP):
iq2['type'] = 'set'
iq2['action']['method'] = 'bye'
iq2.send(block=False)
-
- # The wait=True delays the disconnect until the queue
- # of stanzas to be sent becomes empty.
- self.disconnect(wait=True)
+
+ self.disconnect()
except XMPPError:
print('There was an error sending the custom action.')
@@ -111,65 +98,45 @@ class ActionUserBot(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
- optp.add_option("-o", "--other", dest="other",
- help="JID providing custom stanza")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("-o", "--other", dest="other",
+ help="JID providing custom stanza")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
- if opts.other is None:
- opts.other = raw_input("JID Providing custom stanza: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+ if args.other is None:
+ args.other = input("JID Providing custom stanza: ")
# Setup the CommandBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
- xmpp = ActionUserBot(opts.jid, opts.password, opts.other)
+ xmpp = ActionUserBot(args.jid, args.password, args.other)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0004') # Data Forms
xmpp.register_plugin('xep_0050') # Adhoc Commands
- # 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"
-
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/custom_stanzas/stanza.py b/examples/custom_stanzas/stanza.py
index 50d0f9f2..b2c6f766 100644
--- a/examples/custom_stanzas/stanza.py
+++ b/examples/custom_stanzas/stanza.py
@@ -1,30 +1,30 @@
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class Action(ElementBase):
"""
A stanza class for XML content of the form:
- <action xmlns="sleekxmpp:custom:actions">
+ <action xmlns="slixmpp:custom:actions">
<method>X</method>
<param>X</param>
<status>X</status>
</action>
"""
-
+
#: The `name` field refers to the basic XML tag name of the
#: stanza. Here, the tag name will be 'action'.
name = 'action'
#: The namespace of the main XML tag.
- namespace = 'sleekxmpp:custom:actions'
+ namespace = 'slixmpp:custom:actions'
#: The `plugin_attrib` value is the name that can be used
#: with a parent stanza to access this stanza. For example
#: from an Iq stanza object, accessing:
- #:
+ #:
#: iq['action']
- #:
+ #:
#: would reference an Action object, and will even create
#: an Action object and append it to the Iq stanza if
#: one doesn't already exist.
@@ -49,8 +49,8 @@ class Action(ElementBase):
#: the sub_interfaces set. For example, here all interfaces
#: are marked as sub_interfaces, and so the XML produced will
#: look like:
- #:
- #: <action xmlns="sleekxmpp:custom:actions">
+ #:
+ #: <action xmlns="slixmpp:custom:actions">
#: <method>foo</method>
#: </action>
sub_interfaces = interfaces
diff --git a/examples/disco_browser.py b/examples/disco_browser.py
index 78626e7c..a9e8711f 100755
--- a/examples/disco_browser.py
+++ b/examples/disco_browser.py
@@ -1,35 +1,24 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
-from sleekxmpp.exceptions import IqError, IqTimeout
+import slixmpp
+from slixmpp.exceptions import IqError, IqTimeout
+from slixmpp.xmlstream.asyncio import asyncio
-# 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
-
-
-class Disco(sleekxmpp.ClientXMPP):
+class Disco(slixmpp.ClientXMPP):
"""
A demonstration for using basic service discovery.
@@ -42,7 +31,7 @@ class Disco(sleekxmpp.ClientXMPP):
"""
def __init__(self, jid, password, target_jid, target_node='', get=''):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
# Using service discovery requires the XEP-0030 plugin.
self.register_plugin('xep_0030')
@@ -63,8 +52,9 @@ class Disco(sleekxmpp.ClientXMPP):
# and the XML streams are ready for use. We want to
# listen for this event so that we we can initialize
# our roster.
- self.add_event_handler("session_start", self.start, threaded=True)
+ self.add_event_handler("session_start", self.start)
+ @asyncio.coroutine
def start(self, event):
"""
Process the session_start event.
@@ -86,22 +76,16 @@ class Disco(sleekxmpp.ClientXMPP):
try:
if self.get in self.info_types:
- # By using block=True, the result stanza will be
- # returned. Execution will block until the reply is
- # received. Non-blocking options would be to listen
- # for the disco_info event, or passing a handler
# function using the callback parameter.
- info = self['xep_0030'].get_info(jid=self.target_jid,
- node=self.target_node,
- block=True)
+ info = yield from self['xep_0030'].get_info(jid=self.target_jid,
+ node=self.target_node)
if self.get in self.items_types:
# The same applies from above. Listen for the
# disco_items event or pass a callback function
# if you need to process a non-blocking request.
- items = self['xep_0030'].get_items(jid=self.target_jid,
- node=self.target_node,
- block=True)
- else:
+ items = yield from self['xep_0030'].get_items(jid=self.target_jid,
+ node=self.target_node)
+ if self.get not in self.info_types and self.get not in self.items_types:
logging.error("Invalid disco request type.")
return
except IqError as e:
@@ -136,69 +120,42 @@ class Disco(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
- optp.version = '%%prog 0.1'
- optp.usage = "Usage: %%prog [options] %s <jid> [<node>]" % \
- 'all|info|items|identities|features'
-
- optp.add_option('-q','--quiet', help='set logging to ERROR',
- action='store_const',
- dest='loglevel',
- const=logging.ERROR,
- default=logging.ERROR)
- optp.add_option('-d','--debug', help='set logging to DEBUG',
- action='store_const',
- dest='loglevel',
- const=logging.DEBUG,
- default=logging.ERROR)
- optp.add_option('-v','--verbose', help='set logging to COMM',
- action='store_const',
- dest='loglevel',
- const=5,
- default=logging.ERROR)
+ parser = ArgumentParser(description=Disco.__doc__)
+
+ parser.add_argument("-q","--quiet", help="set logging to ERROR",
+ action="store_const",
+ dest="loglevel",
+ const=logging.ERROR,
+ default=logging.ERROR)
+ parser.add_argument("-d","--debug", help="set logging to DEBUG",
+ action="store_const",
+ dest="loglevel",
+ const=logging.DEBUG,
+ default=logging.ERROR)
# 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")
- opts,args = optp.parse_args()
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("query", choices=["all", "info", "items", "identities", "features"])
+ parser.add_argument("target_jid")
+ parser.add_argument("node", nargs='?')
+
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.loglevel,
format='%(levelname)-8s %(message)s')
- if len(args) < 2:
- optp.print_help()
- exit()
-
- if len(args) == 2:
- args = (args[0], args[1], '')
-
- if opts.jid is None:
- opts.jid = raw_input("Username: ")
- if opts.password is None:
- opts.password = getpass.getpass("Password: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
# Setup the Disco browser.
- xmpp = Disco(opts.jid, opts.password, args[1], args[2], args[0])
-
- # 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"
+ xmpp = Disco(args.jid, args.password, args.target_jid, args.node, args.query)
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process(forever=False)
diff --git a/examples/download_avatars.py b/examples/download_avatars.py
index 64300cff..408c2146 100755
--- a/examples/download_avatars.py
+++ b/examples/download_avatars.py
@@ -1,33 +1,21 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-import threading
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
-from sleekxmpp.exceptions import XMPPError
-
-
-# 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
+import slixmpp
+from slixmpp.exceptions import XMPPError
+from slixmpp import asyncio
FILE_TYPES = {
@@ -37,23 +25,29 @@ FILE_TYPES = {
}
-class AvatarDownloader(sleekxmpp.ClientXMPP):
+class AvatarDownloader(slixmpp.ClientXMPP):
"""
A basic script for downloading the avatars for a user's contacts.
"""
def __init__(self, jid, password):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
- self.add_event_handler("session_start", self.start, threaded=True)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
+ self.add_event_handler("session_start", self.start)
self.add_event_handler("changed_status", self.wait_for_presences)
self.add_event_handler('vcard_avatar_update', self.on_vcard_avatar)
self.add_event_handler('avatar_metadata_publish', self.on_avatar)
self.received = set()
- self.presences_received = threading.Event()
+ self.presences_received = asyncio.Event()
+ self.roster_received = asyncio.Event()
+
+ def roster_received_cb(self, event):
+ self.roster_received.set()
+ self.presences_received.clear()
+ @asyncio.coroutine
def start(self, event):
"""
Process the session_start event.
@@ -68,16 +62,20 @@ class AvatarDownloader(sleekxmpp.ClientXMPP):
data.
"""
self.send_presence()
- self.get_roster()
+ self.get_roster(callback=self.roster_received_cb)
print('Waiting for presence updates...\n')
- self.presences_received.wait(15)
- self.disconnect(wait=True)
+ yield from self.roster_received.wait()
+ print('Roster received')
+ yield from self.presences_received.wait()
+ self.disconnect()
+ @asyncio.coroutine
def on_vcard_avatar(self, pres):
print("Received vCard avatar update from %s" % pres['from'].bare)
try:
- result = self['xep_0054'].get_vcard(pres['from'], cached=True)
+ result = yield from self['xep_0054'].get_vcard(pres['from'].bare, cached=True,
+ timeout=5)
except XMPPError:
print("Error retrieving avatar for %s" % pres['from'])
return
@@ -88,16 +86,18 @@ class AvatarDownloader(sleekxmpp.ClientXMPP):
pres['from'].bare,
pres['vcard_temp_update']['photo'],
filetype)
- with open(filename, 'w+') as img:
+ with open(filename, 'wb+') as img:
img.write(avatar['BINVAL'])
+ @asyncio.coroutine
def on_avatar(self, msg):
print("Received avatar update from %s" % msg['from'])
metadata = msg['pubsub_event']['items']['item']['avatar_metadata']
for info in metadata['items']:
if not info['url']:
try:
- result = self['xep_0084'].retrieve_avatar(msg['from'], info['id'])
+ result = yield from self['xep_0084'].retrieve_avatar(msg['from'].bare, info['id'],
+ timeout=5)
except XMPPError:
print("Error retrieving avatar for %s" % msg['from'])
return
@@ -106,7 +106,7 @@ class AvatarDownloader(sleekxmpp.ClientXMPP):
filetype = FILE_TYPES.get(metadata['type'], 'png')
filename = 'avatar_%s_%s.%s' % (msg['from'].bare, info['id'], filetype)
- with open(filename, 'w+') as img:
+ with open(filename, 'wb+') as img:
img.write(avatar['value'])
else:
# We could retrieve the avatar via HTTP, etc here instead.
@@ -117,6 +117,7 @@ class AvatarDownloader(sleekxmpp.ClientXMPP):
Wait to receive updates from all roster contacts.
"""
self.received.add(pres['from'].bare)
+ print((len(self.received), len(self.client_roster.keys())))
if len(self.received) >= len(self.client_roster.keys()):
self.presences_received.set()
else:
@@ -125,60 +126,40 @@ class AvatarDownloader(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
- optp.add_option('-q','--quiet', help='set logging to ERROR',
- action='store_const',
- dest='loglevel',
- const=logging.ERROR,
- default=logging.ERROR)
- optp.add_option('-d','--debug', help='set logging to DEBUG',
- action='store_const',
- dest='loglevel',
- const=logging.DEBUG,
- default=logging.ERROR)
- optp.add_option('-v','--verbose', help='set logging to COMM',
- action='store_const',
- dest='loglevel',
- const=5,
- default=logging.ERROR)
+ parser = ArgumentParser()
+ parser.add_argument("-q","--quiet", help="set logging to ERROR",
+ action="store_const",
+ dest="loglevel",
+ const=logging.ERROR,
+ default=logging.ERROR)
+ parser.add_argument("-d","--debug", help="set logging to DEBUG",
+ action="store_const",
+ dest="loglevel",
+ const=logging.DEBUG,
+ default=logging.ERROR)
# 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")
- opts,args = optp.parse_args()
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
- xmpp = AvatarDownloader(opts.jid, opts.password)
+ xmpp = AvatarDownloader(args.jid, args.password)
xmpp.register_plugin('xep_0054')
xmpp.register_plugin('xep_0153')
xmpp.register_plugin('xep_0084')
- # 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"
-
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/echo_client.py b/examples/echo_client.py
index f2d38847..820ca014 100755
--- a/examples/echo_client.py
+++ b/examples/echo_client.py
@@ -1,41 +1,30 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
+import slixmpp
-# 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
-
-class EchoBot(sleekxmpp.ClientXMPP):
+class EchoBot(slixmpp.ClientXMPP):
"""
- A simple SleekXMPP bot that will echo messages it
+ A simple Slixmpp bot that will echo messages it
receives, along with a short thank you message.
"""
def __init__(self, jid, password):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
# The session_start event will be triggered when
# the bot establishes its connection with the server
@@ -83,75 +72,42 @@ class EchoBot(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser(description=EchoBot.__doc__)
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
# Setup the EchoBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
- xmpp = EchoBot(opts.jid, opts.password)
+ xmpp = EchoBot(args.jid, args.password)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0004') # Data Forms
xmpp.register_plugin('xep_0060') # PubSub
xmpp.register_plugin('xep_0199') # XMPP Ping
- # 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"
-
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/echo_component.py b/examples/echo_component.py
index 9a24f2fa..664fe311 100755
--- a/examples/echo_component.py
+++ b/examples/echo_component.py
@@ -1,37 +1,26 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
-from sleekxmpp.componentxmpp import ComponentXMPP
-
-# 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
+import slixmpp
+from slixmpp.componentxmpp import ComponentXMPP
class EchoComponent(ComponentXMPP):
"""
- A simple SleekXMPP component that echoes messages.
+ A simple Slixmpp component that echoes messages.
"""
def __init__(self, jid, secret, server, port):
@@ -67,56 +56,50 @@ class EchoComponent(ComponentXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser(description=EchoComponent.__doc__)
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
- optp.add_option("-s", "--server", dest="server",
- help="server to connect to")
- optp.add_option("-P", "--port", dest="port",
- help="port to connect to")
-
- opts, args = optp.parse_args()
-
- if opts.jid is None:
- opts.jid = raw_input("Component JID: ")
- if opts.password is None:
- opts.password = getpass.getpass("Password: ")
- if opts.server is None:
- opts.server = raw_input("Server: ")
- if opts.port is None:
- opts.port = int(raw_input("Port: "))
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("-s", "--server", dest="server",
+ help="server to connect to")
+ parser.add_argument("-P", "--port", dest="port",
+ help="port to connect to")
+
+ args = parser.parse_args()
+
+ if args.jid is None:
+ args.jid = input("Component JID: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+ if args.server is None:
+ args.server = input("Server: ")
+ if args.port is None:
+ args.port = int(input("Port: "))
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.loglevel,
format='%(levelname)-8s %(message)s')
# Setup the EchoComponent and register plugins. Note that while plugins
# may have interdependencies, the order in which you register them does
# not matter.
- xmpp = EchoComponent(opts.jid, opts.password, opts.server, opts.port)
- xmpp.registerPlugin('xep_0030') # Service Discovery
- xmpp.registerPlugin('xep_0004') # Data Forms
- xmpp.registerPlugin('xep_0060') # PubSub
- xmpp.registerPlugin('xep_0199') # XMPP Ping
+ xmpp = EchoComponent(args.jid, args.password, args.server, args.port)
+ xmpp.register_plugin('xep_0030') # Service Discovery
+ xmpp.register_plugin('xep_0004') # Data Forms
+ xmpp.register_plugin('xep_0060') # PubSub
+ xmpp.register_plugin('xep_0199') # XMPP Ping
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/gtalk_custom_domain.py b/examples/gtalk_custom_domain.py
index c974fc55..d25a5786 100755
--- a/examples/gtalk_custom_domain.py
+++ b/examples/gtalk_custom_domain.py
@@ -1,46 +1,34 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
+import slixmpp
import ssl
-from sleekxmpp.xmlstream import cert
+from slixmpp.xmlstream import cert
-# 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
-
-
-class GTalkBot(sleekxmpp.ClientXMPP):
+class GTalkBot(slixmpp.ClientXMPP):
"""
- A demonstration of using SleekXMPP with accounts from a Google Apps
+ A demonstration of using Slixmpp with accounts from a Google Apps
account with a custom domain, because it requires custom certificate
validation.
"""
def __init__(self, jid, password):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
# The session_start event will be triggered when
# the bot establishes its connection with the server
@@ -104,62 +92,42 @@ class GTalkBot(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
# Setup the GTalkBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
- xmpp = GTalkBot(opts.jid, opts.password)
+ xmpp = GTalkBot(args.jid, args.password)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0004') # Data Forms
xmpp.register_plugin('xep_0060') # PubSub
xmpp.register_plugin('xep_0199') # XMPP Ping
- # 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"
-
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/http_over_xmpp.py b/examples/http_over_xmpp.py
index a2fbf664..73e4a612 100644
--- a/examples/http_over_xmpp.py
+++ b/examples/http_over_xmpp.py
@@ -1,17 +1,17 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Implementation of HTTP over XMPP transport
http://xmpp.org/extensions/xep-0332.html
Copyright (C) 2015 Riptide IO, sangeeth@riptideio.com
- This file is part of SleekXMPP.
+ This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp import ClientXMPP
+from slixmpp import ClientXMPP
from optparse import OptionParser
import logging
@@ -32,14 +32,14 @@ class HTTPOverXMPPClient(ClientXMPP):
pass
def http_response_received(self, iq):
- print 'HTTP Response Received : ', iq
- print 'From : ', iq['from']
- print 'To : ', iq['to']
- print 'Type : ', iq['type']
- print 'Headers : ', iq['resp']['headers']
- print 'Code : ', iq['resp']['code']
- print 'Message : ', iq['resp']['message']
- print 'Data : ', iq['resp']['data']
+ print('HTTP Response Received : %s' % iq)
+ print('From : %s' % iq['from'])
+ print('To : %s' % iq['to'])
+ print('Type : %s' % iq['type'])
+ print('Headers : %s' % iq['resp']['headers'])
+ print('Code : %s' % iq['resp']['code'])
+ print('Message : %s' % iq['resp']['message'])
+ print('Data : %s' % iq['resp']['data'])
def session_start(self, event):
# TODO: Fill in the blanks
@@ -87,15 +87,11 @@ if __name__ == '__main__':
format='%(levelname)-8s %(message)s')
if opts.jid is None:
- opts.jid = raw_input('Username: ')
+ opts.jid = input('Username: ')
if opts.password is None:
opts.password = getpass.getpass('Password: ')
xmpp = HTTPOverXMPPClient(opts.jid, opts.password)
- if xmpp.connect((opts.ipaddr, int(opts.port))):
- print 'Connected!'
- xmpp.process(block=True)
- else:
- print 'Not connected!'
- print 'Goodbye....'
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/ibb_transfer/ibb_receiver.py b/examples/ibb_transfer/ibb_receiver.py
index 6aba98e3..e934f295 100755
--- a/examples/ibb_transfer/ibb_receiver.py
+++ b/examples/ibb_transfer/ibb_receiver.py
@@ -1,45 +1,31 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
+import slixmpp
-# 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
-
-class IBBReceiver(sleekxmpp.ClientXMPP):
+class IBBReceiver(slixmpp.ClientXMPP):
"""
A basic example of creating and using an in-band bytestream.
"""
- def __init__(self, jid, password):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ def __init__(self, jid, password, filename):
+ slixmpp.ClientXMPP.__init__(self, jid, password)
- self.register_plugin('xep_0030') # Service Discovery
- self.register_plugin('xep_0047', {
- 'auto_accept': True
- }) # In-band Bytestreams
+ self.file = open(filename, 'wb')
# The session_start event will be triggered when
# the bot establishes its connection with the server
@@ -48,8 +34,9 @@ class IBBReceiver(sleekxmpp.ClientXMPP):
# our roster.
self.add_event_handler("session_start", self.start)
- self.add_event_handler("ibb_stream_start", self.stream_opened, threaded=True)
+ self.add_event_handler("ibb_stream_start", self.stream_opened)
self.add_event_handler("ibb_stream_data", self.stream_data)
+ self.add_event_handler("ibb_stream_end", self.stream_closed)
def start(self, event):
"""
@@ -67,81 +54,59 @@ class IBBReceiver(sleekxmpp.ClientXMPP):
self.send_presence()
self.get_roster()
- def accept_stream(self, iq):
- """
- 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
- configuration. The default is True.
- - setting 'accept_stream' to a function which accepts
- an Iq stanza as its argument, like this one.
-
- The accept_stream function will be used if it exists, and the
- auto_accept value will be used otherwise.
- """
- return True
-
def stream_opened(self, stream):
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.
+ def stream_data(self, stream):
+ self.file.write(stream.read())
- def stream_data(self, event):
- print(event['data'])
+ def stream_closed(self, stream):
+ print('Stream closed: %s from %s' % (stream.sid, stream.peer_jid))
+ self.file.close()
+ self.disconnect()
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("-o", "--out", dest="filename",
+ help="file to save to")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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 = IBBReceiver(opts.jid, opts.password)
-
- # 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"
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+ if args.filename is None:
+ args.filename = input("File path: ")
+
+ # Setup the IBBReceiver and register plugins. Note that while plugins may
+ # have interdependencies, the order in which you register them does
+ # not matter.
+ xmpp = IBBReceiver(args.jid, args.password, args.filename)
+ xmpp.register_plugin('xep_0030') # Service Discovery
+ xmpp.register_plugin('xep_0047', {
+ 'auto_accept': True
+ }) # In-band Bytestreams
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process(forever=False)
diff --git a/examples/ibb_transfer/ibb_sender.py b/examples/ibb_transfer/ibb_sender.py
index 7c380b68..f1c0cab2 100755
--- a/examples/ibb_transfer/ibb_sender.py
+++ b/examples/ibb_transfer/ibb_sender.py
@@ -1,43 +1,36 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
+import asyncio
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
+import slixmpp
+from slixmpp.exceptions import IqError, IqTimeout
-# 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
-
-class IBBSender(sleekxmpp.ClientXMPP):
+class IBBSender(slixmpp.ClientXMPP):
"""
A basic example of creating and using an in-band bytestream.
"""
- def __init__(self, jid, password, receiver, filename):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ def __init__(self, jid, password, receiver, filename, use_messages=False):
+ slixmpp.ClientXMPP.__init__(self, jid, password)
self.receiver = receiver
- self.filename = filename
+
+ self.file = open(filename, 'rb')
+ self.use_messages = use_messages
# The session_start event will be triggered when
# the bot establishes its connection with the server
@@ -46,6 +39,7 @@ class IBBSender(sleekxmpp.ClientXMPP):
# our roster.
self.add_event_handler("session_start", self.start)
+ @asyncio.coroutine
def start(self, event):
"""
Process the session_start event.
@@ -62,84 +56,70 @@ class IBBSender(sleekxmpp.ClientXMPP):
self.send_presence()
self.get_roster()
- # For the purpose of demonstration, we'll set a very small block
- # size. The default block size is 4096. We'll also use a window
- # allowing sending multiple blocks at a time; in this case, three
- # block transfers may be in progress at any time.
- stream = self['xep_0047'].open_stream(self.receiver)
+ try:
+ # Open the IBB stream in which to write to.
+ stream = yield from self['xep_0047'].open_stream(self.receiver, use_messages=self.use_messages)
+
+ # If you want to send in-memory bytes, use stream.sendall() instead.
+ yield from stream.sendfile(self.file, timeout=10)
- with open(self.filename) as f:
- data = f.read()
- stream.sendall(data)
+ # And finally close the stream.
+ yield from stream.close(timeout=10)
+ except (IqError, IqTimeout):
+ print('File transfer errored')
+ else:
+ print('File transfer finished')
+ finally:
+ self.file.close()
+ self.disconnect()
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
- optp.add_option("-r", "--receiver", dest="receiver",
- help="JID to use")
- optp.add_option("-f", "--file", dest="filename",
- help="JID to use")
-
- opts, args = optp.parse_args()
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("-r", "--receiver", dest="receiver",
+ help="JID of the receiver")
+ parser.add_argument("-f", "--file", dest="filename",
+ help="file to send")
+ parser.add_argument("-m", "--use-messages", action="store_true",
+ help="use messages instead of iqs for file transfer")
+
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
- if opts.receiver is None:
- opts.receiver = raw_input("Receiver: ")
- if opts.filename is None:
- opts.filename = raw_input("File path: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+ if args.receiver is None:
+ args.receiver = input("Receiver: ")
+ if args.filename is None:
+ args.filename = input("File path: ")
- # Setup the EchoBot and register plugins. Note that while plugins may
+ # Setup the IBBSender and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
- xmpp = IBBSender(opts.jid, opts.password, opts.receiver, opts.filename)
+ xmpp = IBBSender(args.jid, args.password, args.receiver, args.filename, args.use_messages)
xmpp.register_plugin('xep_0030') # Service Discovery
- xmpp.register_plugin('xep_0004') # Data Forms
xmpp.register_plugin('xep_0047') # In-band Bytestreams
- xmpp.register_plugin('xep_0060') # PubSub
- xmpp.register_plugin('xep_0199') # XMPP Ping
-
- # 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"
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process(forever=False)
diff --git a/examples/migrate_roster.py b/examples/migrate_roster.py
index 9f679523..d599b10c 100755
--- a/examples/migrate_roster.py
+++ b/examples/migrate_roster.py
@@ -1,68 +1,55 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-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
+import slixmpp
# Setup the command line arguments.
-optp = OptionParser()
+parser = ArgumentParser()
# 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)
+parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, 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")
+parser.add_argument("--oldjid", dest="old_jid",
+ help="JID of the old account")
+parser.add_argument("--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")
+parser.add_argument("--newjid", dest="new_jid",
+ help="JID of the old account")
+parser.add_argument("--newpassword", dest="new_password",
+ help="password of the old account")
-opts, args = optp.parse_args()
+args = parser.parse_args()
# Setup logging.
-logging.basicConfig(level=opts.loglevel,
+logging.basicConfig(level=args.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 args.old_jid is None:
+ args.old_jid = input("Old JID: ")
+if args.old_password is None:
+ args.old_password = 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: ")
+if args.new_jid is None:
+ args.new_jid = input("New JID: ")
+if args.new_password is None:
+ args.new_password = getpass("New Password: ")
-old_xmpp = sleekxmpp.ClientXMPP(opts.old_jid, opts.old_password)
+old_xmpp = slixmpp.ClientXMPP(args.old_jid, args.old_password)
# If you are connecting to Facebook and wish to use the
# X-FACEBOOK-PLATFORM authentication mechanism, you will need
@@ -98,7 +85,7 @@ if not roster:
print('No roster to migrate')
sys.exit()
-new_xmpp = sleekxmpp.ClientXMPP(opts.new_jid, opts.new_password)
+new_xmpp = slixmpp.ClientXMPP(args.new_jid, args.new_password)
def on_session2(event):
new_xmpp.get_roster()
new_xmpp.send_presence()
@@ -116,5 +103,5 @@ def on_session2(event):
new_xmpp.disconnect()
new_xmpp.add_event_handler('session_start', on_session2)
-if new_xmpp.connect():
- new_xmpp.process(block=True)
+new_xmpp.connect()
+new_xmpp.process()
diff --git a/examples/muc.py b/examples/muc.py
index 5b5c764c..5f18a143 100755
--- a/examples/muc.py
+++ b/examples/muc.py
@@ -1,42 +1,31 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
+import slixmpp
-# 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
-
-class MUCBot(sleekxmpp.ClientXMPP):
+class MUCBot(slixmpp.ClientXMPP):
"""
- A simple SleekXMPP bot that will greets those
+ A simple Slixmpp bot that will greets those
who enter the room, and acknowledge any messages
that mentions the bot's nickname.
"""
def __init__(self, jid, password, room, nick):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
self.room = room
self.nick = nick
@@ -132,62 +121,49 @@ class MUCBot(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
- optp.add_option("-r", "--room", dest="room",
- help="MUC room to join")
- optp.add_option("-n", "--nick", dest="nick",
- help="MUC nickname")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("-r", "--room", dest="room",
+ help="MUC room to join")
+ parser.add_argument("-n", "--nick", dest="nick",
+ help="MUC nickname")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
- if opts.room is None:
- opts.room = raw_input("MUC room: ")
- if opts.nick is None:
- opts.nick = raw_input("MUC nickname: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+ if args.room is None:
+ args.room = input("MUC room: ")
+ if args.nick is None:
+ args.nick = input("MUC nickname: ")
# Setup the MUCBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
- xmpp = MUCBot(opts.jid, opts.password, opts.room, opts.nick)
+ xmpp = MUCBot(args.jid, args.password, args.room, args.nick)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0045') # Multi-User Chat
xmpp.register_plugin('xep_0199') # XMPP Ping
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/ping.py b/examples/ping.py
index 1a1c2e94..39118ac4 100755
--- a/examples/ping.py
+++ b/examples/ping.py
@@ -1,41 +1,32 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
+from slixmpp.exceptions import IqError, IqTimeout
+from slixmpp import asyncio
-import sleekxmpp
+import slixmpp
-# 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
-
-class PingTest(sleekxmpp.ClientXMPP):
+class PingTest(slixmpp.ClientXMPP):
"""
- A simple SleekXMPP bot that will send a ping request
+ A simple Slixmpp bot that will send a ping request
to a given JID.
"""
def __init__(self, jid, password, pingjid):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
if pingjid is None:
pingjid = self.boundjid.bare
self.pingjid = pingjid
@@ -45,8 +36,9 @@ class PingTest(sleekxmpp.ClientXMPP):
# and the XML streams are ready for use. We want to
# listen for this event so that we we can initialize
# our roster.
- self.add_event_handler("session_start", self.start, threaded=True)
+ self.add_event_handler("session_start", self.start)
+ @asyncio.coroutine
def start(self, event):
"""
Process the session_start event.
@@ -64,8 +56,8 @@ class PingTest(sleekxmpp.ClientXMPP):
self.get_roster()
try:
- rtt = self['xep_0199'].ping(self.pingjid,
- timeout=10)
+ rtt = yield from self['xep_0199'].ping(self.pingjid,
+ timeout=10)
logging.info("Success! RTT: %s", rtt)
except IqError as e:
logging.info("Error pinging %s: %s",
@@ -79,65 +71,44 @@ class PingTest(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
+ parser.add_argument("-t", "--pingto", help="set jid to ping",
+ 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")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
# Setup the PingTest and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
- xmpp = PingTest(opts.jid, opts.password, opts.pingjid)
+ xmpp = PingTest(args.jid, args.password, args.pingjid)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0004') # Data Forms
xmpp.register_plugin('xep_0060') # PubSub
xmpp.register_plugin('xep_0199') # XMPP Ping
- # 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"
-
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/proxy_echo_client.py b/examples/proxy_echo_client.py
index 98935b9c..b149de31 100755
--- a/examples/proxy_echo_client.py
+++ b/examples/proxy_echo_client.py
@@ -1,41 +1,30 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
+import slixmpp
-# 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
-
-class EchoBot(sleekxmpp.ClientXMPP):
+class EchoBot(slixmpp.ClientXMPP):
"""
- A simple SleekXMPP bot that will echo messages it
+ A simple Slixmpp bot that will echo messages it
receives, along with a short thank you message.
"""
def __init__(self, jid, password):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
# The session_start event will be triggered when
# the bot establishes its connection with the server
@@ -82,87 +71,65 @@ class EchoBot(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
- optp.add_option("--phost", dest="proxy_host",
- help="Proxy hostname")
- optp.add_option("--pport", dest="proxy_port",
- help="Proxy port")
- optp.add_option("--puser", dest="proxy_user",
- help="Proxy username")
- optp.add_option("--ppass", dest="proxy_pass",
- help="Proxy password")
-
-
-
- opts, args = optp.parse_args()
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("--phost", dest="proxy_host",
+ help="Proxy hostname")
+ parser.add_argument("--pport", dest="proxy_port",
+ help="Proxy port")
+ parser.add_argument("--puser", dest="proxy_user",
+ help="Proxy username")
+ parser.add_argument("--ppass", dest="proxy_pass",
+ help="Proxy password")
+
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
- if opts.proxy_host is None:
- opts.proxy_host = raw_input("Proxy host: ")
- if opts.proxy_port is None:
- opts.proxy_port = raw_input("Proxy port: ")
- if opts.proxy_user is None:
- opts.proxy_user = raw_input("Proxy username: ")
- if opts.proxy_pass is None and opts.proxy_user:
- opts.proxy_pass = getpass.getpass("Proxy password: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+ if args.proxy_host is None:
+ args.proxy_host = input("Proxy host: ")
+ if args.proxy_port is None:
+ args.proxy_port = input("Proxy port: ")
+ if args.proxy_user is None:
+ args.proxy_user = input("Proxy username: ")
+ if args.proxy_pass is None and args.proxy_user:
+ args.proxy_pass = getpass("Proxy password: ")
# Setup the EchoBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
- xmpp = EchoBot(opts.jid, opts.password)
+ xmpp = EchoBot(args.jid, args.password)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0004') # Data Forms
xmpp.register_plugin('xep_0060') # PubSub
xmpp.register_plugin('xep_0199') # XMPP Ping
- # 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"
-
xmpp.use_proxy = True
xmpp.proxy_config = {
- 'host': opts.proxy_host,
- 'port': int(opts.proxy_port),
- 'username': opts.proxy_user,
- 'password': opts.proxy_pass}
+ 'host': args.proxy_host,
+ 'port': int(args.proxy_port),
+ 'username': args.proxy_user,
+ 'password': args.proxy_pass}
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/pubsub_client.py b/examples/pubsub_client.py
index 9a65553b..c5688750 100755
--- a/examples/pubsub_client.py
+++ b/examples/pubsub_client.py
@@ -1,30 +1,20 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
-from sleekxmpp.xmlstream import ET, tostring
+import asyncio
+import slixmpp
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream import ET, tostring
-# 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
-
-
-class PubsubClient(sleekxmpp.ClientXMPP):
+class PubsubClient(slixmpp.ClientXMPP):
def __init__(self, jid, password, server,
- node=None, action='list', data=''):
+ node=None, action='nodes', data=''):
super(PubsubClient, self).__init__(jid, password)
self.register_plugin('xep_0030')
@@ -40,162 +30,137 @@ class PubsubClient(sleekxmpp.ClientXMPP):
self.data = data
self.pubsub_server = server
- self.add_event_handler('session_start', self.start, threaded=True)
+ self.add_event_handler('session_start', self.start)
+ @asyncio.coroutine
def start(self, event):
self.get_roster()
self.send_presence()
try:
- getattr(self, self.action)()
+ yield from getattr(self, self.action)()
except:
- logging.error('Could not execute: %s' % self.action)
+ logging.error('Could not execute: %s', self.action)
self.disconnect()
def nodes(self):
try:
- result = self['xep_0060'].get_nodes(self.pubsub_server, self.node)
+ result = yield from self['xep_0060'].get_nodes(self.pubsub_server, self.node)
for item in result['disco_items']['items']:
- print(' - %s' % str(item))
- except:
- logging.error('Could not retrieve node list.')
+ logging.info(' - %s', str(item))
+ except XMPPError as error:
+ logging.error('Could not retrieve node list: %s', error.format())
def create(self):
try:
- self['xep_0060'].create_node(self.pubsub_server, self.node)
- except:
- logging.error('Could not create node: %s' % self.node)
+ yield from self['xep_0060'].create_node(self.pubsub_server, self.node)
+ logging.info('Created node %s', self.node)
+ except XMPPError as error:
+ logging.error('Could not create node %s: %s', self.node, error.format())
def delete(self):
try:
- self['xep_0060'].delete_node(self.pubsub_server, self.node)
- print('Deleted node: %s' % self.node)
- except:
- logging.error('Could not delete node: %s' % self.node)
+ yield from self['xep_0060'].delete_node(self.pubsub_server, self.node)
+ logging.info('Deleted node %s', self.node)
+ except XMPPError as error:
+ logging.error('Could not delete node %s: %s', self.node, error.format())
def publish(self):
payload = ET.fromstring("<test xmlns='test'>%s</test>" % self.data)
try:
- result = self['xep_0060'].publish(self.pubsub_server, self.node, payload=payload)
- id = result['pubsub']['publish']['item']['id']
- print('Published at item id: %s' % id)
- except:
- logging.error('Could not publish to: %s' % self.node)
+ result = yield from self['xep_0060'].publish(self.pubsub_server, self.node, payload=payload)
+ logging.info('Published at item id: %s', result['pubsub']['publish']['item']['id'])
+ except XMPPError as error:
+ logging.error('Could not publish to %s: %s', self.node, error.format())
def get(self):
try:
- result = self['xep_0060'].get_item(self.pubsub_server, self.node, self.data)
+ result = yield from self['xep_0060'].get_item(self.pubsub_server, self.node, self.data)
for item in result['pubsub']['items']['substanzas']:
- print('Retrieved item %s: %s' % (item['id'], tostring(item['payload'])))
- except:
- logging.error('Could not retrieve item %s from node %s' % (self.data, self.node))
+ logging.info('Retrieved item %s: %s', item['id'], tostring(item['payload']))
+ except XMPPError as error:
+ logging.error('Could not retrieve item %s from node %s: %s', self.data, self.node, error.format())
def retract(self):
try:
- result = self['xep_0060'].retract(self.pubsub_server, self.node, self.data)
- print('Retracted item %s from node %s' % (self.data, self.node))
- except:
- logging.error('Could not retract item %s from node %s' % (self.data, self.node))
+ yield from self['xep_0060'].retract(self.pubsub_server, self.node, self.data)
+ logging.info('Retracted item %s from node %s', self.data, self.node)
+ except XMPPError as error:
+ logging.error('Could not retract item %s from node %s: %s', self.data, self.node, error.format())
def purge(self):
try:
- result = self['xep_0060'].purge(self.pubsub_server, self.node)
- print('Purged all items from node %s' % self.node)
- except:
- logging.error('Could not purge items from node %s' % self.node)
+ yield from self['xep_0060'].purge(self.pubsub_server, self.node)
+ logging.info('Purged all items from node %s', self.node)
+ except XMPPError as error:
+ logging.error('Could not purge items from node %s: %s', self.node, error.format())
def subscribe(self):
try:
- result = self['xep_0060'].subscribe(self.pubsub_server, self.node)
- print('Subscribed %s to node %s' % (self.boundjid.bare, self.node))
- except:
- logging.error('Could not subscribe %s to node %s' % (self.boundjid.bare, self.node))
+ iq = yield from self['xep_0060'].subscribe(self.pubsub_server, self.node)
+ subscription = iq['pubsub']['subscription']
+ logging.info('Subscribed %s to node %s', subscription['jid'], subscription['node'])
+ except XMPPError as error:
+ logging.error('Could not subscribe %s to node %s: %s', self.boundjid.bare, self.node, error.format())
def unsubscribe(self):
try:
- result = self['xep_0060'].unsubscribe(self.pubsub_server, self.node)
- print('Unsubscribed %s from node %s' % (self.boundjid.bare, self.node))
- except:
- logging.error('Could not unsubscribe %s from node %s' % (self.boundjid.bare, self.node))
+ yield from self['xep_0060'].unsubscribe(self.pubsub_server, self.node)
+ logging.info('Unsubscribed %s from node %s', self.boundjid.bare, self.node)
+ except XMPPError as error:
+ logging.error('Could not unsubscribe %s from node %s: %s', self.boundjid.bare, self.node, error.format())
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
- optp.version = '%%prog 0.1'
- optp.usage = "Usage: %%prog [options] <jid> " + \
+ parser = ArgumentParser()
+ parser.version = '%%prog 0.1'
+ parser.usage = "Usage: %%prog [options] <jid> " + \
'nodes|create|delete|purge|subscribe|unsubscribe|publish|retract|get' + \
' [<node> <data>]'
- optp.add_option('-q','--quiet', help='set logging to ERROR',
- action='store_const',
- dest='loglevel',
- const=logging.ERROR,
- default=logging.ERROR)
- optp.add_option('-d','--debug', help='set logging to DEBUG',
- action='store_const',
- dest='loglevel',
- const=logging.DEBUG,
- default=logging.ERROR)
- optp.add_option('-v','--verbose', help='set logging to COMM',
- action='store_const',
- dest='loglevel',
- const=5,
- default=logging.ERROR)
+ parser.add_argument("-q","--quiet", help="set logging to ERROR",
+ action="store_const",
+ dest="loglevel",
+ const=logging.ERROR,
+ default=logging.INFO)
+ parser.add_argument("-d","--debug", help="set logging to DEBUG",
+ action="store_const",
+ dest="loglevel",
+ const=logging.DEBUG,
+ default=logging.INFO)
# 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")
- opts,args = optp.parse_args()
-
- # Setup logging.
- logging.basicConfig(level=opts.loglevel,
- format='%(levelname)-8s %(message)s')
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
- if len(args) < 2:
- optp.print_help()
- exit()
+ parser.add_argument("server")
+ parser.add_argument("action", choices=["nodes", "create", "delete", "purge", "subscribe", "unsubscribe", "publish", "retract", "get"])
+ parser.add_argument("node", nargs='?')
+ parser.add_argument("data", nargs='?')
- if opts.jid is None:
- opts.jid = raw_input("Username: ")
- if opts.password is None:
- opts.password = getpass.getpass("Password: ")
+ args = parser.parse_args()
- if len(args) == 2:
- args = (args[0], args[1], '', '', '')
- elif len(args) == 3:
- args = (args[0], args[1], args[2], '', '')
- elif len(args) == 4:
- args = (args[0], args[1], args[2], args[3], '')
+ # Setup logging.
+ logging.basicConfig(level=args.loglevel,
+ format='%(levelname)-8s %(message)s')
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
# Setup the Pubsub client
- xmpp = PubsubClient(opts.jid, opts.password,
- server=args[0],
- node=args[2],
- action=args[1],
- data=args[3])
-
- # 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"
+ xmpp = PubsubClient(args.jid, args.password,
+ server=args.server,
+ node=args.node,
+ action=args.action,
+ data=args.data)
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process(forever=False)
diff --git a/examples/pubsub_events.py b/examples/pubsub_events.py
index 12c33a76..369d7114 100755
--- a/examples/pubsub_events.py
+++ b/examples/pubsub_events.py
@@ -1,29 +1,17 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
-from sleekxmpp.xmlstream import ET, tostring
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream.handler import Callback
+import slixmpp
+from slixmpp.xmlstream import ET, tostring
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream.handler import Callback
-# 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
-
-
-class PubsubEvents(sleekxmpp.ClientXMPP):
+class PubsubEvents(slixmpp.ClientXMPP):
def __init__(self, jid, password):
super(PubsubEvents, self).__init__(jid, password)
@@ -96,59 +84,39 @@ class PubsubEvents(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
logging.info("Run this in conjunction with the pubsub_client.py " + \
"example to watch events happen as you give commands.")
# Setup the PubsubEvents listener
- xmpp = PubsubEvents(opts.jid, opts.password)
-
- # 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"
+ xmpp = PubsubEvents(args.jid, args.password)
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/register_account.py b/examples/register_account.py
index 422e5602..8ec238e9 100755
--- a/examples/register_account.py
+++ b/examples/register_account.py
@@ -1,34 +1,23 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
-from sleekxmpp.exceptions import IqError, IqTimeout
+import slixmpp
+from slixmpp.exceptions import IqError, IqTimeout
-# 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
-
-class RegisterBot(sleekxmpp.ClientXMPP):
+class RegisterBot(slixmpp.ClientXMPP):
"""
A basic bot that will attempt to register an account
@@ -40,23 +29,23 @@ class RegisterBot(sleekxmpp.ClientXMPP):
"""
def __init__(self, jid, password):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
# The session_start event will be triggered when
# the bot establishes its connection with the server
# and the XML streams are ready for use. We want to
# listen for this event so that we we can initialize
# our roster.
- self.add_event_handler("session_start", self.start, threaded=True)
+ self.add_event_handler("session_start", self.start)
# 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
# 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
+ # and respond accordingly. Slixmpp provides plugins
# for data forms and OOB links that will make that easier.
- self.add_event_handler("register", self.register, threaded=True)
+ self.add_event_handler("register", self.register)
def start(self, event):
"""
@@ -101,7 +90,7 @@ class RegisterBot(sleekxmpp.ClientXMPP):
resp['register']['password'] = self.password
try:
- resp.send(now=True)
+ yield from resp.send()
logging.info("Account created for %s!" % self.boundjid)
except IqError as e:
logging.error("Could not register account: %s" %
@@ -114,40 +103,37 @@ class RegisterBot(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
# Setup the RegisterBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
- xmpp = RegisterBot(opts.jid, opts.password)
+ xmpp = RegisterBot(args.jid, args.password)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0004') # Data forms
xmpp.register_plugin('xep_0066') # Out-of-band Data
@@ -157,23 +143,6 @@ if __name__ == '__main__':
# 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
-
- # If you want to verify the SSL certificates offered by a server:
- # xmpp.ca_certs = "path/to/ca/cert"
-
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/roster_browser.py b/examples/roster_browser.py
index a16de24c..eb92ad2a 100755
--- a/examples/roster_browser.py
+++ b/examples/roster_browser.py
@@ -1,36 +1,24 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-import threading
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
-from sleekxmpp.exceptions import IqError, IqTimeout
+import slixmpp
+from slixmpp.exceptions import IqError, IqTimeout
+from slixmpp.xmlstream.asyncio import asyncio
-# 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
-
-
-class RosterBrowser(sleekxmpp.ClientXMPP):
+class RosterBrowser(slixmpp.ClientXMPP):
"""
A basic script for dumping a client's roster to
@@ -38,20 +26,19 @@ class RosterBrowser(sleekxmpp.ClientXMPP):
"""
def __init__(self, jid, password):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
# The session_start event will be triggered when
# the bot establishes its connection with the server
# and the XML streams are ready for use. We want to
# listen for this event so that we we can initialize
- # our roster. We need threaded=True so that the
- # session_start handler doesn't block event processing
- # while we wait for presence stanzas to arrive.
- self.add_event_handler("session_start", self.start, threaded=True)
+ # our roster.
+ self.add_event_handler("session_start", self.start)
self.add_event_handler("changed_status", self.wait_for_presences)
self.received = set()
- self.presences_received = threading.Event()
+ self.presences_received = asyncio.Event()
+ @asyncio.coroutine
def start(self, event):
"""
Process the session_start event.
@@ -65,8 +52,12 @@ class RosterBrowser(sleekxmpp.ClientXMPP):
event does not provide any additional
data.
"""
+ future = asyncio.Future()
+ def callback(result):
+ future.set_result(None)
try:
- self.get_roster()
+ self.get_roster(callback=callback)
+ yield from future
except IqError as err:
print('Error: %s' % err.iq['error']['condition'])
except IqTimeout:
@@ -75,7 +66,7 @@ class RosterBrowser(sleekxmpp.ClientXMPP):
print('Waiting for presence updates...\n')
- self.presences_received.wait(5)
+ yield from asyncio.sleep(10)
print('Roster for %s' % self.boundjid.bare)
groups = self.client_roster.groups()
@@ -115,58 +106,37 @@ class RosterBrowser(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
- optp.add_option('-q','--quiet', help='set logging to ERROR',
- action='store_const',
- dest='loglevel',
- const=logging.ERROR,
- default=logging.ERROR)
- optp.add_option('-d','--debug', help='set logging to DEBUG',
- action='store_const',
- dest='loglevel',
- const=logging.DEBUG,
- default=logging.ERROR)
- optp.add_option('-v','--verbose', help='set logging to COMM',
- action='store_const',
- dest='loglevel',
- const=5,
- default=logging.ERROR)
+ parser = ArgumentParser()
+ parser.add_argument("-q","--quiet", help="set logging to ERROR",
+ action="store_const",
+ dest="loglevel",
+ const=logging.ERROR,
+ default=logging.ERROR)
+ parser.add_argument("-d","--debug", help="set logging to DEBUG",
+ action="store_const",
+ dest="loglevel",
+ const=logging.DEBUG,
+ default=logging.ERROR)
# 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")
- opts,args = optp.parse_args()
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
- xmpp = RosterBrowser(opts.jid, opts.password)
-
- # 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"
+ xmpp = RosterBrowser(args.jid, args.password)
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- else:
- print("Unable to connect.")
-
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/rpc_async.py b/examples/rpc_async.py
index e3e23b69..f773a8d1 100755
--- a/examples/rpc_async.py
+++ b/examples/rpc_async.py
@@ -1,15 +1,15 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Dann Martens
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins.xep_0009.remote import Endpoint, remote, Remote, \
+from slixmpp.plugins.xep_0009.remote import Endpoint, remote, Remote, \
ANY_ALL, Future
import time
@@ -20,7 +20,7 @@ class Boomerang(Endpoint):
@remote
def throw(self):
- print "Duck!"
+ print("Duck!")
diff --git a/examples/rpc_client_side.py b/examples/rpc_client_side.py
index e792fc94..0a4ba015 100755
--- a/examples/rpc_client_side.py
+++ b/examples/rpc_client_side.py
@@ -1,15 +1,15 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Dann Martens
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins.xep_0009.remote import Endpoint, remote, Remote, \
+from slixmpp.plugins.xep_0009.remote import Endpoint, remote, Remote, \
ANY_ALL
import threading
import time
diff --git a/examples/rpc_server_side.py b/examples/rpc_server_side.py
index 9e8b48d6..b973e53b 100755
--- a/examples/rpc_server_side.py
+++ b/examples/rpc_server_side.py
@@ -1,15 +1,15 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Dann Martens
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins.xep_0009.remote import Endpoint, remote, Remote, \
+from slixmpp.plugins.xep_0009.remote import Endpoint, remote, Remote, \
ANY_ALL
import threading
diff --git a/examples/s5b_transfer/s5b_receiver.py b/examples/s5b_transfer/s5b_receiver.py
new file mode 100755
index 00000000..bedeaa04
--- /dev/null
+++ b/examples/s5b_transfer/s5b_receiver.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2015 Emmanuel Gil Peyrot
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+import asyncio
+import logging
+from getpass import getpass
+from argparse import ArgumentParser
+
+import slixmpp
+
+
+class S5BReceiver(slixmpp.ClientXMPP):
+
+ """
+ A basic example of creating and using a SOCKS5 bytestream.
+ """
+
+ def __init__(self, jid, password, filename):
+ slixmpp.ClientXMPP.__init__(self, jid, password)
+
+ self.file = open(filename, 'wb')
+
+ self.add_event_handler("socks5_connected", self.stream_opened)
+ self.add_event_handler("socks5_data", self.stream_data)
+ self.add_event_handler("socks5_closed", self.stream_closed)
+
+ def stream_opened(self, sid):
+ logging.info('Stream opened. %s', sid)
+
+ def stream_data(self, data):
+ self.file.write(data)
+
+ def stream_closed(self, exception):
+ logging.info('Stream closed. %s', exception)
+ self.file.close()
+ self.disconnect()
+
+if __name__ == '__main__':
+ # Setup the command line arguments.
+ parser = ArgumentParser()
+
+ # Output verbosity options.
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
+
+ # JID and password options.
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("-o", "--out", dest="filename",
+ help="file to save to")
+
+ args = parser.parse_args()
+
+ # Setup logging.
+ logging.basicConfig(level=args.loglevel,
+ format='%(levelname)-8s %(message)s')
+
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+ if args.filename is None:
+ args.filename = input("File path: ")
+
+ # Setup the S5BReceiver and register plugins. Note that while plugins may
+ # have interdependencies, the order in which you register them does
+ # not matter.
+ xmpp = S5BReceiver(args.jid, args.password, args.filename)
+ xmpp.register_plugin('xep_0030') # Service Discovery
+ xmpp.register_plugin('xep_0065', {
+ 'auto_accept': True
+ }) # SOCKS5 Bytestreams
+
+ # Connect to the XMPP server and start processing XMPP stanzas.
+ xmpp.connect()
+ xmpp.process(forever=False)
diff --git a/examples/s5b_transfer/s5b_sender.py b/examples/s5b_transfer/s5b_sender.py
new file mode 100755
index 00000000..70a9704f
--- /dev/null
+++ b/examples/s5b_transfer/s5b_sender.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2015 Emmanuel Gil Peyrot
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+import asyncio
+import logging
+from getpass import getpass
+from argparse import ArgumentParser
+
+import slixmpp
+from slixmpp.exceptions import IqError, IqTimeout
+
+
+class S5BSender(slixmpp.ClientXMPP):
+
+ """
+ A basic example of creating and using a SOCKS5 bytestream.
+ """
+
+ def __init__(self, jid, password, receiver, filename):
+ slixmpp.ClientXMPP.__init__(self, jid, password)
+
+ self.receiver = receiver
+
+ self.file = open(filename, 'rb')
+
+ # The session_start event will be triggered when
+ # the bot establishes its connection with the server
+ # and the XML streams are ready for use.
+ self.add_event_handler("session_start", self.start)
+
+ @asyncio.coroutine
+ def start(self, event):
+ """
+ Process the session_start event.
+
+ Typical actions for the session_start event are
+ requesting the roster and broadcasting an initial
+ presence stanza.
+
+ Arguments:
+ event -- An empty dictionary. The session_start
+ event does not provide any additional
+ data.
+ """
+
+ try:
+ # Open the S5B stream in which to write to.
+ proxy = yield from self['xep_0065'].handshake(self.receiver)
+
+ # Send the entire file.
+ while True:
+ data = self.file.read(1048576)
+ if not data:
+ break
+ yield from proxy.write(data)
+
+ # And finally close the stream.
+ proxy.transport.write_eof()
+ except (IqError, IqTimeout):
+ print('File transfer errored')
+ else:
+ print('File transfer finished')
+ finally:
+ self.file.close()
+ self.disconnect()
+
+
+if __name__ == '__main__':
+ # Setup the command line arguments.
+ parser = ArgumentParser()
+
+ # Output verbosity options.
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
+
+ # JID and password options.
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("-r", "--receiver", dest="receiver",
+ help="JID of the receiver")
+ parser.add_argument("-f", "--file", dest="filename",
+ help="file to send")
+ parser.add_argument("-m", "--use-messages", action="store_true",
+ help="use messages instead of iqs for file transfer")
+
+ args = parser.parse_args()
+
+ # Setup logging.
+ logging.basicConfig(level=args.loglevel,
+ format='%(levelname)-8s %(message)s')
+
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+ if args.receiver is None:
+ args.receiver = input("Receiver: ")
+ if args.filename is None:
+ args.filename = input("File path: ")
+
+ # Setup the S5BSender and register plugins. Note that while plugins may
+ # have interdependencies, the order in which you register them does
+ # not matter.
+ xmpp = S5BSender(args.jid, args.password, args.receiver, args.filename)
+ xmpp.register_plugin('xep_0030') # Service Discovery
+ xmpp.register_plugin('xep_0065') # SOCKS5 Bytestreams
+
+ # Connect to the XMPP server and start processing XMPP stanzas.
+ xmpp.connect()
+ xmpp.process(forever=False)
diff --git a/examples/send_client.py b/examples/send_client.py
index 192469ae..6e3e5865 100755
--- a/examples/send_client.py
+++ b/examples/send_client.py
@@ -1,41 +1,30 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
-import sleekxmpp
+import slixmpp
-# 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
-
-class SendMsgBot(sleekxmpp.ClientXMPP):
+class SendMsgBot(slixmpp.ClientXMPP):
"""
- A basic SleekXMPP bot that will log in, send a message,
+ A basic Slixmpp bot that will log in, send a message,
and then log out.
"""
def __init__(self, jid, password, recipient, message):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
# The message we wish to send, and the JID that
# will receive it.
@@ -47,7 +36,7 @@ class SendMsgBot(sleekxmpp.ClientXMPP):
# and the XML streams are ready for use. We want to
# listen for this event so that we we can initialize
# our roster.
- self.add_event_handler("session_start", self.start, threaded=True)
+ self.add_event_handler("session_start", self.start)
def start(self, event):
"""
@@ -69,75 +58,53 @@ class SendMsgBot(sleekxmpp.ClientXMPP):
mbody=self.msg,
mtype='chat')
- # Using wait=True ensures that the send queue will be
- # emptied before ending the session.
- self.disconnect(wait=True)
+ self.disconnect()
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser(description=SendMsgBot.__doc__)
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
- optp.add_option("-t", "--to", dest="to",
- help="JID to send the message to")
- optp.add_option("-m", "--message", dest="message",
- help="message to send")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("-t", "--to", dest="to",
+ help="JID to send the message to")
+ parser.add_argument("-m", "--message", dest="message",
+ help="message to send")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
- if opts.to is None:
- opts.to = raw_input("Send To: ")
- if opts.message is None:
- opts.message = raw_input("Message: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+ if args.to is None:
+ args.to = input("Send To: ")
+ if args.message is None:
+ args.message = input("Message: ")
# Setup the EchoBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
- xmpp = SendMsgBot(opts.jid, opts.password, opts.to, opts.message)
+ xmpp = SendMsgBot(args.jid, args.password, args.to, args.message)
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0199') # XMPP Ping
- # 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"
-
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/set_avatar.py b/examples/set_avatar.py
index 08e0b664..f9641b1e 100755
--- a/examples/set_avatar.py
+++ b/examples/set_avatar.py
@@ -1,50 +1,39 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import os
-import sys
import imghdr
import logging
-import getpass
+from getpass import getpass
import threading
-from optparse import OptionParser
+from argparse import ArgumentParser
-import sleekxmpp
-from sleekxmpp.exceptions import XMPPError
+import slixmpp
+from slixmpp.exceptions import XMPPError
+from slixmpp import asyncio
-
-# 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
-
-
-class AvatarSetter(sleekxmpp.ClientXMPP):
+class AvatarSetter(slixmpp.ClientXMPP):
"""
A basic script for downloading the avatars for a user's contacts.
"""
def __init__(self, jid, password, filepath):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
- self.add_event_handler("session_start", self.start, threaded=True)
+ self.add_event_handler("session_start", self.start)
self.filepath = filepath
+ @asyncio.coroutine
def start(self, event):
"""
Process the session_start event.
@@ -77,32 +66,31 @@ class AvatarSetter(sleekxmpp.ClientXMPP):
avatar_file.close()
used_xep84 = False
- try:
- print('Publish XEP-0084 avatar data')
- self['xep_0084'].publish_avatar(avatar)
- used_xep84 = True
- except XMPPError:
+
+ print('Publish XEP-0084 avatar data')
+ result = yield from self['xep_0084'].publish_avatar(avatar)
+ if isinstance(result, XMPPError):
print('Could not publish XEP-0084 avatar')
+ else:
+ used_xep84 = True
- try:
- print('Update vCard with avatar')
- self['xep_0153'].set_avatar(avatar=avatar, mtype=avatar_type)
- except XMPPError:
+ print('Update vCard with avatar')
+ result = yield from self['xep_0153'].set_avatar(avatar=avatar, mtype=avatar_type)
+ if isinstance(result, XMPPError):
print('Could not set vCard avatar')
if used_xep84:
- try:
- print('Advertise XEP-0084 avatar metadata')
- self['xep_0084'].publish_avatar_metadata([
- {'id': avatar_id,
- 'type': avatar_type,
- 'bytes': avatar_bytes}
- # We could advertise multiple avatars to provide
- # options in image type, source (HTTP vs pubsub),
- # size, etc.
- # {'id': ....}
- ])
- except XMPPError:
+ print('Advertise XEP-0084 avatar metadata')
+ result = yield from self['xep_0084'].publish_avatar_metadata([
+ {'id': avatar_id,
+ 'type': avatar_type,
+ 'bytes': avatar_bytes}
+ # We could advertise multiple avatars to provide
+ # options in image type, source (HTTP vs pubsub),
+ # size, etc.
+ # {'id': ....}
+ ])
+ if isinstance(result, XMPPError):
print('Could not publish XEP-0084 metadata')
print('Wait for presence updates to propagate...')
@@ -111,64 +99,44 @@ class AvatarSetter(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
- optp.add_option('-q','--quiet', help='set logging to ERROR',
- action='store_const',
- dest='loglevel',
- const=logging.ERROR,
- default=logging.ERROR)
- optp.add_option('-d','--debug', help='set logging to DEBUG',
- action='store_const',
- dest='loglevel',
- const=logging.DEBUG,
- default=logging.ERROR)
- optp.add_option('-v','--verbose', help='set logging to COMM',
- action='store_const',
- dest='loglevel',
- const=5,
- default=logging.ERROR)
+ parser = ArgumentParser()
+ parser.add_argument("-q","--quiet", help="set logging to ERROR",
+ action="store_const",
+ dest="loglevel",
+ const=logging.ERROR,
+ default=logging.ERROR)
+ parser.add_argument("-d","--debug", help="set logging to DEBUG",
+ action="store_const",
+ dest="loglevel",
+ const=logging.DEBUG,
+ default=logging.ERROR)
# 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")
- optp.add_option("-f", "--file", dest="filepath",
- help="path to the avatar file")
- opts,args = optp.parse_args()
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
+ parser.add_argument("-f", "--file", dest="filepath",
+ help="path to the avatar file")
+
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
- if opts.filepath is None:
- opts.filepath = raw_input("Avatar file location: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+ if args.filepath is None:
+ args.filepath = input("Avatar file location: ")
- xmpp = AvatarSetter(opts.jid, opts.password, opts.filepath)
+ xmpp = AvatarSetter(args.jid, args.password, args.filepath)
xmpp.register_plugin('xep_0054')
xmpp.register_plugin('xep_0153')
xmpp.register_plugin('xep_0084')
- # 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"
-
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/thirdparty_auth.py b/examples/thirdparty_auth.py
index f4d5c400..4129fa91 100755
--- a/examples/thirdparty_auth.py
+++ b/examples/thirdparty_auth.py
@@ -1,18 +1,18 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
try:
from httplib import HTTPSConnection
@@ -21,24 +21,14 @@ except ImportError:
from urllib.parse import urlencode
from http.client import HTTPSConnection
-import sleekxmpp
-from sleekxmpp.xmlstream import JID
+import slixmpp
+from slixmpp.xmlstream import JID
-# 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
-
-class ThirdPartyAuthBot(sleekxmpp.ClientXMPP):
+class ThirdPartyAuthBot(slixmpp.ClientXMPP):
"""
- A simple SleekXMPP bot that will echo messages it
+ A simple Slixmpp bot that will echo messages it
receives, along with a short thank you message.
This version uses a thirdpary service for authentication,
@@ -46,7 +36,7 @@ class ThirdPartyAuthBot(sleekxmpp.ClientXMPP):
"""
def __init__(self, jid, password):
- sleekxmpp.ClientXMPP.__init__(self, jid, password)
+ slixmpp.ClientXMPP.__init__(self, jid, password)
# The X-GOOGLE-TOKEN mech is ranked lower than PLAIN
# due to Google only allowing a single SASL attempt per
@@ -55,7 +45,7 @@ class ThirdPartyAuthBot(sleekxmpp.ClientXMPP):
# X-GOOGLE-TOKEN with a TLS connection, explicitly select
# it using:
#
- # sleekxmpp.ClientXMPP.__init__(self, jid, password,
+ # slixmpp.ClientXMPP.__init__(self, jid, password,
# sasl_mech="X-GOOGLE-TOKEN")
# The session_start event will be triggered when
@@ -104,37 +94,34 @@ class ThirdPartyAuthBot(sleekxmpp.ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
+
-
access_token = None
# Since documentation on how to work with Google tokens
@@ -156,11 +143,11 @@ if __name__ == '__main__':
params = urlencode({
'accountType': 'GOOGLE',
'service': 'mail',
- 'Email': JID(opts.jid).bare,
- 'Passwd': opts.password
+ 'Email': JID(args.jid).bare,
+ 'Passwd': args.password
})
headers = {
- 'Content-Type': 'application/x-www-form-urlencoded'
+ 'Content-Type': 'application/x-www-form-urlencoded'
}
try:
conn.request('POST', '/accounts/ClientLogin', params, headers)
@@ -208,12 +195,12 @@ if __name__ == '__main__':
# We're using an access token instead of a password, so we'll use `''` as
# a password argument filler.
- xmpp = ThirdPartyAuthBot(opts.jid, '')
+ xmpp = ThirdPartyAuthBot(args.jid, '')
xmpp.credentials['access_token'] = access_token
# The credentials dictionary is used to provide additional authentication
# information beyond just a password.
-
+
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0004') # Data Forms
xmpp.register_plugin('xep_0060') # PubSub
@@ -231,17 +218,7 @@ if __name__ == '__main__':
# xmpp.ca_certs = "path/to/ca/cert"
# Connect to the XMPP server and start processing XMPP stanzas.
- # Google only allows one SASL attempt per connection, so in order to
+ # Google only allows one SASL attempt per connection, so in order to
# enable the X-GOOGLE-TOKEN mechanism, we'll disable TLS.
- if xmpp.connect(use_tls=False):
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/user_location.py b/examples/user_location.py
index 2a64cada..5a30f7af 100755
--- a/examples/user_location.py
+++ b/examples/user_location.py
@@ -1,9 +1,9 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
try:
import json
@@ -16,7 +16,7 @@ except ImportError:
print('This demo requires the requests package for using HTTP.')
sys.exit()
-from sleekxmpp import ClientXMPP
+from slixmpp import ClientXMPP
class LocationBot(ClientXMPP):
@@ -24,8 +24,8 @@ class LocationBot(ClientXMPP):
def __init__(self, jid, password):
super(LocationBot, self).__init__(jid, password)
- self.add_event_handler('session_start', self.start, threaded=True)
- self.add_event_handler('user_location_publish',
+ self.add_event_handler('session_start', self.start)
+ self.add_event_handler('user_location_publish',
self.user_location_publish)
self.register_plugin('xep_0004')
@@ -71,55 +71,35 @@ class LocationBot(ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
- xmpp = LocationBot(opts.jid, opts.password)
-
- # 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"
+ xmpp = LocationBot(args.jid, args.password)
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/examples/user_tune.py b/examples/user_tune.py
index 09e050f0..3f5e1c9e 100755
--- a/examples/user_tune.py
+++ b/examples/user_tune.py
@@ -1,9 +1,9 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
import sys
import logging
-import getpass
-from optparse import OptionParser
+from getpass import getpass
+from argparse import ArgumentParser
try:
from appscript import *
@@ -11,7 +11,7 @@ except ImportError:
print('This demo requires the appscript package to interact with iTunes.')
sys.exit()
-from sleekxmpp import ClientXMPP
+from slixmpp import ClientXMPP
class TuneBot(ClientXMPP):
@@ -83,55 +83,35 @@ class TuneBot(ClientXMPP):
if __name__ == '__main__':
# Setup the command line arguments.
- optp = OptionParser()
+ parser = ArgumentParser()
# 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)
+ parser.add_argument("-q", "--quiet", help="set logging to ERROR",
+ action="store_const", dest="loglevel",
+ const=logging.ERROR, default=logging.INFO)
+ parser.add_argument("-d", "--debug", help="set logging to DEBUG",
+ action="store_const", dest="loglevel",
+ const=logging.DEBUG, default=logging.INFO)
# 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")
+ parser.add_argument("-j", "--jid", dest="jid",
+ help="JID to use")
+ parser.add_argument("-p", "--password", dest="password",
+ help="password to use")
- opts, args = optp.parse_args()
+ args = parser.parse_args()
# Setup logging.
- logging.basicConfig(level=opts.loglevel,
+ logging.basicConfig(level=args.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: ")
+ if args.jid is None:
+ args.jid = input("Username: ")
+ if args.password is None:
+ args.password = getpass("Password: ")
- xmpp = TuneBot(opts.jid, opts.password)
-
- # 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"
+ xmpp = TuneBot(args.jid, args.password)
# Connect to the XMPP server and start processing XMPP stanzas.
- if xmpp.connect():
- # If you do not have the dnspython library installed, you will need
- # to manually specify the name of the server if it does not match
- # the one in the JID. For example, to use Google Talk you would
- # need to use:
- #
- # if xmpp.connect(('talk.google.com', 5222)):
- # ...
- xmpp.process(block=True)
- print("Done")
- else:
- print("Unable to connect.")
+ xmpp.connect()
+ xmpp.process()
diff --git a/ez_setup.py b/ez_setup.py
deleted file mode 100644
index 4b983b1e..00000000
--- a/ez_setup.py
+++ /dev/null
@@ -1,233 +0,0 @@
-#!python
-"""Bootstrap setuptools installation
-
-If you want to use setuptools in your package's setup.py, just include this
-file in the same directory with it, and add this to the top of your setup.py::
-
- from ez_setup import use_setuptools
- use_setuptools()
-
-If you want to require a specific version of setuptools, set a download
-mirror, or use an alternate download directory, you can do so by supplying
-the appropriate options to ``use_setuptools()``.
-
-This file can also be run as a script to install or upgrade setuptools.
-"""
-import sys
-DEFAULT_VERSION = "0.6c7"
-DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
-
-md5_data = {
- 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
- 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
- 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
- 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
- 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
- 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
- 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
- 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
- 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
- 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
- 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
- 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
- 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
- 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
- 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
- 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
- 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
- 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
- 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
- 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
- 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
- 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
- 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
- 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
-}
-
-import sys, os
-
-def _validate_md5(egg_name, data):
- if egg_name in md5_data:
- from md5 import md5
- digest = md5(data).hexdigest()
- if digest != md5_data[egg_name]:
- print >>sys.stderr, (
- "md5 validation of %s failed! (Possible download problem?)"
- % egg_name
- )
- sys.exit(2)
- return data
-
-
-def use_setuptools(
- version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, min_version=None,
- download_delay=15
-):
- """Automatically find/download setuptools and make it available on sys.path
-
- `version` should be a valid setuptools version number that is available
- as an egg for download under the `download_base` URL (which should end with
- a '/'). `to_dir` is the directory where setuptools will be downloaded, if
- it is not already available. If `download_delay` is specified, it should
- be the number of seconds that will be paused before initiating a download,
- should one be required. If an older version of setuptools is installed,
- this routine will print a message to ``sys.stderr`` and raise SystemExit in
- an attempt to abort the calling script.
- """
- try:
- import setuptools
- if setuptools.__version__ == '0.0.1':
- print >>sys.stderr, (
- "You have an obsolete version of setuptools installed. Please\n"
- "remove it from your system entirely before rerunning this script."
- )
- sys.exit(2)
- except ImportError:
- egg = download_setuptools(version, download_base, to_dir, download_delay)
- sys.path.insert(0, egg)
- import setuptools; setuptools.bootstrap_install_from = egg
-
- import pkg_resources
- try:
- if not min_version:
- min_version = version
- pkg_resources.require("setuptools>="+min_version)
-
- except pkg_resources.VersionConflict, e:
- # XXX could we install in a subprocess here?
- print >>sys.stderr, (
- "The required version of setuptools (>=%s) is not available, and\n"
- "can't be installed while this script is running. Please install\n"
- " a more recent version first.\n\n(Currently using %r)"
- ) % (min_version, e.args[0])
- sys.exit(2)
-
-def download_setuptools(
- version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
- delay = 15
-):
- """Download setuptools from a specified location and return its filename
-
- `version` should be a valid setuptools version number that is available
- as an egg for download under the `download_base` URL (which should end
- with a '/'). `to_dir` is the directory where the egg will be downloaded.
- `delay` is the number of seconds to pause before an actual download attempt.
- """
- import urllib2, shutil
- egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
- url = download_base + egg_name
- saveto = os.path.join(to_dir, egg_name)
- src = dst = None
- if not os.path.exists(saveto): # Avoid repeated downloads
- try:
- from distutils import log
- if delay:
- log.warn("""
----------------------------------------------------------------------------
-This script requires setuptools version %s to run (even to display
-help). I will attempt to download it for you (from
-%s), but
-you may need to enable firewall access for this script first.
-I will start the download in %d seconds.
-
-(Note: if this machine does not have network access, please obtain the file
-
- %s
-
-and place it in this directory before rerunning this script.)
----------------------------------------------------------------------------""",
- version, download_base, delay, url
- ); from time import sleep; sleep(delay)
- log.warn("Downloading %s", url)
- src = urllib2.urlopen(url)
- # Read/write all in one block, so we don't create a corrupt file
- # if the download is interrupted.
- data = _validate_md5(egg_name, src.read())
- dst = open(saveto,"wb"); dst.write(data)
- finally:
- if src: src.close()
- if dst: dst.close()
- return os.path.realpath(saveto)
-
-def main(argv, version=DEFAULT_VERSION):
- """Install or upgrade setuptools and EasyInstall"""
-
- try:
- import setuptools
- except ImportError:
- egg = None
- try:
- egg = download_setuptools(version, delay=0)
- sys.path.insert(0,egg)
- from setuptools.command.easy_install import main
- return main(list(argv)+[egg]) # we're done here
- finally:
- if egg and os.path.exists(egg):
- os.unlink(egg)
- else:
- if setuptools.__version__ == '0.0.1':
- # tell the user to uninstall obsolete version
- use_setuptools(version)
-
- req = "setuptools>="+version
- import pkg_resources
- try:
- pkg_resources.require(req)
- except pkg_resources.VersionConflict:
- try:
- from setuptools.command.easy_install import main
- except ImportError:
- from easy_install import main
- main(list(argv)+[download_setuptools(delay=0)])
- sys.exit(0) # try to force an exit
- else:
- if argv:
- from setuptools.command.easy_install import main
- main(argv)
- else:
- print "Setuptools version",version,"or greater has been installed."
- print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
-
-
-
-def update_md5(filenames):
- """Update our built-in md5 registry"""
-
- import re
- from md5 import md5
-
- for name in filenames:
- base = os.path.basename(name)
- f = open(name,'rb')
- md5_data[base] = md5(f.read()).hexdigest()
- f.close()
-
- data = [" %r: %r,\n" % it for it in md5_data.items()]
- data.sort()
- repl = "".join(data)
-
- import inspect
- srcfile = inspect.getsourcefile(sys.modules[__name__])
- f = open(srcfile, 'rb'); src = f.read(); f.close()
-
- match = re.search("\nmd5_data = {\n([^}]+)}", src)
- if not match:
- print >>sys.stderr, "Internal error!"
- sys.exit(2)
-
- src = src[:match.start(1)] + repl + src[match.end(1):]
- f = open(srcfile,'w')
- f.write(src)
- f.close()
-
-
-if __name__=='__main__':
- if len(sys.argv)>2 and sys.argv[1]=='--md5update':
- update_md5(sys.argv[2:])
- else:
- main(sys.argv[1:])
-
-
-
-
-
diff --git a/run_tests.py b/run_tests.py
new file mode 100755
index 00000000..3b9df045
--- /dev/null
+++ b/run_tests.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+
+import sys
+import logging
+import unittest
+
+from argparse import ArgumentParser
+from distutils.core import Command
+from importlib import import_module
+from pathlib import Path
+
+
+def run_tests(filenames=None):
+ """
+ Find and run all tests in the tests/ directory.
+
+ Excludes live tests (tests/live_*).
+ """
+ if not filenames:
+ filenames = [i for i in Path('tests').glob('test_*')]
+ else:
+ filenames = [Path(i) for i in filenames]
+
+ modules = ['.'.join(test.parts[:-1] + (test.stem,)) for test in filenames]
+
+ suites = []
+ for filename in modules:
+ module = import_module(filename)
+ suites.append(module.suite)
+
+ tests = unittest.TestSuite(suites)
+ runner = unittest.TextTestRunner(verbosity=2)
+
+ # Disable logging output
+ logging.basicConfig(level=100)
+ logging.disable(100)
+
+ result = runner.run(tests)
+ return result
+
+
+# Add a 'test' command for setup.py
+
+class TestCommand(Command):
+
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ run_tests()
+
+
+if __name__ == '__main__':
+ parser = ArgumentParser(description='Run unit tests.')
+ parser.add_argument('tests', metavar='TEST', nargs='*', help='list of tests to run, or nothing to run them all')
+ args = parser.parse_args()
+
+ result = run_tests(args.tests)
+ print("<tests %s ran='%s' errors='%s' fails='%s' success='%s'/>" % (
+ "xmlns='http//andyet.net/protocol/tests'",
+ result.testsRun, len(result.errors),
+ len(result.failures), result.wasSuccessful()))
+
+ sys.exit(not result.wasSuccessful())
diff --git a/setup.py b/setup.py
index 1cd245aa..ff5bcfb1 100755
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2007-2011 Nathanael C. Fritz
@@ -7,153 +7,52 @@
# This software is licensed as described in the README.rst and LICENSE
# file, which you should have received as part of this distribution.
-import sys
-import codecs
+from pathlib import Path
try:
- from setuptools import setup, Command
+ from setuptools import setup
except ImportError:
- from distutils.core import setup, Command
-# from ez_setup import use_setuptools
+ from distutils.core import setup
-from testall import TestCommand
-from sleekxmpp.version import __version__
-# if 'cygwin' in sys.platform.lower():
-# min_version = '0.6c6'
-# else:
-# min_version = '0.6a9'
-#
-# try:
-# use_setuptools(min_version=min_version)
-# except TypeError:
-# # locally installed ez_setup won't have min_version
-# use_setuptools()
-#
-# from setuptools import setup, find_packages, Extension, Feature
+try:
+ from Cython.Build import cythonize
+except ImportError:
+ print('Cython not found, falling back to the slow stringprep module.')
+ ext_modules = None
+else:
+ ext_modules = cythonize('slixmpp/stringprep.pyx')
+
+from run_tests import TestCommand
+from slixmpp.version import __version__
-VERSION = __version__
-DESCRIPTION = 'SleekXMPP is an elegant Python library for XMPP (aka Jabber, Google Talk, etc).'
-with codecs.open('README.rst', 'r', encoding='UTF-8') as readme:
- LONG_DESCRIPTION = ''.join(readme)
+VERSION = __version__
+DESCRIPTION = ('Slixmpp is an elegant Python library for XMPP (aka Jabber, '
+ 'Google Talk, etc).')
+with open('README.rst', encoding='utf8') as readme:
+ LONG_DESCRIPTION = readme.read()
-CLASSIFIERS = [ 'Intended Audience :: Developers',
- 'License :: OSI Approved :: MIT License',
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 2.6',
- 'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3.1',
- 'Programming Language :: Python :: 3.2',
- 'Programming Language :: Python :: 3.3',
- 'Topic :: Software Development :: Libraries :: Python Modules',
- ]
+CLASSIFIERS = [
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: MIT License',
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 3.4',
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+]
-packages = [ 'sleekxmpp',
- 'sleekxmpp/stanza',
- 'sleekxmpp/test',
- 'sleekxmpp/roster',
- 'sleekxmpp/util',
- 'sleekxmpp/util/sasl',
- 'sleekxmpp/xmlstream',
- 'sleekxmpp/xmlstream/matcher',
- 'sleekxmpp/xmlstream/handler',
- 'sleekxmpp/plugins',
- 'sleekxmpp/plugins/xep_0004',
- 'sleekxmpp/plugins/xep_0004/stanza',
- 'sleekxmpp/plugins/xep_0009',
- 'sleekxmpp/plugins/xep_0009/stanza',
- 'sleekxmpp/plugins/xep_0012',
- 'sleekxmpp/plugins/xep_0013',
- 'sleekxmpp/plugins/xep_0016',
- 'sleekxmpp/plugins/xep_0020',
- 'sleekxmpp/plugins/xep_0027',
- 'sleekxmpp/plugins/xep_0030',
- 'sleekxmpp/plugins/xep_0030/stanza',
- 'sleekxmpp/plugins/xep_0033',
- 'sleekxmpp/plugins/xep_0047',
- 'sleekxmpp/plugins/xep_0048',
- 'sleekxmpp/plugins/xep_0049',
- 'sleekxmpp/plugins/xep_0050',
- 'sleekxmpp/plugins/xep_0054',
- 'sleekxmpp/plugins/xep_0059',
- 'sleekxmpp/plugins/xep_0060',
- 'sleekxmpp/plugins/xep_0060/stanza',
- 'sleekxmpp/plugins/xep_0065',
- 'sleekxmpp/plugins/xep_0066',
- 'sleekxmpp/plugins/xep_0071',
- 'sleekxmpp/plugins/xep_0077',
- 'sleekxmpp/plugins/xep_0078',
- 'sleekxmpp/plugins/xep_0080',
- 'sleekxmpp/plugins/xep_0084',
- 'sleekxmpp/plugins/xep_0085',
- 'sleekxmpp/plugins/xep_0086',
- 'sleekxmpp/plugins/xep_0091',
- 'sleekxmpp/plugins/xep_0092',
- 'sleekxmpp/plugins/xep_0095',
- 'sleekxmpp/plugins/xep_0096',
- 'sleekxmpp/plugins/xep_0107',
- 'sleekxmpp/plugins/xep_0108',
- 'sleekxmpp/plugins/xep_0115',
- 'sleekxmpp/plugins/xep_0118',
- 'sleekxmpp/plugins/xep_0122',
- 'sleekxmpp/plugins/xep_0128',
- 'sleekxmpp/plugins/xep_0131',
- 'sleekxmpp/plugins/xep_0152',
- 'sleekxmpp/plugins/xep_0153',
- 'sleekxmpp/plugins/xep_0172',
- 'sleekxmpp/plugins/xep_0184',
- 'sleekxmpp/plugins/xep_0186',
- 'sleekxmpp/plugins/xep_0191',
- 'sleekxmpp/plugins/xep_0196',
- 'sleekxmpp/plugins/xep_0198',
- 'sleekxmpp/plugins/xep_0199',
- 'sleekxmpp/plugins/xep_0202',
- 'sleekxmpp/plugins/xep_0203',
- 'sleekxmpp/plugins/xep_0221',
- 'sleekxmpp/plugins/xep_0224',
- 'sleekxmpp/plugins/xep_0231',
- 'sleekxmpp/plugins/xep_0235',
- 'sleekxmpp/plugins/xep_0249',
- 'sleekxmpp/plugins/xep_0257',
- 'sleekxmpp/plugins/xep_0258',
- 'sleekxmpp/plugins/xep_0279',
- 'sleekxmpp/plugins/xep_0280',
- 'sleekxmpp/plugins/xep_0297',
- 'sleekxmpp/plugins/xep_0308',
- 'sleekxmpp/plugins/xep_0313',
- 'sleekxmpp/plugins/xep_0319',
- 'sleekxmpp/plugins/xep_0323',
- 'sleekxmpp/plugins/xep_0323/stanza',
- 'sleekxmpp/plugins/xep_0325',
- 'sleekxmpp/plugins/xep_0325/stanza',
- 'sleekxmpp/plugins/xep_0332',
- 'sleekxmpp/plugins/xep_0332/stanza',
- 'sleekxmpp/plugins/google',
- 'sleekxmpp/plugins/google/gmail',
- 'sleekxmpp/plugins/google/auth',
- 'sleekxmpp/plugins/google/settings',
- 'sleekxmpp/plugins/google/nosave',
- 'sleekxmpp/features',
- 'sleekxmpp/features/feature_mechanisms',
- 'sleekxmpp/features/feature_mechanisms/stanza',
- 'sleekxmpp/features/feature_starttls',
- 'sleekxmpp/features/feature_bind',
- 'sleekxmpp/features/feature_session',
- 'sleekxmpp/features/feature_rosterver',
- 'sleekxmpp/features/feature_preapproval',
- 'sleekxmpp/thirdparty',
- ]
+packages = [str(mod.parent) for mod in Path('slixmpp').rglob('__init__.py')]
setup(
- name = "sleekxmpp",
- version = VERSION,
- description = DESCRIPTION,
- long_description = LONG_DESCRIPTION,
- author = 'Nathanael Fritz',
- author_email = 'fritzy [at] netflint.net',
- url = 'http://github.com/fritzy/SleekXMPP',
- license = 'MIT',
- platforms = [ 'any' ],
- packages = packages,
- requires = [ 'dnspython', 'pyasn1', 'pyasn1_modules' ],
- classifiers = CLASSIFIERS,
- cmdclass = {'test': TestCommand}
+ name="slixmpp",
+ version=VERSION,
+ description=DESCRIPTION,
+ long_description=LONG_DESCRIPTION,
+ author='Florent Le Coz',
+ author_email='louiz@louiz.org',
+ url='https://dev.louiz.org/projects/slixmpp',
+ license='MIT',
+ platforms=['any'],
+ packages=packages,
+ ext_modules=ext_modules,
+ install_requires=['aiodns>=1.0', 'pyasn1', 'pyasn1_modules'],
+ classifiers=CLASSIFIERS,
+ cmdclass={'test': TestCommand}
)
diff --git a/sleekxmpp/__init__.py b/sleekxmpp/__init__.py
deleted file mode 100644
index 85ee32b6..00000000
--- a/sleekxmpp/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-import logging
-if hasattr(logging, 'NullHandler'):
- NullHandler = logging.NullHandler
-else:
- class NullHandler(logging.Handler):
- def handle(self, record):
- pass
-logging.getLogger(__name__).addHandler(NullHandler())
-del NullHandler
-
-
-from sleekxmpp.stanza import Message, Presence, Iq
-from sleekxmpp.jid import JID, InvalidJID
-from sleekxmpp.xmlstream.stanzabase import ET, ElementBase, register_stanza_plugin
-from sleekxmpp.xmlstream.handler import *
-from sleekxmpp.xmlstream import XMLStream, RestartStream
-from sleekxmpp.xmlstream.matcher import *
-from sleekxmpp.basexmpp import BaseXMPP
-from sleekxmpp.clientxmpp import ClientXMPP
-from sleekxmpp.componentxmpp import ComponentXMPP
-
-from sleekxmpp.version import __version__, __version_info__
diff --git a/sleekxmpp/features/feature_bind/__init__.py b/sleekxmpp/features/feature_bind/__init__.py
deleted file mode 100644
index 9e0831dd..00000000
--- a/sleekxmpp/features/feature_bind/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.features.feature_bind.bind import FeatureBind
-from sleekxmpp.features.feature_bind.stanza import Bind
-
-
-register_plugin(FeatureBind)
-
-
-# Retain some backwards compatibility
-feature_bind = FeatureBind
diff --git a/sleekxmpp/features/feature_mechanisms/__init__.py b/sleekxmpp/features/feature_mechanisms/__init__.py
deleted file mode 100644
index 9f7611ed..00000000
--- a/sleekxmpp/features/feature_mechanisms/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.features.feature_mechanisms.mechanisms import FeatureMechanisms
-from sleekxmpp.features.feature_mechanisms.stanza import Mechanisms
-from sleekxmpp.features.feature_mechanisms.stanza import Auth
-from sleekxmpp.features.feature_mechanisms.stanza import Success
-from sleekxmpp.features.feature_mechanisms.stanza import Failure
-
-
-register_plugin(FeatureMechanisms)
-
-
-# Retain some backwards compatibility
-feature_mechanisms = FeatureMechanisms
diff --git a/sleekxmpp/features/feature_mechanisms/stanza/__init__.py b/sleekxmpp/features/feature_mechanisms/stanza/__init__.py
deleted file mode 100644
index 38991d89..00000000
--- a/sleekxmpp/features/feature_mechanisms/stanza/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-
-from sleekxmpp.features.feature_mechanisms.stanza.mechanisms import Mechanisms
-from sleekxmpp.features.feature_mechanisms.stanza.auth import Auth
-from sleekxmpp.features.feature_mechanisms.stanza.success import Success
-from sleekxmpp.features.feature_mechanisms.stanza.failure import Failure
-from sleekxmpp.features.feature_mechanisms.stanza.challenge import Challenge
-from sleekxmpp.features.feature_mechanisms.stanza.response import Response
-from sleekxmpp.features.feature_mechanisms.stanza.abort import Abort
diff --git a/sleekxmpp/features/feature_preapproval/__init__.py b/sleekxmpp/features/feature_preapproval/__init__.py
deleted file mode 100644
index ae8b6b70..00000000
--- a/sleekxmpp/features/feature_preapproval/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.features.feature_preapproval.preapproval import FeaturePreApproval
-from sleekxmpp.features.feature_preapproval.stanza import PreApproval
-
-
-register_plugin(FeaturePreApproval)
diff --git a/sleekxmpp/features/feature_rosterver/__init__.py b/sleekxmpp/features/feature_rosterver/__init__.py
deleted file mode 100644
index 33bbf416..00000000
--- a/sleekxmpp/features/feature_rosterver/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.features.feature_rosterver.rosterver import FeatureRosterVer
-from sleekxmpp.features.feature_rosterver.stanza import RosterVer
-
-
-register_plugin(FeatureRosterVer)
-
-
-# Retain some backwards compatibility
-feature_rosterver = FeatureRosterVer
diff --git a/sleekxmpp/features/feature_session/__init__.py b/sleekxmpp/features/feature_session/__init__.py
deleted file mode 100644
index 28bb3f77..00000000
--- a/sleekxmpp/features/feature_session/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.features.feature_session.session import FeatureSession
-from sleekxmpp.features.feature_session.stanza import Session
-
-
-register_plugin(FeatureSession)
-
-
-# Retain some backwards compatibility
-feature_session = FeatureSession
diff --git a/sleekxmpp/features/feature_starttls/__init__.py b/sleekxmpp/features/feature_starttls/__init__.py
deleted file mode 100644
index 68697ce5..00000000
--- a/sleekxmpp/features/feature_starttls/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.features.feature_starttls.starttls import FeatureSTARTTLS
-from sleekxmpp.features.feature_starttls.stanza import *
-
-
-register_plugin(FeatureSTARTTLS)
-
-
-# Retain some backwards compatibility
-feature_starttls = FeatureSTARTTLS
diff --git a/sleekxmpp/jid.py b/sleekxmpp/jid.py
deleted file mode 100644
index 754a3d3a..00000000
--- a/sleekxmpp/jid.py
+++ /dev/null
@@ -1,632 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- sleekxmpp.jid
- ~~~~~~~~~~~~~~~~~~~~~~~
-
- This module allows for working with Jabber IDs (JIDs).
-
- Part of SleekXMPP: The Sleek XMPP Library
-
- :copyright: (c) 2011 Nathanael C. Fritz
- :license: MIT, see LICENSE for more details
-"""
-
-from __future__ import unicode_literals
-
-import re
-import socket
-import stringprep
-import threading
-import encodings.idna
-
-from copy import deepcopy
-
-from sleekxmpp.util import stringprep_profiles
-from sleekxmpp.thirdparty import OrderedDict
-
-#: These characters are not allowed to appear in a JID.
-ILLEGAL_CHARS = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r' + \
- '\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19' + \
- '\x1a\x1b\x1c\x1d\x1e\x1f' + \
- ' !"#$%&\'()*+,./:;<=>?@[\\]^_`{|}~\x7f'
-
-#: The basic regex pattern that a JID must match in order to determine
-#: the local, domain, and resource parts. This regex does NOT do any
-#: validation, which requires application of nodeprep, resourceprep, etc.
-JID_PATTERN = re.compile(
- "^(?:([^\"&'/:<>@]{1,1023})@)?([^/@]{1,1023})(?:/(.{1,1023}))?$"
-)
-
-#: The set of escape sequences for the characters not allowed by nodeprep.
-JID_ESCAPE_SEQUENCES = set(['\\20', '\\22', '\\26', '\\27', '\\2f',
- '\\3a', '\\3c', '\\3e', '\\40', '\\5c'])
-
-#: A mapping of unallowed characters to their escape sequences. An escape
-#: sequence for '\' is also included since it must also be escaped in
-#: certain situations.
-JID_ESCAPE_TRANSFORMATIONS = {' ': '\\20',
- '"': '\\22',
- '&': '\\26',
- "'": '\\27',
- '/': '\\2f',
- ':': '\\3a',
- '<': '\\3c',
- '>': '\\3e',
- '@': '\\40',
- '\\': '\\5c'}
-
-#: The reverse mapping of escape sequences to their original forms.
-JID_UNESCAPE_TRANSFORMATIONS = {'\\20': ' ',
- '\\22': '"',
- '\\26': '&',
- '\\27': "'",
- '\\2f': '/',
- '\\3a': ':',
- '\\3c': '<',
- '\\3e': '>',
- '\\40': '@',
- '\\5c': '\\'}
-
-JID_CACHE = OrderedDict()
-JID_CACHE_LOCK = threading.Lock()
-JID_CACHE_MAX_SIZE = 1024
-
-def _cache(key, parts, locked):
- with JID_CACHE_LOCK:
- JID_CACHE[key] = (parts, locked)
- while len(JID_CACHE) > JID_CACHE_MAX_SIZE:
- found = None
- for key, item in JID_CACHE.items():
- if not item[1]: # if not locked
- found = key
- break
- if not found: # more than MAX_SIZE locked
- # warn?
- break
- del JID_CACHE[found]
-
-# pylint: disable=c0103
-#: The nodeprep profile of stringprep used to validate the local,
-#: or username, portion of a JID.
-nodeprep = stringprep_profiles.create(
- nfkc=True,
- bidi=True,
- mappings=[
- stringprep_profiles.b1_mapping,
- stringprep.map_table_b2],
- prohibited=[
- stringprep.in_table_c11,
- stringprep.in_table_c12,
- stringprep.in_table_c21,
- stringprep.in_table_c22,
- stringprep.in_table_c3,
- stringprep.in_table_c4,
- stringprep.in_table_c5,
- stringprep.in_table_c6,
- stringprep.in_table_c7,
- stringprep.in_table_c8,
- stringprep.in_table_c9,
- lambda c: c in ' \'"&/:<>@'],
- unassigned=[stringprep.in_table_a1])
-
-# pylint: disable=c0103
-#: The resourceprep profile of stringprep, which is used to validate
-#: the resource portion of a JID.
-resourceprep = stringprep_profiles.create(
- nfkc=True,
- bidi=True,
- mappings=[stringprep_profiles.b1_mapping],
- prohibited=[
- stringprep.in_table_c12,
- stringprep.in_table_c21,
- stringprep.in_table_c22,
- stringprep.in_table_c3,
- stringprep.in_table_c4,
- stringprep.in_table_c5,
- stringprep.in_table_c6,
- stringprep.in_table_c7,
- stringprep.in_table_c8,
- stringprep.in_table_c9],
- unassigned=[stringprep.in_table_a1])
-
-
-def _parse_jid(data):
- """
- Parse string data into the node, domain, and resource
- components of a JID, if possible.
-
- :param string data: A string that is potentially a JID.
-
- :raises InvalidJID:
-
- :returns: tuple of the validated local, domain, and resource strings
- """
- match = JID_PATTERN.match(data)
- if not match:
- raise InvalidJID('JID could not be parsed')
-
- (node, domain, resource) = match.groups()
-
- node = _validate_node(node)
- domain = _validate_domain(domain)
- resource = _validate_resource(resource)
-
- return node, domain, resource
-
-
-def _validate_node(node):
- """Validate the local, or username, portion of a JID.
-
- :raises InvalidJID:
-
- :returns: The local portion of a JID, as validated by nodeprep.
- """
- try:
- if node is not None:
- node = nodeprep(node)
-
- if not node:
- raise InvalidJID('Localpart must not be 0 bytes')
- if len(node) > 1023:
- raise InvalidJID('Localpart must be less than 1024 bytes')
- return node
- except stringprep_profiles.StringPrepError:
- raise InvalidJID('Invalid local part')
-
-
-def _validate_domain(domain):
- """Validate the domain portion of a JID.
-
- IP literal addresses are left as-is, if valid. Domain names
- are stripped of any trailing label separators (`.`), and are
- checked with the nameprep profile of stringprep. If the given
- domain is actually a punyencoded version of a domain name, it
- is converted back into its original Unicode form. Domains must
- also not start or end with a dash (`-`).
-
- :raises InvalidJID:
-
- :returns: The validated domain name
- """
- ip_addr = False
-
- # First, check if this is an IPv4 address
- try:
- socket.inet_aton(domain)
- ip_addr = True
- except socket.error:
- pass
-
- # Check if this is an IPv6 address
- if not ip_addr and hasattr(socket, 'inet_pton'):
- try:
- socket.inet_pton(socket.AF_INET6, domain.strip('[]'))
- domain = '[%s]' % domain.strip('[]')
- ip_addr = True
- except (socket.error, ValueError):
- pass
-
- if not ip_addr:
- # This is a domain name, which must be checked further
-
- if domain and domain[-1] == '.':
- domain = domain[:-1]
-
- domain_parts = []
- for label in domain.split('.'):
- try:
- label = encodings.idna.nameprep(label)
- encodings.idna.ToASCII(label)
- pass_nameprep = True
- except UnicodeError:
- pass_nameprep = False
-
- if not pass_nameprep:
- raise InvalidJID('Could not encode domain as ASCII')
-
- if label.startswith('xn--'):
- label = encodings.idna.ToUnicode(label)
-
- for char in label:
- if char in ILLEGAL_CHARS:
- raise InvalidJID('Domain contains illegal characters')
-
- if '-' in (label[0], label[-1]):
- raise InvalidJID('Domain started or ended with -')
-
- domain_parts.append(label)
- domain = '.'.join(domain_parts)
-
- if not domain:
- raise InvalidJID('Domain must not be 0 bytes')
- if len(domain) > 1023:
- raise InvalidJID('Domain must be less than 1024 bytes')
-
- return domain
-
-
-def _validate_resource(resource):
- """Validate the resource portion of a JID.
-
- :raises InvalidJID:
-
- :returns: The local portion of a JID, as validated by resourceprep.
- """
- try:
- if resource is not None:
- resource = resourceprep(resource)
-
- if not resource:
- raise InvalidJID('Resource must not be 0 bytes')
- if len(resource) > 1023:
- raise InvalidJID('Resource must be less than 1024 bytes')
- return resource
- except stringprep_profiles.StringPrepError:
- raise InvalidJID('Invalid resource')
-
-
-def _escape_node(node):
- """Escape the local portion of a JID."""
- result = []
-
- for i, char in enumerate(node):
- if char == '\\':
- if ''.join((node[i:i+3])) in JID_ESCAPE_SEQUENCES:
- result.append('\\5c')
- continue
- result.append(char)
-
- for i, char in enumerate(result):
- if char != '\\':
- result[i] = JID_ESCAPE_TRANSFORMATIONS.get(char, char)
-
- escaped = ''.join(result)
-
- if escaped.startswith('\\20') or escaped.endswith('\\20'):
- raise InvalidJID('Escaped local part starts or ends with "\\20"')
-
- _validate_node(escaped)
-
- return escaped
-
-
-def _unescape_node(node):
- """Unescape a local portion of a JID.
-
- .. note::
- The unescaped local portion is meant ONLY for presentation,
- and should not be used for other purposes.
- """
- unescaped = []
- seq = ''
- for i, char in enumerate(node):
- if char == '\\':
- seq = node[i:i+3]
- if seq not in JID_ESCAPE_SEQUENCES:
- seq = ''
- if seq:
- if len(seq) == 3:
- unescaped.append(JID_UNESCAPE_TRANSFORMATIONS.get(seq, char))
-
- # Pop character off the escape sequence, and ignore it
- seq = seq[1:]
- else:
- unescaped.append(char)
- unescaped = ''.join(unescaped)
-
- return unescaped
-
-
-def _format_jid(local=None, domain=None, resource=None):
- """Format the given JID components into a full or bare JID.
-
- :param string local: Optional. The local portion of the JID.
- :param string domain: Required. The domain name portion of the JID.
- :param strin resource: Optional. The resource portion of the JID.
-
- :return: A full or bare JID string.
- """
- result = []
- if local:
- result.append(local)
- result.append('@')
- if domain:
- result.append(domain)
- if resource:
- result.append('/')
- result.append(resource)
- return ''.join(result)
-
-
-class InvalidJID(ValueError):
- """
- Raised when attempting to create a JID that does not pass validation.
-
- It can also be raised if modifying an existing JID in such a way as
- to make it invalid, such trying to remove the domain from an existing
- full JID while the local and resource portions still exist.
- """
-
-# pylint: disable=R0903
-class UnescapedJID(object):
-
- """
- .. versionadded:: 1.1.10
- """
-
- def __init__(self, local, domain, resource):
- self._jid = (local, domain, resource)
-
- # pylint: disable=R0911
- def __getattr__(self, name):
- """Retrieve the given JID component.
-
- :param name: one of: user, server, domain, resource,
- full, or bare.
- """
- if name == 'resource':
- return self._jid[2] or ''
- elif name in ('user', 'username', 'local', 'node'):
- return self._jid[0] or ''
- elif name in ('server', 'domain', 'host'):
- return self._jid[1] or ''
- elif name in ('full', 'jid'):
- return _format_jid(*self._jid)
- elif name == 'bare':
- return _format_jid(self._jid[0], self._jid[1])
- elif name == '_jid':
- return getattr(super(JID, self), '_jid')
- else:
- return None
-
- def __str__(self):
- """Use the full JID as the string value."""
- return _format_jid(*self._jid)
-
- def __repr__(self):
- """Use the full JID as the representation."""
- return self.__str__()
-
-
-class JID(object):
-
- """
- A representation of a Jabber ID, or JID.
-
- Each JID may have three components: a user, a domain, and an optional
- resource. For example: user@domain/resource
-
- When a resource is not used, the JID is called a bare JID.
- The JID is a full JID otherwise.
-
- **JID Properties:**
- :jid: Alias for ``full``.
- :full: The string value of the full JID.
- :bare: The string value of the bare JID.
- :user: The username portion of the JID.
- :username: Alias for ``user``.
- :local: Alias for ``user``.
- :node: Alias for ``user``.
- :domain: The domain name portion of the JID.
- :server: Alias for ``domain``.
- :host: Alias for ``domain``.
- :resource: The resource portion of the JID.
-
- :param string jid:
- A string of the form ``'[user@]domain[/resource]'``.
- :param string local:
- Optional. Specify the local, or username, portion
- of the JID. If provided, it will override the local
- value provided by the `jid` parameter. The given
- local value will also be escaped if necessary.
- :param string domain:
- Optional. Specify the domain of the JID. If
- provided, it will override the domain given by
- the `jid` parameter.
- :param string resource:
- Optional. Specify the resource value of the JID.
- If provided, it will override the domain given
- by the `jid` parameter.
-
- :raises InvalidJID:
- """
-
- # pylint: disable=W0212
- def __init__(self, jid=None, **kwargs):
- locked = kwargs.get('cache_lock', False)
- in_local = kwargs.get('local', None)
- in_domain = kwargs.get('domain', None)
- in_resource = kwargs.get('resource', None)
- parts = None
- if in_local or in_domain or in_resource:
- parts = (in_local, in_domain, in_resource)
-
- # only check cache if there is a jid string, or parts, not if there
- # are both
- self._jid = None
- key = None
- if (jid is not None) and (parts is None):
- if isinstance(jid, JID):
- # it's already good to go, and there are no additions
- self._jid = jid._jid
- return
- key = jid
- self._jid, locked = JID_CACHE.get(jid, (None, locked))
- elif jid is None and parts is not None:
- key = parts
- self._jid, locked = JID_CACHE.get(parts, (None, locked))
- if not self._jid:
- if not jid:
- parsed_jid = (None, None, None)
- elif not isinstance(jid, JID):
- parsed_jid = _parse_jid(jid)
- else:
- parsed_jid = jid._jid
-
- local, domain, resource = parsed_jid
-
- if 'local' in kwargs:
- local = _escape_node(in_local)
- if 'domain' in kwargs:
- domain = _validate_domain(in_domain)
- if 'resource' in kwargs:
- resource = _validate_resource(in_resource)
-
- self._jid = (local, domain, resource)
- if key:
- _cache(key, self._jid, locked)
-
- def unescape(self):
- """Return an unescaped JID object.
-
- Using an unescaped JID is preferred for displaying JIDs
- to humans, and they should NOT be used for any other
- purposes than for presentation.
-
- :return: :class:`UnescapedJID`
-
- .. versionadded:: 1.1.10
- """
- return UnescapedJID(_unescape_node(self._jid[0]),
- self._jid[1],
- self._jid[2])
-
- def regenerate(self):
- """No-op
-
- .. deprecated:: 1.1.10
- """
- pass
-
- def reset(self, data):
- """Start fresh from a new JID string.
-
- :param string data: A string of the form ``'[user@]domain[/resource]'``.
-
- .. deprecated:: 1.1.10
- """
- self._jid = JID(data)._jid
-
- @property
- def resource(self):
- return self._jid[2] or ''
-
- @property
- def user(self):
- return self._jid[0] or ''
-
- @property
- def local(self):
- return self._jid[0] or ''
-
- @property
- def node(self):
- return self._jid[0] or ''
-
- @property
- def username(self):
- return self._jid[0] or ''
-
- @property
- def server(self):
- return self._jid[1] or ''
-
- @property
- def domain(self):
- return self._jid[1] or ''
-
- @property
- def host(self):
- return self._jid[1] or ''
-
- @property
- def full(self):
- return _format_jid(*self._jid)
-
- @property
- def jid(self):
- return _format_jid(*self._jid)
-
- @property
- def bare(self):
- return _format_jid(self._jid[0], self._jid[1])
-
- @resource.setter
- def resource(self, value):
- self._jid = JID(self, resource=value)._jid
-
- @user.setter
- def user(self, value):
- self._jid = JID(self, local=value)._jid
-
- @username.setter
- def username(self, value):
- self._jid = JID(self, local=value)._jid
-
- @local.setter
- def local(self, value):
- self._jid = JID(self, local=value)._jid
-
- @node.setter
- def node(self, value):
- self._jid = JID(self, local=value)._jid
-
- @server.setter
- def server(self, value):
- self._jid = JID(self, domain=value)._jid
-
- @domain.setter
- def domain(self, value):
- self._jid = JID(self, domain=value)._jid
-
- @host.setter
- def host(self, value):
- self._jid = JID(self, domain=value)._jid
-
- @full.setter
- def full(self, value):
- self._jid = JID(value)._jid
-
- @jid.setter
- def jid(self, value):
- self._jid = JID(value)._jid
-
- @bare.setter
- def bare(self, value):
- parsed = JID(value)._jid
- self._jid = (parsed[0], parsed[1], self._jid[2])
-
-
- def __str__(self):
- """Use the full JID as the string value."""
- return _format_jid(*self._jid)
-
- def __repr__(self):
- """Use the full JID as the representation."""
- return self.__str__()
-
- # pylint: disable=W0212
- def __eq__(self, other):
- """Two JIDs are equal if they have the same full JID value."""
- if isinstance(other, UnescapedJID):
- return False
-
- other = JID(other)
- return self._jid == other._jid
-
- # pylint: disable=W0212
- def __ne__(self, other):
- """Two JIDs are considered unequal if they are not equal."""
- return not self == other
-
- def __hash__(self):
- """Hash a JID based on the string version of its full JID."""
- return hash(self.__str__())
-
- def __copy__(self):
- """Generate a duplicate JID."""
- return JID(self)
-
- def __deepcopy__(self, memo):
- """Generate a duplicate JID."""
- return JID(deepcopy(str(self), memo))
diff --git a/sleekxmpp/plugins/google/__init__.py b/sleekxmpp/plugins/google/__init__.py
deleted file mode 100644
index bd7ca123..00000000
--- a/sleekxmpp/plugins/google/__init__.py
+++ /dev/null
@@ -1,47 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin, BasePlugin
-
-from sleekxmpp.plugins.google.gmail import Gmail
-from sleekxmpp.plugins.google.auth import GoogleAuth
-from sleekxmpp.plugins.google.settings import GoogleSettings
-from sleekxmpp.plugins.google.nosave import GoogleNoSave
-
-
-class Google(BasePlugin):
-
- """
- Google: Custom GTalk Features
-
- Also see: <https://developers.google.com/talk/jep_extensions/extensions>
- """
-
- name = 'google'
- description = 'Google: Custom GTalk Features'
- dependencies = set([
- 'gmail',
- 'google_settings',
- 'google_nosave',
- 'google_auth'
- ])
-
- def __getitem__(self, attr):
- if attr in ('settings', 'nosave', 'auth'):
- return self.xmpp['google_%s' % attr]
- elif attr == 'gmail':
- return self.xmpp['gmail']
- else:
- raise KeyError(attr)
-
-
-register_plugin(Gmail)
-register_plugin(GoogleAuth)
-register_plugin(GoogleSettings)
-register_plugin(GoogleNoSave)
-register_plugin(Google)
diff --git a/sleekxmpp/plugins/google/auth/__init__.py b/sleekxmpp/plugins/google/auth/__init__.py
deleted file mode 100644
index 5a8feb0d..00000000
--- a/sleekxmpp/plugins/google/auth/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.google.auth import stanza
-from sleekxmpp.plugins.google.auth.auth import GoogleAuth
diff --git a/sleekxmpp/plugins/google/auth/auth.py b/sleekxmpp/plugins/google/auth/auth.py
deleted file mode 100644
index 042bd404..00000000
--- a/sleekxmpp/plugins/google/auth/auth.py
+++ /dev/null
@@ -1,52 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-import logging
-
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.google.auth import stanza
-
-
-log = logging.getLogger(__name__)
-
-
-class GoogleAuth(BasePlugin):
-
- """
- Google: Auth Extensions (JID Domain Discovery, OAuth2)
-
- Also see:
- <https://developers.google.com/talk/jep_extensions/jid_domain_change>
- <https://developers.google.com/talk/jep_extensions/oauth>
- """
-
- name = 'google_auth'
- description = 'Google: Auth Extensions (JID Domain Discovery, OAuth2)'
- dependencies = set(['feature_mechanisms'])
- stanza = stanza
-
- def plugin_init(self):
- self.xmpp.namespace_map['http://www.google.com/talk/protocol/auth'] = 'ga'
-
- register_stanza_plugin(self.xmpp['feature_mechanisms'].stanza.Auth,
- stanza.GoogleAuth)
-
- self.xmpp.add_filter('out', self._auth)
-
- def plugin_end(self):
- self.xmpp.del_filter('out', self._auth)
-
- def _auth(self, stanza):
- if isinstance(stanza, self.xmpp['feature_mechanisms'].stanza.Auth):
- stanza.stream = self.xmpp
- stanza['google']['client_uses_full_bind_result'] = True
- if stanza['mechanism'] == 'X-OAUTH2':
- stanza['google']['service'] = 'oauth2'
- print(stanza)
- return stanza
diff --git a/sleekxmpp/plugins/google/gmail/__init__.py b/sleekxmpp/plugins/google/gmail/__init__.py
deleted file mode 100644
index a92e363b..00000000
--- a/sleekxmpp/plugins/google/gmail/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.google.gmail import stanza
-from sleekxmpp.plugins.google.gmail.notifications import Gmail
diff --git a/sleekxmpp/plugins/google/gmail/stanza.py b/sleekxmpp/plugins/google/gmail/stanza.py
deleted file mode 100644
index e7e308e1..00000000
--- a/sleekxmpp/plugins/google/gmail/stanza.py
+++ /dev/null
@@ -1,101 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.xmlstream import ElementBase, register_stanza_plugin
-
-
-class GmailQuery(ElementBase):
- namespace = 'google:mail:notify'
- name = 'query'
- plugin_attrib = 'gmail'
- interfaces = set(['newer_than_time', 'newer_than_tid', 'search'])
-
- def get_search(self):
- return self._get_attr('q', '')
-
- def set_search(self, search):
- self._set_attr('q', search)
-
- def del_search(self):
- self._del_attr('q')
-
- def get_newer_than_time(self):
- return self._get_attr('newer-than-time', '')
-
- def set_newer_than_time(self, value):
- self._set_attr('newer-than-time', value)
-
- def del_newer_than_time(self):
- self._del_attr('newer-than-time')
-
- def get_newer_than_tid(self):
- return self._get_attr('newer-than-tid', '')
-
- def set_newer_than_tid(self, value):
- self._set_attr('newer-than-tid', value)
-
- def del_newer_than_tid(self):
- self._del_attr('newer-than-tid')
-
-
-class MailBox(ElementBase):
- namespace = 'google:mail:notify'
- name = 'mailbox'
- plugin_attrib = 'gmail_messages'
- interfaces = set(['result_time', 'url', 'matched', 'estimate'])
-
- def get_matched(self):
- return self._get_attr('total-matched', '')
-
- def get_estimate(self):
- return self._get_attr('total-estimate', '') == '1'
-
- def get_result_time(self):
- return self._get_attr('result-time', '')
-
-
-class MailThread(ElementBase):
- namespace = 'google:mail:notify'
- name = 'mail-thread-info'
- plugin_attrib = 'thread'
- plugin_multi_attrib = 'threads'
- interfaces = set(['tid', 'participation', 'messages', 'date',
- 'senders', 'url', 'labels', 'subject', 'snippet'])
- sub_interfaces = set(['labels', 'subject', 'snippet'])
-
- def get_senders(self):
- result = []
- senders = self.xml.findall('{%s}senders/{%s}sender' % (
- self.namespace, self.namespace))
-
- for sender in senders:
- result.append(MailSender(xml=sender))
-
- return result
-
-
-class MailSender(ElementBase):
- namespace = 'google:mail:notify'
- name = 'sender'
- plugin_attrib = name
- interfaces = set(['address', 'name', 'originator', 'unread'])
-
- def get_originator(self):
- return self.xml.attrib.get('originator', '0') == '1'
-
- def get_unread(self):
- return self.xml.attrib.get('unread', '0') == '1'
-
-
-class NewMail(ElementBase):
- namespace = 'google:mail:notify'
- name = 'new-mail'
- plugin_attrib = 'gmail_notification'
-
-
-register_stanza_plugin(MailBox, MailThread, iterable=True)
diff --git a/sleekxmpp/plugins/google/nosave/__init__.py b/sleekxmpp/plugins/google/nosave/__init__.py
deleted file mode 100644
index 57847af5..00000000
--- a/sleekxmpp/plugins/google/nosave/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.google.nosave import stanza
-from sleekxmpp.plugins.google.nosave.nosave import GoogleNoSave
diff --git a/sleekxmpp/plugins/google/nosave/nosave.py b/sleekxmpp/plugins/google/nosave/nosave.py
deleted file mode 100644
index d6bef615..00000000
--- a/sleekxmpp/plugins/google/nosave/nosave.py
+++ /dev/null
@@ -1,83 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-import logging
-
-from sleekxmpp.stanza import Iq, Message
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.google.nosave import stanza
-
-
-log = logging.getLogger(__name__)
-
-
-class GoogleNoSave(BasePlugin):
-
- """
- Google: Off the Record Chats
-
- NOTE: This is NOT an encryption method.
-
- Also see <https://developers.google.com/talk/jep_extensions/otr>.
- """
-
- name = 'google_nosave'
- description = 'Google: Off the Record Chats'
- dependencies = set(['google_settings'])
- stanza = stanza
-
- def plugin_init(self):
- register_stanza_plugin(Message, stanza.NoSave)
- register_stanza_plugin(Iq, stanza.NoSaveQuery)
-
- self.xmpp.register_handler(
- Callback('Google Nosave',
- StanzaPath('iq@type=set/google_nosave'),
- self._handle_nosave_change))
-
- def plugin_end(self):
- self.xmpp.remove_handler('Google Nosave')
-
- def enable(self, jid=None, block=True, timeout=None, callback=None):
- if jid is None:
- self.xmpp['google_settings'].update({'archiving_enabled': False},
- block=block, timeout=timeout, callback=callback)
- else:
- iq = self.xmpp.Iq()
- iq['type'] = 'set'
- iq['google_nosave']['item']['jid'] = jid
- iq['google_nosave']['item']['value'] = True
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def disable(self, jid=None, block=True, timeout=None, callback=None):
- if jid is None:
- self.xmpp['google_settings'].update({'archiving_enabled': True},
- block=block, timeout=timeout, callback=callback)
- else:
- iq = self.xmpp.Iq()
- iq['type'] = 'set'
- iq['google_nosave']['item']['jid'] = jid
- iq['google_nosave']['item']['value'] = False
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def get(self, block=True, timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'get'
- iq.enable('google_nosave')
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def _handle_nosave_change(self, iq):
- reply = self.xmpp.Iq()
- reply['type'] = 'result'
- reply['id'] = iq['id']
- reply['to'] = iq['from']
- reply.send()
- self.xmpp.event('google_nosave_change', iq)
diff --git a/sleekxmpp/plugins/google/settings/__init__.py b/sleekxmpp/plugins/google/settings/__init__.py
deleted file mode 100644
index c3a0471d..00000000
--- a/sleekxmpp/plugins/google/settings/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.google.settings import stanza
-from sleekxmpp.plugins.google.settings.settings import GoogleSettings
diff --git a/sleekxmpp/plugins/google/settings/stanza.py b/sleekxmpp/plugins/google/settings/stanza.py
deleted file mode 100644
index d8161770..00000000
--- a/sleekxmpp/plugins/google/settings/stanza.py
+++ /dev/null
@@ -1,110 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.xmlstream import ET, ElementBase, register_stanza_plugin
-
-
-class UserSettings(ElementBase):
- name = 'usersetting'
- namespace = 'google:setting'
- plugin_attrib = 'google_settings'
- interfaces = set(['auto_accept_suggestions',
- 'mail_notifications',
- 'archiving_enabled',
- 'gmail',
- 'email_verified',
- 'domain_privacy_notice',
- 'display_name'])
-
- def _get_setting(self, setting):
- xml = self.xml.find('{%s}%s' % (self.namespace, setting))
- if xml is not None:
- return xml.attrib.get('value', '') == 'true'
- return False
-
- def _set_setting(self, setting, value):
- self._del_setting(setting)
- if value in (True, False):
- xml = ET.Element('{%s}%s' % (self.namespace, setting))
- xml.attrib['value'] = 'true' if value else 'false'
- self.xml.append(xml)
-
- def _del_setting(self, setting):
- xml = self.xml.find('{%s}%s' % (self.namespace, setting))
- if xml is not None:
- self.xml.remove(xml)
-
- def get_display_name(self):
- xml = self.xml.find('{%s}%s' % (self.namespace, 'displayname'))
- if xml is not None:
- return xml.attrib.get('value', '')
- return ''
-
- def set_display_name(self, value):
- self._del_setting(setting)
- if value:
- xml = ET.Element('{%s}%s' % (self.namespace, 'displayname'))
- xml.attrib['value'] = value
- self.xml.append(xml)
-
- def del_display_name(self):
- self._del_setting('displayname')
-
- def get_auto_accept_suggestions(self):
- return self._get_setting('autoacceptsuggestions')
-
- def get_mail_notifications(self):
- return self._get_setting('mailnotifications')
-
- def get_archiving_enabled(self):
- return self._get_setting('archivingenabled')
-
- def get_gmail(self):
- return self._get_setting('gmail')
-
- def get_email_verified(self):
- return self._get_setting('emailverified')
-
- def get_domain_privacy_notice(self):
- return self._get_setting('domainprivacynotice')
-
- def set_auto_accept_suggestions(self, value):
- self._set_setting('autoacceptsuggestions', value)
-
- def set_mail_notifications(self, value):
- self._set_setting('mailnotifications', value)
-
- def set_archiving_enabled(self, value):
- self._set_setting('archivingenabled', value)
-
- def set_gmail(self, value):
- self._set_setting('gmail', value)
-
- def set_email_verified(self, value):
- self._set_setting('emailverified', value)
-
- def set_domain_privacy_notice(self, value):
- self._set_setting('domainprivacynotice', value)
-
- def del_auto_accept_suggestions(self):
- self._del_setting('autoacceptsuggestions')
-
- def del_mail_notifications(self):
- self._del_setting('mailnotifications')
-
- def del_archiving_enabled(self):
- self._del_setting('archivingenabled')
-
- def del_gmail(self):
- self._del_setting('gmail')
-
- def del_email_verified(self):
- self._del_setting('emailverified')
-
- def del_domain_privacy_notice(self):
- self._del_setting('domainprivacynotice')
diff --git a/sleekxmpp/plugins/xep_0004/__init__.py b/sleekxmpp/plugins/xep_0004/__init__.py
deleted file mode 100644
index 2cd18ec8..00000000
--- a/sleekxmpp/plugins/xep_0004/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0004.stanza import Form
-from sleekxmpp.plugins.xep_0004.stanza import FormField, FieldOption
-from sleekxmpp.plugins.xep_0004.dataforms import XEP_0004
-
-
-register_plugin(XEP_0004)
-
-
-# Retain some backwards compatibility
-xep_0004 = XEP_0004
-xep_0004.makeForm = xep_0004.make_form
-xep_0004.buildForm = xep_0004.build_form
diff --git a/sleekxmpp/plugins/xep_0004/stanza/__init__.py b/sleekxmpp/plugins/xep_0004/stanza/__init__.py
deleted file mode 100644
index 6ad35298..00000000
--- a/sleekxmpp/plugins/xep_0004/stanza/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.xep_0004.stanza.field import FormField, FieldOption
-from sleekxmpp.plugins.xep_0004.stanza.form import Form
diff --git a/sleekxmpp/plugins/xep_0009/__init__.py b/sleekxmpp/plugins/xep_0009/__init__.py
deleted file mode 100644
index 0ce3cf2c..00000000
--- a/sleekxmpp/plugins/xep_0009/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Dann Martens (TOMOTON).
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0009 import stanza
-from sleekxmpp.plugins.xep_0009.rpc import XEP_0009
-from sleekxmpp.plugins.xep_0009.stanza import RPCQuery, MethodCall, MethodResponse
-
-
-register_plugin(XEP_0009)
-
-
-# Retain some backwards compatibility
-xep_0009 = XEP_0009
diff --git a/sleekxmpp/plugins/xep_0009/stanza/__init__.py b/sleekxmpp/plugins/xep_0009/stanza/__init__.py
deleted file mode 100644
index 5dcbf330..00000000
--- a/sleekxmpp/plugins/xep_0009/stanza/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Dann Martens (TOMOTON).
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.xep_0009.stanza.RPC import RPCQuery, MethodCall, MethodResponse
diff --git a/sleekxmpp/plugins/xep_0012/__init__.py b/sleekxmpp/plugins/xep_0012/__init__.py
deleted file mode 100644
index 6b778fc1..00000000
--- a/sleekxmpp/plugins/xep_0012/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0012.stanza import LastActivity
-from sleekxmpp.plugins.xep_0012.last_activity import XEP_0012
-
-
-register_plugin(XEP_0012)
-
-
-# Retain some backwards compatibility
-xep_0004 = XEP_0012
diff --git a/sleekxmpp/plugins/xep_0013/__init__.py b/sleekxmpp/plugins/xep_0013/__init__.py
deleted file mode 100644
index ad400949..00000000
--- a/sleekxmpp/plugins/xep_0013/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permissio
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0013.stanza import Offline
-from sleekxmpp.plugins.xep_0013.offline import XEP_0013
-
-
-register_plugin(XEP_0013)
diff --git a/sleekxmpp/plugins/xep_0016/__init__.py b/sleekxmpp/plugins/xep_0016/__init__.py
deleted file mode 100644
index 06704d26..00000000
--- a/sleekxmpp/plugins/xep_0016/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0016 import stanza
-from sleekxmpp.plugins.xep_0016.stanza import Privacy
-from sleekxmpp.plugins.xep_0016.privacy import XEP_0016
-
-
-register_plugin(XEP_0016)
diff --git a/sleekxmpp/plugins/xep_0016/privacy.py b/sleekxmpp/plugins/xep_0016/privacy.py
deleted file mode 100644
index 79fd68f0..00000000
--- a/sleekxmpp/plugins/xep_0016/privacy.py
+++ /dev/null
@@ -1,110 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp import Iq
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0016 import stanza
-from sleekxmpp.plugins.xep_0016.stanza import Privacy, Item
-
-
-class XEP_0016(BasePlugin):
-
- name = 'xep_0016'
- description = 'XEP-0016: Privacy Lists'
- dependencies = set(['xep_0030'])
- stanza = stanza
-
- def plugin_init(self):
- register_stanza_plugin(Iq, Privacy)
-
- def plugin_end(self):
- self.xmpp['xep_0030'].del_feature(feature=Privacy.namespace)
-
- def session_bind(self, jid):
- self.xmpp['xep_0030'].add_feature(Privacy.namespace)
-
- def get_privacy_lists(self, block=True, timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'get'
- iq.enable('privacy')
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def get_list(self, name, block=True, timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'get'
- iq['privacy']['list']['name'] = name
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def get_active(self, block=True, timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'get'
- iq['privacy'].enable('active')
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def get_default(self, block=True, timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'get'
- iq['privacy'].enable('default')
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def activate(self, name, block=True, timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'set'
- iq['privacy']['active']['name'] = name
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def deactivate(self, block=True, timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'set'
- iq['privacy'].enable('active')
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def make_default(self, name, block=True, timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'set'
- iq['privacy']['default']['name'] = name
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def remove_default(self, block=True, timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'set'
- iq['privacy'].enable('default')
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def edit_list(self, name, rules, block=True, timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'set'
- iq['privacy']['list']['name'] = name
- priv_list = iq['privacy']['list']
-
- if not rules:
- rules = []
-
- for rule in rules:
- if isinstance(rule, Item):
- priv_list.append(rule)
- continue
-
- priv_list.add_item(
- rule['value'],
- rule['action'],
- rule['order'],
- itype=rule.get('type', None),
- iq=rule.get('iq', None),
- message=rule.get('message', None),
- presence_in=rule.get('presence_in',
- rule.get('presence-in', None)),
- presence_out=rule.get('presence_out',
- rule.get('presence-out', None)))
-
- def remove_list(self, name, block=True, timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'set'
- iq['privacy']['list']['name'] = name
- return iq.send(block=block, timeout=timeout, callback=callback)
diff --git a/sleekxmpp/plugins/xep_0020/__init__.py b/sleekxmpp/plugins/xep_0020/__init__.py
deleted file mode 100644
index c6aafe97..00000000
--- a/sleekxmpp/plugins/xep_0020/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0020 import stanza
-from sleekxmpp.plugins.xep_0020.stanza import FeatureNegotiation
-from sleekxmpp.plugins.xep_0020.feature_negotiation import XEP_0020
-
-
-register_plugin(XEP_0020)
diff --git a/sleekxmpp/plugins/xep_0027/__init__.py b/sleekxmpp/plugins/xep_0027/__init__.py
deleted file mode 100644
index b6ed9676..00000000
--- a/sleekxmpp/plugins/xep_0027/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0027.stanza import Signed, Encrypted
-from sleekxmpp.plugins.xep_0027.gpg import XEP_0027
-
-
-register_plugin(XEP_0027)
diff --git a/sleekxmpp/plugins/xep_0030/__init__.py b/sleekxmpp/plugins/xep_0030/__init__.py
deleted file mode 100644
index 0d1de65b..00000000
--- a/sleekxmpp/plugins/xep_0030/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0030 import stanza
-from sleekxmpp.plugins.xep_0030.stanza import DiscoInfo, DiscoItems
-from sleekxmpp.plugins.xep_0030.static import StaticDisco
-from sleekxmpp.plugins.xep_0030.disco import XEP_0030
-
-
-register_plugin(XEP_0030)
-
-# Retain some backwards compatibility
-xep_0030 = XEP_0030
-XEP_0030.getInfo = XEP_0030.get_info
-XEP_0030.getItems = XEP_0030.get_items
-XEP_0030.make_static = XEP_0030.restore_defaults
diff --git a/sleekxmpp/plugins/xep_0030/stanza/__init__.py b/sleekxmpp/plugins/xep_0030/stanza/__init__.py
deleted file mode 100644
index 0d97cf3d..00000000
--- a/sleekxmpp/plugins/xep_0030/stanza/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.xep_0030.stanza.info import DiscoInfo
-from sleekxmpp.plugins.xep_0030.stanza.items import DiscoItems
diff --git a/sleekxmpp/plugins/xep_0033/__init__.py b/sleekxmpp/plugins/xep_0033/__init__.py
deleted file mode 100644
index ba8152c4..00000000
--- a/sleekxmpp/plugins/xep_0033/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0033 import stanza
-from sleekxmpp.plugins.xep_0033.stanza import Addresses, Address
-from sleekxmpp.plugins.xep_0033.addresses import XEP_0033
-
-
-register_plugin(XEP_0033)
-
-# Retain some backwards compatibility
-xep_0033 = XEP_0033
-Addresses.addAddress = Addresses.add_address
diff --git a/sleekxmpp/plugins/xep_0047/__init__.py b/sleekxmpp/plugins/xep_0047/__init__.py
deleted file mode 100644
index 5cd7df2e..00000000
--- a/sleekxmpp/plugins/xep_0047/__init__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0047 import stanza
-from sleekxmpp.plugins.xep_0047.stanza import Open, Close, Data
-from sleekxmpp.plugins.xep_0047.stream import IBBytestream
-from sleekxmpp.plugins.xep_0047.ibb import XEP_0047
-
-
-register_plugin(XEP_0047)
-
-
-# Retain some backwards compatibility
-xep_0047 = XEP_0047
diff --git a/sleekxmpp/plugins/xep_0047/stream.py b/sleekxmpp/plugins/xep_0047/stream.py
deleted file mode 100644
index 9651edf8..00000000
--- a/sleekxmpp/plugins/xep_0047/stream.py
+++ /dev/null
@@ -1,148 +0,0 @@
-import socket
-import threading
-import logging
-
-from sleekxmpp.stanza import Iq
-from sleekxmpp.util import Queue
-from sleekxmpp.exceptions import XMPPError
-
-
-log = logging.getLogger(__name__)
-
-
-class IBBytestream(object):
-
- def __init__(self, xmpp, sid, block_size, jid, peer, window_size=1, use_messages=False):
- self.xmpp = xmpp
- self.sid = sid
- self.block_size = block_size
- self.window_size = window_size
- self.use_messages = use_messages
-
- if jid is None:
- jid = xmpp.boundjid
- self.self_jid = jid
- self.peer_jid = peer
-
- self.send_seq = -1
- self.recv_seq = -1
-
- self._send_seq_lock = threading.Lock()
- self._recv_seq_lock = threading.Lock()
-
- self.stream_started = threading.Event()
- self.stream_in_closed = threading.Event()
- self.stream_out_closed = threading.Event()
-
- self.recv_queue = Queue()
-
- self.send_window = threading.BoundedSemaphore(value=self.window_size)
- self.window_ids = set()
- self.window_empty = threading.Event()
- self.window_empty.set()
-
- def send(self, data):
- if not self.stream_started.is_set() or \
- self.stream_out_closed.is_set():
- raise socket.error
- data = data[0:self.block_size]
- self.send_window.acquire()
- with self._send_seq_lock:
- self.send_seq = (self.send_seq + 1) % 65535
- seq = self.send_seq
- if self.use_messages:
- msg = self.xmpp.Message()
- msg['to'] = self.peer_jid
- msg['from'] = self.self_jid
- msg['id'] = self.xmpp.new_id()
- msg['ibb_data']['sid'] = self.sid
- msg['ibb_data']['seq'] = seq
- msg['ibb_data']['data'] = data
- msg.send()
- self.send_window.release()
- else:
- iq = self.xmpp.Iq()
- iq['type'] = 'set'
- iq['to'] = self.peer_jid
- iq['from'] = self.self_jid
- iq['ibb_data']['sid'] = self.sid
- iq['ibb_data']['seq'] = seq
- iq['ibb_data']['data'] = data
- self.window_empty.clear()
- self.window_ids.add(iq['id'])
- iq.send(block=False, callback=self._recv_ack)
- return len(data)
-
- def sendall(self, data):
- sent_len = 0
- while sent_len < len(data):
- sent_len += self.send(data[sent_len:])
-
- def _recv_ack(self, iq):
- self.window_ids.remove(iq['id'])
- if not self.window_ids:
- self.window_empty.set()
- self.send_window.release()
- if iq['type'] == 'error':
- self.close()
-
- def _recv_data(self, stanza):
- with self._recv_seq_lock:
- new_seq = stanza['ibb_data']['seq']
- if new_seq != (self.recv_seq + 1) % 65535:
- self.close()
- raise XMPPError('unexpected-request')
- self.recv_seq = new_seq
-
- data = stanza['ibb_data']['data']
- if len(data) > self.block_size:
- self.close()
- raise XMPPError('not-acceptable')
-
- self.recv_queue.put(data)
- self.xmpp.event('ibb_stream_data', {'stream': self, 'data': data})
-
- if isinstance(stanza, Iq):
- stanza.reply()
- stanza.send()
-
- def recv(self, *args, **kwargs):
- return self.read(block=True)
-
- def read(self, block=True, timeout=None, **kwargs):
- if not self.stream_started.is_set() or \
- self.stream_in_closed.is_set():
- raise socket.error
- if timeout is not None:
- block = True
- try:
- return self.recv_queue.get(block, timeout)
- except:
- return None
-
- def close(self):
- iq = self.xmpp.Iq()
- iq['type'] = 'set'
- iq['to'] = self.peer_jid
- iq['from'] = self.self_jid
- iq['ibb_close']['sid'] = self.sid
- self.stream_out_closed.set()
- iq.send(block=False,
- callback=lambda x: self.stream_in_closed.set())
- self.xmpp.event('ibb_stream_end', self)
-
- def _closed(self, iq):
- self.stream_in_closed.set()
- self.stream_out_closed.set()
- iq.reply()
- iq.send()
- self.xmpp.event('ibb_stream_end', self)
-
- def makefile(self, *args, **kwargs):
- return self
-
- def connect(*args, **kwargs):
- return None
-
- def shutdown(self, *args, **kwargs):
- return None
diff --git a/sleekxmpp/plugins/xep_0048/__init__.py b/sleekxmpp/plugins/xep_0048/__init__.py
deleted file mode 100644
index 2c98d061..00000000
--- a/sleekxmpp/plugins/xep_0048/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0048.stanza import Bookmarks, Conference, URL
-from sleekxmpp.plugins.xep_0048.bookmarks import XEP_0048
-
-
-register_plugin(XEP_0048)
diff --git a/sleekxmpp/plugins/xep_0049/__init__.py b/sleekxmpp/plugins/xep_0049/__init__.py
deleted file mode 100644
index b0c4f904..00000000
--- a/sleekxmpp/plugins/xep_0049/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0049.stanza import PrivateXML
-from sleekxmpp.plugins.xep_0049.private_storage import XEP_0049
-
-
-register_plugin(XEP_0049)
diff --git a/sleekxmpp/plugins/xep_0050/__init__.py b/sleekxmpp/plugins/xep_0050/__init__.py
deleted file mode 100644
index 640b182d..00000000
--- a/sleekxmpp/plugins/xep_0050/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0050.stanza import Command
-from sleekxmpp.plugins.xep_0050.adhoc import XEP_0050
-
-
-register_plugin(XEP_0050)
-
-
-# Retain some backwards compatibility
-xep_0050 = XEP_0050
diff --git a/sleekxmpp/plugins/xep_0054/__init__.py b/sleekxmpp/plugins/xep_0054/__init__.py
deleted file mode 100644
index d460cc8a..00000000
--- a/sleekxmpp/plugins/xep_0054/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0054.stanza import VCardTemp
-from sleekxmpp.plugins.xep_0054.vcard_temp import XEP_0054
-
-
-register_plugin(XEP_0054)
diff --git a/sleekxmpp/plugins/xep_0059/__init__.py b/sleekxmpp/plugins/xep_0059/__init__.py
deleted file mode 100644
index 3464ce32..00000000
--- a/sleekxmpp/plugins/xep_0059/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz, Erik Reuterborg Larsson
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0059.stanza import Set
-from sleekxmpp.plugins.xep_0059.rsm import ResultIterator, XEP_0059
-
-
-register_plugin(XEP_0059)
-
-# Retain some backwards compatibility
-xep_0059 = XEP_0059
diff --git a/sleekxmpp/plugins/xep_0060/__init__.py b/sleekxmpp/plugins/xep_0060/__init__.py
deleted file mode 100644
index 86e2f472..00000000
--- a/sleekxmpp/plugins/xep_0060/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0060.pubsub import XEP_0060
-from sleekxmpp.plugins.xep_0060 import stanza
-
-
-register_plugin(XEP_0060)
-
-
-# Retain some backwards compatibility
-xep_0060 = XEP_0060
diff --git a/sleekxmpp/plugins/xep_0060/stanza/__init__.py b/sleekxmpp/plugins/xep_0060/stanza/__init__.py
deleted file mode 100644
index 37f52f0e..00000000
--- a/sleekxmpp/plugins/xep_0060/stanza/__init__.py
+++ /dev/null
@@ -1,12 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.xep_0060.stanza.pubsub import *
-from sleekxmpp.plugins.xep_0060.stanza.pubsub_owner import *
-from sleekxmpp.plugins.xep_0060.stanza.pubsub_event import *
-from sleekxmpp.plugins.xep_0060.stanza.pubsub_errors import *
diff --git a/sleekxmpp/plugins/xep_0065/__init__.py b/sleekxmpp/plugins/xep_0065/__init__.py
deleted file mode 100644
index feca2ef1..00000000
--- a/sleekxmpp/plugins/xep_0065/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0065.stanza import Socks5
-from sleekxmpp.plugins.xep_0065.proxy import XEP_0065
-
-
-register_plugin(XEP_0065)
diff --git a/sleekxmpp/plugins/xep_0066/__init__.py b/sleekxmpp/plugins/xep_0066/__init__.py
deleted file mode 100644
index 68a50180..00000000
--- a/sleekxmpp/plugins/xep_0066/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0066 import stanza
-from sleekxmpp.plugins.xep_0066.stanza import OOB, OOBTransfer
-from sleekxmpp.plugins.xep_0066.oob import XEP_0066
-
-
-register_plugin(XEP_0066)
-
-
-# Retain some backwards compatibility
-xep_0066 = XEP_0066
diff --git a/sleekxmpp/plugins/xep_0071/__init__.py b/sleekxmpp/plugins/xep_0071/__init__.py
deleted file mode 100644
index c21e9265..00000000
--- a/sleekxmpp/plugins/xep_0071/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permissio
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0071.stanza import XHTML_IM
-from sleekxmpp.plugins.xep_0071.xhtml_im import XEP_0071
-
-
-register_plugin(XEP_0071)
diff --git a/sleekxmpp/plugins/xep_0077/__init__.py b/sleekxmpp/plugins/xep_0077/__init__.py
deleted file mode 100644
index 779ae0ac..00000000
--- a/sleekxmpp/plugins/xep_0077/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0077.stanza import Register, RegisterFeature
-from sleekxmpp.plugins.xep_0077.register import XEP_0077
-
-
-register_plugin(XEP_0077)
-
-
-# Retain some backwards compatibility
-xep_0077 = XEP_0077
diff --git a/sleekxmpp/plugins/xep_0078/__init__.py b/sleekxmpp/plugins/xep_0078/__init__.py
deleted file mode 100644
index 2ea72ffb..00000000
--- a/sleekxmpp/plugins/xep_0078/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0078 import stanza
-from sleekxmpp.plugins.xep_0078.stanza import IqAuth, AuthFeature
-from sleekxmpp.plugins.xep_0078.legacyauth import XEP_0078
-
-
-register_plugin(XEP_0078)
-
-
-# Retain some backwards compatibility
-xep_0078 = XEP_0078
diff --git a/sleekxmpp/plugins/xep_0080/__init__.py b/sleekxmpp/plugins/xep_0080/__init__.py
deleted file mode 100644
index cad23d22..00000000
--- a/sleekxmpp/plugins/xep_0080/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz, Erik Reuterborg Larsson
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0080.stanza import Geoloc
-from sleekxmpp.plugins.xep_0080.geoloc import XEP_0080
-
-
-register_plugin(XEP_0080)
diff --git a/sleekxmpp/plugins/xep_0084/__init__.py b/sleekxmpp/plugins/xep_0084/__init__.py
deleted file mode 100644
index 6b87573f..00000000
--- a/sleekxmpp/plugins/xep_0084/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0084 import stanza
-from sleekxmpp.plugins.xep_0084.stanza import Data, MetaData
-from sleekxmpp.plugins.xep_0084.avatar import XEP_0084
-
-
-register_plugin(XEP_0084)
diff --git a/sleekxmpp/plugins/xep_0085/__init__.py b/sleekxmpp/plugins/xep_0085/__init__.py
deleted file mode 100644
index 445d5059..00000000
--- a/sleekxmpp/plugins/xep_0085/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permissio
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0085.stanza import ChatState
-from sleekxmpp.plugins.xep_0085.chat_states import XEP_0085
-
-
-register_plugin(XEP_0085)
-
-
-# Retain some backwards compatibility
-xep_0085 = XEP_0085
diff --git a/sleekxmpp/plugins/xep_0086/__init__.py b/sleekxmpp/plugins/xep_0086/__init__.py
deleted file mode 100644
index 94600e85..00000000
--- a/sleekxmpp/plugins/xep_0086/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0086.stanza import LegacyError
-from sleekxmpp.plugins.xep_0086.legacy_error import XEP_0086
-
-
-register_plugin(XEP_0086)
-
-
-# Retain some backwards compatibility
-xep_0086 = XEP_0086
diff --git a/sleekxmpp/plugins/xep_0091/__init__.py b/sleekxmpp/plugins/xep_0091/__init__.py
deleted file mode 100644
index 04f21ef5..00000000
--- a/sleekxmpp/plugins/xep_0091/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0091 import stanza
-from sleekxmpp.plugins.xep_0091.stanza import LegacyDelay
-from sleekxmpp.plugins.xep_0091.legacy_delay import XEP_0091
-
-
-register_plugin(XEP_0091)
diff --git a/sleekxmpp/plugins/xep_0092/__init__.py b/sleekxmpp/plugins/xep_0092/__init__.py
deleted file mode 100644
index 293eaae6..00000000
--- a/sleekxmpp/plugins/xep_0092/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0092 import stanza
-from sleekxmpp.plugins.xep_0092.stanza import Version
-from sleekxmpp.plugins.xep_0092.version import XEP_0092
-
-
-register_plugin(XEP_0092)
-
-
-# Retain some backwards compatibility
-xep_0092 = XEP_0092
diff --git a/sleekxmpp/plugins/xep_0095/__init__.py b/sleekxmpp/plugins/xep_0095/__init__.py
deleted file mode 100644
index 4465ef5c..00000000
--- a/sleekxmpp/plugins/xep_0095/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0095 import stanza
-from sleekxmpp.plugins.xep_0095.stanza import SI
-from sleekxmpp.plugins.xep_0095.stream_initiation import XEP_0095
-
-
-register_plugin(XEP_0095)
diff --git a/sleekxmpp/plugins/xep_0096/__init__.py b/sleekxmpp/plugins/xep_0096/__init__.py
deleted file mode 100644
index 5f836169..00000000
--- a/sleekxmpp/plugins/xep_0096/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0096 import stanza
-from sleekxmpp.plugins.xep_0096.stanza import File
-from sleekxmpp.plugins.xep_0096.file_transfer import XEP_0096
-
-
-register_plugin(XEP_0096)
diff --git a/sleekxmpp/plugins/xep_0107/__init__.py b/sleekxmpp/plugins/xep_0107/__init__.py
deleted file mode 100644
index 04302df8..00000000
--- a/sleekxmpp/plugins/xep_0107/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0107 import stanza
-from sleekxmpp.plugins.xep_0107.stanza import UserMood
-from sleekxmpp.plugins.xep_0107.user_mood import XEP_0107
-
-
-register_plugin(XEP_0107)
diff --git a/sleekxmpp/plugins/xep_0108/__init__.py b/sleekxmpp/plugins/xep_0108/__init__.py
deleted file mode 100644
index 34d45113..00000000
--- a/sleekxmpp/plugins/xep_0108/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0108 import stanza
-from sleekxmpp.plugins.xep_0108.stanza import UserActivity
-from sleekxmpp.plugins.xep_0108.user_activity import XEP_0108
-
-
-register_plugin(XEP_0108)
diff --git a/sleekxmpp/plugins/xep_0115/__init__.py b/sleekxmpp/plugins/xep_0115/__init__.py
deleted file mode 100644
index 31a2c03a..00000000
--- a/sleekxmpp/plugins/xep_0115/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0115.stanza import Capabilities
-from sleekxmpp.plugins.xep_0115.static import StaticCaps
-from sleekxmpp.plugins.xep_0115.caps import XEP_0115
-
-
-register_plugin(XEP_0115)
-
-
-# Retain some backwards compatibility
-xep_0115 = XEP_0115
diff --git a/sleekxmpp/plugins/xep_0118/__init__.py b/sleekxmpp/plugins/xep_0118/__init__.py
deleted file mode 100644
index 565f7844..00000000
--- a/sleekxmpp/plugins/xep_0118/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0118 import stanza
-from sleekxmpp.plugins.xep_0118.stanza import UserTune
-from sleekxmpp.plugins.xep_0118.user_tune import XEP_0118
-
-
-register_plugin(XEP_0118)
diff --git a/sleekxmpp/plugins/xep_0122/__init__.py b/sleekxmpp/plugins/xep_0122/__init__.py
deleted file mode 100644
index 4b3e9483..00000000
--- a/sleekxmpp/plugins/xep_0122/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-
-from sleekxmpp.plugins.base import register_plugin
-from sleekxmpp.plugins.xep_0122.stanza import FormValidation
-from sleekxmpp.plugins.xep_0122.data_validation import XEP_0122
-
-
-register_plugin(XEP_0122)
-
-
-# Retain some backwards compatibility
-xep_0122 = XEP_0122
diff --git a/sleekxmpp/plugins/xep_0122/data_validation.py b/sleekxmpp/plugins/xep_0122/data_validation.py
deleted file mode 100644
index ec2cdfcc..00000000
--- a/sleekxmpp/plugins/xep_0122/data_validation.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0004 import stanza
-from sleekxmpp.plugins.xep_0004.stanza import FormField
-from sleekxmpp.plugins.xep_0122.stanza import FormValidation
-
-
-class XEP_0122(BasePlugin):
- """
- XEP-0004: Data Forms
- """
-
- name = 'xep_0122'
- description = 'XEP-0122: Data Forms Validation'
- dependencies = set(['xep_0004'])
- stanza = stanza
-
- def plugin_init(self):
- register_stanza_plugin(FormField, FormValidation)
diff --git a/sleekxmpp/plugins/xep_0128/__init__.py b/sleekxmpp/plugins/xep_0128/__init__.py
deleted file mode 100644
index 27c2cc33..00000000
--- a/sleekxmpp/plugins/xep_0128/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0128.static import StaticExtendedDisco
-from sleekxmpp.plugins.xep_0128.extended_disco import XEP_0128
-
-
-register_plugin(XEP_0128)
-
-
-# Retain some backwards compatibility
-xep_0128 = XEP_0128
diff --git a/sleekxmpp/plugins/xep_0131/__init__.py b/sleekxmpp/plugins/xep_0131/__init__.py
deleted file mode 100644
index ec71c98d..00000000
--- a/sleekxmpp/plugins/xep_0131/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0131 import stanza
-from sleekxmpp.plugins.xep_0131.stanza import Headers
-from sleekxmpp.plugins.xep_0131.headers import XEP_0131
-
-
-register_plugin(XEP_0131)
diff --git a/sleekxmpp/plugins/xep_0152/__init__.py b/sleekxmpp/plugins/xep_0152/__init__.py
deleted file mode 100644
index 7de031b7..00000000
--- a/sleekxmpp/plugins/xep_0152/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0152 import stanza
-from sleekxmpp.plugins.xep_0152.stanza import Reachability
-from sleekxmpp.plugins.xep_0152.reachability import XEP_0152
-
-
-register_plugin(XEP_0152)
diff --git a/sleekxmpp/plugins/xep_0153/__init__.py b/sleekxmpp/plugins/xep_0153/__init__.py
deleted file mode 100644
index f52b7712..00000000
--- a/sleekxmpp/plugins/xep_0153/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0153.stanza import VCardTempUpdate
-from sleekxmpp.plugins.xep_0153.vcard_avatar import XEP_0153
-
-
-register_plugin(XEP_0153)
diff --git a/sleekxmpp/plugins/xep_0172/__init__.py b/sleekxmpp/plugins/xep_0172/__init__.py
deleted file mode 100644
index aa7b9f72..00000000
--- a/sleekxmpp/plugins/xep_0172/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0172 import stanza
-from sleekxmpp.plugins.xep_0172.stanza import UserNick
-from sleekxmpp.plugins.xep_0172.user_nick import XEP_0172
-
-
-register_plugin(XEP_0172)
diff --git a/sleekxmpp/plugins/xep_0184/__init__.py b/sleekxmpp/plugins/xep_0184/__init__.py
deleted file mode 100644
index 4b129b6b..00000000
--- a/sleekxmpp/plugins/xep_0184/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Erik Reuterborg Larsson, Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0184.stanza import Request, Received
-from sleekxmpp.plugins.xep_0184.receipt import XEP_0184
-
-
-register_plugin(XEP_0184)
-
-
-# Retain some backwards compatibility
-xep_0184 = XEP_0184
diff --git a/sleekxmpp/plugins/xep_0186/__init__.py b/sleekxmpp/plugins/xep_0186/__init__.py
deleted file mode 100644
index c9b8c6b9..00000000
--- a/sleekxmpp/plugins/xep_0186/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0186 import stanza
-from sleekxmpp.plugins.xep_0186.stanza import Invisible, Visible
-from sleekxmpp.plugins.xep_0186.invisible_command import XEP_0186
-
-
-register_plugin(XEP_0186)
diff --git a/sleekxmpp/plugins/xep_0191/__init__.py b/sleekxmpp/plugins/xep_0191/__init__.py
deleted file mode 100644
index 934ac631..00000000
--- a/sleekxmpp/plugins/xep_0191/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0191.stanza import Block, Unblock, BlockList
-from sleekxmpp.plugins.xep_0191.blocking import XEP_0191
-
-
-register_plugin(XEP_0191)
diff --git a/sleekxmpp/plugins/xep_0196/__init__.py b/sleekxmpp/plugins/xep_0196/__init__.py
deleted file mode 100644
index 7aeaf6c9..00000000
--- a/sleekxmpp/plugins/xep_0196/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0196 import stanza
-from sleekxmpp.plugins.xep_0196.stanza import UserGaming
-from sleekxmpp.plugins.xep_0196.user_gaming import XEP_0196
-
-
-register_plugin(XEP_0196)
diff --git a/sleekxmpp/plugins/xep_0198/__init__.py b/sleekxmpp/plugins/xep_0198/__init__.py
deleted file mode 100644
index db930347..00000000
--- a/sleekxmpp/plugins/xep_0198/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0198.stanza import Enable, Enabled
-from sleekxmpp.plugins.xep_0198.stanza import Resume, Resumed
-from sleekxmpp.plugins.xep_0198.stanza import Failed
-from sleekxmpp.plugins.xep_0198.stanza import StreamManagement
-from sleekxmpp.plugins.xep_0198.stanza import Ack, RequestAck
-
-from sleekxmpp.plugins.xep_0198.stream_management import XEP_0198
-
-
-register_plugin(XEP_0198)
diff --git a/sleekxmpp/plugins/xep_0199/__init__.py b/sleekxmpp/plugins/xep_0199/__init__.py
deleted file mode 100644
index 5231a5b5..00000000
--- a/sleekxmpp/plugins/xep_0199/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0199.stanza import Ping
-from sleekxmpp.plugins.xep_0199.ping import XEP_0199
-
-
-register_plugin(XEP_0199)
-
-
-# Backwards compatibility for names
-xep_0199 = XEP_0199
-xep_0199.sendPing = xep_0199.send_ping
diff --git a/sleekxmpp/plugins/xep_0202/__init__.py b/sleekxmpp/plugins/xep_0202/__init__.py
deleted file mode 100644
index cdab3665..00000000
--- a/sleekxmpp/plugins/xep_0202/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0202 import stanza
-from sleekxmpp.plugins.xep_0202.stanza import EntityTime
-from sleekxmpp.plugins.xep_0202.time import XEP_0202
-
-
-register_plugin(XEP_0202)
-
-
-# Retain some backwards compatibility
-xep_0202 = XEP_0202
diff --git a/sleekxmpp/plugins/xep_0203/__init__.py b/sleekxmpp/plugins/xep_0203/__init__.py
deleted file mode 100644
index a95ead7e..00000000
--- a/sleekxmpp/plugins/xep_0203/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0203 import stanza
-from sleekxmpp.plugins.xep_0203.stanza import Delay
-from sleekxmpp.plugins.xep_0203.delay import XEP_0203
-
-
-register_plugin(XEP_0203)
-
-# Retain some backwards compatibility
-xep_0203 = XEP_0203
diff --git a/sleekxmpp/plugins/xep_0221/__init__.py b/sleekxmpp/plugins/xep_0221/__init__.py
deleted file mode 100644
index 91341f5b..00000000
--- a/sleekxmpp/plugins/xep_0221/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0221 import stanza
-from sleekxmpp.plugins.xep_0221.stanza import Media, URI
-from sleekxmpp.plugins.xep_0221.media import XEP_0221
-
-
-register_plugin(XEP_0221)
diff --git a/sleekxmpp/plugins/xep_0224/__init__.py b/sleekxmpp/plugins/xep_0224/__init__.py
deleted file mode 100644
index 1a9d2342..00000000
--- a/sleekxmpp/plugins/xep_0224/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0224 import stanza
-from sleekxmpp.plugins.xep_0224.stanza import Attention
-from sleekxmpp.plugins.xep_0224.attention import XEP_0224
-
-
-register_plugin(XEP_0224)
-
-
-# Retain some backwards compatibility
-xep_0224 = XEP_0224
diff --git a/sleekxmpp/plugins/xep_0231/__init__.py b/sleekxmpp/plugins/xep_0231/__init__.py
deleted file mode 100644
index 2861d67b..00000000
--- a/sleekxmpp/plugins/xep_0231/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz,
- Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0231.stanza import BitsOfBinary
-from sleekxmpp.plugins.xep_0231.bob import XEP_0231
-
-
-register_plugin(XEP_0231)
diff --git a/sleekxmpp/plugins/xep_0235/__init__.py b/sleekxmpp/plugins/xep_0235/__init__.py
deleted file mode 100644
index 29d4408a..00000000
--- a/sleekxmpp/plugins/xep_0235/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0235 import stanza
-from sleekxmpp.plugins.xep_0235.stanza import OAuth
-from sleekxmpp.plugins.xep_0235.oauth import XEP_0235
-
-
-register_plugin(XEP_0235)
diff --git a/sleekxmpp/plugins/xep_0249/__init__.py b/sleekxmpp/plugins/xep_0249/__init__.py
deleted file mode 100644
index b85f55ce..00000000
--- a/sleekxmpp/plugins/xep_0249/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Dalek
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0249.stanza import Invite
-from sleekxmpp.plugins.xep_0249.invite import XEP_0249
-
-
-register_plugin(XEP_0249)
-
-
-# Retain some backwards compatibility
-xep_0249 = XEP_0249
diff --git a/sleekxmpp/plugins/xep_0257/__init__.py b/sleekxmpp/plugins/xep_0257/__init__.py
deleted file mode 100644
index 8c5311fd..00000000
--- a/sleekxmpp/plugins/xep_0257/__init__.py
+++ /dev/null
@@ -1,17 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0257 import stanza
-from sleekxmpp.plugins.xep_0257.stanza import Certs, AppendCert
-from sleekxmpp.plugins.xep_0257.stanza import DisableCert, RevokeCert
-from sleekxmpp.plugins.xep_0257.client_cert_management import XEP_0257
-
-
-register_plugin(XEP_0257)
diff --git a/sleekxmpp/plugins/xep_0257/client_cert_management.py b/sleekxmpp/plugins/xep_0257/client_cert_management.py
deleted file mode 100644
index 49317843..00000000
--- a/sleekxmpp/plugins/xep_0257/client_cert_management.py
+++ /dev/null
@@ -1,65 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-import logging
-
-from sleekxmpp import Iq
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0257 import stanza, Certs
-from sleekxmpp.plugins.xep_0257 import AppendCert, DisableCert, RevokeCert
-
-
-log = logging.getLogger(__name__)
-
-
-class XEP_0257(BasePlugin):
-
- name = 'xep_0257'
- description = 'XEP-0258: Client Certificate Management for SASL EXTERNAL'
- dependencies = set(['xep_0030'])
- stanza = stanza
-
- def plugin_init(self):
- register_stanza_plugin(Iq, Certs)
- register_stanza_plugin(Iq, AppendCert)
- register_stanza_plugin(Iq, DisableCert)
- register_stanza_plugin(Iq, RevokeCert)
-
- def get_certs(self, ifrom=None, block=True, timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'get'
- iq['from'] = ifrom
- iq.enable('sasl_certs')
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def add_cert(self, name, cert, allow_management=True, ifrom=None,
- block=True, timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'set'
- iq['from'] = ifrom
- iq['sasl_cert_append']['name'] = name
- iq['sasl_cert_append']['x509cert'] = cert
- iq['sasl_cert_append']['cert_management'] = allow_management
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def disable_cert(self, name, ifrom=None, block=True,
- timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'set'
- iq['from'] = ifrom
- iq['sasl_cert_disable']['name'] = name
- return iq.send(block=block, timeout=timeout, callback=callback)
-
- def revoke_cert(self, name, ifrom=None, block=True,
- timeout=None, callback=None):
- iq = self.xmpp.Iq()
- iq['type'] = 'set'
- iq['from'] = ifrom
- iq['sasl_cert_revoke']['name'] = name
- return iq.send(block=block, timeout=timeout, callback=callback)
diff --git a/sleekxmpp/plugins/xep_0258/__init__.py b/sleekxmpp/plugins/xep_0258/__init__.py
deleted file mode 100644
index 516a3706..00000000
--- a/sleekxmpp/plugins/xep_0258/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0258 import stanza
-from sleekxmpp.plugins.xep_0258.stanza import SecurityLabel, Label
-from sleekxmpp.plugins.xep_0258.stanza import DisplayMarking, EquivalentLabel
-from sleekxmpp.plugins.xep_0258.stanza import ESSLabel, Catalog, CatalogItem
-from sleekxmpp.plugins.xep_0258.security_labels import XEP_0258
-
-
-register_plugin(XEP_0258)
diff --git a/sleekxmpp/plugins/xep_0279/__init__.py b/sleekxmpp/plugins/xep_0279/__init__.py
deleted file mode 100644
index 93db9e7c..00000000
--- a/sleekxmpp/plugins/xep_0279/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0279 import stanza
-from sleekxmpp.plugins.xep_0279.stanza import IPCheck
-from sleekxmpp.plugins.xep_0279.ipcheck import XEP_0279
-
-
-register_plugin(XEP_0279)
diff --git a/sleekxmpp/plugins/xep_0280/__init__.py b/sleekxmpp/plugins/xep_0280/__init__.py
deleted file mode 100644
index 929321af..00000000
--- a/sleekxmpp/plugins/xep_0280/__init__.py
+++ /dev/null
@@ -1,17 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permissio
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0280.stanza import ReceivedCarbon, SentCarbon
-from sleekxmpp.plugins.xep_0280.stanza import PrivateCarbon
-from sleekxmpp.plugins.xep_0280.stanza import CarbonEnable, CarbonDisable
-from sleekxmpp.plugins.xep_0280.carbons import XEP_0280
-
-
-register_plugin(XEP_0280)
diff --git a/sleekxmpp/plugins/xep_0297/__init__.py b/sleekxmpp/plugins/xep_0297/__init__.py
deleted file mode 100644
index 551d9420..00000000
--- a/sleekxmpp/plugins/xep_0297/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0297 import stanza
-from sleekxmpp.plugins.xep_0297.stanza import Forwarded
-from sleekxmpp.plugins.xep_0297.forwarded import XEP_0297
-
-
-register_plugin(XEP_0297)
diff --git a/sleekxmpp/plugins/xep_0308/__init__.py b/sleekxmpp/plugins/xep_0308/__init__.py
deleted file mode 100644
index a6a100ee..00000000
--- a/sleekxmpp/plugins/xep_0308/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permissio
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0308.stanza import Replace
-from sleekxmpp.plugins.xep_0308.correction import XEP_0308
-
-
-register_plugin(XEP_0308)
diff --git a/sleekxmpp/plugins/xep_0313/__init__.py b/sleekxmpp/plugins/xep_0313/__init__.py
deleted file mode 100644
index 8b6ed97d..00000000
--- a/sleekxmpp/plugins/xep_0313/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permissio
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0313.stanza import Result, MAM, Preferences
-from sleekxmpp.plugins.xep_0313.mam import XEP_0313
-
-
-register_plugin(XEP_0313)
diff --git a/sleekxmpp/plugins/xep_0319/__init__.py b/sleekxmpp/plugins/xep_0319/__init__.py
deleted file mode 100644
index 4756e63e..00000000
--- a/sleekxmpp/plugins/xep_0319/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.base import register_plugin
-
-from sleekxmpp.plugins.xep_0319 import stanza
-from sleekxmpp.plugins.xep_0319.stanza import Idle
-from sleekxmpp.plugins.xep_0319.idle import XEP_0319
-
-
-register_plugin(XEP_0319)
diff --git a/sleekxmpp/plugins/xep_0332/stanza/__init__.py b/sleekxmpp/plugins/xep_0332/stanza/__init__.py
deleted file mode 100644
index 201824b7..00000000
--- a/sleekxmpp/plugins/xep_0332/stanza/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Implementation of HTTP over XMPP transport
- http://xmpp.org/extensions/xep-0332.html
- Copyright (C) 2015 Riptide IO, sangeeth@riptideio.com
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.plugins.xep_0332.stanza.request import HTTPRequest
-from sleekxmpp.plugins.xep_0332.stanza.response import HTTPResponse
-from sleekxmpp.plugins.xep_0332.stanza.data import HTTPData
diff --git a/sleekxmpp/roster/__init__.py b/sleekxmpp/roster/__init__.py
deleted file mode 100644
index 18b380c9..00000000
--- a/sleekxmpp/roster/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.roster.item import RosterItem
-from sleekxmpp.roster.single import RosterNode
-from sleekxmpp.roster.multi import Roster
diff --git a/sleekxmpp/stanza/__init__.py b/sleekxmpp/stanza/__init__.py
deleted file mode 100644
index 4bd37dc5..00000000
--- a/sleekxmpp/stanza/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-
-from sleekxmpp.stanza.error import Error
-from sleekxmpp.stanza.iq import Iq
-from sleekxmpp.stanza.message import Message
-from sleekxmpp.stanza.presence import Presence
-from sleekxmpp.stanza.stream_features import StreamFeatures
-from sleekxmpp.stanza.stream_error import StreamError
diff --git a/sleekxmpp/stanza/htmlim.py b/sleekxmpp/stanza/htmlim.py
deleted file mode 100644
index c43178f2..00000000
--- a/sleekxmpp/stanza/htmlim.py
+++ /dev/null
@@ -1,21 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.stanza import Message
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0071 import XHTML_IM as HTMLIM
-
-
-register_stanza_plugin(Message, HTMLIM)
-
-
-# To comply with PEP8, method names now use underscores.
-# Deprecated method names are re-mapped for backwards compatibility.
-HTMLIM.setBody = HTMLIM.set_body
-HTMLIM.getBody = HTMLIM.get_body
-HTMLIM.delBody = HTMLIM.del_body
diff --git a/sleekxmpp/stanza/nick.py b/sleekxmpp/stanza/nick.py
deleted file mode 100644
index 0e9a5c2b..00000000
--- a/sleekxmpp/stanza/nick.py
+++ /dev/null
@@ -1,23 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-# The nickname stanza has been moved to its own plugin, but the existing
-# references are kept for backwards compatibility.
-
-from sleekxmpp.stanza import Message, Presence
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0172 import UserNick as Nick
-
-register_stanza_plugin(Message, Nick)
-register_stanza_plugin(Presence, Nick)
-
-# To comply with PEP8, method names now use underscores.
-# Deprecated method names are re-mapped for backwards compatibility.
-Nick.setNick = Nick.set_nick
-Nick.getNick = Nick.get_nick
-Nick.delNick = Nick.del_nick
diff --git a/sleekxmpp/test/__init__.py b/sleekxmpp/test/__init__.py
deleted file mode 100644
index 54d4dc57..00000000
--- a/sleekxmpp/test/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.test.mocksocket import TestSocket
-from sleekxmpp.test.livesocket import TestLiveSocket
-from sleekxmpp.test.sleektest import *
diff --git a/sleekxmpp/thirdparty/__init__.py b/sleekxmpp/thirdparty/__init__.py
deleted file mode 100644
index 337598ac..00000000
--- a/sleekxmpp/thirdparty/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-try:
- from collections import OrderedDict
-except:
- from sleekxmpp.thirdparty.ordereddict import OrderedDict
-
-try:
- from gnupg import GPG
-except:
- from sleekxmpp.thirdparty.gnupg import GPG
-
-from sleekxmpp.thirdparty import socks
-from sleekxmpp.thirdparty.mini_dateutil import tzutc, tzoffset, parse_iso
-from sleekxmpp.thirdparty.orderedset import OrderedSet
diff --git a/sleekxmpp/thirdparty/ordereddict.py b/sleekxmpp/thirdparty/ordereddict.py
deleted file mode 100644
index 5b0303f5..00000000
--- a/sleekxmpp/thirdparty/ordereddict.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# Copyright (c) 2009 Raymond Hettinger
-#
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this software and associated documentation files
-# (the "Software"), to deal in the Software without restriction,
-# including without limitation the rights to use, copy, modify, merge,
-# publish, distribute, sublicense, and/or sell copies of the Software,
-# and to permit persons to whom the Software is furnished to do so,
-# subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-# OTHER DEALINGS IN THE SOFTWARE.
-
-from UserDict import DictMixin
-
-class OrderedDict(dict, DictMixin):
-
- def __init__(self, *args, **kwds):
- if len(args) > 1:
- raise TypeError('expected at most 1 arguments, got %d' % len(args))
- try:
- self.__end
- except AttributeError:
- self.clear()
- self.update(*args, **kwds)
-
- def clear(self):
- self.__end = end = []
- end += [None, end, end] # sentinel node for doubly linked list
- self.__map = {} # key --> [key, prev, next]
- dict.clear(self)
-
- def __setitem__(self, key, value):
- if key not in self:
- end = self.__end
- curr = end[1]
- curr[2] = end[1] = self.__map[key] = [key, curr, end]
- dict.__setitem__(self, key, value)
-
- def __delitem__(self, key):
- dict.__delitem__(self, key)
- key, prev, next = self.__map.pop(key)
- prev[2] = next
- next[1] = prev
-
- def __iter__(self):
- end = self.__end
- curr = end[2]
- while curr is not end:
- yield curr[0]
- curr = curr[2]
-
- def __reversed__(self):
- end = self.__end
- curr = end[1]
- while curr is not end:
- yield curr[0]
- curr = curr[1]
-
- def popitem(self, last=True):
- if not self:
- raise KeyError('dictionary is empty')
- if last:
- key = reversed(self).next()
- else:
- key = iter(self).next()
- value = self.pop(key)
- return key, value
-
- def __reduce__(self):
- items = [[k, self[k]] for k in self]
- tmp = self.__map, self.__end
- del self.__map, self.__end
- inst_dict = vars(self).copy()
- self.__map, self.__end = tmp
- if inst_dict:
- return (self.__class__, (items,), inst_dict)
- return self.__class__, (items,)
-
- def keys(self):
- return list(self)
-
- setdefault = DictMixin.setdefault
- update = DictMixin.update
- pop = DictMixin.pop
- values = DictMixin.values
- items = DictMixin.items
- iterkeys = DictMixin.iterkeys
- itervalues = DictMixin.itervalues
- iteritems = DictMixin.iteritems
-
- def __repr__(self):
- if not self:
- return '%s()' % (self.__class__.__name__,)
- return '%s(%r)' % (self.__class__.__name__, self.items())
-
- def copy(self):
- return self.__class__(self)
-
- @classmethod
- def fromkeys(cls, iterable, value=None):
- d = cls()
- for key in iterable:
- d[key] = value
- return d
-
- def __eq__(self, other):
- if isinstance(other, OrderedDict):
- if len(self) != len(other):
- return False
- for p, q in zip(self.items(), other.items()):
- if p != q:
- return False
- return True
- return dict.__eq__(self, other)
-
- def __ne__(self, other):
- return not self == other
diff --git a/sleekxmpp/thirdparty/socks.py b/sleekxmpp/thirdparty/socks.py
deleted file mode 100644
index 34090d51..00000000
--- a/sleekxmpp/thirdparty/socks.py
+++ /dev/null
@@ -1,387 +0,0 @@
-"""SocksiPy - Python SOCKS module.
-Version 1.00
-
-Copyright 2006 Dan-Haim. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-3. Neither the name of Dan Haim nor the names of his contributors may be used
- to endorse or promote products derived from this software without specific
- prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY DAN HAIM "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-EVENT SHALL DAN HAIM OR HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA
-OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMANGE.
-
-
-This module provides a standard socket-like interface for Python
-for tunneling connections through SOCKS proxies.
-
-"""
-
-"""
-
-Minor modifications made by Christopher Gilbert (http://motomastyle.com/)
-for use in PyLoris (http://pyloris.sourceforge.net/)
-
-Minor modifications made by Mario Vilas (http://breakingcode.wordpress.com/)
-mainly to merge bug fixes found in Sourceforge
-
-Minor modifications made by Eugene Dementiev (http://www.dementiev.eu/)
-
-"""
-
-import socket
-import struct
-import sys
-
-PROXY_TYPE_SOCKS4 = 1
-PROXY_TYPE_SOCKS5 = 2
-PROXY_TYPE_HTTP = 3
-
-_defaultproxy = None
-_orgsocket = socket.socket
-
-class ProxyError(Exception): pass
-class GeneralProxyError(ProxyError): pass
-class Socks5AuthError(ProxyError): pass
-class Socks5Error(ProxyError): pass
-class Socks4Error(ProxyError): pass
-class HTTPError(ProxyError): pass
-
-_generalerrors = ("success",
- "invalid data",
- "not connected",
- "not available",
- "bad proxy type",
- "bad input")
-
-_socks5errors = ("succeeded",
- "general SOCKS server failure",
- "connection not allowed by ruleset",
- "Network unreachable",
- "Host unreachable",
- "Connection refused",
- "TTL expired",
- "Command not supported",
- "Address type not supported",
- "Unknown error")
-
-_socks5autherrors = ("succeeded",
- "authentication is required",
- "all offered authentication methods were rejected",
- "unknown username or invalid password",
- "unknown error")
-
-_socks4errors = ("request granted",
- "request rejected or failed",
- "request rejected because SOCKS server cannot connect to identd on the client",
- "request rejected because the client program and identd report different user-ids",
- "unknown error")
-
-def setdefaultproxy(proxytype=None, addr=None, port=None, rdns=True, username=None, password=None):
- """setdefaultproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
- Sets a default proxy which all further socksocket objects will use,
- unless explicitly changed.
- """
- global _defaultproxy
- _defaultproxy = (proxytype, addr, port, rdns, username, password)
-
-def wrapmodule(module):
- """wrapmodule(module)
- Attempts to replace a module's socket library with a SOCKS socket. Must set
- a default proxy using setdefaultproxy(...) first.
- This will only work on modules that import socket directly into the namespace;
- most of the Python Standard Library falls into this category.
- """
- if _defaultproxy != None:
- module.socket.socket = socksocket
- else:
- raise GeneralProxyError((4, "no proxy specified"))
-
-class socksocket(socket.socket):
- """socksocket([family[, type[, proto]]]) -> socket object
- Open a SOCKS enabled socket. The parameters are the same as
- those of the standard socket init. In order for SOCKS to work,
- you must specify family=AF_INET, type=SOCK_STREAM and proto=0.
- """
-
- def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None):
- _orgsocket.__init__(self, family, type, proto, _sock)
- if _defaultproxy != None:
- self.__proxy = _defaultproxy
- else:
- self.__proxy = (None, None, None, None, None, None)
- self.__proxysockname = None
- self.__proxypeername = None
-
- def __recvall(self, count):
- """__recvall(count) -> data
- Receive EXACTLY the number of bytes requested from the socket.
- Blocks until the required number of bytes have been received.
- """
- data = self.recv(count)
- while len(data) < count:
- d = self.recv(count-len(data))
- if not d: raise GeneralProxyError((0, "connection closed unexpectedly"))
- data = data + d
- return data
-
- def setproxy(self, proxytype=None, addr=None, port=None, rdns=True, username=None, password=None):
- """setproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
- Sets the proxy to be used.
- proxytype - The type of the proxy to be used. Three types
- are supported: PROXY_TYPE_SOCKS4 (including socks4a),
- PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP
- addr - The address of the server (IP or DNS).
- port - The port of the server. Defaults to 1080 for SOCKS
- servers and 8080 for HTTP proxy servers.
- rdns - Should DNS queries be preformed on the remote side
- (rather than the local side). The default is True.
- Note: This has no effect with SOCKS4 servers.
- username - Username to authenticate with to the server.
- The default is no authentication.
- password - Password to authenticate with to the server.
- Only relevant when username is also provided.
- """
- self.__proxy = (proxytype, addr, port, rdns, username, password)
-
- def __negotiatesocks5(self, destaddr, destport):
- """__negotiatesocks5(self,destaddr,destport)
- Negotiates a connection through a SOCKS5 server.
- """
- # First we'll send the authentication packages we support.
- if (self.__proxy[4]!=None) and (self.__proxy[5]!=None):
- # The username/password details were supplied to the
- # setproxy method so we support the USERNAME/PASSWORD
- # authentication (in addition to the standard none).
- self.sendall(struct.pack('BBBB', 0x05, 0x02, 0x00, 0x02))
- else:
- # No username/password were entered, therefore we
- # only support connections with no authentication.
- self.sendall(struct.pack('BBB', 0x05, 0x01, 0x00))
- # We'll receive the server's response to determine which
- # method was selected
- chosenauth = self.__recvall(2)
- if chosenauth[0:1] != chr(0x05).encode():
- self.close()
- raise GeneralProxyError((1, _generalerrors[1]))
- # Check the chosen authentication method
- if chosenauth[1:2] == chr(0x00).encode():
- # No authentication is required
- pass
- elif chosenauth[1:2] == chr(0x02).encode():
- # Okay, we need to perform a basic username/password
- # authentication.
- self.sendall(chr(0x01).encode() + chr(len(self.__proxy[4])) + self.__proxy[4] + chr(len(self.__proxy[5])) + self.__proxy[5])
- authstat = self.__recvall(2)
- if authstat[0:1] != chr(0x01).encode():
- # Bad response
- self.close()
- raise GeneralProxyError((1, _generalerrors[1]))
- if authstat[1:2] != chr(0x00).encode():
- # Authentication failed
- self.close()
- raise Socks5AuthError((3, _socks5autherrors[3]))
- # Authentication succeeded
- else:
- # Reaching here is always bad
- self.close()
- if chosenauth[1] == chr(0xFF).encode():
- raise Socks5AuthError((2, _socks5autherrors[2]))
- else:
- raise GeneralProxyError((1, _generalerrors[1]))
- # Now we can request the actual connection
- req = struct.pack('BBB', 0x05, 0x01, 0x00)
- # If the given destination address is an IP address, we'll
- # use the IPv4 address request even if remote resolving was specified.
- try:
- ipaddr = socket.inet_aton(destaddr)
- req = req + chr(0x01).encode() + ipaddr
- except socket.error:
- # Well it's not an IP number, so it's probably a DNS name.
- if self.__proxy[3]:
- # Resolve remotely
- ipaddr = None
- req = req + chr(0x03).encode() + chr(len(destaddr)).encode() + destaddr.encode()
- else:
- # Resolve locally
- ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
- req = req + chr(0x01).encode() + ipaddr
- req += struct.pack(">H", destport)
- self.sendall(req)
- # Get the response
- resp = self.__recvall(4)
- if resp[0:1] != chr(0x05).encode():
- self.close()
- raise GeneralProxyError((1, _generalerrors[1]))
- elif resp[1:2] != chr(0x00).encode():
- # Connection failed
- self.close()
- if ord(resp[1:2])<=8:
- raise Socks5Error((ord(resp[1:2]), _socks5errors[ord(resp[1:2])]))
- else:
- raise Socks5Error((9, _socks5errors[9]))
- # Get the bound address/port
- elif resp[3:4] == chr(0x01).encode():
- boundaddr = self.__recvall(4)
- elif resp[3:4] == chr(0x03).encode():
- resp = resp + self.recv(1)
- boundaddr = self.__recvall(ord(resp[4:5]))
- else:
- self.close()
- raise GeneralProxyError((1,_generalerrors[1]))
- boundport = struct.unpack(">H", self.__recvall(2))[0]
- self.__proxysockname = (boundaddr, boundport)
- if ipaddr != None:
- self.__proxypeername = (socket.inet_ntoa(ipaddr), destport)
- else:
- self.__proxypeername = (destaddr, destport)
-
- def getproxysockname(self):
- """getsockname() -> address info
- Returns the bound IP address and port number at the proxy.
- """
- return self.__proxysockname
-
- def getproxypeername(self):
- """getproxypeername() -> address info
- Returns the IP and port number of the proxy.
- """
- return _orgsocket.getpeername(self)
-
- def getpeername(self):
- """getpeername() -> address info
- Returns the IP address and port number of the destination
- machine (note: getproxypeername returns the proxy)
- """
- return self.__proxypeername
-
- def __negotiatesocks4(self,destaddr,destport):
- """__negotiatesocks4(self,destaddr,destport)
- Negotiates a connection through a SOCKS4 server.
- """
- # Check if the destination address provided is an IP address
- rmtrslv = False
- try:
- ipaddr = socket.inet_aton(destaddr)
- except socket.error:
- # It's a DNS name. Check where it should be resolved.
- if self.__proxy[3]:
- ipaddr = struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01)
- rmtrslv = True
- else:
- ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
- # Construct the request packet
- req = struct.pack(">BBH", 0x04, 0x01, destport) + ipaddr
- # The username parameter is considered userid for SOCKS4
- if self.__proxy[4] != None:
- req = req + self.__proxy[4]
- req += chr(0x00).encode()
- # DNS name if remote resolving is required
- # NOTE: This is actually an extension to the SOCKS4 protocol
- # called SOCKS4A and may not be supported in all cases.
- if rmtrslv:
- req = req + destaddr + chr(0x00).encode()
- self.sendall(req)
- # Get the response from the server
- resp = self.__recvall(8)
- if resp[0:1] != chr(0x00).encode():
- # Bad data
- self.close()
- raise GeneralProxyError((1,_generalerrors[1]))
- if resp[1:2] != chr(0x5A).encode():
- # Server returned an error
- self.close()
- if ord(resp[1:2]) in (91, 92, 93):
- self.close()
- raise Socks4Error((ord(resp[1:2]), _socks4errors[ord(resp[1:2]) - 90]))
- else:
- raise Socks4Error((94, _socks4errors[4]))
- # Get the bound address/port
- self.__proxysockname = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0])
- if rmtrslv != None:
- self.__proxypeername = (socket.inet_ntoa(ipaddr), destport)
- else:
- self.__proxypeername = (destaddr, destport)
-
- def __negotiatehttp(self, destaddr, destport):
- """__negotiatehttp(self,destaddr,destport)
- Negotiates a connection through an HTTP server.
- """
- # If we need to resolve locally, we do this now
- if not self.__proxy[3]:
- addr = socket.gethostbyname(destaddr)
- else:
- addr = destaddr
- self.sendall(("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n").encode())
- # We read the response until we get the string "\r\n\r\n"
- resp = self.recv(1)
- while resp.find("\r\n\r\n".encode()) == -1:
- recv = self.recv(1)
- if not recv:
- raise GeneralProxyError((1, _generalerrors[1]))
- resp = resp + recv
- # We just need the first line to check if the connection
- # was successful
- statusline = resp.splitlines()[0].split(" ".encode(), 2)
- if statusline[0] not in ("HTTP/1.0".encode(), "HTTP/1.1".encode()):
- self.close()
- raise GeneralProxyError((1, _generalerrors[1]))
- try:
- statuscode = int(statusline[1])
- except ValueError:
- self.close()
- raise GeneralProxyError((1, _generalerrors[1]))
- if statuscode != 200:
- self.close()
- raise HTTPError((statuscode, statusline[2]))
- self.__proxysockname = ("0.0.0.0", 0)
- self.__proxypeername = (addr, destport)
-
- def connect(self, destpair):
- """connect(self, despair)
- Connects to the specified destination through a proxy.
- destpar - A tuple of the IP/DNS address and the port number.
- (identical to socket's connect).
- To select the proxy server use setproxy().
- """
- # Do a minimal input check first
- if (not type(destpair) in (list,tuple)) or (len(destpair) < 2) or (type(destpair[0]) != type('')) or (type(destpair[1]) != int):
- raise GeneralProxyError((5, _generalerrors[5]))
- if self.__proxy[0] == PROXY_TYPE_SOCKS5:
- if self.__proxy[2] != None:
- portnum = self.__proxy[2]
- else:
- portnum = 1080
- _orgsocket.connect(self, (self.__proxy[1], portnum))
- self.__negotiatesocks5(destpair[0], destpair[1])
- elif self.__proxy[0] == PROXY_TYPE_SOCKS4:
- if self.__proxy[2] != None:
- portnum = self.__proxy[2]
- else:
- portnum = 1080
- _orgsocket.connect(self,(self.__proxy[1], portnum))
- self.__negotiatesocks4(destpair[0], destpair[1])
- elif self.__proxy[0] == PROXY_TYPE_HTTP:
- if self.__proxy[2] != None:
- portnum = self.__proxy[2]
- else:
- portnum = 8080
- _orgsocket.connect(self,(self.__proxy[1], portnum))
- self.__negotiatehttp(destpair[0], destpair[1])
- elif self.__proxy[0] == None:
- _orgsocket.connect(self, (destpair[0], destpair[1]))
- else:
- raise GeneralProxyError((4, _generalerrors[4]))
diff --git a/sleekxmpp/thirdparty/statemachine.py b/sleekxmpp/thirdparty/statemachine.py
deleted file mode 100644
index 6c504dce..00000000
--- a/sleekxmpp/thirdparty/statemachine.py
+++ /dev/null
@@ -1,294 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-import threading
-import time
-import logging
-
-log = logging.getLogger(__name__)
-
-
-class StateMachine(object):
-
- def __init__(self, states=None):
- if not states: states = []
- self.lock = threading.Condition()
- self.__states = []
- self.addStates(states)
- self.__default_state = self.__states[0]
- self.__current_state = self.__default_state
-
- def addStates(self, states):
- self.lock.acquire()
- try:
- for state in states:
- if state in self.__states:
- raise IndexError("The state '%s' is already in the StateMachine." % state)
- self.__states.append(state)
- finally:
- self.lock.release()
-
-
- def transition(self, from_state, to_state, wait=0.0, func=None, args=None, kwargs=None):
- '''
- Transition from the given `from_state` to the given `to_state`.
- This method will return `True` if the state machine is now in `to_state`. It
- will return `False` if a timeout occurred the transition did not occur.
- If `wait` is 0 (the default,) this method returns immediately if the state machine
- is not in `from_state`.
-
- If you want the thread to block and transition once the state machine to enters
- `from_state`, set `wait` to a non-negative value. Note there is no 'block
- indefinitely' flag since this leads to deadlock. If you want to wait indefinitely,
- choose a reasonable value for `wait` (e.g. 20 seconds) and do so in a while loop like so:
-
- ::
-
- while not thread_should_exit and not state_machine.transition('disconnected', 'connecting', wait=20 ):
- pass # timeout will occur every 20s unless transition occurs
- if thread_should_exit: return
- # perform actions here after successful transition
-
- This allows the thread to be responsive by setting `thread_should_exit=True`.
-
- The optional `func` argument allows the user to pass a callable operation which occurs
- within the context of the state transition (e.g. while the state machine is locked.)
- If `func` returns a True value, the transition will occur. If `func` returns a non-
- True value or if an exception is thrown, the transition will not occur. Any thrown
- exception is not caught by the state machine and is the caller's responsibility to handle.
- If `func` completes normally, this method will return the value returned by `func.` If
- values for `args` and `kwargs` are provided, they are expanded and passed like so:
- `func( *args, **kwargs )`.
- '''
- if not args:
- args = []
- if not kwargs:
- kwargs = {}
-
- return self.transition_any((from_state,), to_state, wait=wait,
- func=func, args=args, kwargs=kwargs)
-
-
- def transition_any(self, from_states, to_state, wait=0.0, func=None, args=None, kwargs=None):
- '''
- Transition from any of the given `from_states` to the given `to_state`.
- '''
- if not args:
- args = []
- if not kwargs:
- kwargs = {}
-
- if not isinstance(from_states, (tuple, list, set)):
- raise ValueError("from_states should be a list, tuple, or set")
-
- for state in from_states:
- if not state in self.__states:
- raise ValueError("StateMachine does not contain from_state %s." % state)
- if not to_state in self.__states:
- raise ValueError("StateMachine does not contain to_state %s." % to_state)
-
- if self.__current_state == to_state:
- return True
-
- start = time.time()
- while not self.lock.acquire(False):
- time.sleep(.001)
- if (start + wait - time.time()) <= 0.0:
- log.debug("==== Could not acquire lock in %s sec: %s -> %s ", wait, self.__current_state, to_state)
- return False
-
- while not self.__current_state in from_states:
- # detect timeout:
- remainder = start + wait - time.time()
- if remainder > 0:
- self.lock.wait(remainder)
- else:
- log.debug("State was not ready")
- self.lock.release()
- return False
-
- try: # lock is acquired; all other threads will return false or wait until notify/timeout
- if self.__current_state in from_states: # should always be True due to lock
-
- # Note that func might throw an exception, but that's OK, it aborts the transition
- return_val = func(*args,**kwargs) if func is not None else True
-
- # some 'false' value returned from func,
- # indicating that transition should not occur:
- if not return_val:
- return return_val
-
- log.debug(' ==== TRANSITION %s -> %s', self.__current_state, to_state)
- self._set_state(to_state)
- return return_val # some 'true' value returned by func or True if func was None
- else:
- log.error("StateMachine bug!! The lock should ensure this doesn't happen!")
- return False
- finally:
- self.lock.notify_all()
- self.lock.release()
-
-
- def transition_ctx(self, from_state, to_state, wait=0.0):
- '''
- Use the state machine as a context manager. The transition occurs on /exit/ from
- the `with` context, so long as no exception is thrown. For example:
-
- ::
-
- with state_machine.transition_ctx('one','two', wait=5) as locked:
- if locked:
- # the state machine is currently locked in state 'one', and will
- # transition to 'two' when the 'with' statement ends, so long as
- # no exception is thrown.
- print 'Currently locked in state one: %s' % state_machine['one']
-
- else:
- # The 'wait' timed out, and no lock has been acquired
- print 'Timed out before entering state "one"'
-
- print 'Since no exception was thrown, we are now in state "two": %s' % state_machine['two']
-
-
- The other main difference between this method and `transition()` is that the
- state machine is locked for the duration of the `with` statement. Normally,
- after a `transition()` occurs, the state machine is immediately unlocked and
- available to another thread to call `transition()` again.
- '''
-
- if not from_state in self.__states:
- raise ValueError("StateMachine does not contain from_state %s." % from_state)
- if not to_state in self.__states:
- raise ValueError("StateMachine does not contain to_state %s." % to_state)
-
- return _StateCtx(self, from_state, to_state, wait)
-
-
- def ensure(self, state, wait=0.0, block_on_transition=False):
- '''
- Ensure the state machine is currently in `state`, or wait until it enters `state`.
- '''
- return self.ensure_any((state,), wait=wait, block_on_transition=block_on_transition)
-
-
- def ensure_any(self, states, wait=0.0, block_on_transition=False):
- '''
- Ensure we are currently in one of the given `states` or wait until
- we enter one of those states.
-
- Note that due to the nature of the function, you cannot guarantee that
- the entirety of some operation completes while you remain in a given
- state. That would require acquiring and holding a lock, which
- would mean no other threads could do the same. (You'd essentially
- be serializing all of the threads that are 'ensuring' their tasks
- occurred in some state.
- '''
- if not (isinstance(states,tuple) or isinstance(states,list)):
- raise ValueError('states arg should be a tuple or list')
-
- for state in states:
- if not state in self.__states:
- raise ValueError("StateMachine does not contain state '%s'" % state)
-
- # if we're in the middle of a transition, determine whether we should
- # 'fall back' to the 'current' state, or wait for the new state, in order to
- # avoid an operation occurring in the wrong state.
- # TODO another option would be an ensure_ctx that uses a semaphore to allow
- # threads to indicate they want to remain in a particular state.
- self.lock.acquire()
- start = time.time()
- while not self.__current_state in states:
- # detect timeout:
- remainder = start + wait - time.time()
- if remainder > 0:
- self.lock.wait(remainder)
- else:
- self.lock.release()
- return False
- self.lock.release()
- return True
-
- def reset(self):
- # TODO need to lock before calling this?
- self.transition(self.__current_state, self.__default_state)
-
- def _set_state(self, state): #unsynchronized, only call internally after lock is acquired
- self.__current_state = state
- return state
-
- def current_state(self):
- '''
- Return the current state name.
- '''
- return self.__current_state
-
- def __getitem__(self, state):
- '''
- Non-blocking, non-synchronized test to determine if we are in the given state.
- Use `StateMachine.ensure(state)` to wait until the machine enters a certain state.
- '''
- return self.__current_state == state
-
- def __str__(self):
- return "".join(("StateMachine(", ','.join(self.__states), "): ", self.__current_state))
-
-
-
-class _StateCtx:
-
- def __init__(self, state_machine, from_state, to_state, wait):
- self.state_machine = state_machine
- self.from_state = from_state
- self.to_state = to_state
- self.wait = wait
- self._locked = False
-
- def __enter__(self):
- start = time.time()
- while not self.state_machine[self.from_state] or not self.state_machine.lock.acquire(False):
- # detect timeout:
- remainder = start + self.wait - time.time()
- if remainder > 0:
- self.state_machine.lock.wait(remainder)
- else:
- log.debug('StateMachine timeout while waiting for state: %s', self.from_state)
- return False
-
- self._locked = True # lock has been acquired at this point
- self.state_machine.lock.clear()
- log.debug('StateMachine entered context in state: %s',
- self.state_machine.current_state())
- return True
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- if exc_val is not None:
- log.exception("StateMachine exception in context, remaining in state: %s\n%s:%s",
- self.state_machine.current_state(), exc_type.__name__, exc_val)
-
- if self._locked:
- if exc_val is None:
- log.debug(' ==== TRANSITION %s -> %s',
- self.state_machine.current_state(), self.to_state)
- self.state_machine._set_state(self.to_state)
-
- self.state_machine.lock.notify_all()
- self.state_machine.lock.release()
-
- return False # re-raise any exception
-
-if __name__ == '__main__':
-
- def callback(s, s2):
- print((1, s.transition('on', 'off', wait=0.0, func=callback, args=[s,s2])))
- print((2, s2.transition('off', 'on', func=callback, args=[s,s2])))
- return True
-
- s = StateMachine(('off', 'on'))
- s2 = StateMachine(('off', 'on'))
- print((3, s.transition('off', 'on', wait=0.0, func=callback, args=[s,s2]),))
- print((s.current_state(), s2.current_state()))
diff --git a/sleekxmpp/util/__init__.py b/sleekxmpp/util/__init__.py
deleted file mode 100644
index 47a935af..00000000
--- a/sleekxmpp/util/__init__.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- sleekxmpp.util
- ~~~~~~~~~~~~~~
-
- Part of SleekXMPP: The Sleek XMPP Library
-
- :copyright: (c) 2012 Nathanael C. Fritz, Lance J.T. Stout
- :license: MIT, see LICENSE for more details
-"""
-
-
-from sleekxmpp.util.misc_ops import bytes, unicode, hashes, hash, \
- num_to_bytes, bytes_to_num, quote, \
- XOR, safedict
-
-
-# =====================================================================
-# Standardize import of Queue class:
-
-import sys
-
-def _gevent_threads_enabled():
- if not 'gevent' in sys.modules:
- return False
- try:
- from gevent import thread as green_thread
- thread = __import__('thread')
- return thread.LockType is green_thread.LockType
- except ImportError:
- return False
-
-if _gevent_threads_enabled():
- import gevent.queue as queue
- _queue = queue.JoinableQueue
-else:
- try:
- import queue
- except ImportError:
- import Queue as queue
- _queue = queue.Queue
-class Queue(_queue):
- def put(self, item, block=True, timeout=None):
- if _queue.full(self):
- _queue.get(self)
- return _queue.put(self, item, block, timeout)
-
-QueueEmpty = queue.Empty
diff --git a/sleekxmpp/xmlstream/__init__.py b/sleekxmpp/xmlstream/__init__.py
deleted file mode 100644
index 5a1ea1be..00000000
--- a/sleekxmpp/xmlstream/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.jid import JID
-from sleekxmpp.xmlstream.scheduler import Scheduler
-from sleekxmpp.xmlstream.stanzabase import StanzaBase, ElementBase, ET
-from sleekxmpp.xmlstream.stanzabase import register_stanza_plugin
-from sleekxmpp.xmlstream.tostring import tostring
-from sleekxmpp.xmlstream.xmlstream import XMLStream, RESPONSE_TIMEOUT
-from sleekxmpp.xmlstream.xmlstream import RestartStream
-
-__all__ = ['JID', 'Scheduler', 'StanzaBase', 'ElementBase',
- 'ET', 'StateMachine', 'tostring', 'XMLStream',
- 'RESPONSE_TIMEOUT', 'RestartStream']
diff --git a/sleekxmpp/xmlstream/filesocket.py b/sleekxmpp/xmlstream/filesocket.py
deleted file mode 100644
index 53b83bc7..00000000
--- a/sleekxmpp/xmlstream/filesocket.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- sleekxmpp.xmlstream.filesocket
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This module is a shim for correcting deficiencies in the file
- socket implementation of Python2.6.
-
- Part of SleekXMPP: The Sleek XMPP Library
-
- :copyright: (c) 2011 Nathanael C. Fritz
- :license: MIT, see LICENSE for more details
-"""
-
-from socket import _fileobject
-import errno
-import socket
-
-
-class FileSocket(_fileobject):
-
- """Create a file object wrapper for a socket to work around
- issues present in Python 2.6 when using sockets as file objects.
-
- The parser for :class:`~xml.etree.cElementTree` requires a file, but
- we will be reading from the XMPP connection socket instead.
- """
-
- def read(self, size=4096):
- """Read data from the socket as if it were a file."""
- if self._sock is None:
- return None
- while True:
- try:
- data = self._sock.recv(size)
- break
- except socket.error as serr:
- if serr.errno != errno.EINTR:
- raise
- if data is not None:
- return data
-
-
-class Socket26(socket.socket):
-
- """A custom socket implementation that uses our own FileSocket class
- to work around issues in Python 2.6 when using sockets as files.
- """
-
- def makefile(self, mode='r', bufsize=-1):
- """makefile([mode[, bufsize]]) -> file object
- Return a regular file object corresponding to the socket. The mode
- and bufsize arguments are as for the built-in open() function."""
- return FileSocket(self._sock, mode, bufsize)
diff --git a/sleekxmpp/xmlstream/handler/__init__.py b/sleekxmpp/xmlstream/handler/__init__.py
deleted file mode 100644
index 83c87f01..00000000
--- a/sleekxmpp/xmlstream/handler/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.xmlstream.handler.callback import Callback
-from sleekxmpp.xmlstream.handler.collector import Collector
-from sleekxmpp.xmlstream.handler.waiter import Waiter
-from sleekxmpp.xmlstream.handler.xmlcallback import XMLCallback
-from sleekxmpp.xmlstream.handler.xmlwaiter import XMLWaiter
-
-__all__ = ['Callback', 'Waiter', 'XMLCallback', 'XMLWaiter']
diff --git a/sleekxmpp/xmlstream/jid.py b/sleekxmpp/xmlstream/jid.py
deleted file mode 100644
index 2b59db47..00000000
--- a/sleekxmpp/xmlstream/jid.py
+++ /dev/null
@@ -1,5 +0,0 @@
-import logging
-
-logging.warning('Deprecated: sleekxmpp.xmlstream.jid is moving to sleekxmpp.jid')
-
-from sleekxmpp.jid import JID
diff --git a/sleekxmpp/xmlstream/matcher/__init__.py b/sleekxmpp/xmlstream/matcher/__init__.py
deleted file mode 100644
index aa74c434..00000000
--- a/sleekxmpp/xmlstream/matcher/__init__.py
+++ /dev/null
@@ -1,17 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.xmlstream.matcher.id import MatcherId
-from sleekxmpp.xmlstream.matcher.idsender import MatchIDSender
-from sleekxmpp.xmlstream.matcher.many import MatchMany
-from sleekxmpp.xmlstream.matcher.stanzapath import StanzaPath
-from sleekxmpp.xmlstream.matcher.xmlmask import MatchXMLMask
-from sleekxmpp.xmlstream.matcher.xpath import MatchXPath
-
-__all__ = ['MatcherId', 'MatchMany', 'StanzaPath',
- 'MatchXMLMask', 'MatchXPath']
diff --git a/sleekxmpp/xmlstream/scheduler.py b/sleekxmpp/xmlstream/scheduler.py
deleted file mode 100644
index e6fae37a..00000000
--- a/sleekxmpp/xmlstream/scheduler.py
+++ /dev/null
@@ -1,250 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- sleekxmpp.xmlstream.scheduler
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This module provides a task scheduler that works better
- with SleekXMPP's threading usage than the stock version.
-
- Part of SleekXMPP: The Sleek XMPP Library
-
- :copyright: (c) 2011 Nathanael C. Fritz
- :license: MIT, see LICENSE for more details
-"""
-
-import time
-import threading
-import logging
-import itertools
-
-from sleekxmpp.util import Queue, QueueEmpty
-
-
-#: The time in seconds to wait for events from the event queue, and also the
-#: time between checks for the process stop signal.
-WAIT_TIMEOUT = 1.0
-
-
-log = logging.getLogger(__name__)
-
-
-class Task(object):
-
- """
- A scheduled task that will be executed by the scheduler
- after a given time interval has passed.
-
- :param string name: The name of the task.
- :param int seconds: The number of seconds to wait before executing.
- :param callback: The function to execute.
- :param tuple args: The arguments to pass to the callback.
- :param dict kwargs: The keyword arguments to pass to the callback.
- :param bool repeat: Indicates if the task should repeat.
- Defaults to ``False``.
- :param pointer: A pointer to an event queue for queuing callback
- execution instead of executing immediately.
- """
-
- def __init__(self, name, seconds, callback, args=None,
- kwargs=None, repeat=False, qpointer=None):
- #: The name of the task.
- self.name = name
-
- #: The number of seconds to wait before executing.
- self.seconds = seconds
-
- #: The function to execute once enough time has passed.
- self.callback = callback
-
- #: The arguments to pass to :attr:`callback`.
- self.args = args or tuple()
-
- #: The keyword arguments to pass to :attr:`callback`.
- self.kwargs = kwargs or {}
-
- #: Indicates if the task should repeat after executing,
- #: using the same :attr:`seconds` delay.
- self.repeat = repeat
-
- #: The time when the task should execute next.
- self.next = time.time() + self.seconds
-
- #: The main event queue, which allows for callbacks to
- #: be queued for execution instead of executing immediately.
- self.qpointer = qpointer
-
- def run(self):
- """Execute the task's callback.
-
- If an event queue was supplied, place the callback in the queue;
- otherwise, execute the callback immediately.
- """
- if self.qpointer is not None:
- self.qpointer.put(('schedule', self.callback,
- self.args, self.kwargs, self.name))
- else:
- self.callback(*self.args, **self.kwargs)
- self.reset()
- return self.repeat
-
- def reset(self):
- """Reset the task's timer so that it will repeat."""
- self.next = time.time() + self.seconds
-
-
-class Scheduler(object):
-
- """
- A threaded scheduler that allows for updates mid-execution unlike the
- scheduler in the standard library.
-
- Based on: http://docs.python.org/library/sched.html#module-sched
-
- :param parentstop: An :class:`~threading.Event` to signal stopping
- the scheduler.
- """
-
- def __init__(self, parentstop=None):
- #: A queue for storing tasks
- self.addq = Queue()
-
- #: A list of tasks in order of execution time.
- self.schedule = []
-
- #: If running in threaded mode, this will be the thread processing
- #: the schedule.
- self.thread = None
-
- #: A flag indicating that the scheduler is running.
- self.run = False
-
- #: An :class:`~threading.Event` instance for signalling to stop
- #: the scheduler.
- self.stop = parentstop
-
- #: Lock for accessing the task queue.
- self.schedule_lock = threading.RLock()
-
- #: The time in seconds to wait for events from the event queue,
- #: and also the time between checks for the process stop signal.
- self.wait_timeout = WAIT_TIMEOUT
-
- def process(self, threaded=True, daemon=False):
- """Begin accepting and processing scheduled tasks.
-
- :param bool threaded: Indicates if the scheduler should execute
- in its own thread. Defaults to ``True``.
- """
- if threaded:
- self.thread = threading.Thread(name='scheduler_process',
- target=self._process)
- self.thread.daemon = daemon
- self.thread.start()
- else:
- self._process()
-
- def _process(self):
- """Process scheduled tasks."""
- self.run = True
- try:
- while self.run and not self.stop.is_set():
- updated = False
- if self.schedule:
- wait = self.schedule[0].next - time.time()
- else:
- wait = self.wait_timeout
- try:
- if wait <= 0.0:
- newtask = self.addq.get(False)
- else:
- newtask = None
- while self.run and \
- not self.stop.is_set() and \
- newtask is None and \
- wait > 0:
- try:
- newtask = self.addq.get(True, min(wait, self.wait_timeout))
- except QueueEmpty: # Nothing to add, nothing to do. Check run flags and continue waiting.
- wait -= self.wait_timeout
- except QueueEmpty: # Time to run some tasks, and no new tasks to add.
- self.schedule_lock.acquire()
- # select only those tasks which are to be executed now
- relevant = itertools.takewhile(
- lambda task: time.time() >= task.next, self.schedule)
- # run the tasks and keep the return value in a tuple
- status = map(lambda task: (task, task.run()), relevant)
- # remove non-repeating tasks
- for task, doRepeat in status:
- if not doRepeat:
- try:
- self.schedule.remove(task)
- except ValueError:
- pass
- else:
- # only need to resort tasks if a repeated task has
- # been kept in the list.
- updated = True
- else: # Add new task
- self.schedule_lock.acquire()
- if newtask is not None:
- self.schedule.append(newtask)
- updated = True
- finally:
- if updated:
- self.schedule.sort(key=lambda task: task.next)
- self.schedule_lock.release()
- except KeyboardInterrupt:
- self.run = False
- except SystemExit:
- self.run = False
- log.debug("Quitting Scheduler thread")
-
- def add(self, name, seconds, callback, args=None,
- kwargs=None, repeat=False, qpointer=None):
- """Schedule a new task.
-
- :param string name: The name of the task.
- :param int seconds: The number of seconds to wait before executing.
- :param callback: The function to execute.
- :param tuple args: The arguments to pass to the callback.
- :param dict kwargs: The keyword arguments to pass to the callback.
- :param bool repeat: Indicates if the task should repeat.
- Defaults to ``False``.
- :param pointer: A pointer to an event queue for queuing callback
- execution instead of executing immediately.
- """
- try:
- self.schedule_lock.acquire()
- for task in self.schedule:
- if task.name == name:
- raise ValueError("Key %s already exists" % name)
-
- self.addq.put(Task(name, seconds, callback, args,
- kwargs, repeat, qpointer))
- except:
- raise
- finally:
- self.schedule_lock.release()
-
- def remove(self, name):
- """Remove a scheduled task ahead of schedule, and without
- executing it.
-
- :param string name: The name of the task to remove.
- """
- try:
- self.schedule_lock.acquire()
- the_task = None
- for task in self.schedule:
- if task.name == name:
- the_task = task
- if the_task is not None:
- self.schedule.remove(the_task)
- except:
- raise
- finally:
- self.schedule_lock.release()
-
- def quit(self):
- """Shutdown the scheduler."""
- self.run = False
diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py
deleted file mode 100644
index 62d46100..00000000
--- a/sleekxmpp/xmlstream/xmlstream.py
+++ /dev/null
@@ -1,1817 +0,0 @@
-"""
- sleekxmpp.xmlstream.xmlstream
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This module provides the module for creating and
- interacting with generic XML streams, along with
- the necessary eventing infrastructure.
-
- Part of SleekXMPP: The Sleek XMPP Library
-
- :copyright: (c) 2011 Nathanael C. Fritz
- :license: MIT, see LICENSE for more details
-"""
-
-from __future__ import with_statement, unicode_literals
-
-import base64
-import copy
-import logging
-import signal
-import socket as Socket
-import ssl
-import sys
-import threading
-import time
-import random
-import weakref
-import uuid
-import errno
-
-from xml.parsers.expat import ExpatError
-
-import sleekxmpp
-from sleekxmpp.util import Queue, QueueEmpty, safedict
-from sleekxmpp.thirdparty.statemachine import StateMachine
-from sleekxmpp.xmlstream import Scheduler, tostring, cert
-from sleekxmpp.xmlstream.stanzabase import StanzaBase, ET, ElementBase
-from sleekxmpp.xmlstream.handler import Waiter, XMLCallback
-from sleekxmpp.xmlstream.matcher import MatchXMLMask
-from sleekxmpp.xmlstream.resolver import resolve, default_resolver
-
-# In Python 2.x, file socket objects are broken. A patched socket
-# wrapper is provided for this case in filesocket.py.
-if sys.version_info < (3, 0):
- from sleekxmpp.xmlstream.filesocket import FileSocket, Socket26
-
-
-#: The time in seconds to wait before timing out waiting for response stanzas.
-RESPONSE_TIMEOUT = 30
-
-#: The time in seconds to wait for events from the event queue, and also the
-#: time between checks for the process stop signal.
-WAIT_TIMEOUT = 1.0
-
-#: The number of threads to use to handle XML stream events. This is not the
-#: same as the number of custom event handling threads.
-#: :data:`HANDLER_THREADS` must be at least 1. For Python implementations
-#: with a GIL, this should be left at 1, but for implemetnations without
-#: a GIL increasing this value can provide better performance.
-HANDLER_THREADS = 1
-
-#: The time in seconds to delay between attempts to resend data
-#: after an SSL error.
-SSL_RETRY_DELAY = 0.5
-
-#: The maximum number of times to attempt resending data due to
-#: an SSL error.
-SSL_RETRY_MAX = 10
-
-#: Maximum time to delay between connection attempts is one hour.
-RECONNECT_MAX_DELAY = 600
-
-#: Maximum number of attempts to connect to the server before quitting
-#: and raising a 'connect_failed' event. Setting this to ``None`` will
-#: allow infinite reconnection attempts, and using ``0`` will disable
-#: reconnections. Defaults to ``None``.
-RECONNECT_MAX_ATTEMPTS = None
-
-
-log = logging.getLogger(__name__)
-
-
-class RestartStream(Exception):
- """
- Exception to restart stream processing, including
- resending the stream header.
- """
-
-
-class XMLStream(object):
- """
- An XML stream connection manager and event dispatcher.
-
- The XMLStream class abstracts away the issues of establishing a
- connection with a server and sending and receiving XML "stanzas".
- A stanza is a complete XML element that is a direct child of a root
- document element. Two streams are used, one for each communication
- direction, over the same socket. Once the connection is closed, both
- streams should be complete and valid XML documents.
-
- Three types of events are provided to manage the stream:
- :Stream: Triggered based on received stanzas, similar in concept
- to events in a SAX XML parser.
- :Custom: Triggered manually.
- :Scheduled: Triggered based on time delays.
-
- Typically, stanzas are first processed by a stream event handler which
- will then trigger custom events to continue further processing,
- especially since custom event handlers may run in individual threads.
-
- :param socket: Use an existing socket for the stream. Defaults to
- ``None`` to generate a new socket.
- :param string host: The name of the target server.
- :param int port: The port to use for the connection. Defaults to 0.
- """
-
- def __init__(self, socket=None, host='', port=0, certfile=None,
- keyfile=None, ca_certs=None, **kwargs):
- #: Most XMPP servers support TLSv1, but OpenFire in particular
- #: does not work well with it. For OpenFire, set
- #: :attr:`ssl_version` to use ``SSLv23``::
- #:
- #: import ssl
- #: xmpp.ssl_version = ssl.PROTOCOL_SSLv23
- self.ssl_version = ssl.PROTOCOL_TLSv1
-
- #: The list of accepted ciphers, in OpenSSL Format.
- #: It might be useful to override it for improved security
- #: over the python defaults.
- self.ciphers = None
-
- #: Path to a file containing certificates for verifying the
- #: server SSL certificate. A non-``None`` value will trigger
- #: certificate checking.
- #:
- #: .. note::
- #:
- #: On Mac OS X, certificates in the system keyring will
- #: be consulted, even if they are not in the provided file.
- self.ca_certs = ca_certs
-
- #: Path to a file containing a client certificate to use for
- #: authenticating via SASL EXTERNAL. If set, there must also
- #: be a corresponding `:attr:keyfile` value.
- self.certfile = certfile
-
- #: Path to a file containing the private key for the selected
- #: client certificate to use for authenticating via SASL EXTERNAL.
- self.keyfile = keyfile
-
- self._der_cert = None
-
- #: The time in seconds to wait for events from the event queue,
- #: and also the time between checks for the process stop signal.
- self.wait_timeout = WAIT_TIMEOUT
-
- #: The time in seconds to wait before timing out waiting
- #: for response stanzas.
- self.response_timeout = RESPONSE_TIMEOUT
-
- #: The current amount to time to delay attempting to reconnect.
- #: This value doubles (with some jitter) with each failed
- #: connection attempt up to :attr:`reconnect_max_delay` seconds.
- self.reconnect_delay = None
-
- #: Maximum time to delay between connection attempts is one hour.
- self.reconnect_max_delay = RECONNECT_MAX_DELAY
-
- #: Maximum number of attempts to connect to the server before
- #: quitting and raising a 'connect_failed' event. Setting to
- #: ``None`` allows infinite reattempts, while setting it to ``0``
- #: will disable reconnection attempts. Defaults to ``None``.
- self.reconnect_max_attempts = RECONNECT_MAX_ATTEMPTS
-
- #: The time in seconds to delay between attempts to resend data
- #: after an SSL error.
- self.ssl_retry_max = SSL_RETRY_MAX
-
- #: The maximum number of times to attempt resending data due to
- #: an SSL error.
- self.ssl_retry_delay = SSL_RETRY_DELAY
-
- #: The connection state machine tracks if the stream is
- #: ``'connected'`` or ``'disconnected'``.
- self.state = StateMachine(('disconnected', 'connected'))
- self.state._set_state('disconnected')
-
- #: The default port to return when querying DNS records.
- self.default_port = int(port)
-
- #: The domain to try when querying DNS records.
- self.default_domain = ''
-
- #: The expected name of the server, for validation.
- self._expected_server_name = ''
- self._service_name = ''
-
- #: The desired, or actual, address of the connected server.
- self.address = (host, int(port))
-
- #: A file-like wrapper for the socket for use with the
- #: :mod:`~xml.etree.ElementTree` module.
- self.filesocket = None
- self.set_socket(socket)
-
- if sys.version_info < (3, 0):
- self.socket_class = Socket26
- else:
- self.socket_class = Socket.socket
-
- #: Enable connecting to the server directly over SSL, in
- #: particular when the service provides two ports: one for
- #: non-SSL traffic and another for SSL traffic.
- self.use_ssl = False
-
- #: Enable connecting to the service without using SSL
- #: immediately, but allow upgrading the connection later
- #: to use SSL.
- self.use_tls = False
-
- #: If set to ``True``, attempt to connect through an HTTP
- #: proxy based on the settings in :attr:`proxy_config`.
- self.use_proxy = False
-
- #: If set to ``True``, attempt to use IPv6.
- self.use_ipv6 = True
-
- #: If set to ``True``, allow using the ``dnspython`` DNS library
- #: if available. If set to ``False``, the builtin DNS resolver
- #: will be used, even if ``dnspython`` is installed.
- self.use_dnspython = True
-
- #: Use CDATA for escaping instead of XML entities. Defaults
- #: to ``False``.
- self.use_cdata = False
-
- #: An optional dictionary of proxy settings. It may provide:
- #: :host: The host offering proxy services.
- #: :port: The port for the proxy service.
- #: :username: Optional username for accessing the proxy.
- #: :password: Optional password for accessing the proxy.
- self.proxy_config = {}
-
- #: The default namespace of the stream content, not of the
- #: stream wrapper itself.
- self.default_ns = ''
-
- self.default_lang = None
- self.peer_default_lang = None
-
- #: The namespace of the enveloping stream element.
- self.stream_ns = ''
-
- #: The default opening tag for the stream element.
- self.stream_header = "<stream>"
-
- #: The default closing tag for the stream element.
- self.stream_footer = "</stream>"
-
- #: If ``True``, periodically send a whitespace character over the
- #: wire to keep the connection alive. Mainly useful for connections
- #: traversing NAT.
- self.whitespace_keepalive = True
-
- #: The default interval between keepalive signals when
- #: :attr:`whitespace_keepalive` is enabled.
- self.whitespace_keepalive_interval = 300
-
- #: An :class:`~threading.Event` to signal that the application
- #: is stopping, and that all threads should shutdown.
- self.stop = threading.Event()
-
- #: An :class:`~threading.Event` to signal receiving a closing
- #: stream tag from the server.
- self.stream_end_event = threading.Event()
- self.stream_end_event.set()
-
- #: An :class:`~threading.Event` to signal the start of a stream
- #: session. Until this event fires, the send queue is not used
- #: and data is sent immediately over the wire.
- self.session_started_event = threading.Event()
-
- #: The default time in seconds to wait for a session to start
- #: after connecting before reconnecting and trying again.
- self.session_timeout = 45
-
- #: Flag for controlling if the session can be considered ended
- #: if the connection is terminated.
- self.end_session_on_disconnect = True
-
- #: A queue of stream, custom, and scheduled events to be processed.
- self.event_queue = Queue()
-
- #: A queue of string data to be sent over the stream.
- self.send_queue = Queue(maxsize=256)
- self.send_queue_lock = threading.Lock()
- self.send_lock = threading.RLock()
-
- #: A :class:`~sleekxmpp.xmlstream.scheduler.Scheduler` instance for
- #: executing callbacks in the future based on time delays.
- self.scheduler = Scheduler(self.stop)
- self.__failed_send_stanza = None
-
- #: A mapping of XML namespaces to well-known prefixes.
- self.namespace_map = {StanzaBase.xml_ns: 'xml'}
-
- self.__thread = {}
- self.__root_stanza = []
- self.__handlers = []
- self.__event_handlers = {}
- self.__event_handlers_lock = threading.Lock()
- self.__filters = {'in': [], 'out': [], 'out_sync': []}
- self.__thread_count = 0
- self.__thread_cond = threading.Condition()
- self.__active_threads = set()
- self._use_daemons = False
- self._disconnect_wait_for_threads = True
-
- self._id = 0
- self._id_lock = threading.Lock()
-
- #: We use an ID prefix to ensure that all ID values are unique.
- self._id_prefix = '%s-' % uuid.uuid4()
-
- #: The :attr:`auto_reconnnect` setting controls whether or not
- #: the stream will be restarted in the event of an error.
- self.auto_reconnect = True
-
- #: The :attr:`disconnect_wait` setting is the default value
- #: for controlling if the system waits for the send queue to
- #: empty before ending the stream. This may be overridden by
- #: passing ``wait=True`` or ``wait=False`` to :meth:`disconnect`.
- #: The default :attr:`disconnect_wait` value is ``False``.
- self.disconnect_wait = False
-
- #: A list of DNS results that have not yet been tried.
- self.dns_answers = []
-
- #: The service name to check with DNS SRV records. For
- #: example, setting this to ``'xmpp-client'`` would query the
- #: ``_xmpp-client._tcp`` service.
- self.dns_service = None
-
- self.add_event_handler('connected', self._session_timeout_check)
- self.add_event_handler('disconnected', self._remove_schedules)
- self.add_event_handler('session_start', self._start_keepalive)
- self.add_event_handler('session_start', self._cert_expiration)
-
- def use_signals(self, signals=None):
- """Register signal handlers for ``SIGHUP`` and ``SIGTERM``.
-
- By using signals, a ``'killed'`` event will be raised when the
- application is terminated.
-
- If a signal handler already existed, it will be executed first,
- before the ``'killed'`` event is raised.
-
- :param list signals: A list of signal names to be monitored.
- Defaults to ``['SIGHUP', 'SIGTERM']``.
- """
- if signals is None:
- signals = ['SIGHUP', 'SIGTERM']
-
- existing_handlers = {}
- for sig_name in signals:
- if hasattr(signal, sig_name):
- sig = getattr(signal, sig_name)
- handler = signal.getsignal(sig)
- if handler:
- existing_handlers[sig] = handler
-
- def handle_kill(signum, frame):
- """
- Capture kill event and disconnect cleanly after first
- spawning the ``'killed'`` event.
- """
-
- if signum in existing_handlers and \
- existing_handlers[signum] != handle_kill:
- existing_handlers[signum](signum, frame)
-
- self.event("killed", direct=True)
- self.disconnect()
-
- try:
- for sig_name in signals:
- if hasattr(signal, sig_name):
- sig = getattr(signal, sig_name)
- signal.signal(sig, handle_kill)
- self.__signals_installed = True
- except:
- log.debug("Can not set interrupt signal handlers. " + \
- "SleekXMPP is not running from a main thread.")
-
- def new_id(self):
- """Generate and return a new stream ID in hexadecimal form.
-
- Many stanzas, handlers, or matchers may require unique
- ID values. Using this method ensures that all new ID values
- are unique in this stream.
- """
- with self._id_lock:
- self._id += 1
- return self.get_id()
-
- def get_id(self):
- """Return the current unique stream ID in hexadecimal form."""
- return "%s%X" % (self._id_prefix, self._id)
-
- def connect(self, host='', port=0, use_ssl=False,
- use_tls=True, reattempt=True):
- """Create a new socket and connect to the server.
-
- Setting ``reattempt`` to ``True`` will cause connection
- attempts to be made with an exponential backoff delay (max of
- :attr:`reconnect_max_delay` which defaults to 10 minute) until a
- successful connection is established.
-
- :param host: The name of the desired server for the connection.
- :param port: Port to connect to on the server.
- :param use_ssl: Flag indicating if SSL should be used by connecting
- directly to a port using SSL.
- :param use_tls: Flag indicating if TLS should be used, allowing for
- connecting to a port without using SSL immediately and
- later upgrading the connection.
- :param reattempt: Flag indicating if the socket should reconnect
- after disconnections.
- """
- self.stop.clear()
-
- if host and port:
- self.address = (host, int(port))
- try:
- Socket.inet_aton(self.address[0])
- except (Socket.error, ssl.SSLError):
- self.default_domain = self.address[0]
-
- # Respect previous SSL and TLS usage directives.
- if use_ssl is not None:
- self.use_ssl = use_ssl
- if use_tls is not None:
- self.use_tls = use_tls
-
- # Repeatedly attempt to connect until a successful connection
- # is established.
- attempts = self.reconnect_max_attempts
- connected = self.state.transition('disconnected', 'connected',
- func=self._connect,
- args=(reattempt,))
- while reattempt and not connected and not self.stop.is_set():
- connected = self.state.transition('disconnected', 'connected',
- func=self._connect)
- if not connected:
- if attempts is not None:
- attempts -= 1
- if attempts <= 0:
- self.event('connection_failed', direct=True)
- return False
- return connected
-
- def _connect(self, reattempt=True):
- self.scheduler.remove('Session timeout check')
-
- if self.reconnect_delay is None:
- delay = 1.0
- self.reconnect_delay = delay
-
- if reattempt:
- delay = min(self.reconnect_delay * 2, self.reconnect_max_delay)
- delay = random.normalvariate(delay, delay * 0.1)
- log.debug('Waiting %s seconds before connecting.', delay)
- elapsed = 0
- try:
- while elapsed < delay and not self.stop.is_set():
- time.sleep(0.1)
- elapsed += 0.1
- except KeyboardInterrupt:
- self.set_stop()
- return False
- except SystemExit:
- self.set_stop()
- return False
-
- if self.default_domain:
- try:
- host, address, port = self.pick_dns_answer(self.default_domain,
- self.address[1])
- self.address = (address, port)
- self._service_name = host
- except StopIteration:
- log.debug("No remaining DNS records to try.")
- self.dns_answers = None
- if reattempt:
- self.reconnect_delay = delay
- return False
-
- af = Socket.AF_INET
- proto = 'IPv4'
- if ':' in self.address[0]:
- af = Socket.AF_INET6
- proto = 'IPv6'
- try:
- self.socket = self.socket_class(af, Socket.SOCK_STREAM)
- except Socket.error:
- log.debug("Could not connect using %s", proto)
- return False
-
- self.configure_socket()
-
- if self.use_proxy:
- connected = self._connect_proxy()
- if not connected:
- if reattempt:
- self.reconnect_delay = delay
- return False
-
- if self.use_ssl:
- log.debug("Socket Wrapped for SSL")
- if self.ca_certs is None:
- cert_policy = ssl.CERT_NONE
- else:
- cert_policy = ssl.CERT_REQUIRED
-
- ssl_args = safedict({
- 'certfile': self.certfile,
- 'keyfile': self.keyfile,
- 'ca_certs': self.ca_certs,
- 'cert_reqs': cert_policy,
- 'do_handshake_on_connect': False,
- "ssl_version": self.ssl_version
- })
-
- if sys.version_info >= (2, 7):
- ssl_args['ciphers'] = self.ciphers
-
- ssl_socket = ssl.wrap_socket(self.socket, **ssl_args)
-
- if hasattr(self.socket, 'socket'):
- # We are using a testing socket, so preserve the top
- # layer of wrapping.
- self.socket.socket = ssl_socket
- else:
- self.socket = ssl_socket
-
- try:
- if not self.use_proxy:
- domain = self.address[0]
- if ':' in domain:
- domain = '[%s]' % domain
- log.debug("Connecting to %s:%s", domain, self.address[1])
- self.socket.connect(self.address)
-
- if self.use_ssl:
- try:
- self.socket.do_handshake()
- except (Socket.error, ssl.SSLError):
- log.error('CERT: Invalid certificate trust chain.')
- if not self.event_handled('ssl_invalid_chain'):
- self.disconnect(self.auto_reconnect,
- send_close=False)
- else:
- self.event('ssl_invalid_chain', direct=True)
- return False
-
- self._der_cert = self.socket.getpeercert(binary_form=True)
- pem_cert = ssl.DER_cert_to_PEM_cert(self._der_cert)
- log.debug('CERT: %s', pem_cert)
-
- self.event('ssl_cert', pem_cert, direct=True)
- try:
- cert.verify(self._expected_server_name, self._der_cert)
- except cert.CertificateError as err:
- if not self.event_handled('ssl_invalid_cert'):
- log.error(err)
- self.disconnect(send_close=False)
- else:
- self.event('ssl_invalid_cert',
- pem_cert,
- direct=True)
-
- self.set_socket(self.socket, ignore=True)
- #this event is where you should set your application state
- self.event('connected', direct=True)
- return True
- except (Socket.error, ssl.SSLError) as serr:
- error_msg = "Could not connect to %s:%s. Socket Error #%s: %s"
- self.event('socket_error', serr, direct=True)
- domain = self.address[0]
- if ':' in domain:
- domain = '[%s]' % domain
- log.error(error_msg, domain, self.address[1],
- serr.errno, serr.strerror)
- return False
-
- def _connect_proxy(self):
- """Attempt to connect using an HTTP Proxy."""
-
- # Extract the proxy address, and optional credentials
- address = (self.proxy_config['host'], int(self.proxy_config['port']))
- cred = None
- if self.proxy_config['username']:
- username = self.proxy_config['username']
- password = self.proxy_config['password']
-
- cred = '%s:%s' % (username, password)
- if sys.version_info < (3, 0):
- cred = bytes(cred)
- else:
- cred = bytes(cred, 'utf-8')
- cred = base64.b64encode(cred).decode('utf-8')
-
- # Build the HTTP headers for connecting to the XMPP server
- headers = ['CONNECT %s:%s HTTP/1.0' % self.address,
- 'Host: %s:%s' % self.address,
- 'Proxy-Connection: Keep-Alive',
- 'Pragma: no-cache',
- 'User-Agent: SleekXMPP/%s' % sleekxmpp.__version__]
- if cred:
- headers.append('Proxy-Authorization: Basic %s' % cred)
- headers = '\r\n'.join(headers) + '\r\n\r\n'
-
- try:
- log.debug("Connecting to proxy: %s:%s", *address)
- self.socket.connect(address)
- self.send_raw(headers, now=True)
- resp = ''
- while '\r\n\r\n' not in resp and not self.stop.is_set():
- resp += self.socket.recv(1024).decode('utf-8')
- log.debug('RECV: %s', resp)
-
- lines = resp.split('\r\n')
- if '200' not in lines[0]:
- self.event('proxy_error', resp)
- self.event('connection_failed', direct=True)
- log.error('Proxy Error: %s', lines[0])
- return False
-
- # Proxy connection established, continue connecting
- # with the XMPP server.
- return True
- except (Socket.error, ssl.SSLError) as serr:
- error_msg = "Could not connect to %s:%s. Socket Error #%s: %s"
- self.event('socket_error', serr, direct=True)
- log.error(error_msg, self.address[0], self.address[1],
- serr.errno, serr.strerror)
- return False
-
- def _session_timeout_check(self, event=None):
- """
- Add check to ensure that a session is established within
- a reasonable amount of time.
- """
-
- def _handle_session_timeout():
- if not self.session_started_event.is_set():
- log.debug("Session start has taken more " + \
- "than %d seconds", self.session_timeout)
- self.disconnect(reconnect=self.auto_reconnect)
-
- self.schedule("Session timeout check",
- self.session_timeout,
- _handle_session_timeout)
-
- def disconnect(self, reconnect=False, wait=None, send_close=True):
- """Terminate processing and close the XML streams.
-
- Optionally, the connection may be reconnected and
- resume processing afterwards.
-
- If the disconnect should take place after all items
- in the send queue have been sent, use ``wait=True``.
-
- .. warning::
-
- If you are constantly adding items to the queue
- such that it is never empty, then the disconnect will
- not occur and the call will continue to block.
-
- :param reconnect: Flag indicating if the connection
- and processing should be restarted.
- Defaults to ``False``.
- :param wait: Flag indicating if the send queue should
- be emptied before disconnecting, overriding
- :attr:`disconnect_wait`.
- :param send_close: Flag indicating if the stream footer
- should be sent before terminating the
- connection. Setting this to ``False``
- prevents error loops when trying to
- disconnect after a socket error.
- """
- self.state.transition('connected', 'disconnected',
- wait=2.0,
- func=self._disconnect,
- args=(reconnect, wait, send_close))
-
- def _disconnect(self, reconnect=False, wait=None, send_close=True):
- if not reconnect:
- self.auto_reconnect = False
-
- if self.end_session_on_disconnect or send_close:
- self.event('session_end', direct=True)
-
- # Wait for the send queue to empty.
- if wait is not None:
- if wait:
- self.send_queue.join()
- elif self.disconnect_wait:
- self.send_queue.join()
-
- # Clearing this event will pause the send loop.
- self.session_started_event.clear()
-
- self.__failed_send_stanza = None
-
- # Send the end of stream marker.
- if send_close:
- self.send_raw(self.stream_footer, now=True)
-
- # Wait for confirmation that the stream was
- # closed in the other direction. If we didn't
- # send a stream footer we don't need to wait
- # since the server won't know to respond.
- if send_close:
- log.info('Waiting for %s from server', self.stream_footer)
- self.stream_end_event.wait(4)
- else:
- self.stream_end_event.set()
-
- if not self.auto_reconnect:
- self.set_stop()
- if self._disconnect_wait_for_threads:
- self._wait_for_threads()
-
- try:
- self.socket.shutdown(Socket.SHUT_RDWR)
- self.socket.close()
- self.filesocket.close()
- except (Socket.error, ssl.SSLError) as serr:
- self.event('socket_error', serr, direct=True)
- finally:
- #clear your application state
- self.event('disconnected', direct=True)
- return True
-
- def abort(self):
- self.session_started_event.clear()
- self.set_stop()
- if self._disconnect_wait_for_threads:
- self._wait_for_threads()
- try:
- self.socket.shutdown(Socket.SHUT_RDWR)
- self.socket.close()
- self.filesocket.close()
- except Socket.error:
- pass
- self.state.transition_any(['connected', 'disconnected'], 'disconnected', func=lambda: True)
- self.event("killed", direct=True)
-
- def reconnect(self, reattempt=True, wait=False, send_close=True):
- """Reset the stream's state and reconnect to the server."""
- log.debug("reconnecting...")
- if self.state.ensure('connected'):
- self.state.transition('connected', 'disconnected',
- wait=2.0,
- func=self._disconnect,
- args=(True, wait, send_close))
-
- attempts = self.reconnect_max_attempts
-
- log.debug("connecting...")
- connected = self.state.transition('disconnected', 'connected',
- wait=2.0,
- func=self._connect,
- args=(reattempt,))
- while reattempt and not connected and not self.stop.is_set():
- connected = self.state.transition('disconnected', 'connected',
- wait=2.0, func=self._connect)
- connected = connected or self.state.ensure('connected')
- if not connected:
- if attempts is not None:
- attempts -= 1
- if attempts <= 0:
- self.event('connection_failed', direct=True)
- return False
- return connected
-
- def set_socket(self, socket, ignore=False):
- """Set the socket to use for the stream.
-
- The filesocket will be recreated as well.
-
- :param socket: The new socket object to use.
- :param bool ignore: If ``True``, don't set the connection
- state to ``'connected'``.
- """
- self.socket = socket
- if socket is not None:
- # ElementTree.iterparse requires a file.
- # 0 buffer files have to be binary.
-
- # Use the correct fileobject type based on the Python
- # version to work around a broken implementation in
- # Python 2.x.
- if sys.version_info < (3, 0):
- self.filesocket = FileSocket(self.socket)
- else:
- self.filesocket = self.socket.makefile('rb', 0)
- if not ignore:
- self.state._set_state('connected')
-
- def configure_socket(self):
- """Set timeout and other options for self.socket.
-
- Meant to be overridden.
- """
- self.socket.settimeout(None)
-
- def configure_dns(self, resolver, domain=None, port=None):
- """
- Configure and set options for a :class:`~dns.resolver.Resolver`
- instance, and other DNS related tasks. For example, you
- can also check :meth:`~socket.socket.getaddrinfo` to see
- if you need to call out to ``libresolv.so.2`` to
- run ``res_init()``.
-
- Meant to be overridden.
-
- :param resolver: A :class:`~dns.resolver.Resolver` instance
- or ``None`` if ``dnspython`` is not installed.
- :param domain: The initial domain under consideration.
- :param port: The initial port under consideration.
- """
- pass
-
- def start_tls(self):
- """Perform handshakes for TLS.
-
- If the handshake is successful, the XML stream will need
- to be restarted.
- """
- log.info("Negotiating TLS")
- ssl_versions = {3: 'TLS 1.0', 1: 'SSL 3', 2: 'SSL 2/3'}
- log.info("Using SSL version: %s", ssl_versions[self.ssl_version])
- if self.ca_certs is None:
- cert_policy = ssl.CERT_NONE
- else:
- cert_policy = ssl.CERT_REQUIRED
-
- ssl_args = safedict({
- 'certfile': self.certfile,
- 'keyfile': self.keyfile,
- 'ca_certs': self.ca_certs,
- 'cert_reqs': cert_policy,
- 'do_handshake_on_connect': False,
- "ssl_version": self.ssl_version
- })
-
- if sys.version_info >= (2, 7):
- ssl_args['ciphers'] = self.ciphers
-
- ssl_socket = ssl.wrap_socket(self.socket, **ssl_args)
-
- if hasattr(self.socket, 'socket'):
- # We are using a testing socket, so preserve the top
- # layer of wrapping.
- self.socket.socket = ssl_socket
- else:
- self.socket = ssl_socket
-
- try:
- self.socket.do_handshake()
- except (Socket.error, ssl.SSLError):
- log.error('CERT: Invalid certificate trust chain.')
- if not self.event_handled('ssl_invalid_chain'):
- self.disconnect(self.auto_reconnect, send_close=False)
- else:
- self._der_cert = self.socket.getpeercert(binary_form=True)
- self.event('ssl_invalid_chain', direct=True)
- return False
-
- self._der_cert = self.socket.getpeercert(binary_form=True)
- pem_cert = ssl.DER_cert_to_PEM_cert(self._der_cert)
- log.debug('CERT: %s', pem_cert)
- self.event('ssl_cert', pem_cert, direct=True)
-
- try:
- cert.verify(self._expected_server_name, self._der_cert)
- except cert.CertificateError as err:
- if not self.event_handled('ssl_invalid_cert'):
- log.error(err)
- self.disconnect(self.auto_reconnect, send_close=False)
- else:
- self.event('ssl_invalid_cert', pem_cert, direct=True)
-
- self.set_socket(self.socket)
- return True
-
- def _cert_expiration(self, event):
- """Schedule an event for when the TLS certificate expires."""
-
- if not self.use_tls and not self.use_ssl:
- return
-
- if not self._der_cert:
- log.warn("TLS or SSL was enabled, but no certificate was found.")
- return
-
- def restart():
- if not self.event_handled('ssl_expired_cert'):
- log.warn("The server certificate has expired. Restarting.")
- self.reconnect()
- else:
- pem_cert = ssl.DER_cert_to_PEM_cert(self._der_cert)
- self.event('ssl_expired_cert', pem_cert)
-
- cert_ttl = cert.get_ttl(self._der_cert)
- if cert_ttl is None:
- return
-
- if cert_ttl.days < 0:
- log.warn('CERT: Certificate has expired.')
- restart()
-
- try:
- total_seconds = cert_ttl.total_seconds()
- except AttributeError:
- # for Python < 2.7
- total_seconds = (cert_ttl.microseconds + (cert_ttl.seconds + cert_ttl.days * 24 * 3600) * 10**6) / 10**6
-
- log.info('CERT: Time until certificate expiration: %s' % cert_ttl)
- self.schedule('Certificate Expiration',
- total_seconds,
- restart)
-
- def _start_keepalive(self, event):
- """Begin sending whitespace periodically to keep the connection alive.
-
- May be disabled by setting::
-
- self.whitespace_keepalive = False
-
- The keepalive interval can be set using::
-
- self.whitespace_keepalive_interval = 300
- """
- if self.whitespace_keepalive:
- self.schedule('Whitespace Keepalive',
- self.whitespace_keepalive_interval,
- self.send_raw,
- args=(' ',),
- kwargs={'now': True},
- repeat=True)
-
- def _remove_schedules(self, event):
- """Remove whitespace keepalive and certificate expiration schedules."""
- self.scheduler.remove('Whitespace Keepalive')
- self.scheduler.remove('Certificate Expiration')
-
- def start_stream_handler(self, xml):
- """Perform any initialization actions, such as handshakes,
- once the stream header has been sent.
-
- Meant to be overridden.
- """
- pass
-
- def register_stanza(self, stanza_class):
- """Add a stanza object class as a known root stanza.
-
- A root stanza is one that appears as a direct child of the stream's
- root element.
-
- Stanzas that appear as substanzas of a root stanza do not need to
- be registered here. That is done using register_stanza_plugin() from
- sleekxmpp.xmlstream.stanzabase.
-
- Stanzas that are not registered will not be converted into
- stanza objects, but may still be processed using handlers and
- matchers.
-
- :param stanza_class: The top-level stanza object's class.
- """
- self.__root_stanza.append(stanza_class)
-
- def remove_stanza(self, stanza_class):
- """Remove a stanza from being a known root stanza.
-
- A root stanza is one that appears as a direct child of the stream's
- root element.
-
- Stanzas that are not registered will not be converted into
- stanza objects, but may still be processed using handlers and
- matchers.
- """
- self.__root_stanza.remove(stanza_class)
-
- def add_filter(self, mode, handler, order=None):
- """Add a filter for incoming or outgoing stanzas.
-
- These filters are applied before incoming stanzas are
- passed to any handlers, and before outgoing stanzas
- are put in the send queue.
-
- Each filter must accept a single stanza, and return
- either a stanza or ``None``. If the filter returns
- ``None``, then the stanza will be dropped from being
- processed for events or from being sent.
-
- :param mode: One of ``'in'`` or ``'out'``.
- :param handler: The filter function.
- :param int order: The position to insert the filter in
- the list of active filters.
- """
- if order:
- self.__filters[mode].insert(order, handler)
- else:
- self.__filters[mode].append(handler)
-
- def del_filter(self, mode, handler):
- """Remove an incoming or outgoing filter."""
- self.__filters[mode].remove(handler)
-
- def add_handler(self, mask, pointer, name=None, disposable=False,
- threaded=False, filter=False, instream=False):
- """A shortcut method for registering a handler using XML masks.
-
- The use of :meth:`register_handler()` is preferred.
-
- :param mask: An XML snippet matching the structure of the
- stanzas that will be passed to this handler.
- :param pointer: The handler function itself.
- :parm name: A unique name for the handler. A name will
- be generated if one is not provided.
- :param disposable: Indicates if the handler should be discarded
- after one use.
- :param threaded: **DEPRECATED**.
- Remains for backwards compatibility.
- :param filter: **DEPRECATED**.
- Remains for backwards compatibility.
- :param instream: Indicates if the handler should execute during
- stream processing and not during normal event
- processing.
- """
- # To prevent circular dependencies, we must load the matcher
- # and handler classes here.
-
- if name is None:
- name = 'add_handler_%s' % self.new_id()
- self.register_handler(
- XMLCallback(name,
- MatchXMLMask(mask, self.default_ns),
- pointer,
- once=disposable,
- instream=instream))
-
- def register_handler(self, handler, before=None, after=None):
- """Add a stream event handler that will be executed when a matching
- stanza is received.
-
- :param handler:
- The :class:`~sleekxmpp.xmlstream.handler.base.BaseHandler`
- derived object to execute.
- """
- if handler.stream is None:
- self.__handlers.append(handler)
- handler.stream = weakref.ref(self)
-
- def remove_handler(self, name):
- """Remove any stream event handlers with the given name.
-
- :param name: The name of the handler.
- """
- idx = 0
- for handler in self.__handlers:
- if handler.name == name:
- self.__handlers.pop(idx)
- return True
- idx += 1
- return False
-
- def get_dns_records(self, domain, port=None):
- """Get the DNS records for a domain.
-
- :param domain: The domain in question.
- :param port: If the results don't include a port, use this one.
- """
- if port is None:
- port = self.default_port
-
- resolver = default_resolver()
- self.configure_dns(resolver, domain=domain, port=port)
-
- return resolve(domain, port, service=self.dns_service,
- resolver=resolver,
- use_ipv6=self.use_ipv6,
- use_dnspython=self.use_dnspython)
-
- def pick_dns_answer(self, domain, port=None):
- """Pick a server and port from DNS answers.
-
- Gets DNS answers if none available.
- Removes used answer from available answers.
-
- :param domain: The domain in question.
- :param port: If the results don't include a port, use this one.
- """
- if not self.dns_answers:
- self.dns_answers = self.get_dns_records(domain, port)
-
- if sys.version_info < (3, 0):
- return self.dns_answers.next()
- else:
- return next(self.dns_answers)
-
- def add_event_handler(self, name, pointer,
- threaded=False, disposable=False):
- """Add a custom event handler that will be executed whenever
- its event is manually triggered.
-
- :param name: The name of the event that will trigger
- this handler.
- :param pointer: The function to execute.
- :param threaded: If set to ``True``, the handler will execute
- in its own thread. Defaults to ``False``.
- :param disposable: If set to ``True``, the handler will be
- discarded after one use. Defaults to ``False``.
- """
- if not name in self.__event_handlers:
- self.__event_handlers[name] = []
- self.__event_handlers[name].append((pointer, threaded, disposable))
-
- def del_event_handler(self, name, pointer):
- """Remove a function as a handler for an event.
-
- :param name: The name of the event.
- :param pointer: The function to remove as a handler.
- """
- if not name in self.__event_handlers:
- return
-
- # Need to keep handlers that do not use
- # the given function pointer
- def filter_pointers(handler):
- return handler[0] != pointer
-
- self.__event_handlers[name] = list(filter(
- filter_pointers,
- self.__event_handlers[name]))
-
- def event_handled(self, name):
- """Returns the number of registered handlers for an event.
-
- :param name: The name of the event to check.
- """
- return len(self.__event_handlers.get(name, []))
-
- def event(self, name, data=None, direct=False):
- """Manually trigger a custom event.
-
- :param name: The name of the event to trigger.
- :param data: Data that will be passed to each event handler.
- Defaults to an empty dictionary, but is usually
- a stanza object.
- :param direct: Runs the event directly if True, skipping the
- event queue. All event handlers will run in the
- same thread.
- """
- if not data:
- data = {}
-
- log.debug("Event triggered: " + name)
-
- handlers = self.__event_handlers.get(name, [])
- for handler in handlers:
- #TODO: Data should not be copied, but should be read only,
- # but this might break current code so it's left for future.
-
- out_data = copy.copy(data) if len(handlers) > 1 else data
- old_exception = getattr(data, 'exception', None)
- if direct:
- try:
- handler[0](out_data)
- except Exception as e:
- error_msg = 'Error processing event handler: %s'
- log.exception(error_msg, str(handler[0]))
- if old_exception:
- old_exception(e)
- else:
- self.exception(e)
- else:
- self.event_queue.put(('event', handler, out_data))
- if handler[2]:
- # If the handler is disposable, we will go ahead and
- # remove it now instead of waiting for it to be
- # processed in the queue.
- with self.__event_handlers_lock:
- try:
- h_index = self.__event_handlers[name].index(handler)
- self.__event_handlers[name].pop(h_index)
- except:
- pass
-
- def schedule(self, name, seconds, callback, args=None,
- kwargs=None, repeat=False):
- """Schedule a callback function to execute after a given delay.
-
- :param name: A unique name for the scheduled callback.
- :param seconds: The time in seconds to wait before executing.
- :param callback: A pointer to the function to execute.
- :param args: A tuple of arguments to pass to the function.
- :param kwargs: A dictionary of keyword arguments to pass to
- the function.
- :param repeat: Flag indicating if the scheduled event should
- be reset and repeat after executing.
- """
- self.scheduler.add(name, seconds, callback, args, kwargs,
- repeat, qpointer=self.event_queue)
-
- def incoming_filter(self, xml):
- """Filter incoming XML objects before they are processed.
-
- Possible uses include remapping namespaces, or correcting elements
- from sources with incorrect behavior.
-
- Meant to be overridden.
- """
- return xml
-
- def send(self, data, mask=None, timeout=None, now=False, use_filters=True):
- """A wrapper for :meth:`send_raw()` for sending stanza objects.
-
- May optionally block until an expected response is received.
-
- :param data: The :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase`
- stanza to send on the stream.
- :param mask: **DEPRECATED**
- An XML string snippet matching the structure
- of the expected response. Execution will block
- in this thread until the response is received
- or a timeout occurs.
- :param int timeout: Time in seconds to wait for a response before
- continuing. Defaults to :attr:`response_timeout`.
- :param bool now: Indicates if the send queue should be skipped,
- sending the stanza immediately. Useful mainly
- for stream initialization stanzas.
- Defaults to ``False``.
- :param bool use_filters: Indicates if outgoing filters should be
- applied to the given stanza data. Disabling
- filters is useful when resending stanzas.
- Defaults to ``True``.
- """
- if timeout is None:
- timeout = self.response_timeout
- if hasattr(mask, 'xml'):
- mask = mask.xml
-
- if isinstance(data, ElementBase):
- if use_filters:
- for filter in self.__filters['out']:
- data = filter(data)
- if data is None:
- return
-
- if mask is not None:
- log.warning("Use of send mask waiters is deprecated.")
- wait_for = Waiter("SendWait_%s" % self.new_id(),
- MatchXMLMask(mask))
- self.register_handler(wait_for)
-
- if isinstance(data, ElementBase):
- with self.send_queue_lock:
- if use_filters:
- for filter in self.__filters['out_sync']:
- data = filter(data)
- if data is None:
- return
- str_data = tostring(data.xml, xmlns=self.default_ns,
- stream=self,
- top_level=True)
- self.send_raw(str_data, now)
- else:
- self.send_raw(data, now)
- if mask is not None:
- return wait_for.wait(timeout)
-
- def send_xml(self, data, mask=None, timeout=None, now=False):
- """Send an XML object on the stream, and optionally wait
- for a response.
-
- :param data: The :class:`~xml.etree.ElementTree.Element` XML object
- to send on the stream.
- :param mask: **DEPRECATED**
- An XML string snippet matching the structure
- of the expected response. Execution will block
- in this thread until the response is received
- or a timeout occurs.
- :param int timeout: Time in seconds to wait for a response before
- continuing. Defaults to :attr:`response_timeout`.
- :param bool now: Indicates if the send queue should be skipped,
- sending the stanza immediately. Useful mainly
- for stream initialization stanzas.
- Defaults to ``False``.
- """
- if timeout is None:
- timeout = self.response_timeout
- return self.send(tostring(data), mask, timeout, now)
-
- def send_raw(self, data, now=False, reconnect=None):
- """Send raw data across the stream.
-
- :param string data: Any string value.
- :param bool reconnect: Indicates if the stream should be
- restarted if there is an error sending
- the stanza. Used mainly for testing.
- Defaults to :attr:`auto_reconnect`.
- """
- if now:
- log.debug("SEND (IMMED): %s", data)
- try:
- data = data.encode('utf-8')
- total = len(data)
- sent = 0
- count = 0
- tries = 0
- with self.send_lock:
- while sent < total and not self.stop.is_set():
- try:
- sent += self.socket.send(data[sent:])
- count += 1
- except ssl.SSLError as serr:
- if tries >= self.ssl_retry_max:
- log.debug('SSL error: max retries reached')
- self.exception(serr)
- log.warning("Failed to send %s", data)
- if reconnect is None:
- reconnect = self.auto_reconnect
- if not self.stop.is_set():
- self.disconnect(reconnect,
- send_close=False)
- log.warning('SSL write error: retrying')
- if not self.stop.is_set():
- time.sleep(self.ssl_retry_delay)
- tries += 1
- except Socket.error as serr:
- if serr.errno != errno.EINTR:
- raise
- if count > 1:
- log.debug('SENT: %d chunks', count)
- except (Socket.error, ssl.SSLError) as serr:
- self.event('socket_error', serr, direct=True)
- log.warning("Failed to send %s", data)
- if reconnect is None:
- reconnect = self.auto_reconnect
- if not self.stop.is_set():
- self.disconnect(reconnect, send_close=False)
- else:
- self.send_queue.put(data)
- return True
-
- def _start_thread(self, name, target, track=True):
- self.__thread[name] = threading.Thread(name=name, target=target)
- self.__thread[name].daemon = self._use_daemons
- self.__thread[name].start()
-
- if track:
- self.__active_threads.add(name)
- with self.__thread_cond:
- self.__thread_count += 1
-
- def _end_thread(self, name, early=False):
- with self.__thread_cond:
- curr_thread = threading.current_thread().name
- if curr_thread in self.__active_threads:
- self.__thread_count -= 1
- self.__active_threads.remove(curr_thread)
-
- if early:
- log.debug('Threading deadlock prevention!')
- log.debug(("Marked %s thread as ended due to " + \
- "disconnect() call. %s threads remain.") % (
- name, self.__thread_count))
- else:
- log.debug("Stopped %s thread. %s threads remain." % (
- name, self.__thread_count))
-
- else:
- log.debug(("Finished exiting %s thread after early " + \
- "termination from disconnect() call. " + \
- "%s threads remain.") % (
- name, self.__thread_count))
-
- if self.__thread_count == 0:
- self.__thread_cond.notify()
-
- def set_stop(self):
- self.stop.set()
-
- # Unlock queues
- self.event_queue.put(None)
- self.send_queue.put(None)
-
- def _wait_for_threads(self):
- with self.__thread_cond:
- if self.__thread_count != 0:
- log.debug("Waiting for %s threads to exit." %
- self.__thread_count)
- name = threading.current_thread().name
- if name in self.__thread:
- self._end_thread(name, early=True)
- self.__thread_cond.wait(4)
- if self.__thread_count != 0:
- log.error("Hanged threads: %s" % threading.enumerate())
- log.error("This may be due to calling disconnect() " + \
- "from a non-threaded event handler. Be " + \
- "sure that event handlers that call " + \
- "disconnect() are registered using: " + \
- "add_event_handler(..., threaded=True)")
-
- def process(self, **kwargs):
- """Initialize the XML streams and begin processing events.
-
- The number of threads used for processing stream events is determined
- by :data:`HANDLER_THREADS`.
-
- :param bool block: If ``False``, then event dispatcher will run
- in a separate thread, allowing for the stream to be
- used in the background for another application.
- Otherwise, ``process(block=True)`` blocks the current
- thread. Defaults to ``False``.
- :param bool threaded: **DEPRECATED**
- If ``True``, then event dispatcher will run
- in a separate thread, allowing for the stream to be
- used in the background for another application.
- Defaults to ``True``. This does **not** mean that no
- threads are used at all if ``threaded=False``.
-
- Regardless of these threading options, these threads will
- always exist:
-
- - The event queue processor
- - The send queue processor
- - The scheduler
- """
- if 'threaded' in kwargs and 'block' in kwargs:
- raise ValueError("process() called with both " + \
- "block and threaded arguments")
- elif 'block' in kwargs:
- threaded = not(kwargs.get('block', False))
- else:
- threaded = kwargs.get('threaded', True)
-
- for t in range(0, HANDLER_THREADS):
- log.debug("Starting HANDLER THREAD")
- self._start_thread('event_thread_%s' % t, self._event_runner)
-
- self._start_thread('send_thread', self._send_thread)
- self._start_thread('scheduler_thread', self._scheduler_thread)
-
- if threaded:
- # Run the XML stream in the background for another application.
- self._start_thread('read_thread', self._process, track=False)
- else:
- self._process()
-
- def _process(self):
- """Start processing the XML streams.
-
- Processing will continue after any recoverable errors
- if reconnections are allowed.
- """
-
- # The body of this loop will only execute once per connection.
- # Additional passes will be made only if an error occurs and
- # reconnecting is permitted.
- while True:
- shutdown = False
- try:
- # The call to self.__read_xml will block and prevent
- # the body of the loop from running until a disconnect
- # occurs. After any reconnection, the stream header will
- # be resent and processing will resume.
- while not self.stop.is_set():
- # Only process the stream while connected to the server
- if not self.state.ensure('connected', wait=0.1):
- break
- # Ensure the stream header is sent for any
- # new connections.
- if not self.session_started_event.is_set():
- self.send_raw(self.stream_header, now=True)
- if not self.__read_xml():
- # If the server terminated the stream, end processing
- break
- except KeyboardInterrupt:
- log.debug("Keyboard Escape Detected in _process")
- self.event('killed', direct=True)
- shutdown = True
- except SystemExit:
- log.debug("SystemExit in _process")
- shutdown = True
- except (SyntaxError, ExpatError) as e:
- log.error("Error reading from XML stream.")
- self.exception(e)
- except (Socket.error, ssl.SSLError) as serr:
- self.event('socket_error', serr, direct=True)
- log.error('Socket Error #%s: %s', serr.errno, serr.strerror)
- except ValueError as e:
- msg = e.message if hasattr(e, 'message') else e.args[0]
-
- if 'I/O operation on closed file' in msg:
- log.error('Can not read from closed socket.')
- else:
- self.exception(e)
- except Exception as e:
- if not self.stop.is_set():
- log.error('Connection error.')
- self.exception(e)
-
- if not shutdown and not self.stop.is_set() \
- and self.auto_reconnect:
- self.reconnect()
- else:
- self.disconnect()
- break
-
- def __read_xml(self):
- """Parse the incoming XML stream
-
- Stream events are raised for each received stanza.
- """
- depth = 0
- root = None
- for event, xml in ET.iterparse(self.filesocket, (b'end', b'start')):
- if event == b'start':
- if depth == 0:
- # We have received the start of the root element.
- root = xml
- log.debug('RECV: %s', tostring(root, xmlns=self.default_ns,
- stream=self,
- top_level=True,
- open_only=True))
- # Perform any stream initialization actions, such
- # as handshakes.
- self.stream_end_event.clear()
- self.start_stream_handler(root)
-
- # We have a successful stream connection, so reset
- # exponential backoff for new reconnect attempts.
- self.reconnect_delay = 1.0
- depth += 1
- if event == b'end':
- depth -= 1
- if depth == 0:
- # The stream's root element has closed,
- # terminating the stream.
- log.debug("End of stream recieved")
- self.stream_end_event.set()
- return False
- elif depth == 1:
- # We only raise events for stanzas that are direct
- # children of the root element.
- try:
- self.__spawn_event(xml)
- except RestartStream:
- return True
- if root is not None:
- # Keep the root element empty of children to
- # save on memory use.
- root.clear()
- log.debug("Ending read XML loop")
-
- def _build_stanza(self, xml, default_ns=None):
- """Create a stanza object from a given XML object.
-
- If a specialized stanza type is not found for the XML, then
- a generic :class:`~sleekxmpp.xmlstream.stanzabase.StanzaBase`
- stanza will be returned.
-
- :param xml: The :class:`~xml.etree.ElementTree.Element` XML object
- to convert into a stanza object.
- :param default_ns: Optional default namespace to use instead of the
- stream's current default namespace.
- """
- if default_ns is None:
- default_ns = self.default_ns
- stanza_type = StanzaBase
- for stanza_class in self.__root_stanza:
- if xml.tag == "{%s}%s" % (default_ns, stanza_class.name) or \
- xml.tag == stanza_class.tag_name():
- stanza_type = stanza_class
- break
- stanza = stanza_type(self, xml)
- if stanza['lang'] is None and self.peer_default_lang:
- stanza['lang'] = self.peer_default_lang
- return stanza
-
- def __spawn_event(self, xml):
- """
- Analyze incoming XML stanzas and convert them into stanza
- objects if applicable and queue stream events to be processed
- by matching handlers.
-
- :param xml: The :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase`
- stanza to analyze.
- """
- # Apply any preprocessing filters.
- xml = self.incoming_filter(xml)
-
- # Convert the raw XML object into a stanza object. If no registered
- # stanza type applies, a generic StanzaBase stanza will be used.
- stanza = self._build_stanza(xml)
-
- for filter in self.__filters['in']:
- if stanza is not None:
- stanza = filter(stanza)
- if stanza is None:
- return
-
- log.debug("RECV: %s", stanza)
-
- # Match the stanza against registered handlers. Handlers marked
- # to run "in stream" will be executed immediately; the rest will
- # be queued.
- unhandled = True
- matched_handlers = [h for h in self.__handlers if h.match(stanza)]
- for handler in matched_handlers:
- if len(matched_handlers) > 1:
- stanza_copy = copy.copy(stanza)
- else:
- stanza_copy = stanza
- handler.prerun(stanza_copy)
- self.event_queue.put(('stanza', handler, stanza_copy))
- try:
- if handler.check_delete():
- self.__handlers.remove(handler)
- except:
- pass # not thread safe
- unhandled = False
-
- # Some stanzas require responses, such as Iq queries. A default
- # handler will be executed immediately for this case.
- if unhandled:
- stanza.unhandled()
-
- def _threaded_event_wrapper(self, func, args):
- """Capture exceptions for event handlers that run
- in individual threads.
-
- :param func: The event handler to execute.
- :param args: Arguments to the event handler.
- """
- # this is always already copied before this is invoked
- orig = args[0]
- try:
- func(*args)
- except Exception as e:
- error_msg = 'Error processing event handler: %s'
- log.exception(error_msg, str(func))
- if hasattr(orig, 'exception'):
- orig.exception(e)
- else:
- self.exception(e)
-
- def _event_runner(self):
- """Process the event queue and execute handlers.
-
- The number of event runner threads is controlled by HANDLER_THREADS.
-
- Stream event handlers will all execute in this thread. Custom event
- handlers may be spawned in individual threads.
- """
- log.debug("Loading event runner")
- try:
- while not self.stop.is_set():
- event = self.event_queue.get()
- if event is None:
- continue
-
- etype, handler = event[0:2]
- args = event[2:]
- orig = copy.copy(args[0])
-
- if etype == 'stanza':
- try:
- handler.run(args[0])
- except Exception as e:
- error_msg = 'Error processing stream handler: %s'
- log.exception(error_msg, handler.name)
- orig.exception(e)
- elif etype == 'schedule':
- name = args[2]
- try:
- log.debug('Scheduled event: %s: %s', name, args[0])
- handler(*args[0], **args[1])
- except Exception as e:
- log.exception('Error processing scheduled task')
- self.exception(e)
- elif etype == 'event':
- func, threaded, disposable = handler
- try:
- if threaded:
- x = threading.Thread(
- name="Event_%s" % str(func),
- target=self._threaded_event_wrapper,
- args=(func, args))
- x.daemon = self._use_daemons
- x.start()
- else:
- func(*args)
- except Exception as e:
- error_msg = 'Error processing event handler: %s'
- log.exception(error_msg, str(func))
- if hasattr(orig, 'exception'):
- orig.exception(e)
- else:
- self.exception(e)
- elif etype == 'quit':
- log.debug("Quitting event runner thread")
- break
- except KeyboardInterrupt:
- log.debug("Keyboard Escape Detected in _event_runner")
- self.event('killed', direct=True)
- self.disconnect()
- except SystemExit:
- self.disconnect()
- self.event_queue.put(('quit', None, None))
-
- self._end_thread('event runner')
-
- def _send_thread(self):
- """Extract stanzas from the send queue and send them on the stream."""
- try:
- while not self.stop.is_set():
- while not self.stop.is_set() and \
- not self.session_started_event.is_set():
- self.session_started_event.wait(timeout=0.1) # Wait for session start
- if self.__failed_send_stanza is not None:
- data = self.__failed_send_stanza
- self.__failed_send_stanza = None
- else:
- data = self.send_queue.get() # Wait for data to send
- if data is None:
- continue
- log.debug("SEND: %s", data)
- enc_data = data.encode('utf-8')
- total = len(enc_data)
- sent = 0
- count = 0
- tries = 0
- try:
- with self.send_lock:
- while sent < total and not self.stop.is_set() and \
- self.session_started_event.is_set():
- try:
- sent += self.socket.send(enc_data[sent:])
- count += 1
- except ssl.SSLError as serr:
- if tries >= self.ssl_retry_max:
- log.debug('SSL error: max retries reached')
- self.exception(serr)
- log.warning("Failed to send %s", data)
- if not self.stop.is_set():
- self.disconnect(self.auto_reconnect,
- send_close=False)
- log.warning('SSL write error: retrying')
- if not self.stop.is_set():
- time.sleep(self.ssl_retry_delay)
- tries += 1
- except Socket.error as serr:
- if serr.errno != errno.EINTR:
- raise
- if count > 1:
- log.debug('SENT: %d chunks', count)
- self.send_queue.task_done()
- except (Socket.error, ssl.SSLError) as serr:
- self.event('socket_error', serr, direct=True)
- log.warning("Failed to send %s", data)
- if not self.stop.is_set():
- self.__failed_send_stanza = data
- self._end_thread('send')
- self.disconnect(self.auto_reconnect, send_close=False)
- return
- except Exception as ex:
- log.exception('Unexpected error in send thread: %s', ex)
- self.exception(ex)
- if not self.stop.is_set():
- self._end_thread('send')
- self.disconnect(self.auto_reconnect)
- return
-
- self._end_thread('send')
-
- def _scheduler_thread(self):
- self.scheduler.process(threaded=False)
- self._end_thread('scheduler')
-
- def exception(self, exception):
- """Process an unknown exception.
-
- Meant to be overridden.
-
- :param exception: An unhandled exception object.
- """
- pass
-
-
-# To comply with PEP8, method names now use underscores.
-# Deprecated method names are re-mapped for backwards compatibility.
-XMLStream.startTLS = XMLStream.start_tls
-XMLStream.registerStanza = XMLStream.register_stanza
-XMLStream.removeStanza = XMLStream.remove_stanza
-XMLStream.registerHandler = XMLStream.register_handler
-XMLStream.removeHandler = XMLStream.remove_handler
-XMLStream.setSocket = XMLStream.set_socket
-XMLStream.sendRaw = XMLStream.send_raw
-XMLStream.getId = XMLStream.get_id
-XMLStream.getNewId = XMLStream.new_id
-XMLStream.sendXML = XMLStream.send_xml
diff --git a/slixmpp/__init__.py b/slixmpp/__init__.py
new file mode 100644
index 00000000..c09446df
--- /dev/null
+++ b/slixmpp/__init__.py
@@ -0,0 +1,26 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+import asyncio
+asyncio.sslproto._is_sslproto_available=lambda: False
+import logging
+logging.getLogger(__name__).addHandler(logging.NullHandler())
+
+
+from slixmpp.stanza import Message, Presence, Iq
+from slixmpp.jid import JID, InvalidJID
+from slixmpp.xmlstream.stanzabase import ET, ElementBase, register_stanza_plugin
+from slixmpp.xmlstream.handler import *
+from slixmpp.xmlstream import XMLStream
+from slixmpp.xmlstream.matcher import *
+from slixmpp.xmlstream.asyncio import asyncio, future_wrapper
+from slixmpp.basexmpp import BaseXMPP
+from slixmpp.clientxmpp import ClientXMPP
+from slixmpp.componentxmpp import ComponentXMPP
+
+from slixmpp.version import __version__, __version_info__
diff --git a/sleekxmpp/api.py b/slixmpp/api.py
index 8de61b34..f09e0365 100644
--- a/sleekxmpp/api.py
+++ b/slixmpp/api.py
@@ -1,4 +1,4 @@
-from sleekxmpp.xmlstream import JID
+from slixmpp.xmlstream import JID
class APIWrapper(object):
diff --git a/sleekxmpp/basexmpp.py b/slixmpp/basexmpp.py
index cb72b9bd..83741bd7 100644
--- a/sleekxmpp/basexmpp.py
+++ b/slixmpp/basexmpp.py
@@ -1,49 +1,39 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.basexmpp
+ slixmpp.basexmpp
~~~~~~~~~~~~~~~~~~
This module provides the common XMPP functionality
for both clients and components.
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
"""
-from __future__ import with_statement, unicode_literals
-
-import sys
import logging
import threading
-from sleekxmpp import plugins, roster, stanza
-from sleekxmpp.api import APIRegistry
-from sleekxmpp.exceptions import IqError, IqTimeout
+from slixmpp import plugins, roster, stanza
+from slixmpp.api import APIRegistry
+from slixmpp.exceptions import IqError, IqTimeout
-from sleekxmpp.stanza import Message, Presence, Iq, StreamError
-from sleekxmpp.stanza.roster import Roster
-from sleekxmpp.stanza.nick import Nick
+from slixmpp.stanza import Message, Presence, Iq, StreamError
+from slixmpp.stanza.roster import Roster
+from slixmpp.stanza.nick import Nick
-from sleekxmpp.xmlstream import XMLStream, JID
-from sleekxmpp.xmlstream import ET, register_stanza_plugin
-from sleekxmpp.xmlstream.matcher import MatchXPath
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.stanzabase import XML_NS
+from slixmpp.xmlstream import XMLStream, JID
+from slixmpp.xmlstream import ET, register_stanza_plugin
+from slixmpp.xmlstream.matcher import MatchXPath
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.stanzabase import XML_NS
-from sleekxmpp.plugins import PluginManager, load_plugin
+from slixmpp.plugins import PluginManager, load_plugin
log = logging.getLogger(__name__)
-# In order to make sure that Unicode is handled properly
-# in Python 2.x, reset the default encoding.
-if sys.version_info < (3, 0):
- from sleekxmpp.util.misc_ops import setdefaultencoding
- setdefaultencoding('utf8')
-
-
class BaseXMPP(XMLStream):
"""
@@ -66,12 +56,12 @@ class BaseXMPP(XMLStream):
self.stream_id = None
#: The JabberID (JID) requested for this connection.
- self.requested_jid = JID(jid, cache_lock=True)
+ self.requested_jid = JID(jid)
#: The JabberID (JID) used by this connection,
#: as set after session binding. This may even be a
#: different bare JID than what was requested.
- self.boundjid = JID(jid, cache_lock=True)
+ self.boundjid = JID(jid)
self._expected_server_name = self.boundjid.host
self._redirect_attempts = 0
@@ -143,7 +133,7 @@ class BaseXMPP(XMLStream):
#: behave as expected when sending stanzas.
self.sentpresence = False
- #: A reference to :mod:`sleekxmpp.stanza` to make accessing
+ #: A reference to :mod:`slixmpp.stanza` to make accessing
#: stanza classes easier.
self.stanza = stanza
@@ -152,6 +142,13 @@ class BaseXMPP(XMLStream):
MatchXPath('{%s}message/{%s}body' % (self.default_ns,
self.default_ns)),
self._handle_message))
+
+ self.register_handler(
+ Callback('IMError',
+ MatchXPath('{%s}message/{%s}error' % (self.default_ns,
+ self.default_ns)),
+ self._handle_message_error))
+
self.register_handler(
Callback('Presence',
MatchXPath("{%s}presence" % self.default_ns),
@@ -212,37 +209,16 @@ class BaseXMPP(XMLStream):
log.warning('Legacy XMPP 0.9 protocol detected.')
self.event('legacy_protocol')
- def process(self, *args, **kwargs):
- """Initialize plugins and begin processing the XML stream.
-
- The number of threads used for processing stream events is determined
- by :data:`HANDLER_THREADS`.
-
- :param bool block: If ``False``, then event dispatcher will run
- in a separate thread, allowing for the stream to be
- used in the background for another application.
- Otherwise, ``process(block=True)`` blocks the current
- thread. Defaults to ``False``.
- :param bool threaded: **DEPRECATED**
- If ``True``, then event dispatcher will run
- in a separate thread, allowing for the stream to be
- used in the background for another application.
- Defaults to ``True``. This does **not** mean that no
- threads are used at all if ``threaded=False``.
-
- Regardless of these threading options, these threads will
- always exist:
-
- - The event queue processor
- - The send queue processor
- - The scheduler
- """
+ def process(self, *, forever=True, timeout=None):
+ self.init_plugins()
+ XMLStream.process(self, forever=forever, timeout=timeout)
+
+ def init_plugins(self):
for name in self.plugin:
if not hasattr(self.plugin[name], 'post_inited'):
if hasattr(self.plugin[name], 'post_init'):
self.plugin[name].post_init()
self.plugin[name].post_inited = True
- return XMLStream.process(self, *args, **kwargs)
def register_plugin(self, plugin, pconfig=None, module=None):
"""Register and configure a plugin for use in this stream.
@@ -315,11 +291,11 @@ class BaseXMPP(XMLStream):
:param id: An ideally unique ID value for this stanza thread.
Defaults to 0.
- :param ifrom: The from :class:`~sleekxmpp.xmlstream.jid.JID`
+ :param ifrom: The from :class:`~slixmpp.xmlstream.jid.JID`
to use for this stanza.
- :param ito: The destination :class:`~sleekxmpp.xmlstream.jid.JID`
+ :param ito: The destination :class:`~slixmpp.xmlstream.jid.JID`
for this stanza.
- :param itype: The :class:`~sleekxmpp.stanza.iq.Iq`'s type,
+ :param itype: The :class:`~slixmpp.stanza.iq.Iq`'s type,
one of: ``'get'``, ``'set'``, ``'result'``,
or ``'error'``.
:param iquery: Optional namespace for adding a query element.
@@ -333,14 +309,14 @@ class BaseXMPP(XMLStream):
return iq
def make_iq_get(self, queryxmlns=None, ito=None, ifrom=None, iq=None):
- """Create an :class:`~sleekxmpp.stanza.iq.Iq` stanza of type ``'get'``.
+ """Create an :class:`~slixmpp.stanza.iq.Iq` stanza of type ``'get'``.
Optionally, a query element may be added.
:param queryxmlns: The namespace of the query to use.
- :param ito: The destination :class:`~sleekxmpp.xmlstream.jid.JID`
+ :param ito: The destination :class:`~slixmpp.xmlstream.jid.JID`
for this stanza.
- :param ifrom: The ``'from'`` :class:`~sleekxmpp.xmlstream.jid.JID`
+ :param ifrom: The ``'from'`` :class:`~slixmpp.xmlstream.jid.JID`
to use for this stanza.
:param iq: Optionally use an existing stanza instead
of generating a new one.
@@ -357,13 +333,13 @@ class BaseXMPP(XMLStream):
def make_iq_result(self, id=None, ito=None, ifrom=None, iq=None):
"""
- Create an :class:`~sleekxmpp.stanza.iq.Iq` stanza of type
+ Create an :class:`~slixmpp.stanza.iq.Iq` stanza of type
``'result'`` with the given ID value.
:param id: An ideally unique ID value. May use :meth:`new_id()`.
- :param ito: The destination :class:`~sleekxmpp.xmlstream.jid.JID`
+ :param ito: The destination :class:`~slixmpp.xmlstream.jid.JID`
for this stanza.
- :param ifrom: The ``'from'`` :class:`~sleekxmpp.xmlstream.jid.JID`
+ :param ifrom: The ``'from'`` :class:`~slixmpp.xmlstream.jid.JID`
to use for this stanza.
:param iq: Optionally use an existing stanza instead
of generating a new one.
@@ -382,19 +358,19 @@ class BaseXMPP(XMLStream):
def make_iq_set(self, sub=None, ito=None, ifrom=None, iq=None):
"""
- Create an :class:`~sleekxmpp.stanza.iq.Iq` stanza of type ``'set'``.
+ Create an :class:`~slixmpp.stanza.iq.Iq` stanza of type ``'set'``.
Optionally, a substanza may be given to use as the
stanza's payload.
:param sub: Either an
- :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase`
+ :class:`~slixmpp.xmlstream.stanzabase.ElementBase`
stanza object or an
:class:`~xml.etree.ElementTree.Element` XML object
- to use as the :class:`~sleekxmpp.stanza.iq.Iq`'s payload.
- :param ito: The destination :class:`~sleekxmpp.xmlstream.jid.JID`
+ to use as the :class:`~slixmpp.stanza.iq.Iq`'s payload.
+ :param ito: The destination :class:`~slixmpp.xmlstream.jid.JID`
for this stanza.
- :param ifrom: The ``'from'`` :class:`~sleekxmpp.xmlstream.jid.JID`
+ :param ifrom: The ``'from'`` :class:`~slixmpp.xmlstream.jid.JID`
to use for this stanza.
:param iq: Optionally use an existing stanza instead
of generating a new one.
@@ -414,7 +390,7 @@ class BaseXMPP(XMLStream):
condition='feature-not-implemented',
text=None, ito=None, ifrom=None, iq=None):
"""
- Create an :class:`~sleekxmpp.stanza.iq.Iq` stanza of type ``'error'``.
+ Create an :class:`~slixmpp.stanza.iq.Iq` stanza of type ``'error'``.
:param id: An ideally unique ID value. May use :meth:`new_id()`.
:param type: The type of the error, such as ``'cancel'`` or
@@ -422,9 +398,9 @@ class BaseXMPP(XMLStream):
:param condition: The error condition. Defaults to
``'feature-not-implemented'``.
:param text: A message describing the cause of the error.
- :param ito: The destination :class:`~sleekxmpp.xmlstream.jid.JID`
+ :param ito: The destination :class:`~slixmpp.xmlstream.jid.JID`
for this stanza.
- :param ifrom: The ``'from'`` :class:`~sleekxmpp.xmlstream.jid.JID`
+ :param ifrom: The ``'from'`` :class:`~slixmpp.xmlstream.jid.JID`
to use for this stanza.
:param iq: Optionally use an existing stanza instead
of generating a new one.
@@ -443,15 +419,15 @@ class BaseXMPP(XMLStream):
def make_iq_query(self, iq=None, xmlns='', ito=None, ifrom=None):
"""
- Create or modify an :class:`~sleekxmpp.stanza.iq.Iq` stanza
+ Create or modify an :class:`~slixmpp.stanza.iq.Iq` stanza
to use the given query namespace.
:param iq: Optionally use an existing stanza instead
of generating a new one.
:param xmlns: The query's namespace.
- :param ito: The destination :class:`~sleekxmpp.xmlstream.jid.JID`
+ :param ito: The destination :class:`~slixmpp.xmlstream.jid.JID`
for this stanza.
- :param ifrom: The ``'from'`` :class:`~sleekxmpp.xmlstream.jid.JID`
+ :param ifrom: The ``'from'`` :class:`~slixmpp.xmlstream.jid.JID`
to use for this stanza.
"""
if not iq:
@@ -477,7 +453,7 @@ class BaseXMPP(XMLStream):
mhtml=None, mfrom=None, mnick=None):
"""
Create and initialize a new
- :class:`~sleekxmpp.stanza.message.Message` stanza.
+ :class:`~slixmpp.stanza.message.Message` stanza.
:param mto: The recipient of the message.
:param mbody: The main contents of the message.
@@ -503,7 +479,7 @@ class BaseXMPP(XMLStream):
pto=None, ptype=None, pfrom=None, pnick=None):
"""
Create and initialize a new
- :class:`~sleekxmpp.stanza.presence.Presence` stanza.
+ :class:`~slixmpp.stanza.presence.Presence` stanza.
:param pshow: The presence's show value.
:param pstatus: The presence's status message.
@@ -527,7 +503,7 @@ class BaseXMPP(XMLStream):
mhtml=None, mfrom=None, mnick=None):
"""
Create, initialize, and send a new
- :class:`~sleekxmpp.stanza.message.Message` stanza.
+ :class:`~slixmpp.stanza.message.Message` stanza.
:param mto: The recipient of the message.
:param mbody: The main contents of the message.
@@ -547,7 +523,7 @@ class BaseXMPP(XMLStream):
pto=None, pfrom=None, ptype=None, pnick=None):
"""
Create, initialize, and send a new
- :class:`~sleekxmpp.stanza.presence.Presence` stanza.
+ :class:`~slixmpp.stanza.presence.Presence` stanza.
:param pshow: The presence's show value.
:param pstatus: The presence's status message.
@@ -564,7 +540,7 @@ class BaseXMPP(XMLStream):
ptype='subscribe', pnick=None):
"""
Create, initialize, and send a new
- :class:`~sleekxmpp.stanza.presence.Presence` stanza of
+ :class:`~slixmpp.stanza.presence.Presence` stanza of
type ``'subscribe'``.
:param pto: The recipient of a directed presence.
@@ -661,7 +637,7 @@ class BaseXMPP(XMLStream):
def set_jid(self, jid):
"""Rip a JID apart and claim it as our own."""
log.debug("setting jid to %s", jid)
- self.boundjid = JID(jid, cache_lock=True)
+ self.boundjid = JID(jid)
def getjidresource(self, fulljid):
if '/' in fulljid:
@@ -720,6 +696,12 @@ class BaseXMPP(XMLStream):
msg['to'] = self.boundjid
self.event('message', msg)
+ def _handle_message_error(self, msg):
+ """Process incoming message error stanzas."""
+ if not self.is_component and not msg['to'].bare:
+ msg['to'] = self.boundjid
+ self.event('message_error', msg)
+
def _handle_available(self, pres):
self.roster[pres['to']][pres['from']].handle_available(pres)
@@ -788,8 +770,8 @@ class BaseXMPP(XMLStream):
def exception(self, exception):
"""Process any uncaught exceptions, notably
- :class:`~sleekxmpp.exceptions.IqError` and
- :class:`~sleekxmpp.exceptions.IqTimeout` exceptions.
+ :class:`~slixmpp.exceptions.IqError` and
+ :class:`~slixmpp.exceptions.IqTimeout` exceptions.
:param exception: An unhandled :class:`Exception` object.
"""
@@ -809,23 +791,3 @@ class BaseXMPP(XMLStream):
pass
else:
log.exception(exception)
-
-
-# Restore the old, lowercased name for backwards compatibility.
-basexmpp = BaseXMPP
-
-# To comply with PEP8, method names now use underscores.
-# Deprecated method names are re-mapped for backwards compatibility.
-BaseXMPP.registerPlugin = BaseXMPP.register_plugin
-BaseXMPP.makeIq = BaseXMPP.make_iq
-BaseXMPP.makeIqGet = BaseXMPP.make_iq_get
-BaseXMPP.makeIqResult = BaseXMPP.make_iq_result
-BaseXMPP.makeIqSet = BaseXMPP.make_iq_set
-BaseXMPP.makeIqError = BaseXMPP.make_iq_error
-BaseXMPP.makeIqQuery = BaseXMPP.make_iq_query
-BaseXMPP.makeQueryRoster = BaseXMPP.make_query_roster
-BaseXMPP.makeMessage = BaseXMPP.make_message
-BaseXMPP.makePresence = BaseXMPP.make_presence
-BaseXMPP.sendMessage = BaseXMPP.send_message
-BaseXMPP.sendPresence = BaseXMPP.send_presence
-BaseXMPP.sendPresenceSubscription = BaseXMPP.send_presence_subscription
diff --git a/sleekxmpp/clientxmpp.py b/slixmpp/clientxmpp.py
index 31a5a70b..40d20333 100644
--- a/sleekxmpp/clientxmpp.py
+++ b/slixmpp/clientxmpp.py
@@ -1,27 +1,25 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.clientxmpp
+ slixmpp.clientxmpp
~~~~~~~~~~~~~~~~~~~~
This module provides XMPP functionality that
is specific to client connections.
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
"""
-from __future__ import absolute_import, unicode_literals
-
import logging
-from sleekxmpp.stanza import StreamFeatures
-from sleekxmpp.basexmpp import BaseXMPP
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.xmlstream import XMLStream
-from sleekxmpp.xmlstream.matcher import StanzaPath, MatchXPath
-from sleekxmpp.xmlstream.handler import Callback
+from slixmpp.stanza import StreamFeatures
+from slixmpp.basexmpp import BaseXMPP
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream import XMLStream
+from slixmpp.xmlstream.matcher import StanzaPath, MatchXPath
+from slixmpp.xmlstream.handler import Callback
# Flag indicating if DNS SRV records are available for use.
try:
@@ -38,7 +36,7 @@ log = logging.getLogger(__name__)
class ClientXMPP(BaseXMPP):
"""
- SleekXMPP's client class. (Use only for good, not for evil.)
+ Slixmpp's client class. (Use only for good, not for evil.)
Typical use pattern:
@@ -55,7 +53,7 @@ class ClientXMPP(BaseXMPP):
:param plugin_config: A dictionary of plugin configurations.
:param plugin_whitelist: A list of approved plugins that
will be loaded when calling
- :meth:`~sleekxmpp.basexmpp.BaseXMPP.register_plugins()`.
+ :meth:`~slixmpp.basexmpp.BaseXMPP.register_plugins()`.
:param escape_quotes: **Deprecated.**
"""
@@ -133,8 +131,8 @@ class ClientXMPP(BaseXMPP):
def password(self, value):
self.credentials['password'] = value
- def connect(self, address=tuple(), reattempt=True,
- use_tls=True, use_ssl=False):
+ def connect(self, address=tuple(), use_ssl=False,
+ force_starttls=True, disable_starttls=False):
"""Connect to the XMPP server.
When no address is given, a SRV lookup for the server will
@@ -142,14 +140,11 @@ class ClientXMPP(BaseXMPP):
will be used.
:param address: A tuple containing the server's host and port.
- :param reattempt: If ``True``, repeat attempting to connect if an
- error occurs. Defaults to ``True``.
:param use_tls: Indicates if TLS should be used for the
connection. Defaults to ``True``.
:param use_ssl: Indicates if the older SSL connection method
should be used. Defaults to ``False``.
"""
- self.session_started_event.clear()
# If an address was provided, disable using DNS SRV lookup;
# otherwise, use the domain from the client JID with the standard
@@ -160,9 +155,8 @@ class ClientXMPP(BaseXMPP):
address = (self.boundjid.host, 5222)
self.dns_service = 'xmpp-client'
- return XMLStream.connect(self, address[0], address[1],
- use_tls=use_tls, use_ssl=use_ssl,
- reattempt=reattempt)
+ return XMLStream.connect(self, address[0], address[1], use_ssl=use_ssl,
+ force_starttls=force_starttls, disable_starttls=disable_starttls)
def register_feature(self, name, handler, restart=False, order=5000):
"""Register a stream feature handler.
@@ -195,13 +189,10 @@ class ClientXMPP(BaseXMPP):
``'none'``. If set to ``'remove'``,
the entry will be deleted.
:param groups: The roster groups that contain this item.
- :param block: Specify if the roster request will block
- until a response is received, or a timeout
- occurs. Defaults to ``True``.
:param timeout: The length of time (in seconds) to wait
for a response before continuing if blocking
is used. Defaults to
- :attr:`~sleekxmpp.xmlstream.xmlstream.XMLStream.response_timeout`.
+ :attr:`~slixmpp.xmlstream.xmlstream.XMLStream.response_timeout`.
:param callback: Optional reference to a stream handler function.
Will be executed when the roster is received.
Implies ``block=False``.
@@ -212,12 +203,11 @@ class ClientXMPP(BaseXMPP):
subscription = kwargs.get('subscription', current['subscription'])
groups = kwargs.get('groups', current['groups'])
- block = kwargs.get('block', True)
timeout = kwargs.get('timeout', None)
callback = kwargs.get('callback', None)
return self.client_roster.update(jid, name, subscription, groups,
- block, timeout, callback)
+ timeout, callback)
def del_roster_item(self, jid):
"""Remove an item from the roster.
@@ -228,19 +218,11 @@ class ClientXMPP(BaseXMPP):
"""
return self.client_roster.remove(jid)
- def get_roster(self, block=True, timeout=None, callback=None):
+ def get_roster(self, callback=None, timeout=None, timeout_callback=None):
"""Request the roster from the server.
- :param block: Specify if the roster request will block until a
- response is received, or a timeout occurs.
- Defaults to ``True``.
- :param timeout: The length of time (in seconds) to wait for a response
- before continuing if blocking is used.
- Defaults to
- :attr:`~sleekxmpp.xmlstream.xmlstream.XMLStream.response_timeout`.
- :param callback: Optional reference to a stream handler function. Will
+ :param callback: Reference to a stream handler function. Will
be executed when the roster is received.
- Implies ``block=False``.
"""
iq = self.Iq()
iq['type'] = 'get'
@@ -248,23 +230,16 @@ class ClientXMPP(BaseXMPP):
if 'rosterver' in self.features:
iq['roster']['ver'] = self.client_roster.version
+ if callback is None:
+ callback = lambda resp: self.event('roster_update', resp)
+ else:
+ orig_cb = callback
+ def wrapped(resp):
+ self.event('roster_update', resp)
+ orig_cb(resp)
+ callback = wrapped
- if not block or callback is not None:
- block = False
- if callback is None:
- callback = lambda resp: self.event('roster_update', resp)
- else:
- orig_cb = callback
- def wrapped(resp):
- self.event('roster_update', resp)
- orig_cb(resp)
- callback = wrapped
-
- response = iq.send(block, timeout, callback)
-
- if block:
- self.event('roster_update', response)
- return response
+ iq.send(callback, timeout, timeout_callback)
def _reset_connection_state(self, event=None):
#TODO: Use stream state here
@@ -324,15 +299,7 @@ class ClientXMPP(BaseXMPP):
def _handle_session_bind(self, jid):
"""Set the client roster to the JID set by the server.
- :param :class:`sleekxmpp.xmlstream.jid.JID` jid: The bound JID as
+ :param :class:`slixmpp.xmlstream.jid.JID` jid: The bound JID as
dictated by the server. The same as :attr:`boundjid`.
"""
self.client_roster = self.roster[jid]
-
-
-# To comply with PEP8, method names now use underscores.
-# Deprecated method names are re-mapped for backwards compatibility.
-ClientXMPP.updateRoster = ClientXMPP.update_roster
-ClientXMPP.delRosterItem = ClientXMPP.del_roster_item
-ClientXMPP.getRoster = ClientXMPP.get_roster
-ClientXMPP.registerFeature = ClientXMPP.register_feature
diff --git a/sleekxmpp/componentxmpp.py b/slixmpp/componentxmpp.py
index 4b229a6f..868798d1 100644
--- a/sleekxmpp/componentxmpp.py
+++ b/slixmpp/componentxmpp.py
@@ -1,28 +1,25 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.clientxmpp
+ slixmpp.clientxmpp
~~~~~~~~~~~~~~~~~~~~
This module provides XMPP functionality that
is specific to external server component connections.
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
"""
-from __future__ import absolute_import
-
import logging
-import sys
import hashlib
-from sleekxmpp.basexmpp import BaseXMPP
-from sleekxmpp.xmlstream import XMLStream
-from sleekxmpp.xmlstream import ET
-from sleekxmpp.xmlstream.matcher import MatchXPath
-from sleekxmpp.xmlstream.handler import Callback
+from slixmpp.basexmpp import BaseXMPP
+from slixmpp.xmlstream import XMLStream
+from slixmpp.xmlstream import ET
+from slixmpp.xmlstream.matcher import MatchXPath
+from slixmpp.xmlstream.handler import Callback
log = logging.getLogger(__name__)
@@ -31,7 +28,7 @@ log = logging.getLogger(__name__)
class ComponentXMPP(BaseXMPP):
"""
- SleekXMPP's basic XMPP server component.
+ Slixmpp's basic XMPP server component.
Use only for good, not for evil.
@@ -42,7 +39,7 @@ class ComponentXMPP(BaseXMPP):
:param plugin_config: A dictionary of plugin configurations.
:param plugin_whitelist: A list of approved plugins that
will be loaded when calling
- :meth:`~sleekxmpp.basexmpp.BaseXMPP.register_plugins()`.
+ :meth:`~slixmpp.basexmpp.BaseXMPP.register_plugins()`.
:param use_jc_ns: Indicates if the ``'jabber:client'`` namespace
should be used instead of the standard
``'jabber:component:accept'`` namespace.
@@ -63,7 +60,7 @@ class ComponentXMPP(BaseXMPP):
BaseXMPP.__init__(self, jid, default_ns)
self.auto_authorize = None
- self.stream_header = "<stream:stream %s %s to='%s'>" % (
+ self.stream_header = '<stream:stream %s %s to="%s">' % (
'xmlns="jabber:component:accept"',
'xmlns:stream="%s"' % self.stream_ns,
jid)
@@ -76,6 +73,8 @@ class ComponentXMPP(BaseXMPP):
self.plugin_whitelist = plugin_whitelist
self.is_component = True
+ self.sessionstarted = False
+
self.register_handler(
Callback('Handshake',
MatchXPath('{jabber:component:accept}handshake'),
@@ -83,12 +82,9 @@ class ComponentXMPP(BaseXMPP):
self.add_event_handler('presence_probe',
self._handle_probe)
- def connect(self, host=None, port=None, use_ssl=False,
- use_tls=False, reattempt=True):
+ def connect(self, host=None, port=None, use_ssl=False):
"""Connect to the server.
- Setting ``reattempt`` to ``True`` will cause connection attempts to
- be made every second until a successful connection is established.
:param host: The name of the desired server for the connection.
Defaults to :attr:`server_host`.
@@ -96,11 +92,6 @@ class ComponentXMPP(BaseXMPP):
Defauts to :attr:`server_port`.
:param use_ssl: Flag indicating if SSL should be used by connecting
directly to a port using SSL.
- :param use_tls: Flag indicating if TLS should be used, allowing for
- connecting to a port without using SSL immediately and
- later upgrading the connection.
- :param reattempt: Flag indicating if the socket should reconnect
- after disconnections.
"""
if host is None:
host = self.server_host
@@ -109,14 +100,9 @@ class ComponentXMPP(BaseXMPP):
self.server_name = self.boundjid.host
- if use_tls:
- log.info("XEP-0114 components can not use TLS")
-
log.debug("Connecting to %s:%s", host, port)
return XMLStream.connect(self, host=host, port=port,
- use_ssl=use_ssl,
- use_tls=False,
- reattempt=reattempt)
+ use_ssl=use_ssl)
def incoming_filter(self, xml):
"""
@@ -141,14 +127,11 @@ class ComponentXMPP(BaseXMPP):
# Construct a hash of the stream ID and the component secret.
sid = xml.get('id', '')
- pre_hash = '%s%s' % (sid, self.secret)
- if sys.version_info >= (3, 0):
- # Handle Unicode byte encoding in Python 3.
- pre_hash = bytes(pre_hash, 'utf-8')
+ pre_hash = bytes('%s%s' % (sid, self.secret), 'utf-8')
handshake = ET.Element('{jabber:component:accept}handshake')
handshake.text = hashlib.sha1(pre_hash).hexdigest().lower()
- self.send_xml(handshake, now=True)
+ self.send_xml(handshake)
def _handle_handshake(self, xml):
"""The handshake has been accepted.
@@ -156,8 +139,8 @@ class ComponentXMPP(BaseXMPP):
:param xml: The reply handshake stanza.
"""
self.session_bind_event.set()
- self.session_started_event.set()
- self.event('session_bind', self.boundjid, direct=True)
+ self.sessionstarted = True
+ self.event('session_bind', self.boundjid)
self.event('session_start')
def _handle_probe(self, pres):
diff --git a/sleekxmpp/exceptions.py b/slixmpp/exceptions.py
index 8a2aa75c..a6c09a0b 100644
--- a/sleekxmpp/exceptions.py
+++ b/slixmpp/exceptions.py
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.exceptions
+ slixmpp.exceptions
~~~~~~~~~~~~~~~~~~~~
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
@@ -17,11 +17,11 @@ class XMPPError(Exception):
to indicate that an error response stanza should be sent.
The exception method for stanza objects extending
- :class:`~sleekxmpp.stanza.rootstanza.RootStanza` will create an error
+ :class:`~slixmpp.stanza.rootstanza.RootStanza` will create an error
stanza and initialize any additional substanzas using the extension
information included in the exception.
- Meant for use in SleekXMPP plugins and applications using SleekXMPP.
+ Meant for use in Slixmpp plugins and applications using Slixmpp.
Extension information can be included to add additional XML elements
to the generated error stanza.
@@ -56,6 +56,18 @@ class XMPPError(Exception):
self.extension_ns = extension_ns
self.extension_args = extension_args
+ def format(self):
+ """
+ Format the error in a simple user-readable string.
+ """
+ text = [self.etype, self.condition]
+ if self.text:
+ text.append(self.text)
+ if self.extension:
+ text.append(self.extension)
+ # TODO: handle self.extension_args
+ return ': '.join(text)
+
class IqTimeout(XMPPError):
@@ -69,7 +81,7 @@ class IqTimeout(XMPPError):
condition='remote-server-timeout',
etype='cancel')
- #: The :class:`~sleekxmpp.stanza.iq.Iq` stanza whose response
+ #: The :class:`~slixmpp.stanza.iq.Iq` stanza whose response
#: did not arrive before the timeout expired.
self.iq = iq
@@ -87,5 +99,5 @@ class IqError(XMPPError):
text=iq['error']['text'],
etype=iq['error']['type'])
- #: The :class:`~sleekxmpp.stanza.iq.Iq` error result stanza.
+ #: The :class:`~slixmpp.stanza.iq.Iq` error result stanza.
self.iq = iq
diff --git a/sleekxmpp/features/__init__.py b/slixmpp/features/__init__.py
index 869de7e9..5b728ee8 100644
--- a/sleekxmpp/features/__init__.py
+++ b/slixmpp/features/__init__.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
diff --git a/slixmpp/features/feature_bind/__init__.py b/slixmpp/features/feature_bind/__init__.py
new file mode 100644
index 00000000..65f5b626
--- /dev/null
+++ b/slixmpp/features/feature_bind/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.features.feature_bind.bind import FeatureBind
+from slixmpp.features.feature_bind.stanza import Bind
+
+
+register_plugin(FeatureBind)
+
+
+# Retain some backwards compatibility
+feature_bind = FeatureBind
diff --git a/sleekxmpp/features/feature_bind/bind.py b/slixmpp/features/feature_bind/bind.py
index ee4c1e9b..c031ab72 100644
--- a/sleekxmpp/features/feature_bind/bind.py
+++ b/slixmpp/features/feature_bind/bind.py
@@ -1,18 +1,18 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.jid import JID
-from sleekxmpp.stanza import Iq, StreamFeatures
-from sleekxmpp.features.feature_bind import stanza
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
+from slixmpp.jid import JID
+from slixmpp.stanza import Iq, StreamFeatures
+from slixmpp.features.feature_bind import stanza
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
log = logging.getLogger(__name__)
@@ -42,24 +42,26 @@ class FeatureBind(BasePlugin):
features -- The stream features stanza.
"""
log.debug("Requesting resource: %s", self.xmpp.requested_jid.resource)
+ self.features = features
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq.enable('bind')
if self.xmpp.requested_jid.resource:
iq['bind']['resource'] = self.xmpp.requested_jid.resource
- response = iq.send(now=True)
- self.xmpp.boundjid = JID(response['bind']['jid'], cache_lock=True)
+ iq.send(callback=self._on_bind_response)
+
+ def _on_bind_response(self, response):
+ self.xmpp.boundjid = JID(response['bind']['jid'])
self.xmpp.bound = True
- self.xmpp.event('session_bind', self.xmpp.boundjid, direct=True)
+ self.xmpp.event('session_bind', self.xmpp.boundjid)
self.xmpp.session_bind_event.set()
self.xmpp.features.add('bind')
log.info("JID set to: %s", self.xmpp.boundjid.full)
- if 'session' not in features['features']:
+ if 'session' not in self.features['features']:
log.debug("Established Session")
self.xmpp.sessionstarted = True
- self.xmpp.session_started_event.set()
self.xmpp.event('session_start')
diff --git a/sleekxmpp/features/feature_bind/stanza.py b/slixmpp/features/feature_bind/stanza.py
index 8ce7536f..b9ecd97c 100644
--- a/sleekxmpp/features/feature_bind/stanza.py
+++ b/slixmpp/features/feature_bind/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class Bind(ElementBase):
diff --git a/slixmpp/features/feature_mechanisms/__init__.py b/slixmpp/features/feature_mechanisms/__init__.py
new file mode 100644
index 00000000..7532eaa2
--- /dev/null
+++ b/slixmpp/features/feature_mechanisms/__init__.py
@@ -0,0 +1,22 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.features.feature_mechanisms.mechanisms import FeatureMechanisms
+from slixmpp.features.feature_mechanisms.stanza import Mechanisms
+from slixmpp.features.feature_mechanisms.stanza import Auth
+from slixmpp.features.feature_mechanisms.stanza import Success
+from slixmpp.features.feature_mechanisms.stanza import Failure
+
+
+register_plugin(FeatureMechanisms)
+
+
+# Retain some backwards compatibility
+feature_mechanisms = FeatureMechanisms
diff --git a/sleekxmpp/features/feature_mechanisms/mechanisms.py b/slixmpp/features/feature_mechanisms/mechanisms.py
index 1d8f8798..8e507afc 100644
--- a/sleekxmpp/features/feature_mechanisms/mechanisms.py
+++ b/slixmpp/features/feature_mechanisms/mechanisms.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,14 +9,14 @@
import ssl
import logging
-from sleekxmpp.util import sasl
-from sleekxmpp.util.stringprep_profiles import StringPrepError
-from sleekxmpp.stanza import StreamFeatures
-from sleekxmpp.xmlstream import RestartStream, register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream.matcher import MatchXPath
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.features.feature_mechanisms import stanza
+from slixmpp.util import sasl
+from slixmpp.util.stringprep_profiles import StringPrepError
+from slixmpp.stanza import StreamFeatures
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream.matcher import MatchXPath
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.features.feature_mechanisms import stanza
log = logging.getLogger(__name__)
@@ -172,8 +172,11 @@ class FeatureMechanisms(BasePlugin):
min_mech=self.min_mech)
except sasl.SASLNoAppropriateMechanism:
log.error("No appropriate login method.")
- self.xmpp.event("no_auth", direct=True)
- self.xmpp.event("failed_auth", direct=True)
+ self.xmpp.event("failed_all_auth")
+ if not self.attempted_mechs:
+ # Only trigger this event if we didn't try at least one
+ # method
+ self.xmpp.event("no_auth")
self.attempted_mechs = set()
return self.xmpp.disconnect()
except StringPrepError:
@@ -196,7 +199,7 @@ class FeatureMechanisms(BasePlugin):
self.attempted_mechs.add(self.mech.name)
self._send_auth()
else:
- resp.send(now=True)
+ resp.send()
return True
@@ -217,7 +220,7 @@ class FeatureMechanisms(BasePlugin):
else:
if resp.get_value() == '':
resp.del_value()
- resp.send(now=True)
+ resp.send()
def _handle_success(self, stanza):
"""SASL authentication succeeded. Restart the stream."""
@@ -232,13 +235,15 @@ class FeatureMechanisms(BasePlugin):
self.attempted_mechs = set()
self.xmpp.authenticated = True
self.xmpp.features.add('mechanisms')
- self.xmpp.event('auth_success', stanza, direct=True)
- raise RestartStream()
+ self.xmpp.event('auth_success', stanza)
+ # Restart the stream
+ self.xmpp.init_parser()
+ self.xmpp.send_raw(self.xmpp.stream_header)
def _handle_fail(self, stanza):
"""SASL authentication failed. Disconnect and shutdown."""
self.attempted_mechs.add(self.mech.name)
log.info("Authentication failed: %s", stanza['condition'])
- self.xmpp.event("failed_auth", stanza, direct=True)
+ self.xmpp.event("failed_auth", stanza)
self._send_auth()
return True
diff --git a/slixmpp/features/feature_mechanisms/stanza/__init__.py b/slixmpp/features/feature_mechanisms/stanza/__init__.py
new file mode 100644
index 00000000..4d515bf2
--- /dev/null
+++ b/slixmpp/features/feature_mechanisms/stanza/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+
+from slixmpp.features.feature_mechanisms.stanza.mechanisms import Mechanisms
+from slixmpp.features.feature_mechanisms.stanza.auth import Auth
+from slixmpp.features.feature_mechanisms.stanza.success import Success
+from slixmpp.features.feature_mechanisms.stanza.failure import Failure
+from slixmpp.features.feature_mechanisms.stanza.challenge import Challenge
+from slixmpp.features.feature_mechanisms.stanza.response import Response
+from slixmpp.features.feature_mechanisms.stanza.abort import Abort
diff --git a/sleekxmpp/features/feature_mechanisms/stanza/abort.py b/slixmpp/features/feature_mechanisms/stanza/abort.py
index aaca348d..fca29aee 100644
--- a/sleekxmpp/features/feature_mechanisms/stanza/abort.py
+++ b/slixmpp/features/feature_mechanisms/stanza/abort.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import StanzaBase
+from slixmpp.xmlstream import StanzaBase
class Abort(StanzaBase):
diff --git a/sleekxmpp/features/feature_mechanisms/stanza/auth.py b/slixmpp/features/feature_mechanisms/stanza/auth.py
index 6b6f85a3..c32069ec 100644
--- a/sleekxmpp/features/feature_mechanisms/stanza/auth.py
+++ b/slixmpp/features/feature_mechanisms/stanza/auth.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import base64
-from sleekxmpp.util import bytes
-from sleekxmpp.xmlstream import StanzaBase
+from slixmpp.util import bytes
+from slixmpp.xmlstream import StanzaBase
class Auth(StanzaBase):
diff --git a/sleekxmpp/features/feature_mechanisms/stanza/challenge.py b/slixmpp/features/feature_mechanisms/stanza/challenge.py
index 24290281..21a061ee 100644
--- a/sleekxmpp/features/feature_mechanisms/stanza/challenge.py
+++ b/slixmpp/features/feature_mechanisms/stanza/challenge.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import base64
-from sleekxmpp.util import bytes
-from sleekxmpp.xmlstream import StanzaBase
+from slixmpp.util import bytes
+from slixmpp.xmlstream import StanzaBase
class Challenge(StanzaBase):
diff --git a/sleekxmpp/features/feature_mechanisms/stanza/failure.py b/slixmpp/features/feature_mechanisms/stanza/failure.py
index b9f32605..cc0ac877 100644
--- a/sleekxmpp/features/feature_mechanisms/stanza/failure.py
+++ b/slixmpp/features/feature_mechanisms/stanza/failure.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import StanzaBase, ET
+from slixmpp.xmlstream import StanzaBase, ET
class Failure(StanzaBase):
diff --git a/sleekxmpp/features/feature_mechanisms/stanza/mechanisms.py b/slixmpp/features/feature_mechanisms/stanza/mechanisms.py
index bbd56813..4437e155 100644
--- a/sleekxmpp/features/feature_mechanisms/stanza/mechanisms.py
+++ b/slixmpp/features/feature_mechanisms/stanza/mechanisms.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class Mechanisms(ElementBase):
diff --git a/sleekxmpp/features/feature_mechanisms/stanza/response.py b/slixmpp/features/feature_mechanisms/stanza/response.py
index ca7624f1..8da236ba 100644
--- a/sleekxmpp/features/feature_mechanisms/stanza/response.py
+++ b/slixmpp/features/feature_mechanisms/stanza/response.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import base64
-from sleekxmpp.util import bytes
-from sleekxmpp.xmlstream import StanzaBase
+from slixmpp.util import bytes
+from slixmpp.xmlstream import StanzaBase
class Response(StanzaBase):
diff --git a/sleekxmpp/features/feature_mechanisms/stanza/success.py b/slixmpp/features/feature_mechanisms/stanza/success.py
index 7a4eab8e..f7cde0f8 100644
--- a/sleekxmpp/features/feature_mechanisms/stanza/success.py
+++ b/slixmpp/features/feature_mechanisms/stanza/success.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import base64
-from sleekxmpp.util import bytes
-from sleekxmpp.xmlstream import StanzaBase
+from slixmpp.util import bytes
+from slixmpp.xmlstream import StanzaBase
class Success(StanzaBase):
diff --git a/slixmpp/features/feature_preapproval/__init__.py b/slixmpp/features/feature_preapproval/__init__.py
new file mode 100644
index 00000000..f22be050
--- /dev/null
+++ b/slixmpp/features/feature_preapproval/__init__.py
@@ -0,0 +1,15 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.features.feature_preapproval.preapproval import FeaturePreApproval
+from slixmpp.features.feature_preapproval.stanza import PreApproval
+
+
+register_plugin(FeaturePreApproval)
diff --git a/sleekxmpp/features/feature_preapproval/preapproval.py b/slixmpp/features/feature_preapproval/preapproval.py
index c7106ed3..1d60d7e7 100644
--- a/sleekxmpp/features/feature_preapproval/preapproval.py
+++ b/slixmpp/features/feature_preapproval/preapproval.py
@@ -1,17 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.stanza import StreamFeatures
-from sleekxmpp.features.feature_preapproval import stanza
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.base import BasePlugin
+from slixmpp.stanza import StreamFeatures
+from slixmpp.features.feature_preapproval import stanza
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.base import BasePlugin
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/features/feature_preapproval/stanza.py b/slixmpp/features/feature_preapproval/stanza.py
index 4a59bd16..03d721ef 100644
--- a/sleekxmpp/features/feature_preapproval/stanza.py
+++ b/slixmpp/features/feature_preapproval/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class PreApproval(ElementBase):
diff --git a/slixmpp/features/feature_rosterver/__init__.py b/slixmpp/features/feature_rosterver/__init__.py
new file mode 100644
index 00000000..d338b584
--- /dev/null
+++ b/slixmpp/features/feature_rosterver/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.features.feature_rosterver.rosterver import FeatureRosterVer
+from slixmpp.features.feature_rosterver.stanza import RosterVer
+
+
+register_plugin(FeatureRosterVer)
+
+
+# Retain some backwards compatibility
+feature_rosterver = FeatureRosterVer
diff --git a/sleekxmpp/features/feature_rosterver/rosterver.py b/slixmpp/features/feature_rosterver/rosterver.py
index 2991f587..2c2c8c84 100644
--- a/sleekxmpp/features/feature_rosterver/rosterver.py
+++ b/slixmpp/features/feature_rosterver/rosterver.py
@@ -1,17 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.stanza import StreamFeatures
-from sleekxmpp.features.feature_rosterver import stanza
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.base import BasePlugin
+from slixmpp.stanza import StreamFeatures
+from slixmpp.features.feature_rosterver import stanza
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.base import BasePlugin
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/features/feature_rosterver/stanza.py b/slixmpp/features/feature_rosterver/stanza.py
index 025872fa..c9a4a2da 100644
--- a/sleekxmpp/features/feature_rosterver/stanza.py
+++ b/slixmpp/features/feature_rosterver/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class RosterVer(ElementBase):
diff --git a/slixmpp/features/feature_session/__init__.py b/slixmpp/features/feature_session/__init__.py
new file mode 100644
index 00000000..0ac950c6
--- /dev/null
+++ b/slixmpp/features/feature_session/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.features.feature_session.session import FeatureSession
+from slixmpp.features.feature_session.stanza import Session
+
+
+register_plugin(FeatureSession)
+
+
+# Retain some backwards compatibility
+feature_session = FeatureSession
diff --git a/sleekxmpp/features/feature_session/session.py b/slixmpp/features/feature_session/session.py
index ceadd5f3..0635455a 100644
--- a/sleekxmpp/features/feature_session/session.py
+++ b/slixmpp/features/feature_session/session.py
@@ -1,18 +1,18 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.stanza import Iq, StreamFeatures
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
+from slixmpp.stanza import Iq, StreamFeatures
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
-from sleekxmpp.features.feature_session import stanza
+from slixmpp.features.feature_session import stanza
log = logging.getLogger(__name__)
@@ -44,11 +44,11 @@ class FeatureSession(BasePlugin):
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq.enable('session')
- iq.send(now=True)
+ iq.send(callback=self._on_start_session_response)
+ def _on_start_session_response(self, response):
self.xmpp.features.add('session')
log.debug("Established Session")
self.xmpp.sessionstarted = True
- self.xmpp.session_started_event.set()
self.xmpp.event('session_start')
diff --git a/sleekxmpp/features/feature_session/stanza.py b/slixmpp/features/feature_session/stanza.py
index 94e949ee..f68483d6 100644
--- a/sleekxmpp/features/feature_session/stanza.py
+++ b/slixmpp/features/feature_session/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class Session(ElementBase):
diff --git a/slixmpp/features/feature_starttls/__init__.py b/slixmpp/features/feature_starttls/__init__.py
new file mode 100644
index 00000000..81a88650
--- /dev/null
+++ b/slixmpp/features/feature_starttls/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.features.feature_starttls.starttls import FeatureSTARTTLS
+from slixmpp.features.feature_starttls.stanza import *
+
+
+register_plugin(FeatureSTARTTLS)
+
+
+# Retain some backwards compatibility
+feature_starttls = FeatureSTARTTLS
diff --git a/sleekxmpp/features/feature_starttls/stanza.py b/slixmpp/features/feature_starttls/stanza.py
index b968e134..df50897e 100644
--- a/sleekxmpp/features/feature_starttls/stanza.py
+++ b/slixmpp/features/feature_starttls/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import StanzaBase, ElementBase
+from slixmpp.xmlstream import StanzaBase, ElementBase
class STARTTLS(ElementBase):
diff --git a/sleekxmpp/features/feature_starttls/starttls.py b/slixmpp/features/feature_starttls/starttls.py
index eb5eee1d..d472dad7 100644
--- a/sleekxmpp/features/feature_starttls/starttls.py
+++ b/slixmpp/features/feature_starttls/starttls.py
@@ -1,19 +1,19 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.stanza import StreamFeatures
-from sleekxmpp.xmlstream import RestartStream, register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream.matcher import MatchXPath
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.features.feature_starttls import stanza
+from slixmpp.stanza import StreamFeatures
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream.matcher import MatchXPath
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.features.feature_starttls import stanza
log = logging.getLogger(__name__)
@@ -52,10 +52,10 @@ class FeatureSTARTTLS(BasePlugin):
# We have already negotiated TLS, but the server is
# offering it again, against spec.
return False
- elif not self.xmpp.use_tls:
+ elif self.xmpp.disable_starttls:
return False
else:
- self.xmpp.send(features['starttls'], now=True)
+ self.xmpp.send(features['starttls'])
return True
def _handle_starttls_proceed(self, proceed):
@@ -63,4 +63,3 @@ class FeatureSTARTTLS(BasePlugin):
log.debug("Starting TLS")
if self.xmpp.start_tls():
self.xmpp.features.add('starttls')
- raise RestartStream()
diff --git a/slixmpp/jid.py b/slixmpp/jid.py
new file mode 100644
index 00000000..2e23e242
--- /dev/null
+++ b/slixmpp/jid.py
@@ -0,0 +1,449 @@
+# -*- coding: utf-8 -*-
+"""
+ slixmpp.jid
+ ~~~~~~~~~~~~~~~~~~~~~~~
+
+ This module allows for working with Jabber IDs (JIDs).
+
+ Part of Slixmpp: The Slick XMPP Library
+
+ :copyright: (c) 2011 Nathanael C. Fritz
+ :license: MIT, see LICENSE for more details
+"""
+
+import re
+import socket
+
+from copy import deepcopy
+from functools import lru_cache
+
+from slixmpp.stringprep import nodeprep, resourceprep, idna, StringprepError
+
+HAVE_INET_PTON = hasattr(socket, 'inet_pton')
+
+#: The basic regex pattern that a JID must match in order to determine
+#: the local, domain, and resource parts. This regex does NOT do any
+#: validation, which requires application of nodeprep, resourceprep, etc.
+JID_PATTERN = re.compile(
+ "^(?:([^\"&'/:<>@]{1,1023})@)?([^/@]{1,1023})(?:/(.{1,1023}))?$"
+)
+
+#: The set of escape sequences for the characters not allowed by nodeprep.
+JID_ESCAPE_SEQUENCES = {'\\20', '\\22', '\\26', '\\27', '\\2f',
+ '\\3a', '\\3c', '\\3e', '\\40', '\\5c'}
+
+#: The reverse mapping of escape sequences to their original forms.
+JID_UNESCAPE_TRANSFORMATIONS = {'\\20': ' ',
+ '\\22': '"',
+ '\\26': '&',
+ '\\27': "'",
+ '\\2f': '/',
+ '\\3a': ':',
+ '\\3c': '<',
+ '\\3e': '>',
+ '\\40': '@',
+ '\\5c': '\\'}
+
+
+# TODO: Find the best cache size for a standard usage.
+@lru_cache(maxsize=1024)
+def _parse_jid(data):
+ """
+ Parse string data into the node, domain, and resource
+ components of a JID, if possible.
+
+ :param string data: A string that is potentially a JID.
+
+ :raises InvalidJID:
+
+ :returns: tuple of the validated local, domain, and resource strings
+ """
+ match = JID_PATTERN.match(data)
+ if not match:
+ raise InvalidJID('JID could not be parsed')
+
+ (node, domain, resource) = match.groups()
+
+ node = _validate_node(node)
+ domain = _validate_domain(domain)
+ resource = _validate_resource(resource)
+
+ return node, domain, resource
+
+
+def _validate_node(node):
+ """Validate the local, or username, portion of a JID.
+
+ :raises InvalidJID:
+
+ :returns: The local portion of a JID, as validated by nodeprep.
+ """
+ if node is None:
+ return None
+
+ try:
+ node = nodeprep(node)
+ except StringprepError:
+ raise InvalidJID('Nodeprep failed')
+
+ if not node:
+ raise InvalidJID('Localpart must not be 0 bytes')
+ if len(node) > 1023:
+ raise InvalidJID('Localpart must be less than 1024 bytes')
+ return node
+
+
+def _validate_domain(domain):
+ """Validate the domain portion of a JID.
+
+ IP literal addresses are left as-is, if valid. Domain names
+ are stripped of any trailing label separators (`.`), and are
+ checked with the nameprep profile of stringprep. If the given
+ domain is actually a punyencoded version of a domain name, it
+ is converted back into its original Unicode form. Domains must
+ also not start or end with a dash (`-`).
+
+ :raises InvalidJID:
+
+ :returns: The validated domain name
+ """
+ ip_addr = False
+
+ # First, check if this is an IPv4 address
+ try:
+ socket.inet_aton(domain)
+ ip_addr = True
+ except socket.error:
+ pass
+
+ # Check if this is an IPv6 address
+ if not ip_addr and HAVE_INET_PTON and domain[0] == '[' and domain[-1] == ']':
+ try:
+ ip = domain[1:-1]
+ socket.inet_pton(socket.AF_INET6, ip)
+ ip_addr = True
+ except (socket.error, ValueError):
+ pass
+
+ if not ip_addr:
+ # This is a domain name, which must be checked further
+
+ if domain and domain[-1] == '.':
+ domain = domain[:-1]
+
+ try:
+ domain = idna(domain)
+ except StringprepError:
+ raise InvalidJID('idna validation failed')
+
+ if ':' in domain:
+ raise InvalidJID('Domain containing a port')
+ for label in domain.split('.'):
+ if not label:
+ raise InvalidJID('Domain containing too many dots')
+ if '-' in (label[0], label[-1]):
+ raise InvalidJID('Domain started or ended with -')
+
+ if not domain:
+ raise InvalidJID('Domain must not be 0 bytes')
+ if len(domain) > 1023:
+ raise InvalidJID('Domain must be less than 1024 bytes')
+
+ return domain
+
+
+def _validate_resource(resource):
+ """Validate the resource portion of a JID.
+
+ :raises InvalidJID:
+
+ :returns: The local portion of a JID, as validated by resourceprep.
+ """
+ if resource is None:
+ return None
+
+ try:
+ resource = resourceprep(resource)
+ except StringprepError:
+ raise InvalidJID('Resourceprep failed')
+
+ if not resource:
+ raise InvalidJID('Resource must not be 0 bytes')
+ if len(resource) > 1023:
+ raise InvalidJID('Resource must be less than 1024 bytes')
+ return resource
+
+
+def _unescape_node(node):
+ """Unescape a local portion of a JID.
+
+ .. note::
+ The unescaped local portion is meant ONLY for presentation,
+ and should not be used for other purposes.
+ """
+ unescaped = []
+ seq = ''
+ for i, char in enumerate(node):
+ if char == '\\':
+ seq = node[i:i+3]
+ if seq not in JID_ESCAPE_SEQUENCES:
+ seq = ''
+ if seq:
+ if len(seq) == 3:
+ unescaped.append(JID_UNESCAPE_TRANSFORMATIONS.get(seq, char))
+
+ # Pop character off the escape sequence, and ignore it
+ seq = seq[1:]
+ else:
+ unescaped.append(char)
+ return ''.join(unescaped)
+
+
+def _format_jid(local=None, domain=None, resource=None):
+ """Format the given JID components into a full or bare JID.
+
+ :param string local: Optional. The local portion of the JID.
+ :param string domain: Required. The domain name portion of the JID.
+ :param strin resource: Optional. The resource portion of the JID.
+
+ :return: A full or bare JID string.
+ """
+ result = []
+ if local is not None:
+ result.append(local)
+ result.append('@')
+ if domain is not None:
+ result.append(domain)
+ if resource is not None:
+ result.append('/')
+ result.append(resource)
+ return ''.join(result)
+
+
+class InvalidJID(ValueError):
+ """
+ Raised when attempting to create a JID that does not pass validation.
+
+ It can also be raised if modifying an existing JID in such a way as
+ to make it invalid, such trying to remove the domain from an existing
+ full JID while the local and resource portions still exist.
+ """
+
+# pylint: disable=R0903
+class UnescapedJID:
+
+ """
+ .. versionadded:: 1.1.10
+ """
+
+ __slots__ = ('_node', '_domain', '_resource')
+
+ def __init__(self, node, domain, resource):
+ self._node = node
+ self._domain = domain
+ self._resource = resource
+
+ def __getattribute__(self, name):
+ """Retrieve the given JID component.
+
+ :param name: one of: user, server, domain, resource,
+ full, or bare.
+ """
+ if name == 'resource':
+ return self._resource or ''
+ if name in ('user', 'username', 'local', 'node'):
+ return self._node or ''
+ if name in ('server', 'domain', 'host'):
+ return self._domain or ''
+ if name in ('full', 'jid'):
+ return _format_jid(self._node, self._domain, self._resource)
+ if name == 'bare':
+ return _format_jid(self._node, self._domain)
+ return object.__getattribute__(self, name)
+
+ def __str__(self):
+ """Use the full JID as the string value."""
+ return _format_jid(self._node, self._domain, self._resource)
+
+ def __repr__(self):
+ """Use the full JID as the representation."""
+ return _format_jid(self._node, self._domain, self._resource)
+
+
+class JID:
+
+ """
+ A representation of a Jabber ID, or JID.
+
+ Each JID may have three components: a user, a domain, and an optional
+ resource. For example: user@domain/resource
+
+ When a resource is not used, the JID is called a bare JID.
+ The JID is a full JID otherwise.
+
+ **JID Properties:**
+ :full: The string value of the full JID.
+ :jid: Alias for ``full``.
+ :bare: The string value of the bare JID.
+ :node: The node portion of the JID.
+ :user: Alias for ``node``.
+ :local: Alias for ``node``.
+ :username: Alias for ``node``.
+ :domain: The domain name portion of the JID.
+ :server: Alias for ``domain``.
+ :host: Alias for ``domain``.
+ :resource: The resource portion of the JID.
+
+ :param string jid:
+ A string of the form ``'[user@]domain[/resource]'``.
+
+ :raises InvalidJID:
+ """
+
+ __slots__ = ('_node', '_domain', '_resource')
+
+ def __init__(self, jid=None):
+ if not jid:
+ self._node = None
+ self._domain = None
+ self._resource = None
+ elif not isinstance(jid, JID):
+ self._node, self._domain, self._resource = _parse_jid(jid)
+ else:
+ self._node = jid._node
+ self._domain = jid._domain
+ self._resource = jid._resource
+
+ def unescape(self):
+ """Return an unescaped JID object.
+
+ Using an unescaped JID is preferred for displaying JIDs
+ to humans, and they should NOT be used for any other
+ purposes than for presentation.
+
+ :return: :class:`UnescapedJID`
+
+ .. versionadded:: 1.1.10
+ """
+ return UnescapedJID(_unescape_node(self._node),
+ self._domain,
+ self._resource)
+
+ @property
+ def node(self):
+ return self._node or ''
+
+ @property
+ def user(self):
+ return self._node or ''
+
+ @property
+ def local(self):
+ return self._node or ''
+
+ @property
+ def username(self):
+ return self._node or ''
+
+ @property
+ def domain(self):
+ return self._domain or ''
+
+ @property
+ def server(self):
+ return self._domain or ''
+
+ @property
+ def host(self):
+ return self._domain or ''
+
+ @property
+ def resource(self):
+ return self._resource or ''
+
+ @property
+ def bare(self):
+ return _format_jid(self._node, self._domain)
+
+ @property
+ def full(self):
+ return _format_jid(self._node, self._domain, self._resource)
+
+ @property
+ def jid(self):
+ return _format_jid(self._node, self._domain, self._resource)
+
+ @node.setter
+ def node(self, value):
+ self._node = _validate_node(value)
+
+ @user.setter
+ def user(self, value):
+ self._node = _validate_node(value)
+
+ @local.setter
+ def local(self, value):
+ self._node = _validate_node(value)
+
+ @username.setter
+ def username(self, value):
+ self._node = _validate_node(value)
+
+ @domain.setter
+ def domain(self, value):
+ self._domain = _validate_domain(value)
+
+ @server.setter
+ def server(self, value):
+ self._domain = _validate_domain(value)
+
+ @host.setter
+ def host(self, value):
+ self._domain = _validate_domain(value)
+
+ @bare.setter
+ def bare(self, value):
+ node, domain, resource = _parse_jid(value)
+ assert not resource
+ self._node = node
+ self._domain = domain
+
+ @resource.setter
+ def resource(self, value):
+ self._resource = _validate_resource(value)
+
+ @full.setter
+ def full(self, value):
+ self._node, self._domain, self._resource = _parse_jid(value)
+
+ @jid.setter
+ def jid(self, value):
+ self._node, self._domain, self._resource = _parse_jid(value)
+
+ def __str__(self):
+ """Use the full JID as the string value."""
+ return _format_jid(self._node, self._domain, self._resource)
+
+ def __repr__(self):
+ """Use the full JID as the representation."""
+ return _format_jid(self._node, self._domain, self._resource)
+
+ # pylint: disable=W0212
+ def __eq__(self, other):
+ """Two JIDs are equal if they have the same full JID value."""
+ if isinstance(other, UnescapedJID):
+ return False
+ if not isinstance(other, JID):
+ other = JID(other)
+
+ return (self._node == other._node and
+ self._domain == other._domain and
+ self._resource == other._resource)
+
+ def __ne__(self, other):
+ """Two JIDs are considered unequal if they are not equal."""
+ return not self == other
+
+ def __hash__(self):
+ """Hash a JID based on the string version of its full JID."""
+ return hash(_format_jid(self._node, self._domain, self._resource))
diff --git a/sleekxmpp/plugins/__init__.py b/slixmpp/plugins/__init__.py
index f501687b..d28cf281 100644
--- a/sleekxmpp/plugins/__init__.py
+++ b/slixmpp/plugins/__init__.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins.base import PluginManager, PluginNotFound, BasePlugin
-from sleekxmpp.plugins.base import register_plugin, load_plugin
+from slixmpp.plugins.base import PluginManager, PluginNotFound, BasePlugin
+from slixmpp.plugins.base import register_plugin, load_plugin
__all__ = [
diff --git a/sleekxmpp/plugins/base.py b/slixmpp/plugins/base.py
index 67675908..0fe083bc 100644
--- a/sleekxmpp/plugins/base.py
+++ b/slixmpp/plugins/base.py
@@ -1,13 +1,13 @@
# -*- encoding: utf-8 -*-
"""
- sleekxmpp.plugins.base
+ slixmpp.plugins.base
~~~~~~~~~~~~~~~~~~~~~~
This module provides XMPP functionality that
is specific to client connections.
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2012 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
@@ -19,10 +19,6 @@ import logging
import threading
-if sys.version_info >= (3, 0):
- unicode = str
-
-
log = logging.getLogger(__name__)
@@ -82,14 +78,14 @@ def load_plugin(name, module=None):
try:
if not module:
try:
- module = 'sleekxmpp.plugins.%s' % name
+ module = 'slixmpp.plugins.%s' % name
__import__(module)
mod = sys.modules[module]
except ImportError:
- module = 'sleekxmpp.features.%s' % name
+ module = 'slixmpp.features.%s' % name
__import__(module)
mod = sys.modules[module]
- elif isinstance(module, (str, unicode)):
+ elif isinstance(module, str):
__import__(module)
mod = sys.modules[module]
else:
@@ -146,7 +142,6 @@ class PluginManager(object):
:param dict config: Optional settings dictionary for
configuring plugin behaviour.
"""
- top_level = False
if enabled is None:
enabled = set()
@@ -170,14 +165,14 @@ class PluginManager(object):
self.enable(dep, enabled=enabled)
plugin._init()
- if top_level:
- for name in enabled:
- if hasattr(self.plugins[name], 'old_style'):
- # Older style plugins require post_init()
- # to run just before stream processing begins,
- # so we don't call it here.
- pass
- self.plugins[name].post_init()
+ for name in enabled:
+ if hasattr(self._plugins[name], 'old_style'):
+ # Older style plugins require post_init()
+ # to run just before stream processing begins,
+ # so we don't call it here.
+ pass
+ else:
+ self._plugins[name].post_init()
def enable_all(self, names=None, config=None):
"""Enable all registered plugins.
@@ -355,6 +350,3 @@ class BasePlugin(object):
Only needed if the plugin has circular dependencies.
"""
pass
-
-
-base_plugin = BasePlugin
diff --git a/sleekxmpp/plugins/gmail_notify.py b/slixmpp/plugins/gmail_notify.py
index fc97a2ab..8071984c 100644
--- a/sleekxmpp/plugins/gmail_notify.py
+++ b/slixmpp/plugins/gmail_notify.py
@@ -1,16 +1,16 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from . import base
+from slixmpp.plugins import BasePlugin
from .. xmlstream.handler.callback import Callback
from .. xmlstream.matcher.xpath import MatchXPath
-from .. xmlstream.stanzabase import registerStanzaPlugin, ElementBase, ET, JID
+from .. xmlstream.stanzabase import register_stanza_plugin, ElementBase, ET, JID
from .. stanza.iq import Iq
@@ -90,7 +90,7 @@ class NewMail(ElementBase):
plugin_attrib = 'new-mail'
-class gmail_notify(base.base_plugin):
+class gmail_notify(BasePlugin):
"""
Google Talk: Gmail Notifications
"""
@@ -112,9 +112,9 @@ class gmail_notify(base.base_plugin):
NewMail.name)),
self.handle_new_mail))
- registerStanzaPlugin(Iq, GmailQuery)
- registerStanzaPlugin(Iq, MailBox)
- registerStanzaPlugin(Iq, NewMail)
+ register_stanza_plugin(Iq, GmailQuery)
+ register_stanza_plugin(Iq, MailBox)
+ register_stanza_plugin(Iq, NewMail)
self.last_result_time = None
diff --git a/sleekxmpp/plugins/google/auth/stanza.py b/slixmpp/plugins/google/auth/stanza.py
index 2d13f85a..c5c693ee 100644
--- a/sleekxmpp/plugins/google/auth/stanza.py
+++ b/slixmpp/plugins/google/auth/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class GoogleAuth(ElementBase):
@@ -21,13 +21,11 @@ class GoogleAuth(ElementBase):
def setup(self, xml):
"""Don't create XML for the plugin."""
self.xml = ET.Element('')
- print('setting up google extension')
def get_client_uses_full_bind_result(self):
return self.parent()._get_attr(self.discovery_attr) == 'true'
def set_client_uses_full_bind_result(self, value):
- print('>>>', value)
if value in (True, 'true'):
self.parent()._set_attr(self.discovery_attr, 'true')
else:
diff --git a/sleekxmpp/plugins/google/gmail/notifications.py b/slixmpp/plugins/google/gmail/notifications.py
index e65b2ca7..e6785ccb 100644
--- a/sleekxmpp/plugins/google/gmail/notifications.py
+++ b/slixmpp/plugins/google/gmail/notifications.py
@@ -1,19 +1,19 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.stanza import Iq
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import MatchXPath
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.google.gmail import stanza
+from slixmpp.stanza import Iq
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import MatchXPath
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.google.gmail import stanza
log = logging.getLogger(__name__)
@@ -56,22 +56,16 @@ class Gmail(BasePlugin):
iq.reply().send()
self.xmpp.event('gmail_notification')
- def check(self, block=True, timeout=None, callback=None):
+ def check(self, timeout=None, callback=None):
last_time = self._last_result_time
last_tid = self._last_result_tid
- if not block:
- callback = lambda iq: self._update_last_results(iq, callback)
+ callback = lambda iq: self._update_last_results(iq, callback)
- resp = self.search(newer_time=last_time,
- newer_tid=last_tid,
- block=block,
- timeout=timeout,
- callback=callback)
-
- if block:
- self._update_last_results(resp)
- return resp
+ return self.search(newer_time=last_time,
+ newer_tid=last_tid,
+ timeout=timeout,
+ callback=callback)
def _update_last_results(self, iq, callback=None):
self._last_result_time = iq['gmail_messages']['result_time']
@@ -81,7 +75,7 @@ class Gmail(BasePlugin):
if callback:
callback(iq)
- def search(self, query=None, newer_time=None, newer_tid=None, block=True,
+ def search(self, query=None, newer_time=None, newer_tid=None,
timeout=None, callback=None):
if not query:
log.info('Gmail: Checking for new email')
@@ -93,4 +87,4 @@ class Gmail(BasePlugin):
iq['gmail']['search'] = query
iq['gmail']['newer_than_time'] = newer_time
iq['gmail']['newer_than_tid'] = newer_tid
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback)
diff --git a/sleekxmpp/plugins/google/nosave/stanza.py b/slixmpp/plugins/google/nosave/stanza.py
index 791d4b0c..b060a486 100644
--- a/sleekxmpp/plugins/google/nosave/stanza.py
+++ b/slixmpp/plugins/google/nosave/stanza.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.jid import JID
-from sleekxmpp.xmlstream import ElementBase, register_stanza_plugin
+from slixmpp.jid import JID
+from slixmpp.xmlstream import ElementBase, register_stanza_plugin
class NoSave(ElementBase):
diff --git a/sleekxmpp/plugins/google/settings/settings.py b/slixmpp/plugins/google/settings/settings.py
index 591956fc..84a8dfa9 100644
--- a/sleekxmpp/plugins/google/settings/settings.py
+++ b/slixmpp/plugins/google/settings/settings.py
@@ -1,17 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza import Iq
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.google.settings import stanza
+from slixmpp.stanza import Iq
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.google.settings import stanza
class GoogleSettings(BasePlugin):
@@ -38,13 +38,13 @@ class GoogleSettings(BasePlugin):
def plugin_end(self):
self.xmpp.remove_handler('Google Settings')
- def get(self, block=True, timeout=None, callback=None):
+ def get(self, timeout=None, callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'get'
iq.enable('google_settings')
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback)
- def update(self, settings, block=True, timeout=None, callback=None):
+ def update(self, settings, timeout=None, callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq.enable('google_settings')
@@ -52,7 +52,7 @@ class GoogleSettings(BasePlugin):
for setting, value in settings.items():
iq['google_settings'][setting] = value
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback)
def _handle_settings_change(self, iq):
reply = self.xmpp.Iq()
diff --git a/slixmpp/plugins/xep_0004/__init__.py b/slixmpp/plugins/xep_0004/__init__.py
new file mode 100644
index 00000000..3eb2b7a5
--- /dev/null
+++ b/slixmpp/plugins/xep_0004/__init__.py
@@ -0,0 +1,22 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0004.stanza import Form
+from slixmpp.plugins.xep_0004.stanza import FormField, FieldOption
+from slixmpp.plugins.xep_0004.dataforms import XEP_0004
+
+
+register_plugin(XEP_0004)
+
+
+# Retain some backwards compatibility
+xep_0004 = XEP_0004
+xep_0004.makeForm = xep_0004.make_form
+xep_0004.buildForm = xep_0004.build_form
diff --git a/sleekxmpp/plugins/xep_0004/dataforms.py b/slixmpp/plugins/xep_0004/dataforms.py
index dde6e6a8..90a87774 100644
--- a/sleekxmpp/plugins/xep_0004/dataforms.py
+++ b/slixmpp/plugins/xep_0004/dataforms.py
@@ -1,18 +1,18 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp import Message
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0004 import stanza
-from sleekxmpp.plugins.xep_0004.stanza import Form, FormField, FieldOption
+from slixmpp import Message
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0004 import stanza
+from slixmpp.plugins.xep_0004.stanza import Form, FormField, FieldOption
class XEP_0004(BasePlugin):
diff --git a/slixmpp/plugins/xep_0004/stanza/__init__.py b/slixmpp/plugins/xep_0004/stanza/__init__.py
new file mode 100644
index 00000000..9daaab75
--- /dev/null
+++ b/slixmpp/plugins/xep_0004/stanza/__init__.py
@@ -0,0 +1,10 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.xep_0004.stanza.field import FormField, FieldOption
+from slixmpp.plugins.xep_0004.stanza.form import Form
diff --git a/sleekxmpp/plugins/xep_0004/stanza/field.py b/slixmpp/plugins/xep_0004/stanza/field.py
index 73e48758..42f1210b 100644
--- a/sleekxmpp/plugins/xep_0004/stanza/field.py
+++ b/slixmpp/plugins/xep_0004/stanza/field.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class FormField(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0004/stanza/form.py b/slixmpp/plugins/xep_0004/stanza/form.py
index 3dcc7821..0c67acc6 100644
--- a/sleekxmpp/plugins/xep_0004/stanza/form.py
+++ b/slixmpp/plugins/xep_0004/stanza/form.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,10 +9,11 @@
import copy
import logging
-from sleekxmpp.thirdparty import OrderedDict, OrderedSet
+from collections import OrderedDict
+from slixmpp.thirdparty import OrderedSet
-from sleekxmpp.xmlstream import ElementBase, ET
-from sleekxmpp.plugins.xep_0004.stanza import FormField
+from slixmpp.xmlstream import ElementBase, ET
+from slixmpp.plugins.xep_0004.stanza import FormField
log = logging.getLogger(__name__)
@@ -259,21 +260,16 @@ class Form(ElementBase):
return new
-Form.setType = Form.set_type
Form.addField = Form.add_field
-Form.addItem = Form.add_item
Form.addReported = Form.add_reported
Form.delFields = Form.del_fields
Form.delInstructions = Form.del_instructions
-Form.delItems = Form.del_items
Form.delReported = Form.del_reported
Form.getFields = Form.get_fields
Form.getInstructions = Form.get_instructions
-Form.getItems = Form.get_items
Form.getReported = Form.get_reported
Form.getValues = Form.get_values
Form.setFields = Form.set_fields
Form.setInstructions = Form.set_instructions
-Form.setItems = Form.set_items
Form.setReported = Form.set_reported
Form.setValues = Form.set_values
diff --git a/slixmpp/plugins/xep_0009/__init__.py b/slixmpp/plugins/xep_0009/__init__.py
new file mode 100644
index 00000000..a06306b2
--- /dev/null
+++ b/slixmpp/plugins/xep_0009/__init__.py
@@ -0,0 +1,20 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Dann Martens (TOMOTON).
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0009 import stanza
+from slixmpp.plugins.xep_0009.rpc import XEP_0009
+from slixmpp.plugins.xep_0009.stanza import RPCQuery, MethodCall, MethodResponse
+
+
+register_plugin(XEP_0009)
+
+
+# Retain some backwards compatibility
+xep_0009 = XEP_0009
diff --git a/sleekxmpp/plugins/xep_0009/binding.py b/slixmpp/plugins/xep_0009/binding.py
index a55993ad..d922dfc7 100644
--- a/sleekxmpp/plugins/xep_0009/binding.py
+++ b/slixmpp/plugins/xep_0009/binding.py
@@ -1,19 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Dann Martens (TOMOTON).
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ET
+from slixmpp.xmlstream import ET
import base64
import logging
import time
-import sys
-
-if sys.version_info > (3, 0):
- unicode = str
log = logging.getLogger(__name__)
@@ -58,7 +54,7 @@ def _py2xml(*args):
boolean = ET.Element("{%s}boolean" % _namespace)
boolean.text = str(int(x))
val.append(boolean)
- elif type(x) in (str, unicode):
+ elif type(x) is str:
string = ET.Element("{%s}string" % _namespace)
string.text = x
val.append(string)
@@ -156,7 +152,7 @@ class rpctime(object):
def __init__(self,data=None):
#assume string data is in iso format YYYYMMDDTHH:MM:SS
- if type(data) in (str, unicode):
+ if type(data) is str:
self.timestamp = time.strptime(data,"%Y%m%dT%H:%M:%S")
elif type(data) is time.struct_time:
self.timestamp = data
diff --git a/sleekxmpp/plugins/xep_0009/remote.py b/slixmpp/plugins/xep_0009/remote.py
index b02f587e..9675c88d 100644
--- a/sleekxmpp/plugins/xep_0009/remote.py
+++ b/slixmpp/plugins/xep_0009/remote.py
@@ -1,32 +1,25 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Dann Martens (TOMOTON).
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins.xep_0009.binding import py2xml, xml2py, xml2fault, fault2xml
+from slixmpp.plugins.xep_0009.binding import py2xml, xml2py, xml2fault, fault2xml
from threading import RLock
import abc
import inspect
import logging
-import sleekxmpp
+import slixmpp
import sys
import threading
import traceback
log = logging.getLogger(__name__)
-# Define a function _isstr() to check if an object is a string in a way
-# compatible with Python 2 and Python 3 (basestring does not exists in Python 3).
-try:
- basestring # This evaluation will throw an exception if basestring does not exists (Python 3).
- def _isstr(obj):
- return isinstance(obj, basestring)
-except NameError:
- def _isstr(obj):
- return isinstance(obj, str)
+def _isstr(obj):
+ return isinstance(obj, str)
# Class decorator to declare a metaclass to a class in a way compatible with Python 2 and 3.
@@ -472,7 +465,7 @@ class RemoteSession(object):
Initializes a new RPC session.
Arguments:
- client -- The SleekXMPP client associated with this session.
+ client -- The Slixmpp client associated with this session.
session_close_callback -- A callback called when the
session is closed.
'''
@@ -489,7 +482,7 @@ class RemoteSession(object):
def _notify(self, event):
log.debug("RPC Session as %s started.", self._client.boundjid.full)
- self._client.sendPresence()
+ self._client.send_presence()
self._event.set()
pass
@@ -768,12 +761,12 @@ class Remote(object):
callback -- An optional callback which can be used to track
the starting state of the session.
'''
- client = sleekxmpp.ClientXMPP(jid, password)
+ client = slixmpp.ClientXMPP(jid, password)
#? Register plug-ins.
- client.registerPlugin('xep_0004') # Data Forms
- client.registerPlugin('xep_0009') # Jabber-RPC
- client.registerPlugin('xep_0030') # Service Discovery
- client.registerPlugin('xep_0060') # PubSub
- client.registerPlugin('xep_0199') # XMPP Ping
+ client.register_plugin('xep_0004') # Data Forms
+ client.register_plugin('xep_0009') # Jabber-RPC
+ client.register_plugin('xep_0030') # Service Discovery
+ client.register_plugin('xep_0060') # PubSub
+ client.register_plugin('xep_0199') # XMPP Ping
return cls.new_session_with_client(client, callback)
diff --git a/sleekxmpp/plugins/xep_0009/rpc.py b/slixmpp/plugins/xep_0009/rpc.py
index 6179355e..3ce156cf 100644
--- a/sleekxmpp/plugins/xep_0009/rpc.py
+++ b/slixmpp/plugins/xep_0009/rpc.py
@@ -1,218 +1,223 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Dann Martens (TOMOTON).
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-import logging
-
-from sleekxmpp import Iq
-from sleekxmpp.xmlstream import ET, register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import MatchXPath
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0009 import stanza
-from sleekxmpp.plugins.xep_0009.stanza.RPC import RPCQuery, MethodCall, MethodResponse
-
-
-log = logging.getLogger(__name__)
-
-
-class XEP_0009(BasePlugin):
-
- name = 'xep_0009'
- description = 'XEP-0009: Jabber-RPC'
- dependencies = set(['xep_0030'])
- stanza = stanza
-
- def plugin_init(self):
- register_stanza_plugin(Iq, RPCQuery)
- register_stanza_plugin(RPCQuery, MethodCall)
- register_stanza_plugin(RPCQuery, MethodResponse)
-
- self.xmpp.register_handler(
- Callback('RPC Call', MatchXPath('{%s}iq/{%s}query/{%s}methodCall' % (self.xmpp.default_ns, RPCQuery.namespace, RPCQuery.namespace)),
- self._handle_method_call)
- )
- self.xmpp.register_handler(
- Callback('RPC Call', MatchXPath('{%s}iq/{%s}query/{%s}methodResponse' % (self.xmpp.default_ns, RPCQuery.namespace, RPCQuery.namespace)),
- self._handle_method_response)
- )
- self.xmpp.register_handler(
- Callback('RPC Call', MatchXPath('{%s}iq/{%s}error' % (self.xmpp.default_ns, self.xmpp.default_ns)),
- self._handle_error)
- )
- self.xmpp.add_event_handler('jabber_rpc_method_call', self._on_jabber_rpc_method_call)
- self.xmpp.add_event_handler('jabber_rpc_method_response', self._on_jabber_rpc_method_response)
- self.xmpp.add_event_handler('jabber_rpc_method_fault', self._on_jabber_rpc_method_fault)
- self.xmpp.add_event_handler('jabber_rpc_error', self._on_jabber_rpc_error)
- self.xmpp.add_event_handler('error', self._handle_error)
- #self.activeCalls = []
-
- self.xmpp['xep_0030'].add_feature('jabber:iq:rpc')
- self.xmpp['xep_0030'].add_identity('automation','rpc')
-
- def make_iq_method_call(self, pto, pmethod, params):
- iq = self.xmpp.makeIqSet()
- iq.attrib['to'] = pto
- iq.attrib['from'] = self.xmpp.boundjid.full
- iq.enable('rpc_query')
- iq['rpc_query']['method_call']['method_name'] = pmethod
- iq['rpc_query']['method_call']['params'] = params
- return iq
-
- def make_iq_method_response(self, pid, pto, params):
- iq = self.xmpp.makeIqResult(pid)
- iq.attrib['to'] = pto
- iq.attrib['from'] = self.xmpp.boundjid.full
- iq.enable('rpc_query')
- iq['rpc_query']['method_response']['params'] = params
- return iq
-
- def make_iq_method_response_fault(self, pid, pto, params):
- iq = self.xmpp.makeIqResult(pid)
- iq.attrib['to'] = pto
- iq.attrib['from'] = self.xmpp.boundjid.full
- iq.enable('rpc_query')
- iq['rpc_query']['method_response']['params'] = None
- iq['rpc_query']['method_response']['fault'] = params
- return iq
-
-# def make_iq_method_error(self, pto, pid, pmethod, params, code, type, condition):
-# iq = self.xmpp.makeIqError(pid)
-# iq.attrib['to'] = pto
-# iq.attrib['from'] = self.xmpp.boundjid.full
-# iq['error']['code'] = code
-# iq['error']['type'] = type
-# iq['error']['condition'] = condition
-# iq['rpc_query']['method_call']['method_name'] = pmethod
-# iq['rpc_query']['method_call']['params'] = params
-# return iq
-
- def _item_not_found(self, iq):
- payload = iq.get_payload()
- iq.reply().error().set_payload(payload)
- iq['error']['code'] = '404'
- iq['error']['type'] = 'cancel'
- iq['error']['condition'] = 'item-not-found'
- return iq
-
- def _undefined_condition(self, iq):
- payload = iq.get_payload()
- iq.reply().error().set_payload(payload)
- iq['error']['code'] = '500'
- iq['error']['type'] = 'cancel'
- iq['error']['condition'] = 'undefined-condition'
- return iq
-
- def _forbidden(self, iq):
- payload = iq.get_payload()
- iq.reply().error().set_payload(payload)
- iq['error']['code'] = '403'
- iq['error']['type'] = 'auth'
- iq['error']['condition'] = 'forbidden'
- return iq
-
- def _recipient_unvailable(self, iq):
- payload = iq.get_payload()
- iq.reply().error().set_payload(payload)
- iq['error']['code'] = '404'
- iq['error']['type'] = 'wait'
- iq['error']['condition'] = 'recipient-unavailable'
- return iq
-
- def _handle_method_call(self, iq):
- type = iq['type']
- if type == 'set':
- log.debug("Incoming Jabber-RPC call from %s", iq['from'])
- self.xmpp.event('jabber_rpc_method_call', iq)
- else:
- if type == 'error' and ['rpc_query'] is None:
- self.handle_error(iq)
- else:
- log.debug("Incoming Jabber-RPC error from %s", iq['from'])
- self.xmpp.event('jabber_rpc_error', iq)
-
- def _handle_method_response(self, iq):
- if iq['rpc_query']['method_response']['fault'] is not None:
- log.debug("Incoming Jabber-RPC fault from %s", iq['from'])
- #self._on_jabber_rpc_method_fault(iq)
- self.xmpp.event('jabber_rpc_method_fault', iq)
- else:
- log.debug("Incoming Jabber-RPC response from %s", iq['from'])
- self.xmpp.event('jabber_rpc_method_response', iq)
-
- def _handle_error(self, iq):
- print("['XEP-0009']._handle_error -> ERROR! Iq is '%s'" % iq)
- print("#######################")
- print("### NOT IMPLEMENTED ###")
- print("#######################")
-
- def _on_jabber_rpc_method_call(self, iq, forwarded=False):
- """
- A default handler for Jabber-RPC method call. If another
- handler is registered, this one will defer and not run.
-
- If this handler is called by your own custom handler with
- forwarded set to True, then it will run as normal.
- """
- if not forwarded and self.xmpp.event_handled('jabber_rpc_method_call') > 1:
- return
- # Reply with error by default
- error = self.client.plugin['xep_0009']._item_not_found(iq)
- error.send()
-
- def _on_jabber_rpc_method_response(self, iq, forwarded=False):
- """
- A default handler for Jabber-RPC method response. If another
- handler is registered, this one will defer and not run.
-
- If this handler is called by your own custom handler with
- forwarded set to True, then it will run as normal.
- """
- if not forwarded and self.xmpp.event_handled('jabber_rpc_method_response') > 1:
- return
- error = self.client.plugin['xep_0009']._recpient_unavailable(iq)
- error.send()
-
- def _on_jabber_rpc_method_fault(self, iq, forwarded=False):
- """
- A default handler for Jabber-RPC fault response. If another
- handler is registered, this one will defer and not run.
-
- If this handler is called by your own custom handler with
- forwarded set to True, then it will run as normal.
- """
- if not forwarded and self.xmpp.event_handled('jabber_rpc_method_fault') > 1:
- return
- error = self.client.plugin['xep_0009']._recpient_unavailable(iq)
- error.send()
-
- def _on_jabber_rpc_error(self, iq, forwarded=False):
- """
- A default handler for Jabber-RPC error response. If another
- handler is registered, this one will defer and not run.
-
- If this handler is called by your own custom handler with
- forwarded set to True, then it will run as normal.
- """
- if not forwarded and self.xmpp.event_handled('jabber_rpc_error') > 1:
- return
- error = self.client.plugin['xep_0009']._recpient_unavailable(iq, iq.get_payload())
- error.send()
-
- def _send_fault(self, iq, fault_xml): #
- fault = self.make_iq_method_response_fault(iq['id'], iq['from'], fault_xml)
- fault.send()
-
- def _send_error(self, iq):
- print("['XEP-0009']._send_error -> ERROR! Iq is '%s'" % iq)
- print("#######################")
- print("### NOT IMPLEMENTED ###")
- print("#######################")
-
- def _extract_method(self, stanza):
- xml = ET.fromstring("%s" % stanza)
- return xml.find("./methodCall/methodName").text
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Dann Martens (TOMOTON).
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+import logging
+
+from slixmpp import Iq
+from slixmpp.xmlstream import ET, register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import MatchXPath
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0009 import stanza
+from slixmpp.plugins.xep_0009.stanza.RPC import RPCQuery, MethodCall, MethodResponse
+
+
+log = logging.getLogger(__name__)
+
+
+class XEP_0009(BasePlugin):
+
+ name = 'xep_0009'
+ description = 'XEP-0009: Jabber-RPC'
+ dependencies = set(['xep_0030'])
+ stanza = stanza
+
+ def plugin_init(self):
+ register_stanza_plugin(Iq, RPCQuery)
+ register_stanza_plugin(RPCQuery, MethodCall)
+ register_stanza_plugin(RPCQuery, MethodResponse)
+
+ self.xmpp.register_handler(
+ Callback('RPC Call', MatchXPath('{%s}iq/{%s}query/{%s}methodCall' % (self.xmpp.default_ns, RPCQuery.namespace, RPCQuery.namespace)),
+ self._handle_method_call)
+ )
+ self.xmpp.register_handler(
+ Callback('RPC Call', MatchXPath('{%s}iq/{%s}query/{%s}methodResponse' % (self.xmpp.default_ns, RPCQuery.namespace, RPCQuery.namespace)),
+ self._handle_method_response)
+ )
+ self.xmpp.register_handler(
+ Callback('RPC Call', MatchXPath('{%s}iq/{%s}error' % (self.xmpp.default_ns, self.xmpp.default_ns)),
+ self._handle_error)
+ )
+ self.xmpp.add_event_handler('jabber_rpc_method_call', self._on_jabber_rpc_method_call)
+ self.xmpp.add_event_handler('jabber_rpc_method_response', self._on_jabber_rpc_method_response)
+ self.xmpp.add_event_handler('jabber_rpc_method_fault', self._on_jabber_rpc_method_fault)
+ self.xmpp.add_event_handler('jabber_rpc_error', self._on_jabber_rpc_error)
+ self.xmpp.add_event_handler('error', self._handle_error)
+ #self.activeCalls = []
+
+ self.xmpp['xep_0030'].add_feature('jabber:iq:rpc')
+ self.xmpp['xep_0030'].add_identity('automation','rpc')
+
+ def make_iq_method_call(self, pto, pmethod, params):
+ iq = self.xmpp.make_iq_set()
+ iq.attrib['to'] = pto
+ iq.attrib['from'] = self.xmpp.boundjid.full
+ iq.enable('rpc_query')
+ iq['rpc_query']['method_call']['method_name'] = pmethod
+ iq['rpc_query']['method_call']['params'] = params
+ return iq
+
+ def make_iq_method_response(self, pid, pto, params):
+ iq = self.xmpp.make_iq_result(pid)
+ iq.attrib['to'] = pto
+ iq.attrib['from'] = self.xmpp.boundjid.full
+ iq.enable('rpc_query')
+ iq['rpc_query']['method_response']['params'] = params
+ return iq
+
+ def make_iq_method_response_fault(self, pid, pto, params):
+ iq = self.xmpp.make_iq_result(pid)
+ iq.attrib['to'] = pto
+ iq.attrib['from'] = self.xmpp.boundjid.full
+ iq.enable('rpc_query')
+ iq['rpc_query']['method_response']['params'] = None
+ iq['rpc_query']['method_response']['fault'] = params
+ return iq
+
+# def make_iq_method_error(self, pto, pid, pmethod, params, code, type, condition):
+# iq = self.xmpp.make_iq_error(pid)
+# iq.attrib['to'] = pto
+# iq.attrib['from'] = self.xmpp.boundjid.full
+# iq['error']['code'] = code
+# iq['error']['type'] = type
+# iq['error']['condition'] = condition
+# iq['rpc_query']['method_call']['method_name'] = pmethod
+# iq['rpc_query']['method_call']['params'] = params
+# return iq
+
+ def _item_not_found(self, iq):
+ payload = iq.get_payload()
+ iq = iq.reply()
+ iq.error().set_payload(payload)
+ iq['error']['code'] = '404'
+ iq['error']['type'] = 'cancel'
+ iq['error']['condition'] = 'item-not-found'
+ return iq
+
+ def _undefined_condition(self, iq):
+ payload = iq.get_payload()
+ iq = iq.reply()
+ iq.error().set_payload(payload)
+ iq['error']['code'] = '500'
+ iq['error']['type'] = 'cancel'
+ iq['error']['condition'] = 'undefined-condition'
+ return iq
+
+ def _forbidden(self, iq):
+ payload = iq.get_payload()
+ iq = iq.reply()
+ iq.error().set_payload(payload)
+ iq['error']['code'] = '403'
+ iq['error']['type'] = 'auth'
+ iq['error']['condition'] = 'forbidden'
+ return iq
+
+ def _recipient_unvailable(self, iq):
+ payload = iq.get_payload()
+ iq = iq.reply()
+ error().set_payload(payload)
+ iq['error']['code'] = '404'
+ iq['error']['type'] = 'wait'
+ iq['error']['condition'] = 'recipient-unavailable'
+ return iq
+
+ def _handle_method_call(self, iq):
+ type = iq['type']
+ if type == 'set':
+ log.debug("Incoming Jabber-RPC call from %s", iq['from'])
+ self.xmpp.event('jabber_rpc_method_call', iq)
+ else:
+ if type == 'error' and ['rpc_query'] is None:
+ self.handle_error(iq)
+ else:
+ log.debug("Incoming Jabber-RPC error from %s", iq['from'])
+ self.xmpp.event('jabber_rpc_error', iq)
+
+ def _handle_method_response(self, iq):
+ if iq['rpc_query']['method_response']['fault'] is not None:
+ log.debug("Incoming Jabber-RPC fault from %s", iq['from'])
+ #self._on_jabber_rpc_method_fault(iq)
+ self.xmpp.event('jabber_rpc_method_fault', iq)
+ else:
+ log.debug("Incoming Jabber-RPC response from %s", iq['from'])
+ self.xmpp.event('jabber_rpc_method_response', iq)
+
+ def _handle_error(self, iq):
+ print("['XEP-0009']._handle_error -> ERROR! Iq is '%s'" % iq)
+ print("#######################")
+ print("### NOT IMPLEMENTED ###")
+ print("#######################")
+
+ def _on_jabber_rpc_method_call(self, iq, forwarded=False):
+ """
+ A default handler for Jabber-RPC method call. If another
+ handler is registered, this one will defer and not run.
+
+ If this handler is called by your own custom handler with
+ forwarded set to True, then it will run as normal.
+ """
+ if not forwarded and self.xmpp.event_handled('jabber_rpc_method_call') > 1:
+ return
+ # Reply with error by default
+ error = self.client.plugin['xep_0009']._item_not_found(iq)
+ error.send()
+
+ def _on_jabber_rpc_method_response(self, iq, forwarded=False):
+ """
+ A default handler for Jabber-RPC method response. If another
+ handler is registered, this one will defer and not run.
+
+ If this handler is called by your own custom handler with
+ forwarded set to True, then it will run as normal.
+ """
+ if not forwarded and self.xmpp.event_handled('jabber_rpc_method_response') > 1:
+ return
+ error = self.client.plugin['xep_0009']._recpient_unavailable(iq)
+ error.send()
+
+ def _on_jabber_rpc_method_fault(self, iq, forwarded=False):
+ """
+ A default handler for Jabber-RPC fault response. If another
+ handler is registered, this one will defer and not run.
+
+ If this handler is called by your own custom handler with
+ forwarded set to True, then it will run as normal.
+ """
+ if not forwarded and self.xmpp.event_handled('jabber_rpc_method_fault') > 1:
+ return
+ error = self.client.plugin['xep_0009']._recpient_unavailable(iq)
+ error.send()
+
+ def _on_jabber_rpc_error(self, iq, forwarded=False):
+ """
+ A default handler for Jabber-RPC error response. If another
+ handler is registered, this one will defer and not run.
+
+ If this handler is called by your own custom handler with
+ forwarded set to True, then it will run as normal.
+ """
+ if not forwarded and self.xmpp.event_handled('jabber_rpc_error') > 1:
+ return
+ error = self.client.plugin['xep_0009']._recpient_unavailable(iq, iq.get_payload())
+ error.send()
+
+ def _send_fault(self, iq, fault_xml): #
+ fault = self.make_iq_method_response_fault(iq['id'], iq['from'], fault_xml)
+ fault.send()
+
+ def _send_error(self, iq):
+ print("['XEP-0009']._send_error -> ERROR! Iq is '%s'" % iq)
+ print("#######################")
+ print("### NOT IMPLEMENTED ###")
+ print("#######################")
+
+ def _extract_method(self, stanza):
+ xml = ET.fromstring("%s" % stanza)
+ return xml.find("./methodCall/methodName").text
+
diff --git a/sleekxmpp/plugins/xep_0009/stanza/RPC.py b/slixmpp/plugins/xep_0009/stanza/RPC.py
index 3d1c77a2..3abab8fc 100644
--- a/sleekxmpp/plugins/xep_0009/stanza/RPC.py
+++ b/slixmpp/plugins/xep_0009/stanza/RPC.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Dann Martens (TOMOTON).
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream.stanzabase import ElementBase
+from slixmpp.xmlstream.stanzabase import ElementBase
from xml.etree import cElementTree as ET
diff --git a/slixmpp/plugins/xep_0009/stanza/__init__.py b/slixmpp/plugins/xep_0009/stanza/__init__.py
new file mode 100644
index 00000000..79a8a3d7
--- /dev/null
+++ b/slixmpp/plugins/xep_0009/stanza/__init__.py
@@ -0,0 +1,9 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Dann Martens (TOMOTON).
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.xep_0009.stanza.RPC import RPCQuery, MethodCall, MethodResponse
diff --git a/slixmpp/plugins/xep_0012/__init__.py b/slixmpp/plugins/xep_0012/__init__.py
new file mode 100644
index 00000000..3dd39987
--- /dev/null
+++ b/slixmpp/plugins/xep_0012/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0012.stanza import LastActivity
+from slixmpp.plugins.xep_0012.last_activity import XEP_0012
+
+
+register_plugin(XEP_0012)
+
+
+# Retain some backwards compatibility
+xep_0004 = XEP_0012
diff --git a/sleekxmpp/plugins/xep_0012/last_activity.py b/slixmpp/plugins/xep_0012/last_activity.py
index 8790b47c..6a7773c1 100644
--- a/sleekxmpp/plugins/xep_0012/last_activity.py
+++ b/slixmpp/plugins/xep_0012/last_activity.py
@@ -1,157 +1,156 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-import logging
-from datetime import datetime, timedelta
-
-from sleekxmpp.plugins import BasePlugin, register_plugin
-from sleekxmpp import Iq
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.xmlstream import JID, register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins.xep_0012 import stanza, LastActivity
-
-
-log = logging.getLogger(__name__)
-
-
-class XEP_0012(BasePlugin):
-
- """
- XEP-0012 Last Activity
- """
-
- name = 'xep_0012'
- description = 'XEP-0012: Last Activity'
- dependencies = set(['xep_0030'])
- stanza = stanza
-
- def plugin_init(self):
- register_stanza_plugin(Iq, LastActivity)
-
- self._last_activities = {}
-
- self.xmpp.register_handler(
- Callback('Last Activity',
- StanzaPath('iq@type=get/last_activity'),
- self._handle_get_last_activity))
-
- self.api.register(self._default_get_last_activity,
- 'get_last_activity',
- default=True)
- self.api.register(self._default_set_last_activity,
- 'set_last_activity',
- default=True)
- self.api.register(self._default_del_last_activity,
- 'del_last_activity',
- default=True)
-
- def plugin_end(self):
- self.xmpp.remove_handler('Last Activity')
- self.xmpp['xep_0030'].del_feature(feature='jabber:iq:last')
-
- def session_bind(self, jid):
- self.xmpp['xep_0030'].add_feature('jabber:iq:last')
-
- def begin_idle(self, jid=None, status=None):
- self.set_last_activity(jid, 0, status)
-
- def end_idle(self, jid=None):
- self.del_last_activity(jid)
-
- def start_uptime(self, status=None):
- self.set_last_activity(jid, 0, status)
-
- def set_last_activity(self, jid=None, seconds=None, status=None):
- self.api['set_last_activity'](jid, args={
- 'seconds': seconds,
- 'status': status})
-
- def del_last_activity(self, jid):
- self.api['del_last_activity'](jid)
-
- def get_last_activity(self, jid, local=False, ifrom=None, block=True,
- timeout=None, callback=None):
- if jid is not None and not isinstance(jid, JID):
- jid = JID(jid)
-
- if self.xmpp.is_component:
- if jid.domain == self.xmpp.boundjid.domain:
- local = True
- else:
- if str(jid) == str(self.xmpp.boundjid):
- local = True
- jid = jid.full
-
- if local or jid in (None, ''):
- log.debug("Looking up local last activity data for %s", jid)
- return self.api['get_last_activity'](jid, None, ifrom, None)
-
- iq = self.xmpp.Iq()
- iq['from'] = ifrom
- iq['to'] = jid
- iq['type'] = 'get'
- iq.enable('last_activity')
- return iq.send(timeout=timeout,
- block=block,
- callback=callback)
-
- def _handle_get_last_activity(self, iq):
- log.debug("Received last activity query from " + \
- "<%s> to <%s>.", iq['from'], iq['to'])
- reply = self.api['get_last_activity'](iq['to'], None, iq['from'], iq)
- reply.send()
-
- # =================================================================
- # Default in-memory implementations for storing last activity data.
- # =================================================================
-
- def _default_set_last_activity(self, jid, node, ifrom, data):
- seconds = data.get('seconds', None)
- if seconds is None:
- seconds = 0
-
- status = data.get('status', None)
- if status is None:
- status = ''
-
- self._last_activities[jid] = {
- 'seconds': datetime.now() - timedelta(seconds=seconds),
- 'status': status}
-
- def _default_del_last_activity(self, jid, node, ifrom, data):
- if jid in self._last_activities:
- del self._last_activities[jid]
-
- def _default_get_last_activity(self, jid, node, ifrom, iq):
- if not isinstance(iq, Iq):
- reply = self.xmpp.Iq()
- else:
- iq.reply()
- reply = iq
-
- if jid not in self._last_activities:
- raise XMPPError('service-unavailable')
-
- bare = JID(jid).bare
-
- if bare != self.xmpp.boundjid.bare:
- if bare in self.xmpp.roster[jid]:
- sub = self.xmpp.roster[jid][bare]['subscription']
- if sub not in ('from', 'both'):
- raise XMPPError('forbidden')
-
- td = datetime.now() - self._last_activities[jid]['seconds']
- seconds = td.seconds + td.days * 24 * 3600
- status = self._last_activities[jid]['status']
-
- reply['last_activity']['seconds'] = seconds
- reply['last_activity']['status'] = status
-
- return reply
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+import logging
+from datetime import datetime, timedelta
+
+from slixmpp.plugins import BasePlugin, register_plugin
+from slixmpp import future_wrapper, Iq
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream import JID, register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins.xep_0012 import stanza, LastActivity
+
+
+log = logging.getLogger(__name__)
+
+
+class XEP_0012(BasePlugin):
+
+ """
+ XEP-0012 Last Activity
+ """
+
+ name = 'xep_0012'
+ description = 'XEP-0012: Last Activity'
+ dependencies = set(['xep_0030'])
+ stanza = stanza
+
+ def plugin_init(self):
+ register_stanza_plugin(Iq, LastActivity)
+
+ self._last_activities = {}
+
+ self.xmpp.register_handler(
+ Callback('Last Activity',
+ StanzaPath('iq@type=get/last_activity'),
+ self._handle_get_last_activity))
+
+ self.api.register(self._default_get_last_activity,
+ 'get_last_activity',
+ default=True)
+ self.api.register(self._default_set_last_activity,
+ 'set_last_activity',
+ default=True)
+ self.api.register(self._default_del_last_activity,
+ 'del_last_activity',
+ default=True)
+
+ def plugin_end(self):
+ self.xmpp.remove_handler('Last Activity')
+ self.xmpp['xep_0030'].del_feature(feature='jabber:iq:last')
+
+ def session_bind(self, jid):
+ self.xmpp['xep_0030'].add_feature('jabber:iq:last')
+
+ def begin_idle(self, jid=None, status=None):
+ self.set_last_activity(jid, 0, status)
+
+ def end_idle(self, jid=None):
+ self.del_last_activity(jid)
+
+ def start_uptime(self, status=None):
+ self.set_last_activity(jid, 0, status)
+
+ def set_last_activity(self, jid=None, seconds=None, status=None):
+ self.api['set_last_activity'](jid, args={
+ 'seconds': seconds,
+ 'status': status})
+
+ def del_last_activity(self, jid):
+ self.api['del_last_activity'](jid)
+
+ @future_wrapper
+ def get_last_activity(self, jid, local=False, ifrom=None, timeout=None,
+ callback=None, timeout_callback=None):
+ if jid is not None and not isinstance(jid, JID):
+ jid = JID(jid)
+
+ if self.xmpp.is_component:
+ if jid.domain == self.xmpp.boundjid.domain:
+ local = True
+ else:
+ if str(jid) == str(self.xmpp.boundjid):
+ local = True
+ jid = jid.full
+
+ if local or jid in (None, ''):
+ log.debug("Looking up local last activity data for %s", jid)
+ return self.api['get_last_activity'](jid, None, ifrom, None)
+
+ iq = self.xmpp.Iq()
+ iq['from'] = ifrom
+ iq['to'] = jid
+ iq['type'] = 'get'
+ iq.enable('last_activity')
+ return iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
+
+ def _handle_get_last_activity(self, iq):
+ log.debug("Received last activity query from " + \
+ "<%s> to <%s>.", iq['from'], iq['to'])
+ reply = self.api['get_last_activity'](iq['to'], None, iq['from'], iq)
+ reply.send()
+
+ # =================================================================
+ # Default in-memory implementations for storing last activity data.
+ # =================================================================
+
+ def _default_set_last_activity(self, jid, node, ifrom, data):
+ seconds = data.get('seconds', None)
+ if seconds is None:
+ seconds = 0
+
+ status = data.get('status', None)
+ if status is None:
+ status = ''
+
+ self._last_activities[jid] = {
+ 'seconds': datetime.now() - timedelta(seconds=seconds),
+ 'status': status}
+
+ def _default_del_last_activity(self, jid, node, ifrom, data):
+ if jid in self._last_activities:
+ del self._last_activities[jid]
+
+ def _default_get_last_activity(self, jid, node, ifrom, iq):
+ if not isinstance(iq, Iq):
+ reply = self.xmpp.Iq()
+ else:
+ reply = iq.reply()
+
+ if jid not in self._last_activities:
+ raise XMPPError('service-unavailable')
+
+ bare = JID(jid).bare
+
+ if bare != self.xmpp.boundjid.bare:
+ if bare in self.xmpp.roster[jid]:
+ sub = self.xmpp.roster[jid][bare]['subscription']
+ if sub not in ('from', 'both'):
+ raise XMPPError('forbidden')
+
+ td = datetime.now() - self._last_activities[jid]['seconds']
+ seconds = td.seconds + td.days * 24 * 3600
+ status = self._last_activities[jid]['status']
+
+ reply['last_activity']['seconds'] = seconds
+ reply['last_activity']['status'] = status
+
+ return reply
diff --git a/sleekxmpp/plugins/xep_0012/stanza.py b/slixmpp/plugins/xep_0012/stanza.py
index 079865b9..bd539a2d 100644
--- a/sleekxmpp/plugins/xep_0012/stanza.py
+++ b/slixmpp/plugins/xep_0012/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class LastActivity(ElementBase):
diff --git a/slixmpp/plugins/xep_0013/__init__.py b/slixmpp/plugins/xep_0013/__init__.py
new file mode 100644
index 00000000..c02a6c5a
--- /dev/null
+++ b/slixmpp/plugins/xep_0013/__init__.py
@@ -0,0 +1,15 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permissio
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0013.stanza import Offline
+from slixmpp.plugins.xep_0013.offline import XEP_0013
+
+
+register_plugin(XEP_0013)
diff --git a/sleekxmpp/plugins/xep_0013/offline.py b/slixmpp/plugins/xep_0013/offline.py
index a0d992a7..51840e7b 100644
--- a/sleekxmpp/plugins/xep_0013/offline.py
+++ b/slixmpp/plugins/xep_0013/offline.py
@@ -1,21 +1,21 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permissio
"""
import logging
-import sleekxmpp
-from sleekxmpp.stanza import Message, Iq
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.xmlstream.handler import Collector
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0013 import stanza
+import slixmpp
+from slixmpp.stanza import Message, Iq
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream.handler import Collector
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0013 import stanza
log = logging.getLogger(__name__)
@@ -48,7 +48,8 @@ class XEP_0013(BasePlugin):
local=False,
**kwargs)
- def view(self, nodes, ifrom=None, block=True, timeout=None, callback=None):
+ def view(self, nodes, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
if not isinstance(nodes, (list, set)):
nodes = [nodes]
@@ -67,23 +68,16 @@ class XEP_0013(BasePlugin):
StanzaPath('message/offline'))
self.xmpp.register_handler(collector)
- if not block and callback is not None:
- def wrapped_cb(iq):
- results = collector.stop()
- if iq['type'] == 'result':
- iq['offline']['results'] = results
- callback(iq)
- return iq.send(block=block, timeout=timeout, callback=wrapped_cb)
- else:
- try:
- resp = iq.send(block=block, timeout=timeout, callback=callback)
- resp['offline']['results'] = collector.stop()
- return resp
- except XMPPError as e:
- collector.stop()
- raise e
-
- def remove(self, nodes, ifrom=None, block=True, timeout=None, callback=None):
+ def wrapped_cb(iq):
+ results = collector.stop()
+ if iq['type'] == 'result':
+ iq['offline']['results'] = results
+ callback(iq)
+ iq.send(timeout=timeout, callback=wrapped_cb,
+ timeout_callback=timeout_callback)
+
+ def remove(self, nodes, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
if not isinstance(nodes, (list, set)):
nodes = [nodes]
@@ -97,9 +91,11 @@ class XEP_0013(BasePlugin):
item['action'] = 'remove'
offline.append(item)
- return iq.send(block=block, timeout=timeout, callback=callback)
+ iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
- def fetch(self, ifrom=None, block=True, timeout=None, callback=None):
+ def fetch(self, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq['from'] = ifrom
@@ -110,25 +106,19 @@ class XEP_0013(BasePlugin):
StanzaPath('message/offline'))
self.xmpp.register_handler(collector)
- if not block and callback is not None:
- def wrapped_cb(iq):
- results = collector.stop()
- if iq['type'] == 'result':
- iq['offline']['results'] = results
- callback(iq)
- return iq.send(block=block, timeout=timeout, callback=wrapped_cb)
- else:
- try:
- resp = iq.send(block=block, timeout=timeout, callback=callback)
- resp['offline']['results'] = collector.stop()
- return resp
- except XMPPError as e:
- collector.stop()
- raise e
-
- def purge(self, ifrom=None, block=True, timeout=None, callback=None):
+ def wrapped_cb(iq):
+ results = collector.stop()
+ if iq['type'] == 'result':
+ iq['offline']['results'] = results
+ callback(iq)
+ iq.send(timeout=timeout, callback=wrapped_cb,
+ timeout_callback=timeout_callback)
+
+ def purge(self, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq['from'] = ifrom
iq['offline']['purge'] = True
- return iq.send(block=block, timeout=timeout, callback=callback)
+ iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
diff --git a/sleekxmpp/plugins/xep_0013/stanza.py b/slixmpp/plugins/xep_0013/stanza.py
index c9c69786..cf9c385b 100644
--- a/sleekxmpp/plugins/xep_0013/stanza.py
+++ b/slixmpp/plugins/xep_0013/stanza.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permissio
"""
-from sleekxmpp.jid import JID
-from sleekxmpp.xmlstream import ElementBase, register_stanza_plugin
+from slixmpp.jid import JID
+from slixmpp.xmlstream import ElementBase, register_stanza_plugin
class Offline(ElementBase):
diff --git a/slixmpp/plugins/xep_0016/__init__.py b/slixmpp/plugins/xep_0016/__init__.py
new file mode 100644
index 00000000..aa95c78d
--- /dev/null
+++ b/slixmpp/plugins/xep_0016/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0016 import stanza
+from slixmpp.plugins.xep_0016.stanza import Privacy
+from slixmpp.plugins.xep_0016.privacy import XEP_0016
+
+
+register_plugin(XEP_0016)
diff --git a/slixmpp/plugins/xep_0016/privacy.py b/slixmpp/plugins/xep_0016/privacy.py
new file mode 100644
index 00000000..38444b2b
--- /dev/null
+++ b/slixmpp/plugins/xep_0016/privacy.py
@@ -0,0 +1,127 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp import Iq
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0016 import stanza
+from slixmpp.plugins.xep_0016.stanza import Privacy, Item
+
+
+class XEP_0016(BasePlugin):
+
+ name = 'xep_0016'
+ description = 'XEP-0016: Privacy Lists'
+ dependencies = set(['xep_0030'])
+ stanza = stanza
+
+ def plugin_init(self):
+ register_stanza_plugin(Iq, Privacy)
+
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature=Privacy.namespace)
+
+ def session_bind(self, jid):
+ self.xmpp['xep_0030'].add_feature(Privacy.namespace)
+
+ def get_privacy_lists(self, timeout=None, callback=None,
+ timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'get'
+ iq.enable('privacy')
+ iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
+
+ def get_list(self, name, timeout=None, callback=None, timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'get'
+ iq['privacy']['list']['name'] = name
+ iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
+
+ def get_active(self, timeout=None, callback=None, timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'get'
+ iq['privacy'].enable('active')
+ iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
+
+ def get_default(self, timeout=None, callback=None,
+ timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'get'
+ iq['privacy'].enable('default')
+ iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
+
+ def activate(self, name, timeout=None, callback=None,
+ timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'set'
+ iq['privacy']['active']['name'] = name
+ iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
+
+ def deactivate(self, timeout=None, callback=None,
+ timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'set'
+ iq['privacy'].enable('active')
+ iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
+
+ def make_default(self, name, timeout=None, callback=None,
+ timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'set'
+ iq['privacy']['default']['name'] = name
+ iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
+
+ def remove_default(self, timeout=None, callback=None,
+ timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'set'
+ iq['privacy'].enable('default')
+ iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
+
+ def edit_list(self, name, rules, timeout=None, callback=None,
+ timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'set'
+ iq['privacy']['list']['name'] = name
+ priv_list = iq['privacy']['list']
+
+ if not rules:
+ rules = []
+
+ for rule in rules:
+ if isinstance(rule, Item):
+ priv_list.append(rule)
+ continue
+
+ priv_list.add_item(
+ rule['value'],
+ rule['action'],
+ rule['order'],
+ itype=rule.get('type', None),
+ iq=rule.get('iq', None),
+ message=rule.get('message', None),
+ presence_in=rule.get('presence_in',
+ rule.get('presence-in', None)),
+ presence_out=rule.get('presence_out',
+ rule.get('presence-out', None)))
+
+ def remove_list(self, name, timeout=None, callback=None,
+ timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'set'
+ iq['privacy']['list']['name'] = name
+ iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
diff --git a/sleekxmpp/plugins/xep_0016/stanza.py b/slixmpp/plugins/xep_0016/stanza.py
index 3f9977fc..58c9fdb3 100644
--- a/sleekxmpp/plugins/xep_0016/stanza.py
+++ b/slixmpp/plugins/xep_0016/stanza.py
@@ -1,4 +1,4 @@
-from sleekxmpp.xmlstream import ET, ElementBase, register_stanza_plugin
+from slixmpp.xmlstream import ET, ElementBase, register_stanza_plugin
class Privacy(ElementBase):
diff --git a/slixmpp/plugins/xep_0020/__init__.py b/slixmpp/plugins/xep_0020/__init__.py
new file mode 100644
index 00000000..53d96fe4
--- /dev/null
+++ b/slixmpp/plugins/xep_0020/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0020 import stanza
+from slixmpp.plugins.xep_0020.stanza import FeatureNegotiation
+from slixmpp.plugins.xep_0020.feature_negotiation import XEP_0020
+
+
+register_plugin(XEP_0020)
diff --git a/sleekxmpp/plugins/xep_0020/feature_negotiation.py b/slixmpp/plugins/xep_0020/feature_negotiation.py
index 7cb82cd5..2f4e8c15 100644
--- a/sleekxmpp/plugins/xep_0020/feature_negotiation.py
+++ b/slixmpp/plugins/xep_0020/feature_negotiation.py
@@ -1,20 +1,20 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp import Iq, Message
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin, JID
-from sleekxmpp.plugins.xep_0020 import stanza, FeatureNegotiation
-from sleekxmpp.plugins.xep_0004 import Form
+from slixmpp import Iq, Message
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin, JID
+from slixmpp.plugins.xep_0020 import stanza, FeatureNegotiation
+from slixmpp.plugins.xep_0004 import Form
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/plugins/xep_0020/stanza.py b/slixmpp/plugins/xep_0020/stanza.py
index 13e4056e..d9cea8f4 100644
--- a/sleekxmpp/plugins/xep_0020/stanza.py
+++ b/slixmpp/plugins/xep_0020/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class FeatureNegotiation(ElementBase):
diff --git a/slixmpp/plugins/xep_0027/__init__.py b/slixmpp/plugins/xep_0027/__init__.py
new file mode 100644
index 00000000..1f510cb2
--- /dev/null
+++ b/slixmpp/plugins/xep_0027/__init__.py
@@ -0,0 +1,15 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0027.stanza import Signed, Encrypted
+from slixmpp.plugins.xep_0027.gpg import XEP_0027
+
+
+register_plugin(XEP_0027)
diff --git a/sleekxmpp/plugins/xep_0027/gpg.py b/slixmpp/plugins/xep_0027/gpg.py
index 52c1c461..a0b1df48 100644
--- a/sleekxmpp/plugins/xep_0027/gpg.py
+++ b/slixmpp/plugins/xep_0027/gpg.py
@@ -1,19 +1,19 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.thirdparty import GPG
+from slixmpp.thirdparty import GPG
-from sleekxmpp.stanza import Presence, Message
-from sleekxmpp.plugins.base import BasePlugin, register_plugin
-from sleekxmpp.xmlstream import ElementBase, register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins.xep_0027 import stanza, Signed, Encrypted
+from slixmpp.stanza import Presence, Message
+from slixmpp.plugins.base import BasePlugin, register_plugin
+from slixmpp.xmlstream import ElementBase, register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins.xep_0027 import stanza, Signed, Encrypted
def _extract_data(data, kind):
@@ -67,8 +67,7 @@ class XEP_0027(BasePlugin):
register_stanza_plugin(Message, Encrypted)
self.xmpp.add_event_handler('unverified_signed_presence',
- self._handle_unverified_signed_presence,
- threaded=True)
+ self._handle_unverified_signed_presence)
self.xmpp.register_handler(
Callback('Signed Presence',
diff --git a/sleekxmpp/plugins/xep_0027/stanza.py b/slixmpp/plugins/xep_0027/stanza.py
index 08f2032b..fd41cace 100644
--- a/sleekxmpp/plugins/xep_0027/stanza.py
+++ b/slixmpp/plugins/xep_0027/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class Signed(ElementBase):
diff --git a/slixmpp/plugins/xep_0030/__init__.py b/slixmpp/plugins/xep_0030/__init__.py
new file mode 100644
index 00000000..1fc71069
--- /dev/null
+++ b/slixmpp/plugins/xep_0030/__init__.py
@@ -0,0 +1,22 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0030 import stanza
+from slixmpp.plugins.xep_0030.stanza import DiscoInfo, DiscoItems
+from slixmpp.plugins.xep_0030.static import StaticDisco
+from slixmpp.plugins.xep_0030.disco import XEP_0030
+
+
+register_plugin(XEP_0030)
+
+# Retain some backwards compatibility
+xep_0030 = XEP_0030
+XEP_0030.getInfo = XEP_0030.get_info
+XEP_0030.make_static = XEP_0030.restore_defaults
diff --git a/sleekxmpp/plugins/xep_0030/disco.py b/slixmpp/plugins/xep_0030/disco.py
index 721f73f6..e6286b92 100644
--- a/sleekxmpp/plugins/xep_0030/disco.py
+++ b/slixmpp/plugins/xep_0030/disco.py
@@ -1,20 +1,21 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp import Iq
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin, JID
-from sleekxmpp.plugins.xep_0030 import stanza, DiscoInfo, DiscoItems
-from sleekxmpp.plugins.xep_0030 import StaticDisco
+from slixmpp import Iq
+from slixmpp import future_wrapper
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin, JID
+from slixmpp.plugins.xep_0030 import stanza, DiscoInfo, DiscoItems
+from slixmpp.plugins.xep_0030 import StaticDisco
log = logging.getLogger(__name__)
@@ -65,7 +66,7 @@ class XEP_0030(BasePlugin):
static node handlers.
default_handlers -- A dictionary mapping operations to the default
global handler (by default, the static handlers).
- xmpp -- The main SleekXMPP object.
+ xmpp -- The main Slixmpp object.
Methods:
set_node_handler -- Assign a handler to a JID/node combination.
@@ -122,6 +123,12 @@ class XEP_0030(BasePlugin):
for op in self._disco_ops:
self.api.register(getattr(self.static, op), op, default=True)
+ def session_bind(self, jid):
+ self.add_feature('http://jabber.org/protocol/disco#info')
+
+ def plugin_end(self):
+ self.del_feature('http://jabber.org/protocol/disco#info')
+
def _add_disco_op(self, op, default_handler):
self.api.register(default_handler, op)
self.api.register_default(default_handler, op)
@@ -233,7 +240,7 @@ class XEP_0030(BasePlugin):
node -- The particular node to query.
feature -- The name of the feature to check.
local -- If true, then the query is for a JID/node
- combination handled by this Sleek instance and
+ combination handled by this Slixmpp instance and
no stanzas need to be sent.
Otherwise, a disco stanza must be sent to the
remove JID to retrieve the info.
@@ -268,7 +275,7 @@ class XEP_0030(BasePlugin):
itype -- The type of the identity to check.
lang -- The language of the identity to check.
local -- If true, then the query is for a JID/node
- combination handled by this Sleek instance and
+ combination handled by this Slixmpp instance and
no stanzas need to be sent.
Otherwise, a disco stanza must be sent to the
remove JID to retrieve the info.
@@ -288,6 +295,7 @@ class XEP_0030(BasePlugin):
'cached': cached}
return self.api['has_identity'](jid, node, ifrom, data)
+ @future_wrapper
def get_info(self, jid=None, node=None, local=None,
cached=None, **kwargs):
"""
@@ -305,7 +313,7 @@ class XEP_0030(BasePlugin):
jid -- Request info from this JID.
node -- The particular node to query.
local -- If true, then the query is for a JID/node
- combination handled by this Sleek instance and
+ combination handled by this Slixmpp instance and
no stanzas need to be sent.
Otherwise, a disco stanza must be sent to the
remove JID to retrieve the info.
@@ -317,10 +325,8 @@ class XEP_0030(BasePlugin):
be skipped, even if a result has already been
cached. Defaults to false.
ifrom -- Specifiy the sender's JID.
- block -- If true, block and wait for the stanzas' reply.
- timeout -- The time in seconds to block while waiting for
- a reply. If None, then wait indefinitely. The
- timeout value is only used when block=True.
+ timeout -- The time in seconds to wait for reply, before
+ calling timeout_callback
callback -- Optional callback to execute when a reply is
received instead of blocking and waiting for
the reply.
@@ -365,7 +371,6 @@ class XEP_0030(BasePlugin):
iq['type'] = 'get'
iq['disco_info']['node'] = node if node else ''
return iq.send(timeout=kwargs.get('timeout', None),
- block=kwargs.get('block', True),
callback=kwargs.get('callback', None),
timeout_callback=kwargs.get('timeout_callback', None))
@@ -378,6 +383,7 @@ class XEP_0030(BasePlugin):
info = info['disco_info']
self.api['set_info'](jid, node, None, info)
+ @future_wrapper
def get_items(self, jid=None, node=None, local=False, **kwargs):
"""
Retrieve the disco#items results from a given JID/node combination.
@@ -394,12 +400,11 @@ class XEP_0030(BasePlugin):
jid -- Request info from this JID.
node -- The particular node to query.
local -- If true, then the query is for a JID/node
- combination handled by this Sleek instance and
+ combination handled by this Slixmpp instance and
no stanzas need to be sent.
Otherwise, a disco stanza must be sent to the
remove JID to retrieve the items.
ifrom -- Specifiy the sender's JID.
- block -- If true, block and wait for the stanzas' reply.
timeout -- The time in seconds to block while waiting for
a reply. If None, then wait indefinitely.
callback -- Optional callback to execute when a reply is
@@ -424,10 +429,10 @@ class XEP_0030(BasePlugin):
iq['type'] = 'get'
iq['disco_items']['node'] = node if node else ''
if kwargs.get('iterator', False) and self.xmpp['xep_0059']:
+ raise NotImplementedError("XEP 0059 has not yet been fixed")
return self.xmpp['xep_0059'].iterate(iq, 'disco_items')
else:
return iq.send(timeout=kwargs.get('timeout', None),
- block=kwargs.get('block', True),
callback=kwargs.get('callback', None),
timeout_callback=kwargs.get('timeout_callback', None))
@@ -641,7 +646,7 @@ class XEP_0030(BasePlugin):
info['id'] = iq['id']
info.send()
else:
- iq.reply()
+ iq = iq.reply()
if info:
info = self._fix_default_info(info)
iq.set_payload(info.xml)
@@ -681,7 +686,7 @@ class XEP_0030(BasePlugin):
if isinstance(items, Iq):
items.send()
else:
- iq.reply()
+ iq = iq.reply()
if items:
iq.set_payload(items.xml)
iq.send()
@@ -694,7 +699,7 @@ class XEP_0030(BasePlugin):
"""
Disco#info results for a JID are required to include at least
one identity and feature. As a default, if no other identity is
- provided, SleekXMPP will use either the generic component or the
+ provided, Slixmpp will use either the generic component or the
bot client identity. A the standard disco#info feature will also be
added if no features are provided.
diff --git a/slixmpp/plugins/xep_0030/stanza/__init__.py b/slixmpp/plugins/xep_0030/stanza/__init__.py
new file mode 100644
index 00000000..bdac9bf2
--- /dev/null
+++ b/slixmpp/plugins/xep_0030/stanza/__init__.py
@@ -0,0 +1,10 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.xep_0030.stanza.info import DiscoInfo
+from slixmpp.plugins.xep_0030.stanza.items import DiscoItems
diff --git a/sleekxmpp/plugins/xep_0030/stanza/info.py b/slixmpp/plugins/xep_0030/stanza/info.py
index 25d1d07f..39ee83d5 100644
--- a/sleekxmpp/plugins/xep_0030/stanza/info.py
+++ b/slixmpp/plugins/xep_0030/stanza/info.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class DiscoInfo(ElementBase):
@@ -40,7 +40,7 @@ class DiscoInfo(ElementBase):
<iq type="result">
<query xmlns="http://jabber.org/protocol/disco#info">
- <identity category="client" type="bot" name="SleekXMPP Bot" />
+ <identity category="client" type="bot" name="Slixmpp Bot" />
<feature var="http://jabber.org/protocol/disco#info" />
<feature var="jabber:x:data" />
<feature var="urn:xmpp:ping" />
@@ -120,7 +120,7 @@ class DiscoInfo(ElementBase):
id_xml.attrib['{%s}lang' % self.xml_ns] = lang
if name:
id_xml.attrib['name'] = name
- self.xml.append(id_xml)
+ self.xml.insert(0, id_xml)
return True
return False
diff --git a/sleekxmpp/plugins/xep_0030/stanza/items.py b/slixmpp/plugins/xep_0030/stanza/items.py
index 10458614..0e238492 100644
--- a/sleekxmpp/plugins/xep_0030/stanza/items.py
+++ b/slixmpp/plugins/xep_0030/stanza/items.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, register_stanza_plugin
+from slixmpp.xmlstream import ElementBase, register_stanza_plugin
class DiscoItems(ElementBase):
@@ -23,8 +23,8 @@ class DiscoItems(ElementBase):
node="xmppdev"
name="XMPP Dev" />
<item jid="chat.example.com"
- node="sleekdev"
- name="SleekXMPP Dev" />
+ node="slixdev"
+ name="Slixmpp Dev" />
</query>
</iq>
diff --git a/sleekxmpp/plugins/xep_0030/static.py b/slixmpp/plugins/xep_0030/static.py
index dd5317d1..d9a7c80a 100644
--- a/sleekxmpp/plugins/xep_0030/static.py
+++ b/slixmpp/plugins/xep_0030/static.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,10 +9,10 @@
import logging
import threading
-from sleekxmpp import Iq
-from sleekxmpp.exceptions import XMPPError, IqError, IqTimeout
-from sleekxmpp.xmlstream import JID
-from sleekxmpp.plugins.xep_0030 import DiscoInfo, DiscoItems
+from slixmpp import Iq
+from slixmpp.exceptions import XMPPError, IqError, IqTimeout
+from slixmpp.xmlstream import JID
+from slixmpp.plugins.xep_0030 import DiscoInfo, DiscoItems
log = logging.getLogger(__name__)
@@ -32,7 +32,7 @@ class StaticDisco(object):
Attributes:
nodes -- A dictionary mapping (JID, node) tuples to a dict
containing a disco#info and a disco#items stanza.
- xmpp -- The main SleekXMPP object.
+ xmpp -- The main Slixmpp object.
"""
def __init__(self, xmpp, disco):
@@ -43,7 +43,7 @@ class StaticDisco(object):
information in memory without any additional processing.
Arguments:
- xmpp -- The main SleekXMPP object.
+ xmpp -- The main Slixmpp object.
"""
self.nodes = {}
self.xmpp = xmpp
@@ -123,7 +123,7 @@ class StaticDisco(object):
The data parameter may provide:
feature -- The feature to check for support.
local -- If true, then the query is for a JID/node
- combination handled by this Sleek instance and
+ combination handled by this Slixmpp instance and
no stanzas need to be sent.
Otherwise, a disco stanza must be sent to the
remove JID to retrieve the info.
@@ -163,7 +163,7 @@ class StaticDisco(object):
itype -- The type of the identity to check.
lang -- The language of the identity to check.
local -- If true, then the query is for a JID/node
- combination handled by this Sleek instance and
+ combination handled by this Slixmpp instance and
no stanzas need to be sent.
Otherwise, a disco stanza must be sent to the
remove JID to retrieve the info.
diff --git a/slixmpp/plugins/xep_0033/__init__.py b/slixmpp/plugins/xep_0033/__init__.py
new file mode 100644
index 00000000..e6953ce7
--- /dev/null
+++ b/slixmpp/plugins/xep_0033/__init__.py
@@ -0,0 +1,20 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0033 import stanza
+from slixmpp.plugins.xep_0033.stanza import Addresses, Address
+from slixmpp.plugins.xep_0033.addresses import XEP_0033
+
+
+register_plugin(XEP_0033)
+
+# Retain some backwards compatibility
+xep_0033 = XEP_0033
+Addresses.addAddress = Addresses.add_address
diff --git a/sleekxmpp/plugins/xep_0033/addresses.py b/slixmpp/plugins/xep_0033/addresses.py
index 13cb7267..7b3c2d17 100644
--- a/sleekxmpp/plugins/xep_0033/addresses.py
+++ b/slixmpp/plugins/xep_0033/addresses.py
@@ -1,17 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp import Message, Presence
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0033 import stanza, Addresses
+from slixmpp import Message, Presence
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0033 import stanza, Addresses
class XEP_0033(BasePlugin):
diff --git a/sleekxmpp/plugins/xep_0033/stanza.py b/slixmpp/plugins/xep_0033/stanza.py
index 1ff9fb20..3f89f373 100644
--- a/sleekxmpp/plugins/xep_0033/stanza.py
+++ b/slixmpp/plugins/xep_0033/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import JID, ElementBase, ET, register_stanza_plugin
+from slixmpp.xmlstream import JID, ElementBase, ET, register_stanza_plugin
class Addresses(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0045.py b/slixmpp/plugins/xep_0045.py
index cc96d66e..f6f48891 100644
--- a/sleekxmpp/plugins/xep_0045.py
+++ b/slixmpp/plugins/xep_0045.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,13 +9,13 @@ from __future__ import with_statement
import logging
-from sleekxmpp import Presence
-from sleekxmpp.plugins import BasePlugin, register_plugin
-from sleekxmpp.xmlstream import register_stanza_plugin, ElementBase, JID, ET
-from sleekxmpp.xmlstream.handler.callback import Callback
-from sleekxmpp.xmlstream.matcher.xpath import MatchXPath
-from sleekxmpp.xmlstream.matcher.xmlmask import MatchXMLMask
-from sleekxmpp.exceptions import IqError, IqTimeout
+from slixmpp import Presence
+from slixmpp.plugins import BasePlugin, register_plugin
+from slixmpp.xmlstream import register_stanza_plugin, ElementBase, JID, ET
+from slixmpp.xmlstream.handler.callback import Callback
+from slixmpp.xmlstream.matcher.xpath import MatchXPath
+from slixmpp.xmlstream.matcher.xmlmask import MatchXMLMask
+from slixmpp.exceptions import IqError, IqTimeout
log = logging.getLogger(__name__)
@@ -135,6 +135,12 @@ class XEP_0045(BasePlugin):
'http://jabber.org/protocol/muc#user',
'http://jabber.org/protocol/muc#user')), self.handle_groupchat_invite))
+ def plugin_end(self):
+ self.xmpp.plugin['xep_0030'].del_feature(feature='http://jabber.org/protocol/muc')
+
+ def session_bind(self, jid):
+ self.xmpp.plugin['xep_0030'].add_feature('http://jabber.org/protocol/muc')
+
def handle_groupchat_invite(self, inv):
""" Handle an invite into a muc.
"""
@@ -154,7 +160,7 @@ class XEP_0045(BasePlugin):
got_online = False
if pr['muc']['room'] not in self.rooms.keys():
return
- entry = pr['muc'].getStanzaValues()
+ entry = pr['muc'].get_stanza_values()
entry['show'] = pr['show']
entry['status'] = pr['status']
entry['alt_nick'] = pr['nick']
@@ -210,7 +216,7 @@ class XEP_0045(BasePlugin):
def configureRoom(self, room, form=None, ifrom=None):
if form is None:
form = self.getRoomConfig(room, ifrom=ifrom)
- iq = self.xmpp.makeIqSet()
+ iq = self.xmpp.make_iq_set()
iq['to'] = room
if ifrom is not None:
iq['from'] = ifrom
@@ -230,7 +236,7 @@ class XEP_0045(BasePlugin):
def joinMUC(self, room, nick, maxhistory="0", password='', wait=False, pstatus=None, pshow=None, pfrom=None):
""" Join the specified room, requesting 'maxhistory' lines of history.
"""
- stanza = self.xmpp.makePresence(pto="%s/%s" % (room, nick), pstatus=pstatus, pshow=pshow, pfrom=pfrom)
+ stanza = self.xmpp.make_presence(pto="%s/%s" % (room, nick), pstatus=pstatus, pshow=pshow, pfrom=pfrom)
x = ET.Element('{http://jabber.org/protocol/muc}x')
if password:
passelement = ET.Element('{http://jabber.org/protocol/muc}password')
@@ -254,7 +260,7 @@ class XEP_0045(BasePlugin):
self.ourNicks[room] = nick
def destroy(self, room, reason='', altroom = '', ifrom=None):
- iq = self.xmpp.makeIqSet()
+ iq = self.xmpp.make_iq_set()
if ifrom is not None:
iq['from'] = ifrom
iq['to'] = room
@@ -286,7 +292,7 @@ class XEP_0045(BasePlugin):
else:
item = ET.Element('{http://jabber.org/protocol/muc#admin}item', {'affiliation':affiliation, 'jid':jid})
query.append(item)
- iq = self.xmpp.makeIqSet(query)
+ iq = self.xmpp.make_iq_set(query)
iq['to'] = room
iq['from'] = ifrom
# For now, swallow errors to preserve existing API
@@ -307,9 +313,9 @@ class XEP_0045(BasePlugin):
if role not in ('moderator', 'participant', 'visitor', 'none'):
raise TypeError
query = ET.Element('{http://jabber.org/protocol/muc#admin}query')
- item = ET.Element('item', {'role':role, 'nick':nick})
+ item = ET.Element('item', {'role':role, 'nick':nick})
query.append(item)
- iq = self.xmpp.makeIqSet(query)
+ iq = self.xmpp.make_iq_set(query)
iq['to'] = room
result = iq.send()
if result is False or result['type'] != 'result':
@@ -318,7 +324,7 @@ class XEP_0045(BasePlugin):
def invite(self, room, jid, reason='', mfrom=''):
""" Invite a jid to a room."""
- msg = self.xmpp.makeMessage(room)
+ msg = self.xmpp.make_message(room)
msg['from'] = mfrom
x = ET.Element('{http://jabber.org/protocol/muc#user}x')
invite = ET.Element('{http://jabber.org/protocol/muc#user}invite', {'to': jid})
@@ -334,13 +340,13 @@ class XEP_0045(BasePlugin):
""" Leave the specified room.
"""
if msg:
- self.xmpp.sendPresence(pshow='unavailable', pto="%s/%s" % (room, nick), pstatus=msg, pfrom=pfrom)
+ self.xmpp.send_presence(pshow='unavailable', pto="%s/%s" % (room, nick), pstatus=msg, pfrom=pfrom)
else:
- self.xmpp.sendPresence(pshow='unavailable', pto="%s/%s" % (room, nick), pfrom=pfrom)
+ self.xmpp.send_presence(pshow='unavailable', pto="%s/%s" % (room, nick), pfrom=pfrom)
del self.rooms[room]
def getRoomConfig(self, room, ifrom=''):
- iq = self.xmpp.makeIqGet('http://jabber.org/protocol/muc#owner')
+ iq = self.xmpp.make_iq_get('http://jabber.org/protocol/muc#owner')
iq['to'] = room
iq['from'] = ifrom
# For now, swallow errors to preserve existing API
@@ -359,7 +365,7 @@ class XEP_0045(BasePlugin):
query = ET.Element('{http://jabber.org/protocol/muc#owner}query')
x = ET.Element('{jabber:x:data}x', type='cancel')
query.append(x)
- iq = self.xmpp.makeIqSet(query)
+ iq = self.xmpp.make_iq_set(query)
iq['to'] = room
iq['from'] = ifrom
iq.send()
@@ -368,7 +374,7 @@ class XEP_0045(BasePlugin):
query = ET.Element('{http://jabber.org/protocol/muc#owner}query')
x = config.getXML('submit')
query.append(x)
- iq = self.xmpp.makeIqSet(query)
+ iq = self.xmpp.make_iq_set(query)
iq['to'] = room
iq['from'] = ifrom
iq.send()
diff --git a/slixmpp/plugins/xep_0047/__init__.py b/slixmpp/plugins/xep_0047/__init__.py
new file mode 100644
index 00000000..5bb9e7cc
--- /dev/null
+++ b/slixmpp/plugins/xep_0047/__init__.py
@@ -0,0 +1,21 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0047 import stanza
+from slixmpp.plugins.xep_0047.stanza import Open, Close, Data
+from slixmpp.plugins.xep_0047.stream import IBBytestream
+from slixmpp.plugins.xep_0047.ibb import XEP_0047
+
+
+register_plugin(XEP_0047)
+
+
+# Retain some backwards compatibility
+xep_0047 = XEP_0047
diff --git a/sleekxmpp/plugins/xep_0047/ibb.py b/slixmpp/plugins/xep_0047/ibb.py
index 62dddac2..52d7fbe5 100644
--- a/sleekxmpp/plugins/xep_0047/ibb.py
+++ b/slixmpp/plugins/xep_0047/ibb.py
@@ -1,14 +1,14 @@
+import asyncio
import uuid
import logging
-import threading
-from sleekxmpp import Message, Iq
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0047 import stanza, Open, Close, Data, IBBytestream
+from slixmpp import Message, Iq
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0047 import stanza, Open, Close, Data, IBBytestream
log = logging.getLogger(__name__)
@@ -23,17 +23,11 @@ class XEP_0047(BasePlugin):
default_config = {
'block_size': 4096,
'max_block_size': 8192,
- 'window_size': 1,
'auto_accept': False,
}
def plugin_init(self):
self._streams = {}
- self._pending_streams = {}
- self._pending_lock = threading.Lock()
- self._stream_lock = threading.Lock()
-
- self._preauthed_sids_lock = threading.Lock()
self._preauthed_sids = {}
register_stanza_plugin(Iq, Open)
@@ -85,9 +79,8 @@ class XEP_0047(BasePlugin):
self._streams[(jid, sid, peer_jid)] = stream
def _del_stream(self, jid, sid, peer_jid, data):
- with self._stream_lock:
- if (jid, sid, peer_jid) in self._streams:
- del self._streams[(jid, sid, peer_jid)]
+ if (jid, sid, peer_jid) in self._streams:
+ del self._streams[(jid, sid, peer_jid)]
def _accept_stream(self, iq):
receiver = iq['to']
@@ -100,23 +93,20 @@ class XEP_0047(BasePlugin):
def _authorized(self, jid, sid, ifrom, iq):
if self.auto_accept:
- if iq['ibb_open']['block_size'] <= self.max_block_size:
- return True
+ return True
return False
def _authorized_sid(self, jid, sid, ifrom, iq):
- with self._preauthed_sids_lock:
- if (jid, sid, ifrom) in self._preauthed_sids:
- del self._preauthed_sids[(jid, sid, ifrom)]
- return True
- return False
+ if (jid, sid, ifrom) in self._preauthed_sids:
+ del self._preauthed_sids[(jid, sid, ifrom)]
+ return True
+ return False
def _preauthorize_sid(self, jid, sid, ifrom, data):
- with self._preauthed_sids_lock:
- self._preauthed_sids[(jid, sid, ifrom)] = True
+ self._preauthed_sids[(jid, sid, ifrom)] = True
- def open_stream(self, jid, block_size=None, sid=None, window=1, use_messages=False,
- ifrom=None, block=True, timeout=None, callback=None):
+ def open_stream(self, jid, block_size=None, sid=None, use_messages=False,
+ ifrom=None, timeout=None, callback=None):
if sid is None:
sid = str(uuid.uuid4())
if block_size is None:
@@ -128,48 +118,28 @@ class XEP_0047(BasePlugin):
iq['from'] = ifrom
iq['ibb_open']['block_size'] = block_size
iq['ibb_open']['sid'] = sid
- iq['ibb_open']['stanza'] = 'iq'
+ iq['ibb_open']['stanza'] = 'message' if use_messages else 'iq'
stream = IBBytestream(self.xmpp, sid, block_size,
- iq['from'], iq['to'], window,
- use_messages)
+ iq['from'], iq['to'], use_messages)
- with self._stream_lock:
- self._pending_streams[iq['id']] = stream
+ stream_future = asyncio.Future()
- self._pending_streams[iq['id']] = stream
-
- if block:
- resp = iq.send(timeout=timeout)
- self._handle_opened_stream(resp)
- return stream
- else:
- cb = None
+ def _handle_opened_stream(iq):
+ log.debug('IBB stream (%s) accepted by %s', stream.sid, iq['from'])
+ stream.self_jid = iq['to']
+ stream.peer_jid = iq['from']
+ stream.stream_started = True
+ self.api['set_stream'](stream.self_jid, stream.sid, stream.peer_jid, stream)
+ stream_future.set_result(stream)
if callback is not None:
- def chained(resp):
- self._handle_opened_stream(resp)
- callback(resp)
- cb = chained
- else:
- cb = self._handle_opened_stream
- return iq.send(block=block, timeout=timeout, callback=cb)
-
- def _handle_opened_stream(self, iq):
- if iq['type'] == 'result':
- with self._stream_lock:
- stream = self._pending_streams.get(iq['id'], None)
- if stream is not None:
- log.debug('IBB stream (%s) accepted by %s', stream.sid, iq['from'])
- stream.self_jid = iq['to']
- stream.peer_jid = iq['from']
- stream.stream_started.set()
- self.api['set_stream'](stream.self_jid, stream.sid, stream.peer_jid, stream)
- self.xmpp.event('ibb_stream_start', stream)
- self.xmpp.event('stream:%s:%s' % (stream.sid, stream.peer_jid), stream)
-
- with self._stream_lock:
- if iq['id'] in self._pending_streams:
- del self._pending_streams[iq['id']]
+ callback(stream)
+ self.xmpp.event('ibb_stream_start', stream)
+ self.xmpp.event('stream:%s:%s' % (stream.sid, stream.peer_jid), stream)
+
+ iq.send(timeout=timeout, callback=_handle_opened_stream)
+
+ return stream_future
def _handle_open_request(self, iq):
sid = iq['ibb_open']['sid']
@@ -181,18 +151,16 @@ class XEP_0047(BasePlugin):
raise XMPPError(etype='modify', condition='bad-request')
if not self._accept_stream(iq):
- raise XMPPError(etype='modify', condition='not-acceptable')
+ raise XMPPError(etype='cancel', condition='not-acceptable')
if size > self.max_block_size:
raise XMPPError('resource-constraint')
stream = IBBytestream(self.xmpp, sid, size,
- iq['to'], iq['from'],
- self.window_size)
- stream.stream_started.set()
+ iq['to'], iq['from'])
+ stream.stream_started = True
self.api['set_stream'](stream.self_jid, stream.sid, stream.peer_jid, stream)
- iq.reply()
- iq.send()
+ iq.reply().send()
self.xmpp.event('ibb_stream_start', stream)
self.xmpp.event('stream:%s:%s' % (sid, stream.peer_jid), stream)
diff --git a/sleekxmpp/plugins/xep_0047/stanza.py b/slixmpp/plugins/xep_0047/stanza.py
index 7e5d2fed..7f8ff0ba 100644
--- a/sleekxmpp/plugins/xep_0047/stanza.py
+++ b/slixmpp/plugins/xep_0047/stanza.py
@@ -1,9 +1,9 @@
import re
import base64
-from sleekxmpp.util import bytes
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.util import bytes
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream import ElementBase
VALID_B64 = re.compile(r'[A-Za-z0-9\+\/]*=*')
@@ -24,7 +24,7 @@ class Open(ElementBase):
interfaces = set(('block_size', 'sid', 'stanza'))
def get_block_size(self):
- return int(self._get_attr('block-size'))
+ return int(self._get_attr('block-size', '0'))
def set_block_size(self, value):
self._set_attr('block-size', str(value))
@@ -47,7 +47,10 @@ class Data(ElementBase):
self._set_attr('seq', str(value))
def get_data(self):
- b64_data = self.xml.text.strip()
+ text = self.xml.text
+ if not text:
+ raise XMPPError('not-acceptable', 'IBB data element is empty.')
+ b64_data = text.strip()
if VALID_B64.match(b64_data).group() == b64_data:
return from_b64(b64_data)
else:
diff --git a/slixmpp/plugins/xep_0047/stream.py b/slixmpp/plugins/xep_0047/stream.py
new file mode 100644
index 00000000..3be894eb
--- /dev/null
+++ b/slixmpp/plugins/xep_0047/stream.py
@@ -0,0 +1,128 @@
+import asyncio
+import socket
+import logging
+
+from slixmpp.stanza import Iq
+from slixmpp.exceptions import XMPPError
+
+
+log = logging.getLogger(__name__)
+
+
+class IBBytestream(object):
+
+ def __init__(self, xmpp, sid, block_size, jid, peer, use_messages=False):
+ self.xmpp = xmpp
+ self.sid = sid
+ self.block_size = block_size
+ self.use_messages = use_messages
+
+ if jid is None:
+ jid = xmpp.boundjid
+ self.self_jid = jid
+ self.peer_jid = peer
+
+ self.send_seq = -1
+ self.recv_seq = -1
+
+ self.stream_started = False
+ self.stream_in_closed = False
+ self.stream_out_closed = False
+
+ self.recv_queue = asyncio.Queue()
+
+ @asyncio.coroutine
+ def send(self, data, timeout=None):
+ if not self.stream_started or self.stream_out_closed:
+ raise socket.error
+ if len(data) > self.block_size:
+ data = data[:self.block_size]
+ self.send_seq = (self.send_seq + 1) % 65535
+ seq = self.send_seq
+ if self.use_messages:
+ msg = self.xmpp.Message()
+ msg['to'] = self.peer_jid
+ msg['from'] = self.self_jid
+ msg['id'] = self.xmpp.new_id()
+ msg['ibb_data']['sid'] = self.sid
+ msg['ibb_data']['seq'] = seq
+ msg['ibb_data']['data'] = data
+ msg.send()
+ else:
+ iq = self.xmpp.Iq()
+ iq['type'] = 'set'
+ iq['to'] = self.peer_jid
+ iq['from'] = self.self_jid
+ iq['ibb_data']['sid'] = self.sid
+ iq['ibb_data']['seq'] = seq
+ iq['ibb_data']['data'] = data
+ yield from iq.send(timeout=timeout)
+ return len(data)
+
+ @asyncio.coroutine
+ def sendall(self, data, timeout=None):
+ sent_len = 0
+ while sent_len < len(data):
+ sent_len += yield from self.send(data[sent_len:self.block_size], timeout=timeout)
+
+ @asyncio.coroutine
+ def sendfile(self, file, timeout=None):
+ while True:
+ data = file.read(self.block_size)
+ if not data:
+ break
+ yield from self.send(data, timeout=timeout)
+
+ def _recv_data(self, stanza):
+ new_seq = stanza['ibb_data']['seq']
+ if new_seq != (self.recv_seq + 1) % 65535:
+ self.close()
+ raise XMPPError('unexpected-request')
+ self.recv_seq = new_seq
+
+ data = stanza['ibb_data']['data']
+ if len(data) > self.block_size:
+ self.close()
+ raise XMPPError('not-acceptable')
+
+ self.recv_queue.put_nowait(data)
+ self.xmpp.event('ibb_stream_data', self)
+
+ if isinstance(stanza, Iq):
+ stanza.reply().send()
+
+ def recv(self, *args, **kwargs):
+ return self.read()
+
+ def read(self):
+ if not self.stream_started or self.stream_in_closed:
+ raise socket.error
+ return self.recv_queue.get_nowait()
+
+ def close(self, timeout=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'set'
+ iq['to'] = self.peer_jid
+ iq['from'] = self.self_jid
+ iq['ibb_close']['sid'] = self.sid
+ self.stream_out_closed = True
+ def _close_stream(_):
+ self.stream_in_closed = True
+ future = iq.send(timeout=timeout, callback=_close_stream)
+ self.xmpp.event('ibb_stream_end', self)
+ return future
+
+ def _closed(self, iq):
+ self.stream_in_closed = True
+ self.stream_out_closed = True
+ iq.reply().send()
+ self.xmpp.event('ibb_stream_end', self)
+
+ def makefile(self, *args, **kwargs):
+ return self
+
+ def connect(*args, **kwargs):
+ return None
+
+ def shutdown(self, *args, **kwargs):
+ return None
diff --git a/slixmpp/plugins/xep_0048/__init__.py b/slixmpp/plugins/xep_0048/__init__.py
new file mode 100644
index 00000000..d19f12a3
--- /dev/null
+++ b/slixmpp/plugins/xep_0048/__init__.py
@@ -0,0 +1,15 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0048.stanza import Bookmarks, Conference, URL
+from slixmpp.plugins.xep_0048.bookmarks import XEP_0048
+
+
+register_plugin(XEP_0048)
diff --git a/sleekxmpp/plugins/xep_0048/bookmarks.py b/slixmpp/plugins/xep_0048/bookmarks.py
index 0bb5ae38..fa76df39 100644
--- a/sleekxmpp/plugins/xep_0048/bookmarks.py
+++ b/slixmpp/plugins/xep_0048/bookmarks.py
@@ -1,20 +1,20 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp import Iq
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0048 import stanza, Bookmarks, Conference, URL
+from slixmpp import Iq
+from slixmpp.plugins import BasePlugin
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.xep_0048 import stanza, Bookmarks, Conference, URL
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/plugins/xep_0048/stanza.py b/slixmpp/plugins/xep_0048/stanza.py
index 21829392..c158535a 100644
--- a/sleekxmpp/plugins/xep_0048/stanza.py
+++ b/slixmpp/plugins/xep_0048/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ET, ElementBase, register_stanza_plugin
+from slixmpp.xmlstream import ET, ElementBase, register_stanza_plugin
class Bookmarks(ElementBase):
diff --git a/slixmpp/plugins/xep_0049/__init__.py b/slixmpp/plugins/xep_0049/__init__.py
new file mode 100644
index 00000000..396be75d
--- /dev/null
+++ b/slixmpp/plugins/xep_0049/__init__.py
@@ -0,0 +1,15 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0049.stanza import PrivateXML
+from slixmpp.plugins.xep_0049.private_storage import XEP_0049
+
+
+register_plugin(XEP_0049)
diff --git a/sleekxmpp/plugins/xep_0049/private_storage.py b/slixmpp/plugins/xep_0049/private_storage.py
index ef6cbdde..a66c05d1 100644
--- a/sleekxmpp/plugins/xep_0049/private_storage.py
+++ b/slixmpp/plugins/xep_0049/private_storage.py
@@ -1,19 +1,19 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp import Iq
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0049 import stanza, PrivateXML
+from slixmpp import Iq
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.xep_0049 import stanza, PrivateXML
log = logging.getLogger(__name__)
@@ -32,7 +32,8 @@ class XEP_0049(BasePlugin):
def register(self, stanza):
register_stanza_plugin(PrivateXML, stanza, iterable=True)
- def store(self, data, ifrom=None, block=True, timeout=None, callback=None):
+ def store(self, data, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq['from'] = ifrom
@@ -43,11 +44,14 @@ class XEP_0049(BasePlugin):
for elem in data:
iq['private'].append(elem)
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
- def retrieve(self, name, ifrom=None, block=True, timeout=None, callback=None):
+ def retrieve(self, name, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'get'
iq['from'] = ifrom
iq['private'].enable(name)
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
diff --git a/sleekxmpp/plugins/xep_0049/stanza.py b/slixmpp/plugins/xep_0049/stanza.py
index d424e2f0..a8d425ba 100644
--- a/sleekxmpp/plugins/xep_0049/stanza.py
+++ b/slixmpp/plugins/xep_0049/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ET, ElementBase
+from slixmpp.xmlstream import ET, ElementBase
class PrivateXML(ElementBase):
diff --git a/slixmpp/plugins/xep_0050/__init__.py b/slixmpp/plugins/xep_0050/__init__.py
new file mode 100644
index 00000000..5a2d4805
--- /dev/null
+++ b/slixmpp/plugins/xep_0050/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0050.stanza import Command
+from slixmpp.plugins.xep_0050.adhoc import XEP_0050
+
+
+register_plugin(XEP_0050)
+
+
+# Retain some backwards compatibility
+xep_0050 = XEP_0050
diff --git a/sleekxmpp/plugins/xep_0050/adhoc.py b/slixmpp/plugins/xep_0050/adhoc.py
index 7ab659f4..fa6017d5 100644
--- a/sleekxmpp/plugins/xep_0050/adhoc.py
+++ b/slixmpp/plugins/xep_0050/adhoc.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,15 +9,15 @@
import logging
import time
-from sleekxmpp import Iq
-from sleekxmpp.exceptions import IqError
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin, JID
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0050 import stanza
-from sleekxmpp.plugins.xep_0050 import Command
-from sleekxmpp.plugins.xep_0004 import Form
+from slixmpp import Iq
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin, JID
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0050 import stanza
+from slixmpp.plugins.xep_0050 import Command
+from slixmpp.plugins.xep_0004 import Form
log = logging.getLogger(__name__)
@@ -37,10 +37,6 @@ class XEP_0050(BasePlugin):
Also see <http://xmpp.org/extensions/xep-0050.html>
- Configuration Values:
- threaded -- Indicates if command events should be threaded.
- Defaults to True.
-
Events:
command_execute -- Received a command with action="execute"
command_next -- Received a command with action="next"
@@ -48,8 +44,6 @@ class XEP_0050(BasePlugin):
command_cancel -- Received a command with action="cancel"
Attributes:
- threaded -- Indicates if command events should be threaded.
- Defaults to True.
commands -- A dictionary mapping JID/node pairs to command
names and handlers.
sessions -- A dictionary or equivalent backend mapping
@@ -57,8 +51,8 @@ class XEP_0050(BasePlugin):
relevant to a command's session.
Methods:
- plugin_init -- Overrides base_plugin.plugin_init
- post_init -- Overrides base_plugin.post_init
+ plugin_init -- Overrides BasePlugin.plugin_init
+ post_init -- Overrides BasePlugin.post_init
new_session -- Return a new session ID.
prep_handlers -- Placeholder. May call with a list of handlers
to prepare them for use with the session storage
@@ -83,7 +77,6 @@ class XEP_0050(BasePlugin):
dependencies = set(['xep_0030', 'xep_0004'])
stanza = stanza
default_config = {
- 'threaded': True,
'session_db': None
}
@@ -104,17 +97,13 @@ class XEP_0050(BasePlugin):
register_stanza_plugin(Command, Form, iterable=True)
self.xmpp.add_event_handler('command_execute',
- self._handle_command_start,
- threaded=self.threaded)
+ self._handle_command_start)
self.xmpp.add_event_handler('command_next',
- self._handle_command_next,
- threaded=self.threaded)
+ self._handle_command_next)
self.xmpp.add_event_handler('command_cancel',
- self._handle_command_cancel,
- threaded=self.threaded)
+ self._handle_command_cancel)
self.xmpp.add_event_handler('command_complete',
- self._handle_command_complete,
- threaded=self.threaded)
+ self._handle_command_complete)
def plugin_end(self):
self.xmpp.del_event_handler('command_execute',
@@ -227,6 +216,7 @@ class XEP_0050(BasePlugin):
name, handler = self.commands.get(key, ('Not found', None))
if not handler:
log.debug('Command not found: %s, %s', key, self.commands)
+ raise XMPPError('item-not-found')
payload = []
for stanza in iq['command']['substanzas']:
@@ -343,7 +333,7 @@ class XEP_0050(BasePlugin):
for item in payload:
register_stanza_plugin(Command, item.__class__, iterable=True)
- iq.reply()
+ iq = iq.reply()
iq['command']['node'] = session['node']
iq['command']['sessionid'] = session['id']
@@ -386,7 +376,7 @@ class XEP_0050(BasePlugin):
if handler:
handler(iq, session)
del self.sessions[sessionid]
- iq.reply()
+ iq = iq.reply()
iq['command']['node'] = node
iq['command']['sessionid'] = sessionid
iq['command']['status'] = 'canceled'
@@ -434,7 +424,8 @@ class XEP_0050(BasePlugin):
for item in payload:
register_stanza_plugin(Command, item.__class__, iterable=True)
- iq.reply()
+ iq = iq.reply()
+
iq['command']['node'] = node
iq['command']['sessionid'] = sessionid
iq['command']['actions'] = []
@@ -458,12 +449,11 @@ class XEP_0050(BasePlugin):
Arguments:
jid -- The JID to query for commands.
local -- If true, then the query is for a JID/node
- combination handled by this Sleek instance and
+ combination handled by this Slixmpp instance and
no stanzas need to be sent.
Otherwise, a disco stanza must be sent to the
remove JID to retrieve the items.
ifrom -- Specifiy the sender's JID.
- block -- If true, block and wait for the stanzas' reply.
timeout -- The time in seconds to block while waiting for
a reply. If None, then wait indefinitely.
callback -- Optional callback to execute when a reply is
@@ -496,13 +486,10 @@ class XEP_0050(BasePlugin):
command workflow methods contained in the
session instead of returning the response
stanza itself. Defaults to False.
- block -- Specify if the send call will block until a
- response is received, or a timeout occurs.
- Defaults to True.
timeout -- The length of time (in seconds) to wait for a
response before exiting the send call
if blocking is used. Defaults to
- sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler
function. Will be executed when a reply
stanza is received if flow=False.
@@ -523,22 +510,12 @@ class XEP_0050(BasePlugin):
if not flow:
return iq.send(**kwargs)
else:
- if kwargs.get('block', True):
- try:
- result = iq.send(**kwargs)
- except IqError as err:
- result = err.iq
- self._handle_command_result(result)
- else:
- iq.send(block=False, callback=self._handle_command_result)
+ iq.send(callback=self._handle_command_result)
- def start_command(self, jid, node, session, ifrom=None, block=False):
+ def start_command(self, jid, node, session, ifrom=None):
"""
Initiate executing a command provided by a remote agent.
- The default workflow provided is non-blocking, but a blocking
- version may be used with block=True.
-
The provided session dictionary should contain:
next -- A handler for processing the command result.
error -- A handler for processing any error stanzas
@@ -549,13 +526,10 @@ class XEP_0050(BasePlugin):
node -- The node for the desired command.
session -- A dictionary of relevant session data.
ifrom -- Optionally specify the sender's JID.
- block -- If True, block execution until a result
- is received. Defaults to False.
"""
session['jid'] = jid
session['node'] = node
session['timestamp'] = time.time()
- session['block'] = block
if 'payload' not in session:
session['payload'] = None
@@ -575,14 +549,7 @@ class XEP_0050(BasePlugin):
sessionid = 'client:pending_' + iq['id']
session['id'] = sessionid
self.sessions[sessionid] = session
- if session['block']:
- try:
- result = iq.send(block=True)
- except IqError as err:
- result = err.iq
- self._handle_command_result(result)
- else:
- iq.send(block=False, callback=self._handle_command_result)
+ iq.send(callback=self._handle_command_result)
def continue_command(self, session, direction='next'):
"""
@@ -601,8 +568,7 @@ class XEP_0050(BasePlugin):
action=direction,
payload=session.get('payload', None),
sessionid=session['id'],
- flow=True,
- block=session['block'])
+ flow=True)
def cancel_command(self, session):
"""
@@ -621,8 +587,7 @@ class XEP_0050(BasePlugin):
action='cancel',
payload=session.get('payload', None),
sessionid=session['id'],
- flow=True,
- block=session['block'])
+ flow=True)
def complete_command(self, session):
"""
@@ -641,8 +606,7 @@ class XEP_0050(BasePlugin):
action='complete',
payload=session.get('payload', None),
sessionid=session['id'],
- flow=True,
- block=session['block'])
+ flow=True)
def terminate_command(self, session):
"""
diff --git a/sleekxmpp/plugins/xep_0050/stanza.py b/slixmpp/plugins/xep_0050/stanza.py
index 2367c77b..9bae7d15 100644
--- a/sleekxmpp/plugins/xep_0050/stanza.py
+++ b/slixmpp/plugins/xep_0050/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class Command(ElementBase):
diff --git a/slixmpp/plugins/xep_0054/__init__.py b/slixmpp/plugins/xep_0054/__init__.py
new file mode 100644
index 00000000..2029b41f
--- /dev/null
+++ b/slixmpp/plugins/xep_0054/__init__.py
@@ -0,0 +1,15 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0054.stanza import VCardTemp
+from slixmpp.plugins.xep_0054.vcard_temp import XEP_0054
+
+
+register_plugin(XEP_0054)
diff --git a/sleekxmpp/plugins/xep_0054/stanza.py b/slixmpp/plugins/xep_0054/stanza.py
index 2d017d6e..48a41432 100644
--- a/sleekxmpp/plugins/xep_0054/stanza.py
+++ b/slixmpp/plugins/xep_0054/stanza.py
@@ -1,9 +1,9 @@
import base64
import datetime as dt
-from sleekxmpp.util import bytes
-from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin, JID
-from sleekxmpp.plugins import xep_0082
+from slixmpp.util import bytes
+from slixmpp.xmlstream import ElementBase, ET, register_stanza_plugin, JID
+from slixmpp.plugins import xep_0082
class VCardTemp(ElementBase):
@@ -325,7 +325,10 @@ class Birthday(ElementBase):
def get_bday(self):
if not self.xml.text:
return None
- return xep_0082.parse(self.xml.text)
+ try:
+ return xep_0082.parse(self.xml.text)
+ except ValueError:
+ return self.xml.text
class Rev(ElementBase):
@@ -344,7 +347,10 @@ class Rev(ElementBase):
def get_rev(self):
if not self.xml.text:
return None
- return xep_0082.parse(self.xml.text)
+ try:
+ return xep_0082.parse(self.xml.text)
+ except ValueError:
+ return self.xml.text
class Title(ElementBase):
@@ -524,8 +530,11 @@ class TimeZone(ElementBase):
def get_tz(self):
if not self.xml.text:
return xep_0082.tzutc()
- time = xep_0082.parse('00:00:00%s' % self.xml.text)
- return time.tzinfo
+ try:
+ time = xep_0082.parse('00:00:00%s' % self.xml.text)
+ return time.tzinfo
+ except ValueError:
+ return self.xml.text
register_stanza_plugin(VCardTemp, Name)
diff --git a/sleekxmpp/plugins/xep_0054/vcard_temp.py b/slixmpp/plugins/xep_0054/vcard_temp.py
index 97da8c7c..f0173386 100644
--- a/sleekxmpp/plugins/xep_0054/vcard_temp.py
+++ b/slixmpp/plugins/xep_0054/vcard_temp.py
@@ -1,20 +1,21 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp import JID, Iq
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0054 import VCardTemp, stanza
+from slixmpp import JID, Iq
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0054 import VCardTemp, stanza
+from slixmpp import future_wrapper
log = logging.getLogger(__name__)
@@ -59,8 +60,9 @@ class XEP_0054(BasePlugin):
def make_vcard(self):
return VCardTemp()
+ @future_wrapper
def get_vcard(self, jid=None, ifrom=None, local=None, cached=False,
- block=True, callback=None, timeout=None):
+ callback=None, timeout=None, timeout_callback=None):
if local is None:
if jid is not None and not isinstance(jid, JID):
jid = JID(jid)
@@ -99,14 +101,12 @@ class XEP_0054(BasePlugin):
iq['type'] = 'get'
iq.enable('vcard_temp')
- vcard = iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout,
+ timeout_callback=timeout_callback)
- if block:
- self.api['set_vcard'](vcard['from'], args=vcard['vcard_temp'])
- return vcard
-
- def publish_vcard(self, vcard=None, jid=None, block=True, ifrom=None,
- callback=None, timeout=None):
+ @future_wrapper
+ def publish_vcard(self, vcard=None, jid=None, ifrom=None,
+ callback=None, timeout=None, timeout_callback=None):
self.api['set_vcard'](jid, None, ifrom, vcard)
if self.xmpp.is_component:
return
@@ -116,7 +116,8 @@ class XEP_0054(BasePlugin):
iq['from'] = ifrom
iq['type'] = 'set'
iq.append(vcard)
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout,
+ timeout_callback=timeout_callback)
def _handle_get_vcard(self, iq):
if iq['type'] == 'result':
@@ -127,7 +128,7 @@ class XEP_0054(BasePlugin):
if isinstance(vcard, Iq):
vcard.send()
else:
- iq.reply()
+ iq = iq.reply()
iq.append(vcard)
iq.send()
elif iq['type'] == 'set':
diff --git a/slixmpp/plugins/xep_0059/__init__.py b/slixmpp/plugins/xep_0059/__init__.py
new file mode 100644
index 00000000..21a0e5c9
--- /dev/null
+++ b/slixmpp/plugins/xep_0059/__init__.py
@@ -0,0 +1,18 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz, Erik Reuterborg Larsson
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0059.stanza import Set
+from slixmpp.plugins.xep_0059.rsm import ResultIterator, XEP_0059
+
+
+register_plugin(XEP_0059)
+
+# Retain some backwards compatibility
+xep_0059 = XEP_0059
diff --git a/sleekxmpp/plugins/xep_0059/rsm.py b/slixmpp/plugins/xep_0059/rsm.py
index d73b45bc..5876a9aa 100644
--- a/sleekxmpp/plugins/xep_0059/rsm.py
+++ b/slixmpp/plugins/xep_0059/rsm.py
@@ -1,19 +1,19 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Erik Reuterborg Larsson
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-import sleekxmpp
-from sleekxmpp import Iq
-from sleekxmpp.plugins import BasePlugin, register_plugin
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0059 import stanza, Set
-from sleekxmpp.exceptions import XMPPError
+import slixmpp
+from slixmpp import Iq
+from slixmpp.plugins import BasePlugin, register_plugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.xep_0059 import stanza, Set
+from slixmpp.exceptions import XMPPError
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/plugins/xep_0059/stanza.py b/slixmpp/plugins/xep_0059/stanza.py
index 48f5c8a0..e2701af4 100644
--- a/sleekxmpp/plugins/xep_0059/stanza.py
+++ b/slixmpp/plugins/xep_0059/stanza.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Erik Reuterborg Larsson
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
-from sleekxmpp.plugins.xep_0030.stanza.items import DiscoItems
+from slixmpp.xmlstream import ElementBase, ET
+from slixmpp.plugins.xep_0030.stanza.items import DiscoItems
class Set(ElementBase):
diff --git a/slixmpp/plugins/xep_0060/__init__.py b/slixmpp/plugins/xep_0060/__init__.py
new file mode 100644
index 00000000..6c4d8428
--- /dev/null
+++ b/slixmpp/plugins/xep_0060/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0060.pubsub import XEP_0060
+from slixmpp.plugins.xep_0060 import stanza
+
+
+register_plugin(XEP_0060)
+
+
+# Retain some backwards compatibility
+xep_0060 = XEP_0060
diff --git a/sleekxmpp/plugins/xep_0060/pubsub.py b/slixmpp/plugins/xep_0060/pubsub.py
index bec5f565..8e12ae92 100644
--- a/sleekxmpp/plugins/xep_0060/pubsub.py
+++ b/slixmpp/plugins/xep_0060/pubsub.py
@@ -1,18 +1,18 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.xmlstream import JID
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.plugins.xep_0060 import stanza
+from slixmpp.xmlstream import JID
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.plugins.xep_0060 import stanza
log = logging.getLogger(__name__)
@@ -152,7 +152,7 @@ class XEP_0060(BasePlugin):
self.node_event_map[node] = event_name
def create_node(self, jid, node, config=None, ntype=None, ifrom=None,
- block=True, callback=None, timeout=None):
+ timeout_callback=None, callback=None, timeout=None):
"""
Create and configure a new pubsub node.
@@ -174,11 +174,9 @@ class XEP_0060(BasePlugin):
ntype -- The type of node to create. Servers typically default
to using 'leaf' if no type is provided.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -200,10 +198,11 @@ class XEP_0060(BasePlugin):
config.add_field(var='pubsub#node_type', value=ntype)
iq['pubsub']['configure'].append(config)
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
def subscribe(self, jid, node, bare=True, subscribee=None, options=None,
- ifrom=None, block=True, callback=None, timeout=None):
+ ifrom=None, timeout_callback=None, callback=None,
+ timeout=None):
"""
Subscribe to updates from a pubsub node.
@@ -220,12 +219,10 @@ class XEP_0060(BasePlugin):
subscribee -- The JID that is subscribing to the node.
options --
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a
response before exiting the send call if blocking
is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -247,10 +244,11 @@ class XEP_0060(BasePlugin):
iq['pubsub']['subscribe']['jid'] = subscribee
if options is not None:
iq['pubsub']['options'].append(options)
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
def unsubscribe(self, jid, node, subid=None, bare=True, subscribee=None,
- ifrom=None, block=True, callback=None, timeout=None):
+ ifrom=None, timeout_callback=None, callback=None,
+ timeout=None):
"""
Unubscribe from updates from a pubsub node.
@@ -262,19 +260,17 @@ class XEP_0060(BasePlugin):
Arguments:
jid -- The pubsub service JID.
- node -- The node to subscribe to.
+ node -- The node to unsubscribe from.
subid -- The specific subscription, if multiple subscriptions
exist for this JID/node combination.
bare -- Indicates if the subscribee is a bare or full JID.
Defaults to True for a bare JID.
- subscribee -- The JID that is subscribing to the node.
+ subscribee -- The JID that is unsubscribing from the node.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a
response before exiting the send call if blocking
is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -295,42 +291,43 @@ class XEP_0060(BasePlugin):
iq['pubsub']['unsubscribe']['jid'] = subscribee
iq['pubsub']['unsubscribe']['subid'] = subid
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
- def get_subscriptions(self, jid, node=None, ifrom=None, block=True,
- callback=None, timeout=None):
+ def get_subscriptions(self, jid, node=None, ifrom=None,
+ timeout_callback=None, callback=None,
+ timeout=None):
iq = self.xmpp.Iq(sto=jid, sfrom=ifrom, stype='get')
iq['pubsub']['subscriptions']['node'] = node
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
- def get_affiliations(self, jid, node=None, ifrom=None, block=True,
- callback=None, timeout=None):
+ def get_affiliations(self, jid, node=None, ifrom=None,
+ timeout_callback=None, callback=None, timeout=None):
iq = self.xmpp.Iq(sto=jid, sfrom=ifrom, stype='get')
iq['pubsub']['affiliations']['node'] = node
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
def get_subscription_options(self, jid, node=None, user_jid=None,
- ifrom=None, block=True, callback=None,
- timeout=None):
+ ifrom=None, timeout_callback=None,
+ callback=None, timeout=None):
iq = self.xmpp.Iq(sto=jid, sfrom=ifrom, stype='get')
if user_jid is None:
iq['pubsub']['default']['node'] = node
else:
iq['pubsub']['options']['node'] = node
iq['pubsub']['options']['jid'] = user_jid
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
def set_subscription_options(self, jid, node, user_jid, options,
- ifrom=None, block=True, callback=None,
- timeout=None):
+ ifrom=None, timeout_callback=None,
+ callback=None, timeout=None):
iq = self.xmpp.Iq(sto=jid, sfrom=ifrom, stype='get')
iq['pubsub']['options']['node'] = node
iq['pubsub']['options']['jid'] = user_jid
iq['pubsub']['options'].append(options)
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
- def get_node_config(self, jid, node=None, ifrom=None, block=True,
- callback=None, timeout=None):
+ def get_node_config(self, jid, node=None, ifrom=None,
+ timeout_callback=None, callback=None, timeout=None):
"""
Retrieve the configuration for a node, or the pubsub service's
default configuration for new nodes.
@@ -341,11 +338,9 @@ class XEP_0060(BasePlugin):
the default configuration for new nodes will be
requested. Defaults to None.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -354,10 +349,11 @@ class XEP_0060(BasePlugin):
iq['pubsub_owner']['default']
else:
iq['pubsub_owner']['configure']['node'] = node
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
- def get_node_subscriptions(self, jid, node, ifrom=None, block=True,
- callback=None, timeout=None):
+ def get_node_subscriptions(self, jid, node, ifrom=None,
+ timeout_callback=None, callback=None,
+ timeout=None):
"""
Retrieve the subscriptions associated with a given node.
@@ -365,19 +361,17 @@ class XEP_0060(BasePlugin):
jid -- The JID of the pubsub service.
node -- The node to retrieve subscriptions from.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
iq = self.xmpp.Iq(sto=jid, sfrom=ifrom, stype='get')
iq['pubsub_owner']['subscriptions']['node'] = node
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
- def get_node_affiliations(self, jid, node, ifrom=None, block=True,
+ def get_node_affiliations(self, jid, node, ifrom=None, timeout_callback=None,
callback=None, timeout=None):
"""
Retrieve the affiliations associated with a given node.
@@ -386,20 +380,18 @@ class XEP_0060(BasePlugin):
jid -- The JID of the pubsub service.
node -- The node to retrieve affiliations from.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
iq = self.xmpp.Iq(sto=jid, sfrom=ifrom, stype='get')
iq['pubsub_owner']['affiliations']['node'] = node
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
- def delete_node(self, jid, node, ifrom=None, block=True,
- callback=None, timeout=None):
+ def delete_node(self, jid, node, ifrom=None, timeout_callback=None, callback=None,
+ timeout=None):
"""
Delete a a pubsub node.
@@ -407,27 +399,26 @@ class XEP_0060(BasePlugin):
jid -- The JID of the pubsub service.
node -- The node to delete.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
iq = self.xmpp.Iq(sto=jid, sfrom=ifrom, stype='set')
iq['pubsub_owner']['delete']['node'] = node
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
- def set_node_config(self, jid, node, config, ifrom=None, block=True,
- callback=None, timeout=None):
+ def set_node_config(self, jid, node, config, ifrom=None,
+ timeout_callback=None, callback=None, timeout=None):
iq = self.xmpp.Iq(sto=jid, sfrom=ifrom, stype='set')
iq['pubsub_owner']['configure']['node'] = node
iq['pubsub_owner']['configure'].append(config)
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
def publish(self, jid, node, id=None, payload=None, options=None,
- ifrom=None, block=True, callback=None, timeout=None):
+ ifrom=None, timeout_callback=None, callback=None,
+ timeout=None):
"""
Add a new item to a node, or edit an existing item.
@@ -449,11 +440,9 @@ class XEP_0060(BasePlugin):
payload -- The item content to publish.
options -- A form of publish options.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -464,10 +453,10 @@ class XEP_0060(BasePlugin):
if payload is not None:
iq['pubsub']['publish']['item']['payload'] = payload
iq['pubsub']['publish_options'] = options
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
- def retract(self, jid, node, id, notify=None, ifrom=None, block=True,
- callback=None, timeout=None):
+ def retract(self, jid, node, id, notify=None, ifrom=None,
+ timeout_callback=None, callback=None, timeout=None):
"""
Delete a single item from a node.
"""
@@ -476,16 +465,16 @@ class XEP_0060(BasePlugin):
iq['pubsub']['retract']['node'] = node
iq['pubsub']['retract']['notify'] = notify
iq['pubsub']['retract']['item']['id'] = id
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
- def purge(self, jid, node, ifrom=None, block=True, callback=None,
+ def purge(self, jid, node, ifrom=None, timeout_callback=None, callback=None,
timeout=None):
"""
Remove all items from a node.
"""
iq = self.xmpp.Iq(sto=jid, sfrom=ifrom, stype='set')
iq['pubsub_owner']['purge']['node'] = node
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
def get_nodes(self, *args, **kwargs):
"""
@@ -493,8 +482,8 @@ class XEP_0060(BasePlugin):
"""
return self.xmpp['xep_0030'].get_items(*args, **kwargs)
- def get_item(self, jid, node, item_id, ifrom=None, block=True,
- callback=None, timeout=None):
+ def get_item(self, jid, node, item_id, ifrom=None,
+ timeout_callback=None, callback=None, timeout=None):
"""
Retrieve the content of an individual item.
"""
@@ -503,10 +492,10 @@ class XEP_0060(BasePlugin):
item['id'] = item_id
iq['pubsub']['items']['node'] = node
iq['pubsub']['items'].append(item)
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
def get_items(self, jid, node, item_ids=None, max_items=None,
- iterator=False, ifrom=None, block=False,
+ iterator=False, ifrom=None, timeout_callback=None,
callback=None, timeout=None):
"""
Request the contents of a node's items.
@@ -530,22 +519,21 @@ class XEP_0060(BasePlugin):
if iterator:
return self.xmpp['xep_0059'].iterate(iq, 'pubsub')
else:
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
- def get_item_ids(self, jid, node, ifrom=None, block=True,
- callback=None, timeout=None, iterator=False):
+ def get_item_ids(self, jid, node, ifrom=None, timeout_callback=None, callback=None,
+ timeout=None, iterator=False):
"""
Retrieve the ItemIDs hosted by a given node, using disco.
"""
- return self.xmpp['xep_0030'].get_items(jid, node,
- ifrom=ifrom,
- block=block,
- callback=callback,
- timeout=timeout,
- iterator=iterator)
+ self.xmpp['xep_0030'].get_items(jid, node, ifrom=ifrom,
+ callback=callback, timeout=timeout,
+ iterator=iterator,
+ timeout_callback=timeout_callback)
def modify_affiliations(self, jid, node, affiliations=None, ifrom=None,
- block=True, callback=None, timeout=None):
+ timeout_callback=None, callback=None,
+ timeout=None):
iq = self.xmpp.Iq(sto=jid, sfrom=ifrom, stype='set')
iq['pubsub_owner']['affiliations']['node'] = node
@@ -558,10 +546,11 @@ class XEP_0060(BasePlugin):
aff['affiliation'] = affiliation
iq['pubsub_owner']['affiliations'].append(aff)
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
- def modify_subscriptions(self, jid, node, subscriptions=None, ifrom=None,
- block=True, callback=None, timeout=None):
+ def modify_subscriptions(self, jid, node, subscriptions=None,
+ ifrom=None, timeout_callback=None,
+ callback=None, timeout=None):
iq = self.xmpp.Iq(sto=jid, sfrom=ifrom, stype='set')
iq['pubsub_owner']['subscriptions']['node'] = node
@@ -574,4 +563,4 @@ class XEP_0060(BasePlugin):
sub['subscription'] = subscription
iq['pubsub_owner']['subscriptions'].append(sub)
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout, timeout_callback=timeout_callback)
diff --git a/slixmpp/plugins/xep_0060/stanza/__init__.py b/slixmpp/plugins/xep_0060/stanza/__init__.py
new file mode 100644
index 00000000..31c4ac68
--- /dev/null
+++ b/slixmpp/plugins/xep_0060/stanza/__init__.py
@@ -0,0 +1,12 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.xep_0060.stanza.pubsub import *
+from slixmpp.plugins.xep_0060.stanza.pubsub_owner import *
+from slixmpp.plugins.xep_0060.stanza.pubsub_event import *
+from slixmpp.plugins.xep_0060.stanza.pubsub_errors import *
diff --git a/sleekxmpp/plugins/xep_0060/stanza/base.py b/slixmpp/plugins/xep_0060/stanza/base.py
index d0b7851e..b8f3d6cc 100644
--- a/sleekxmpp/plugins/xep_0060/stanza/base.py
+++ b/slixmpp/plugins/xep_0060/stanza/base.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ET
+from slixmpp.xmlstream import ET
class OptionalSetting(object):
diff --git a/sleekxmpp/plugins/xep_0060/stanza/pubsub.py b/slixmpp/plugins/xep_0060/stanza/pubsub.py
index c1907a13..b4293918 100644
--- a/sleekxmpp/plugins/xep_0060/stanza/pubsub.py
+++ b/slixmpp/plugins/xep_0060/stanza/pubsub.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp import Iq, Message
-from sleekxmpp.xmlstream import register_stanza_plugin, ElementBase, ET, JID
-from sleekxmpp.plugins import xep_0004
-from sleekxmpp.plugins.xep_0060.stanza.base import OptionalSetting
+from slixmpp import Iq, Message
+from slixmpp.xmlstream import register_stanza_plugin, ElementBase, ET, JID
+from slixmpp.plugins import xep_0004
+from slixmpp.plugins.xep_0060.stanza.base import OptionalSetting
class Pubsub(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0060/stanza/pubsub_errors.py b/slixmpp/plugins/xep_0060/stanza/pubsub_errors.py
index 59cf1a50..3e728009 100644
--- a/sleekxmpp/plugins/xep_0060/stanza/pubsub_errors.py
+++ b/slixmpp/plugins/xep_0060/stanza/pubsub_errors.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza import Error
-from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin
+from slixmpp.stanza import Error
+from slixmpp.xmlstream import ElementBase, ET, register_stanza_plugin
class PubsubErrorCondition(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0060/stanza/pubsub_event.py b/slixmpp/plugins/xep_0060/stanza/pubsub_event.py
index 32f217fa..1ba97c75 100644
--- a/sleekxmpp/plugins/xep_0060/stanza/pubsub_event.py
+++ b/slixmpp/plugins/xep_0060/stanza/pubsub_event.py
@@ -1,17 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import datetime as dt
-from sleekxmpp import Message
-from sleekxmpp.xmlstream import register_stanza_plugin, ElementBase, ET, JID
-from sleekxmpp.plugins.xep_0004 import Form
-from sleekxmpp.plugins import xep_0082
+from slixmpp import Message
+from slixmpp.xmlstream import register_stanza_plugin, ElementBase, ET, JID
+from slixmpp.plugins.xep_0004 import Form
+from slixmpp.plugins import xep_0082
class Event(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0060/stanza/pubsub_owner.py b/slixmpp/plugins/xep_0060/stanza/pubsub_owner.py
index d975a46d..402e5e30 100644
--- a/sleekxmpp/plugins/xep_0060/stanza/pubsub_owner.py
+++ b/slixmpp/plugins/xep_0060/stanza/pubsub_owner.py
@@ -1,17 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp import Iq
-from sleekxmpp.xmlstream import register_stanza_plugin, ElementBase, ET, JID
-from sleekxmpp.plugins.xep_0004 import Form
-from sleekxmpp.plugins.xep_0060.stanza.base import OptionalSetting
-from sleekxmpp.plugins.xep_0060.stanza.pubsub import Affiliations, Affiliation
-from sleekxmpp.plugins.xep_0060.stanza.pubsub import Configure, Subscriptions
+from slixmpp import Iq
+from slixmpp.xmlstream import register_stanza_plugin, ElementBase, ET, JID
+from slixmpp.plugins.xep_0004 import Form
+from slixmpp.plugins.xep_0060.stanza.base import OptionalSetting
+from slixmpp.plugins.xep_0060.stanza.pubsub import Affiliations, Affiliation
+from slixmpp.plugins.xep_0060.stanza.pubsub import Configure, Subscriptions
class PubsubOwner(ElementBase):
diff --git a/slixmpp/plugins/xep_0065/__init__.py b/slixmpp/plugins/xep_0065/__init__.py
new file mode 100644
index 00000000..c392bd23
--- /dev/null
+++ b/slixmpp/plugins/xep_0065/__init__.py
@@ -0,0 +1,8 @@
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0065.socks5 import Socks5Protocol
+from slixmpp.plugins.xep_0065.stanza import Socks5
+from slixmpp.plugins.xep_0065.proxy import XEP_0065
+
+
+register_plugin(XEP_0065)
diff --git a/sleekxmpp/plugins/xep_0065/proxy.py b/slixmpp/plugins/xep_0065/proxy.py
index d890b57a..c5d358dd 100644
--- a/sleekxmpp/plugins/xep_0065/proxy.py
+++ b/slixmpp/plugins/xep_0065/proxy.py
@@ -1,29 +1,27 @@
+import asyncio
import logging
-import threading
import socket
from hashlib import sha1
from uuid import uuid4
-from sleekxmpp.thirdparty.socks import socksocket, PROXY_TYPE_SOCKS5
+from slixmpp.stanza import Iq
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins.base import BasePlugin
-from sleekxmpp.stanza import Iq
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins.base import base_plugin
-
-from sleekxmpp.plugins.xep_0065 import stanza, Socks5
+from slixmpp.plugins.xep_0065 import stanza, Socks5, Socks5Protocol
log = logging.getLogger(__name__)
-class XEP_0065(base_plugin):
+class XEP_0065(BasePlugin):
name = 'xep_0065'
- description = "Socks5 Bytestreams"
+ description = "XEP-0065: SOCKS5 Bytestreams"
dependencies = set(['xep_0030'])
default_config = {
'auto_accept': False
@@ -34,9 +32,6 @@ class XEP_0065(base_plugin):
self._proxies = {}
self._sessions = {}
- self._sessions_lock = threading.Lock()
-
- self._preauthed_sids_lock = threading.Lock()
self._preauthed_sids = {}
self.xmpp.register_handler(
@@ -65,34 +60,34 @@ class XEP_0065(base_plugin):
connection.
"""
if not self._proxies:
- self._proxies = self.discover_proxies()
+ self._proxies = yield from self.discover_proxies()
if sid is None:
sid = uuid4().hex
- used = self.request_stream(to, sid=sid, ifrom=ifrom, timeout=timeout)
+ used = yield from self.request_stream(to, sid=sid, ifrom=ifrom, timeout=timeout)
proxy = used['socks']['streamhost_used']['jid']
if proxy not in self._proxies:
log.warning('Received unknown SOCKS5 proxy: %s', proxy)
return
- with self._sessions_lock:
- self._sessions[sid] = self._connect_proxy(
- sid,
- self.xmpp.boundjid,
- to,
+ try:
+ self._sessions[sid] = (yield from self._connect_proxy(
+ self._get_dest_sha1(sid, self.xmpp.boundjid, to),
self._proxies[proxy][0],
- self._proxies[proxy][1],
- peer=to)
+ self._proxies[proxy][1]))[1]
+ except socket.error:
+ return None
+ addr, port = yield from self._sessions[sid].connected
# Request that the proxy activate the session with the target.
- self.activate(proxy, sid, to, timeout=timeout)
- socket = self.get_socket(sid)
- self.xmpp.event('stream:%s:%s' % (sid, to), socket)
- return socket
+ yield from self.activate(proxy, sid, to, timeout=timeout)
+ sock = self.get_socket(sid)
+ self.xmpp.event('stream:%s:%s' % (sid, to), sock)
+ return sock
- def request_stream(self, to, sid=None, ifrom=None, block=True, timeout=None, callback=None):
+ def request_stream(self, to, sid=None, ifrom=None, timeout=None, callback=None):
if sid is None:
sid = uuid4().hex
@@ -107,7 +102,7 @@ class XEP_0065(base_plugin):
iq['socks']['sid'] = sid
for proxy, (host, port) in self._proxies.items():
iq['socks'].add_streamhost(proxy, host, port)
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback)
def discover_proxies(self, jid=None, ifrom=None, timeout=None):
"""Auto-discover the JIDs of SOCKS5 proxies on an XMPP server."""
@@ -119,11 +114,16 @@ class XEP_0065(base_plugin):
discovered = set()
- disco_items = self.xmpp['xep_0030'].get_items(jid, timeout=timeout)
+ disco_items = yield from self.xmpp['xep_0030'].get_items(jid, timeout=timeout)
+ disco_items = {item[0] for item in disco_items['disco_items']['items']}
+
+ disco_info_futures = {}
+ for item in disco_items:
+ disco_info_futures[item] = self.xmpp['xep_0030'].get_info(item, timeout=timeout)
- for item in disco_items['disco_items']['items']:
+ for item in disco_items:
try:
- disco_info = self.xmpp['xep_0030'].get_info(item[0], timeout=timeout)
+ disco_info = yield from disco_info_futures[item]
except XMPPError:
continue
else:
@@ -135,7 +135,7 @@ class XEP_0065(base_plugin):
for jid in discovered:
try:
- addr = self.get_network_address(jid, ifrom=ifrom, timeout=timeout)
+ addr = yield from self.get_network_address(jid, ifrom=ifrom, timeout=timeout)
self._proxies[jid] = (addr['socks']['streamhost']['host'],
addr['socks']['streamhost']['port'])
except XMPPError:
@@ -143,11 +143,20 @@ class XEP_0065(base_plugin):
return self._proxies
- def get_network_address(self, proxy, ifrom=None, block=True, timeout=None, callback=None):
+ def get_network_address(self, proxy, ifrom=None, timeout=None, callback=None):
"""Get the network information of a proxy."""
iq = self.xmpp.Iq(sto=proxy, stype='get', sfrom=ifrom)
iq.enable('socks')
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback)
+
+ def _get_dest_sha1(self, sid, requester, target):
+ # The hostname MUST be SHA1(SID + Requester JID + Target JID)
+ # where the output is hexadecimal-encoded (not binary).
+ digest = sha1()
+ digest.update(sid.encode('utf8'))
+ digest.update(str(requester).encode('utf8'))
+ digest.update(str(target).encode('utf8'))
+ return digest.hexdigest()
def _handle_streamhost(self, iq):
"""Handle incoming SOCKS5 session request."""
@@ -159,40 +168,59 @@ class XEP_0065(base_plugin):
raise XMPPError(etype='modify', condition='not-acceptable')
streamhosts = iq['socks']['streamhosts']
- conn = None
- used_streamhost = None
+ requester = iq['from']
+ target = iq['to']
- sender = iq['from']
+ dest = self._get_dest_sha1(sid, requester, target)
+
+ proxy_futures = []
for streamhost in streamhosts:
- try:
- conn = self._connect_proxy(sid,
- sender,
- self.xmpp.boundjid,
+ proxy_futures.append(self._connect_proxy(
+ dest,
streamhost['host'],
- streamhost['port'],
- peer=sender)
+ streamhost['port']))
+
+ @asyncio.coroutine
+ def gather(futures, iq, streamhosts):
+ proxies = yield from asyncio.gather(*futures, return_exceptions=True)
+ for streamhost, proxy in zip(streamhosts, proxies):
+ if isinstance(proxy, ValueError):
+ continue
+ elif isinstance(proxy, socket.error):
+ log.error('Socket error while connecting to the proxy.')
+ continue
+ proxy = proxy[1]
+ # TODO: what if the future never happens?
+ try:
+ addr, port = yield from proxy.connected
+ except socket.error:
+ log.exception('Socket error while connecting to the proxy.')
+ continue
+ # TODO: make a better choice than just the first working one.
used_streamhost = streamhost['jid']
+ conn = proxy
break
- except socket.error:
- continue
- else:
- raise XMPPError(etype='cancel', condition='item-not-found')
+ else:
+ raise XMPPError(etype='cancel', condition='item-not-found')
+
+ # TODO: close properly the connection to the other proxies.
- iq.reply()
- with self._sessions_lock:
+ iq = iq.reply()
self._sessions[sid] = conn
- iq['socks']['sid'] = sid
- iq['socks']['streamhost_used']['jid'] = used_streamhost
- iq.send()
- self.xmpp.event('socks5_stream', conn)
- self.xmpp.event('stream:%s:%s' % (sid, conn.peer_jid), conn)
+ iq['socks']['sid'] = sid
+ iq['socks']['streamhost_used']['jid'] = used_streamhost
+ iq.send()
+ self.xmpp.event('socks5_stream', conn)
+ self.xmpp.event('stream:%s:%s' % (sid, requester), conn)
+
+ asyncio.async(gather(proxy_futures, iq, streamhosts))
- def activate(self, proxy, sid, target, ifrom=None, block=True, timeout=None, callback=None):
+ def activate(self, proxy, sid, target, ifrom=None, timeout=None, callback=None):
"""Activate the socks5 session that has been negotiated."""
iq = self.xmpp.Iq(sto=proxy, stype='set', sfrom=ifrom)
iq['socks']['sid'] = sid
iq['socks']['activate'] = target
- iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback)
def deactivate(self, sid):
"""Closes the proxy socket associated with this SID."""
@@ -204,66 +232,27 @@ class XEP_0065(base_plugin):
except socket.error:
pass
# Though this should not be neccessary remove the closed session anyway
- with self._sessions_lock:
- if sid in self._sessions:
- log.warn(('SOCKS5 session with sid = "%s" was not ' +
- 'removed from _sessions by sock.close()') % sid)
- del self._sessions[sid]
+ if sid in self._sessions:
+ log.warn(('SOCKS5 session with sid = "%s" was not ' +
+ 'removed from _sessions by sock.close()') % sid)
+ del self._sessions[sid]
def close(self):
"""Closes all proxy sockets."""
for sid, sock in self._sessions.items():
sock.close()
- with self._sessions_lock:
- self._sessions = {}
+ self._sessions = {}
- def _connect_proxy(self, sid, requester, target, proxy, proxy_port, peer=None):
- """ Establishes a connection between the client and the server-side
+ def _connect_proxy(self, dest, proxy, proxy_port):
+ """ Returns a future to a connection between the client and the server-side
Socks5 proxy.
- sid : The StreamID. <str>
- requester : The JID of the requester. <str>
- target : The JID of the target. <str>
- proxy_host : The hostname or the IP of the proxy. <str>
- proxy_port : The port of the proxy. <str> or <int>
- peer : The JID for the other side of the stream, regardless
- of target or requester status.
+ dest : The SHA-1 of (SID + Requester JID + Target JID), in hex. <str>
+ host : The hostname or the IP of the proxy. <str>
+ port : The port of the proxy. <str> or <int>
"""
- # Because the xep_0065 plugin uses the proxy_port as string,
- # the Proxy class accepts the proxy_port argument as a string
- # or an integer. Here, we force to use the port as an integer.
- proxy_port = int(proxy_port)
-
- sock = socksocket()
- sock.setproxy(PROXY_TYPE_SOCKS5, proxy, port=proxy_port)
-
- # The hostname MUST be SHA1(SID + Requester JID + Target JID)
- # where the output is hexadecimal-encoded (not binary).
- digest = sha1()
- digest.update(sid.encode('utf-8'))
- digest.update(str(requester).encode('utf-8'))
- digest.update(str(target).encode('utf-8'))
-
- dest = digest.hexdigest()
-
- # The port MUST be 0.
- sock.connect((dest, 0))
- log.info('Socket connected.')
-
- _close = sock.close
- def close(*args, **kwargs):
- with self._sessions_lock:
- if sid in self._sessions:
- del self._sessions[sid]
- _close()
- log.info('Socket closed.')
- sock.close = close
-
- sock.peer_jid = peer
- sock.self_jid = target if requester == peer else requester
-
- self.xmpp.event('socks_connected', sid)
- return sock
+ factory = lambda: Socks5Protocol(dest, 0, self.xmpp.event)
+ return self.xmpp.loop.create_connection(factory, proxy, proxy_port)
def _accept_stream(self, iq):
receiver = iq['to']
@@ -278,15 +267,13 @@ class XEP_0065(base_plugin):
return self.auto_accept
def _authorized_sid(self, jid, sid, ifrom, iq):
- with self._preauthed_sids_lock:
- log.debug('>>> authed sids: %s', self._preauthed_sids)
- log.debug('>>> lookup: %s %s %s', jid, sid, ifrom)
- if (jid, sid, ifrom) in self._preauthed_sids:
- del self._preauthed_sids[(jid, sid, ifrom)]
- return True
- return False
+ log.debug('>>> authed sids: %s', self._preauthed_sids)
+ log.debug('>>> lookup: %s %s %s', jid, sid, ifrom)
+ if (jid, sid, ifrom) in self._preauthed_sids:
+ del self._preauthed_sids[(jid, sid, ifrom)]
+ return True
+ return False
def _preauthorize_sid(self, jid, sid, ifrom, data):
log.debug('>>>> %s %s %s %s', jid, sid, ifrom, data)
- with self._preauthed_sids_lock:
- self._preauthed_sids[(jid, sid, ifrom)] = True
+ self._preauthed_sids[(jid, sid, ifrom)] = True
diff --git a/slixmpp/plugins/xep_0065/socks5.py b/slixmpp/plugins/xep_0065/socks5.py
new file mode 100644
index 00000000..54267b32
--- /dev/null
+++ b/slixmpp/plugins/xep_0065/socks5.py
@@ -0,0 +1,265 @@
+'''Pure asyncio implementation of RFC 1928 - SOCKS Protocol Version 5.'''
+
+import asyncio
+import enum
+import logging
+import socket
+import struct
+
+from slixmpp.stringprep import punycode, StringprepError
+
+
+log = logging.getLogger(__name__)
+
+
+class ProtocolMismatch(Exception):
+ '''We only implement SOCKS5, no other version or protocol.'''
+
+
+class ProtocolError(Exception):
+ '''Some protocol error.'''
+
+
+class MethodMismatch(Exception):
+ '''The server answered with a method we didn’t ask for.'''
+
+
+class MethodUnacceptable(Exception):
+ '''None of our methods is supported by the server.'''
+
+
+class AddressTypeUnacceptable(Exception):
+ '''The address type (ATYP) field isn’t one of IPv4, IPv6 or domain name.'''
+
+
+class ReplyError(Exception):
+ '''The server answered with an error.'''
+
+ possible_values = (
+ "succeeded",
+ "general SOCKS server failure",
+ "connection not allowed by ruleset",
+ "Network unreachable",
+ "Host unreachable",
+ "Connection refused",
+ "TTL expired",
+ "Command not supported",
+ "Address type not supported",
+ "Unknown error")
+
+ def __init__(self, result):
+ if result < 9:
+ Exception.__init__(self, self.possible_values[result])
+ else:
+ Exception.__init__(self, self.possible_values[9])
+
+
+class Method(enum.IntEnum):
+ '''Known methods for a SOCKS5 session.'''
+ none = 0
+ gssapi = 1
+ password = 2
+ # Methods 3 to 127 are reserved by IANA.
+ # Methods 128 to 254 are reserved for private use.
+ unacceptable = 255
+ not_yet_selected = -1
+
+
+class Command(enum.IntEnum):
+ '''Existing commands for requests.'''
+ connect = 1
+ bind = 2
+ udp_associate = 3
+
+
+class AddressType(enum.IntEnum):
+ '''Existing address types.'''
+ ipv4 = 1
+ domain = 3
+ ipv6 = 4
+
+
+class Socks5Protocol(asyncio.Protocol):
+ '''This implements SOCKS5 as an asyncio protocol.'''
+
+ def __init__(self, dest_addr, dest_port, event):
+ self.methods = {Method.none}
+ self.selected_method = Method.not_yet_selected
+ self.transport = None
+ self.dest = (dest_addr, dest_port)
+ self.connected = asyncio.Future()
+ self.event = event
+ self.paused = asyncio.Future()
+ self.paused.set_result(None)
+
+ def register_method(self, method):
+ '''Register a SOCKS5 method.'''
+ self.methods.add(method)
+
+ def unregister_method(self, method):
+ '''Unregister a SOCKS5 method.'''
+ self.methods.remove(method)
+
+ def connection_made(self, transport):
+ '''Called when the connection to the SOCKS5 server is established.'''
+
+ log.debug('SOCKS5 connection established.')
+
+ self.transport = transport
+ self._send_methods()
+
+ def data_received(self, data):
+ '''Called when we received some data from the SOCKS5 server.'''
+
+ log.debug('SOCKS5 message received.')
+
+ # If we are already connected, this is a data packet.
+ if self.connected.done():
+ return self.event('socks5_data', data)
+
+ # Every SOCKS5 message starts with the protocol version.
+ if data[0] != 5:
+ raise ProtocolMismatch()
+
+ # Then select the correct handler for the data we just received.
+ if self.selected_method == Method.not_yet_selected:
+ self._handle_method(data)
+ else:
+ self._handle_connect(data)
+
+ def connection_lost(self, exc):
+ log.debug('SOCKS5 connection closed.')
+ self.event('socks5_closed', exc)
+
+ def pause_writing(self):
+ self.paused = asyncio.Future()
+
+ def resume_writing(self):
+ self.paused.set_result(None)
+
+ def write(self, data):
+ yield from self.paused
+ self.transport.write(data)
+
+ def _send_methods(self):
+ '''Send the methods request, first thing a client should do.'''
+
+ # Create the buffer for our request.
+ request = bytearray(len(self.methods) + 2)
+
+ # Protocol version.
+ request[0] = 5
+
+ # Number of methods to send.
+ request[1] = len(self.methods)
+
+ # List every method we support.
+ for i, method in enumerate(self.methods):
+ request[i + 2] = method
+
+ # Send the request.
+ self.transport.write(request)
+
+ def _send_request(self, command):
+ '''Send a request, should be done after having negociated a method.'''
+
+ # Encode the destination address to embed it in our request.
+ # We need to do that first because its length is variable.
+ address, port = self.dest
+ addr = self._encode_addr(address)
+
+ # Create the buffer for our request.
+ request = bytearray(5 + len(addr))
+
+ # Protocol version.
+ request[0] = 5
+
+ # Specify the command we want to use.
+ request[1] = command
+
+ # request[2] is reserved, keeping it at 0.
+
+ # Add our destination address and port.
+ request[3:3+len(addr)] = addr
+ request[-2:] = struct.pack('>H', port)
+
+ # Send the request.
+ log.debug('SOCKS5 message sent.')
+ self.transport.write(request)
+
+ def _handle_method(self, data):
+ '''Handle a method reply from the server.'''
+
+ if len(data) != 2:
+ raise ProtocolError()
+ selected_method = data[1]
+ if selected_method not in self.methods:
+ raise MethodMismatch()
+ if selected_method == Method.unacceptable:
+ raise MethodUnacceptable()
+ self.selected_method = selected_method
+ self._send_request(Command.connect)
+
+ def _handle_connect(self, data):
+ '''Handle a connect reply from the server.'''
+
+ try:
+ addr, port = self._parse_result(data)
+ except ReplyError as exception:
+ self.connected.set_exception(exception)
+ self.connected.set_result((addr, port))
+ self.event('socks5_connected', (addr, port))
+
+ def _parse_result(self, data):
+ '''Parse a reply from the server.'''
+
+ result = data[1]
+ if result != 0:
+ raise ReplyError(result)
+ addr = self._parse_addr(data[3:-2])
+ port = struct.unpack('>H', data[-2:])[0]
+ return (addr, port)
+
+ @staticmethod
+ def _parse_addr(addr):
+ '''Parse an address (IP or domain) from a bytestream.'''
+
+ addr_type = addr[0]
+ if addr_type == AddressType.ipv6:
+ try:
+ return socket.inet_ntop(socket.AF_INET6, addr[1:])
+ except ValueError as e:
+ raise AddressTypeUnacceptable(e)
+ if addr_type == AddressType.ipv4:
+ try:
+ return socket.inet_ntop(socket.AF_INET, addr[1:])
+ except ValueError as e:
+ raise AddressTypeUnacceptable(e)
+ if addr_type == AddressType.domain:
+ length = addr[1]
+ address = addr[2:]
+ if length != len(address):
+ raise Exception('Size mismatch')
+ return address.decode()
+ raise AddressTypeUnacceptable(addr_type)
+
+ @staticmethod
+ def _encode_addr(addr):
+ '''Encode an address (IP or domain) into a bytestream.'''
+
+ try:
+ ipv6 = socket.inet_pton(socket.AF_INET6, addr)
+ return b'\x04' + ipv6
+ except OSError:
+ pass
+ try:
+ ipv4 = socket.inet_aton(addr)
+ return b'\x01' + ipv4
+ except OSError:
+ pass
+ try:
+ domain = punycode(addr)
+ return b'\x03' + bytes([len(domain)]) + domain
+ except StringprepError:
+ pass
+ raise Exception('Err…')
diff --git a/sleekxmpp/plugins/xep_0065/stanza.py b/slixmpp/plugins/xep_0065/stanza.py
index e48bf1b5..5ba15b32 100644
--- a/sleekxmpp/plugins/xep_0065/stanza.py
+++ b/slixmpp/plugins/xep_0065/stanza.py
@@ -1,5 +1,5 @@
-from sleekxmpp.jid import JID
-from sleekxmpp.xmlstream import ElementBase, register_stanza_plugin
+from slixmpp.jid import JID
+from slixmpp.xmlstream import ElementBase, register_stanza_plugin
class Socks5(ElementBase):
diff --git a/slixmpp/plugins/xep_0066/__init__.py b/slixmpp/plugins/xep_0066/__init__.py
new file mode 100644
index 00000000..7f7e0ebd
--- /dev/null
+++ b/slixmpp/plugins/xep_0066/__init__.py
@@ -0,0 +1,20 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0066 import stanza
+from slixmpp.plugins.xep_0066.stanza import OOB, OOBTransfer
+from slixmpp.plugins.xep_0066.oob import XEP_0066
+
+
+register_plugin(XEP_0066)
+
+
+# Retain some backwards compatibility
+xep_0066 = XEP_0066
diff --git a/sleekxmpp/plugins/xep_0066/oob.py b/slixmpp/plugins/xep_0066/oob.py
index 959c15a2..c9d4ae5b 100644
--- a/sleekxmpp/plugins/xep_0066/oob.py
+++ b/slixmpp/plugins/xep_0066/oob.py
@@ -1,20 +1,20 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.stanza import Message, Presence, Iq
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0066 import stanza
+from slixmpp.stanza import Message, Presence, Iq
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0066 import stanza
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/plugins/xep_0066/stanza.py b/slixmpp/plugins/xep_0066/stanza.py
index 21387485..e1da5bdd 100644
--- a/sleekxmpp/plugins/xep_0066/stanza.py
+++ b/slixmpp/plugins/xep_0066/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class OOBTransfer(ElementBase):
diff --git a/slixmpp/plugins/xep_0071/__init__.py b/slixmpp/plugins/xep_0071/__init__.py
new file mode 100644
index 00000000..19275c7a
--- /dev/null
+++ b/slixmpp/plugins/xep_0071/__init__.py
@@ -0,0 +1,15 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permissio
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0071.stanza import XHTML_IM
+from slixmpp.plugins.xep_0071.xhtml_im import XEP_0071
+
+
+register_plugin(XEP_0071)
diff --git a/sleekxmpp/plugins/xep_0071/stanza.py b/slixmpp/plugins/xep_0071/stanza.py
index d5ff1a1b..3df686cf 100644
--- a/sleekxmpp/plugins/xep_0071/stanza.py
+++ b/slixmpp/plugins/xep_0071/stanza.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza import Message
-from sleekxmpp.util import unicode
-from sleekxmpp.thirdparty import OrderedDict
-from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin, tostring
+from slixmpp.stanza import Message
+from slixmpp.util import unicode
+from collections import OrderedDict
+from slixmpp.xmlstream import ElementBase, ET, register_stanza_plugin, tostring
XHTML_NS = 'http://www.w3.org/1999/xhtml'
diff --git a/sleekxmpp/plugins/xep_0071/xhtml_im.py b/slixmpp/plugins/xep_0071/xhtml_im.py
index 096a00aa..0b412126 100644
--- a/sleekxmpp/plugins/xep_0071/xhtml_im.py
+++ b/slixmpp/plugins/xep_0071/xhtml_im.py
@@ -1,16 +1,16 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza import Message
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0071 import stanza, XHTML_IM
+from slixmpp.stanza import Message
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.xep_0071 import stanza, XHTML_IM
class XEP_0071(BasePlugin):
diff --git a/slixmpp/plugins/xep_0077/__init__.py b/slixmpp/plugins/xep_0077/__init__.py
new file mode 100644
index 00000000..a73cfae9
--- /dev/null
+++ b/slixmpp/plugins/xep_0077/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0077.stanza import Register, RegisterFeature
+from slixmpp.plugins.xep_0077.register import XEP_0077
+
+
+register_plugin(XEP_0077)
+
+
+# Retain some backwards compatibility
+xep_0077 = XEP_0077
diff --git a/sleekxmpp/plugins/xep_0077/register.py b/slixmpp/plugins/xep_0077/register.py
index ee07548b..eb2e7443 100644
--- a/sleekxmpp/plugins/xep_0077/register.py
+++ b/slixmpp/plugins/xep_0077/register.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,10 +9,10 @@
import logging
import ssl
-from sleekxmpp.stanza import StreamFeatures, Iq
-from sleekxmpp.xmlstream import register_stanza_plugin, JID
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0077 import stanza, Register, RegisterFeature
+from slixmpp.stanza import StreamFeatures, Iq
+from slixmpp.xmlstream import register_stanza_plugin, JID
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0077 import stanza, Register, RegisterFeature
log = logging.getLogger(__name__)
@@ -77,30 +77,29 @@ class XEP_0077(BasePlugin):
if self.create_account and self.xmpp.event_handled('register'):
form = self.get_registration()
- self.xmpp.event('register', form, direct=True)
+ self.xmpp.event('register', form)
return True
return False
- def get_registration(self, jid=None, ifrom=None, block=True,
+ def get_registration(self, jid=None, ifrom=None,
timeout=None, callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'get'
iq['to'] = jid
iq['from'] = ifrom
iq.enable('register')
- return iq.send(block=block, timeout=timeout,
- callback=callback, now=True)
+ return iq.send(timeout=timeout, callback=callback)
- def cancel_registration(self, jid=None, ifrom=None, block=True,
+ def cancel_registration(self, jid=None, ifrom=None,
timeout=None, callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq['to'] = jid
iq['from'] = ifrom
iq['register']['remove'] = True
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback)
- def change_password(self, password, jid=None, ifrom=None, block=True,
+ def change_password(self, password, jid=None, ifrom=None,
timeout=None, callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'set'
@@ -112,4 +111,4 @@ class XEP_0077(BasePlugin):
else:
iq['register']['username'] = self.xmpp.boundjid.user
iq['register']['password'] = password
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback)
diff --git a/sleekxmpp/plugins/xep_0077/stanza.py b/slixmpp/plugins/xep_0077/stanza.py
index e06c1910..6ac543c2 100644
--- a/sleekxmpp/plugins/xep_0077/stanza.py
+++ b/slixmpp/plugins/xep_0077/stanza.py
@@ -1,14 +1,14 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from __future__ import unicode_literals
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class Register(ElementBase):
diff --git a/slixmpp/plugins/xep_0078/__init__.py b/slixmpp/plugins/xep_0078/__init__.py
new file mode 100644
index 00000000..21bdc19e
--- /dev/null
+++ b/slixmpp/plugins/xep_0078/__init__.py
@@ -0,0 +1,20 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0078 import stanza
+from slixmpp.plugins.xep_0078.stanza import IqAuth, AuthFeature
+from slixmpp.plugins.xep_0078.legacyauth import XEP_0078
+
+
+register_plugin(XEP_0078)
+
+
+# Retain some backwards compatibility
+xep_0078 = XEP_0078
diff --git a/sleekxmpp/plugins/xep_0078/legacyauth.py b/slixmpp/plugins/xep_0078/legacyauth.py
index da6bfa2c..d949a913 100644
--- a/sleekxmpp/plugins/xep_0078/legacyauth.py
+++ b/slixmpp/plugins/xep_0078/legacyauth.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,15 +9,13 @@
import uuid
import logging
import hashlib
-import random
-import sys
-from sleekxmpp.jid import JID
-from sleekxmpp.exceptions import IqError, IqTimeout
-from sleekxmpp.stanza import Iq, StreamFeatures
-from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0078 import stanza
+from slixmpp.jid import JID
+from slixmpp.exceptions import IqError, IqTimeout
+from slixmpp.stanza import Iq, StreamFeatures
+from slixmpp.xmlstream import ElementBase, ET, register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0078 import stanza
log = logging.getLogger(__name__)
@@ -79,15 +77,15 @@ class XEP_0078(BasePlugin):
iq['auth']['username'] = self.xmpp.requested_jid.user
try:
- resp = iq.send(now=True)
+ resp = iq.send()
except IqError as err:
log.info("Authentication failed: %s", err.iq['error']['condition'])
- self.xmpp.event('failed_auth', direct=True)
+ self.xmpp.event('failed_auth')
self.xmpp.disconnect()
return True
except IqTimeout:
log.info("Authentication failed: %s", 'timeout')
- self.xmpp.event('failed_auth', direct=True)
+ self.xmpp.event('failed_auth')
self.xmpp.disconnect()
return True
@@ -105,12 +103,8 @@ class XEP_0078(BasePlugin):
if 'digest' in resp['auth']['fields']:
log.debug('Authenticating via jabber:iq:auth Digest')
- if sys.version_info < (3, 0):
- stream_id = bytes(self.xmpp.stream_id)
- password = bytes(self.xmpp.password)
- else:
- stream_id = bytes(self.xmpp.stream_id, encoding='utf-8')
- password = bytes(self.xmpp.password, encoding='utf-8')
+ stream_id = bytes(self.xmpp.stream_id, encoding='utf-8')
+ password = bytes(self.xmpp.password, encoding='utf-8')
digest = hashlib.sha1(b'%s%s' % (stream_id, password)).hexdigest()
iq['auth']['digest'] = digest
@@ -120,28 +114,26 @@ class XEP_0078(BasePlugin):
# Step 3: Send credentials
try:
- result = iq.send(now=True)
+ result = iq.send()
except IqError as err:
log.info("Authentication failed")
- self.xmpp.event("failed_auth", direct=True)
+ self.xmpp.event("failed_auth")
self.xmpp.disconnect()
except IqTimeout:
log.info("Authentication failed")
- self.xmpp.event("failed_auth", direct=True)
+ self.xmpp.event("failed_auth")
self.xmpp.disconnect()
self.xmpp.features.add('auth')
self.xmpp.authenticated = True
- self.xmpp.boundjid = JID(self.xmpp.requested_jid,
- resource=resource,
- cache_lock=True)
- self.xmpp.event('session_bind', self.xmpp.boundjid, direct=True)
+ self.xmpp.boundjid = JID(self.xmpp.requested_jid)
+ self.xmpp.boundjid.resource = resource
+ self.xmpp.event('session_bind', self.xmpp.boundjid)
log.debug("Established Session")
self.xmpp.sessionstarted = True
- self.xmpp.session_started_event.set()
self.xmpp.event('session_start')
return True
diff --git a/sleekxmpp/plugins/xep_0078/stanza.py b/slixmpp/plugins/xep_0078/stanza.py
index c8b26071..7dc9401d 100644
--- a/sleekxmpp/plugins/xep_0078/stanza.py
+++ b/slixmpp/plugins/xep_0078/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin
+from slixmpp.xmlstream import ElementBase, ET, register_stanza_plugin
class IqAuth(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0079/__init__.py b/slixmpp/plugins/xep_0079/__init__.py
index 09e66715..864c9018 100644
--- a/sleekxmpp/plugins/xep_0079/__init__.py
+++ b/slixmpp/plugins/xep_0079/__init__.py
@@ -1,18 +1,18 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins.base import register_plugin
+from slixmpp.plugins.base import register_plugin
-from sleekxmpp.plugins.xep_0079.stanza import (
+from slixmpp.plugins.xep_0079.stanza import (
AMP, Rule, InvalidRules, UnsupportedConditions,
UnsupportedActions, FailedRules, FailedRule,
AMPFeature)
-from sleekxmpp.plugins.xep_0079.amp import XEP_0079
+from slixmpp.plugins.xep_0079.amp import XEP_0079
register_plugin(XEP_0079)
diff --git a/sleekxmpp/plugins/xep_0079/amp.py b/slixmpp/plugins/xep_0079/amp.py
index 918fb841..6e65d02a 100644
--- a/sleekxmpp/plugins/xep_0079/amp.py
+++ b/slixmpp/plugins/xep_0079/amp.py
@@ -1,19 +1,19 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permissio
"""
import logging
-from sleekxmpp.stanza import Message, Error, StreamFeatures
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.matcher import StanzaPath, MatchMany
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0079 import stanza
+from slixmpp.stanza import Message, Error, StreamFeatures
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.matcher import StanzaPath, MatchMany
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0079 import stanza
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/plugins/xep_0079/stanza.py b/slixmpp/plugins/xep_0079/stanza.py
index cb6932d6..e3e1553a 100644
--- a/sleekxmpp/plugins/xep_0079/stanza.py
+++ b/slixmpp/plugins/xep_0079/stanza.py
@@ -1,14 +1,14 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from __future__ import unicode_literals
-from sleekxmpp.xmlstream import ElementBase, register_stanza_plugin
+from slixmpp.xmlstream import ElementBase, register_stanza_plugin
class AMP(ElementBase):
diff --git a/slixmpp/plugins/xep_0080/__init__.py b/slixmpp/plugins/xep_0080/__init__.py
new file mode 100644
index 00000000..c487ef9c
--- /dev/null
+++ b/slixmpp/plugins/xep_0080/__init__.py
@@ -0,0 +1,15 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz, Erik Reuterborg Larsson
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0080.stanza import Geoloc
+from slixmpp.plugins.xep_0080.geoloc import XEP_0080
+
+
+register_plugin(XEP_0080)
diff --git a/sleekxmpp/plugins/xep_0080/geoloc.py b/slixmpp/plugins/xep_0080/geoloc.py
index ba594cce..c9d97edb 100644
--- a/sleekxmpp/plugins/xep_0080/geoloc.py
+++ b/slixmpp/plugins/xep_0080/geoloc.py
@@ -1,17 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Erik Reuterborg Larsson
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-import sleekxmpp
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0080 import stanza, Geoloc
+import slixmpp
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.xep_0080 import stanza, Geoloc
log = logging.getLogger(__name__)
@@ -76,20 +76,18 @@ class XEP_0080(BasePlugin):
options -- Optional form of publish options.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
options = kwargs.get('options', None)
ifrom = kwargs.get('ifrom', None)
- block = kwargs.get('block', None)
callback = kwargs.get('callback', None)
timeout = kwargs.get('timeout', None)
- for param in ('ifrom', 'block', 'callback', 'timeout', 'options'):
+ timeout_callback = kwargs.get('timeout_callback', None)
+ for param in ('ifrom', 'block', 'callback', 'timeout', 'options', 'timeout_callback'):
if param in kwargs:
del kwargs[param]
@@ -99,27 +97,25 @@ class XEP_0080(BasePlugin):
return self.xmpp['xep_0163'].publish(geoloc,
options=options,
ifrom=ifrom,
- block=block,
callback=callback,
- timeout=timeout)
+ timeout=timeout,
+ timeout_callback=timeout_callback)
- def stop(self, ifrom=None, block=True, callback=None, timeout=None):
+ def stop(self, ifrom=None, callback=None, timeout=None, timeout_callback=None):
"""
Clear existing user location information to stop notifications.
Arguments:
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
geoloc = Geoloc()
return self.xmpp['xep_0163'].publish(geoloc,
ifrom=ifrom,
- block=block,
callback=callback,
- timeout=timeout)
+ timeout=timeout,
+ timeout_callback=None)
diff --git a/sleekxmpp/plugins/xep_0080/stanza.py b/slixmpp/plugins/xep_0080/stanza.py
index 8f466516..e25fea4f 100644
--- a/sleekxmpp/plugins/xep_0080/stanza.py
+++ b/slixmpp/plugins/xep_0080/stanza.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
-from sleekxmpp.plugins import xep_0082
+from slixmpp.xmlstream import ElementBase
+from slixmpp.plugins import xep_0082
class Geoloc(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0082.py b/slixmpp/plugins/xep_0082.py
index 26eb68fa..24436622 100644
--- a/sleekxmpp/plugins/xep_0082.py
+++ b/slixmpp/plugins/xep_0082.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import datetime as dt
-from sleekxmpp.plugins import BasePlugin, register_plugin
-from sleekxmpp.thirdparty import tzutc, tzoffset, parse_iso
+from slixmpp.plugins import BasePlugin, register_plugin
+from slixmpp.thirdparty import tzutc, tzoffset, parse_iso
# =====================================================================
diff --git a/slixmpp/plugins/xep_0084/__init__.py b/slixmpp/plugins/xep_0084/__init__.py
new file mode 100644
index 00000000..aa5fdae5
--- /dev/null
+++ b/slixmpp/plugins/xep_0084/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0084 import stanza
+from slixmpp.plugins.xep_0084.stanza import Data, MetaData
+from slixmpp.plugins.xep_0084.avatar import XEP_0084
+
+
+register_plugin(XEP_0084)
diff --git a/sleekxmpp/plugins/xep_0084/avatar.py b/slixmpp/plugins/xep_0084/avatar.py
index 677a888d..e5f9dfaa 100644
--- a/sleekxmpp/plugins/xep_0084/avatar.py
+++ b/slixmpp/plugins/xep_0084/avatar.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,12 +9,12 @@
import hashlib
import logging
-from sleekxmpp import Iq
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin, JID
-from sleekxmpp.plugins.xep_0084 import stanza, Data, MetaData
+from slixmpp import Iq
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin, JID
+from slixmpp.plugins.xep_0084 import stanza, Data, MetaData
log = logging.getLogger(__name__)
@@ -44,28 +44,29 @@ class XEP_0084(BasePlugin):
def generate_id(self, data):
return hashlib.sha1(data).hexdigest()
- def retrieve_avatar(self, jid, id, url=None, ifrom=None, block=True,
- callback=None, timeout=None):
+ def retrieve_avatar(self, jid, id, url=None, ifrom=None,
+ callback=None, timeout=None, timeout_callback=None):
return self.xmpp['xep_0060'].get_item(jid, Data.namespace, id,
ifrom=ifrom,
- block=block,
callback=callback,
- timeout=timeout)
+ timeout=timeout,
+ timeout_callback=timeout_callback)
- def publish_avatar(self, data, ifrom=None, block=True, callback=None,
- timeout=None):
+ def publish_avatar(self, data, ifrom=None, callback=None,
+ timeout=None, timeout_callback=None):
payload = Data()
payload['value'] = data
return self.xmpp['xep_0163'].publish(payload,
id=self.generate_id(data),
ifrom=ifrom,
- block=block,
callback=callback,
- timeout=timeout)
+ timeout=timeout,
+ timeout_callback=timeout_callback)
def publish_avatar_metadata(self, items=None, pointers=None,
- ifrom=None, block=True,
- callback=None, timeout=None):
+ ifrom=None,
+ callback=None, timeout=None,
+ timeout_callback=None):
metadata = MetaData()
if items is None:
items = []
@@ -84,21 +85,19 @@ class XEP_0084(BasePlugin):
return self.xmpp['xep_0163'].publish(metadata,
id=info['id'],
ifrom=ifrom,
- block=block,
callback=callback,
- timeout=timeout)
+ timeout=timeout,
+ timeout_callback=timeout_callback)
- def stop(self, ifrom=None, block=True, callback=None, timeout=None):
+ def stop(self, ifrom=None, callback=None, timeout=None, timeout_callback=None):
"""
Clear existing avatar metadata information to stop notifications.
Arguments:
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -106,6 +105,6 @@ class XEP_0084(BasePlugin):
return self.xmpp['xep_0163'].publish(metadata,
node=MetaData.namespace,
ifrom=ifrom,
- block=block,
callback=callback,
- timeout=timeout)
+ timeout=timeout,
+ timeout_callback=timeout_callback)
diff --git a/sleekxmpp/plugins/xep_0084/stanza.py b/slixmpp/plugins/xep_0084/stanza.py
index fd21e6f1..ebcd73e3 100644
--- a/sleekxmpp/plugins/xep_0084/stanza.py
+++ b/slixmpp/plugins/xep_0084/stanza.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from base64 import b64encode, b64decode
-from sleekxmpp.util import bytes as sbytes
-from sleekxmpp.xmlstream import ET, ElementBase, register_stanza_plugin
+from slixmpp.util import bytes
+from slixmpp.xmlstream import ET, ElementBase, register_stanza_plugin
class Data(ElementBase):
@@ -20,15 +20,12 @@ class Data(ElementBase):
def get_value(self):
if self.xml.text:
- return b64decode(sbytes(self.xml.text))
- return ''
+ return b64decode(bytes(self.xml.text))
+ return b''
def set_value(self, value):
if value:
- self.xml.text = b64encode(sbytes(value))
- # Python3 base64 encoded is bytes and needs to be decoded to string
- if isinstance(self.xml.text, bytes):
- self.xml.text = self.xml.text.decode()
+ self.xml.text = b64encode(bytes(value)).decode()
else:
self.xml.text = ''
diff --git a/slixmpp/plugins/xep_0085/__init__.py b/slixmpp/plugins/xep_0085/__init__.py
new file mode 100644
index 00000000..9b9da990
--- /dev/null
+++ b/slixmpp/plugins/xep_0085/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permissio
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0085.stanza import ChatState
+from slixmpp.plugins.xep_0085.chat_states import XEP_0085
+
+
+register_plugin(XEP_0085)
+
+
+# Retain some backwards compatibility
+xep_0085 = XEP_0085
diff --git a/sleekxmpp/plugins/xep_0085/chat_states.py b/slixmpp/plugins/xep_0085/chat_states.py
index 17f82afd..1aab9eaa 100644
--- a/sleekxmpp/plugins/xep_0085/chat_states.py
+++ b/slixmpp/plugins/xep_0085/chat_states.py
@@ -1,20 +1,20 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permissio
"""
import logging
-import sleekxmpp
-from sleekxmpp.stanza import Message
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin, ElementBase, ET
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0085 import stanza, ChatState
+import slixmpp
+from slixmpp.stanza import Message
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin, ElementBase, ET
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0085 import stanza, ChatState
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/plugins/xep_0085/stanza.py b/slixmpp/plugins/xep_0085/stanza.py
index c2cafb19..d1a5b151 100644
--- a/sleekxmpp/plugins/xep_0085/stanza.py
+++ b/slixmpp/plugins/xep_0085/stanza.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permissio
"""
-import sleekxmpp
-from sleekxmpp.xmlstream import ElementBase, ET
+import slixmpp
+from slixmpp.xmlstream import ElementBase, ET
class ChatState(ElementBase):
diff --git a/slixmpp/plugins/xep_0086/__init__.py b/slixmpp/plugins/xep_0086/__init__.py
new file mode 100644
index 00000000..c6946e5a
--- /dev/null
+++ b/slixmpp/plugins/xep_0086/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0086.stanza import LegacyError
+from slixmpp.plugins.xep_0086.legacy_error import XEP_0086
+
+
+register_plugin(XEP_0086)
+
+
+# Retain some backwards compatibility
+xep_0086 = XEP_0086
diff --git a/sleekxmpp/plugins/xep_0086/legacy_error.py b/slixmpp/plugins/xep_0086/legacy_error.py
index f7d0ac9c..0a6e0e87 100644
--- a/sleekxmpp/plugins/xep_0086/legacy_error.py
+++ b/slixmpp/plugins/xep_0086/legacy_error.py
@@ -1,46 +1,46 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-from sleekxmpp.stanza import Error
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0086 import stanza, LegacyError
-
-
-class XEP_0086(BasePlugin):
-
- """
- XEP-0086: Error Condition Mappings
-
- Older XMPP implementations used code based error messages, similar
- to HTTP response codes. Since then, error condition elements have
- been introduced. XEP-0086 provides a mapping between the new
- condition elements and a combination of error types and the older
- response codes.
-
- Also see <http://xmpp.org/extensions/xep-0086.html>.
-
- Configuration Values:
- override -- Indicates if applying legacy error codes should
- be done automatically. Defaults to True.
- If False, then inserting legacy error codes can
- be done using:
- iq['error']['legacy']['condition'] = ...
- """
-
- name = 'xep_0086'
- description = 'XEP-0086: Error Condition Mappings'
- dependencies = set()
- stanza = stanza
- default_config = {
- 'override': True
- }
-
- def plugin_init(self):
- register_stanza_plugin(Error, LegacyError,
- overrides=self.override)
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.stanza import Error
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0086 import stanza, LegacyError
+
+
+class XEP_0086(BasePlugin):
+
+ """
+ XEP-0086: Error Condition Mappings
+
+ Older XMPP implementations used code based error messages, similar
+ to HTTP response codes. Since then, error condition elements have
+ been introduced. XEP-0086 provides a mapping between the new
+ condition elements and a combination of error types and the older
+ response codes.
+
+ Also see <http://xmpp.org/extensions/xep-0086.html>.
+
+ Configuration Values:
+ override -- Indicates if applying legacy error codes should
+ be done automatically. Defaults to True.
+ If False, then inserting legacy error codes can
+ be done using:
+ iq['error']['legacy']['condition'] = ...
+ """
+
+ name = 'xep_0086'
+ description = 'XEP-0086: Error Condition Mappings'
+ dependencies = set()
+ stanza = stanza
+ default_config = {
+ 'override': True
+ }
+
+ def plugin_init(self):
+ register_stanza_plugin(Error, LegacyError,
+ overrides=self.override)
diff --git a/sleekxmpp/plugins/xep_0086/stanza.py b/slixmpp/plugins/xep_0086/stanza.py
index d4909806..cbc9429d 100644
--- a/sleekxmpp/plugins/xep_0086/stanza.py
+++ b/slixmpp/plugins/xep_0086/stanza.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza import Error
-from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin
+from slixmpp.stanza import Error
+from slixmpp.xmlstream import ElementBase, ET, register_stanza_plugin
class LegacyError(ElementBase):
diff --git a/slixmpp/plugins/xep_0091/__init__.py b/slixmpp/plugins/xep_0091/__init__.py
new file mode 100644
index 00000000..e5d166b1
--- /dev/null
+++ b/slixmpp/plugins/xep_0091/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0091 import stanza
+from slixmpp.plugins.xep_0091.stanza import LegacyDelay
+from slixmpp.plugins.xep_0091.legacy_delay import XEP_0091
+
+
+register_plugin(XEP_0091)
diff --git a/sleekxmpp/plugins/xep_0091/legacy_delay.py b/slixmpp/plugins/xep_0091/legacy_delay.py
index 7323d468..6aef2ba1 100644
--- a/sleekxmpp/plugins/xep_0091/legacy_delay.py
+++ b/slixmpp/plugins/xep_0091/legacy_delay.py
@@ -1,16 +1,16 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza import Message, Presence
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0091 import stanza
+from slixmpp.stanza import Message, Presence
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0091 import stanza
class XEP_0091(BasePlugin):
diff --git a/sleekxmpp/plugins/xep_0091/stanza.py b/slixmpp/plugins/xep_0091/stanza.py
index 17e55764..ac6457e6 100644
--- a/sleekxmpp/plugins/xep_0091/stanza.py
+++ b/slixmpp/plugins/xep_0091/stanza.py
@@ -1,16 +1,16 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import datetime as dt
-from sleekxmpp.jid import JID
-from sleekxmpp.xmlstream import ElementBase
-from sleekxmpp.plugins import xep_0082
+from slixmpp.jid import JID
+from slixmpp.xmlstream import ElementBase
+from slixmpp.plugins import xep_0082
class LegacyDelay(ElementBase):
diff --git a/slixmpp/plugins/xep_0092/__init__.py b/slixmpp/plugins/xep_0092/__init__.py
new file mode 100644
index 00000000..93743a14
--- /dev/null
+++ b/slixmpp/plugins/xep_0092/__init__.py
@@ -0,0 +1,20 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0092 import stanza
+from slixmpp.plugins.xep_0092.stanza import Version
+from slixmpp.plugins.xep_0092.version import XEP_0092
+
+
+register_plugin(XEP_0092)
+
+
+# Retain some backwards compatibility
+xep_0092 = XEP_0092
diff --git a/sleekxmpp/plugins/xep_0092/stanza.py b/slixmpp/plugins/xep_0092/stanza.py
index 77654e37..04097a8b 100644
--- a/sleekxmpp/plugins/xep_0092/stanza.py
+++ b/slixmpp/plugins/xep_0092/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class Version(ElementBase):
@@ -23,7 +23,7 @@ class Version(ElementBase):
<iq type="result">
<query xmlns="jabber:iq:version">
- <name>SleekXMPP</name>
+ <name>Slixmpp</name>
<version>1.0</version>
<os>Linux</os>
</query>
diff --git a/sleekxmpp/plugins/xep_0092/version.py b/slixmpp/plugins/xep_0092/version.py
index b16ad516..ff0317da 100644
--- a/sleekxmpp/plugins/xep_0092/version.py
+++ b/slixmpp/plugins/xep_0092/version.py
@@ -1,20 +1,20 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-import sleekxmpp
-from sleekxmpp import Iq
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0092 import Version, stanza
+import slixmpp
+from slixmpp import Iq
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0092 import Version, stanza
log = logging.getLogger(__name__)
@@ -31,8 +31,8 @@ class XEP_0092(BasePlugin):
dependencies = set(['xep_0030'])
stanza = stanza
default_config = {
- 'software_name': 'SleekXMPP',
- 'version': sleekxmpp.__version__,
+ 'software_name': 'Slixmpp',
+ 'version': slixmpp.__version__,
'os': ''
}
@@ -64,13 +64,14 @@ class XEP_0092(BasePlugin):
Arguments:
iq -- The Iq stanza containing the software version query.
"""
- iq.reply()
+ iq = iq.reply()
iq['software_version']['name'] = self.software_name
iq['software_version']['version'] = self.version
iq['software_version']['os'] = self.os
iq.send()
- def get_version(self, jid, ifrom=None, block=True, timeout=None, callback=None):
+ def get_version(self, jid, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
"""
Retrieve the software version of a remote agent.
@@ -82,4 +83,5 @@ class XEP_0092(BasePlugin):
iq['from'] = ifrom
iq['type'] = 'get'
iq['query'] = Version.namespace
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
diff --git a/slixmpp/plugins/xep_0095/__init__.py b/slixmpp/plugins/xep_0095/__init__.py
new file mode 100644
index 00000000..3c6380e1
--- /dev/null
+++ b/slixmpp/plugins/xep_0095/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0095 import stanza
+from slixmpp.plugins.xep_0095.stanza import SI
+from slixmpp.plugins.xep_0095.stream_initiation import XEP_0095
+
+
+register_plugin(XEP_0095)
diff --git a/sleekxmpp/plugins/xep_0095/stanza.py b/slixmpp/plugins/xep_0095/stanza.py
index 34999a11..62b5f6f8 100644
--- a/sleekxmpp/plugins/xep_0095/stanza.py
+++ b/slixmpp/plugins/xep_0095/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class SI(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0095/stream_initiation.py b/slixmpp/plugins/xep_0095/stream_initiation.py
index 927248a5..3f909d93 100644
--- a/sleekxmpp/plugins/xep_0095/stream_initiation.py
+++ b/slixmpp/plugins/xep_0095/stream_initiation.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -11,13 +11,13 @@ import threading
from uuid import uuid4
-from sleekxmpp import Iq, Message
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin, JID
-from sleekxmpp.plugins.xep_0095 import stanza, SI
+from slixmpp import Iq, Message
+from slixmpp.exceptions import XMPPError
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin, JID
+from slixmpp.plugins.xep_0095 import stanza, SI
log = logging.getLogger(__name__)
@@ -182,7 +182,6 @@ class XEP_0095(BasePlugin):
if stream_handler:
self.xmpp.add_event_handler('stream:%s:%s' % (sid, jid),
stream_handler,
- threaded=True,
disposable=True)
return iq.send()
diff --git a/slixmpp/plugins/xep_0096/__init__.py b/slixmpp/plugins/xep_0096/__init__.py
new file mode 100644
index 00000000..866a9820
--- /dev/null
+++ b/slixmpp/plugins/xep_0096/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0096 import stanza
+from slixmpp.plugins.xep_0096.stanza import File
+from slixmpp.plugins.xep_0096.file_transfer import XEP_0096
+
+
+register_plugin(XEP_0096)
diff --git a/sleekxmpp/plugins/xep_0096/file_transfer.py b/slixmpp/plugins/xep_0096/file_transfer.py
index 52ba2f27..3c09a5b5 100644
--- a/sleekxmpp/plugins/xep_0096/file_transfer.py
+++ b/slixmpp/plugins/xep_0096/file_transfer.py
@@ -1,19 +1,19 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp import Iq, Message
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin, JID
-from sleekxmpp.plugins.xep_0096 import stanza, File
+from slixmpp import Iq, Message
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin, JID
+from slixmpp.plugins.xep_0096 import stanza, File
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/plugins/xep_0096/stanza.py b/slixmpp/plugins/xep_0096/stanza.py
index 65eb5bc5..d3781c8d 100644
--- a/sleekxmpp/plugins/xep_0096/stanza.py
+++ b/slixmpp/plugins/xep_0096/stanza.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import datetime as dt
-from sleekxmpp.xmlstream import ElementBase, register_stanza_plugin
-from sleekxmpp.plugins import xep_0082
+from slixmpp.xmlstream import ElementBase, register_stanza_plugin
+from slixmpp.plugins import xep_0082
class File(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0106.py b/slixmpp/plugins/xep_0106.py
index 1859a77b..a4717956 100644
--- a/sleekxmpp/plugins/xep_0106.py
+++ b/slixmpp/plugins/xep_0106.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins import BasePlugin, register_plugin
+from slixmpp.plugins import BasePlugin, register_plugin
class XEP_0106(BasePlugin):
diff --git a/slixmpp/plugins/xep_0107/__init__.py b/slixmpp/plugins/xep_0107/__init__.py
new file mode 100644
index 00000000..778fd33b
--- /dev/null
+++ b/slixmpp/plugins/xep_0107/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0107 import stanza
+from slixmpp.plugins.xep_0107.stanza import UserMood
+from slixmpp.plugins.xep_0107.user_mood import XEP_0107
+
+
+register_plugin(XEP_0107)
diff --git a/sleekxmpp/plugins/xep_0107/stanza.py b/slixmpp/plugins/xep_0107/stanza.py
index 2c5814ea..05967de9 100644
--- a/sleekxmpp/plugins/xep_0107/stanza.py
+++ b/slixmpp/plugins/xep_0107/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class UserMood(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0107/user_mood.py b/slixmpp/plugins/xep_0107/user_mood.py
index 2d2f3551..c56d15fa 100644
--- a/sleekxmpp/plugins/xep_0107/user_mood.py
+++ b/slixmpp/plugins/xep_0107/user_mood.py
@@ -1,19 +1,19 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp import Message
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import MatchXPath
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.plugins.xep_0107 import stanza, UserMood
+from slixmpp import Message
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import MatchXPath
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.plugins.xep_0107 import stanza, UserMood
log = logging.getLogger(__name__)
@@ -40,8 +40,8 @@ class XEP_0107(BasePlugin):
def session_bind(self, jid):
self.xmpp['xep_0163'].register_pep('user_mood', UserMood)
- def publish_mood(self, value=None, text=None, options=None,
- ifrom=None, block=True, callback=None, timeout=None):
+ def publish_mood(self, value=None, text=None, options=None, ifrom=None,
+ callback=None, timeout=None, timeout_callback=None):
"""
Publish the user's current mood.
@@ -51,43 +51,35 @@ class XEP_0107(BasePlugin):
for the mood.
options -- Optional form of publish options.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
mood = UserMood()
mood['value'] = value
mood['text'] = text
- return self.xmpp['xep_0163'].publish(mood,
- node=UserMood.namespace,
- options=options,
- ifrom=ifrom,
- block=block,
- callback=callback,
- timeout=timeout)
-
- def stop(self, ifrom=None, block=True, callback=None, timeout=None):
+ self.xmpp['xep_0163'].publish(mood, node=UserMood.namespace,
+ options=options, ifrom=ifrom,
+ callback=callback, timeout=timeout,
+ timeout_callback=timeout_callback)
+
+ def stop(self, ifrom=None, callback=None, timeout=None,
+ timeout_callback=None):
"""
Clear existing user mood information to stop notifications.
Arguments:
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
mood = UserMood()
- return self.xmpp['xep_0163'].publish(mood,
- node=UserMood.namespace,
- ifrom=ifrom,
- block=block,
- callback=callback,
- timeout=timeout)
+ self.xmpp['xep_0163'].publish(mood, node=UserMood.namespace,
+ ifrom=ifrom, callback=callback,
+ timeout=timeout,
+ timeout_callback=timeout_callback)
diff --git a/slixmpp/plugins/xep_0108/__init__.py b/slixmpp/plugins/xep_0108/__init__.py
new file mode 100644
index 00000000..54cc5ddd
--- /dev/null
+++ b/slixmpp/plugins/xep_0108/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0108 import stanza
+from slixmpp.plugins.xep_0108.stanza import UserActivity
+from slixmpp.plugins.xep_0108.user_activity import XEP_0108
+
+
+register_plugin(XEP_0108)
diff --git a/sleekxmpp/plugins/xep_0108/stanza.py b/slixmpp/plugins/xep_0108/stanza.py
index 4650160a..d65dfdf9 100644
--- a/sleekxmpp/plugins/xep_0108/stanza.py
+++ b/slixmpp/plugins/xep_0108/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class UserActivity(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0108/user_activity.py b/slixmpp/plugins/xep_0108/user_activity.py
index 3a2f49b8..502dfae0 100644
--- a/sleekxmpp/plugins/xep_0108/user_activity.py
+++ b/slixmpp/plugins/xep_0108/user_activity.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.plugins.xep_0108 import stanza, UserActivity
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.plugins.xep_0108 import stanza, UserActivity
log = logging.getLogger(__name__)
@@ -33,8 +33,9 @@ class XEP_0108(BasePlugin):
def session_bind(self, jid):
self.xmpp['xep_0163'].register_pep('user_activity', UserActivity)
- def publish_activity(self, general, specific=None, text=None, options=None,
- ifrom=None, block=True, callback=None, timeout=None):
+ def publish_activity(self, general, specific=None, text=None,
+ options=None, ifrom=None, callback=None,
+ timeout=None, timeout_callback=None):
"""
Publish the user's current activity.
@@ -46,43 +47,36 @@ class XEP_0108(BasePlugin):
for the activity.
options -- Optional form of publish options.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
activity = UserActivity()
activity['value'] = (general, specific)
activity['text'] = text
- return self.xmpp['xep_0163'].publish(activity,
- node=UserActivity.namespace,
- options=options,
- ifrom=ifrom,
- block=block,
- callback=callback,
- timeout=timeout)
+ self.xmpp['xep_0163'].publish(activity, node=UserActivity.namespace,
+ options=options, ifrom=ifrom,
+ callback=callback,
+ timeout=timeout,
+ timeout_callback=timeout_callback)
- def stop(self, ifrom=None, block=True, callback=None, timeout=None):
+ def stop(self, ifrom=None, callback=None, timeout=None,
+ timeout_callback=None):
"""
Clear existing user activity information to stop notifications.
Arguments:
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
activity = UserActivity()
- return self.xmpp['xep_0163'].publish(activity,
- node=UserActivity.namespace,
- ifrom=ifrom,
- block=block,
- callback=callback,
- timeout=timeout)
+ self.xmpp['xep_0163'].publish(activity, node=UserActivity.namespace,
+ ifrom=ifrom, callback=callback,
+ timeout=timeout,
+ timeout_callback=timeout_callback)
diff --git a/slixmpp/plugins/xep_0115/__init__.py b/slixmpp/plugins/xep_0115/__init__.py
new file mode 100644
index 00000000..51c437c6
--- /dev/null
+++ b/slixmpp/plugins/xep_0115/__init__.py
@@ -0,0 +1,20 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0115.stanza import Capabilities
+from slixmpp.plugins.xep_0115.static import StaticCaps
+from slixmpp.plugins.xep_0115.caps import XEP_0115
+
+
+register_plugin(XEP_0115)
+
+
+# Retain some backwards compatibility
+xep_0115 = XEP_0115
diff --git a/sleekxmpp/plugins/xep_0115/caps.py b/slixmpp/plugins/xep_0115/caps.py
index 41b5c52e..c6f9ea10 100644
--- a/sleekxmpp/plugins/xep_0115/caps.py
+++ b/slixmpp/plugins/xep_0115/caps.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,16 +9,16 @@
import logging
import hashlib
import base64
-import threading
-from sleekxmpp import __version__
-from sleekxmpp.stanza import StreamFeatures, Presence, Iq
-from sleekxmpp.xmlstream import register_stanza_plugin, JID
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.exceptions import XMPPError, IqError, IqTimeout
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0115 import stanza, StaticCaps
+from slixmpp import __version__
+from slixmpp.stanza import StreamFeatures, Presence, Iq
+from slixmpp.xmlstream import register_stanza_plugin, JID
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp import asyncio
+from slixmpp.exceptions import XMPPError, IqError, IqTimeout
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0115 import stanza, StaticCaps
log = logging.getLogger(__name__)
@@ -46,7 +46,7 @@ class XEP_0115(BasePlugin):
'md5': hashlib.md5}
if self.caps_node is None:
- self.caps_node = 'http://sleekxmpp.com/ver/%s' % __version__
+ self.caps_node = 'http://slixmpp.com/ver/%s' % __version__
register_stanza_plugin(Presence, stanza.Capabilities)
register_stanza_plugin(StreamFeatures, stanza.Capabilities)
@@ -65,8 +65,7 @@ class XEP_0115(BasePlugin):
self.xmpp.add_filter('out', self._filter_add_caps)
- self.xmpp.add_event_handler('entity_caps', self._process_caps,
- threaded=True)
+ self.xmpp.add_event_handler('entity_caps', self._process_caps)
if not self.xmpp.is_component:
self.xmpp.register_feature('caps',
@@ -90,9 +89,6 @@ class XEP_0115(BasePlugin):
disco.assign_verstring = self.assign_verstring
disco.get_verstring = self.get_verstring
- self._processing_lock = threading.Lock()
- self._processing = set()
-
def plugin_end(self):
self.xmpp['xep_0030'].del_feature(feature=stanza.Capabilities.namespace)
self.xmpp.del_filter('out', self._filter_add_caps)
@@ -136,6 +132,7 @@ class XEP_0115(BasePlugin):
self.xmpp.event('entity_caps', p)
+ @asyncio.coroutine
def _process_caps(self, pres):
if not pres['caps']['hash']:
log.debug("Received unsupported legacy caps: %s, %s, %s",
@@ -164,17 +161,11 @@ class XEP_0115(BasePlugin):
except XMPPError:
return
- # Only lookup the same caps once at a time.
- with self._processing_lock:
- if ver in self._processing:
- log.debug('Already processing verstring %s' % ver)
- return
- self._processing.add(ver)
-
log.debug("New caps verification string: %s", ver)
try:
node = '%s#%s' % (pres['caps']['node'], ver)
- caps = self.xmpp['xep_0030'].get_info(pres['from'], node)
+ caps = yield from self.xmpp['xep_0030'].get_info(pres['from'], node,
+ coroutine=True)
if isinstance(caps, Iq):
caps = caps['disco_info']
@@ -185,9 +176,6 @@ class XEP_0115(BasePlugin):
except XMPPError:
log.debug("Could not retrieve disco#info results for caps for %s", node)
- with self._processing_lock:
- self._processing.remove(ver)
-
def _validate_caps(self, caps, hash, check_verstring):
# Check Identities
full_ids = caps.get_identities(dedupe=False)
@@ -292,9 +280,10 @@ class XEP_0115(BasePlugin):
binary = hash(S.encode('utf8')).digest()
return base64.b64encode(binary).decode('utf-8')
+ @asyncio.coroutine
def update_caps(self, jid=None, node=None, preserve=False):
try:
- info = self.xmpp['xep_0030'].get_info(jid, node, local=True)
+ info = yield from self.xmpp['xep_0030'].get_info(jid, node, local=True)
if isinstance(info, Iq):
info = info['disco_info']
ver = self.generate_verstring(info, self.hash)
@@ -305,7 +294,7 @@ class XEP_0115(BasePlugin):
self.cache_caps(ver, info)
self.assign_verstring(jid, ver)
- if self.xmpp.session_started_event.is_set() and self.broadcast:
+ if self.xmpp.sessionstarted and self.broadcast:
if self.xmpp.is_component or preserve:
for contact in self.xmpp.roster[jid]:
self.xmpp.roster[jid][contact].send_last_presence()
diff --git a/sleekxmpp/plugins/xep_0115/stanza.py b/slixmpp/plugins/xep_0115/stanza.py
index 3e80b5cf..36fb173c 100644
--- a/sleekxmpp/plugins/xep_0115/stanza.py
+++ b/slixmpp/plugins/xep_0115/stanza.py
@@ -1,14 +1,14 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from __future__ import unicode_literals
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class Capabilities(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0115/static.py b/slixmpp/plugins/xep_0115/static.py
index f83c244c..0d1caa01 100644
--- a/sleekxmpp/plugins/xep_0115/static.py
+++ b/slixmpp/plugins/xep_0115/static.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.xmlstream import JID
-from sleekxmpp.exceptions import IqError, IqTimeout
+from slixmpp.xmlstream import JID
+from slixmpp.exceptions import IqError, IqTimeout
log = logging.getLogger(__name__)
@@ -43,7 +43,7 @@ class StaticCaps(object):
The data parameter may provide:
feature -- The feature to check for support.
local -- If true, then the query is for a JID/node
- combination handled by this Sleek instance and
+ combination handled by this Slixmpp instance and
no stanzas need to be sent.
Otherwise, a disco stanza must be sent to the
remove JID to retrieve the info.
@@ -87,7 +87,7 @@ class StaticCaps(object):
itype -- The type of the identity to check.
lang -- The language of the identity to check.
local -- If true, then the query is for a JID/node
- combination handled by this Sleek instance and
+ combination handled by this Slixmpp instance and
no stanzas need to be sent.
Otherwise, a disco stanza must be sent to the
remove JID to retrieve the info.
diff --git a/slixmpp/plugins/xep_0118/__init__.py b/slixmpp/plugins/xep_0118/__init__.py
new file mode 100644
index 00000000..7ad48998
--- /dev/null
+++ b/slixmpp/plugins/xep_0118/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0118 import stanza
+from slixmpp.plugins.xep_0118.stanza import UserTune
+from slixmpp.plugins.xep_0118.user_tune import XEP_0118
+
+
+register_plugin(XEP_0118)
diff --git a/sleekxmpp/plugins/xep_0118/stanza.py b/slixmpp/plugins/xep_0118/stanza.py
index 3fdab284..4f5a1795 100644
--- a/sleekxmpp/plugins/xep_0118/stanza.py
+++ b/slixmpp/plugins/xep_0118/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class UserTune(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0118/user_tune.py b/slixmpp/plugins/xep_0118/user_tune.py
index 1bb00122..0882a5ba 100644
--- a/sleekxmpp/plugins/xep_0118/user_tune.py
+++ b/slixmpp/plugins/xep_0118/user_tune.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.plugins.xep_0118 import stanza, UserTune
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.plugins.xep_0118 import stanza, UserTune
log = logging.getLogger(__name__)
@@ -35,7 +35,7 @@ class XEP_0118(BasePlugin):
def publish_tune(self, artist=None, length=None, rating=None, source=None,
title=None, track=None, uri=None, options=None,
- ifrom=None, block=True, callback=None, timeout=None):
+ ifrom=None, callback=None, timeout=None, timeout_callback=None):
"""
Publish the user's current tune.
@@ -49,11 +49,9 @@ class XEP_0118(BasePlugin):
uri -- A URL to more information about the song.
options -- Optional form of publish options.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -69,21 +67,19 @@ class XEP_0118(BasePlugin):
node=UserTune.namespace,
options=options,
ifrom=ifrom,
- block=block,
callback=callback,
- timeout=timeout)
+ timeout=timeout,
+ timeout_callback=timeout_callback)
- def stop(self, ifrom=None, block=True, callback=None, timeout=None):
+ def stop(self, ifrom=None, callback=None, timeout=None, timeout_callback=None):
"""
Clear existing user tune information to stop notifications.
Arguments:
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -91,6 +87,6 @@ class XEP_0118(BasePlugin):
return self.xmpp['xep_0163'].publish(tune,
node=UserTune.namespace,
ifrom=ifrom,
- block=block,
callback=callback,
- timeout=timeout)
+ timeout=timeout,
+ timeout_callback=timeout_callback)
diff --git a/slixmpp/plugins/xep_0122/__init__.py b/slixmpp/plugins/xep_0122/__init__.py
new file mode 100644
index 00000000..76ca80b2
--- /dev/null
+++ b/slixmpp/plugins/xep_0122/__init__.py
@@ -0,0 +1,11 @@
+
+from slixmpp.plugins.base import register_plugin
+from slixmpp.plugins.xep_0122.stanza import FormValidation
+from slixmpp.plugins.xep_0122.data_validation import XEP_0122
+
+
+register_plugin(XEP_0122)
+
+
+# Retain some backwards compatibility
+xep_0122 = XEP_0122
diff --git a/slixmpp/plugins/xep_0122/data_validation.py b/slixmpp/plugins/xep_0122/data_validation.py
new file mode 100644
index 00000000..6129db51
--- /dev/null
+++ b/slixmpp/plugins/xep_0122/data_validation.py
@@ -0,0 +1,19 @@
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0004 import stanza
+from slixmpp.plugins.xep_0004.stanza import FormField
+from slixmpp.plugins.xep_0122.stanza import FormValidation
+
+
+class XEP_0122(BasePlugin):
+ """
+ XEP-0122: Data Forms
+ """
+
+ name = 'xep_0122'
+ description = 'XEP-0122: Data Forms Validation'
+ dependencies = set(['xep_0004'])
+ stanza = stanza
+
+ def plugin_init(self):
+ register_stanza_plugin(FormField, FormValidation)
diff --git a/sleekxmpp/plugins/xep_0122/stanza.py b/slixmpp/plugins/xep_0122/stanza.py
index bc3c177a..9f1c423d 100644
--- a/sleekxmpp/plugins/xep_0122/stanza.py
+++ b/slixmpp/plugins/xep_0122/stanza.py
@@ -1,5 +1,4 @@
-
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class FormValidation(ElementBase):
diff --git a/slixmpp/plugins/xep_0128/__init__.py b/slixmpp/plugins/xep_0128/__init__.py
new file mode 100644
index 00000000..fb6dbf7c
--- /dev/null
+++ b/slixmpp/plugins/xep_0128/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0128.static import StaticExtendedDisco
+from slixmpp.plugins.xep_0128.extended_disco import XEP_0128
+
+
+register_plugin(XEP_0128)
+
+
+# Retain some backwards compatibility
+xep_0128 = XEP_0128
diff --git a/sleekxmpp/plugins/xep_0128/extended_disco.py b/slixmpp/plugins/xep_0128/extended_disco.py
index d785affe..5cc1d35a 100644
--- a/sleekxmpp/plugins/xep_0128/extended_disco.py
+++ b/slixmpp/plugins/xep_0128/extended_disco.py
@@ -1,20 +1,20 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-import sleekxmpp
-from sleekxmpp import Iq
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0004 import Form
-from sleekxmpp.plugins.xep_0030 import DiscoInfo
-from sleekxmpp.plugins.xep_0128 import StaticExtendedDisco
+import slixmpp
+from slixmpp import Iq
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0004 import Form
+from slixmpp.plugins.xep_0030 import DiscoInfo
+from slixmpp.plugins.xep_0128 import StaticExtendedDisco
class XEP_0128(BasePlugin):
@@ -31,7 +31,7 @@ class XEP_0128(BasePlugin):
disco -- A reference to the XEP-0030 plugin.
static -- Object containing the default set of static
node handlers.
- xmpp -- The main SleekXMPP object.
+ xmpp -- The main Slixmpp object.
Methods:
set_extended_info -- Set extensions to a disco#info result.
diff --git a/sleekxmpp/plugins/xep_0128/static.py b/slixmpp/plugins/xep_0128/static.py
index 427011c0..ab1ea590 100644
--- a/sleekxmpp/plugins/xep_0128/static.py
+++ b/slixmpp/plugins/xep_0128/static.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-import sleekxmpp
-from sleekxmpp.plugins.xep_0030 import StaticDisco
+import slixmpp
+from slixmpp.plugins.xep_0030 import StaticDisco
log = logging.getLogger(__name__)
diff --git a/slixmpp/plugins/xep_0131/__init__.py b/slixmpp/plugins/xep_0131/__init__.py
new file mode 100644
index 00000000..4151cc72
--- /dev/null
+++ b/slixmpp/plugins/xep_0131/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0131 import stanza
+from slixmpp.plugins.xep_0131.stanza import Headers
+from slixmpp.plugins.xep_0131.headers import XEP_0131
+
+
+register_plugin(XEP_0131)
diff --git a/sleekxmpp/plugins/xep_0131/headers.py b/slixmpp/plugins/xep_0131/headers.py
index 3e47541a..81fc9188 100644
--- a/sleekxmpp/plugins/xep_0131/headers.py
+++ b/slixmpp/plugins/xep_0131/headers.py
@@ -1,16 +1,16 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp import Message, Presence
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0131 import stanza
-from sleekxmpp.plugins.xep_0131.stanza import Headers
+from slixmpp import Message, Presence
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0131 import stanza
+from slixmpp.plugins.xep_0131.stanza import Headers
class XEP_0131(BasePlugin):
diff --git a/sleekxmpp/plugins/xep_0131/stanza.py b/slixmpp/plugins/xep_0131/stanza.py
index 347adf96..cbbe61a7 100644
--- a/sleekxmpp/plugins/xep_0131/stanza.py
+++ b/slixmpp/plugins/xep_0131/stanza.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.thirdparty import OrderedDict
-from sleekxmpp.xmlstream import ET, ElementBase
+from collections import OrderedDict
+from slixmpp.xmlstream import ET, ElementBase
class Headers(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0133.py b/slixmpp/plugins/xep_0133.py
index 7bbe4c3c..a1eb9e02 100644
--- a/sleekxmpp/plugins/xep_0133.py
+++ b/slixmpp/plugins/xep_0133.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins import BasePlugin, register_plugin
+from slixmpp.plugins import BasePlugin, register_plugin
class XEP_0133(BasePlugin):
@@ -35,15 +35,14 @@ class XEP_0133(BasePlugin):
def create_command(name):
- def admin_command(self, jid=None, session=None, ifrom=None, block=False):
+ def admin_command(self, jid=None, session=None, ifrom=None):
if jid is None:
jid = self.xmpp.boundjid.server
self.xmpp['xep_0050'].start_command(
jid=jid,
node='http://jabber.org/protocol/admin#%s' % name,
session=session,
- ifrom=ifrom,
- block=block)
+ ifrom=ifrom)
return admin_command
diff --git a/sleekxmpp/plugins/xep_0138.py b/slixmpp/plugins/xep_0138.py
index c5d8f06f..049060cf 100644
--- a/sleekxmpp/plugins/xep_0138.py
+++ b/slixmpp/plugins/xep_0138.py
@@ -1,23 +1,20 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-import socket
import zlib
-from sleekxmpp.thirdparty.suelta.util import bytes
-
-from sleekxmpp.stanza import StreamFeatures
-from sleekxmpp.xmlstream import RestartStream, register_stanza_plugin, ElementBase, StanzaBase
-from sleekxmpp.xmlstream.matcher import *
-from sleekxmpp.xmlstream.handler import *
-from sleekxmpp.plugins import BasePlugin, register_plugin
+from slixmpp.stanza import StreamFeatures
+from slixmpp.xmlstream import RestartStream, register_stanza_plugin, ElementBase, StanzaBase
+from slixmpp.xmlstream.matcher import *
+from slixmpp.xmlstream.handler import *
+from slixmpp.plugins import BasePlugin, register_plugin
log = logging.getLogger(__name__)
diff --git a/slixmpp/plugins/xep_0152/__init__.py b/slixmpp/plugins/xep_0152/__init__.py
new file mode 100644
index 00000000..4e6d3a09
--- /dev/null
+++ b/slixmpp/plugins/xep_0152/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0152 import stanza
+from slixmpp.plugins.xep_0152.stanza import Reachability
+from slixmpp.plugins.xep_0152.reachability import XEP_0152
+
+
+register_plugin(XEP_0152)
diff --git a/sleekxmpp/plugins/xep_0152/reachability.py b/slixmpp/plugins/xep_0152/reachability.py
index 4cf81739..e6d94b65 100644
--- a/sleekxmpp/plugins/xep_0152/reachability.py
+++ b/slixmpp/plugins/xep_0152/reachability.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.plugins.xep_0152 import stanza, Reachability
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.plugins.xep_0152 import stanza, Reachability
log = logging.getLogger(__name__)
@@ -33,8 +33,9 @@ class XEP_0152(BasePlugin):
def session_bind(self, jid):
self.xmpp['xep_0163'].register_pep('reachability', Reachability)
- def publish_reachability(self, addresses, options=None,
- ifrom=None, block=True, callback=None, timeout=None):
+ def publish_reachability(self, addresses, options=None, ifrom=None,
+ callback=None, timeout=None,
+ timeout_callback=None):
"""
Publish alternative addresses where the user can be reached.
@@ -43,11 +44,9 @@ class XEP_0152(BasePlugin):
optional description for each address.
options -- Optional form of publish options.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -66,21 +65,19 @@ class XEP_0152(BasePlugin):
node=Reachability.namespace,
options=options,
ifrom=ifrom,
- block=block,
callback=callback,
- timeout=timeout)
+ timeout=timeout,
+ timeout_callback=timeout_callback)
- def stop(self, ifrom=None, block=True, callback=None, timeout=None):
+ def stop(self, ifrom=None, callback=None, timeout=None, timeout_callback=None):
"""
Clear existing user activity information to stop notifications.
Arguments:
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -88,6 +85,6 @@ class XEP_0152(BasePlugin):
return self.xmpp['xep_0163'].publish(reach,
node=Reachability.namespace,
ifrom=ifrom,
- block=block,
callback=callback,
- timeout=timeout)
+ timeout=timeout,
+ timeout_callback=timeout_callback)
diff --git a/sleekxmpp/plugins/xep_0152/stanza.py b/slixmpp/plugins/xep_0152/stanza.py
index bd173ce1..661544e3 100644
--- a/sleekxmpp/plugins/xep_0152/stanza.py
+++ b/slixmpp/plugins/xep_0152/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, register_stanza_plugin
+from slixmpp.xmlstream import ElementBase, register_stanza_plugin
class Reachability(ElementBase):
diff --git a/slixmpp/plugins/xep_0153/__init__.py b/slixmpp/plugins/xep_0153/__init__.py
new file mode 100644
index 00000000..378cec90
--- /dev/null
+++ b/slixmpp/plugins/xep_0153/__init__.py
@@ -0,0 +1,15 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0153.stanza import VCardTempUpdate
+from slixmpp.plugins.xep_0153.vcard_avatar import XEP_0153
+
+
+register_plugin(XEP_0153)
diff --git a/sleekxmpp/plugins/xep_0153/stanza.py b/slixmpp/plugins/xep_0153/stanza.py
index 4e6a660f..fe8d5e98 100644
--- a/sleekxmpp/plugins/xep_0153/stanza.py
+++ b/slixmpp/plugins/xep_0153/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class VCardTempUpdate(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0153/vcard_avatar.py b/slixmpp/plugins/xep_0153/vcard_avatar.py
index ec1ae782..b2c4caf5 100644
--- a/sleekxmpp/plugins/xep_0153/vcard_avatar.py
+++ b/slixmpp/plugins/xep_0153/vcard_avatar.py
@@ -1,20 +1,20 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import hashlib
import logging
-import threading
-from sleekxmpp.stanza import Presence
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.plugins.xep_0153 import stanza, VCardTempUpdate
+from slixmpp.stanza import Presence
+from slixmpp.exceptions import XMPPError, IqTimeout
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.plugins.xep_0153 import stanza, VCardTempUpdate
+from slixmpp import asyncio, future_wrapper
log = logging.getLogger(__name__)
@@ -30,8 +30,6 @@ class XEP_0153(BasePlugin):
def plugin_init(self):
self._hashes = {}
- self._allow_advertising = threading.Event()
-
register_stanza_plugin(Presence, VCardTempUpdate)
self.xmpp.add_filter('out', self._update_presence)
@@ -59,36 +57,62 @@ class XEP_0153(BasePlugin):
self.xmpp.del_event_handler('presence_chat', self._recv_presence)
self.xmpp.del_event_handler('presence_away', self._recv_presence)
- def set_avatar(self, jid=None, avatar=None, mtype=None, block=True,
- timeout=None, callback=None):
+ @future_wrapper
+ def set_avatar(self, jid=None, avatar=None, mtype=None, timeout=None,
+ callback=None, timeout_callback=None):
if jid is None:
jid = self.xmpp.boundjid.bare
- vcard = self.xmpp['xep_0054'].get_vcard(jid, cached=True)
- vcard = vcard['vcard_temp']
- vcard['PHOTO']['TYPE'] = mtype
- vcard['PHOTO']['BINVAL'] = avatar
+ future = asyncio.Future()
+
+ def propagate_timeout_exception(fut):
+ try:
+ fut.done()
+ except IqTimeout as e:
+ future.set_exception(e)
+
+ def custom_callback(result):
+ vcard = result['vcard_temp']
+ vcard['PHOTO']['TYPE'] = mtype
+ vcard['PHOTO']['BINVAL'] = avatar
+
+ new_future = self.xmpp['xep_0054'].publish_vcard(jid=jid,
+ vcard=vcard,
+ timeout=timeout,
+ callback=next_callback,
+ timeout_callback=timeout_callback)
+ new_future.add_done_callback(propagate_timeout_exception)
+
+ def next_callback(result):
+ if result['type'] == 'error':
+ future.set_exception(result)
+ else:
+ self.api['reset_hash'](jid)
+ self.xmpp.roster[jid].send_last_presence()
- self.xmpp['xep_0054'].publish_vcard(jid=jid, vcard=vcard)
+ future.set_result(result)
- self.api['reset_hash'](jid)
- self.xmpp.roster[jid].send_last_presence()
+ first_future = self.xmpp['xep_0054'].get_vcard(jid, cached=False, timeout=timeout,
+ callback=custom_callback,
+ timeout_callback=timeout_callback)
+ first_future.add_done_callback(propagate_timeout_exception)
+ return future
+ @asyncio.coroutine
def _start(self, event):
try:
- vcard = self.xmpp['xep_0054'].get_vcard(self.xmpp.boundjid.bare)
+ vcard = yield from self.xmpp['xep_0054'].get_vcard(self.xmpp.boundjid.bare)
data = vcard['vcard_temp']['PHOTO']['BINVAL']
if not data:
new_hash = ''
else:
new_hash = hashlib.sha1(data).hexdigest()
self.api['set_hash'](self.xmpp.boundjid, args=new_hash)
- self._allow_advertising.set()
except XMPPError:
- log.debug('Could not retrieve vCard for %s' % self.xmpp.boundjid.bare)
+ log.debug('Could not retrieve vCard for %s', self.xmpp.boundjid.bare)
def _end(self, event):
- self._allow_advertising.clear()
+ pass
def _update_presence(self, stanza):
if not isinstance(stanza, Presence):
@@ -110,9 +134,10 @@ class XEP_0153(BasePlugin):
if own_jid:
self.xmpp.roster[jid].send_last_presence()
- try:
- iq = self.xmpp['xep_0054'].get_vcard(jid=jid.bare, ifrom=ifrom)
-
+ def callback(iq):
+ if iq['type'] == 'error':
+ log.debug('Could not retrieve vCard for %s', jid)
+ return
data = iq['vcard_temp']['PHOTO']['BINVAL']
if not data:
new_hash = ''
@@ -120,8 +145,9 @@ class XEP_0153(BasePlugin):
new_hash = hashlib.sha1(data).hexdigest()
self.api['set_hash'](jid, args=new_hash)
- except XMPPError:
- log.debug('Could not retrieve vCard for %s' % jid)
+
+ self.xmpp['xep_0054'].get_vcard(jid=jid.bare, ifrom=ifrom,
+ callback=callback)
def _recv_presence(self, pres):
try:
@@ -129,7 +155,7 @@ class XEP_0153(BasePlugin):
# Don't process vCard avatars for MUC occupants
# since they all share the same bare JID.
return
- except: pass
+ except: pass
if not pres.match('presence/vcard_temp_update'):
self.api['set_hash'](pres['from'], args=None)
diff --git a/sleekxmpp/plugins/xep_0163.py b/slixmpp/plugins/xep_0163.py
index 2d1a63b7..b85c662c 100644
--- a/sleekxmpp/plugins/xep_0163.py
+++ b/slixmpp/plugins/xep_0163.py
@@ -1,15 +1,16 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.base import BasePlugin, register_plugin
+from slixmpp import asyncio
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.base import BasePlugin, register_plugin
log = logging.getLogger(__name__)
@@ -61,7 +62,7 @@ class XEP_0163(BasePlugin):
for ns in namespace:
self.xmpp['xep_0030'].add_feature('%s+notify' % ns,
jid=jid)
- self.xmpp['xep_0115'].update_caps(jid)
+ asyncio.async(self.xmpp['xep_0115'].update_caps(jid))
def remove_interest(self, namespace, jid=None):
"""
@@ -80,10 +81,10 @@ class XEP_0163(BasePlugin):
for ns in namespace:
self.xmpp['xep_0030'].del_feature(jid=jid,
feature='%s+notify' % namespace)
- self.xmpp['xep_0115'].update_caps(jid)
+ asyncio.async(self.xmpp['xep_0115'].update_caps(jid))
def publish(self, stanza, node=None, id=None, options=None, ifrom=None,
- block=True, callback=None, timeout=None):
+ timeout_callback=None, callback=None, timeout=None):
"""
Publish a PEP update.
@@ -97,11 +98,9 @@ class XEP_0163(BasePlugin):
id -- Optionally specify the ID of the item.
options -- A form of publish options.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -110,14 +109,12 @@ class XEP_0163(BasePlugin):
if id is None:
id = 'current'
- return self.xmpp['xep_0060'].publish(ifrom, node,
- id=id,
- payload=stanza.xml,
- options=options,
- ifrom=ifrom,
- block=block,
- callback=callback,
- timeout=timeout)
+ return self.xmpp['xep_0060'].publish(ifrom, node, id=id,
+ payload=stanza.xml,
+ options=options, ifrom=ifrom,
+ callback=callback,
+ timeout=timeout,
+ timeout_callback=timeout_callback)
register_plugin(XEP_0163)
diff --git a/slixmpp/plugins/xep_0172/__init__.py b/slixmpp/plugins/xep_0172/__init__.py
new file mode 100644
index 00000000..6e8d25e0
--- /dev/null
+++ b/slixmpp/plugins/xep_0172/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0172 import stanza
+from slixmpp.plugins.xep_0172.stanza import UserNick
+from slixmpp.plugins.xep_0172.user_nick import XEP_0172
+
+
+register_plugin(XEP_0172)
diff --git a/sleekxmpp/plugins/xep_0172/stanza.py b/slixmpp/plugins/xep_0172/stanza.py
index 110c237b..305f3a00 100644
--- a/sleekxmpp/plugins/xep_0172/stanza.py
+++ b/slixmpp/plugins/xep_0172/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class UserNick(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0172/user_nick.py b/slixmpp/plugins/xep_0172/user_nick.py
index cab13c15..b9f20b27 100644
--- a/sleekxmpp/plugins/xep_0172/user_nick.py
+++ b/slixmpp/plugins/xep_0172/user_nick.py
@@ -1,20 +1,20 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.stanza.message import Message
-from sleekxmpp.stanza.presence import Presence
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import MatchXPath
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.plugins.xep_0172 import stanza, UserNick
+from slixmpp.stanza.message import Message
+from slixmpp.stanza.presence import Presence
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import MatchXPath
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.plugins.xep_0172 import stanza, UserNick
log = logging.getLogger(__name__)
@@ -42,7 +42,7 @@ class XEP_0172(BasePlugin):
def session_bind(self, jid):
self.xmpp['xep_0163'].register_pep('user_nick', UserNick)
- def publish_nick(self, nick=None, options=None, ifrom=None, block=True,
+ def publish_nick(self, nick=None, options=None, ifrom=None, timeout_callback=None,
callback=None, timeout=None):
"""
Publish the user's current nick.
@@ -51,42 +51,33 @@ class XEP_0172(BasePlugin):
nick -- The user nickname to publish.
options -- Optional form of publish options.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
nickname = UserNick()
nickname['nick'] = nick
- return self.xmpp['xep_0163'].publish(nickname,
- node=UserNick.namespace,
- options=options,
- ifrom=ifrom,
- block=block,
- callback=callback,
- timeout=timeout)
-
- def stop(self, ifrom=None, block=True, callback=None, timeout=None):
+ self.xmpp['xep_0163'].publish(nickname, node=UserNick.namespace,
+ options=options, ifrom=ifrom,
+ callback=callback, timeout=timeout,
+ timeout_callback=timeout_callback)
+
+ def stop(self, ifrom=None, timeout_callback=None, callback=None, timeout=None):
"""
Clear existing user nick information to stop notifications.
Arguments:
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
nick = UserNick()
- return self.xmpp['xep_0163'].publish(nick,
- node=UserNick.namespace,
- ifrom=ifrom,
- block=block,
- callback=callback,
- timeout=timeout)
+ return self.xmpp['xep_0163'].publish(nick, node=UserNick.namespace,
+ ifrom=ifrom, callback=callback,
+ timeout=timeout,
+ timeout_callback=timeout_callback)
diff --git a/slixmpp/plugins/xep_0184/__init__.py b/slixmpp/plugins/xep_0184/__init__.py
new file mode 100644
index 00000000..83c2d7c2
--- /dev/null
+++ b/slixmpp/plugins/xep_0184/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Erik Reuterborg Larsson, Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0184.stanza import Request, Received
+from slixmpp.plugins.xep_0184.receipt import XEP_0184
+
+
+register_plugin(XEP_0184)
+
+
+# Retain some backwards compatibility
+xep_0184 = XEP_0184
diff --git a/sleekxmpp/plugins/xep_0184/receipt.py b/slixmpp/plugins/xep_0184/receipt.py
index 3e97d8db..2c3555dc 100644
--- a/sleekxmpp/plugins/xep_0184/receipt.py
+++ b/slixmpp/plugins/xep_0184/receipt.py
@@ -1,19 +1,19 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Erik Reuterborg Larsson, Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.stanza import Message
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0184 import stanza, Request, Received
+from slixmpp.stanza import Message
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0184 import stanza, Request, Received
class XEP_0184(BasePlugin):
@@ -67,9 +67,7 @@ class XEP_0184(BasePlugin):
"""
ack = self.xmpp.Message()
ack['to'] = msg['from']
- ack['from'] = msg['to']
ack['receipt'] = msg['id']
- ack['id'] = msg['id']
ack.send()
def _handle_receipt_received(self, msg):
diff --git a/sleekxmpp/plugins/xep_0184/stanza.py b/slixmpp/plugins/xep_0184/stanza.py
index a7607035..16a640e7 100644
--- a/sleekxmpp/plugins/xep_0184/stanza.py
+++ b/slixmpp/plugins/xep_0184/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Erik Reuterborg Larsson, Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream.stanzabase import ElementBase, ET
+from slixmpp.xmlstream.stanzabase import ElementBase, ET
class Request(ElementBase):
diff --git a/slixmpp/plugins/xep_0186/__init__.py b/slixmpp/plugins/xep_0186/__init__.py
new file mode 100644
index 00000000..0dc09337
--- /dev/null
+++ b/slixmpp/plugins/xep_0186/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0186 import stanza
+from slixmpp.plugins.xep_0186.stanza import Invisible, Visible
+from slixmpp.plugins.xep_0186.invisible_command import XEP_0186
+
+
+register_plugin(XEP_0186)
diff --git a/sleekxmpp/plugins/xep_0186/invisible_command.py b/slixmpp/plugins/xep_0186/invisible_command.py
index 15f63b2d..c20a3a06 100644
--- a/sleekxmpp/plugins/xep_0186/invisible_command.py
+++ b/slixmpp/plugins/xep_0186/invisible_command.py
@@ -1,17 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp import Iq
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0186 import stanza, Visible, Invisible
+from slixmpp import Iq
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.xep_0186 import stanza, Visible, Invisible
log = logging.getLogger(__name__)
@@ -27,18 +27,18 @@ class XEP_0186(BasePlugin):
register_stanza_plugin(Iq, Visible)
register_stanza_plugin(Iq, Invisible)
- def set_invisible(self, ifrom=None, block=True, callback=None,
+ def set_invisible(self, ifrom=None, callback=None,
timeout=None):
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq['from'] = ifrom
iq.enable('invisible')
- iq.send(block=block, callback=callback, timeout=timeout)
+ iq.send(callback=callback, timeout=timeout)
- def set_visible(self, ifrom=None, block=True, callback=None,
+ def set_visible(self, ifrom=None, callback=None,
timeout=None):
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq['from'] = ifrom
iq.enable('visible')
- iq.send(block=block, callback=callback, timeout=timeout)
+ iq.send(callback=callback, timeout=timeout)
diff --git a/sleekxmpp/plugins/xep_0186/stanza.py b/slixmpp/plugins/xep_0186/stanza.py
index aadbaa16..1ae7e834 100644
--- a/sleekxmpp/plugins/xep_0186/stanza.py
+++ b/slixmpp/plugins/xep_0186/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class Invisible(ElementBase):
diff --git a/slixmpp/plugins/xep_0191/__init__.py b/slixmpp/plugins/xep_0191/__init__.py
new file mode 100644
index 00000000..cd75684a
--- /dev/null
+++ b/slixmpp/plugins/xep_0191/__init__.py
@@ -0,0 +1,15 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0191.stanza import Block, Unblock, BlockList
+from slixmpp.plugins.xep_0191.blocking import XEP_0191
+
+
+register_plugin(XEP_0191)
diff --git a/sleekxmpp/plugins/xep_0191/blocking.py b/slixmpp/plugins/xep_0191/blocking.py
index 57632319..fa2a013e 100644
--- a/sleekxmpp/plugins/xep_0191/blocking.py
+++ b/slixmpp/plugins/xep_0191/blocking.py
@@ -1,19 +1,19 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp import Iq
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin, JID
-from sleekxmpp.plugins.xep_0191 import stanza, Block, Unblock, BlockList
+from slixmpp import Iq
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin, JID
+from slixmpp.plugins.xep_0191 import stanza, Block, Unblock, BlockList
log = logging.getLogger(__name__)
@@ -45,14 +45,17 @@ class XEP_0191(BasePlugin):
self.xmpp.remove_handler('Blocked Contact')
self.xmpp.remove_handler('Unblocked Contact')
- def get_blocked(self, ifrom=None, block=True, timeout=None, callback=None):
+ def get_blocked(self, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'get'
iq['from'] = ifrom
iq.enable('blocklist')
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
- def block(self, jids, ifrom=None, block=True, timeout=None, callback=None):
+ def block(self, jids, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq['from'] = ifrom
@@ -61,9 +64,11 @@ class XEP_0191(BasePlugin):
jids = [jids]
iq['block']['items'] = jids
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
- def unblock(self, jids=None, ifrom=None, block=True, timeout=None, callback=None):
+ def unblock(self, jids=None, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq['from'] = ifrom
@@ -74,7 +79,8 @@ class XEP_0191(BasePlugin):
jids = [jids]
iq['unblock']['items'] = jids
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
def _handle_blocked(self, iq):
self.xmpp.event('blocked', iq)
diff --git a/sleekxmpp/plugins/xep_0191/stanza.py b/slixmpp/plugins/xep_0191/stanza.py
index c5a284bd..4dac7bfc 100644
--- a/sleekxmpp/plugins/xep_0191/stanza.py
+++ b/slixmpp/plugins/xep_0191/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ET, ElementBase, JID
+from slixmpp.xmlstream import ET, ElementBase, JID
class BlockList(ElementBase):
diff --git a/slixmpp/plugins/xep_0196/__init__.py b/slixmpp/plugins/xep_0196/__init__.py
new file mode 100644
index 00000000..89f0f89e
--- /dev/null
+++ b/slixmpp/plugins/xep_0196/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0196 import stanza
+from slixmpp.plugins.xep_0196.stanza import UserGaming
+from slixmpp.plugins.xep_0196.user_gaming import XEP_0196
+
+
+register_plugin(XEP_0196)
diff --git a/sleekxmpp/plugins/xep_0196/stanza.py b/slixmpp/plugins/xep_0196/stanza.py
index 571c89d7..9c3cd0ed 100644
--- a/sleekxmpp/plugins/xep_0196/stanza.py
+++ b/slixmpp/plugins/xep_0196/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class UserGaming(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0196/user_gaming.py b/slixmpp/plugins/xep_0196/user_gaming.py
index e78f1acc..f0dee99f 100644
--- a/sleekxmpp/plugins/xep_0196/user_gaming.py
+++ b/slixmpp/plugins/xep_0196/user_gaming.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.plugins.xep_0196 import stanza, UserGaming
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.plugins.xep_0196 import stanza, UserGaming
log = logging.getLogger(__name__)
@@ -33,9 +33,11 @@ class XEP_0196(BasePlugin):
def session_bind(self, jid):
self.xmpp['xep_0163'].register_pep('user_gaming', UserGaming)
- def publish_gaming(self, name=None, level=None, server_name=None, uri=None,
- character_name=None, character_profile=None, server_address=None,
- options=None, ifrom=None, block=True, callback=None, timeout=None):
+ def publish_gaming(self, name=None, level=None, server_name=None,
+ uri=None, character_name=None,
+ character_profile=None, server_address=None,
+ options=None, ifrom=None, callback=None,
+ timeout=None, timeout_callback=None):
"""
Publish the user's current gaming status.
@@ -50,11 +52,9 @@ class XEP_0196(BasePlugin):
character_profile -- A URI for a profile of the user's character.
options -- Optional form of publish options.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -67,31 +67,27 @@ class XEP_0196(BasePlugin):
gaming['server_name'] = server_name
gaming['server_address'] = server_address
return self.xmpp['xep_0163'].publish(gaming,
- node=UserGaming.namespace,
- options=options,
- ifrom=ifrom,
- block=block,
- callback=callback,
- timeout=timeout)
+ node=UserGaming.namespace,
+ options=options, ifrom=ifrom,
+ callback=callback, timeout=timeout,
+ timeout_callback=timeout_callback)
- def stop(self, ifrom=None, block=True, callback=None, timeout=None):
+ def stop(self, ifrom=None, callback=None, timeout=None,
+ timeout_callback=None):
"""
Clear existing user gaming information to stop notifications.
Arguments:
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
gaming = UserGaming()
return self.xmpp['xep_0163'].publish(gaming,
- node=UserGaming.namespace,
- ifrom=ifrom,
- block=block,
- callback=callback,
- timeout=timeout)
+ node=UserGaming.namespace,
+ ifrom=ifrom, callback=callback,
+ timeout=timeout,
+ timeout_callback=timeout_callback)
diff --git a/slixmpp/plugins/xep_0198/__init__.py b/slixmpp/plugins/xep_0198/__init__.py
new file mode 100644
index 00000000..bd709041
--- /dev/null
+++ b/slixmpp/plugins/xep_0198/__init__.py
@@ -0,0 +1,20 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0198.stanza import Enable, Enabled
+from slixmpp.plugins.xep_0198.stanza import Resume, Resumed
+from slixmpp.plugins.xep_0198.stanza import Failed
+from slixmpp.plugins.xep_0198.stanza import StreamManagement
+from slixmpp.plugins.xep_0198.stanza import Ack, RequestAck
+
+from slixmpp.plugins.xep_0198.stream_management import XEP_0198
+
+
+register_plugin(XEP_0198)
diff --git a/sleekxmpp/plugins/xep_0198/stanza.py b/slixmpp/plugins/xep_0198/stanza.py
index 6461d766..b1c4c010 100644
--- a/sleekxmpp/plugins/xep_0198/stanza.py
+++ b/slixmpp/plugins/xep_0198/stanza.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza import Error
-from sleekxmpp.xmlstream import ElementBase, StanzaBase
+from slixmpp.stanza import Error
+from slixmpp.xmlstream import ElementBase, StanzaBase
class Enable(StanzaBase):
diff --git a/sleekxmpp/plugins/xep_0198/stream_management.py b/slixmpp/plugins/xep_0198/stream_management.py
index 48029913..acf37cd7 100644
--- a/sleekxmpp/plugins/xep_0198/stream_management.py
+++ b/slixmpp/plugins/xep_0198/stream_management.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -10,12 +10,12 @@ import logging
import threading
import collections
-from sleekxmpp.stanza import Message, Presence, Iq, StreamFeatures
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback, Waiter
-from sleekxmpp.xmlstream.matcher import MatchXPath, MatchMany
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.plugins.xep_0198 import stanza
+from slixmpp.stanza import Message, Presence, Iq, StreamFeatures
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback, Waiter
+from slixmpp.xmlstream.matcher import MatchXPath, MatchMany
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.plugins.xep_0198 import stanza
log = logging.getLogger(__name__)
@@ -173,7 +173,7 @@ class XEP_0198(BasePlugin):
ack = stanza.Ack(self.xmpp)
with self.handled_lock:
ack['h'] = self.handled
- self.xmpp.send_raw(str(ack), now=True)
+ self.xmpp.send_raw(str(ack))
def request_ack(self, e=None):
"""Request an ack from the server."""
@@ -199,14 +199,14 @@ class XEP_0198(BasePlugin):
self.enabled.set()
enable = stanza.Enable(self.xmpp)
enable['resume'] = self.allow_resume
- enable.send(now=True)
+ enable.send()
self.handled = 0
elif self.sm_id and self.allow_resume:
self.enabled.set()
resume = stanza.Resume(self.xmpp)
resume['h'] = self.handled
resume['previd'] = self.sm_id
- resume.send(now=True)
+ resume.send()
# Wait for a response before allowing stream feature processing
# to continue. The actual result processing will be done in the
@@ -239,8 +239,7 @@ class XEP_0198(BasePlugin):
self.xmpp.features.add('stream_management')
self._handle_ack(stanza)
for id, stanza in self.unacked_queue:
- self.xmpp.send(stanza, now=True, use_filters=False)
- self.xmpp.session_started_event.set()
+ self.xmpp.send(stanza, use_filters=False)
self.xmpp.event('session_resumed', stanza)
def _handle_failed(self, stanza):
diff --git a/slixmpp/plugins/xep_0199/__init__.py b/slixmpp/plugins/xep_0199/__init__.py
new file mode 100644
index 00000000..7c7bd221
--- /dev/null
+++ b/slixmpp/plugins/xep_0199/__init__.py
@@ -0,0 +1,20 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0199.stanza import Ping
+from slixmpp.plugins.xep_0199.ping import XEP_0199
+
+
+register_plugin(XEP_0199)
+
+
+# Backwards compatibility for names
+xep_0199 = XEP_0199
+xep_0199.sendPing = xep_0199.send_ping
diff --git a/sleekxmpp/plugins/xep_0199/ping.py b/slixmpp/plugins/xep_0199/ping.py
index 836ff4ae..bb2ceb38 100644
--- a/sleekxmpp/plugins/xep_0199/ping.py
+++ b/slixmpp/plugins/xep_0199/ping.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,14 +9,15 @@
import time
import logging
-from sleekxmpp.jid import JID
-from sleekxmpp.stanza import Iq
-from sleekxmpp.exceptions import IqError, IqTimeout
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0199 import stanza, Ping
+from slixmpp.jid import JID
+from slixmpp.stanza import Iq
+from slixmpp import asyncio
+from slixmpp.exceptions import IqError, IqTimeout
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0199 import stanza, Ping
log = logging.getLogger(__name__)
@@ -71,8 +72,7 @@ class XEP_0199(BasePlugin):
if self.keepalive:
self.xmpp.add_event_handler('session_start',
- self.enable_keepalive,
- threaded=True)
+ self.enable_keepalive)
self.xmpp.add_event_handler('session_end',
self.disable_keepalive)
@@ -101,7 +101,7 @@ class XEP_0199(BasePlugin):
repeat=True)
def disable_keepalive(self, event=None):
- self.xmpp.scheduler.remove('Ping keepalive')
+ self.xmpp.cancel_schedule('Ping keepalive')
def _keepalive(self, event=None):
log.debug("Keepalive ping...")
@@ -119,20 +119,17 @@ class XEP_0199(BasePlugin):
log.debug("Pinged by %s", iq['from'])
iq.reply().send()
- def send_ping(self, jid, ifrom=None, block=True, timeout=None, callback=None):
+ def send_ping(self, jid, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
"""Send a ping request.
Arguments:
jid -- The JID that will receive the ping.
ifrom -- Specifiy the sender JID.
- block -- Indicate if execution should block until
- a pong response is received. Defaults
- to True.
timeout -- Time in seconds to wait for a response.
Defaults to self.timeout.
callback -- Optional handler to execute when a pong
- is received. Useful in conjunction with
- the option block=False.
+ is received.
"""
if not timeout:
timeout = self.timeout
@@ -143,10 +140,13 @@ class XEP_0199(BasePlugin):
iq['from'] = ifrom
iq.enable('ping')
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
+ @asyncio.coroutine
def ping(self, jid=None, ifrom=None, timeout=None):
"""Send a ping request and calculate RTT.
+ This is a coroutine.
Arguments:
jid -- The JID that will receive the ping.
@@ -172,7 +172,8 @@ class XEP_0199(BasePlugin):
log.debug('Pinging %s' % jid)
try:
- self.send_ping(jid, ifrom=ifrom, timeout=timeout)
+ yield from self.send_ping(jid, ifrom=ifrom, timeout=timeout,
+ coroutine=True)
except IqError as e:
if own_host:
rtt = time.time() - start
diff --git a/sleekxmpp/plugins/xep_0199/stanza.py b/slixmpp/plugins/xep_0199/stanza.py
index 6586a763..425e891b 100644
--- a/sleekxmpp/plugins/xep_0199/stanza.py
+++ b/slixmpp/plugins/xep_0199/stanza.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-import sleekxmpp
-from sleekxmpp.xmlstream import ElementBase
+import slixmpp
+from slixmpp.xmlstream import ElementBase
class Ping(ElementBase):
diff --git a/slixmpp/plugins/xep_0202/__init__.py b/slixmpp/plugins/xep_0202/__init__.py
new file mode 100644
index 00000000..1197eabc
--- /dev/null
+++ b/slixmpp/plugins/xep_0202/__init__.py
@@ -0,0 +1,20 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0202 import stanza
+from slixmpp.plugins.xep_0202.stanza import EntityTime
+from slixmpp.plugins.xep_0202.time import XEP_0202
+
+
+register_plugin(XEP_0202)
+
+
+# Retain some backwards compatibility
+xep_0202 = XEP_0202
diff --git a/sleekxmpp/plugins/xep_0202/stanza.py b/slixmpp/plugins/xep_0202/stanza.py
index b6ccc960..c855663b 100644
--- a/sleekxmpp/plugins/xep_0202/stanza.py
+++ b/slixmpp/plugins/xep_0202/stanza.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,9 +9,9 @@
import logging
import datetime as dt
-from sleekxmpp.xmlstream import ElementBase
-from sleekxmpp.plugins import xep_0082
-from sleekxmpp.thirdparty import tzutc, tzoffset
+from slixmpp.xmlstream import ElementBase
+from slixmpp.plugins import xep_0082
+from slixmpp.thirdparty import tzutc, tzoffset
class EntityTime(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0202/time.py b/slixmpp/plugins/xep_0202/time.py
index 4e48eae8..185200fc 100644
--- a/sleekxmpp/plugins/xep_0202/time.py
+++ b/slixmpp/plugins/xep_0202/time.py
@@ -1,99 +1,99 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-
-import logging
-
-from sleekxmpp.stanza.iq import Iq
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins import xep_0082
-from sleekxmpp.plugins.xep_0202 import stanza
-
-
-log = logging.getLogger(__name__)
-
-
-class XEP_0202(BasePlugin):
-
- """
- XEP-0202: Entity Time
- """
-
- name = 'xep_0202'
- description = 'XEP-0202: Entity Time'
- dependencies = set(['xep_0030', 'xep_0082'])
- stanza = stanza
- default_config = {
- #: As a default, respond to time requests with the
- #: local time returned by XEP-0082. However, a
- #: custom function can be supplied which accepts
- #: the JID of the entity to query for the time.
- 'local_time': None,
- 'tz_offset': 0
- }
-
- def plugin_init(self):
- """Start the XEP-0203 plugin."""
-
- if not self.local_time:
- def default_local_time(jid):
- return xep_0082.datetime(offset=self.tz_offset)
-
- self.local_time = default_local_time
-
- self.xmpp.register_handler(
- Callback('Entity Time',
- StanzaPath('iq/entity_time'),
- self._handle_time_request))
- register_stanza_plugin(Iq, stanza.EntityTime)
-
- def plugin_end(self):
- self.xmpp['xep_0030'].del_feature(feature='urn:xmpp:time')
- self.xmpp.remove_handler('Entity Time')
-
- def session_bind(self, jid):
- self.xmpp['xep_0030'].add_feature('urn:xmpp:time')
-
- def _handle_time_request(self, iq):
- """
- Respond to a request for the local time.
-
- The time is taken from self.local_time(), which may be replaced
- during plugin configuration with a function that maps JIDs to
- times.
-
- Arguments:
- iq -- The Iq time request stanza.
- """
- if iq['type'] == 'get':
- iq.reply()
- iq['entity_time']['time'] = self.local_time(iq['to'])
- iq.send()
-
- def get_entity_time(self, to, ifrom=None, **iqargs):
- """
- Request the time from another entity.
-
- Arguments:
- to -- JID of the entity to query.
- ifrom -- Specifiy the sender's JID.
- block -- If true, block and wait for the stanzas' reply.
- timeout -- The time in seconds to block while waiting for
- a reply. If None, then wait indefinitely.
- callback -- Optional callback to execute when a reply is
- received instead of blocking and waiting for
- the reply.
- """
- iq = self.xmpp.Iq()
- iq['type'] = 'get'
- iq['to'] = to
- iq['from'] = ifrom
- iq.enable('entity_time')
- return iq.send(**iqargs)
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+import logging
+
+from slixmpp.stanza.iq import Iq
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins import xep_0082
+from slixmpp.plugins.xep_0202 import stanza
+
+
+log = logging.getLogger(__name__)
+
+
+class XEP_0202(BasePlugin):
+
+ """
+ XEP-0202: Entity Time
+ """
+
+ name = 'xep_0202'
+ description = 'XEP-0202: Entity Time'
+ dependencies = set(['xep_0030', 'xep_0082'])
+ stanza = stanza
+ default_config = {
+ #: As a default, respond to time requests with the
+ #: local time returned by XEP-0082. However, a
+ #: custom function can be supplied which accepts
+ #: the JID of the entity to query for the time.
+ 'local_time': None,
+ 'tz_offset': 0
+ }
+
+ def plugin_init(self):
+ """Start the XEP-0203 plugin."""
+
+ if not self.local_time:
+ def default_local_time(jid):
+ return xep_0082.datetime(offset=self.tz_offset)
+
+ self.local_time = default_local_time
+
+ self.xmpp.register_handler(
+ Callback('Entity Time',
+ StanzaPath('iq/entity_time'),
+ self._handle_time_request))
+ register_stanza_plugin(Iq, stanza.EntityTime)
+
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature='urn:xmpp:time')
+ self.xmpp.remove_handler('Entity Time')
+
+ def session_bind(self, jid):
+ self.xmpp['xep_0030'].add_feature('urn:xmpp:time')
+
+ def _handle_time_request(self, iq):
+ """
+ Respond to a request for the local time.
+
+ The time is taken from self.local_time(), which may be replaced
+ during plugin configuration with a function that maps JIDs to
+ times.
+
+ Arguments:
+ iq -- The Iq time request stanza.
+ """
+ iq = iq.reply()
+ iq['entity_time']['time'] = self.local_time(iq['to'])
+ iq.send()
+
+ def get_entity_time(self, to, ifrom=None, **iqargs):
+ """
+ Request the time from another entity.
+
+ Arguments:
+ to -- JID of the entity to query.
+ ifrom -- Specifiy the sender's JID.
+ block -- If true, block and wait for the stanzas' reply.
+ timeout -- The time in seconds to block while waiting for
+ a reply. If None, then wait indefinitely.
+ callback -- Optional callback to execute when a reply is
+ received instead of blocking and waiting for
+ the reply.
+ """
+ iq = self.xmpp.Iq()
+ iq['type'] = 'get'
+ iq['to'] = to
+ iq['from'] = ifrom
+ iq.enable('entity_time')
+ return iq.send(**iqargs)
+
diff --git a/slixmpp/plugins/xep_0203/__init__.py b/slixmpp/plugins/xep_0203/__init__.py
new file mode 100644
index 00000000..59cb7af2
--- /dev/null
+++ b/slixmpp/plugins/xep_0203/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0203 import stanza
+from slixmpp.plugins.xep_0203.stanza import Delay
+from slixmpp.plugins.xep_0203.delay import XEP_0203
+
+
+register_plugin(XEP_0203)
+
+# Retain some backwards compatibility
+xep_0203 = XEP_0203
diff --git a/sleekxmpp/plugins/xep_0203/delay.py b/slixmpp/plugins/xep_0203/delay.py
index 31f31ce3..725003e2 100644
--- a/sleekxmpp/plugins/xep_0203/delay.py
+++ b/slixmpp/plugins/xep_0203/delay.py
@@ -1,16 +1,16 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza import Message, Presence
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0203 import stanza
+from slixmpp.stanza import Message, Presence
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0203 import stanza
class XEP_0203(BasePlugin):
diff --git a/sleekxmpp/plugins/xep_0203/stanza.py b/slixmpp/plugins/xep_0203/stanza.py
index e147e975..de907c69 100644
--- a/sleekxmpp/plugins/xep_0203/stanza.py
+++ b/slixmpp/plugins/xep_0203/stanza.py
@@ -1,16 +1,16 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import datetime as dt
-from sleekxmpp.jid import JID
-from sleekxmpp.xmlstream import ElementBase
-from sleekxmpp.plugins import xep_0082
+from slixmpp.jid import JID
+from slixmpp.xmlstream import ElementBase
+from slixmpp.plugins import xep_0082
class Delay(ElementBase):
diff --git a/slixmpp/plugins/xep_0221/__init__.py b/slixmpp/plugins/xep_0221/__init__.py
new file mode 100644
index 00000000..b977acc7
--- /dev/null
+++ b/slixmpp/plugins/xep_0221/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0221 import stanza
+from slixmpp.plugins.xep_0221.stanza import Media, URI
+from slixmpp.plugins.xep_0221.media import XEP_0221
+
+
+register_plugin(XEP_0221)
diff --git a/sleekxmpp/plugins/xep_0221/media.py b/slixmpp/plugins/xep_0221/media.py
index c4b4a90f..4c34fbd2 100644
--- a/sleekxmpp/plugins/xep_0221/media.py
+++ b/slixmpp/plugins/xep_0221/media.py
@@ -1,17 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0221 import stanza, Media, URI
-from sleekxmpp.plugins.xep_0004 import FormField
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.xep_0221 import stanza, Media, URI
+from slixmpp.plugins.xep_0004 import FormField
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/plugins/xep_0221/stanza.py b/slixmpp/plugins/xep_0221/stanza.py
index 915ab380..2a2bbabd 100644
--- a/sleekxmpp/plugins/xep_0221/stanza.py
+++ b/slixmpp/plugins/xep_0221/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, register_stanza_plugin
+from slixmpp.xmlstream import ElementBase, register_stanza_plugin
class Media(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0222.py b/slixmpp/plugins/xep_0222.py
index 2cc7f703..059f4c85 100644
--- a/sleekxmpp/plugins/xep_0222.py
+++ b/slixmpp/plugins/xep_0222.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.base import BasePlugin, register_plugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.base import BasePlugin, register_plugin
log = logging.getLogger(__name__)
@@ -40,12 +40,11 @@ class XEP_0222(BasePlugin):
return self.xmpp['xep_0060'].set_node_config(None, node, config,
ifrom=ifrom,
- block=block,
callback=callback,
timeout=timeout)
def store(self, stanza, node=None, id=None, ifrom=None, options=None,
- block=True, callback=None, timeout=None):
+ callback=None, timeout=None):
"""
Store public data via PEP.
@@ -60,11 +59,9 @@ class XEP_0222(BasePlugin):
options -- Publish options to use, which will be modified to
fit the persistent storage option profile.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -85,12 +82,11 @@ class XEP_0222(BasePlugin):
return self.xmpp['xep_0163'].publish(stanza, node,
options=options,
ifrom=ifrom,
- block=block,
callback=callback,
timeout=timeout)
def retrieve(self, node, id=None, item_ids=None, ifrom=None,
- block=True, callback=None, timeout=None):
+ callback=None, timeout=None):
"""
Retrieve public data via PEP.
@@ -103,11 +99,9 @@ class XEP_0222(BasePlugin):
item_ids -- Specify a group of IDs. If id is also specified, it
will be included in item_ids.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -119,7 +113,6 @@ class XEP_0222(BasePlugin):
return self.xmpp['xep_0060'].get_items(None, node,
item_ids=item_ids,
ifrom=ifrom,
- block=block,
callback=callback,
timeout=timeout)
diff --git a/sleekxmpp/plugins/xep_0223.py b/slixmpp/plugins/xep_0223.py
index abbecfc7..2461bb20 100644
--- a/sleekxmpp/plugins/xep_0223.py
+++ b/slixmpp/plugins/xep_0223.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.base import BasePlugin, register_plugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.base import BasePlugin, register_plugin
log = logging.getLogger(__name__)
@@ -32,6 +32,7 @@ class XEP_0223(BasePlugin):
"""
Update a node's configuration to match the public storage profile.
"""
+ # TODO: that cannot possibly work, why is this here?
config = self.xmpp['xep_0004'].Form()
config['type'] = 'submit'
@@ -39,13 +40,12 @@ class XEP_0223(BasePlugin):
config.add_field(var=field, value=value)
return self.xmpp['xep_0060'].set_node_config(None, node, config,
- ifrom=ifrom,
- block=block,
- callback=callback,
- timeout=timeout)
+ ifrom=ifrom,
+ callback=callback,
+ timeout=timeout)
def store(self, stanza, node=None, id=None, ifrom=None, options=None,
- block=True, callback=None, timeout=None):
+ callback=None, timeout=None, timeout_callback=None):
"""
Store private data via PEP.
@@ -60,11 +60,9 @@ class XEP_0223(BasePlugin):
options -- Publish options to use, which will be modified to
fit the persistent storage option profile.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -82,15 +80,13 @@ class XEP_0223(BasePlugin):
options.add_field(var=field)
options['fields'][field]['value'] = value
- return self.xmpp['xep_0163'].publish(stanza, node,
- options=options,
- ifrom=ifrom,
- block=block,
- callback=callback,
- timeout=timeout)
+ return self.xmpp['xep_0163'].publish(stanza, node, options=options,
+ ifrom=ifrom, callback=callback,
+ timeout=timeout,
+ timeout_callback=timeout_callback)
def retrieve(self, node, id=None, item_ids=None, ifrom=None,
- block=True, callback=None, timeout=None):
+ callback=None, timeout=None, timeout_callback=None):
"""
Retrieve private data via PEP.
@@ -103,11 +99,9 @@ class XEP_0223(BasePlugin):
item_ids -- Specify a group of IDs. If id is also specified, it
will be included in item_ids.
ifrom -- Specify the sender's JID.
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait for a response
before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
+ Defaults to slixmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler function. Will
be executed when a reply stanza is received.
"""
@@ -117,11 +111,9 @@ class XEP_0223(BasePlugin):
item_ids.append(id)
return self.xmpp['xep_0060'].get_items(None, node,
- item_ids=item_ids,
- ifrom=ifrom,
- block=block,
- callback=callback,
- timeout=timeout)
+ item_ids=item_ids, ifrom=ifrom,
+ callback=callback, timeout=timeout,
+ timeout_callback=timeout_callback)
register_plugin(XEP_0223)
diff --git a/slixmpp/plugins/xep_0224/__init__.py b/slixmpp/plugins/xep_0224/__init__.py
new file mode 100644
index 00000000..4fadfd70
--- /dev/null
+++ b/slixmpp/plugins/xep_0224/__init__.py
@@ -0,0 +1,20 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0224 import stanza
+from slixmpp.plugins.xep_0224.stanza import Attention
+from slixmpp.plugins.xep_0224.attention import XEP_0224
+
+
+register_plugin(XEP_0224)
+
+
+# Retain some backwards compatibility
+xep_0224 = XEP_0224
diff --git a/sleekxmpp/plugins/xep_0224/attention.py b/slixmpp/plugins/xep_0224/attention.py
index 4e560604..2777e1b0 100644
--- a/sleekxmpp/plugins/xep_0224/attention.py
+++ b/slixmpp/plugins/xep_0224/attention.py
@@ -1,19 +1,19 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.stanza import Message
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0224 import stanza
+from slixmpp.stanza import Message
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0224 import stanza
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/plugins/xep_0224/stanza.py b/slixmpp/plugins/xep_0224/stanza.py
index f15172d9..2b77dadd 100644
--- a/sleekxmpp/plugins/xep_0224/stanza.py
+++ b/slixmpp/plugins/xep_0224/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class Attention(ElementBase):
diff --git a/slixmpp/plugins/xep_0231/__init__.py b/slixmpp/plugins/xep_0231/__init__.py
new file mode 100644
index 00000000..57d57846
--- /dev/null
+++ b/slixmpp/plugins/xep_0231/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz,
+ Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0231.stanza import BitsOfBinary
+from slixmpp.plugins.xep_0231.bob import XEP_0231
+
+
+register_plugin(XEP_0231)
diff --git a/sleekxmpp/plugins/xep_0231/bob.py b/slixmpp/plugins/xep_0231/bob.py
index 5e1f590b..a3b5edd4 100644
--- a/sleekxmpp/plugins/xep_0231/bob.py
+++ b/slixmpp/plugins/xep_0231/bob.py
@@ -1,8 +1,8 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz,
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -10,13 +10,14 @@
import logging
import hashlib
-from sleekxmpp.stanza import Iq, Message, Presence
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.plugins.xep_0231 import stanza, BitsOfBinary
+from slixmpp import future_wrapper
+from slixmpp.stanza import Iq, Message, Presence
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.plugins.xep_0231 import stanza, BitsOfBinary
log = logging.getLogger(__name__)
@@ -81,8 +82,9 @@ class XEP_0231(BasePlugin):
return cid
+ @future_wrapper
def get_bob(self, jid=None, cid=None, cached=True, ifrom=None,
- block=True, timeout=None, callback=None):
+ timeout=None, callback=None):
if cached:
data = self.api['get_bob'](None, None, ifrom, args=cid)
if data is not None:
@@ -97,7 +99,7 @@ class XEP_0231(BasePlugin):
iq['from'] = ifrom
iq['type'] = 'get'
iq['bob']['cid'] = cid
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout=timeout, callback=callback)
def del_bob(self, cid):
self.api['del_bob'](args=cid)
@@ -115,7 +117,7 @@ class XEP_0231(BasePlugin):
data.send()
return
- iq.reply()
+ iq = iq.reply()
iq.append(data)
iq.send()
@@ -132,8 +134,7 @@ class XEP_0231(BasePlugin):
def _get_bob(self, jid, node, ifrom, cid):
if cid in self._cids:
return self._cids[cid]
- else:
- raise XMPPError('item-not-found')
+ raise XMPPError('item-not-found')
def _del_bob(self, jid, node, ifrom, cid):
if cid in self._cids:
diff --git a/sleekxmpp/plugins/xep_0231/stanza.py b/slixmpp/plugins/xep_0231/stanza.py
index 8bf0d6ee..b3b96eff 100644
--- a/sleekxmpp/plugins/xep_0231/stanza.py
+++ b/slixmpp/plugins/xep_0231/stanza.py
@@ -1,8 +1,8 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz,
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -10,8 +10,8 @@
import base64
-from sleekxmpp.util import bytes
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.util import bytes
+from slixmpp.xmlstream import ElementBase
class BitsOfBinary(ElementBase):
@@ -21,10 +21,10 @@ class BitsOfBinary(ElementBase):
interfaces = set(('cid', 'max_age', 'type', 'data'))
def get_max_age(self):
- return self._get_attr('max-age')
+ return int(self._get_attr('max-age'))
def set_max_age(self, value):
- self._set_attr('max-age', value)
+ self._set_attr('max-age', str(value))
def get_data(self):
return base64.b64decode(bytes(self.xml.text))
diff --git a/slixmpp/plugins/xep_0235/__init__.py b/slixmpp/plugins/xep_0235/__init__.py
new file mode 100644
index 00000000..8810a84d
--- /dev/null
+++ b/slixmpp/plugins/xep_0235/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0235 import stanza
+from slixmpp.plugins.xep_0235.stanza import OAuth
+from slixmpp.plugins.xep_0235.oauth import XEP_0235
+
+
+register_plugin(XEP_0235)
diff --git a/sleekxmpp/plugins/xep_0235/oauth.py b/slixmpp/plugins/xep_0235/oauth.py
index df0e2ebf..bcd220b0 100644
--- a/sleekxmpp/plugins/xep_0235/oauth.py
+++ b/slixmpp/plugins/xep_0235/oauth.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,10 +9,10 @@
import logging
-from sleekxmpp import Message
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0235 import stanza, OAuth
+from slixmpp import Message
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.xep_0235 import stanza, OAuth
class XEP_0235(BasePlugin):
diff --git a/sleekxmpp/plugins/xep_0235/stanza.py b/slixmpp/plugins/xep_0235/stanza.py
index 0050d583..abb4a38d 100644
--- a/sleekxmpp/plugins/xep_0235/stanza.py
+++ b/slixmpp/plugins/xep_0235/stanza.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -11,7 +11,7 @@ import hashlib
import urllib
import base64
-from sleekxmpp.xmlstream import ET, ElementBase, JID
+from slixmpp.xmlstream import ET, ElementBase, JID
class OAuth(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0242.py b/slixmpp/plugins/xep_0242.py
index c1bada27..ea077a70 100644
--- a/sleekxmpp/plugins/xep_0242.py
+++ b/slixmpp/plugins/xep_0242.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins import BasePlugin, register_plugin
+from slixmpp.plugins import BasePlugin, register_plugin
class XEP_0242(BasePlugin):
diff --git a/slixmpp/plugins/xep_0249/__init__.py b/slixmpp/plugins/xep_0249/__init__.py
new file mode 100644
index 00000000..5d120ec6
--- /dev/null
+++ b/slixmpp/plugins/xep_0249/__init__.py
@@ -0,0 +1,19 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2011 Nathanael C. Fritz, Dalek
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0249.stanza import Invite
+from slixmpp.plugins.xep_0249.invite import XEP_0249
+
+
+register_plugin(XEP_0249)
+
+
+# Retain some backwards compatibility
+xep_0249 = XEP_0249
diff --git a/sleekxmpp/plugins/xep_0249/invite.py b/slixmpp/plugins/xep_0249/invite.py
index 4b7abd4a..fe5f5884 100644
--- a/sleekxmpp/plugins/xep_0249/invite.py
+++ b/slixmpp/plugins/xep_0249/invite.py
@@ -1,20 +1,20 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Dalek
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-import sleekxmpp
-from sleekxmpp import Message
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins.xep_0249 import Invite, stanza
+import slixmpp
+from slixmpp import Message
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins.xep_0249 import Invite, stanza
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/plugins/xep_0249/stanza.py b/slixmpp/plugins/xep_0249/stanza.py
index ba4060d7..5979f091 100644
--- a/sleekxmpp/plugins/xep_0249/stanza.py
+++ b/slixmpp/plugins/xep_0249/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Dalek
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class Invite(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0256.py b/slixmpp/plugins/xep_0256.py
index 0db8ea3b..4ad4f0ea 100644
--- a/sleekxmpp/plugins/xep_0256.py
+++ b/slixmpp/plugins/xep_0256.py
@@ -1,19 +1,19 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp import Presence
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.plugins import BasePlugin, register_plugin
-from sleekxmpp.xmlstream import register_stanza_plugin
+from slixmpp import Presence
+from slixmpp.exceptions import XMPPError
+from slixmpp.plugins import BasePlugin, register_plugin
+from slixmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0012 import stanza, LastActivity
+from slixmpp.plugins.xep_0012 import stanza, LastActivity
log = logging.getLogger(__name__)
diff --git a/slixmpp/plugins/xep_0257/__init__.py b/slixmpp/plugins/xep_0257/__init__.py
new file mode 100644
index 00000000..2621ad8f
--- /dev/null
+++ b/slixmpp/plugins/xep_0257/__init__.py
@@ -0,0 +1,17 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0257 import stanza
+from slixmpp.plugins.xep_0257.stanza import Certs, AppendCert
+from slixmpp.plugins.xep_0257.stanza import DisableCert, RevokeCert
+from slixmpp.plugins.xep_0257.client_cert_management import XEP_0257
+
+
+register_plugin(XEP_0257)
diff --git a/slixmpp/plugins/xep_0257/client_cert_management.py b/slixmpp/plugins/xep_0257/client_cert_management.py
new file mode 100644
index 00000000..a6d07506
--- /dev/null
+++ b/slixmpp/plugins/xep_0257/client_cert_management.py
@@ -0,0 +1,70 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+import logging
+
+from slixmpp import Iq
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.xep_0257 import stanza, Certs
+from slixmpp.plugins.xep_0257 import AppendCert, DisableCert, RevokeCert
+
+
+log = logging.getLogger(__name__)
+
+
+class XEP_0257(BasePlugin):
+
+ name = 'xep_0257'
+ description = 'XEP-0257: Client Certificate Management for SASL EXTERNAL'
+ dependencies = set(['xep_0030'])
+ stanza = stanza
+
+ def plugin_init(self):
+ register_stanza_plugin(Iq, Certs)
+ register_stanza_plugin(Iq, AppendCert)
+ register_stanza_plugin(Iq, DisableCert)
+ register_stanza_plugin(Iq, RevokeCert)
+
+ def get_certs(self, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'get'
+ iq['from'] = ifrom
+ iq.enable('sasl_certs')
+ return iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
+
+ def add_cert(self, name, cert, allow_management=True, ifrom=None,
+ timeout=None, callback=None, timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'set'
+ iq['from'] = ifrom
+ iq['sasl_cert_append']['name'] = name
+ iq['sasl_cert_append']['x509cert'] = cert
+ iq['sasl_cert_append']['cert_management'] = allow_management
+ return iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
+
+ def disable_cert(self, name, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'set'
+ iq['from'] = ifrom
+ iq['sasl_cert_disable']['name'] = name
+ return iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
+
+ def revoke_cert(self, name, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'set'
+ iq['from'] = ifrom
+ iq['sasl_cert_revoke']['name'] = name
+ return iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
diff --git a/sleekxmpp/plugins/xep_0257/stanza.py b/slixmpp/plugins/xep_0257/stanza.py
index c3c41db2..86b63451 100644
--- a/sleekxmpp/plugins/xep_0257/stanza.py
+++ b/slixmpp/plugins/xep_0257/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin
+from slixmpp.xmlstream import ElementBase, ET, register_stanza_plugin
class Certs(ElementBase):
diff --git a/slixmpp/plugins/xep_0258/__init__.py b/slixmpp/plugins/xep_0258/__init__.py
new file mode 100644
index 00000000..7210072d
--- /dev/null
+++ b/slixmpp/plugins/xep_0258/__init__.py
@@ -0,0 +1,18 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0258 import stanza
+from slixmpp.plugins.xep_0258.stanza import SecurityLabel, Label
+from slixmpp.plugins.xep_0258.stanza import DisplayMarking, EquivalentLabel
+from slixmpp.plugins.xep_0258.stanza import ESSLabel, Catalog, CatalogItem
+from slixmpp.plugins.xep_0258.security_labels import XEP_0258
+
+
+register_plugin(XEP_0258)
diff --git a/sleekxmpp/plugins/xep_0258/security_labels.py b/slixmpp/plugins/xep_0258/security_labels.py
index 439143c1..2fb048c7 100644
--- a/sleekxmpp/plugins/xep_0258/security_labels.py
+++ b/slixmpp/plugins/xep_0258/security_labels.py
@@ -1,17 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp import Iq, Message
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0258 import stanza, SecurityLabel, Catalog
+from slixmpp import Iq, Message
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.xep_0258 import stanza, SecurityLabel, Catalog
log = logging.getLogger(__name__)
@@ -34,11 +34,11 @@ class XEP_0258(BasePlugin):
def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature(SecurityLabel.namespace)
- def get_catalog(self, jid, ifrom=None, block=True,
+ def get_catalog(self, jid, ifrom=None,
callback=None, timeout=None):
iq = self.xmpp.Iq()
iq['to'] = jid
iq['from'] = ifrom
iq['type'] = 'get'
iq.enable('security_label_catalog')
- return iq.send(block=block, callback=callback, timeout=timeout)
+ return iq.send(callback=callback, timeout=timeout)
diff --git a/sleekxmpp/plugins/xep_0258/stanza.py b/slixmpp/plugins/xep_0258/stanza.py
index a506064b..e47bd34f 100644
--- a/sleekxmpp/plugins/xep_0258/stanza.py
+++ b/slixmpp/plugins/xep_0258/stanza.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from base64 import b64encode, b64decode
-from sleekxmpp.util import bytes
-from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin
+from slixmpp.util import bytes
+from slixmpp.xmlstream import ElementBase, ET, register_stanza_plugin
class SecurityLabel(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0270.py b/slixmpp/plugins/xep_0270.py
index eadd45ad..4d02a0a1 100644
--- a/sleekxmpp/plugins/xep_0270.py
+++ b/slixmpp/plugins/xep_0270.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins import BasePlugin, register_plugin
+from slixmpp.plugins import BasePlugin, register_plugin
class XEP_0270(BasePlugin):
diff --git a/slixmpp/plugins/xep_0279/__init__.py b/slixmpp/plugins/xep_0279/__init__.py
new file mode 100644
index 00000000..45fd3af0
--- /dev/null
+++ b/slixmpp/plugins/xep_0279/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0279 import stanza
+from slixmpp.plugins.xep_0279.stanza import IPCheck
+from slixmpp.plugins.xep_0279.ipcheck import XEP_0279
+
+
+register_plugin(XEP_0279)
diff --git a/sleekxmpp/plugins/xep_0279/ipcheck.py b/slixmpp/plugins/xep_0279/ipcheck.py
index f8c167c7..e8cea46f 100644
--- a/sleekxmpp/plugins/xep_0279/ipcheck.py
+++ b/slixmpp/plugins/xep_0279/ipcheck.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,10 +9,10 @@
import logging
-from sleekxmpp import Iq
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0279 import stanza, IPCheck
+from slixmpp import Iq
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.xep_0279 import stanza, IPCheck
class XEP_0279(BasePlugin):
@@ -31,9 +31,11 @@ class XEP_0279(BasePlugin):
def plugin_end(self):
self.xmpp['xep_0030'].del_feature(feature='urn:xmpp:sic:0')
- def check_ip(self, ifrom=None, block=True, timeout=None, callback=None):
+ def check_ip(self, ifrom=None, block=True, timeout=None, callback=None,
+ timeout_callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'get'
iq['from'] = ifrom
iq.enable('ip_check')
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(block=block, timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
diff --git a/sleekxmpp/plugins/xep_0279/stanza.py b/slixmpp/plugins/xep_0279/stanza.py
index 181b5957..f80623cd 100644
--- a/sleekxmpp/plugins/xep_0279/stanza.py
+++ b/slixmpp/plugins/xep_0279/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class IPCheck(ElementBase):
diff --git a/slixmpp/plugins/xep_0280/__init__.py b/slixmpp/plugins/xep_0280/__init__.py
new file mode 100644
index 00000000..ed9a19ef
--- /dev/null
+++ b/slixmpp/plugins/xep_0280/__init__.py
@@ -0,0 +1,17 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permissio
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0280.stanza import ReceivedCarbon, SentCarbon
+from slixmpp.plugins.xep_0280.stanza import PrivateCarbon
+from slixmpp.plugins.xep_0280.stanza import CarbonEnable, CarbonDisable
+from slixmpp.plugins.xep_0280.carbons import XEP_0280
+
+
+register_plugin(XEP_0280)
diff --git a/sleekxmpp/plugins/xep_0280/carbons.py b/slixmpp/plugins/xep_0280/carbons.py
index 482d046a..a64ccbfd 100644
--- a/sleekxmpp/plugins/xep_0280/carbons.py
+++ b/slixmpp/plugins/xep_0280/carbons.py
@@ -1,20 +1,20 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permissio
"""
import logging
-import sleekxmpp
-from sleekxmpp.stanza import Message, Iq
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0280 import stanza
+import slixmpp
+from slixmpp.stanza import Message, Iq
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0280 import stanza
log = logging.getLogger(__name__)
@@ -66,16 +66,20 @@ class XEP_0280(BasePlugin):
def _handle_carbon_sent(self, msg):
self.xmpp.event('carbon_sent', msg)
- def enable(self, ifrom=None, block=True, timeout=None, callback=None):
+ def enable(self, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq['from'] = ifrom
iq.enable('carbon_enable')
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout_callback=timeout_callback, timeout=timeout,
+ callback=callback)
- def disable(self, ifrom=None, block=True, timeout=None, callback=None):
+ def disable(self, ifrom=None, timeout=None, callback=None,
+ timeout_callback=None):
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq['from'] = ifrom
iq.enable('carbon_disable')
- return iq.send(block=block, timeout=timeout, callback=callback)
+ return iq.send(timeout_callback=timeout_callback, timeout=timeout,
+ callback=callback)
diff --git a/sleekxmpp/plugins/xep_0280/stanza.py b/slixmpp/plugins/xep_0280/stanza.py
index 2f3aad86..46276189 100644
--- a/sleekxmpp/plugins/xep_0280/stanza.py
+++ b/slixmpp/plugins/xep_0280/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permissio
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class ReceivedCarbon(ElementBase):
diff --git a/slixmpp/plugins/xep_0297/__init__.py b/slixmpp/plugins/xep_0297/__init__.py
new file mode 100644
index 00000000..8d7adb63
--- /dev/null
+++ b/slixmpp/plugins/xep_0297/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0297 import stanza
+from slixmpp.plugins.xep_0297.stanza import Forwarded
+from slixmpp.plugins.xep_0297.forwarded import XEP_0297
+
+
+register_plugin(XEP_0297)
diff --git a/sleekxmpp/plugins/xep_0297/forwarded.py b/slixmpp/plugins/xep_0297/forwarded.py
index 95703a2d..7c40bf30 100644
--- a/sleekxmpp/plugins/xep_0297/forwarded.py
+++ b/slixmpp/plugins/xep_0297/forwarded.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,12 +9,12 @@
import logging
-from sleekxmpp import Iq, Message, Presence
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins.xep_0297 import stanza, Forwarded
+from slixmpp import Iq, Message, Presence
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins.xep_0297 import stanza, Forwarded
class XEP_0297(BasePlugin):
diff --git a/sleekxmpp/plugins/xep_0297/stanza.py b/slixmpp/plugins/xep_0297/stanza.py
index 8b97accc..233ad4f6 100644
--- a/sleekxmpp/plugins/xep_0297/stanza.py
+++ b/slixmpp/plugins/xep_0297/stanza.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza import Message, Presence, Iq
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.stanza import Message, Presence, Iq
+from slixmpp.xmlstream import ElementBase
class Forwarded(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0302.py b/slixmpp/plugins/xep_0302.py
index dee60f91..6092b3e3 100644
--- a/sleekxmpp/plugins/xep_0302.py
+++ b/slixmpp/plugins/xep_0302.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins import BasePlugin, register_plugin
+from slixmpp.plugins import BasePlugin, register_plugin
class XEP_0302(BasePlugin):
diff --git a/slixmpp/plugins/xep_0308/__init__.py b/slixmpp/plugins/xep_0308/__init__.py
new file mode 100644
index 00000000..147cbd4b
--- /dev/null
+++ b/slixmpp/plugins/xep_0308/__init__.py
@@ -0,0 +1,15 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permissio
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0308.stanza import Replace
+from slixmpp.plugins.xep_0308.correction import XEP_0308
+
+
+register_plugin(XEP_0308)
diff --git a/sleekxmpp/plugins/xep_0308/correction.py b/slixmpp/plugins/xep_0308/correction.py
index d32b4bc4..3802b799 100644
--- a/sleekxmpp/plugins/xep_0308/correction.py
+++ b/slixmpp/plugins/xep_0308/correction.py
@@ -1,20 +1,20 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permissio
"""
import logging
-import sleekxmpp
-from sleekxmpp.stanza import Message
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0308 import stanza, Replace
+import slixmpp
+from slixmpp.stanza import Message
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0308 import stanza, Replace
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/plugins/xep_0308/stanza.py b/slixmpp/plugins/xep_0308/stanza.py
index 8f88cbc0..eb04d1ad 100644
--- a/sleekxmpp/plugins/xep_0308/stanza.py
+++ b/slixmpp/plugins/xep_0308/stanza.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permissio
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class Replace(ElementBase):
diff --git a/slixmpp/plugins/xep_0313/__init__.py b/slixmpp/plugins/xep_0313/__init__.py
new file mode 100644
index 00000000..42d9025a
--- /dev/null
+++ b/slixmpp/plugins/xep_0313/__init__.py
@@ -0,0 +1,15 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permissio
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0313.stanza import Result, MAM, Preferences
+from slixmpp.plugins.xep_0313.mam import XEP_0313
+
+
+register_plugin(XEP_0313)
diff --git a/sleekxmpp/plugins/xep_0313/mam.py b/slixmpp/plugins/xep_0313/mam.py
index 4b82ca03..d1c6b983 100644
--- a/sleekxmpp/plugins/xep_0313/mam.py
+++ b/slixmpp/plugins/xep_0313/mam.py
@@ -1,21 +1,21 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permissio
"""
import logging
-import sleekxmpp
-from sleekxmpp.stanza import Message, Iq
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.xmlstream.handler import Collector
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.plugins.xep_0313 import stanza
+import slixmpp
+from slixmpp.stanza import Message, Iq
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream.handler import Collector
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.plugins.xep_0313 import stanza
log = logging.getLogger(__name__)
@@ -41,7 +41,7 @@ class XEP_0313(BasePlugin):
register_stanza_plugin(stanza.MAM, self.xmpp['xep_0059'].stanza.Set)
def retrieve(self, jid=None, start=None, end=None, with_jid=None, ifrom=None,
- block=True, timeout=None, callback=None, iterator=False):
+ timeout=None, callback=None, iterator=False):
iq = self.xmpp.Iq()
query_id = iq['id']
@@ -60,21 +60,12 @@ class XEP_0313(BasePlugin):
if iterator:
return self.xmpp['xep_0059'].iterate(iq, 'mam', 'results')
- elif not block and callback is not None:
- def wrapped_cb(iq):
- results = collector.stop()
- if iq['type'] == 'result':
- iq['mam']['results'] = results
- callback(iq)
- return iq.send(block=block, timeout=timeout, callback=wrapped_cb)
- else:
- try:
- resp = iq.send(block=block, timeout=timeout, callback=callback)
- resp['mam']['results'] = collector.stop()
- return resp
- except XMPPError as e:
- collector.stop()
- raise e
+ def wrapped_cb(iq):
+ results = collector.stop()
+ if iq['type'] == 'result':
+ iq['mam']['results'] = results
+ callback(iq)
+ return iq.send(timeout=timeout, callback=wrapped_cb)
def set_preferences(self, jid=None, default=None, always=None, never=None,
ifrom=None, block=True, timeout=None, callback=None):
diff --git a/sleekxmpp/plugins/xep_0313/stanza.py b/slixmpp/plugins/xep_0313/stanza.py
index 81576cd4..d7cfa222 100644
--- a/sleekxmpp/plugins/xep_0313/stanza.py
+++ b/slixmpp/plugins/xep_0313/stanza.py
@@ -1,16 +1,16 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permissio
"""
import datetime as dt
-from sleekxmpp.jid import JID
-from sleekxmpp.xmlstream import ElementBase, ET
-from sleekxmpp.plugins import xep_0082
+from slixmpp.jid import JID
+from slixmpp.xmlstream import ElementBase, ET
+from slixmpp.plugins import xep_0082
class MAM(ElementBase):
diff --git a/slixmpp/plugins/xep_0319/__init__.py b/slixmpp/plugins/xep_0319/__init__.py
new file mode 100644
index 00000000..a9253b49
--- /dev/null
+++ b/slixmpp/plugins/xep_0319/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.base import register_plugin
+
+from slixmpp.plugins.xep_0319 import stanza
+from slixmpp.plugins.xep_0319.stanza import Idle
+from slixmpp.plugins.xep_0319.idle import XEP_0319
+
+
+register_plugin(XEP_0319)
diff --git a/sleekxmpp/plugins/xep_0319/idle.py b/slixmpp/plugins/xep_0319/idle.py
index 90456f9f..1fd980a5 100644
--- a/sleekxmpp/plugins/xep_0319/idle.py
+++ b/slixmpp/plugins/xep_0319/idle.py
@@ -1,19 +1,19 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from datetime import datetime, timedelta
-from sleekxmpp.stanza import Presence
-from sleekxmpp.plugins import BasePlugin
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins.xep_0319 import stanza
+from slixmpp.stanza import Presence
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins.xep_0319 import stanza
class XEP_0319(BasePlugin):
diff --git a/sleekxmpp/plugins/xep_0319/stanza.py b/slixmpp/plugins/xep_0319/stanza.py
index abfb4f41..ea70087b 100644
--- a/sleekxmpp/plugins/xep_0319/stanza.py
+++ b/slixmpp/plugins/xep_0319/stanza.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import datetime as dt
-from sleekxmpp.xmlstream import ElementBase
-from sleekxmpp.plugins import xep_0082
+from slixmpp.xmlstream import ElementBase
+from slixmpp.plugins import xep_0082
class Idle(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0323/__init__.py b/slixmpp/plugins/xep_0323/__init__.py
index 10779ada..6bf42fd6 100644
--- a/sleekxmpp/plugins/xep_0323/__init__.py
+++ b/slixmpp/plugins/xep_0323/__init__.py
@@ -1,17 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins.base import register_plugin
+from slixmpp.plugins.base import register_plugin
-from sleekxmpp.plugins.xep_0323.sensordata import XEP_0323
-from sleekxmpp.plugins.xep_0323 import stanza
+from slixmpp.plugins.xep_0323.sensordata import XEP_0323
+from slixmpp.plugins.xep_0323 import stanza
register_plugin(XEP_0323)
diff --git a/sleekxmpp/plugins/xep_0323/device.py b/slixmpp/plugins/xep_0323/device.py
index 80e6fd95..994fc5ce 100644
--- a/sleekxmpp/plugins/xep_0323/device.py
+++ b/slixmpp/plugins/xep_0323/device.py
@@ -1,9 +1,9 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -30,7 +30,7 @@ class Device(object):
# {'type':'numeric',
# 'name':'myname',
# 'value': 42,
- # 'unit':'Z'}];
+ # 'unit':'Z'}]
self.timestamp_data = {}
self.momentary_data = {}
self.momentary_timestamp = ""
diff --git a/sleekxmpp/plugins/xep_0323/sensordata.py b/slixmpp/plugins/xep_0323/sensordata.py
index a3d4cf34..c88deee9 100644
--- a/sleekxmpp/plugins/xep_0323/sensordata.py
+++ b/slixmpp/plugins/xep_0323/sensordata.py
@@ -1,9 +1,9 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -13,14 +13,14 @@ import time
import datetime
from threading import Thread, Lock, Timer
-from sleekxmpp.plugins.xep_0323.timerreset import TimerReset
-
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.plugins.xep_0323 import stanza
-from sleekxmpp.plugins.xep_0323.stanza import Sensordata
+from slixmpp.plugins.xep_0323.timerreset import TimerReset
+from slixmpp.xmlstream import JID
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.plugins.xep_0323 import stanza
+from slixmpp.plugins.xep_0323.stanza import Sensordata
log = logging.getLogger(__name__)
@@ -82,9 +82,9 @@ class XEP_0323(BasePlugin):
sequence number (unique between the client/sensor pair)
Methods:
- plugin_init -- Overrides base_plugin.plugin_init
- post_init -- Overrides base_plugin.post_init
- plugin_end -- Overrides base_plugin.plugin_end
+ plugin_init -- Overrides BasePlugin.plugin_init
+ post_init -- Overrides BasePlugin.post_init
+ plugin_end -- Overrides BasePlugin.plugin_end
Sensor side
-----------
@@ -299,11 +299,11 @@ class XEP_0323(BasePlugin):
self.sessions[session]["commTimers"] = {}
self.sessions[session]["nodeDone"] = {}
- iq.reply()
+ iq = iq.reply()
iq['accepted']['seqnr'] = seqnr
if not request_delay_sec is None:
iq['accepted']['queued'] = "true"
- iq.send(block=False)
+ iq.send()
self.sessions[session]["node_list"] = process_nodes
@@ -321,11 +321,11 @@ class XEP_0323(BasePlugin):
self._threaded_node_request(session, process_fields, req_flags)
else:
- iq.reply()
+ iq = iq.reply()
iq['type'] = 'error'
iq['rejected']['seqnr'] = seqnr
iq['rejected']['error'] = error_msg
- iq.send(block=False)
+ iq.send()
def _threaded_node_request(self, session, process_fields, flags):
"""
@@ -505,21 +505,21 @@ class XEP_0323(BasePlugin):
self.sessions[s]["commTimers"][n].cancel()
# Confirm
- iq.reply()
+ iq = iq.reply()
iq['type'] = 'result'
iq['cancelled']['seqnr'] = seqnr
- iq.send(block=False)
+ iq.send()
# Delete session
del self.sessions[s]
return
# Could not find session, send reject
- iq.reply()
+ iq = iq.reply()
iq['type'] = 'error'
iq['rejected']['seqnr'] = seqnr
iq['rejected']['error'] = "Cancel request received, no matching request is active."
- iq.send(block=False)
+ iq.send()
# =================================================================
# Client side (data retriever) API
@@ -600,7 +600,7 @@ class XEP_0323(BasePlugin):
iq['req']._set_flags(flags)
self.sessions[seqnr] = {"from": iq['from'], "to": iq['to'], "seqnr": seqnr, "callback": callback}
- iq.send(block=False)
+ iq.send()
return seqnr
@@ -621,7 +621,7 @@ class XEP_0323(BasePlugin):
iq['type'] = "get"
iq['id'] = seqnr
iq['cancel']['seqnr'] = seqnr
- iq.send(block=False)
+ iq.send()
def _get_new_seqnr(self):
""" Returns a unique sequence number (unique across threads) """
@@ -675,8 +675,8 @@ class XEP_0323(BasePlugin):
field_block["name"] = d['name']
field_block["typename"] = d._get_typename()
field_block["value"] = d['value']
- if not d['unit'] == "": field_block["unit"] = d['unit'];
- if not d['dataType'] == "": field_block["dataType"] = d['dataType'];
+ if not d['unit'] == "": field_block["unit"] = d['unit']
+ if not d['dataType'] == "": field_block["dataType"] = d['dataType']
flags = d._get_flags()
if not len(flags) == 0:
field_block["flags"] = flags
diff --git a/sleekxmpp/plugins/xep_0325/stanza/__init__.py b/slixmpp/plugins/xep_0323/stanza/__init__.py
index 746c2033..e1603e41 100644
--- a/sleekxmpp/plugins/xep_0325/stanza/__init__.py
+++ b/slixmpp/plugins/xep_0323/stanza/__init__.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins.xep_0325.stanza.control import *
+from slixmpp.plugins.xep_0323.stanza.sensordata import *
diff --git a/sleekxmpp/plugins/xep_0323/stanza/base.py b/slixmpp/plugins/xep_0323/stanza/base.py
index 1dadcf46..7959b818 100644
--- a/sleekxmpp/plugins/xep_0323/stanza/base.py
+++ b/slixmpp/plugins/xep_0323/stanza/base.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ET
+from slixmpp.xmlstream import ET
pass
diff --git a/sleekxmpp/plugins/xep_0323/stanza/sensordata.py b/slixmpp/plugins/xep_0323/stanza/sensordata.py
index e8718161..aa223a62 100644
--- a/sleekxmpp/plugins/xep_0323/stanza/sensordata.py
+++ b/slixmpp/plugins/xep_0323/stanza/sensordata.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp import Iq, Message
-from sleekxmpp.xmlstream import register_stanza_plugin, ElementBase, ET, JID
+from slixmpp import Iq, Message
+from slixmpp.xmlstream import register_stanza_plugin, ElementBase, ET, JID
from re import match
class Sensordata(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0323/timerreset.py b/slixmpp/plugins/xep_0323/timerreset.py
index 398b47c1..616380e7 100644
--- a/sleekxmpp/plugins/xep_0323/timerreset.py
+++ b/slixmpp/plugins/xep_0323/timerreset.py
@@ -1,9 +1,9 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
diff --git a/sleekxmpp/plugins/xep_0325/__init__.py b/slixmpp/plugins/xep_0325/__init__.py
index 01c38dce..ce8cb7ce 100644
--- a/sleekxmpp/plugins/xep_0325/__init__.py
+++ b/slixmpp/plugins/xep_0325/__init__.py
@@ -1,17 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins.base import register_plugin
+from slixmpp.plugins.base import register_plugin
-from sleekxmpp.plugins.xep_0325.control import XEP_0325
-from sleekxmpp.plugins.xep_0325 import stanza
+from slixmpp.plugins.xep_0325.control import XEP_0325
+from slixmpp.plugins.xep_0325 import stanza
register_plugin(XEP_0325)
diff --git a/sleekxmpp/plugins/xep_0325/control.py b/slixmpp/plugins/xep_0325/control.py
index 11e7a045..9a493b02 100644
--- a/sleekxmpp/plugins/xep_0325/control.py
+++ b/slixmpp/plugins/xep_0325/control.py
@@ -1,22 +1,24 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
import time
-from threading import Thread, Timer, Lock
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.plugins.xep_0325 import stanza
-from sleekxmpp.plugins.xep_0325.stanza import Control
+from slixmpp import asyncio
+from functools import partial
+from slixmpp.xmlstream import JID
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.plugins.xep_0325 import stanza
+from slixmpp.plugins.xep_0325.stanza import Control
log = logging.getLogger(__name__)
@@ -39,10 +41,6 @@ class XEP_0325(BasePlugin):
Also see <http://xmpp.org/extensions/xep-0325.html>
- Configuration Values:
- threaded -- Indicates if communication with sensors should be threaded.
- Defaults to True.
-
Events:
Sensor side
-----------
@@ -57,8 +55,6 @@ class XEP_0325(BasePlugin):
control request, type error
Attributes:
- threaded -- Indicates if command events should be threaded.
- Defaults to True.
sessions -- A dictionary or equivalent backend mapping
session IDs to dictionaries containing data
relevant to a request's session. This dictionary is used
@@ -78,9 +74,9 @@ class XEP_0325(BasePlugin):
sequence number (unique between the client/sensor pair)
Methods:
- plugin_init -- Overrides base_plugin.plugin_init
- post_init -- Overrides base_plugin.post_init
- plugin_end -- Overrides base_plugin.plugin_end
+ plugin_init -- Overrides BasePlugin.plugin_init
+ post_init -- Overrides BasePlugin.post_init
+ plugin_end -- Overrides BasePlugin.plugin_end
Sensor side
-----------
@@ -106,7 +102,6 @@ class XEP_0325(BasePlugin):
default_config = {
- 'threaded': True
# 'session_db': None
}
@@ -138,13 +133,12 @@ class XEP_0325(BasePlugin):
self.sessions = {}
self.last_seqnr = 0
- self.seqnr_lock = Lock()
## For testning only
self.test_authenticated_from = ""
def post_init(self):
- """ Init complete. Register our features in Serivce discovery. """
+ """ Init complete. Register our features in Service discovery. """
BasePlugin.post_init(self)
self.xmpp['xep_0030'].add_feature(Control.namespace)
self.xmpp['xep_0030'].set_items(node=Control.namespace, items=tuple())
@@ -197,9 +191,7 @@ class XEP_0325(BasePlugin):
def _get_new_seqnr(self):
""" Returns a unique sequence number (unique across threads) """
- self.seqnr_lock.acquire()
- self.last_seqnr += 1
- self.seqnr_lock.release()
+ self.last_seqnr = self.last_seqnr + 1
return str(self.last_seqnr)
def _handle_set_req(self, iq):
@@ -262,16 +254,9 @@ class XEP_0325(BasePlugin):
self.sessions[session]["reply"] = True
self.sessions[session]["node_list"] = process_nodes
- if self.threaded:
- #print("starting thread")
- tr_req = Thread(target=self._threaded_node_request, args=(session, process_fields))
- tr_req.start()
- #print("started thread")
- else:
- self._threaded_node_request(session, process_fields)
-
+ self._node_request(session, process_fields)
else:
- iq.reply()
+ iq = iq.reply()
iq['type'] = 'error'
iq['setResponse']['responseCode'] = "NotFound"
if missing_node is not None:
@@ -280,7 +265,7 @@ class XEP_0325(BasePlugin):
iq['setResponse'].add_data(missing_field)
iq['setResponse']['error']['var'] = "Output"
iq['setResponse']['error']['text'] = error_msg
- iq.send(block=False)
+ iq.send()
def _handle_direct_set(self, msg):
"""
@@ -329,16 +314,10 @@ class XEP_0325(BasePlugin):
self.sessions[session]["reply"] = False
self.sessions[session]["node_list"] = process_nodes
- if self.threaded:
- #print("starting thread")
- tr_req = Thread(target=self._threaded_node_request, args=(session, process_fields))
- tr_req.start()
- #print("started thread")
- else:
- self._threaded_node_request(session, process_fields)
+ self._node_request(session, process_fields)
- def _threaded_node_request(self, session, process_fields):
+ def _node_request(self, session, process_fields):
"""
Helper function to handle the device control in a separate thread.
@@ -351,9 +330,8 @@ class XEP_0325(BasePlugin):
self.sessions[session]["nodeDone"][node] = False
for node in self.sessions[session]["node_list"]:
- timer = Timer(self.nodes[node]['commTimeout'], self._event_comm_timeout, args=(session, node))
+ timer = self.xmpp.loop.call_later(self.nodes[node]['commTimeout'], partial(self._event_comm_timeout, args=(session, node)))
self.sessions[session]["commTimers"][node] = timer
- timer.start()
self.nodes[node]['device'].set_control_fields(process_fields, session=session, callback=self._device_set_command_callback)
def _event_comm_timeout(self, session, nodeId):
@@ -379,7 +357,7 @@ class XEP_0325(BasePlugin):
iq['setResponse'].add_node(nodeId)
iq['setResponse']['error']['var'] = "Output"
iq['setResponse']['error']['text'] = "Timeout."
- iq.send(block=False)
+ iq.send()
## TODO - should we send one timeout per node??
@@ -440,7 +418,7 @@ class XEP_0325(BasePlugin):
iq['setResponse'].add_data(error_field)
iq['setResponse']['error']['var'] = error_field
iq['setResponse']['error']['text'] = error_msg
- iq.send(block=False)
+ iq.send()
# Drop communication with this device and check if we are done
self.sessions[session]["nodeDone"][nodeId] = True
@@ -460,7 +438,7 @@ class XEP_0325(BasePlugin):
iq['type'] = "result"
iq['id'] = self.sessions[session]['seqnr']
iq['setResponse']['responseCode'] = "OK"
- iq.send(block=False)
+ iq.send()
# The session is complete, delete it
del self.sessions[session]
@@ -523,7 +501,7 @@ class XEP_0325(BasePlugin):
iq['set'].add_data(name=name, typename=typename, value=value)
self.sessions[seqnr] = {"from": iq['from'], "to": iq['to'], "callback": callback}
- iq.send(block=False)
+ iq.send()
def set_command(self, from_jid, to_jid, fields, nodeIds=None):
"""
@@ -567,3 +545,4 @@ class XEP_0325(BasePlugin):
callback = self.sessions[seqnr]["callback"]
callback(from_jid=from_jid, result=result, nodeIds=nodeIds, fields=fields, error_msg=error_msg)
+
diff --git a/sleekxmpp/plugins/xep_0325/device.py b/slixmpp/plugins/xep_0325/device.py
index f1ed0733..05275088 100644
--- a/sleekxmpp/plugins/xep_0325/device.py
+++ b/slixmpp/plugins/xep_0325/device.py
@@ -1,9 +1,9 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
diff --git a/sleekxmpp/plugins/xep_0323/stanza/__init__.py b/slixmpp/plugins/xep_0325/stanza/__init__.py
index c039cefa..1466db5d 100644
--- a/sleekxmpp/plugins/xep_0323/stanza/__init__.py
+++ b/slixmpp/plugins/xep_0325/stanza/__init__.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins.xep_0323.stanza.sensordata import *
+from slixmpp.plugins.xep_0325.stanza.control import *
diff --git a/sleekxmpp/plugins/xep_0325/stanza/base.py b/slixmpp/plugins/xep_0325/stanza/base.py
index 1dadcf46..7959b818 100644
--- a/sleekxmpp/plugins/xep_0325/stanza/base.py
+++ b/slixmpp/plugins/xep_0325/stanza/base.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ET
+from slixmpp.xmlstream import ET
pass
diff --git a/sleekxmpp/plugins/xep_0325/stanza/control.py b/slixmpp/plugins/xep_0325/stanza/control.py
index 1fd5c35d..c47f3a4e 100644
--- a/sleekxmpp/plugins/xep_0325/stanza/control.py
+++ b/slixmpp/plugins/xep_0325/stanza/control.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp import Iq, Message
-from sleekxmpp.xmlstream import register_stanza_plugin, ElementBase, ET, JID
+from slixmpp import Iq, Message
+from slixmpp.xmlstream import register_stanza_plugin, ElementBase, ET, JID
from re import match
class Control(ElementBase):
@@ -424,7 +424,6 @@ class BaseParameter(ElementBase):
def _get_typename(self):
return self.name
-
class BooleanParameter(BaseParameter):
"""
Field data of type boolean.
diff --git a/sleekxmpp/plugins/xep_0332/__init__.py b/slixmpp/plugins/xep_0332/__init__.py
index 27755faa..8bf6b369 100644
--- a/sleekxmpp/plugins/xep_0332/__init__.py
+++ b/slixmpp/plugins/xep_0332/__init__.py
@@ -1,17 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Implementation of HTTP over XMPP transport
http://xmpp.org/extensions/xep-0332.html
Copyright (C) 2015 Riptide IO, sangeeth@riptideio.com
- This file is part of SleekXMPP.
+ This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.plugins.base import register_plugin
+from slixmpp.plugins.base import register_plugin
-from sleekxmpp.plugins.xep_0332 import stanza
-from sleekxmpp.plugins.xep_0332.http import XEP_0332
+from slixmpp.plugins.xep_0332 import stanza
+from slixmpp.plugins.xep_0332.http import XEP_0332
register_plugin(XEP_0332)
diff --git a/sleekxmpp/plugins/xep_0332/http.py b/slixmpp/plugins/xep_0332/http.py
index 70bcafa6..7ad14dc8 100644
--- a/sleekxmpp/plugins/xep_0332/http.py
+++ b/slixmpp/plugins/xep_0332/http.py
@@ -1,26 +1,26 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Implementation of HTTP over XMPP transport
http://xmpp.org/extensions/xep-0332.html
Copyright (C) 2015 Riptide IO, sangeeth@riptideio.com
- This file is part of SleekXMPP.
+ This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp import Iq
+from slixmpp import Iq
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.xmlstream.matcher import StanzaPath
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
-from sleekxmpp.plugins.base import BasePlugin
-from sleekxmpp.plugins.xep_0332.stanza import (
+from slixmpp.plugins.base import BasePlugin
+from slixmpp.plugins.xep_0332.stanza import (
HTTPRequest, HTTPResponse, HTTPData
)
-from sleekxmpp.plugins.xep_0131.stanza import Headers
+from slixmpp.plugins.xep_0131.stanza import Headers
log = logging.getLogger(__name__)
diff --git a/slixmpp/plugins/xep_0332/stanza/__init__.py b/slixmpp/plugins/xep_0332/stanza/__init__.py
new file mode 100644
index 00000000..f98375c6
--- /dev/null
+++ b/slixmpp/plugins/xep_0332/stanza/__init__.py
@@ -0,0 +1,13 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Implementation of HTTP over XMPP transport
+ http://xmpp.org/extensions/xep-0332.html
+ Copyright (C) 2015 Riptide IO, sangeeth@riptideio.com
+ This file is part of slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.plugins.xep_0332.stanza.request import HTTPRequest
+from slixmpp.plugins.xep_0332.stanza.response import HTTPResponse
+from slixmpp.plugins.xep_0332.stanza.data import HTTPData
diff --git a/sleekxmpp/plugins/xep_0332/stanza/data.py b/slixmpp/plugins/xep_0332/stanza/data.py
index a3678038..a19c94f5 100644
--- a/sleekxmpp/plugins/xep_0332/stanza/data.py
+++ b/slixmpp/plugins/xep_0332/stanza/data.py
@@ -1,14 +1,14 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Implementation of HTTP over XMPP transport
http://xmpp.org/extensions/xep-0332.html
Copyright (C) 2015 Riptide IO, sangeeth@riptideio.com
- This file is part of SleekXMPP.
+ This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class HTTPData(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0332/stanza/request.py b/slixmpp/plugins/xep_0332/stanza/request.py
index 9a298e57..e3e46361 100644
--- a/sleekxmpp/plugins/xep_0332/stanza/request.py
+++ b/slixmpp/plugins/xep_0332/stanza/request.py
@@ -1,14 +1,14 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ slixmpp: The Slick XMPP Library
Implementation of HTTP over XMPP transport
http://xmpp.org/extensions/xep-0332.html
Copyright (C) 2015 Riptide IO, sangeeth@riptideio.com
- This file is part of SleekXMPP.
+ This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class HTTPRequest(ElementBase):
diff --git a/sleekxmpp/plugins/xep_0332/stanza/response.py b/slixmpp/plugins/xep_0332/stanza/response.py
index 6804ade9..a0b8fe34 100644
--- a/sleekxmpp/plugins/xep_0332/stanza/response.py
+++ b/slixmpp/plugins/xep_0332/stanza/response.py
@@ -1,14 +1,14 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Implementation of HTTP over XMPP transport
http://xmpp.org/extensions/xep-0332.html
Copyright (C) 2015 Riptide IO, sangeeth@riptideio.com
- This file is part of SleekXMPP.
+ This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase
+from slixmpp.xmlstream import ElementBase
class HTTPResponse(ElementBase):
diff --git a/slixmpp/roster/__init__.py b/slixmpp/roster/__init__.py
new file mode 100644
index 00000000..9a9b69a1
--- /dev/null
+++ b/slixmpp/roster/__init__.py
@@ -0,0 +1,11 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.roster.item import RosterItem
+from slixmpp.roster.single import RosterNode
+from slixmpp.roster.multi import Roster
diff --git a/sleekxmpp/roster/item.py b/slixmpp/roster/item.py
index ae194e0a..c1eb574a 100644
--- a/sleekxmpp/roster/item.py
+++ b/slixmpp/roster/item.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -71,7 +71,7 @@ class RosterItem(object):
groups -- A list of group names for the JID.
Attributes:
- xmpp -- The main SleekXMPP instance.
+ xmpp -- The main Slixmpp instance.
owner -- The JID that owns the roster.
jid -- The JID for the roster item.
db -- Optional datastore interface object.
@@ -110,7 +110,7 @@ class RosterItem(object):
Create a new roster item.
Arguments:
- xmpp -- The main SleekXMPP instance.
+ xmpp -- The main Slixmpp instance.
jid -- The item's JID.
owner -- The roster owner's JID. Defaults
so self.xmpp.boundjid.bare.
diff --git a/sleekxmpp/roster/multi.py b/slixmpp/roster/multi.py
index 5d070ec8..e1a44a08 100644
--- a/sleekxmpp/roster/multi.py
+++ b/slixmpp/roster/multi.py
@@ -1,20 +1,20 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza import Presence
-from sleekxmpp.xmlstream import JID
-from sleekxmpp.roster import RosterNode
+from slixmpp.stanza import Presence
+from slixmpp.xmlstream import JID
+from slixmpp.roster import RosterNode
class Roster(object):
"""
- SleekXMPP's roster manager.
+ Slixmpp's roster manager.
The roster is divided into "nodes", where each node is responsible
for a single JID. While the distinction is not strictly necessary
@@ -27,7 +27,7 @@ class Roster(object):
methods that the datastore interface object must provide.
Attributes:
- xmpp -- The main SleekXMPP instance.
+ xmpp -- The main Slixmpp instance.
db -- Optional interface object to an external datastore.
auto_authorize -- Default auto_authorize value for new roster nodes.
Defaults to True.
@@ -44,7 +44,7 @@ class Roster(object):
Create a new roster.
Arguments:
- xmpp -- The main SleekXMPP instance.
+ xmpp -- The main Slixmpp instance.
db -- Optional interface object to a datastore.
"""
self.xmpp = xmpp
diff --git a/sleekxmpp/roster/single.py b/slixmpp/roster/single.py
index e9ce4f21..62fbca41 100644
--- a/sleekxmpp/roster/single.py
+++ b/slixmpp/roster/single.py
@@ -1,15 +1,15 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import threading
-from sleekxmpp.xmlstream import JID
-from sleekxmpp.roster import RosterItem
+from slixmpp.xmlstream import JID
+from slixmpp.roster import RosterItem
class RosterNode(object):
@@ -18,7 +18,7 @@ class RosterNode(object):
A roster node is a roster for a single JID.
Attributes:
- xmpp -- The main SleekXMPP instance.
+ xmpp -- The main Slixmpp instance.
jid -- The JID that owns the roster node.
db -- Optional interface to an external datastore.
auto_authorize -- Determines how authorizations are handled:
@@ -49,7 +49,7 @@ class RosterNode(object):
Create a roster node for a JID.
Arguments:
- xmpp -- The main SleekXMPP instance.
+ xmpp -- The main Slixmpp instance.
jid -- The JID that owns the roster.
db -- Optional interface to an external datastore.
"""
@@ -237,7 +237,8 @@ class RosterNode(object):
if not self.xmpp.is_component:
return self.update(jid, subscription='remove')
- def update(self, jid, name=None, subscription=None, groups=None, block=True, timeout=None, callback=None):
+ def update(self, jid, name=None, subscription=None, groups=[],
+ timeout=None, callback=None, timeout_callback=None):
"""
Update a JID's subscription information.
@@ -247,15 +248,11 @@ class RosterNode(object):
subscription -- The subscription state. May be one of: 'to',
'from', 'both', 'none', or 'remove'.
groups -- A list of group names.
- block -- Specify if the roster request will block
- until a response is received, or a timeout
- occurs. Defaults to True.
timeout -- The length of time (in seconds) to wait
for a response before continuing if blocking
is used. Defaults to self.response_timeout.
callback -- Optional reference to a stream handler function.
Will be executed when the roster is received.
- Implies block=False.
"""
if not groups:
groups = []
@@ -271,7 +268,8 @@ class RosterNode(object):
'subscription': subscription,
'groups': groups}}
- return iq.send(block, timeout, callback)
+ return iq.send(timeout=timeout, callback=callback,
+ timeout_callback=timeout_callback)
def presence(self, jid, resource=None):
"""
diff --git a/slixmpp/stanza/__init__.py b/slixmpp/stanza/__init__.py
new file mode 100644
index 00000000..6cd6a2c5
--- /dev/null
+++ b/slixmpp/stanza/__init__.py
@@ -0,0 +1,15 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+
+from slixmpp.stanza.error import Error
+from slixmpp.stanza.iq import Iq
+from slixmpp.stanza.message import Message
+from slixmpp.stanza.presence import Presence
+from slixmpp.stanza.stream_features import StreamFeatures
+from slixmpp.stanza.stream_error import StreamError
diff --git a/sleekxmpp/stanza/atom.py b/slixmpp/stanza/atom.py
index 4e9591a5..ccded724 100644
--- a/sleekxmpp/stanza/atom.py
+++ b/slixmpp/stanza/atom.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import register_stanza_plugin, ElementBase
+from slixmpp.xmlstream import ElementBase, register_stanza_plugin
class AtomEntry(ElementBase):
diff --git a/sleekxmpp/stanza/error.py b/slixmpp/stanza/error.py
index 56558ba8..67f736c0 100644
--- a/sleekxmpp/stanza/error.py
+++ b/slixmpp/stanza/error.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream import ElementBase, ET
+from slixmpp.xmlstream import ElementBase, ET
class Error(ElementBase):
@@ -162,13 +162,3 @@ class Error(ElementBase):
def del_redirect(self):
self._del_sub('{%s}redirect' % self.condition_ns)
-
-
-# To comply with PEP8, method names now use underscores.
-# Deprecated method names are re-mapped for backwards compatibility.
-Error.getCondition = Error.get_condition
-Error.setCondition = Error.set_condition
-Error.delCondition = Error.del_condition
-Error.getText = Error.get_text
-Error.setText = Error.set_text
-Error.delText = Error.del_text
diff --git a/slixmpp/stanza/htmlim.py b/slixmpp/stanza/htmlim.py
new file mode 100644
index 00000000..a5a3e5f3
--- /dev/null
+++ b/slixmpp/stanza/htmlim.py
@@ -0,0 +1,14 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.stanza import Message
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.xep_0071 import XHTML_IM as HTMLIM
+
+
+register_stanza_plugin(Message, HTMLIM)
diff --git a/sleekxmpp/stanza/iq.py b/slixmpp/stanza/iq.py
index 088de4c0..a64dfa7f 100644
--- a/sleekxmpp/stanza/iq.py
+++ b/slixmpp/stanza/iq.py
@@ -1,16 +1,17 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza.rootstanza import RootStanza
-from sleekxmpp.xmlstream import StanzaBase, ET
-from sleekxmpp.xmlstream.handler import Waiter, Callback
-from sleekxmpp.xmlstream.matcher import MatchIDSender, MatcherId
-from sleekxmpp.exceptions import IqTimeout, IqError
+from slixmpp.stanza.rootstanza import RootStanza
+from slixmpp.xmlstream import StanzaBase, ET
+from slixmpp.xmlstream.handler import Waiter, Callback, CoroutineCallback
+from slixmpp.xmlstream.asyncio import asyncio
+from slixmpp.xmlstream.matcher import MatchIDSender, MatcherId
+from slixmpp.exceptions import IqTimeout, IqError
class Iq(RootStanza):
@@ -31,6 +32,9 @@ class Iq(RootStanza):
as a carrier stanza for an application-specific protocol instead.
Example <iq> Stanzas:
+
+ .. code-block:: xml
+
<iq to="user@example.com" type="get" id="314">
<query xmlns="http://jabber.org/protocol/disco#items" />
</iq>
@@ -46,20 +50,9 @@ class Iq(RootStanza):
</iq>
Stanza Interface:
- query -- The namespace of the <query> element if one exists.
-
+ - **query**: The namespace of the <query> element if one exists.
Attributes:
- types -- May be one of: get, set, result, or error.
-
- Methods:
- __init__ -- Overrides StanzaBase.__init__.
- unhandled -- Send error if there are no handlers.
- set_payload -- Overrides StanzaBase.set_payload.
- set_query -- Add or modify a <query> element.
- get_query -- Return the namespace of the <query> element.
- del_query -- Remove the <query> element.
- reply -- Overrides StanzaBase.reply
- send -- Overrides StanzaBase.send
+ - **types**: May be one of: get, set, result, or error.
"""
namespace = 'jabber:client'
@@ -88,17 +81,18 @@ class Iq(RootStanza):
Overrides StanzaBase.unhandled.
"""
if self['type'] in ('get', 'set'):
- self.reply()
- self['error']['condition'] = 'feature-not-implemented'
- self['error']['text'] = 'No handlers registered for this request.'
- self.send()
+ reply = self.reply()
+ reply['error']['condition'] = 'feature-not-implemented'
+ reply['error']['text'] = 'No handlers registered for this request.'
+ reply.send()
def set_payload(self, value):
"""
Set the XML contents of the <iq> stanza.
- Arguments:
- value -- An XML object to use as the <iq> stanza's contents
+ :param value: An XML object or a list of XML objects to use as the <iq>
+ stanza's contents
+ :type value: list or XML object
"""
self.clear()
StanzaBase.set_payload(self, value)
@@ -110,8 +104,7 @@ class Iq(RootStanza):
Query elements are differentiated by their namespace.
- Arguments:
- value -- The namespace of the <query> element.
+ :param str value: The namespace of the <query> element.
"""
query = self.xml.find("{%s}query" % value)
if query is None and value:
@@ -125,7 +118,9 @@ class Iq(RootStanza):
return self
def get_query(self):
- """Return the namespace of the <query> element."""
+ """Return the namespace of the <query> element.
+
+ :rtype: str"""
for child in self.xml:
if child.tag.endswith('query'):
ns = child.tag.split('}')[0]
@@ -143,57 +138,44 @@ class Iq(RootStanza):
def reply(self, clear=True):
"""
- Send a reply <iq> stanza.
+ Create a new <iq> stanza replying to ``self``.
Overrides StanzaBase.reply
Sets the 'type' to 'result' in addition to the default
StanzaBase.reply behavior.
- Arguments:
- clear -- Indicates if existing content should be
- removed before replying. Defaults to True.
+ :param bool clear: Indicates if existing content should be
+ removed before replying. Defaults to True.
"""
- self['type'] = 'result'
- StanzaBase.reply(self, clear)
- return self
+ new_iq = StanzaBase.reply(self, clear=clear)
+ new_iq['type'] = 'result'
+ return new_iq
- def send(self, block=True, timeout=None, callback=None, now=False, timeout_callback=None):
- """
- Send an <iq> stanza over the XML stream.
+ def send(self, callback=None, timeout=None, timeout_callback=None):
+ """Send an <iq> stanza over the XML stream.
- The send call can optionally block until a response is received or
- a timeout occurs. Be aware that using blocking in non-threaded event
- handlers can drastically impact performance. Otherwise, a callback
- handler can be provided that will be executed when the Iq stanza's
- result reply is received. Be aware though that that the callback
- handler will not be executed in its own thread.
+ A callback handler can be provided that will be executed when the Iq
+ stanza's result reply is received.
- Using both block and callback is not recommended, and only the
- callback argument will be used in that case.
+ Returns a future which result will be set to the result Iq if it is of type 'get' or 'set'
+ (when it is received), or a future with the result set to None if it has another type.
Overrides StanzaBase.send
- Arguments:
- block -- Specify if the send call will block until a response
- is received, or a timeout occurs. Defaults to True.
- timeout -- The length of time (in seconds) to wait for a response
- before exiting the send call if blocking is used.
- Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
- callback -- Optional reference to a stream handler function. Will
- be executed when a reply stanza is received.
- now -- Indicates if the send queue should be skipped and send
- the stanza immediately. Used during stream
- initialization. Defaults to False.
- timeout_callback -- Optional reference to a stream handler function.
- Will be executed when the timeout expires before a
- response has been received with the originally-sent IQ
- stanza. Only called if there is a callback parameter
- (and therefore are in async mode).
+ :param function callback: Optional reference to a stream handler
+ function. Will be executed when a reply
+ stanza is received.
+ :param int timeout: The length of time (in seconds) to wait for a
+ response before the timeout_callback is called,
+ instead of the regular callback
+ :param function timeout_callback: Optional reference to a stream handler
+ function. Will be executed when the
+ timeout expires before a response has
+ been received for the originally-sent
+ IQ stanza.
+ :rtype: asyncio.Future
"""
- if timeout is None:
- timeout = self.stream.response_timeout
-
if self.stream.session_bind_event.is_set():
matcher = MatchIDSender({
'id': self['id'],
@@ -203,43 +185,49 @@ class Iq(RootStanza):
else:
matcher = MatcherId(self['id'])
- if callback is not None and self['type'] in ('get', 'set'):
+ future = asyncio.Future()
+
+ def callback_success(result):
+ if result['type'] == 'error':
+ future.set_exception(IqError(result))
+ else:
+ future.set_result(result)
+
+ if timeout is not None:
+ self.stream.cancel_schedule('IqTimeout_%s' % self['id'])
+ if callback is not None:
+ callback(result)
+
+ def callback_timeout():
+ future.set_exception(IqTimeout(self))
+ self.stream.remove_handler('IqCallback_%s' % self['id'])
+ if timeout_callback is not None:
+ timeout_callback(self)
+
+ if self['type'] in ('get', 'set'):
handler_name = 'IqCallback_%s' % self['id']
- if timeout_callback:
- self.callback = callback
- self.timeout_callback = timeout_callback
+ if asyncio.iscoroutinefunction(callback):
+ constr = CoroutineCallback
+ else:
+ constr = Callback
+ if timeout is not None:
self.stream.schedule('IqTimeout_%s' % self['id'],
timeout,
- self._fire_timeout,
+ callback_timeout,
repeat=False)
- handler = Callback(handler_name,
- matcher,
- self._handle_result,
- once=True)
- else:
- handler = Callback(handler_name,
- matcher,
- callback,
- once=True)
+ handler = constr(handler_name,
+ matcher,
+ callback_success,
+ once=True)
self.stream.register_handler(handler)
- StanzaBase.send(self, now=now)
- return handler_name
- elif block and self['type'] in ('get', 'set'):
- waitfor = Waiter('IqWait_%s' % self['id'], matcher)
- self.stream.register_handler(waitfor)
- StanzaBase.send(self, now=now)
- result = waitfor.wait(timeout)
- if not result:
- raise IqTimeout(self)
- if result['type'] == 'error':
- raise IqError(result)
- return result
else:
- return StanzaBase.send(self, now=now)
+ future.set_result(None)
+ StanzaBase.send(self)
+ return future
def _handle_result(self, iq):
# we got the IQ, so don't fire the timeout
- self.stream.scheduler.remove('IqTimeout_%s' % self['id'])
+ self.stream.cancel_schedule('IqTimeout_%s' % self['id'])
self.callback(iq)
def _fire_timeout(self):
@@ -271,11 +259,3 @@ class Iq(RootStanza):
else:
StanzaBase._set_stanza_values(self, values)
return self
-
-
-# To comply with PEP8, method names now use underscores.
-# Deprecated method names are re-mapped for backwards compatibility.
-Iq.setPayload = Iq.set_payload
-Iq.getQuery = Iq.get_query
-Iq.setQuery = Iq.set_query
-Iq.delQuery = Iq.del_query
diff --git a/sleekxmpp/stanza/message.py b/slixmpp/stanza/message.py
index 0bb6e587..cbb170fa 100644
--- a/sleekxmpp/stanza/message.py
+++ b/slixmpp/stanza/message.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza.rootstanza import RootStanza
-from sleekxmpp.xmlstream import StanzaBase, ET
+from slixmpp.stanza.rootstanza import RootStanza
+from slixmpp.xmlstream import StanzaBase, ET
class Message(RootStanza):
@@ -23,6 +23,9 @@ class Message(RootStanza):
an error response.
Example <message> stanzas:
+
+ .. code-block:: xml
+
<message to="user1@example.com" from="user2@example.com">
<body>Hi!</body>
</message>
@@ -32,26 +35,13 @@ class Message(RootStanza):
</message>
Stanza Interface:
- body -- The main contents of the message.
- subject -- An optional description of the message's contents.
- mucroom -- (Read-only) The name of the MUC room that sent the message.
- mucnick -- (Read-only) The MUC nickname of message's sender.
+ - **body**: The main contents of the message.
+ - **subject**: An optional description of the message's contents.
+ - **mucroom**: (Read-only) The name of the MUC room that sent the message.
+ - **mucnick**: (Read-only) The MUC nickname of message's sender.
Attributes:
- types -- May be one of: normal, chat, headline, groupchat, or error.
-
- Methods:
- setup -- Overrides StanzaBase.setup.
- chat -- Set the message type to 'chat'.
- normal -- Set the message type to 'normal'.
- reply -- Overrides StanzaBase.reply
- get_type -- Overrides StanzaBase interface
- get_mucroom -- Return the name of the MUC room of the message.
- set_mucroom -- Dummy method to prevent assignment.
- del_mucroom -- Dummy method to prevent deletion.
- get_mucnick -- Return the MUC nickname of the message's sender.
- set_mucnick -- Dummy method to prevent assignment.
- del_mucnick -- Dummy method to prevent deletion.
+ - **types**: May be one of: normal, chat, headline, groupchat, or error.
"""
name = 'message'
@@ -81,18 +71,25 @@ class Message(RootStanza):
Overrides default stanza interface behavior.
Returns 'normal' if no type attribute is present.
+
+ :rtype: str
"""
return self._get_attr('type', 'normal')
def get_parent_thread(self):
- """Return the message thread's parent thread."""
+ """Return the message thread's parent thread.
+
+ :rtype: str
+ """
thread = self.xml.find('{%s}thread' % self.namespace)
if thread is not None:
return thread.attrib.get('parent', '')
return ''
def set_parent_thread(self, value):
- """Add or change the message thread's parent thread."""
+ """Add or change the message thread's parent thread.
+
+ :param str value: identifier of the thread"""
thread = self.xml.find('{%s}thread' % self.namespace)
if value:
if thread is None:
@@ -128,32 +125,33 @@ class Message(RootStanza):
Sets proper 'to' attribute if the message is from a MUC, and
adds a message body if one is given.
- Arguments:
- body -- Optional text content for the message.
- clear -- Indicates if existing content should be removed
- before replying. Defaults to True.
+ :param str body: Optional text content for the message.
+ :param bool clear: Indicates if existing content should be removed
+ before replying. Defaults to True.
+
+ :rtype: :class:`~.Message`
"""
- thread = self['thread']
- parent = self['parent_thread']
+ new_message = StanzaBase.reply(self, clear)
- StanzaBase.reply(self, clear)
if self['type'] == 'groupchat':
- self['to'] = self['to'].bare
+ new_message['to'] = new_message['to'].bare
- self['thread'] = thread
- self['parent_thread'] = parent
+ new_message['thread'] = self['thread']
+ new_message['parent_thread'] = self['parent_thread']
- del self['id']
+ del new_message['id']
if body is not None:
- self['body'] = body
- return self
+ new_message['body'] = body
+ return new_message
def get_mucroom(self):
"""
Return the name of the MUC room where the message originated.
Read-only stanza interface.
+
+ :rtype: str
"""
if self['type'] == 'groupchat':
return self['from'].bare
@@ -165,6 +163,8 @@ class Message(RootStanza):
Return the nickname of the MUC user that sent the message.
Read-only stanza interface.
+
+ :rtype: str
"""
if self['type'] == 'groupchat':
return self['from'].resource
@@ -186,14 +186,3 @@ class Message(RootStanza):
def del_mucnick(self):
"""Dummy method to prevent deletion."""
pass
-
-
-# To comply with PEP8, method names now use underscores.
-# Deprecated method names are re-mapped for backwards compatibility.
-Message.getType = Message.get_type
-Message.getMucroom = Message.get_mucroom
-Message.setMucroom = Message.set_mucroom
-Message.delMucroom = Message.del_mucroom
-Message.getMucnick = Message.get_mucnick
-Message.setMucnick = Message.set_mucnick
-Message.delMucnick = Message.del_mucnick
diff --git a/slixmpp/stanza/nick.py b/slixmpp/stanza/nick.py
new file mode 100644
index 00000000..3bb7d63d
--- /dev/null
+++ b/slixmpp/stanza/nick.py
@@ -0,0 +1,17 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+# The nickname stanza has been moved to its own plugin, but the existing
+# references are kept for backwards compatibility.
+
+from slixmpp.stanza import Message, Presence
+from slixmpp.xmlstream import register_stanza_plugin
+from slixmpp.plugins.xep_0172 import UserNick as Nick
+
+register_stanza_plugin(Message, Nick)
+register_stanza_plugin(Presence, Nick)
diff --git a/sleekxmpp/stanza/presence.py b/slixmpp/stanza/presence.py
index 84bcd122..1e8a940e 100644
--- a/sleekxmpp/stanza/presence.py
+++ b/slixmpp/stanza/presence.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza.rootstanza import RootStanza
-from sleekxmpp.xmlstream import StanzaBase
+from slixmpp.stanza.rootstanza import RootStanza
+from slixmpp.xmlstream import StanzaBase
class Presence(RootStanza):
@@ -27,6 +27,9 @@ class Presence(RootStanza):
to help keep the network running smoothly.
Example <presence> stanzas:
+
+ .. code-block:: xml
+
<presence />
<presence from="user@example.com">
@@ -40,24 +43,14 @@ class Presence(RootStanza):
<presence to="user@otherhost.com" type="subscribe" />
Stanza Interface:
- priority -- A value used by servers to determine message routing.
- show -- The type of status, such as away or available for chat.
- status -- Custom, human readable status message.
+ - **priority**: A value used by servers to determine message routing.
+ - **show**: The type of status, such as away or available for chat.
+ - **status**: Custom, human readable status message.
Attributes:
- types -- One of: available, unavailable, error, probe,
- subscribe, subscribed, unsubscribe,
- and unsubscribed.
- showtypes -- One of: away, chat, dnd, and xa.
-
- Methods:
- setup -- Overrides StanzaBase.setup
- reply -- Overrides StanzaBase.reply
- set_show -- Set the value of the <show> element.
- get_type -- Get the value of the type attribute or <show> element.
- set_type -- Set the value of the type attribute or <show> element.
- get_priority -- Get the value of the <priority> element.
- set_priority -- Set the value of the <priority> element.
+ - **types**: One of: available, unavailable, error, probe,
+ subscribe, subscribed, unsubscribe, and unsubscribed.
+ - **showtypes**: One of: away, chat, dnd, and xa.
"""
name = 'presence'
@@ -93,8 +86,7 @@ class Presence(RootStanza):
"""
Set the value of the <show> element.
- Arguments:
- show -- Must be one of: away, chat, dnd, or xa.
+ :param str show: Must be one of: away, chat, dnd, or xa.
"""
if show is None:
self._del_sub('show')
@@ -119,8 +111,7 @@ class Presence(RootStanza):
Set the type attribute's value, and the <show> element
if applicable.
- Arguments:
- value -- Must be in either self.types or self.showtypes.
+ :param str value: Must be in either self.types or self.showtypes.
"""
if value in self.types:
self['show'] = None
@@ -146,14 +137,15 @@ class Presence(RootStanza):
Bot clients should typically use a priority of 0 if the same
JID is used elsewhere by a human-interacting client.
- Arguments:
- value -- An integer value greater than or equal to 0.
+ :param int value: An integer value greater than or equal to 0.
"""
self._set_sub_text('priority', text=str(value))
def get_priority(self):
"""
Return the value of the <presence> element as an integer.
+
+ :rtype: int
"""
p = self._get_sub_text('priority')
if not p:
@@ -166,26 +158,16 @@ class Presence(RootStanza):
def reply(self, clear=True):
"""
- Set the appropriate presence reply type.
+ Create a new reply <presence/> stanza from ``self``.
Overrides StanzaBase.reply.
- Arguments:
- clear -- Indicates if the stanza contents should be removed
- before replying. Defaults to True.
+ :param bool clear: Indicates if the stanza contents should be removed
+ before replying. Defaults to True.
"""
+ new_presence = StanzaBase.reply(self, clear)
if self['type'] == 'unsubscribe':
- self['type'] = 'unsubscribed'
+ new_presence['type'] = 'unsubscribed'
elif self['type'] == 'subscribe':
- self['type'] = 'subscribed'
- return StanzaBase.reply(self, clear)
-
-
-# To comply with PEP8, method names now use underscores.
-# Deprecated method names are re-mapped for backwards compatibility.
-Presence.setShow = Presence.set_show
-Presence.getType = Presence.get_type
-Presence.setType = Presence.set_type
-Presence.delType = Presence.get_type
-Presence.getPriority = Presence.get_priority
-Presence.setPriority = Presence.set_priority
+ new_presence['type'] = 'subscribed'
+ return new_presence
diff --git a/sleekxmpp/stanza/rootstanza.py b/slixmpp/stanza/rootstanza.py
index 52b807e5..a6dd958e 100644
--- a/sleekxmpp/stanza/rootstanza.py
+++ b/slixmpp/stanza/rootstanza.py
@@ -1,16 +1,16 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
-from sleekxmpp.exceptions import XMPPError, IqError, IqTimeout
-from sleekxmpp.stanza import Error
-from sleekxmpp.xmlstream import ET, StanzaBase, register_stanza_plugin
+from slixmpp.exceptions import XMPPError, IqError, IqTimeout
+from slixmpp.stanza import Error
+from slixmpp.xmlstream import ET, StanzaBase, register_stanza_plugin
log = logging.getLogger(__name__)
@@ -46,41 +46,41 @@ class RootStanza(StanzaBase):
# locally. Using the condition/text from that error
# response could leak too much information, so we'll
# only use a generic error here.
- self.reply()
- self['error']['condition'] = 'undefined-condition'
- self['error']['text'] = 'External error'
- self['error']['type'] = 'cancel'
+ reply = self.reply()
+ reply['error']['condition'] = 'undefined-condition'
+ reply['error']['text'] = 'External error'
+ reply['error']['type'] = 'cancel'
log.warning('You should catch IqError exceptions')
- self.send()
+ reply.send()
elif isinstance(e, IqTimeout):
- self.reply()
- self['error']['condition'] = 'remote-server-timeout'
- self['error']['type'] = 'wait'
+ reply = self.reply()
+ reply['error']['condition'] = 'remote-server-timeout'
+ reply['error']['type'] = 'wait'
log.warning('You should catch IqTimeout exceptions')
- self.send()
+ reply.send()
elif isinstance(e, XMPPError):
# We raised this deliberately
keep_id = self['id']
- self.reply(clear=e.clear)
- self['id'] = keep_id
- self['error']['condition'] = e.condition
- self['error']['text'] = e.text
- self['error']['type'] = e.etype
+ reply = self.reply(clear=e.clear)
+ reply['id'] = keep_id
+ reply['error']['condition'] = e.condition
+ reply['error']['text'] = e.text
+ reply['error']['type'] = e.etype
if e.extension is not None:
# Extended error tag
extxml = ET.Element("{%s}%s" % (e.extension_ns, e.extension),
e.extension_args)
- self['error'].append(extxml)
- self.send()
+ reply['error'].append(extxml)
+ reply.send()
else:
# We probably didn't raise this on purpose, so send an error stanza
keep_id = self['id']
- self.reply()
- self['id'] = keep_id
- self['error']['condition'] = 'undefined-condition'
- self['error']['text'] = "SleekXMPP got into trouble."
- self['error']['type'] = 'cancel'
- self.send()
+ reply = self.reply()
+ reply['id'] = keep_id
+ reply['error']['condition'] = 'undefined-condition'
+ reply['error']['text'] = "Slixmpp got into trouble."
+ reply['error']['type'] = 'cancel'
+ reply.send()
# log the error
log.exception('Error handling {%s}%s stanza',
self.namespace, self.name)
diff --git a/sleekxmpp/stanza/roster.py b/slixmpp/stanza/roster.py
index 681efd4f..c017c33f 100644
--- a/sleekxmpp/stanza/roster.py
+++ b/slixmpp/stanza/roster.py
@@ -1,14 +1,14 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza import Iq
-from sleekxmpp.xmlstream import JID
-from sleekxmpp.xmlstream import ET, ElementBase, register_stanza_plugin
+from slixmpp.stanza import Iq
+from slixmpp.xmlstream import JID
+from slixmpp.xmlstream import ET, ElementBase, register_stanza_plugin
class Roster(ElementBase):
@@ -150,9 +150,3 @@ class RosterItem(ElementBase):
register_stanza_plugin(Iq, Roster)
register_stanza_plugin(Roster, RosterItem, iterable=True)
-
-# To comply with PEP8, method names now use underscores.
-# Deprecated method names are re-mapped for backwards compatibility.
-Roster.setItems = Roster.set_items
-Roster.getItems = Roster.get_items
-Roster.delItems = Roster.del_items
diff --git a/sleekxmpp/stanza/stream_error.py b/slixmpp/stanza/stream_error.py
index ed0078c9..d8b8bb5a 100644
--- a/sleekxmpp/stanza/stream_error.py
+++ b/slixmpp/stanza/stream_error.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.stanza.error import Error
-from sleekxmpp.xmlstream import StanzaBase
+from slixmpp.stanza.error import Error
+from slixmpp.xmlstream import StanzaBase
class StreamError(Error, StanzaBase):
diff --git a/sleekxmpp/stanza/stream_features.py b/slixmpp/stanza/stream_features.py
index e487721e..05788771 100644
--- a/sleekxmpp/stanza/stream_features.py
+++ b/slixmpp/stanza/stream_features.py
@@ -1,13 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.thirdparty import OrderedDict
-from sleekxmpp.xmlstream import StanzaBase
+from collections import OrderedDict
+from slixmpp.xmlstream import StanzaBase
class StreamFeatures(StanzaBase):
diff --git a/slixmpp/stringprep.py b/slixmpp/stringprep.py
new file mode 100644
index 00000000..99506d78
--- /dev/null
+++ b/slixmpp/stringprep.py
@@ -0,0 +1,121 @@
+# -*- coding: utf-8 -*-
+"""
+ slixmpp.stringprep
+ ~~~~~~~~~~~~~~~~~~~~~~~
+
+ This module is a fallback using python’s stringprep instead of libidn’s.
+
+ Part of Slixmpp: The Slick XMPP Library
+
+ :copyright: (c) 2015 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+ :license: MIT, see LICENSE for more details
+"""
+
+import logging
+import stringprep
+from slixmpp.util import stringprep_profiles
+import encodings.idna
+
+class StringprepError(Exception):
+ pass
+
+#: These characters are not allowed to appear in a domain part.
+ILLEGAL_CHARS = ('\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r'
+ '\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19'
+ '\x1a\x1b\x1c\x1d\x1e\x1f'
+ ' !"#$%&\'()*+,./:;<=>?@[\\]^_`{|}~\x7f')
+
+
+# pylint: disable=c0103
+#: The nodeprep profile of stringprep used to validate the local,
+#: or username, portion of a JID.
+_nodeprep = stringprep_profiles.create(
+ nfkc=True,
+ bidi=True,
+ mappings=[
+ stringprep_profiles.b1_mapping,
+ stringprep.map_table_b2],
+ prohibited=[
+ stringprep.in_table_c11,
+ stringprep.in_table_c12,
+ stringprep.in_table_c21,
+ stringprep.in_table_c22,
+ stringprep.in_table_c3,
+ stringprep.in_table_c4,
+ stringprep.in_table_c5,
+ stringprep.in_table_c6,
+ stringprep.in_table_c7,
+ stringprep.in_table_c8,
+ stringprep.in_table_c9,
+ lambda c: c in ' \'"&/:<>@'],
+ unassigned=[stringprep.in_table_a1])
+
+def nodeprep(node):
+ try:
+ return _nodeprep(node)
+ except stringprep_profiles.StringPrepError:
+ raise StringprepError
+
+# pylint: disable=c0103
+#: The resourceprep profile of stringprep, which is used to validate
+#: the resource portion of a JID.
+_resourceprep = stringprep_profiles.create(
+ nfkc=True,
+ bidi=True,
+ mappings=[stringprep_profiles.b1_mapping],
+ prohibited=[
+ stringprep.in_table_c12,
+ stringprep.in_table_c21,
+ stringprep.in_table_c22,
+ stringprep.in_table_c3,
+ stringprep.in_table_c4,
+ stringprep.in_table_c5,
+ stringprep.in_table_c6,
+ stringprep.in_table_c7,
+ stringprep.in_table_c8,
+ stringprep.in_table_c9],
+ unassigned=[stringprep.in_table_a1])
+
+def resourceprep(resource):
+ try:
+ return _resourceprep(resource)
+ except stringprep_profiles.StringPrepError:
+ raise StringprepError
+
+def idna(domain):
+ domain_parts = []
+ for label in domain.split('.'):
+ try:
+ label = encodings.idna.nameprep(label)
+ encodings.idna.ToASCII(label)
+ except UnicodeError:
+ raise StringprepError
+
+ if label.startswith('xn--'):
+ label = encodings.idna.ToUnicode(label)
+
+ for char in label:
+ if char in ILLEGAL_CHARS:
+ raise StringprepError
+
+ domain_parts.append(label)
+ return '.'.join(domain_parts)
+
+def punycode(domain):
+ domain_parts = []
+ for label in domain.split('.'):
+ try:
+ label = encodings.idna.nameprep(label)
+ encodings.idna.ToASCII(label)
+ except UnicodeError:
+ raise StringprepError
+
+ for char in label:
+ if char in ILLEGAL_CHARS:
+ raise StringprepError
+
+ domain_parts.append(label)
+ return b'.'.join(domain_parts)
+
+logging.getLogger(__name__).warning('Using slower stringprep, consider '
+ 'compiling the faster cython/libidn one.')
diff --git a/slixmpp/stringprep.pyx b/slixmpp/stringprep.pyx
new file mode 100644
index 00000000..e751c8ea
--- /dev/null
+++ b/slixmpp/stringprep.pyx
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+# cython: language_level = 3
+# distutils: libraries = idn
+"""
+ slixmpp.stringprep
+ ~~~~~~~~~~~~~~~~~~~~~~~
+
+ This module wraps libidn’s stringprep and idna functions using Cython.
+
+ Part of Slixmpp: The Slick XMPP Library
+
+ :copyright: (c) 2015 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+ :license: MIT, see LICENSE for more details
+"""
+
+from libc.stdlib cimport free
+
+
+# Those are Cython declarations for the C function we’ll be using.
+
+cdef extern from "stringprep.h" nogil:
+ int stringprep_profile(const char* in_, char** out, const char* profile,
+ int flags)
+
+cdef extern from "idna.h" nogil:
+ int idna_to_ascii_8z(const char* in_, char** out, int flags)
+ int idna_to_unicode_8z8z(const char* in_, char** out, int flags)
+
+
+class StringprepError(Exception):
+ pass
+
+
+cdef str _stringprep(str in_, const char* profile):
+ """Python wrapper for libidn’s stringprep."""
+ cdef char* out
+ ret = stringprep_profile(in_.encode('utf-8'), &out, profile, 0)
+ if ret != 0:
+ raise StringprepError(ret)
+ unicode_out = out.decode('utf-8')
+ free(out)
+ return unicode_out
+
+
+def nodeprep(str node):
+ """The nodeprep profile of stringprep used to validate the local, or
+ username, portion of a JID."""
+ return _stringprep(node, 'Nodeprep')
+
+
+def resourceprep(str resource):
+ """The resourceprep profile of stringprep, which is used to validate the
+ resource portion of a JID."""
+ return _stringprep(resource, 'Resourceprep')
+
+
+def idna(str domain):
+ """The idna conversion functions, which are used to validate the domain
+ portion of a JID."""
+
+ cdef char* ascii_domain
+ cdef char* utf8_domain
+
+ ret = idna_to_ascii_8z(domain.encode('utf-8'), &ascii_domain, 0)
+ if ret != 0:
+ raise StringprepError(ret)
+
+ ret = idna_to_unicode_8z8z(ascii_domain, &utf8_domain, 0)
+ free(ascii_domain)
+ if ret != 0:
+ raise StringprepError(ret)
+
+ unicode_domain = utf8_domain.decode('utf-8')
+ free(utf8_domain)
+ return unicode_domain
+
+
+def punycode(str domain):
+ """Converts a domain name to its punycode representation."""
+
+ cdef char* ascii_domain
+ cdef bytes bytes_domain
+
+ ret = idna_to_ascii_8z(domain.encode('utf-8'), &ascii_domain, 0)
+ if ret != 0:
+ raise StringprepError(ret)
+ bytes_domain = ascii_domain
+ free(ascii_domain)
+ return bytes_domain
diff --git a/slixmpp/test/__init__.py b/slixmpp/test/__init__.py
new file mode 100644
index 00000000..0244afe3
--- /dev/null
+++ b/slixmpp/test/__init__.py
@@ -0,0 +1,11 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.test.mocksocket import TestSocket, TestTransport
+from slixmpp.test.livesocket import TestLiveSocket
+from slixmpp.test.slixtest import *
diff --git a/sleekxmpp/test/livesocket.py b/slixmpp/test/livesocket.py
index d70ee4eb..e7deb617 100644
--- a/sleekxmpp/test/livesocket.py
+++ b/slixmpp/test/livesocket.py
@@ -1,15 +1,14 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import socket
import threading
-
-from sleekxmpp.util import Queue
+from queue import Queue
class TestLiveSocket(object):
diff --git a/sleekxmpp/test/mocksocket.py b/slixmpp/test/mocksocket.py
index 4c9d1699..149df29c 100644
--- a/sleekxmpp/test/mocksocket.py
+++ b/slixmpp/test/mocksocket.py
@@ -1,14 +1,13 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import socket
-
-from sleekxmpp.util import Queue
+from queue import Queue
class TestSocket(object):
@@ -151,3 +150,96 @@ class TestSocket(object):
return self.recv_queue.get(block, timeout)
except:
return None
+
+class TestTransport(object):
+
+ """
+ A transport socket that reads and writes to queues instead
+ of an actual networking socket.
+
+ Methods:
+ next_sent -- Return the next sent stanza.
+ recv_data -- Make a stanza available to read next.
+ recv -- Read the next stanza from the socket.
+ send -- Write a stanza to the socket.
+ makefile -- Dummy call, returns self.
+ read -- Read the next stanza from the socket.
+ """
+
+ def __init__(self, xmpp):
+ self.xmpp = xmpp
+ self.socket = TestSocket()
+ # ------------------------------------------------------------------
+ # Testing Interface
+
+ def next_sent(self, timeout=None):
+ """
+ Get the next stanza that has been 'sent'.
+
+ Arguments:
+ timeout -- Optional timeout for waiting for a new value.
+ """
+ return self.socket.next_sent()
+
+ def disconnect_error(self):
+ """
+ Simulate a disconnect error by raising a socket.error exception
+ for any current or further socket operations.
+ """
+ self.socket.disconnect_error()
+
+ # ------------------------------------------------------------------
+ # Socket Interface
+
+ def recv(self, *args, **kwargs):
+ """
+ Read a value from the received queue.
+
+ Arguments:
+ Placeholders. Same as for socket.Socket.recv.
+ """
+ return
+
+ def write(self, data):
+ """
+ Send data by placing it in the send queue.
+
+ Arguments:
+ data -- String value to write.
+ """
+ self.socket.send(data)
+ return len(data)
+
+ # ------------------------------------------------------------------
+ # File Socket
+
+ def makefile(self, *args, **kwargs):
+ """
+ File socket version to use with ElementTree.
+
+ Arguments:
+ Placeholders, same as socket.Socket.makefile()
+ """
+ return self
+
+ def read(self, block=True, timeout=None, **kwargs):
+ """
+ Implement the file socket interface.
+
+ Arguments:
+ block -- Indicate if the read should block until a
+ value is ready.
+ timeout -- Time in seconds a block should last before
+ returning None.
+ """
+ return self.socket.recv(block, timeout, **kwargs)
+
+ def get_extra_info(self, *args, **kwargs):
+ return self.socket
+
+ def abort(self, *args, **kwargs):
+ return
+
+ def close(self, *args, **kwargs):
+ return
+
diff --git a/sleekxmpp/test/sleektest.py b/slixmpp/test/slixtest.py
index e26f99ce..f66cf6be 100644
--- a/sleekxmpp/test/sleektest.py
+++ b/slixmpp/test/slixtest.py
@@ -1,29 +1,33 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import unittest
+from queue import Queue
from xml.parsers.expat import ExpatError
-from sleekxmpp import ClientXMPP, ComponentXMPP
-from sleekxmpp.util import Queue
-from sleekxmpp.stanza import Message, Iq, Presence
-from sleekxmpp.test import TestSocket, TestLiveSocket
-from sleekxmpp.xmlstream import ET
-from sleekxmpp.xmlstream import ElementBase
-from sleekxmpp.xmlstream.tostring import tostring
-from sleekxmpp.xmlstream.matcher import StanzaPath, MatcherId, MatchIDSender
-from sleekxmpp.xmlstream.matcher import MatchXMLMask, MatchXPath
+from slixmpp.test import TestTransport
+from slixmpp import ClientXMPP, ComponentXMPP
+from slixmpp.stanza import Message, Iq, Presence
+from slixmpp.xmlstream import ET
+from slixmpp.xmlstream import ElementBase
+from slixmpp.xmlstream.tostring import tostring, highlight
+from slixmpp.xmlstream.matcher import StanzaPath, MatcherId, MatchIDSender
+from slixmpp.xmlstream.matcher import MatchXMLMask, MatchXPath
+import asyncio
+cls = asyncio.get_event_loop().__class__
-class SleekTest(unittest.TestCase):
+cls.idle_call = lambda self, callback: callback()
+
+class SlixTest(unittest.TestCase):
"""
- A SleekXMPP specific TestCase class that provides
+ A Slixmpp specific TestCase class that provides
methods for comparing message, iq, and presence stanzas.
Methods:
@@ -264,16 +268,16 @@ class SleekTest(unittest.TestCase):
stanza3.values = values
debug = "Three methods for creating stanzas do not match.\n"
- debug += "Given XML:\n%s\n" % tostring(xml)
- debug += "Given stanza:\n%s\n" % tostring(stanza.xml)
- debug += "Generated stanza:\n%s\n" % tostring(stanza2.xml)
- debug += "Second generated stanza:\n%s\n" % tostring(stanza3.xml)
+ debug += "Given XML:\n%s\n" % highlight(tostring(xml))
+ debug += "Given stanza:\n%s\n" % highlight(tostring(stanza.xml))
+ debug += "Generated stanza:\n%s\n" % highlight(tostring(stanza2.xml))
+ debug += "Second generated stanza:\n%s\n" % highlight(tostring(stanza3.xml))
result = self.compare(xml, stanza.xml, stanza2.xml, stanza3.xml)
else:
debug = "Two methods for creating stanzas do not match.\n"
- debug += "Given XML:\n%s\n" % tostring(xml)
- debug += "Given stanza:\n%s\n" % tostring(stanza.xml)
- debug += "Generated stanza:\n%s\n" % tostring(stanza2.xml)
+ debug += "Given XML:\n%s\n" % highlight(tostring(xml))
+ debug += "Given stanza:\n%s\n" % highlight(tostring(stanza.xml))
+ debug += "Generated stanza:\n%s\n" % highlight(tostring(stanza2.xml))
result = self.compare(xml, stanza.xml, stanza2.xml)
self.failUnless(result, debug)
@@ -288,8 +292,11 @@ class SleekTest(unittest.TestCase):
if self.xmpp:
self.xmpp.socket.disconnect_error()
- def stream_start(self, mode='client', skip=True, header=None, socket='mock', jid='tester@localhost',
- password='test', server='localhost', port=5222, sasl_mech=None, plugins=None, plugin_config=None):
+ def stream_start(self, mode='client', skip=True, header=None,
+ socket='mock', jid='tester@localhost/resource',
+ password='test', server='localhost',
+ port=5222, sasl_mech=None,
+ plugins=None, plugin_config={}):
"""
Initialize an XMPP client or component using a dummy XML stream.
@@ -303,7 +310,7 @@ class SleekTest(unittest.TestCase):
should be a dummy, mock socket or a live, functioning
socket. Defaults to 'mock'.
jid -- The JID to use for the connection.
- Defaults to 'tester@localhost'.
+ Defaults to 'tester@localhost/resource'.
password -- The password to use for the connection.
Defaults to 'test'.
server -- The name of the XMPP server. Defaults to 'localhost'.
@@ -326,41 +333,27 @@ class SleekTest(unittest.TestCase):
else:
raise ValueError("Unknown XMPP connection mode.")
+ self.xmpp.connection_made(TestTransport(self.xmpp))
+ self.xmpp.session_bind_event.set()
# Remove unique ID prefix to make it easier to test
self.xmpp._id_prefix = ''
- self.xmpp._disconnect_wait_for_threads = False
self.xmpp.default_lang = None
self.xmpp.peer_default_lang = None
- # We will use this to wait for the session_start event
- # for live connections.
- skip_queue = Queue()
+ # Simulate connecting for mock sockets.
+ self.xmpp.auto_reconnect = False
- if socket == 'mock':
- self.xmpp.set_socket(TestSocket())
+ # Must have the stream header ready for xmpp.process() to work.
+ if not header:
+ header = self.xmpp.stream_header
- # Simulate connecting for mock sockets.
- self.xmpp.auto_reconnect = False
- self.xmpp.state._set_state('connected')
+ self.xmpp.data_received(header)
- # Must have the stream header ready for xmpp.process() to work.
- if not header:
- header = self.xmpp.stream_header
- self.xmpp.socket.recv_data(header)
- elif socket == 'live':
- self.xmpp.socket_class = TestLiveSocket
+ if skip:
+ self.xmpp.socket.next_sent()
+ if mode == 'component':
+ self.xmpp.socket.next_sent()
- def wait_for_session(x):
- self.xmpp.socket.clear()
- skip_queue.put('started')
-
- self.xmpp.add_event_handler('session_start', wait_for_session)
- if server is not None:
- self.xmpp.connect((server, port))
- else:
- self.xmpp.connect()
- else:
- raise ValueError("Unknown socket type.")
if plugins is None:
self.xmpp.register_plugins()
@@ -372,19 +365,6 @@ class SleekTest(unittest.TestCase):
# this to True in tests related to those plugins.
self.xmpp.use_message_ids = False
- self.xmpp.process(threaded=True)
- if skip:
- if socket != 'live':
- # Mark send queue as usable
- self.xmpp.session_bind_event.set()
- self.xmpp.session_started_event.set()
- # Clear startup stanzas
- self.xmpp.socket.next_sent(timeout=1)
- if mode == 'component':
- self.xmpp.socket.next_sent(timeout=1)
- else:
- skip_queue.get(block=True, timeout=10)
-
def make_header(self, sto='',
sfrom='',
sid='',
@@ -446,27 +426,7 @@ class SleekTest(unittest.TestCase):
timeout -- Time to wait in seconds for data to be received by
a live connection.
"""
- if not defaults:
- defaults = []
-
- if self.xmpp.socket.is_live:
- # we are working with a live connection, so we should
- # verify what has been received instead of simulating
- # receiving data.
- recv_data = self.xmpp.socket.next_recv(timeout)
- if recv_data is None:
- self.fail("No stanza was received.")
- xml = self.parse_xml(recv_data)
- self.fix_namespaces(xml, 'jabber:client')
- stanza = self.xmpp._build_stanza(xml, 'jabber:client')
- self.check(stanza, data,
- method=method,
- defaults=defaults,
- use_values=use_values)
- else:
- # place the data in the dummy socket receiving queue.
- data = str(data)
- self.xmpp.socket.recv_data(data)
+ self.xmpp.data_received(data)
def recv_header(self, sto='',
sfrom='',
@@ -524,7 +484,7 @@ class SleekTest(unittest.TestCase):
if list(recv_xml):
# We received more than just the header
for xml in recv_xml:
- self.xmpp.socket.recv_data(tostring(xml))
+ self.xmpp.data_received(tostring(xml))
attrib = recv_xml.attrib
recv_xml.clear()
@@ -542,31 +502,7 @@ class SleekTest(unittest.TestCase):
if method is None and hasattr(self, 'match_method'):
method = getattr(self, 'match_method')
- if self.xmpp.socket.is_live:
- # we are working with a live connection, so we should
- # verify what has been received instead of simulating
- # receiving data.
- recv_data = self.xmpp.socket.next_recv(timeout)
- xml = self.parse_xml(data)
- recv_xml = self.parse_xml(recv_data)
- if recv_data is None:
- self.fail("No stanza was received.")
- if method == 'exact':
- self.failUnless(self.compare(xml, recv_xml),
- "Features do not match.\nDesired:\n%s\nReceived:\n%s" % (
- tostring(xml), tostring(recv_xml)))
- elif method == 'mask':
- matcher = MatchXMLMask(xml)
- self.failUnless(matcher.match(recv_xml),
- "Stanza did not match using %s method:\n" % method + \
- "Criteria:\n%s\n" % tostring(xml) + \
- "Stanza:\n%s" % tostring(recv_xml))
- else:
- raise ValueError("Uknown matching method: %s" % method)
- else:
- # place the data in the dummy socket receiving queue.
- data = str(data)
- self.xmpp.socket.recv_data(data)
+ self.xmpp.socket.data_received(data)
def send_header(self, sto='',
sfrom='',
@@ -626,13 +562,13 @@ class SleekTest(unittest.TestCase):
if method == 'exact':
self.failUnless(self.compare(xml, sent_xml),
"Features do not match.\nDesired:\n%s\nReceived:\n%s" % (
- tostring(xml), tostring(sent_xml)))
+ highlight(tostring(xml)), highlight(tostring(sent_xml))))
elif method == 'mask':
matcher = MatchXMLMask(xml)
self.failUnless(matcher.match(sent_xml),
"Stanza did not match using %s method:\n" % method + \
- "Criteria:\n%s\n" % tostring(xml) + \
- "Stanza:\n%s" % tostring(sent_xml))
+ "Criteria:\n%s\n" % highlight(tostring(xml)) + \
+ "Stanza:\n%s" % highlight(tostring(sent_xml)))
else:
raise ValueError("Uknown matching method: %s" % method)
@@ -684,7 +620,7 @@ class SleekTest(unittest.TestCase):
that the XMPP client is disconnected after an error.
"""
if hasattr(self, 'xmpp') and self.xmpp is not None:
- self.xmpp.socket.recv_data(self.xmpp.stream_footer)
+ self.xmpp.data_received(self.xmpp.stream_footer)
self.xmpp.disconnect()
# ------------------------------------------------------------------
diff --git a/slixmpp/thirdparty/__init__.py b/slixmpp/thirdparty/__init__.py
new file mode 100644
index 00000000..d950f4f9
--- /dev/null
+++ b/slixmpp/thirdparty/__init__.py
@@ -0,0 +1,7 @@
+try:
+ from gnupg import GPG
+except:
+ from slixmpp.thirdparty.gnupg import GPG
+
+from slixmpp.thirdparty.mini_dateutil import tzutc, tzoffset, parse_iso
+from slixmpp.thirdparty.orderedset import OrderedSet
diff --git a/sleekxmpp/thirdparty/gnupg.py b/slixmpp/thirdparty/gnupg.py
index a89289fd..a89289fd 100644
--- a/sleekxmpp/thirdparty/gnupg.py
+++ b/slixmpp/thirdparty/gnupg.py
diff --git a/sleekxmpp/thirdparty/mini_dateutil.py b/slixmpp/thirdparty/mini_dateutil.py
index e751a448..e751a448 100644
--- a/sleekxmpp/thirdparty/mini_dateutil.py
+++ b/slixmpp/thirdparty/mini_dateutil.py
diff --git a/sleekxmpp/thirdparty/orderedset.py b/slixmpp/thirdparty/orderedset.py
index f6642db3..f6642db3 100644
--- a/sleekxmpp/thirdparty/orderedset.py
+++ b/slixmpp/thirdparty/orderedset.py
diff --git a/slixmpp/util/__init__.py b/slixmpp/util/__init__.py
new file mode 100644
index 00000000..8f70b2bb
--- /dev/null
+++ b/slixmpp/util/__init__.py
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+"""
+ slixmpp.util
+ ~~~~~~~~~~~~~~
+
+ Part of Slixmpp: The Slick XMPP Library
+
+ :copyright: (c) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ :license: MIT, see LICENSE for more details
+"""
+
+
+from slixmpp.util.misc_ops import bytes, unicode, hashes, hash, \
+ num_to_bytes, bytes_to_num, quote, \
+ XOR
diff --git a/sleekxmpp/util/misc_ops.py b/slixmpp/util/misc_ops.py
index 18c919a8..2e661045 100644
--- a/sleekxmpp/util/misc_ops.py
+++ b/slixmpp/util/misc_ops.py
@@ -3,12 +3,7 @@ import hashlib
def unicode(text):
- if sys.version_info < (3, 0):
- if isinstance(text, str):
- text = text.decode('utf-8')
- import __builtin__
- return __builtin__.unicode(text)
- elif not isinstance(text, str):
+ if not isinstance(text, str):
return text.decode('utf-8')
else:
return text
@@ -27,20 +22,16 @@ def bytes(text):
if text is None:
return b''
- if sys.version_info < (3, 0):
- import __builtin__
- return __builtin__.bytes(text)
+ import builtins
+ if isinstance(text, builtins.bytes):
+ # We already have bytes, so do nothing
+ return text
+ if isinstance(text, list):
+ # Convert a list of integers to bytes
+ return builtins.bytes(text)
else:
- import builtins
- if isinstance(text, builtins.bytes):
- # We already have bytes, so do nothing
- return text
- if isinstance(text, list):
- # Convert a list of integers to bytes
- return builtins.bytes(text)
- else:
- # Convert UTF-8 text to bytes
- return builtins.bytes(text, encoding='utf-8')
+ # Convert UTF-8 text to bytes
+ return builtins.bytes(text, encoding='utf-8')
def quote(text):
@@ -91,10 +82,7 @@ def XOR(x, y):
"""
result = b''
for a, b in zip(x, y):
- if sys.version_info < (3, 0):
- result += chr((ord(a) ^ ord(b)))
- else:
- result += bytes([a ^ b])
+ result += bytes([a ^ b])
return result
@@ -153,13 +141,3 @@ def setdefaultencoding(encoding):
raise RuntimeError("Could not find setdefaultencoding")
sys.setdefaultencoding = func
return func(encoding)
-
-
-def safedict(data):
- if sys.version_info < (2, 7):
- safe = {}
- for key in data:
- safe[key.encode('utf8')] = data[key]
- return safe
- else:
- return data
diff --git a/sleekxmpp/util/sasl/__init__.py b/slixmpp/util/sasl/__init__.py
index 2d344e9b..0e7e7fbd 100644
--- a/sleekxmpp/util/sasl/__init__.py
+++ b/slixmpp/util/sasl/__init__.py
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.util.sasl
+ slixmpp.util.sasl
~~~~~~~~~~~~~~~~~~~
This module was originally based on Dave Cridland's Suelta library.
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copryight: (c) 2004-2013 David Alan Cridland
:copyright: (c) 2013 Nathanael C. Fritz, Lance J.T. Stout
@@ -13,5 +13,5 @@
:license: MIT, see LICENSE for more details
"""
-from sleekxmpp.util.sasl.client import *
-from sleekxmpp.util.sasl.mechanisms import *
+from slixmpp.util.sasl.client import *
+from slixmpp.util.sasl.mechanisms import *
diff --git a/sleekxmpp/util/sasl/client.py b/slixmpp/util/sasl/client.py
index fd685547..d5daf4be 100644
--- a/sleekxmpp/util/sasl/client.py
+++ b/slixmpp/util/sasl/client.py
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.util.sasl.client
+ slixmpp.util.sasl.client
~~~~~~~~~~~~~~~~~~~~~~~~~~
This module was originally based on Dave Cridland's Suelta library.
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copryight: (c) 2004-2013 David Alan Cridland
:copyright: (c) 2013 Nathanael C. Fritz, Lance J.T. Stout
@@ -16,7 +16,7 @@
import logging
import stringprep
-from sleekxmpp.util import hashes, bytes, stringprep_profiles
+from slixmpp.util import hashes, bytes, stringprep_profiles
log = logging.getLogger(__name__)
diff --git a/sleekxmpp/util/sasl/mechanisms.py b/slixmpp/util/sasl/mechanisms.py
index 7a7ebf7b..de0203c0 100644
--- a/sleekxmpp/util/sasl/mechanisms.py
+++ b/slixmpp/util/sasl/mechanisms.py
@@ -1,13 +1,13 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.util.sasl.mechanisms
+ slixmpp.util.sasl.mechanisms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A collection of supported SASL mechanisms.
This module was originally based on Dave Cridland's Suelta library.
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copryight: (c) 2004-2013 David Alan Cridland
:copyright: (c) 2013 Nathanael C. Fritz, Lance J.T. Stout
@@ -15,14 +15,13 @@
:license: MIT, see LICENSE for more details
"""
-import sys
import hmac
import random
from base64 import b64encode, b64decode
-from sleekxmpp.util import bytes, hash, XOR, quote, num_to_bytes
-from sleekxmpp.util.sasl.client import sasl_mech, Mech, \
+from slixmpp.util import bytes, hash, XOR, quote, num_to_bytes
+from slixmpp.util.sasl.client import sasl_mech, Mech, \
SASLCancelled, SASLFailed, \
SASLMutualAuthFailed
@@ -227,9 +226,9 @@ class SCRAM(Mech):
escaped = []
for char in value:
if char == ',':
- escaped += '=2C'
+ escaped += b'=2C'
elif char == '=':
- escaped += '=3D'
+ escaped += b'=3D'
else:
escaped += char
return "".join(escaped).encode("utf-8")
@@ -365,8 +364,7 @@ class DIGEST(Mech):
for char in challenge:
- if sys.version_info >= (3, 0):
- char = bytes([char])
+ char = bytes([char])
if state == 'var':
if char.isspace():
diff --git a/sleekxmpp/util/stringprep_profiles.py b/slixmpp/util/stringprep_profiles.py
index 84326bc3..5fb0b4b7 100644
--- a/sleekxmpp/util/stringprep_profiles.py
+++ b/slixmpp/util/stringprep_profiles.py
@@ -1,13 +1,13 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.util.stringprep_profiles
+ slixmpp.util.stringprep_profiles
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This module makes it easier to define profiles of stringprep,
such as nodeprep and resourceprep for JID validation, and
SASLprep for SASL.
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2012 Nathanael C. Fritz, Lance J.T. Stout
:license: MIT, see LICENSE for more details
@@ -19,7 +19,7 @@ from __future__ import unicode_literals
import stringprep
from unicodedata import ucd_3_2_0 as unicodedata
-from sleekxmpp.util import unicode
+from slixmpp.util import unicode
class StringPrepError(UnicodeError):
diff --git a/sleekxmpp/version.py b/slixmpp/version.py
index acea9334..98a20603 100644
--- a/sleekxmpp/version.py
+++ b/slixmpp/version.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -9,5 +9,5 @@
# We don't want to have to import the entire library
# just to get the version info for setup.py
-__version__ = '1.4.0'
-__version_info__ = (1, 4, 0, '', 0)
+__version__ = '1.0'
+__version_info__ = (1, 0)
diff --git a/slixmpp/xmlstream/__init__.py b/slixmpp/xmlstream/__init__.py
new file mode 100644
index 00000000..b5302292
--- /dev/null
+++ b/slixmpp/xmlstream/__init__.py
@@ -0,0 +1,17 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.jid import JID
+from slixmpp.xmlstream.stanzabase import StanzaBase, ElementBase, ET
+from slixmpp.xmlstream.stanzabase import register_stanza_plugin
+from slixmpp.xmlstream.tostring import tostring, highlight
+from slixmpp.xmlstream.xmlstream import XMLStream, RESPONSE_TIMEOUT
+
+__all__ = ['JID', 'StanzaBase', 'ElementBase',
+ 'ET', 'StateMachine', 'tostring', 'highlight', 'XMLStream',
+ 'RESPONSE_TIMEOUT']
diff --git a/slixmpp/xmlstream/asyncio.py b/slixmpp/xmlstream/asyncio.py
new file mode 100644
index 00000000..0e0f610a
--- /dev/null
+++ b/slixmpp/xmlstream/asyncio.py
@@ -0,0 +1,50 @@
+"""
+A module that monkey patches the standard asyncio module to add an
+idle_call() method to the main loop. This method is used to execute a
+callback whenever the loop is not busy handling anything else. This means
+that it is a callback with lower priority than IO, timer, or even
+call_soon() ones. These callback are called only once each.
+"""
+
+import asyncio
+from asyncio import events
+from functools import wraps
+
+import collections
+
+def idle_call(self, callback):
+ if asyncio.iscoroutinefunction(callback):
+ raise TypeError("coroutines cannot be used with idle_call()")
+ handle = events.Handle(callback, [], self)
+ self._idle.append(handle)
+
+def my_run_once(self):
+ if self._idle:
+ self._ready.append(events.Handle(lambda: None, (), self))
+ real_run_once(self)
+ if self._idle:
+ handle = self._idle.popleft()
+ handle._run()
+
+cls = asyncio.get_event_loop().__class__
+
+cls._idle = collections.deque()
+cls.idle_call = idle_call
+real_run_once = cls._run_once
+cls._run_once = my_run_once
+
+def future_wrapper(func):
+ """
+ Make sure the result of a function call is an asyncio.Future()
+ object.
+ """
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ result = func(*args, **kwargs)
+ if isinstance(result, asyncio.Future):
+ return result
+ future = asyncio.Future()
+ future.set_result(result)
+ return future
+
+ return wrapper
diff --git a/sleekxmpp/xmlstream/cert.py b/slixmpp/xmlstream/cert.py
index d357b326..d357b326 100644
--- a/sleekxmpp/xmlstream/cert.py
+++ b/slixmpp/xmlstream/cert.py
diff --git a/slixmpp/xmlstream/handler/__init__.py b/slixmpp/xmlstream/handler/__init__.py
new file mode 100644
index 00000000..51a7ca6a
--- /dev/null
+++ b/slixmpp/xmlstream/handler/__init__.py
@@ -0,0 +1,16 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.xmlstream.handler.callback import Callback
+from slixmpp.xmlstream.handler.coroutine_callback import CoroutineCallback
+from slixmpp.xmlstream.handler.collector import Collector
+from slixmpp.xmlstream.handler.waiter import Waiter
+from slixmpp.xmlstream.handler.xmlcallback import XMLCallback
+from slixmpp.xmlstream.handler.xmlwaiter import XMLWaiter
+
+__all__ = ['Callback', 'CoroutineCallback', 'Waiter', 'XMLCallback', 'XMLWaiter']
diff --git a/sleekxmpp/xmlstream/handler/base.py b/slixmpp/xmlstream/handler/base.py
index 01c1991a..b6bff096 100644
--- a/sleekxmpp/xmlstream/handler/base.py
+++ b/slixmpp/xmlstream/handler/base.py
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.xmlstream.handler.base
+ slixmpp.xmlstream.handler.base
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
@@ -25,10 +25,10 @@ class BaseHandler(object):
during the second.
:param string name: The name of the handler.
- :param matcher: A :class:`~sleekxmpp.xmlstream.matcher.base.MatcherBase`
+ :param matcher: A :class:`~slixmpp.xmlstream.matcher.base.MatcherBase`
derived object that will be used to determine if a
stanza should be accepted by this handler.
- :param stream: The :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream`
+ :param stream: The :class:`~slixmpp.xmlstream.xmlstream.XMLStream`
instance that the handle will respond to.
"""
@@ -50,7 +50,7 @@ class BaseHandler(object):
"""Compare a stanza or XML object with the handler's matcher.
:param xml: An XML or
- :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase` object
+ :class:`~slixmpp.xmlstream.stanzabase.ElementBase` object
"""
return self._matcher.match(xml)
@@ -58,7 +58,7 @@ class BaseHandler(object):
"""Prepare the handler for execution while the XML
stream is being processed.
- :param payload: A :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase`
+ :param payload: A :class:`~slixmpp.xmlstream.stanzabase.ElementBase`
object.
"""
self._payload = payload
@@ -67,7 +67,7 @@ class BaseHandler(object):
"""Execute the handler after XML stream processing and during the
main event loop.
- :param payload: A :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase`
+ :param payload: A :class:`~slixmpp.xmlstream.stanzabase.ElementBase`
object.
"""
self._payload = payload
@@ -77,8 +77,3 @@ class BaseHandler(object):
of stream handlers.
"""
return self._destroy
-
-
-# To comply with PEP8, method names now use underscores.
-# Deprecated method names are re-mapped for backwards compatibility.
-BaseHandler.checkDelete = BaseHandler.check_delete
diff --git a/sleekxmpp/xmlstream/handler/callback.py b/slixmpp/xmlstream/handler/callback.py
index 7e3388f1..4cb329af 100644
--- a/sleekxmpp/xmlstream/handler/callback.py
+++ b/slixmpp/xmlstream/handler/callback.py
@@ -1,15 +1,15 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.xmlstream.handler.callback
+ slixmpp.xmlstream.handler.callback
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
"""
-from sleekxmpp.xmlstream.handler.base import BaseHandler
+from slixmpp.xmlstream.handler.base import BaseHandler
class Callback(BaseHandler):
@@ -23,14 +23,14 @@ class Callback(BaseHandler):
Callback functions are all executed in the same thread, so be aware if
you are executing functions that will block for extended periods of
- time. Typically, you should signal your own events using the SleekXMPP
- object's :meth:`~sleekxmpp.xmlstream.xmlstream.XMLStream.event()`
+ time. Typically, you should signal your own events using the Slixmpp
+ object's :meth:`~slixmpp.xmlstream.xmlstream.XMLStream.event()`
method to pass the stanza off to a threaded event handler for further
processing.
:param string name: The name of the handler.
- :param matcher: A :class:`~sleekxmpp.xmlstream.matcher.base.MatcherBase`
+ :param matcher: A :class:`~slixmpp.xmlstream.matcher.base.MatcherBase`
derived object for matching stanza objects.
:param pointer: The function to execute during callback.
:param bool thread: **DEPRECATED.** Remains only for
@@ -40,7 +40,7 @@ class Callback(BaseHandler):
:param bool instream: Indicates if the callback should be executed
during stream processing instead of in the
main event loop.
- :param stream: The :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream`
+ :param stream: The :class:`~slixmpp.xmlstream.xmlstream.XMLStream`
instance this handler should monitor.
"""
@@ -56,7 +56,7 @@ class Callback(BaseHandler):
the callback was created with ``instream=True``.
:param payload: The matched
- :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase` object.
+ :class:`~slixmpp.xmlstream.stanzabase.ElementBase` object.
"""
if self._once:
self._destroy = True
@@ -67,7 +67,7 @@ class Callback(BaseHandler):
"""Execute the callback function with the matched stanza payload.
:param payload: The matched
- :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase` object.
+ :class:`~slixmpp.xmlstream.stanzabase.ElementBase` object.
:param bool instream: Force the handler to execute during stream
processing. This should only be used by
:meth:`prerun()`. Defaults to ``False``.
diff --git a/sleekxmpp/xmlstream/handler/collector.py b/slixmpp/xmlstream/handler/collector.py
index 8f02f8c3..d9e20279 100644
--- a/sleekxmpp/xmlstream/handler/collector.py
+++ b/slixmpp/xmlstream/handler/collector.py
@@ -1,18 +1,18 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.xmlstream.handler.collector
+ slixmpp.xmlstream.handler.collector
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2012 Nathanael C. Fritz, Lance J.T. Stout
:license: MIT, see LICENSE for more details
"""
import logging
+from queue import Queue, Empty
-from sleekxmpp.util import Queue, QueueEmpty
-from sleekxmpp.xmlstream.handler.base import BaseHandler
+from slixmpp.xmlstream.handler.base import BaseHandler
log = logging.getLogger(__name__)
@@ -27,9 +27,9 @@ class Collector(BaseHandler):
accumulate matching stanzas until told to stop.
:param string name: The name of the handler.
- :param matcher: A :class:`~sleekxmpp.xmlstream.matcher.base.MatcherBase`
+ :param matcher: A :class:`~slixmpp.xmlstream.matcher.base.MatcherBase`
derived object for matching stanza objects.
- :param stream: The :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream`
+ :param stream: The :class:`~slixmpp.xmlstream.xmlstream.XMLStream`
instance this handler should monitor.
"""
@@ -41,7 +41,7 @@ class Collector(BaseHandler):
"""Store the matched stanza when received during processing.
:param payload: The matched
- :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase` object.
+ :class:`~slixmpp.xmlstream.stanzabase.ElementBase` object.
"""
self._payload.put(payload)
@@ -59,7 +59,7 @@ class Collector(BaseHandler):
try:
while True:
results.append(self._payload.get(False))
- except QueueEmpty:
+ except Empty:
pass
self.stream().remove_handler(self.name)
diff --git a/slixmpp/xmlstream/handler/coroutine_callback.py b/slixmpp/xmlstream/handler/coroutine_callback.py
new file mode 100644
index 00000000..8ad9572e
--- /dev/null
+++ b/slixmpp/xmlstream/handler/coroutine_callback.py
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*-
+"""
+ slixmpp.xmlstream.handler.callback
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Part of Slixmpp: The Slick XMPP Library
+
+ :copyright: (c) 2011 Nathanael C. Fritz
+ :license: MIT, see LICENSE for more details
+"""
+
+from slixmpp.xmlstream.handler.base import BaseHandler
+from slixmpp.xmlstream.asyncio import asyncio
+
+
+class CoroutineCallback(BaseHandler):
+
+ """
+ The Callback handler will execute a callback function with
+ matched stanzas.
+
+ The handler may execute the callback either during stream
+ processing or during the main event loop.
+
+ The event will be scheduled to be run soon in the event loop instead
+ of immediately.
+
+ :param string name: The name of the handler.
+ :param matcher: A :class:`~slixmpp.xmlstream.matcher.base.MatcherBase`
+ derived object for matching stanza objects.
+ :param pointer: The function to execute during callback. If ``pointer``
+ is not a coroutine, this function will raise a ValueError.
+ :param bool once: Indicates if the handler should be used only
+ once. Defaults to False.
+ :param bool instream: Indicates if the callback should be executed
+ during stream processing instead of in the
+ main event loop.
+ :param stream: The :class:`~slixmpp.xmlstream.xmlstream.XMLStream`
+ instance this handler should monitor.
+ """
+
+ def __init__(self, name, matcher, pointer, once=False,
+ instream=False, stream=None):
+ BaseHandler.__init__(self, name, matcher, stream)
+ if not asyncio.iscoroutinefunction(pointer):
+ raise ValueError("Given function is not a coroutine")
+
+ @asyncio.coroutine
+ def pointer_wrapper(stanza, *args, **kwargs):
+ try:
+ yield from pointer(stanza, *args, **kwargs)
+ except Exception as e:
+ stanza.exception(e)
+
+ self._pointer = pointer_wrapper
+ self._once = once
+ self._instream = instream
+
+ def prerun(self, payload):
+ """Execute the callback during stream processing, if
+ the callback was created with ``instream=True``.
+
+ :param payload: The matched
+ :class:`~slixmpp.xmlstream.stanzabase.ElementBase` object.
+ """
+ if self._once:
+ self._destroy = True
+ if self._instream:
+ self.run(payload, True)
+
+ def run(self, payload, instream=False):
+ """Execute the callback function with the matched stanza payload.
+
+ :param payload: The matched
+ :class:`~slixmpp.xmlstream.stanzabase.ElementBase` object.
+ :param bool instream: Force the handler to execute during stream
+ processing. This should only be used by
+ :meth:`prerun()`. Defaults to ``False``.
+ """
+ if not self._instream or instream:
+ asyncio.async(self._pointer(payload))
+ if self._once:
+ self._destroy = True
+ del self._pointer
diff --git a/sleekxmpp/xmlstream/handler/waiter.py b/slixmpp/xmlstream/handler/waiter.py
index 66e14496..c25063db 100644
--- a/sleekxmpp/xmlstream/handler/waiter.py
+++ b/slixmpp/xmlstream/handler/waiter.py
@@ -1,18 +1,18 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.xmlstream.handler.waiter
+ slixmpp.xmlstream.handler.waiter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
"""
import logging
+from queue import Queue, Empty
-from sleekxmpp.util import Queue, QueueEmpty
-from sleekxmpp.xmlstream.handler.base import BaseHandler
+from slixmpp.xmlstream.handler.base import BaseHandler
log = logging.getLogger(__name__)
@@ -26,9 +26,9 @@ class Waiter(BaseHandler):
given the matched stanza, or ``False`` if the waiter has timed out.
:param string name: The name of the handler.
- :param matcher: A :class:`~sleekxmpp.xmlstream.matcher.base.MatcherBase`
+ :param matcher: A :class:`~slixmpp.xmlstream.matcher.base.MatcherBase`
derived object for matching stanza objects.
- :param stream: The :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream`
+ :param stream: The :class:`~slixmpp.xmlstream.xmlstream.XMLStream`
instance this handler should monitor.
"""
@@ -40,7 +40,7 @@ class Waiter(BaseHandler):
"""Store the matched stanza when received during processing.
:param payload: The matched
- :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase` object.
+ :class:`~slixmpp.xmlstream.stanzabase.ElementBase` object.
"""
self._payload.put(payload)
@@ -59,7 +59,7 @@ class Waiter(BaseHandler):
:param int timeout: The number of seconds to wait for the stanza
to arrive. Defaults to the the stream's
- :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream.response_timeout`
+ :class:`~slixmpp.xmlstream.xmlstream.XMLStream.response_timeout`
value.
"""
if timeout is None:
@@ -71,7 +71,7 @@ class Waiter(BaseHandler):
try:
stanza = self._payload.get(True, 1)
break
- except QueueEmpty:
+ except Empty:
elapsed_time += 1
if elapsed_time >= timeout:
log.warning("Timed out waiting for %s", self.name)
diff --git a/sleekxmpp/xmlstream/handler/xmlcallback.py b/slixmpp/xmlstream/handler/xmlcallback.py
index 11607ffb..60ccbaed 100644
--- a/sleekxmpp/xmlstream/handler/xmlcallback.py
+++ b/slixmpp/xmlstream/handler/xmlcallback.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.handler import Callback
class XMLCallback(Callback):
diff --git a/sleekxmpp/xmlstream/handler/xmlwaiter.py b/slixmpp/xmlstream/handler/xmlwaiter.py
index 5201caf3..dc014da0 100644
--- a/sleekxmpp/xmlstream/handler/xmlwaiter.py
+++ b/slixmpp/xmlstream/handler/xmlwaiter.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream.handler import Waiter
+from slixmpp.xmlstream.handler import Waiter
class XMLWaiter(Waiter):
diff --git a/slixmpp/xmlstream/matcher/__init__.py b/slixmpp/xmlstream/matcher/__init__.py
new file mode 100644
index 00000000..47487d4a
--- /dev/null
+++ b/slixmpp/xmlstream/matcher/__init__.py
@@ -0,0 +1,17 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from slixmpp.xmlstream.matcher.id import MatcherId
+from slixmpp.xmlstream.matcher.idsender import MatchIDSender
+from slixmpp.xmlstream.matcher.many import MatchMany
+from slixmpp.xmlstream.matcher.stanzapath import StanzaPath
+from slixmpp.xmlstream.matcher.xmlmask import MatchXMLMask
+from slixmpp.xmlstream.matcher.xpath import MatchXPath
+
+__all__ = ['MatcherId', 'MatchMany', 'StanzaPath',
+ 'MatchXMLMask', 'MatchXPath']
diff --git a/sleekxmpp/xmlstream/matcher/base.py b/slixmpp/xmlstream/matcher/base.py
index 83c26688..4f15c63d 100644
--- a/sleekxmpp/xmlstream/matcher/base.py
+++ b/slixmpp/xmlstream/matcher/base.py
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.xmlstream.matcher.base
+ slixmpp.xmlstream.matcher.base
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
diff --git a/sleekxmpp/xmlstream/matcher/id.py b/slixmpp/xmlstream/matcher/id.py
index 11ab70bb..ddef75dc 100644
--- a/sleekxmpp/xmlstream/matcher/id.py
+++ b/slixmpp/xmlstream/matcher/id.py
@@ -1,15 +1,15 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.xmlstream.matcher.id
+ slixmpp.xmlstream.matcher.id
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
"""
-from sleekxmpp.xmlstream.matcher.base import MatcherBase
+from slixmpp.xmlstream.matcher.base import MatcherBase
class MatcherId(MatcherBase):
@@ -23,7 +23,7 @@ class MatcherId(MatcherBase):
"""Compare the given stanza's ``'id'`` attribute to the stored
``id`` value.
- :param xml: The :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase`
+ :param xml: The :class:`~slixmpp.xmlstream.stanzabase.ElementBase`
stanza to compare against.
"""
return xml['id'] == self._criteria
diff --git a/sleekxmpp/xmlstream/matcher/idsender.py b/slixmpp/xmlstream/matcher/idsender.py
index 5c2c1f51..79f73911 100644
--- a/sleekxmpp/xmlstream/matcher/idsender.py
+++ b/slixmpp/xmlstream/matcher/idsender.py
@@ -1,15 +1,15 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.xmlstream.matcher.id
+ slixmpp.xmlstream.matcher.id
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
"""
-from sleekxmpp.xmlstream.matcher.base import MatcherBase
+from slixmpp.xmlstream.matcher.base import MatcherBase
class MatchIDSender(MatcherBase):
@@ -24,7 +24,7 @@ class MatchIDSender(MatcherBase):
"""Compare the given stanza's ``'id'`` attribute to the stored
``id`` value, and verify the sender's JID.
- :param xml: The :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase`
+ :param xml: The :class:`~slixmpp.xmlstream.stanzabase.ElementBase`
stanza to compare against.
"""
diff --git a/sleekxmpp/xmlstream/matcher/many.py b/slixmpp/xmlstream/matcher/many.py
index f470ec9c..ef6a64d3 100644
--- a/sleekxmpp/xmlstream/matcher/many.py
+++ b/slixmpp/xmlstream/matcher/many.py
@@ -1,12 +1,12 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.xmlstream.matcher.base import MatcherBase
+from slixmpp.xmlstream.matcher.base import MatcherBase
class MatchMany(MatcherBase):
diff --git a/sleekxmpp/xmlstream/matcher/stanzapath.py b/slixmpp/xmlstream/matcher/stanzapath.py
index a4c0fda0..c9f245e1 100644
--- a/sleekxmpp/xmlstream/matcher/stanzapath.py
+++ b/slixmpp/xmlstream/matcher/stanzapath.py
@@ -1,16 +1,16 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.xmlstream.matcher.stanzapath
+ slixmpp.xmlstream.matcher.stanzapath
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
"""
-from sleekxmpp.xmlstream.matcher.base import MatcherBase
-from sleekxmpp.xmlstream.stanzabase import fix_ns
+from slixmpp.xmlstream.matcher.base import MatcherBase
+from slixmpp.xmlstream.stanzabase import fix_ns
class StanzaPath(MatcherBase):
@@ -34,10 +34,10 @@ class StanzaPath(MatcherBase):
Compare a stanza against a "stanza path". A stanza path is similar to
an XPath expression, but uses the stanza's interfaces and plugins
instead of the underlying XML. See the documentation for the stanza
- :meth:`~sleekxmpp.xmlstream.stanzabase.ElementBase.match()` method
+ :meth:`~slixmpp.xmlstream.stanzabase.ElementBase.match()` method
for more information.
- :param stanza: The :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase`
+ :param stanza: The :class:`~slixmpp.xmlstream.stanzabase.ElementBase`
stanza to compare against.
"""
return stanza.match(self._criteria) or stanza.match(self._raw_criteria)
diff --git a/sleekxmpp/xmlstream/matcher/xmlmask.py b/slixmpp/xmlstream/matcher/xmlmask.py
index 56f728e1..7e26abe2 100644
--- a/sleekxmpp/xmlstream/matcher/xmlmask.py
+++ b/slixmpp/xmlstream/matcher/xmlmask.py
@@ -1,7 +1,7 @@
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -10,8 +10,8 @@ import logging
from xml.parsers.expat import ExpatError
-from sleekxmpp.xmlstream.stanzabase import ET
-from sleekxmpp.xmlstream.matcher.base import MatcherBase
+from slixmpp.xmlstream.stanzabase import ET
+from slixmpp.xmlstream.matcher.base import MatcherBase
log = logging.getLogger(__name__)
@@ -29,8 +29,8 @@ class MatchXMLMask(MatcherBase):
<message xmlns="jabber:client"><body /></message>
Use of XMLMask is discouraged, and
- :class:`~sleekxmpp.xmlstream.matcher.xpath.MatchXPath` or
- :class:`~sleekxmpp.xmlstream.matcher.stanzapath.StanzaPath`
+ :class:`~slixmpp.xmlstream.matcher.xpath.MatchXPath` or
+ :class:`~slixmpp.xmlstream.matcher.stanzapath.StanzaPath`
should be used instead.
:param criteria: Either an :class:`~xml.etree.ElementTree.Element` XML
diff --git a/sleekxmpp/xmlstream/matcher/xpath.py b/slixmpp/xmlstream/matcher/xpath.py
index f3d28429..31ab1b8c 100644
--- a/sleekxmpp/xmlstream/matcher/xpath.py
+++ b/slixmpp/xmlstream/matcher/xpath.py
@@ -1,16 +1,16 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.xmlstream.matcher.xpath
+ slixmpp.xmlstream.matcher.xpath
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
"""
-from sleekxmpp.xmlstream.stanzabase import ET, fix_ns
-from sleekxmpp.xmlstream.matcher.base import MatcherBase
+from slixmpp.xmlstream.stanzabase import ET, fix_ns
+from slixmpp.xmlstream.matcher.base import MatcherBase
class MatchXPath(MatcherBase):
@@ -26,7 +26,7 @@ class MatchXPath(MatcherBase):
:meth:`~xml.etree.ElementTree.Element.find()` method does
not support the use of attribute selectors. If you need to
support Python 2.6 or 3.1, it might be more useful to use a
- :class:`~sleekxmpp.xmlstream.matcher.stanzapath.StanzaPath` matcher.
+ :class:`~slixmpp.xmlstream.matcher.stanzapath.StanzaPath` matcher.
If the value of :data:`IGNORE_NS` is set to ``True``, then XPath
expressions will be matched without using namespaces.
@@ -48,7 +48,7 @@ class MatchXPath(MatcherBase):
:meth:`~xml.etree.ElementTree.Element.find()` method does not
support attribute selectors in the XPath expression.
- :param xml: The :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase`
+ :param xml: The :class:`~slixmpp.xmlstream.stanzabase.ElementBase`
stanza to compare against.
"""
if hasattr(xml, 'xml'):
diff --git a/sleekxmpp/xmlstream/resolver.py b/slixmpp/xmlstream/resolver.py
index 188e5ac7..778f7dc3 100644
--- a/sleekxmpp/xmlstream/resolver.py
+++ b/slixmpp/xmlstream/resolver.py
@@ -1,13 +1,14 @@
# -*- encoding: utf-8 -*-
"""
- sleekxmpp.xmlstream.dns
+ slixmpp.xmlstream.dns
~~~~~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2012 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
"""
+from slixmpp.xmlstream.asyncio import asyncio
import socket
import logging
import random
@@ -16,51 +17,44 @@ import random
log = logging.getLogger(__name__)
-#: Global flag indicating the availability of the ``dnspython`` package.
-#: Installing ``dnspython`` can be done via:
+#: Global flag indicating the availability of the ``aiodns`` package.
+#: Installing ``aiodns`` can be done via:
#:
#: .. code-block:: sh
#:
-#: pip install dnspython
-#:
-#: For Python3, installation may require installing from source using
-#: the ``python3`` branch:
-#:
-#: .. code-block:: sh
-#:
-#: git clone http://github.com/rthalley/dnspython
-#: cd dnspython
-#: git checkout python3
-#: python3 setup.py install
-DNSPYTHON_AVAILABLE = False
+#: pip install aiodns
+AIODNS_AVAILABLE = False
try:
- import dns.resolver
- DNSPYTHON_AVAILABLE = True
+ import aiodns
+ AIODNS_AVAILABLE = True
except ImportError as e:
- log.debug("Could not find dnspython package. " + \
+ log.debug("Could not find aiodns package. " + \
"Not all features will be available")
-def default_resolver():
+def default_resolver(loop):
"""Return a basic DNS resolver object.
- :returns: A :class:`dns.resolver.Resolver` object if dnspython
+ :returns: A :class:`aiodns.DNSResolver` object if aiodns
is available. Otherwise, ``None``.
"""
- if DNSPYTHON_AVAILABLE:
- return dns.resolver.get_default_resolver()
+ if AIODNS_AVAILABLE:
+ return aiodns.DNSResolver(loop=loop,
+ tries=1,
+ timeout=1.0)
return None
+@asyncio.coroutine
def resolve(host, port=None, service=None, proto='tcp',
- resolver=None, use_ipv6=True, use_dnspython=True):
+ resolver=None, use_ipv6=True, use_aiodns=True, loop=None):
"""Peform DNS resolution for a given hostname.
Resolution may perform SRV record lookups if a service and protocol
are specified. The returned addresses will be sorted according to
the SRV priorities and weights.
- If no resolver is provided, the dnspython resolver will be used if
+ If no resolver is provided, the aiodns resolver will be used if
available. Otherwise the built-in socket facilities will be used,
but those do not provide SRV support.
@@ -77,7 +71,7 @@ def resolve(host, port=None, service=None, proto='tcp',
:param use_ipv6: Optionally control the use of IPv6 in situations
where it is either not available, or performance
is degraded. Defaults to ``True``.
- :param use_dnspython: Optionally control if dnspython is used to make
+ :param use_aiodns: Optionally control if aiodns is used to make
the DNS queries instead of the built-in DNS
library.
@@ -85,25 +79,25 @@ def resolve(host, port=None, service=None, proto='tcp',
:type port: int
:type service: string
:type proto: string
- :type resolver: :class:`dns.resolver.Resolver`
+ :type resolver: :class:`aiodns.DNSResolver`
:type use_ipv6: bool
- :type use_dnspython: bool
+ :type use_aiodns: bool
:return: An iterable of IP address, port pairs in the order
dictated by SRV priorities and weights, if applicable.
"""
- if not use_dnspython:
- if DNSPYTHON_AVAILABLE:
- log.debug("DNS: Not using dnspython, but dnspython is installed.")
+ if not use_aiodns:
+ if AIODNS_AVAILABLE:
+ log.debug("DNS: Not using aiodns, but aiodns is installed.")
else:
- log.debug("DNS: Not using dnspython.")
+ log.debug("DNS: Not using aiodns.")
if not use_ipv6:
log.debug("DNS: Use of IPv6 has been disabled.")
- if resolver is None and DNSPYTHON_AVAILABLE and use_dnspython:
- resolver = dns.resolver.get_default_resolver()
+ if resolver is None and AIODNS_AVAILABLE and use_aiodns:
+ resolver = aiodns.DNSResolver(loop=loop)
# An IPv6 literal is allowed to be enclosed in square brackets, but
# the brackets must be stripped in order to process the literal;
@@ -113,7 +107,7 @@ def resolve(host, port=None, service=None, proto='tcp',
try:
# If `host` is an IPv4 literal, we can return it immediately.
ipv4 = socket.inet_aton(host)
- yield (host, host, port)
+ return [(host, host, port)]
except socket.error:
pass
@@ -123,7 +117,7 @@ def resolve(host, port=None, service=None, proto='tcp',
# it immediately.
if hasattr(socket, 'inet_pton'):
ipv6 = socket.inet_pton(socket.AF_INET6, host)
- yield (host, host, port)
+ return [(host, host, port)]
except (socket.error, ValueError):
pass
@@ -133,29 +127,34 @@ def resolve(host, port=None, service=None, proto='tcp',
if not service:
hosts = [(host, port)]
else:
- hosts = get_SRV(host, port, service, proto,
- resolver=resolver,
- use_dnspython=use_dnspython)
+ hosts = yield from get_SRV(host, port, service, proto,
+ resolver=resolver,
+ use_aiodns=use_aiodns)
+ if not hosts:
+ hosts = [(host, port)]
+ results = []
for host, port in hosts:
- results = []
if host == 'localhost':
if use_ipv6:
results.append((host, '::1', port))
results.append((host, '127.0.0.1', port))
+
if use_ipv6:
- for address in get_AAAA(host, resolver=resolver,
- use_dnspython=use_dnspython):
+ aaaa = yield from get_AAAA(host, resolver=resolver,
+ use_aiodns=use_aiodns, loop=loop)
+ for address in aaaa:
results.append((host, address, port))
- for address in get_A(host, resolver=resolver,
- use_dnspython=use_dnspython):
- results.append((host, address, port))
- for host, address, port in results:
- yield host, address, port
+ a = yield from get_A(host, resolver=resolver,
+ use_aiodns=use_aiodns, loop=loop)
+ for address in a:
+ results.append((host, address, port))
+ return results
-def get_A(host, resolver=None, use_dnspython=True):
+@asyncio.coroutine
+def get_A(host, resolver=None, use_aiodns=True, loop=None):
"""Lookup DNS A records for a given host.
If ``resolver`` is not provided, or is ``None``, then resolution will
@@ -163,46 +162,42 @@ def get_A(host, resolver=None, use_dnspython=True):
:param host: The hostname to resolve for A record IPv4 addresses.
:param resolver: Optional DNS resolver object to use for the query.
- :param use_dnspython: Optionally control if dnspython is used to make
+ :param use_aiodns: Optionally control if aiodns is used to make
the DNS queries instead of the built-in DNS
library.
:type host: string
- :type resolver: :class:`dns.resolver.Resolver` or ``None``
- :type use_dnspython: bool
+ :type resolver: :class:`aiodns.DNSResolver` or ``None``
+ :type use_aiodns: bool
:return: A list of IPv4 literals.
"""
log.debug("DNS: Querying %s for A records." % host)
- # If not using dnspython, attempt lookup using the OS level
+ # If not using aiodns, attempt lookup using the OS level
# getaddrinfo() method.
- if resolver is None or not use_dnspython:
+ if resolver is None or not use_aiodns:
try:
- recs = socket.getaddrinfo(host, None, socket.AF_INET,
- socket.SOCK_STREAM)
+ recs = yield from loop.getaddrinfo(host, None,
+ family=socket.AF_INET,
+ type=socket.SOCK_STREAM)
return [rec[4][0] for rec in recs]
except socket.gaierror:
- log.debug("DNS: Error retreiving A address info for %s." % host)
+ log.debug("DNS: Error retrieving A address info for %s." % host)
return []
- # Using dnspython:
+ # Using aiodns:
+ future = resolver.query(host, 'A')
try:
- recs = resolver.query(host, dns.rdatatype.A)
- return [rec.to_text() for rec in recs]
- except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
- log.debug("DNS: No A records for %s" % host)
- return []
- except dns.exception.Timeout:
- log.debug("DNS: A record resolution timed out for %s" % host)
- return []
- except dns.exception.DNSException as e:
- log.debug("DNS: Error querying A records for %s" % host)
- log.exception(e)
- return []
+ recs = yield from future
+ except Exception as e:
+ log.debug('DNS: Exception while querying for %s A records: %s', host, e)
+ recs = []
+ return [rec.host for rec in recs]
-def get_AAAA(host, resolver=None, use_dnspython=True):
+@asyncio.coroutine
+def get_AAAA(host, resolver=None, use_aiodns=True, loop=None):
"""Lookup DNS AAAA records for a given host.
If ``resolver`` is not provided, or is ``None``, then resolution will
@@ -210,56 +205,51 @@ def get_AAAA(host, resolver=None, use_dnspython=True):
:param host: The hostname to resolve for AAAA record IPv6 addresses.
:param resolver: Optional DNS resolver object to use for the query.
- :param use_dnspython: Optionally control if dnspython is used to make
+ :param use_aiodns: Optionally control if aiodns is used to make
the DNS queries instead of the built-in DNS
library.
:type host: string
- :type resolver: :class:`dns.resolver.Resolver` or ``None``
- :type use_dnspython: bool
+ :type resolver: :class:`aiodns.DNSResolver` or ``None``
+ :type use_aiodns: bool
:return: A list of IPv6 literals.
"""
log.debug("DNS: Querying %s for AAAA records." % host)
- # If not using dnspython, attempt lookup using the OS level
+ # If not using aiodns, attempt lookup using the OS level
# getaddrinfo() method.
- if resolver is None or not use_dnspython:
+ if resolver is None or not use_aiodns:
if not socket.has_ipv6:
- log.debug("Unable to query %s for AAAA records: IPv6 is not supported", host)
+ log.debug("DNS: Unable to query %s for AAAA records: IPv6 is not supported", host)
return []
try:
- recs = socket.getaddrinfo(host, None, socket.AF_INET6,
- socket.SOCK_STREAM)
+ recs = yield from loop.getaddrinfo(host, None,
+ family=socket.AF_INET6,
+ type=socket.SOCK_STREAM)
return [rec[4][0] for rec in recs]
except (OSError, socket.gaierror):
log.debug("DNS: Error retreiving AAAA address " + \
"info for %s." % host)
return []
- # Using dnspython:
+ # Using aiodns:
+ future = resolver.query(host, 'AAAA')
try:
- recs = resolver.query(host, dns.rdatatype.AAAA)
- return [rec.to_text() for rec in recs]
- except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
- log.debug("DNS: No AAAA records for %s" % host)
- return []
- except dns.exception.Timeout:
- log.debug("DNS: AAAA record resolution timed out for %s" % host)
- return []
- except dns.exception.DNSException as e:
- log.debug("DNS: Error querying AAAA records for %s" % host)
- log.exception(e)
- return []
-
-
-def get_SRV(host, port, service, proto='tcp', resolver=None, use_dnspython=True):
+ recs = yield from future
+ except Exception as e:
+ log.debug('DNS: Exception while querying for %s AAAA records: %s', host, e)
+ recs = []
+ return recs
+
+@asyncio.coroutine
+def get_SRV(host, port, service, proto='tcp', resolver=None, use_aiodns=True):
"""Perform SRV record resolution for a given host.
.. note::
- This function requires the use of the ``dnspython`` package. Calling
- :func:`get_SRV` without ``dnspython`` will return the provided host
+ This function requires the use of the ``aiodns`` package. Calling
+ :func:`get_SRV` without ``aiodns`` will return the provided host
and port without performing any DNS queries.
:param host: The hostname to resolve.
@@ -274,32 +264,23 @@ def get_SRV(host, port, service, proto='tcp', resolver=None, use_dnspython=True)
:type port: int
:type service: string
:type proto: string
- :type resolver: :class:`dns.resolver.Resolver`
+ :type resolver: :class:`aiodns.DNSResolver`
:return: A list of hostname, port pairs in the order dictacted
by SRV priorities and weights.
"""
- if resolver is None or not use_dnspython:
- log.warning("DNS: dnspython not found. Can not use SRV lookup.")
+ if resolver is None or not use_aiodns:
+ log.warning("DNS: aiodns not found. Can not use SRV lookup.")
return [(host, port)]
log.debug("DNS: Querying SRV records for %s" % host)
try:
- recs = resolver.query('_%s._%s.%s' % (service, proto, host),
- dns.rdatatype.SRV)
- except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
- log.debug("DNS: No SRV records for %s." % host)
- return [(host, port)]
- except dns.exception.Timeout:
- log.debug("DNS: SRV record resolution timed out for %s." % host)
- return [(host, port)]
- except dns.exception.DNSException as e:
- log.debug("DNS: Error querying SRV records for %s." % host)
- log.exception(e)
- return [(host, port)]
-
- if len(recs) == 1 and recs[0].target == '.':
- return [(host, port)]
+ future = resolver.query('_%s._%s.%s' % (service, proto, host),
+ 'SRV')
+ recs = yield from future
+ except Exception as e:
+ log.debug('DNS: Exception while querying for %s SRV records: %s', host, e)
+ return []
answers = {}
for rec in recs:
@@ -323,7 +304,7 @@ def get_SRV(host, port, service, proto='tcp', resolver=None, use_dnspython=True)
for running_sum in sums:
if running_sum >= selected:
rec = sums[running_sum]
- host = rec.target.to_text()
+ host = rec.host
if host.endswith('.'):
host = host[:-1]
sorted_recs.append((host, rec.port))
diff --git a/sleekxmpp/xmlstream/stanzabase.py b/slixmpp/xmlstream/stanzabase.py
index c2e0f718..1ddee825 100644
--- a/sleekxmpp/xmlstream/stanzabase.py
+++ b/slixmpp/xmlstream/stanzabase.py
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.xmlstream.stanzabase
+ slixmpp.xmlstream.stanzabase
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
module implements a wrapper layer for XML objects
that allows them to be treated like dictionaries.
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
@@ -19,10 +19,9 @@ import logging
import weakref
from xml.etree import cElementTree as ET
-from sleekxmpp.util import safedict
-from sleekxmpp.xmlstream import JID
-from sleekxmpp.xmlstream.tostring import tostring
-from sleekxmpp.thirdparty import OrderedDict
+from slixmpp.xmlstream import JID
+from slixmpp.xmlstream.tostring import tostring
+from collections import OrderedDict
log = logging.getLogger(__name__)
@@ -39,7 +38,7 @@ def register_stanza_plugin(stanza, plugin, iterable=False, overrides=False):
"""
Associate a stanza object as a plugin for another stanza.
- >>> from sleekxmpp.xmlstream import register_stanza_plugin
+ >>> from slixmpp.xmlstream import register_stanza_plugin
>>> register_stanza_plugin(Iq, CustomStanza)
Plugin stanzas marked as iterable will be included in the list of
@@ -92,10 +91,6 @@ def register_stanza_plugin(stanza, plugin, iterable=False, overrides=False):
stanza.plugin_overrides[interface] = plugin.plugin_attrib
-# To maintain backwards compatibility for now, preserve the camel case name.
-registerStanzaPlugin = register_stanza_plugin
-
-
def multifactory(stanza, plugin_attrib):
"""
Returns a ElementBase class for handling reoccuring child stanzas
@@ -206,7 +201,7 @@ def fix_ns(xpath, split=False, propagate_ns=True, default_ns=''):
class ElementBase(object):
"""
- The core of SleekXMPP's stanza XML manipulation and handling is provided
+ The core of Slixmpp's stanza XML manipulation and handling is provided
by ElementBase. ElementBase wraps XML cElementTree objects and enables
access to the XML contents through dictionary syntax, similar in style
to the Ruby XMPP library Blather's stanza implementation.
@@ -680,7 +675,7 @@ class ElementBase(object):
if lang and attrib in self.lang_interfaces:
kwargs['lang'] = lang
- kwargs = safedict(kwargs)
+ kwargs = OrderedDict(kwargs)
if attrib == 'substanzas':
return self.iterables
@@ -758,7 +753,7 @@ class ElementBase(object):
if lang and attrib in self.lang_interfaces:
kwargs['lang'] = lang
- kwargs = safedict(kwargs)
+ kwargs = OrderedDict(kwargs)
if attrib in self.interfaces or attrib == 'lang':
if value is not None:
@@ -846,7 +841,7 @@ class ElementBase(object):
if lang and attrib in self.lang_interfaces:
kwargs['lang'] = lang
- kwargs = safedict(kwargs)
+ kwargs = OrderedDict(kwargs)
if attrib in self.interfaces or attrib == 'lang':
del_method = "del_%s" % attrib.lower()
@@ -1427,7 +1422,7 @@ class StanzaBase(ElementBase):
"""
StanzaBase provides the foundation for all other stanza objects used
- by SleekXMPP, and defines a basic set of interfaces common to nearly
+ by Slixmpp, and defines a basic set of interfaces common to nearly
all stanzas. These interfaces are the ``'id'``, ``'type'``, ``'to'``,
and ``'from'`` attributes. An additional interface, ``'payload'``, is
available to access the XML contents of the stanza. Most stanza objects
@@ -1443,13 +1438,13 @@ class StanzaBase(ElementBase):
``'error'``, ``'get'``, or ``'set'``, etc.
:payload: The XML contents of the stanza.
- :param XMLStream stream: Optional :class:`sleekxmpp.xmlstream.XMLStream`
+ :param XMLStream stream: Optional :class:`slixmpp.xmlstream.XMLStream`
object responsible for sending this stanza.
:param XML xml: Optional XML contents to initialize stanza values.
:param string stype: Optional stanza type value.
- :param sto: Optional string or :class:`sleekxmpp.xmlstream.JID`
+ :param sto: Optional string or :class:`slixmpp.xmlstream.JID`
object of the recipient's JID.
- :param sfrom: Optional string or :class:`sleekxmpp.xmlstream.JID`
+ :param sfrom: Optional string or :class:`slixmpp.xmlstream.JID`
object of the sender's JID.
:param string sid: Optional ID value for the stanza.
:param parent: Optionally specify a parent stanza object will
@@ -1488,7 +1483,7 @@ class StanzaBase(ElementBase):
Only type values contained in :attr:`types` are accepted.
- :param string value: One of the values contained in :attr:`types`
+ :param str value: One of the values contained in :attr:`types`
"""
if value in self.types:
self.xml.attrib['type'] = value
@@ -1501,7 +1496,7 @@ class StanzaBase(ElementBase):
def set_to(self, value):
"""Set the ``'to'`` attribute of the stanza.
- :param value: A string or :class:`sleekxmpp.xmlstream.JID` object
+ :param value: A string or :class:`slixmpp.xmlstream.JID` object
representing the recipient's JID.
"""
return self._set_attr('to', str(value))
@@ -1513,8 +1508,8 @@ class StanzaBase(ElementBase):
def set_from(self, value):
"""Set the 'from' attribute of the stanza.
- Arguments:
- from -- A string or JID object representing the sender's JID.
+ :param from: A string or JID object representing the sender's JID.
+ :type from: str or :class:`.JID`
"""
return self._set_attr('from', str(value))
@@ -1552,16 +1547,17 @@ class StanzaBase(ElementBase):
:param bool clear: Indicates if the stanza's contents should be
removed. Defaults to ``True``.
"""
+ new_stanza = copy.copy(self)
# if it's a component, use from
if self.stream and hasattr(self.stream, "is_component") and \
self.stream.is_component:
- self['from'], self['to'] = self['to'], self['from']
+ new_stanza['from'], new_stanza['to'] = self['to'], self['from']
else:
- self['to'] = self['from']
- del self['from']
+ new_stanza['to'] = self['from']
+ del new_stanza['from']
if clear:
- self.clear()
- return self
+ new_stanza.clear()
+ return new_stanza
def error(self):
"""Set the stanza's type to ``'error'``."""
@@ -1583,14 +1579,14 @@ class StanzaBase(ElementBase):
log.exception('Error handling {%s}%s stanza', self.namespace,
self.name)
- def send(self, now=False):
+ def send(self):
"""Queue the stanza to be sent on the XML stream.
:param bool now: Indicates if the queue should be skipped and the
stanza sent immediately. Useful for stream
initialization. Defaults to ``False``.
"""
- self.stream.send(self, now=now)
+ self.stream.send(self)
def __copy__(self):
"""Return a copy of the stanza object that does not share the
@@ -1631,24 +1627,5 @@ class StanzaBase(ElementBase):
ElementBase.values = property(ElementBase._get_stanza_values,
ElementBase._set_stanza_values)
-
-# To comply with PEP8, method names now use underscores.
-# Deprecated method names are re-mapped for backwards compatibility.
-ElementBase.initPlugin = ElementBase.init_plugin
-ElementBase._getAttr = ElementBase._get_attr
-ElementBase._setAttr = ElementBase._set_attr
-ElementBase._delAttr = ElementBase._del_attr
-ElementBase._getSubText = ElementBase._get_sub_text
-ElementBase._setSubText = ElementBase._set_sub_text
-ElementBase._delSub = ElementBase._del_sub
-ElementBase.getStanzaValues = ElementBase._get_stanza_values
-ElementBase.setStanzaValues = ElementBase._set_stanza_values
-
-StanzaBase.setType = StanzaBase.set_type
-StanzaBase.getTo = StanzaBase.get_to
-StanzaBase.setTo = StanzaBase.set_to
-StanzaBase.getFrom = StanzaBase.get_from
-StanzaBase.setFrom = StanzaBase.set_from
-StanzaBase.getPayload = StanzaBase.get_payload
-StanzaBase.setPayload = StanzaBase.set_payload
-StanzaBase.delPayload = StanzaBase.del_payload
+ElementBase.get_stanza_values = ElementBase._get_stanza_values
+ElementBase.set_stanza_values = ElementBase._set_stanza_values
diff --git a/sleekxmpp/xmlstream/tostring.py b/slixmpp/xmlstream/tostring.py
index c49abd3e..6726bf1e 100644
--- a/sleekxmpp/xmlstream/tostring.py
+++ b/slixmpp/xmlstream/tostring.py
@@ -1,26 +1,18 @@
# -*- coding: utf-8 -*-
"""
- sleekxmpp.xmlstream.tostring
+ slixmpp.xmlstream.tostring
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This module converts XML objects into Unicode strings and
intelligently includes namespaces only when necessary to
keep the output readable.
- Part of SleekXMPP: The Sleek XMPP Library
+ Part of Slixmpp: The Slick XMPP Library
:copyright: (c) 2011 Nathanael C. Fritz
:license: MIT, see LICENSE for more details
"""
-from __future__ import unicode_literals
-
-import sys
-
-if sys.version_info < (3, 0):
- import types
-
-
XML_NS = 'http://www.w3.org/XML/1998/namespace'
@@ -45,7 +37,7 @@ def tostring(xml=None, xmlns='', stream=None, outbuffer='',
that new ones can be declared when needed.
:type xml: :py:class:`~xml.etree.ElementTree.Element`
- :type stream: :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream`
+ :type stream: :class:`~slixmpp.xmlstream.xmlstream.XMLStream`
:rtype: Unicode string
"""
@@ -145,10 +137,6 @@ def escape(text, use_cdata=False):
:param string text: The XML text to convert.
:rtype: Unicode string
"""
- if sys.version_info < (3, 0):
- if type(text) != types.UnicodeType:
- text = unicode(text, 'utf-8', 'ignore')
-
escapes = {'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
@@ -170,3 +158,26 @@ def escape(text, use_cdata=False):
escaped = map(lambda x : "<![CDATA[%s]]>" % x, text.split("]]>"))
return "<![CDATA[]]]><![CDATA[]>]]>".join(escaped)
return text
+
+
+def _get_highlight():
+ try:
+ from pygments import highlight
+ from pygments.lexers import get_lexer_by_name
+ from pygments.formatters import Terminal256Formatter
+
+ LEXER = get_lexer_by_name('xml')
+ FORMATTER = Terminal256Formatter()
+
+ class Highlighter:
+ __slots__ = ['string']
+ def __init__(self, string):
+ self.string = string
+ def __str__(self):
+ return highlight(str(self.string), LEXER, FORMATTER).strip()
+
+ return Highlighter
+ except ImportError:
+ return lambda x: x
+
+highlight = _get_highlight()
diff --git a/slixmpp/xmlstream/xmlstream.py b/slixmpp/xmlstream/xmlstream.py
new file mode 100644
index 00000000..28bfb17c
--- /dev/null
+++ b/slixmpp/xmlstream/xmlstream.py
@@ -0,0 +1,943 @@
+"""
+ slixmpp.xmlstream.xmlstream
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ This module provides the module for creating and
+ interacting with generic XML streams, along with
+ the necessary eventing infrastructure.
+
+ Part of Slixmpp: The Slick XMPP Library
+
+ :copyright: (c) 2011 Nathanael C. Fritz
+ :license: MIT, see LICENSE for more details
+"""
+
+import functools
+import logging
+import socket as Socket
+import ssl
+import weakref
+import uuid
+
+import xml.etree.ElementTree
+
+from slixmpp.xmlstream.asyncio import asyncio
+from slixmpp.xmlstream import tostring, highlight
+from slixmpp.xmlstream.stanzabase import StanzaBase, ElementBase
+from slixmpp.xmlstream.resolver import resolve, default_resolver
+
+#: The time in seconds to wait before timing out waiting for response stanzas.
+RESPONSE_TIMEOUT = 30
+
+log = logging.getLogger(__name__)
+
+class NotConnectedError(Exception):
+ """
+ Raised when we try to send something over the wire but we are not
+ connected.
+ """
+
+class XMLStream(asyncio.BaseProtocol):
+ """
+ An XML stream connection manager and event dispatcher.
+
+ The XMLStream class abstracts away the issues of establishing a
+ connection with a server and sending and receiving XML "stanzas".
+ A stanza is a complete XML element that is a direct child of a root
+ document element. Two streams are used, one for each communication
+ direction, over the same socket. Once the connection is closed, both
+ streams should be complete and valid XML documents.
+
+ Three types of events are provided to manage the stream:
+ :Stream: Triggered based on received stanzas, similar in concept
+ to events in a SAX XML parser.
+ :Custom: Triggered manually.
+ :Scheduled: Triggered based on time delays.
+
+ Typically, stanzas are first processed by a stream event handler which
+ will then trigger custom events to continue further processing,
+ especially since custom event handlers may run in individual threads.
+
+ :param socket: Use an existing socket for the stream. Defaults to
+ ``None`` to generate a new socket.
+ :param string host: The name of the target server.
+ :param int port: The port to use for the connection. Defaults to 0.
+ """
+
+ def __init__(self, socket=None, host='', port=0):
+ # The asyncio.Transport object provided by the connection_made()
+ # callback when we are connected
+ self.transport = None
+
+ # The socket the is used internally by the transport object
+ self.socket = None
+
+ self.connect_loop_wait = 0
+
+ self.parser = None
+ self.xml_depth = 0
+ self.xml_root = None
+
+ self.force_starttls = None
+ self.disable_starttls = None
+
+ # A dict of {name: handle}
+ self.scheduled_events = {}
+
+ self.ssl_context = ssl.create_default_context()
+ self.ssl_context.check_hostname = False
+ self.ssl_context.verify_mode = ssl.CERT_NONE
+
+ # The event to trigger when the create_connection() succeeds. It can
+ # be "connected" or "tls_success" depending on the step we are at.
+ self.event_when_connected = "connected"
+
+ #: The list of accepted ciphers, in OpenSSL Format.
+ #: It might be useful to override it for improved security
+ #: over the python defaults.
+ self.ciphers = None
+
+ #: Path to a file containing certificates for verifying the
+ #: server SSL certificate. A non-``None`` value will trigger
+ #: certificate checking.
+ #:
+ #: .. note::
+ #:
+ #: On Mac OS X, certificates in the system keyring will
+ #: be consulted, even if they are not in the provided file.
+ self.ca_certs = None
+
+ #: Path to a file containing a client certificate to use for
+ #: authenticating via SASL EXTERNAL. If set, there must also
+ #: be a corresponding `:attr:keyfile` value.
+ self.certfile = None
+
+ #: Path to a file containing the private key for the selected
+ #: client certificate to use for authenticating via SASL EXTERNAL.
+ self.keyfile = None
+
+ self._der_cert = None
+
+ # The asyncio event loop
+ self._loop = None
+
+ #: The default port to return when querying DNS records.
+ self.default_port = int(port)
+
+ #: The domain to try when querying DNS records.
+ self.default_domain = ''
+
+ #: The expected name of the server, for validation.
+ self._expected_server_name = ''
+ self._service_name = ''
+
+ #: The desired, or actual, address of the connected server.
+ self.address = (host, int(port))
+
+ #: Enable connecting to the server directly over SSL, in
+ #: particular when the service provides two ports: one for
+ #: non-SSL traffic and another for SSL traffic.
+ self.use_ssl = False
+
+ #: If set to ``True``, attempt to connect through an HTTP
+ #: proxy based on the settings in :attr:`proxy_config`.
+ self.use_proxy = False
+
+ #: If set to ``True``, attempt to use IPv6.
+ self.use_ipv6 = True
+
+ #: If set to ``True``, allow using the ``dnspython`` DNS library
+ #: if available. If set to ``False``, the builtin DNS resolver
+ #: will be used, even if ``dnspython`` is installed.
+ self.use_aiodns = True
+
+ #: Use CDATA for escaping instead of XML entities. Defaults
+ #: to ``False``.
+ self.use_cdata = False
+
+ #: An optional dictionary of proxy settings. It may provide:
+ #: :host: The host offering proxy services.
+ #: :port: The port for the proxy service.
+ #: :username: Optional username for accessing the proxy.
+ #: :password: Optional password for accessing the proxy.
+ self.proxy_config = {}
+
+ #: The default namespace of the stream content, not of the
+ #: stream wrapper itself.
+ self.default_ns = ''
+
+ self.default_lang = None
+ self.peer_default_lang = None
+
+ #: The namespace of the enveloping stream element.
+ self.stream_ns = ''
+
+ #: The default opening tag for the stream element.
+ self.stream_header = "<stream>"
+
+ #: The default closing tag for the stream element.
+ self.stream_footer = "</stream>"
+
+ #: If ``True``, periodically send a whitespace character over the
+ #: wire to keep the connection alive. Mainly useful for connections
+ #: traversing NAT.
+ self.whitespace_keepalive = True
+
+ #: The default interval between keepalive signals when
+ #: :attr:`whitespace_keepalive` is enabled.
+ self.whitespace_keepalive_interval = 300
+
+ #: Flag for controlling if the session can be considered ended
+ #: if the connection is terminated.
+ self.end_session_on_disconnect = True
+
+ #: A mapping of XML namespaces to well-known prefixes.
+ self.namespace_map = {StanzaBase.xml_ns: 'xml'}
+
+ self.__root_stanza = []
+ self.__handlers = []
+ self.__event_handlers = {}
+ self.__filters = {'in': [], 'out': [], 'out_sync': []}
+
+ self._id = 0
+
+ #: We use an ID prefix to ensure that all ID values are unique.
+ self._id_prefix = '%s-' % uuid.uuid4()
+
+ #: A list of DNS results that have not yet been tried.
+ self.dns_answers = None
+
+ #: The service name to check with DNS SRV records. For
+ #: example, setting this to ``'xmpp-client'`` would query the
+ #: ``_xmpp-client._tcp`` service.
+ self.dns_service = None
+
+ #: An asyncio Future being done when the stream is disconnected.
+ self.disconnected = asyncio.Future()
+
+ self.add_event_handler('disconnected', self._remove_schedules)
+ self.add_event_handler('session_start', self._start_keepalive)
+
+ @property
+ def loop(self):
+ if self._loop is None:
+ self._loop = asyncio.get_event_loop()
+ return self._loop
+
+ @loop.setter
+ def loop(self, value):
+ self._loop = value
+
+ def new_id(self):
+ """Generate and return a new stream ID in hexadecimal form.
+
+ Many stanzas, handlers, or matchers may require unique
+ ID values. Using this method ensures that all new ID values
+ are unique in this stream.
+ """
+ self._id += 1
+ return self.get_id()
+
+ def get_id(self):
+ """Return the current unique stream ID in hexadecimal form."""
+ return "%s%X" % (self._id_prefix, self._id)
+
+ def connect(self, host='', port=0, use_ssl=False,
+ force_starttls=True, disable_starttls=False):
+ """Create a new socket and connect to the server.
+
+ :param host: The name of the desired server for the connection.
+ :param port: Port to connect to on the server.
+ :param use_ssl: Flag indicating if SSL should be used by connecting
+ directly to a port using SSL. If it is False, the
+ connection will be upgraded to SSL/TLS later, using
+ STARTTLS. Only use this value for old servers that
+ have specific port for SSL/TLS
+ TODO fix the comment
+ :param force_starttls: If True, the connection will be aborted if
+ the server does not initiate a STARTTLS
+ negociation. If None, the connection will be
+ upgraded to TLS only if the server initiate
+ the STARTTLS negociation, otherwise it will
+ connect in clear. If False it will never
+ upgrade to TLS, even if the server provides
+ it. Use this for example if you’re on
+ localhost
+
+ """
+ if host and port:
+ self.address = (host, int(port))
+ try:
+ Socket.inet_aton(self.address[0])
+ except (Socket.error, ssl.SSLError):
+ self.default_domain = self.address[0]
+
+ # Respect previous TLS usage.
+ if use_ssl is not None:
+ self.use_ssl = use_ssl
+ if force_starttls is not None:
+ self.force_starttls = force_starttls
+ if disable_starttls is not None:
+ self.disable_starttls = disable_starttls
+
+ self.event("connecting")
+ asyncio.async(self._connect_routine())
+
+ @asyncio.coroutine
+ def _connect_routine(self):
+ self.event_when_connected = "connected"
+
+ record = yield from self.pick_dns_answer(self.default_domain)
+ if record is not None:
+ host, address, port = record
+ self.address = (address, port)
+ self._service_name = host
+ else:
+ # No DNS records left, stop iterating
+ # and try (host, port) as a last resort
+ self.dns_answers = None
+
+ yield from asyncio.sleep(self.connect_loop_wait)
+ try:
+ yield from self.loop.create_connection(lambda: self,
+ self.address[0],
+ self.address[1],
+ ssl=self.use_ssl)
+ except Socket.gaierror as e:
+ self.event('connection_failed',
+ 'No DNS record available for %s' % self.default_domain)
+ except OSError as e:
+ log.debug('Connection failed: %s', e)
+ self.event("connection_failed", e)
+ self.connect_loop_wait = self.connect_loop_wait * 2 + 1
+ asyncio.async(self._connect_routine())
+ else:
+ self.connect_loop_wait = 0
+
+ def process(self, *, forever=True, timeout=None):
+ """Process all the available XMPP events (receiving or sending data on the
+ socket(s), calling various registered callbacks, calling expired
+ timers, handling signal events, etc). If timeout is None, this
+ function will run forever. If timeout is a number, this function
+ will return after the given time in seconds.
+ """
+ if timeout is None:
+ if forever:
+ self.loop.run_forever()
+ else:
+ self.loop.run_until_complete(self.disconnected)
+ else:
+ tasks = [asyncio.sleep(timeout)]
+ if not forever:
+ tasks.append(self.disconnected)
+ self.loop.run_until_complete(asyncio.wait(tasks))
+
+ def init_parser(self):
+ """init the XML parser. The parser must always be reset for each new
+ connexion
+ """
+ self.xml_depth = 0
+ self.xml_root = None
+ self.parser = xml.etree.ElementTree.XMLPullParser(("start", "end"))
+
+ def connection_made(self, transport):
+ """Called when the TCP connection has been established with the server
+ """
+ self.event(self.event_when_connected)
+ self.transport = transport
+ self.socket = self.transport.get_extra_info("socket")
+ self.init_parser()
+ self.send_raw(self.stream_header)
+
+ def data_received(self, data):
+ """Called when incoming data is received on the socket.
+
+ We feed that data to the parser and the see if this produced any XML
+ event. This could trigger one or more event (a stanza is received,
+ the stream is opened, etc).
+ """
+ self.parser.feed(data)
+ for event, xml in self.parser.read_events():
+ if event == 'start':
+ if self.xml_depth == 0:
+ # We have received the start of the root element.
+ self.xml_root = xml
+ log.debug('RECV: %s', highlight(tostring(self.xml_root, xmlns=self.default_ns,
+ stream=self,
+ top_level=True,
+ open_only=True)))
+ self.start_stream_handler(self.xml_root)
+ self.xml_depth += 1
+ if event == 'end':
+ self.xml_depth -= 1
+ if self.xml_depth == 0:
+ # The stream's root element has closed,
+ # terminating the stream.
+ log.debug("End of stream received")
+ self.abort()
+ elif self.xml_depth == 1:
+ # A stanza is an XML element that is a direct child of
+ # the root element, hence the check of depth == 1
+ self.loop.idle_call(functools.partial(self.__spawn_event, xml))
+ if self.xml_root is not None:
+ # Keep the root element empty of children to
+ # save on memory use.
+ self.xml_root.clear()
+
+ def is_connected(self):
+ return self.transport is not None
+
+ def eof_received(self):
+ """When the TCP connection is properly closed by the remote end
+ """
+ self.event("eof_received")
+
+ def connection_lost(self, exception):
+ """On any kind of disconnection, initiated by us or not. This signals the
+ closure of the TCP connection
+ """
+ log.info("connection_lost: %s", (exception,))
+ self.event("disconnected")
+ if self.end_session_on_disconnect:
+ self.event('session_end')
+ # All these objects are associated with one TCP connection. Since
+ # we are not connected anymore, destroy them
+ self.parser = None
+ self.transport = None
+ self.socket = None
+
+ def disconnect(self, wait=2.0):
+ """Close the XML stream and wait for an acknowldgement from the server for
+ at most `wait` seconds. After the given number of seconds has
+ passed without a response from the serveur, or when the server
+ successfuly responds with a closure of its own stream, abort() is
+ called. If wait is 0.0, this is almost equivalent to calling abort()
+ directly.
+
+ Does nothing if we are not connected.
+
+ :param wait: Time to wait for a response from the server.
+
+ """
+ if self.transport:
+ self.send_raw(self.stream_footer)
+ self.schedule('Disconnect wait', wait,
+ self.abort, repeat=False)
+
+ def abort(self):
+ """
+ Forcibly close the connection
+ """
+ if self.transport:
+ self.transport.close()
+ self.transport.abort()
+ self.event("killed")
+ self.disconnected.set_result(True)
+ self.disconnected = asyncio.Future()
+
+ def reconnect(self, wait=2.0):
+ """Calls disconnect(), and once we are disconnected (after the timeout, or
+ when the server acknowledgement is received), call connect()
+ """
+ log.debug("reconnecting...")
+ self.disconnect(wait)
+ self.add_event_handler('disconnected', self.connect, disposable=True)
+
+ def configure_socket(self):
+ """Set timeout and other options for self.socket.
+
+ Meant to be overridden.
+ """
+ pass
+
+ def configure_dns(self, resolver, domain=None, port=None):
+ """
+ Configure and set options for a :class:`~dns.resolver.Resolver`
+ instance, and other DNS related tasks. For example, you
+ can also check :meth:`~socket.socket.getaddrinfo` to see
+ if you need to call out to ``libresolv.so.2`` to
+ run ``res_init()``.
+
+ Meant to be overridden.
+
+ :param resolver: A :class:`~dns.resolver.Resolver` instance
+ or ``None`` if ``dnspython`` is not installed.
+ :param domain: The initial domain under consideration.
+ :param port: The initial port under consideration.
+ """
+ pass
+
+ def start_tls(self):
+ """Perform handshakes for TLS.
+
+ If the handshake is successful, the XML stream will need
+ to be restarted.
+ """
+ self.event_when_connected = "tls_success"
+
+ if self.ciphers is not None:
+ self.ssl_context.set_ciphers(self.ciphers)
+ if self.keyfile and self.certfile:
+ try:
+ self.ssl_context.load_cert_chain(self.certfile, self.keyfile)
+ except (ssl.SSLError, OSError):
+ log.debug('Error loading the cert chain:', exc_info=True)
+ else:
+ log.debug('Loaded cert file %s and key file %s',
+ self.certfile, self.keyfile)
+ if self.ca_certs is not None:
+ self.ssl_context.verify_mode = ssl.CERT_REQUIRED
+ self.ssl_context.load_verify_locations(cafile=self.ca_certs)
+
+ ssl_connect_routine = self.loop.create_connection(lambda: self, ssl=self.ssl_context,
+ sock=self.socket,
+ server_hostname=self.default_domain)
+ @asyncio.coroutine
+ def ssl_coro():
+ try:
+ transp, prot = yield from ssl_connect_routine
+ except ssl.SSLError as e:
+ log.debug('SSL: Unable to connect', exc_info=True)
+ log.error('CERT: Invalid certificate trust chain.')
+ if not self.event_handled('ssl_invalid_chain'):
+ self.disconnect()
+ else:
+ self.event('ssl_invalid_chain', e)
+ else:
+ der_cert = transp.get_extra_info("socket").getpeercert(True)
+ pem_cert = ssl.DER_cert_to_PEM_cert(der_cert)
+ self.event('ssl_cert', pem_cert)
+
+ asyncio.async(ssl_coro())
+
+ def _start_keepalive(self, event):
+ """Begin sending whitespace periodically to keep the connection alive.
+
+ May be disabled by setting::
+
+ self.whitespace_keepalive = False
+
+ The keepalive interval can be set using::
+
+ self.whitespace_keepalive_interval = 300
+ """
+ self.schedule('Whitespace Keepalive',
+ self.whitespace_keepalive_interval,
+ self.send_raw,
+ args=(' ',),
+ repeat=True)
+
+ def _remove_schedules(self, event):
+ """Remove some schedules that become pointless when disconnected"""
+ self.cancel_schedule('Whitespace Keepalive')
+ self.cancel_schedule('Disconnect wait')
+
+ def start_stream_handler(self, xml):
+ """Perform any initialization actions, such as handshakes,
+ once the stream header has been sent.
+
+ Meant to be overridden.
+ """
+ pass
+
+ def register_stanza(self, stanza_class):
+ """Add a stanza object class as a known root stanza.
+
+ A root stanza is one that appears as a direct child of the stream's
+ root element.
+
+ Stanzas that appear as substanzas of a root stanza do not need to
+ be registered here. That is done using register_stanza_plugin() from
+ slixmpp.xmlstream.stanzabase.
+
+ Stanzas that are not registered will not be converted into
+ stanza objects, but may still be processed using handlers and
+ matchers.
+
+ :param stanza_class: The top-level stanza object's class.
+ """
+ self.__root_stanza.append(stanza_class)
+
+ def remove_stanza(self, stanza_class):
+ """Remove a stanza from being a known root stanza.
+
+ A root stanza is one that appears as a direct child of the stream's
+ root element.
+
+ Stanzas that are not registered will not be converted into
+ stanza objects, but may still be processed using handlers and
+ matchers.
+ """
+ self.__root_stanza.remove(stanza_class)
+
+ def add_filter(self, mode, handler, order=None):
+ """Add a filter for incoming or outgoing stanzas.
+
+ These filters are applied before incoming stanzas are
+ passed to any handlers, and before outgoing stanzas
+ are put in the send queue.
+
+ Each filter must accept a single stanza, and return
+ either a stanza or ``None``. If the filter returns
+ ``None``, then the stanza will be dropped from being
+ processed for events or from being sent.
+
+ :param mode: One of ``'in'`` or ``'out'``.
+ :param handler: The filter function.
+ :param int order: The position to insert the filter in
+ the list of active filters.
+ """
+ if order:
+ self.__filters[mode].insert(order, handler)
+ else:
+ self.__filters[mode].append(handler)
+
+ def del_filter(self, mode, handler):
+ """Remove an incoming or outgoing filter."""
+ self.__filters[mode].remove(handler)
+
+ def register_handler(self, handler, before=None, after=None):
+ """Add a stream event handler that will be executed when a matching
+ stanza is received.
+
+ :param handler:
+ The :class:`~slixmpp.xmlstream.handler.base.BaseHandler`
+ derived object to execute.
+ """
+ if handler.stream is None:
+ self.__handlers.append(handler)
+ handler.stream = weakref.ref(self)
+
+ def remove_handler(self, name):
+ """Remove any stream event handlers with the given name.
+
+ :param name: The name of the handler.
+ """
+ idx = 0
+ for handler in self.__handlers:
+ if handler.name == name:
+ self.__handlers.pop(idx)
+ return True
+ idx += 1
+ return False
+
+ @asyncio.coroutine
+ def get_dns_records(self, domain, port=None):
+ """Get the DNS records for a domain.
+
+ :param domain: The domain in question.
+ :param port: If the results don't include a port, use this one.
+ """
+ if port is None:
+ port = self.default_port
+
+ resolver = default_resolver(loop=self.loop)
+ self.configure_dns(resolver, domain=domain, port=port)
+
+ result = yield from resolve(domain, port,
+ service=self.dns_service,
+ resolver=resolver,
+ use_ipv6=self.use_ipv6,
+ use_aiodns=self.use_aiodns,
+ loop=self.loop)
+ return result
+
+ @asyncio.coroutine
+ def pick_dns_answer(self, domain, port=None):
+ """Pick a server and port from DNS answers.
+
+ Gets DNS answers if none available.
+ Removes used answer from available answers.
+
+ :param domain: The domain in question.
+ :param port: If the results don't include a port, use this one.
+ """
+ if self.dns_answers is None:
+ dns_records = yield from self.get_dns_records(domain, port)
+ self.dns_answers = iter(dns_records)
+
+ try:
+ return next(self.dns_answers)
+ except StopIteration:
+ return
+
+ def add_event_handler(self, name, pointer, disposable=False):
+ """Add a custom event handler that will be executed whenever
+ its event is manually triggered.
+
+ :param name: The name of the event that will trigger
+ this handler.
+ :param pointer: The function to execute.
+ :param disposable: If set to ``True``, the handler will be
+ discarded after one use. Defaults to ``False``.
+ """
+ if not name in self.__event_handlers:
+ self.__event_handlers[name] = []
+ self.__event_handlers[name].append((pointer, disposable))
+
+ def del_event_handler(self, name, pointer):
+ """Remove a function as a handler for an event.
+
+ :param name: The name of the event.
+ :param pointer: The function to remove as a handler.
+ """
+ if not name in self.__event_handlers:
+ return
+
+ # Need to keep handlers that do not use
+ # the given function pointer
+ def filter_pointers(handler):
+ return handler[0] != pointer
+
+ self.__event_handlers[name] = list(filter(
+ filter_pointers,
+ self.__event_handlers[name]))
+
+ def event_handled(self, name):
+ """Returns the number of registered handlers for an event.
+
+ :param name: The name of the event to check.
+ """
+ return len(self.__event_handlers.get(name, []))
+
+ def event(self, name, data={}):
+ """Manually trigger a custom event.
+
+ :param name: The name of the event to trigger.
+ :param data: Data that will be passed to each event handler.
+ Defaults to an empty dictionary, but is usually
+ a stanza object.
+ """
+ log.debug("Event triggered: %s", name)
+
+ handlers = self.__event_handlers.get(name, [])
+ for handler in handlers:
+ handler_callback, disposable = handler
+ old_exception = getattr(data, 'exception', None)
+
+ # If the callback is a coroutine, schedule it instead of
+ # running it directly
+ if asyncio.iscoroutinefunction(handler_callback):
+ @asyncio.coroutine
+ def handler_callback_routine(cb):
+ try:
+ yield from cb(data)
+ except Exception as e:
+ if old_exception:
+ old_exception(e)
+ else:
+ self.exception(e)
+ asyncio.async(handler_callback_routine(handler_callback))
+ else:
+ try:
+ handler_callback(data)
+ except Exception as e:
+ if old_exception:
+ old_exception(e)
+ else:
+ self.exception(e)
+ if disposable:
+ # If the handler is disposable, we will go ahead and
+ # remove it now instead of waiting for it to be
+ # processed in the queue.
+ try:
+ self.__event_handlers[name].remove(handler)
+ except ValueError:
+ pass
+
+ def schedule(self, name, seconds, callback, args=tuple(),
+ kwargs={}, repeat=False):
+ """Schedule a callback function to execute after a given delay.
+
+ :param name: A unique name for the scheduled callback.
+ :param seconds: The time in seconds to wait before executing.
+ :param callback: A pointer to the function to execute.
+ :param args: A tuple of arguments to pass to the function.
+ :param kwargs: A dictionary of keyword arguments to pass to
+ the function.
+ :param repeat: Flag indicating if the scheduled event should
+ be reset and repeat after executing.
+ """
+ if seconds is None:
+ seconds = RESPONSE_TIMEOUT
+ cb = functools.partial(callback, *args, **kwargs)
+ if repeat:
+ handle = self.loop.call_later(seconds, self._execute_and_reschedule,
+ name, cb, seconds)
+ else:
+ handle = self.loop.call_later(seconds, self._execute_and_unschedule,
+ name, cb)
+
+ # Save that handle, so we can just cancel this scheduled event by
+ # canceling scheduled_events[name]
+ self.scheduled_events[name] = handle
+
+ def cancel_schedule(self, name):
+ try:
+ handle = self.scheduled_events.pop(name)
+ handle.cancel()
+ except KeyError:
+ log.debug("Tried to cancel unscheduled event: %s" % (name,))
+
+ def _safe_cb_run(self, name, cb):
+ log.debug('Scheduled event: %s', name)
+ try:
+ cb()
+ except Exception as e:
+ self.exception(e)
+
+ def _execute_and_reschedule(self, name, cb, seconds):
+ """Simple method that calls the given callback, and then schedule itself to
+ be called after the given number of seconds.
+ """
+ self._safe_cb_run(name, cb)
+ handle = self.loop.call_later(seconds, self._execute_and_reschedule,
+ name, cb, seconds)
+ self.scheduled_events[name] = handle
+
+ def _execute_and_unschedule(self, name, cb):
+ """
+ Execute the callback and remove the handler for it.
+ """
+ self._safe_cb_run(name, cb)
+ del self.scheduled_events[name]
+
+ def incoming_filter(self, xml):
+ """Filter incoming XML objects before they are processed.
+
+ Possible uses include remapping namespaces, or correcting elements
+ from sources with incorrect behavior.
+
+ Meant to be overridden.
+ """
+ return xml
+
+ def send(self, data, use_filters=True):
+ """A wrapper for :meth:`send_raw()` for sending stanza objects.
+
+ May optionally block until an expected response is received.
+
+ :param data: The :class:`~slixmpp.xmlstream.stanzabase.ElementBase`
+ stanza to send on the stream.
+ :param bool use_filters: Indicates if outgoing filters should be
+ applied to the given stanza data. Disabling
+ filters is useful when resending stanzas.
+ Defaults to ``True``.
+ """
+ if isinstance(data, ElementBase):
+ if use_filters:
+ for filter in self.__filters['out']:
+ data = filter(data)
+ if data is None:
+ return
+
+ if isinstance(data, ElementBase):
+ if use_filters:
+ for filter in self.__filters['out_sync']:
+ data = filter(data)
+ if data is None:
+ return
+ str_data = tostring(data.xml, xmlns=self.default_ns,
+ stream=self,
+ top_level=True)
+ self.send_raw(str_data)
+ else:
+ self.send_raw(data)
+
+ def send_xml(self, data):
+ """Send an XML object on the stream
+
+ :param data: The :class:`~xml.etree.ElementTree.Element` XML object
+ to send on the stream.
+ """
+ return self.send(tostring(data))
+
+ def send_raw(self, data):
+ """Send raw data across the stream.
+
+ :param string data: Any bytes or utf-8 string value.
+ """
+ log.debug("SEND: %s", highlight(data))
+ if not self.transport:
+ raise NotConnectedError()
+ if isinstance(data, str):
+ data = data.encode('utf-8')
+ self.transport.write(data)
+
+ def _build_stanza(self, xml, default_ns=None):
+ """Create a stanza object from a given XML object.
+
+ If a specialized stanza type is not found for the XML, then
+ a generic :class:`~slixmpp.xmlstream.stanzabase.StanzaBase`
+ stanza will be returned.
+
+ :param xml: The :class:`~xml.etree.ElementTree.Element` XML object
+ to convert into a stanza object.
+ :param default_ns: Optional default namespace to use instead of the
+ stream's current default namespace.
+ """
+ if default_ns is None:
+ default_ns = self.default_ns
+ stanza_type = StanzaBase
+ for stanza_class in self.__root_stanza:
+ if xml.tag == "{%s}%s" % (default_ns, stanza_class.name) or \
+ xml.tag == stanza_class.tag_name():
+ stanza_type = stanza_class
+ break
+ stanza = stanza_type(self, xml)
+ if stanza['lang'] is None and self.peer_default_lang:
+ stanza['lang'] = self.peer_default_lang
+ return stanza
+
+ def __spawn_event(self, xml):
+ """
+ Analyze incoming XML stanzas and convert them into stanza
+ objects if applicable and queue stream events to be processed
+ by matching handlers.
+
+ :param xml: The :class:`~slixmpp.xmlstream.stanzabase.ElementBase`
+ stanza to analyze.
+ """
+ # Apply any preprocessing filters.
+ xml = self.incoming_filter(xml)
+
+ # Convert the raw XML object into a stanza object. If no registered
+ # stanza type applies, a generic StanzaBase stanza will be used.
+ stanza = self._build_stanza(xml)
+ for filter in self.__filters['in']:
+ if stanza is not None:
+ stanza = filter(stanza)
+ if stanza is None:
+ return
+
+ log.debug("RECV: %s", highlight(stanza))
+
+ # Match the stanza against registered handlers. Handlers marked
+ # to run "in stream" will be executed immediately; the rest will
+ # be queued.
+ handled = False
+ matched_handlers = [h for h in self.__handlers if h.match(stanza)]
+ for handler in matched_handlers:
+ handler.prerun(stanza)
+ try:
+ handler.run(stanza)
+ except Exception as e:
+ stanza.exception(e)
+ if handler.check_delete():
+ self.__handlers.remove(handler)
+ handled = True
+
+ # Some stanzas require responses, such as Iq queries. A default
+ # handler will be executed immediately for this case.
+ if not handled:
+ stanza.unhandled()
+
+ def exception(self, exception):
+ """Process an unknown exception.
+
+ Meant to be overridden.
+
+ :param exception: An unhandled exception object.
+ """
+ pass
+
diff --git a/testall.py b/testall.py
deleted file mode 100755
index 2cb6f538..00000000
--- a/testall.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-if len(sys.argv)>1 and sys.argv[1].lower() == 'gevent':
- from gevent import monkey
- monkey.patch_all()
-
-import os
-import logging
-import unittest
-import distutils.core
-
-from glob import glob
-from os.path import splitext, basename, join as pjoin
-
-
-def run_tests():
- """
- Find and run all tests in the tests/ directory.
-
- Excludes live tests (tests/live_*).
- """
- testfiles = ['tests.test_overall']
- exclude = ['__init__.py', 'test_overall.py']
- for t in glob(pjoin('tests', '*.py')):
- if True not in [t.endswith(ex) for ex in exclude]:
- if basename(t).startswith('test_'):
- testfiles.append('tests.%s' % splitext(basename(t))[0])
-
- suites = []
- for file in testfiles:
- __import__(file)
- suites.append(sys.modules[file].suite)
-
- tests = unittest.TestSuite(suites)
- runner = unittest.TextTestRunner(verbosity=2)
-
- # Disable logging output
- logging.basicConfig(level=100)
- logging.disable(100)
-
- result = runner.run(tests)
- return result
-
-
-# Add a 'test' command for setup.py
-
-class TestCommand(distutils.core.Command):
-
- user_options = [ ]
-
- def initialize_options(self):
- self._dir = os.getcwd()
-
- def finalize_options(self):
- pass
-
- def run(self):
- run_tests()
-
-
-if __name__ == '__main__':
- result = run_tests()
- print("<tests %s ran='%s' errors='%s' fails='%s' success='%s' gevent_enabled=%s/>" % (
- "xmlns='http//andyet.net/protocol/tests'",
- result.testsRun, len(result.errors),
- len(result.failures), result.wasSuccessful(),'gevent' in sys.modules))
diff --git a/tests/live_multiple_streams.py b/tests/live_multiple_streams.py
index 69ee74c4..b026dd55 100644
--- a/tests/live_multiple_streams.py
+++ b/tests/live_multiple_streams.py
@@ -1,16 +1,16 @@
import logging
-from sleekxmpp.test import *
+from slixmpp.test import *
-class TestMultipleStreams(SleekTest):
+class TestMultipleStreams(SlixTest):
"""
Test that we can test a live stanza stream.
"""
def setUp(self):
- self.client1 = SleekTest()
- self.client2 = SleekTest()
+ self.client1 = SlixTest()
+ self.client2 = SlixTest()
def tearDown(self):
self.client1.stream_close()
diff --git a/tests/live_test.py b/tests/live_test.py
index b71930af..327657a7 100644
--- a/tests/live_test.py
+++ b/tests/live_test.py
@@ -1,9 +1,9 @@
import logging
-from sleekxmpp.test import *
+from slixmpp.test import *
-class TestLiveStream(SleekTest):
+class TestLiveStream(SlixTest):
"""
Test that we can test a live stanza stream.
"""
diff --git a/tests/test_events.py b/tests/test_events.py
index a41ed017..65494d80 100644
--- a/tests/test_events.py
+++ b/tests/test_events.py
@@ -1,9 +1,9 @@
import time
import unittest
-from sleekxmpp.test import SleekTest
+from slixmpp.test import SlixTest
-class TestEvents(SleekTest):
+class TestEvents(SlixTest):
def setUp(self):
self.stream_start()
@@ -22,9 +22,6 @@ class TestEvents(SleekTest):
self.xmpp.event("test_event")
self.xmpp.event("test_event")
- # Give the event queue time to process.
- time.sleep(0.1)
-
msg = "Event was not triggered the correct number of times: %s"
self.failUnless(happened == [True, True], msg)
@@ -43,9 +40,6 @@ class TestEvents(SleekTest):
# Should not trigger because it was deleted
self.xmpp.event("test_event", {})
- # Give the event queue time to process.
- time.sleep(0.1)
-
msg = "Event was not triggered the correct number of times: %s"
self.failUnless(happened == [True], msg % happened)
@@ -66,9 +60,6 @@ class TestEvents(SleekTest):
self.xmpp.add_event_handler("test_event", handletestevent)
self.xmpp.event("test_event", {})
- # Give the event queue time to process.
- time.sleep(0.1)
-
msg = "Event was not triggered the correct number of times: %s"
self.failUnless(happened == [True, True], msg % happened)
@@ -86,9 +77,6 @@ class TestEvents(SleekTest):
# Should not trigger because it was deleted
self.xmpp.event("test_event", {})
- # Give the event queue time to process.
- time.sleep(0.1)
-
msg = "Event was not triggered the correct number of times: %s"
self.failUnless(happened == [True], msg % happened)
diff --git a/tests/test_jid.py b/tests/test_jid.py
index ed2aeea9..1233eb37 100644
--- a/tests/test_jid.py
+++ b/tests/test_jid.py
@@ -1,12 +1,12 @@
# -*- encoding: utf8 -*-
from __future__ import unicode_literals
import unittest
-from sleekxmpp.test import SleekTest
-from sleekxmpp import JID, InvalidJID
-from sleekxmpp.jid import nodeprep
+from slixmpp.test import SlixTest
+from slixmpp import JID, InvalidJID
+from slixmpp.jid import nodeprep
-class TestJIDClass(SleekTest):
+class TestJIDClass(SlixTest):
"""Verify that the JID class can parse and manipulate JIDs."""
@@ -138,143 +138,149 @@ class TestJIDClass(SleekTest):
def testJIDInequality(self):
jid1 = JID('user@domain/resource')
jid2 = JID('otheruser@domain/resource')
- self.assertFalse(jid1 == jid2, "Same JIDs are not considered equal")
- self.assertTrue(jid1 != jid2, "Same JIDs are considered not equal")
+ self.assertFalse(jid1 == jid2, "Different JIDs are considered equal")
+ self.assertTrue(jid1 != jid2, "Different JIDs are considered equal")
def testZeroLengthDomain(self):
- self.assertRaises(InvalidJID, JID, domain='')
+ jid1 = JID('')
+ jid2 = JID()
+ self.assertTrue(jid1 == jid2, "Empty JIDs are not considered equal")
+ self.assertTrue(jid1.domain == '', "Empty JID’s domain part not empty")
+ self.assertTrue(jid1.full == '', "Empty JID’s full part not empty")
+
+ self.assertRaises(InvalidJID, JID, 'user@')
+ self.assertRaises(InvalidJID, JID, '/resource')
self.assertRaises(InvalidJID, JID, 'user@/resource')
def testZeroLengthLocalPart(self):
- self.assertRaises(InvalidJID, JID, local='', domain='test.com')
+ self.assertRaises(InvalidJID, JID, '@test.com')
+ self.assertRaises(InvalidJID, JID, '@test.com/resource')
+
+ def testZeroLengthNodeDomain(self):
self.assertRaises(InvalidJID, JID, '@/test.com')
def testZeroLengthResource(self):
- self.assertRaises(InvalidJID, JID, domain='test.com', resource='')
self.assertRaises(InvalidJID, JID, 'test.com/')
+ self.assertRaises(InvalidJID, JID, 'user@test.com/')
def test1023LengthDomain(self):
domain = ('a.' * 509) + 'a.com'
- jid1 = JID(domain=domain)
- jid2 = JID('user@%s/resource' % domain)
+ jid = JID('user@%s/resource' % domain)
def test1023LengthLocalPart(self):
local = 'a' * 1023
- jid1 = JID(local=local, domain='test.com')
- jid2 = JID('%s@test.com' % local)
+ jid = JID('%s@test.com' % local)
def test1023LengthResource(self):
resource = 'r' * 1023
- jid1 = JID(domain='test.com', resource=resource)
- jid2 = JID('test.com/%s' % resource)
+ jid = JID('test.com/%s' % resource)
def test1024LengthDomain(self):
domain = ('a.' * 509) + 'aa.com'
- self.assertRaises(InvalidJID, JID, domain=domain)
self.assertRaises(InvalidJID, JID, 'user@%s/resource' % domain)
+ self.assertRaises(InvalidJID, JID, 'user@%s' % domain)
+ self.assertRaises(InvalidJID, JID, '%s/resource' % domain)
+ self.assertRaises(InvalidJID, JID, domain)
def test1024LengthLocalPart(self):
local = 'a' * 1024
- self.assertRaises(InvalidJID, JID, local=local, domain='test.com')
- self.assertRaises(InvalidJID, JID, '%s@/test.com' % local)
+ self.assertRaises(InvalidJID, JID, '%s@test.com' % local)
+ self.assertRaises(InvalidJID, JID, '%s@test.com/resource' % local)
def test1024LengthResource(self):
resource = 'r' * 1024
- self.assertRaises(InvalidJID, JID, domain='test.com', resource=resource)
self.assertRaises(InvalidJID, JID, 'test.com/%s' % resource)
+ self.assertRaises(InvalidJID, JID, 'user@test.com/%s' % resource)
def testTooLongDomainLabel(self):
domain = ('a' * 64) + '.com'
- self.assertRaises(InvalidJID, JID, domain=domain)
self.assertRaises(InvalidJID, JID, 'user@%s/resource' % domain)
def testDomainEmptyLabel(self):
domain = 'aaa..bbb.com'
- self.assertRaises(InvalidJID, JID, domain=domain)
self.assertRaises(InvalidJID, JID, 'user@%s/resource' % domain)
def testDomainIPv4(self):
domain = '127.0.0.1'
- jid1 = JID(domain=domain)
- jid2 = JID('user@%s/resource' % domain)
+
+ jid1 = JID('%s' % domain)
+ jid2 = JID('user@%s' % domain)
+ jid3 = JID('%s/resource' % domain)
+ jid4 = JID('user@%s/resource' % domain)
def testDomainIPv6(self):
domain = '[::1]'
- jid1 = JID(domain=domain)
- jid2 = JID('user@%s/resource' % domain)
+
+ jid1 = JID('%s' % domain)
+ jid2 = JID('user@%s' % domain)
+ jid3 = JID('%s/resource' % domain)
+ jid4 = JID('user@%s/resource' % domain)
def testDomainInvalidIPv6NoBrackets(self):
domain = '::1'
- jid1 = JID(domain=domain)
- jid2 = JID('user@%s/resource' % domain)
- self.assertEqual(jid1.domain, '[::1]')
- self.assertEqual(jid2.domain, '[::1]')
+ self.assertRaises(InvalidJID, JID, '%s' % domain)
+ self.assertRaises(InvalidJID, JID, 'user@%s' % domain)
+ self.assertRaises(InvalidJID, JID, '%s/resource' % domain)
+ self.assertRaises(InvalidJID, JID, 'user@%s/resource' % domain)
def testDomainInvalidIPv6MissingBracket(self):
domain = '[::1'
- jid1 = JID(domain=domain)
- jid2 = JID('user@%s/resource' % domain)
- self.assertEqual(jid1.domain, '[::1]')
- self.assertEqual(jid2.domain, '[::1]')
+ self.assertRaises(InvalidJID, JID, '%s' % domain)
+ self.assertRaises(InvalidJID, JID, 'user@%s' % domain)
+ self.assertRaises(InvalidJID, JID, '%s/resource' % domain)
+ self.assertRaises(InvalidJID, JID, 'user@%s/resource' % domain)
+
+ def testDomainInvalidIPv6WrongBracket(self):
+ domain = '[::]1]'
+
+ self.assertRaises(InvalidJID, JID, '%s' % domain)
+ self.assertRaises(InvalidJID, JID, 'user@%s' % domain)
+ self.assertRaises(InvalidJID, JID, '%s/resource' % domain)
+ self.assertRaises(InvalidJID, JID, 'user@%s/resource' % domain)
def testDomainWithPort(self):
domain = 'example.com:5555'
- self.assertRaises(InvalidJID, JID, domain=domain)
+
+ self.assertRaises(InvalidJID, JID, '%s' % domain)
+ self.assertRaises(InvalidJID, JID, 'user@%s' % domain)
+ self.assertRaises(InvalidJID, JID, '%s/resource' % domain)
self.assertRaises(InvalidJID, JID, 'user@%s/resource' % domain)
def testDomainWithTrailingDot(self):
domain = 'example.com.'
- jid1 = JID(domain=domain)
- jid2 = JID('user@%s/resource' % domain)
+ jid = JID('user@%s/resource' % domain)
- self.assertEqual(jid1.domain, 'example.com')
- self.assertEqual(jid2.domain, 'example.com')
+ self.assertEqual(jid.domain, 'example.com')
def testDomainWithDashes(self):
domain = 'example.com-'
- self.assertRaises(InvalidJID, JID, domain=domain)
self.assertRaises(InvalidJID, JID, 'user@%s/resource' % domain)
domain = '-example.com'
- self.assertRaises(InvalidJID, JID, domain=domain)
self.assertRaises(InvalidJID, JID, 'user@%s/resource' % domain)
def testACEDomain(self):
domain = 'xn--bcher-kva.ch'
- jid1 = JID(domain=domain)
- jid2 = JID('user@%s/resource' % domain)
-
- self.assertEqual(jid1.domain.encode('utf-8'), b'b\xc3\xbccher.ch')
- self.assertEqual(jid2.domain.encode('utf-8'), b'b\xc3\xbccher.ch')
-
- def testJIDEscapeExistingSequences(self):
- jid = JID(local='blah\\foo\\20bar', domain='example.com')
- self.assertEqual(jid.local, 'blah\\foo\\5c20bar')
+ jid = JID('user@%s/resource' % domain)
- def testJIDEscape(self):
- jid = JID(local='here\'s_a_wild_&_/cr%zy/_address_for:<wv>("IMPS")',
- domain='example.com')
- self.assertEqual(jid.local, r'here\27s_a_wild_\26_\2fcr%zy\2f_address_for\3a\3cwv\3e(\22IMPS\22)')
+ self.assertEqual(jid.domain.encode('utf-8'), b'b\xc3\xbccher.ch')
def testJIDUnescape(self):
- jid = JID(local='here\'s_a_wild_&_/cr%zy/_address_for:<wv>("IMPS")',
- domain='example.com')
+ jid = JID('here\\27s_a_wild_\\26_\\2fcr%zy\\2f_\\40ddress\\20for\\3a\\3cwv\\3e(\\22IMPS\\22)\\5c@example.com')
ujid = jid.unescape()
- self.assertEqual(ujid.local, 'here\'s_a_wild_&_/cr%zy/_address_for:<wv>("IMPS")')
+ self.assertEqual(ujid.local, 'here\'s_a_wild_&_/cr%zy/_@ddress for:<wv>("imps")\\')
- jid = JID(local='blah\\foo\\20bar', domain='example.com')
+ jid = JID('blah\\5cfoo\\5c20bar@example.com')
ujid = jid.unescape()
self.assertEqual(ujid.local, 'blah\\foo\\20bar')
def testStartOrEndWithEscapedSpaces(self):
local = ' foo'
- self.assertRaises(InvalidJID, JID, local=local, domain='example.com')
self.assertRaises(InvalidJID, JID, '%s@example.com' % local)
local = 'bar '
- self.assertRaises(InvalidJID, JID, local=local, domain='example.com')
self.assertRaises(InvalidJID, JID, '%s@example.com' % local)
# Need more input for these cases. A JID starting with \20 *is* valid
diff --git a/tests/test_overall.py b/tests/test_overall.py
index 05fdc6d8..3f32913c 100644
--- a/tests/test_overall.py
+++ b/tests/test_overall.py
@@ -14,16 +14,13 @@ class TestOverall(unittest.TestCase):
def testModules(self):
"""Testing all modules by compiling them"""
- src = '.%ssleekxmpp' % os.sep
- if sys.version_info < (3, 0):
- rx = re.compile('/[.]svn')
- else:
- rx = re.compile('/[.]svn|.*26.*')
+ src = '.%sslixmpp' % os.sep
+ rx = re.compile('/[.]svn|.*26.*')
self.failUnless(compileall.compile_dir(src, rx=rx, quiet=True))
def testTabNanny(self):
"""Testing that indentation is consistent"""
- self.failIf(tabnanny.check('..%ssleekxmpp' % os.sep))
+ self.failIf(tabnanny.check('..%sslixmpp' % os.sep))
suite = unittest.TestLoader().loadTestsFromTestCase(TestOverall)
diff --git a/tests/test_plugins.py b/tests/test_plugins.py
index 6220d7a5..ee6d44c0 100644
--- a/tests/test_plugins.py
+++ b/tests/test_plugins.py
@@ -1,7 +1,7 @@
import unittest
import logging
-from sleekxmpp.plugins.base import PluginManager, BasePlugin, register_plugin
+from slixmpp.plugins.base import PluginManager, BasePlugin, register_plugin
class A(BasePlugin):
@@ -77,7 +77,7 @@ class TestPlugins(unittest.TestCase):
p.disable('a')
self.assertEqual(len(p), 0, "Wrong number of enabled plugins.")
- self.assertEqual(events, ['init', 'end'],
+ self.assertEqual(events, ['init', 'end'],
"Plugin lifecycle methods not called.")
def test_enable_dependencies(self):
diff --git a/tests/test_stanza_base.py b/tests/test_stanza_base.py
index deb7ab96..dac3f046 100644
--- a/tests/test_stanza_base.py
+++ b/tests/test_stanza_base.py
@@ -1,9 +1,9 @@
import unittest
-from sleekxmpp.test import SleekTest
-from sleekxmpp.xmlstream.stanzabase import ET, StanzaBase
+from slixmpp.test import SlixTest
+from slixmpp.xmlstream.stanzabase import ET, StanzaBase
-class TestStanzaBase(SleekTest):
+class TestStanzaBase(SlixTest):
def testTo(self):
"""Test the 'to' interface of StanzaBase."""
@@ -61,7 +61,7 @@ class TestStanzaBase(SleekTest):
stanza['from'] = "sender@example.com"
stanza['payload'] = ET.Element("{foo}foo")
- stanza.reply()
+ stanza = stanza.reply()
self.failUnless(str(stanza['to'] == "sender@example.com"),
"Stanza reply did not change 'to' attribute.")
diff --git a/tests/test_stanza_element.py b/tests/test_stanza_element.py
index e678b56e..0c49f201 100644
--- a/tests/test_stanza_element.py
+++ b/tests/test_stanza_element.py
@@ -1,10 +1,10 @@
import unittest
-from sleekxmpp.test import SleekTest
-from sleekxmpp.xmlstream.stanzabase import ElementBase, register_stanza_plugin, ET
-from sleekxmpp.thirdparty import OrderedDict
+from slixmpp.test import SlixTest
+from slixmpp.xmlstream.stanzabase import ElementBase, register_stanza_plugin, ET
+from collections import OrderedDict
-class TestElementBase(SleekTest):
+class TestElementBase(SlixTest):
def testFixNs(self):
"""Test fixing namespaces in an XPath expression."""
@@ -38,7 +38,7 @@ class TestElementBase(SleekTest):
""")
def testGetStanzaValues(self):
- """Test getStanzaValues using plugins and substanzas."""
+ """Test get_stanza_values using plugins and substanzas."""
class TestStanzaPlugin(ElementBase):
name = "foo2"
@@ -65,7 +65,7 @@ class TestElementBase(SleekTest):
substanza['bar'] = 'c'
stanza.append(substanza)
- values = stanza.getStanzaValues()
+ values = stanza.get_stanza_values()
expected = {'lang': '',
'bar': 'a',
'baz': '',
@@ -85,7 +85,7 @@ class TestElementBase(SleekTest):
def testSetStanzaValues(self):
- """Test using setStanzaValues with substanzas and plugins."""
+ """Test using set_stanza_values with substanzas and plugins."""
class TestStanzaPlugin(ElementBase):
name = "pluginfoo"
@@ -157,10 +157,10 @@ class TestElementBase(SleekTest):
stanza = TestStanza()
substanza = TestStanza()
stanza.append(substanza)
- stanza.setStanzaValues({'bar': 'a',
- 'baz': 'b',
- 'qux': 42,
- 'foobar': {'fizz': 'c'}})
+ stanza.set_stanza_values({'bar': 'a',
+ 'baz': 'b',
+ 'qux': 42,
+ 'foobar': {'fizz': 'c'}})
# Test non-plugin interfaces
expected = {'substanzas': [substanza],
diff --git a/tests/test_stanza_error.py b/tests/test_stanza_error.py
index d95a33ce..c6a92eb6 100644
--- a/tests/test_stanza_error.py
+++ b/tests/test_stanza_error.py
@@ -1,8 +1,8 @@
import unittest
-from sleekxmpp.test import SleekTest
+from slixmpp.test import SlixTest
-class TestErrorStanzas(SleekTest):
+class TestErrorStanzas(SlixTest):
def setUp(self):
# Ensure that the XEP-0086 plugin has been loaded.
diff --git a/tests/test_stanza_gmail.py b/tests/test_stanza_gmail.py
index a15fea20..a17efca2 100644
--- a/tests/test_stanza_gmail.py
+++ b/tests/test_stanza_gmail.py
@@ -1,11 +1,11 @@
import unittest
-from sleekxmpp import Iq
-from sleekxmpp.test import SleekTest
-import sleekxmpp.plugins.gmail_notify as gmail
-from sleekxmpp.xmlstream import register_stanza_plugin, ET
+from slixmpp import Iq
+from slixmpp.test import SlixTest
+import slixmpp.plugins.gmail_notify as gmail
+from slixmpp.xmlstream import register_stanza_plugin, ET
-class TestGmail(SleekTest):
+class TestGmail(SlixTest):
def setUp(self):
register_stanza_plugin(Iq, gmail.GmailQuery)
diff --git a/tests/test_stanza_iq.py b/tests/test_stanza_iq.py
index 0f5e30b0..0b248da6 100644
--- a/tests/test_stanza_iq.py
+++ b/tests/test_stanza_iq.py
@@ -1,9 +1,9 @@
import unittest
-from sleekxmpp.test import SleekTest
-from sleekxmpp.xmlstream.stanzabase import ET
+from slixmpp.test import SlixTest
+from slixmpp.xmlstream.stanzabase import ET
-class TestIqStanzas(SleekTest):
+class TestIqStanzas(SlixTest):
def tearDown(self):
"""Shutdown the XML stream after testing."""
@@ -19,7 +19,7 @@ class TestIqStanzas(SleekTest):
def testPayload(self):
"""Test setting Iq stanza payload."""
iq = self.Iq()
- iq.setPayload(ET.Element('{test}tester'))
+ iq.set_payload(ET.Element('{test}tester'))
self.check(iq, """
<iq id="0">
<tester xmlns="test" />
@@ -82,7 +82,7 @@ class TestIqStanzas(SleekTest):
iq = self.Iq()
iq['to'] = 'user@localhost'
iq['type'] = 'get'
- iq.reply()
+ iq = iq.reply()
self.check(iq, """
<iq id="0" type="result" />
diff --git a/tests/test_stanza_message.py b/tests/test_stanza_message.py
index 9968a630..68c78dab 100644
--- a/tests/test_stanza_message.py
+++ b/tests/test_stanza_message.py
@@ -1,11 +1,11 @@
import unittest
-from sleekxmpp.test import SleekTest
-from sleekxmpp.stanza.message import Message
-from sleekxmpp.stanza.htmlim import HTMLIM
-from sleekxmpp.xmlstream import register_stanza_plugin
+from slixmpp.test import SlixTest
+from slixmpp.stanza.message import Message
+from slixmpp.stanza.htmlim import HTMLIM
+from slixmpp.xmlstream import register_stanza_plugin
-class TestMessageStanzas(SleekTest):
+class TestMessageStanzas(SlixTest):
def setUp(self):
register_stanza_plugin(Message, HTMLIM)
@@ -17,7 +17,7 @@ class TestMessageStanzas(SleekTest):
msg['from'] = 'room@someservice.someserver.tld/somenick'
msg['type'] = 'groupchat'
msg['body'] = "this is a message"
- msg.reply()
+ msg = msg.reply()
self.failUnless(str(msg['to']) == 'room@someservice.someserver.tld')
def testAttribProperty(self):
@@ -29,12 +29,12 @@ class TestMessageStanzas(SleekTest):
def testHTMLPlugin(self):
"Test message/html/body stanza"
msg = self.Message()
- msg['to'] = "fritzy@netflint.net/sleekxmpp"
+ msg['to'] = "fritzy@netflint.net/slixmpp"
msg['body'] = "this is the plaintext message"
msg['type'] = 'chat'
msg['html']['body'] = '<p>This is the htmlim message</p>'
self.check(msg, """
- <message to="fritzy@netflint.net/sleekxmpp" type="chat">
+ <message to="fritzy@netflint.net/slixmpp" type="chat">
<body>this is the plaintext message</body>
<html xmlns="http://jabber.org/protocol/xhtml-im">
<body xmlns="http://www.w3.org/1999/xhtml">
diff --git a/tests/test_stanza_presence.py b/tests/test_stanza_presence.py
index 184dce96..73aaba97 100644
--- a/tests/test_stanza_presence.py
+++ b/tests/test_stanza_presence.py
@@ -1,8 +1,8 @@
import unittest
-import sleekxmpp
-from sleekxmpp.test import SleekTest
+import slixmpp
+from slixmpp.test import SlixTest
-class TestPresenceStanzas(SleekTest):
+class TestPresenceStanzas(SlixTest):
def testPresenceShowRegression(self):
"""Regression check presence['type'] = 'dnd' show value working"""
@@ -38,7 +38,7 @@ class TestPresenceStanzas(SleekTest):
p['type'] = 'unavailable'
p['from'] = 'bill@chadmore.com/gmail15af'
- c = sleekxmpp.ClientXMPP('crap@wherever', 'password')
+ c = slixmpp.ClientXMPP('crap@wherever', 'password')
happened = []
def handlechangedpresence(event):
diff --git a/tests/test_stanza_roster.py b/tests/test_stanza_roster.py
index d121568b..4496fc18 100644
--- a/tests/test_stanza_roster.py
+++ b/tests/test_stanza_roster.py
@@ -1,14 +1,14 @@
import unittest
-from sleekxmpp.test import SleekTest
-from sleekxmpp.xmlstream import ET
+from slixmpp.test import SlixTest
+from slixmpp.xmlstream import ET
-class TestRosterStanzas(SleekTest):
+class TestRosterStanzas(SlixTest):
def testAddItems(self):
"""Test adding items to a roster stanza."""
iq = self.Iq()
- iq['roster'].setItems({
+ iq['roster'].set_items({
'user@example.com': {
'name': 'User',
'subscription': 'both',
diff --git a/tests/test_stanza_xep_0004.py b/tests/test_stanza_xep_0004.py
index b87afb24..7b01b575 100644
--- a/tests/test_stanza_xep_0004.py
+++ b/tests/test_stanza_xep_0004.py
@@ -1,13 +1,13 @@
import unittest
-from sleekxmpp import Message
-from sleekxmpp.test import SleekTest
-from sleekxmpp.thirdparty import OrderedDict
+from slixmpp import Message
+from slixmpp.test import SlixTest
+from collections import OrderedDict
-import sleekxmpp.plugins.xep_0004 as xep_0004
-from sleekxmpp.xmlstream import register_stanza_plugin
+import slixmpp.plugins.xep_0004 as xep_0004
+from slixmpp.xmlstream import register_stanza_plugin
-class TestDataForms(SleekTest):
+class TestDataForms(SlixTest):
def setUp(self):
register_stanza_plugin(Message, xep_0004.Form)
diff --git a/tests/test_stanza_xep_0009.py b/tests/test_stanza_xep_0009.py
index fa1ed19b..f1a61b80 100644
--- a/tests/test_stanza_xep_0009.py
+++ b/tests/test_stanza_xep_0009.py
@@ -1,9 +1,9 @@
# -*- encoding:utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Dann Martens (TOMOTON).
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -13,22 +13,18 @@ from __future__ import unicode_literals
import base64
import sys
-from sleekxmpp.plugins.xep_0009.stanza.RPC import RPCQuery, MethodCall, \
+from slixmpp.plugins.xep_0009.stanza.RPC import RPCQuery, MethodCall, \
MethodResponse
-from sleekxmpp.plugins.xep_0009.binding import py2xml, xml2py, rpcbase64, \
+from slixmpp.plugins.xep_0009.binding import py2xml, xml2py, rpcbase64, \
rpctime
-from sleekxmpp.stanza.iq import Iq
-from sleekxmpp.test.sleektest import SleekTest
-from sleekxmpp.xmlstream.stanzabase import register_stanza_plugin
-from sleekxmpp.xmlstream.tostring import tostring
+from slixmpp.stanza.iq import Iq
+from slixmpp.test.slixtest import SlixTest
+from slixmpp.xmlstream.stanzabase import register_stanza_plugin
+from slixmpp.xmlstream.tostring import tostring
import unittest
-if sys.version_info > (3, 0):
- unicode = str
-
-
-class TestJabberRPC(SleekTest):
+class TestJabberRPC(SlixTest):
def setUp(self):
register_stanza_plugin(Iq, RPCQuery)
diff --git a/tests/test_stanza_xep_0030.py b/tests/test_stanza_xep_0030.py
index 986c1880..d8e99ffb 100644
--- a/tests/test_stanza_xep_0030.py
+++ b/tests/test_stanza_xep_0030.py
@@ -1,11 +1,11 @@
import unittest
-from sleekxmpp import Iq
-from sleekxmpp.test import SleekTest
-import sleekxmpp.plugins.xep_0030 as xep_0030
-from sleekxmpp.xmlstream import register_stanza_plugin
+from slixmpp import Iq
+from slixmpp.test import SlixTest
+import slixmpp.plugins.xep_0030 as xep_0030
+from slixmpp.xmlstream import register_stanza_plugin
-class TestDisco(SleekTest):
+class TestDisco(SlixTest):
"""
Test creating and manipulating the disco#info and
diff --git a/tests/test_stanza_xep_0033.py b/tests/test_stanza_xep_0033.py
index bf10cf6c..0e560a7e 100644
--- a/tests/test_stanza_xep_0033.py
+++ b/tests/test_stanza_xep_0033.py
@@ -1,11 +1,11 @@
import unittest
-from sleekxmpp import Message
-from sleekxmpp.test import SleekTest
-import sleekxmpp.plugins.xep_0033 as xep_0033
-from sleekxmpp.xmlstream import register_stanza_plugin
+from slixmpp import Message
+from slixmpp.test import SlixTest
+import slixmpp.plugins.xep_0033 as xep_0033
+from slixmpp.xmlstream import register_stanza_plugin
-class TestAddresses(SleekTest):
+class TestAddresses(SlixTest):
def setUp(self):
register_stanza_plugin(Message, xep_0033.Addresses)
diff --git a/tests/test_stanza_xep_0047.py b/tests/test_stanza_xep_0047.py
index 9fd3c4d6..12283136 100644
--- a/tests/test_stanza_xep_0047.py
+++ b/tests/test_stanza_xep_0047.py
@@ -1,12 +1,12 @@
import unittest
-from sleekxmpp.exceptions import XMPPError
-from sleekxmpp import Iq
-from sleekxmpp.test import SleekTest
-from sleekxmpp.plugins.xep_0047 import Data
-from sleekxmpp.xmlstream import register_stanza_plugin, ET
+from slixmpp.exceptions import XMPPError
+from slixmpp import Iq
+from slixmpp.test import SlixTest
+from slixmpp.plugins.xep_0047 import Data
+from slixmpp.xmlstream import register_stanza_plugin, ET
-class TestIBB(SleekTest):
+class TestIBB(SlixTest):
def setUp(self):
register_stanza_plugin(Iq, Data)
@@ -82,11 +82,11 @@ class TestIBB(SleekTest):
iq = Iq()
iq['type'] = 'set'
iq['ibb_data']['seq'] = 0
- iq['ibb_data']['data'] = 'sleekxmpp'
+ iq['ibb_data']['data'] = 'slixmpp'
self.check(iq, """
<iq type="set">
- <data xmlns="http://jabber.org/protocol/ibb" seq="0">c2xlZWt4bXBw</data>
+ <data xmlns="http://jabber.org/protocol/ibb" seq="0">c2xpeG1wcA==</data>
</iq>
""")
diff --git a/tests/test_stanza_xep_0050.py b/tests/test_stanza_xep_0050.py
index 9d49b3ee..7272d783 100644
--- a/tests/test_stanza_xep_0050.py
+++ b/tests/test_stanza_xep_0050.py
@@ -1,11 +1,11 @@
-from sleekxmpp import Iq
+from slixmpp import Iq
import unittest
-from sleekxmpp.test import SleekTest
-from sleekxmpp.plugins.xep_0050 import Command
-from sleekxmpp.xmlstream import register_stanza_plugin
+from slixmpp.test import SlixTest
+from slixmpp.plugins.xep_0050 import Command
+from slixmpp.xmlstream import register_stanza_plugin
-class TestAdHocCommandStanzas(SleekTest):
+class TestAdHocCommandStanzas(SlixTest):
def setUp(self):
register_stanza_plugin(Iq, Command)
diff --git a/tests/test_stanza_xep_0059.py b/tests/test_stanza_xep_0059.py
index 860ec869..246481ce 100644
--- a/tests/test_stanza_xep_0059.py
+++ b/tests/test_stanza_xep_0059.py
@@ -1,10 +1,10 @@
import unittest
-from sleekxmpp.test import SleekTest
-from sleekxmpp.plugins.xep_0059 import Set
-from sleekxmpp.xmlstream import ET
+from slixmpp.test import SlixTest
+from slixmpp.plugins.xep_0059 import Set
+from slixmpp.xmlstream import ET
-class TestSetStanzas(SleekTest):
+class TestSetStanzas(SlixTest):
def testSetFirstIndex(self):
s = Set()
diff --git a/tests/test_stanza_xep_0060.py b/tests/test_stanza_xep_0060.py
index 332b53ea..567757cb 100644
--- a/tests/test_stanza_xep_0060.py
+++ b/tests/test_stanza_xep_0060.py
@@ -1,11 +1,11 @@
import unittest
-from sleekxmpp.test import SleekTest
-import sleekxmpp.plugins.xep_0004 as xep_0004
-import sleekxmpp.plugins.xep_0060.stanza as pubsub
-from sleekxmpp.xmlstream.stanzabase import ET
+from slixmpp.test import SlixTest
+import slixmpp.plugins.xep_0004 as xep_0004
+import slixmpp.plugins.xep_0060.stanza as pubsub
+from slixmpp.xmlstream.stanzabase import ET
-class TestPubsubStanzas(SleekTest):
+class TestPubsubStanzas(SlixTest):
def testAffiliations(self):
"Testing iq/pubsub/affiliations/affiliation stanzas"
@@ -55,12 +55,12 @@ class TestPubsubStanzas(SleekTest):
iq = self.Iq()
iq['pubsub']['subscription']['suboptions']['required'] = True
iq['pubsub']['subscription']['node'] = 'testnode alsdkjfas'
- iq['pubsub']['subscription']['jid'] = "fritzy@netflint.net/sleekxmpp"
+ iq['pubsub']['subscription']['jid'] = "fritzy@netflint.net/slixmpp"
iq['pubsub']['subscription']['subscription'] = 'unconfigured'
self.check(iq, """
<iq id="0">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
- <subscription node="testnode alsdkjfas" jid="fritzy@netflint.net/sleekxmpp" subscription="unconfigured">
+ <subscription node="testnode alsdkjfas" jid="fritzy@netflint.net/slixmpp" subscription="unconfigured">
<subscribe-options>
<required />
</subscribe-options>
@@ -157,17 +157,17 @@ class TestPubsubStanzas(SleekTest):
iq = self.Iq()
iq['pubsub']['subscribe']['options']
iq['pubsub']['subscribe']['node'] = 'cheese'
- iq['pubsub']['subscribe']['jid'] = 'fritzy@netflint.net/sleekxmpp'
+ iq['pubsub']['subscribe']['jid'] = 'fritzy@netflint.net/slixmpp'
iq['pubsub']['subscribe']['options']['node'] = 'cheese'
- iq['pubsub']['subscribe']['options']['jid'] = 'fritzy@netflint.net/sleekxmpp'
+ iq['pubsub']['subscribe']['options']['jid'] = 'fritzy@netflint.net/slixmpp'
form = xep_0004.Form()
form.addField('pubsub#title', ftype='text-single', value='this thing is awesome')
iq['pubsub']['subscribe']['options']['options'] = form
self.check(iq, """
<iq id="0">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
- <subscribe node="cheese" jid="fritzy@netflint.net/sleekxmpp">
- <options node="cheese" jid="fritzy@netflint.net/sleekxmpp">
+ <subscribe node="cheese" jid="fritzy@netflint.net/slixmpp">
+ <options node="cheese" jid="fritzy@netflint.net/slixmpp">
<x xmlns="jabber:x:data" type="submit">
<field var="pubsub#title">
<value>this thing is awesome</value>
diff --git a/tests/test_stanza_xep_0085.py b/tests/test_stanza_xep_0085.py
index 303e6c5b..d62d2e46 100644
--- a/tests/test_stanza_xep_0085.py
+++ b/tests/test_stanza_xep_0085.py
@@ -1,11 +1,11 @@
import unittest
-from sleekxmpp import Message
-from sleekxmpp.test import SleekTest
-import sleekxmpp.plugins.xep_0085 as xep_0085
-from sleekxmpp.xmlstream import register_stanza_plugin
+from slixmpp import Message
+from slixmpp.test import SlixTest
+import slixmpp.plugins.xep_0085 as xep_0085
+from slixmpp.xmlstream import register_stanza_plugin
-class TestChatStates(SleekTest):
+class TestChatStates(SlixTest):
def setUp(self):
register_stanza_plugin(Message, xep_0085.stanza.Active)
diff --git a/tests/test_stanza_xep_0122.py b/tests/test_stanza_xep_0122.py
index fca49bbb..0c032c05 100644
--- a/tests/test_stanza_xep_0122.py
+++ b/tests/test_stanza_xep_0122.py
@@ -1,13 +1,13 @@
import unittest
-from sleekxmpp import Message
-from sleekxmpp.test import SleekTest
-import sleekxmpp.plugins.xep_0004 as xep_0004
-import sleekxmpp.plugins.xep_0122 as xep_0122
-from sleekxmpp.xmlstream import register_stanza_plugin
+from slixmpp import Message
+from slixmpp.test import SlixTest
+import slixmpp.plugins.xep_0004 as xep_0004
+import slixmpp.plugins.xep_0122 as xep_0122
+from slixmpp.xmlstream import register_stanza_plugin
-class TestDataForms(SleekTest):
+class TestDataForms(SlixTest):
def setUp(self):
register_stanza_plugin(Message, xep_0004.Form)
@@ -19,12 +19,12 @@ class TestDataForms(SleekTest):
"""Testing basic validation setting and getting."""
msg = self.Message()
form = msg['form']
- field = form.addField(var='f1',
- ftype='text-single',
- label='Text',
- desc='A text field',
- required=True,
- value='Some text!')
+ field = form.add_field(var='f1',
+ ftype='text-single',
+ label='Text',
+ desc='A text field',
+ required=True,
+ value='Some text!')
validation = field['validate']
validation['datatype'] = 'xs:string'
@@ -54,12 +54,12 @@ class TestDataForms(SleekTest):
"""Testing open validation setting and getting."""
msg = self.Message()
form = msg['form']
- field = form.addField(var='f1',
- ftype='text-single',
- label='Text',
- desc='A text field',
- required=True,
- value='Some text!')
+ field = form.add_field(var='f1',
+ ftype='text-single',
+ label='Text',
+ desc='A text field',
+ required=True,
+ value='Some text!')
validation = field['validate']
validation.set_open(True)
@@ -88,12 +88,12 @@ class TestDataForms(SleekTest):
"""Testing regex validation setting and getting."""
msg = self.Message()
form = msg['form']
- field = form.addField(var='f1',
- ftype='text-single',
- label='Text',
- desc='A text field',
- required=True,
- value='Some text!')
+ field = form.add_field(var='f1',
+ ftype='text-single',
+ label='Text',
+ desc='A text field',
+ required=True,
+ value='Some text!')
regex_value = '[0-9]+'
@@ -126,12 +126,12 @@ class TestDataForms(SleekTest):
"""Testing range validation setting and getting."""
msg = self.Message()
form = msg['form']
- field = form.addField(var='f1',
- ftype='text-single',
- label='Text',
- desc='A text field',
- required=True,
- value='Some text!')
+ field = form.add_field(var='f1',
+ ftype='text-single',
+ label='Text',
+ desc='A text field',
+ required=True,
+ value='Some text!')
validation = field['validate']
validation.set_range(True, minimum=0, maximum=10)
@@ -160,11 +160,11 @@ class TestDataForms(SleekTest):
"""
msg = self.Message()
form = msg['form']
- field = form.addReported(var='f1', ftype='text-single', label='Text')
+ field = form.add_reported(var='f1', ftype='text-single', label='Text')
validation = field['validate']
validation.set_basic(True)
- form.addItem({'f1': 'Some text!'})
+ form.add_item({'f1': 'Some text!'})
self.check(msg, """
<message>
diff --git a/tests/test_stanza_xep_0184.py b/tests/test_stanza_xep_0184.py
index 0c340487..9d2f0c07 100644
--- a/tests/test_stanza_xep_0184.py
+++ b/tests/test_stanza_xep_0184.py
@@ -1,11 +1,11 @@
import unittest
-from sleekxmpp import Message
-from sleekxmpp.test import SleekTest
-import sleekxmpp.plugins.xep_0184 as xep_0184
-from sleekxmpp.xmlstream import register_stanza_plugin
+from slixmpp import Message
+from slixmpp.test import SlixTest
+import slixmpp.plugins.xep_0184 as xep_0184
+from slixmpp.xmlstream import register_stanza_plugin
-class TestReciept(SleekTest):
+class TestReciept(SlixTest):
def setUp(self):
register_stanza_plugin(Message, xep_0184.Request)
diff --git a/tests/test_stanza_xep_0323.py b/tests/test_stanza_xep_0323.py
index 7b1dfe42..991481d7 100644
--- a/tests/test_stanza_xep_0323.py
+++ b/tests/test_stanza_xep_0323.py
@@ -1,12 +1,11 @@
# -*- coding: utf-8 -*-
-from sleekxmpp.test import *
-import sleekxmpp.plugins.xep_0323 as xep_0323
+from slixmpp.test import *
+import slixmpp.plugins.xep_0323 as xep_0323
namespace='sn'
-class TestSensorDataStanzas(SleekTest):
-
+class TestSensorDataStanzas(SlixTest):
def setUp(self):
pass
diff --git a/tests/test_stanza_xep_0325.py b/tests/test_stanza_xep_0325.py
index dc2e8efe..3e388ac3 100644
--- a/tests/test_stanza_xep_0325.py
+++ b/tests/test_stanza_xep_0325.py
@@ -1,21 +1,20 @@
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
-from sleekxmpp.test import *
-import sleekxmpp.plugins.xep_0325 as xep_0325
+from slixmpp.test import *
+import slixmpp.plugins.xep_0325 as xep_0325
namespace='sn'
-class TestControlStanzas(SleekTest):
-
+class TestControlStanzas(SlixTest):
def setUp(self):
pass
diff --git a/tests/test_stream.py b/tests/test_stream.py
index f68f8426..0476039c 100644
--- a/tests/test_stream.py
+++ b/tests/test_stream.py
@@ -1,9 +1,9 @@
import time
import unittest
-from sleekxmpp.test import SleekTest
+from slixmpp.test import SlixTest
-class TestStreamTester(SleekTest):
+class TestStreamTester(SlixTest):
"""
Test that we can simulate and test a stanza stream.
"""
@@ -16,7 +16,7 @@ class TestStreamTester(SleekTest):
self.stream_start(mode='client')
def echo(msg):
- msg.reply('Thanks for sending: %(body)s' % msg).send()
+ msg.reply('Thanks for sending: %s' % msg['body']).send()
self.xmpp.add_event_handler('message', echo)
@@ -58,23 +58,4 @@ class TestStreamTester(SleekTest):
self.stream_start(mode='client', skip=False)
self.send_header(sto='localhost')
- def testStreamDisconnect(self):
- """Test that the test socket can simulate disconnections."""
- self.stream_start()
- events = set()
-
- def stream_error(event):
- events.add('socket_error')
-
- self.xmpp.add_event_handler('socket_error', stream_error)
-
- self.stream_disconnect()
- self.xmpp.send_raw(' ')
-
- time.sleep(.1)
-
- self.failUnless('socket_error' in events,
- "Stream error event not raised: %s" % events)
-
-
suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamTester)
diff --git a/tests/test_stream_exceptions.py b/tests/test_stream_exceptions.py
index d18d059a..f21f197e 100644
--- a/tests/test_stream_exceptions.py
+++ b/tests/test_stream_exceptions.py
@@ -1,11 +1,11 @@
-from sleekxmpp.xmlstream.matcher import MatchXPath
-from sleekxmpp.xmlstream.handler import Callback
-from sleekxmpp.exceptions import XMPPError
+from slixmpp.xmlstream.matcher import MatchXPath
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.exceptions import XMPPError
import unittest
-from sleekxmpp.test import SleekTest
+from slixmpp.test import SlixTest
-class TestStreamExceptions(SleekTest):
+class TestStreamExceptions(SlixTest):
"""
Test handling roster updates.
"""
@@ -13,40 +13,11 @@ class TestStreamExceptions(SleekTest):
def tearDown(self):
self.stream_close()
- def testExceptionReply(self):
- """Test that raising an exception replies with the original stanza."""
-
- def message(msg):
- msg.reply()
- msg['body'] = 'Body changed'
- raise XMPPError(clear=False)
-
- self.stream_start()
- self.xmpp.add_event_handler('message', message)
-
- self.recv("""
- <message>
- <body>This is going to cause an error.</body>
- </message>
- """)
-
- self.send("""
- <message type="error">
- <body>This is going to cause an error.</body>
- <error type="cancel" code="500">
- <undefined-condition
- xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
- </error>
- </message>
- """)
-
def testExceptionContinueWorking(self):
- """Test that Sleek continues to respond after an XMPPError is raised."""
+ """Test that Slixmpp continues to respond after an XMPPError is raised."""
def message(msg):
- msg.reply()
- msg['body'] = 'Body changed'
- raise XMPPError(clear=False)
+ raise XMPPError(clear=True)
self.stream_start()
self.xmpp.add_event_handler('message', message)
@@ -59,7 +30,6 @@ class TestStreamExceptions(SleekTest):
self.send("""
<message type="error">
- <body>This is going to cause an error.</body>
<error type="cancel" code="500">
<undefined-condition
xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
@@ -75,7 +45,6 @@ class TestStreamExceptions(SleekTest):
self.send("""
<message type="error">
- <body>This is going to cause an error.</body>
<error type="cancel" code="500">
<undefined-condition
xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
@@ -151,38 +120,8 @@ class TestStreamExceptions(SleekTest):
</iq>
""", use_values=False)
- def testThreadedXMPPErrorException(self):
- """Test raising an XMPPError exception in a threaded handler."""
-
- def message(msg):
- raise XMPPError(condition='feature-not-implemented',
- text="We don't do things that way here.",
- etype='cancel')
-
- self.stream_start()
- self.xmpp.add_event_handler('message', message,
- threaded=True)
-
- self.recv("""
- <message>
- <body>This is going to cause an error.</body>
- </message>
- """)
-
- self.send("""
- <message type="error">
- <error type="cancel" code="501">
- <feature-not-implemented
- xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
- <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
- We don&apos;t do things that way here.
- </text>
- </error>
- </message>
- """)
-
def testUnknownException(self):
- """Test raising an generic exception in a threaded handler."""
+ """Test raising an generic exception in a handler."""
raised_errors = []
@@ -208,7 +147,7 @@ class TestStreamExceptions(SleekTest):
<undefined-condition
xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
- SleekXMPP got into trouble.
+ Slixmpp got into trouble.
</text>
</error>
</message>
@@ -217,7 +156,7 @@ class TestStreamExceptions(SleekTest):
self.assertEqual(raised_errors, [True], "Exception was not raised: %s" % raised_errors)
def testUnknownException(self):
- """Test Sleek continues to respond after an unknown exception."""
+ """Test Slixmpp continues to respond after an unknown exception."""
raised_errors = []
@@ -243,7 +182,7 @@ class TestStreamExceptions(SleekTest):
<undefined-condition
xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
- SleekXMPP got into trouble.
+ Slixmpp got into trouble.
</text>
</error>
</message>
@@ -261,7 +200,7 @@ class TestStreamExceptions(SleekTest):
<undefined-condition
xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
- SleekXMPP got into trouble.
+ Slixmpp got into trouble.
</text>
</error>
</message>
diff --git a/tests/test_stream_filters.py b/tests/test_stream_filters.py
index ee17ffdc..c5fde338 100644
--- a/tests/test_stream_filters.py
+++ b/tests/test_stream_filters.py
@@ -1,11 +1,11 @@
import time
-from sleekxmpp import Message
+from slixmpp import Message
import unittest
-from sleekxmpp.test import SleekTest
+from slixmpp.test import SlixTest
-class TestFilters(SleekTest):
+class TestFilters(SlixTest):
"""
Test using incoming and outgoing filters.
@@ -47,8 +47,6 @@ class TestFilters(SleekTest):
</message>
""")
- time.sleep(0.5)
-
self.assertEqual(data, ['', 'testing filter'],
'Incoming filter did not apply %s' % data)
diff --git a/tests/test_stream_handlers.py b/tests/test_stream_handlers.py
index 0208cd16..24b5c1a6 100644
--- a/tests/test_stream_handlers.py
+++ b/tests/test_stream_handlers.py
@@ -2,12 +2,12 @@ import time
import threading
import unittest
-from sleekxmpp.test import SleekTest
-from sleekxmpp.exceptions import IqTimeout
-from sleekxmpp import Callback, MatchXPath
+from slixmpp.test import SlixTest
+from slixmpp.exceptions import IqTimeout
+from slixmpp import Callback, MatchXPath
-class TestHandlers(SleekTest):
+class TestHandlers(SlixTest):
"""
Test using handlers and waiters.
"""
@@ -48,15 +48,15 @@ class TestHandlers(SleekTest):
iq['id'] = 'test'
iq['type'] = 'set'
iq['query'] = 'test'
- reply = iq.send(block=True)
- if reply:
+ def callback_waiter(result):
self.xmpp.send_raw("""
<message>
<body>Successful: %s</body>
</message>
- """ % reply['query'])
+ """ % result['query'])
+ iq.send(callback=callback_waiter)
- self.xmpp.add_event_handler('message', waiter_handler, threaded=True)
+ self.xmpp.add_event_handler('message', waiter_handler)
# Send message to trigger waiter_handler
self.recv("""
@@ -93,11 +93,11 @@ class TestHandlers(SleekTest):
iq['type'] = 'set'
iq['query'] = 'test2'
try:
- reply = iq.send(block=True, timeout=0)
+ reply = iq.send(timeout=0)
except IqTimeout:
pass
- self.xmpp.add_event_handler('message', waiter_handler, threaded=True)
+ self.xmpp.add_event_handler('message', waiter_handler)
# Start test by triggerig waiter_handler
self.recv("""<message><body>Start Test</body></message>""")
@@ -109,9 +109,6 @@ class TestHandlers(SleekTest):
iq['query'] = 'test2'
self.send(iq)
- # Give the event queue time to process.
- time.sleep(0.1)
-
# Check that the waiter is no longer registered
waiter_exists = self.xmpp.remove_handler('IqWait_test2')
@@ -148,41 +145,9 @@ class TestHandlers(SleekTest):
</iq>
""")
- # Give event queue time to process
- time.sleep(0.1)
-
self.failUnless(events == ['foo'],
"Iq callback was not executed: %s" % events)
- def testIqTimeoutCallback(self):
- """Test that iq.send(tcallback=handle_foo, timeout_callback=handle_timeout) works."""
- events = []
-
- def handle_foo(iq):
- events.append('foo')
-
- def handle_timeout(iq):
- events.append('timeout')
-
- iq = self.Iq()
- iq['type'] = 'get'
- iq['id'] = 'test-foo'
- iq['to'] = 'user@localhost'
- iq['query'] = 'foo'
- iq.send(callback=handle_foo, timeout_callback=handle_timeout, timeout=0.05)
-
- self.send("""
- <iq type="get" id="test-foo" to="user@localhost">
- <query xmlns="foo" />
- </iq>
- """)
-
- # Give event queue time to process
- time.sleep(1)
-
- self.failUnless(events == ['timeout'],
- "Iq timeout was not executed: %s" % events)
-
def testMultipleHandlersForStanza(self):
"""
Test that multiple handlers for a single stanza work
@@ -235,26 +200,23 @@ class TestHandlers(SleekTest):
events = []
- def run_test():
- # Check that Iq was sent by waiter_handler
- iq = self.Iq()
- iq['id'] = 'test'
- iq['to'] = 'tester@sleekxmpp.com/test'
- iq['type'] = 'set'
- iq['query'] = 'test'
- result = iq.send()
+ def callback(result):
events.append(result['from'].full)
- t = threading.Thread(name="sender_test", target=run_test)
- t.start()
+ iq = self.Iq()
+ iq['id'] = 'test'
+ iq['to'] = 'tester@slixmpp.com/test'
+ iq['type'] = 'set'
+ iq['query'] = 'test'
+ iq.send(callback=callback)
self.recv("""
- <iq id="test" from="evil@sleekxmpp.com/bad" type="result">
+ <iq id="test" from="evil@slixmpp.com/bad" type="result">
<query xmlns="test" />
</iq>
""")
self.recv("""
- <iq id="test" from="evil2@sleekxmpp.com" type="result">
+ <iq id="test" from="evil2@slixmpp.com" type="result">
<query xmlns="test" />
</iq>
""")
@@ -266,18 +228,12 @@ class TestHandlers(SleekTest):
# Now for a good one
self.recv("""
- <iq id="test" from="tester@sleekxmpp.com/test" type="result">
+ <iq id="test" from="tester@slixmpp.com/test" type="result">
<query xmlns="test" />
</iq>
""")
- t.join()
-
- time.sleep(0.1)
-
- self.assertEqual(events, ['tester@sleekxmpp.com/test'], "Did not timeout on bad sender")
-
-
+ self.assertEqual(events, ['tester@slixmpp.com/test'], "Did not timeout on bad sender")
suite = unittest.TestLoader().loadTestsFromTestCase(TestHandlers)
diff --git a/tests/test_stream_presence.py b/tests/test_stream_presence.py
index 365a09ed..ea2337a2 100644
--- a/tests/test_stream_presence.py
+++ b/tests/test_stream_presence.py
@@ -1,9 +1,9 @@
import time
import unittest
-from sleekxmpp.test import SleekTest
+from slixmpp.test import SlixTest
-class TestStreamPresence(SleekTest):
+class TestStreamPresence(SlixTest):
"""
Test handling roster updates.
"""
@@ -38,9 +38,6 @@ class TestStreamPresence(SleekTest):
to="tester@localhost"/>
""")
- # Give event queue time to process.
- time.sleep(0.1)
-
self.assertEqual(events, set(('unavailable',)),
"Got offline incorrectly triggered: %s." % events)
@@ -83,9 +80,6 @@ class TestStreamPresence(SleekTest):
type="unavailable" />
""")
- # Give event queue time to process.
- time.sleep(0.1)
-
self.assertEqual(events, ['got_offline'],
"Got offline incorrectly triggered: %s" % events)
@@ -108,9 +102,6 @@ class TestStreamPresence(SleekTest):
to="tester@localhost" />
""")
- # Give event queue time to process.
- time.sleep(0.1)
-
expected = set(('presence_available', 'got_online'))
self.assertEqual(events, expected,
"Incorrect events triggered: %s" % events)
@@ -242,8 +233,6 @@ class TestStreamPresence(SleekTest):
<presence type="unsubscribed" />
""")
- time.sleep(.5)
-
self.assertEqual(events, ptypes,
"Not all events raised: %s" % events)
@@ -364,8 +353,6 @@ class TestStreamPresence(SleekTest):
</presence>
""")
- time.sleep(0.3)
-
self.assertEqual(events, ['available', 'away', 'dnd', 'chat',
'xa', 'unavailable', 'available',
'available', 'dnd'],
diff --git a/tests/test_stream_roster.py b/tests/test_stream_roster.py
index 221954ab..6a171ce7 100644
--- a/tests/test_stream_roster.py
+++ b/tests/test_stream_roster.py
@@ -2,13 +2,13 @@
from __future__ import unicode_literals
import unittest
-from sleekxmpp.exceptions import IqTimeout
-from sleekxmpp.test import SleekTest
+from slixmpp.exceptions import IqTimeout
+from slixmpp.test import SlixTest
import time
import threading
-class TestStreamRoster(SleekTest):
+class TestStreamRoster(SlixTest):
"""
Test handling roster updates.
"""
@@ -24,9 +24,7 @@ class TestStreamRoster(SleekTest):
self.xmpp.add_event_handler('roster_update', roster_updates.append)
- # Since get_roster blocks, we need to run it in a thread.
- t = threading.Thread(name='get_roster', target=self.xmpp.get_roster)
- t.start()
+ self.xmpp.get_roster()
self.send("""
<iq type="get" id="1">
@@ -47,12 +45,6 @@ class TestStreamRoster(SleekTest):
</iq>
""")
- # Wait for get_roster to return.
- t.join()
-
- # Give the event queue time to process.
- time.sleep(.1)
-
self.check_roster('tester@localhost', 'user@localhost',
name='User',
subscription='from',
@@ -96,8 +88,6 @@ class TestStreamRoster(SleekTest):
subscription='both',
groups=['Friends', 'Examples'])
- # Give the event queue time to process.
- time.sleep(.1)
self.failUnless('roster_update' in events,
"Roster updated event not triggered: %s" % events)
@@ -170,16 +160,6 @@ class TestStreamRoster(SleekTest):
</iq>
""")
- def testRosterTimeout(self):
- """Test handling a timed out roster request."""
- self.stream_start()
-
- def do_test():
- self.xmpp.get_roster(timeout=0)
- time.sleep(.1)
-
- self.assertRaises(IqTimeout, do_test)
-
def testRosterCallback(self):
"""Test handling a roster request callback."""
self.stream_start()
@@ -188,12 +168,7 @@ class TestStreamRoster(SleekTest):
def roster_callback(iq):
events.append('roster_callback')
- # Since get_roster blocks, we need to run it in a thread.
- t = threading.Thread(name='get_roster',
- target=self.xmpp.get_roster,
- kwargs={str('block'): False,
- str('callback'): roster_callback})
- t.start()
+ self.xmpp.get_roster(callback=roster_callback)
self.send("""
<iq type="get" id="1">
@@ -213,12 +188,6 @@ class TestStreamRoster(SleekTest):
</iq>
""")
- # Wait for get_roster to return.
- t.join()
-
- # Give the event queue time to process.
- time.sleep(.1)
-
self.failUnless(events == ['roster_callback'],
"Roster timeout event not triggered: %s." % events)
@@ -235,9 +204,6 @@ class TestStreamRoster(SleekTest):
</iq>
""")
- # Give the event queue time to process.
- time.sleep(.1)
-
self.check_roster('tester@localhost', 'andré@foo',
subscription='both',
groups=['Unicode'])
@@ -253,9 +219,6 @@ class TestStreamRoster(SleekTest):
</presence>
""")
- # Give the event queue time to process.
- time.sleep(.1)
-
result = self.xmpp.client_roster['andré@foo'].resources
expected = {'bar': {'status':'Testing',
'show':'away',
@@ -298,8 +261,8 @@ class TestStreamRoster(SleekTest):
self.stream_start()
self.assertTrue('rosterver' not in self.xmpp.features)
- t = threading.Thread(name='get_roster', target=self.xmpp.get_roster)
- t.start()
+ self.xmpp.get_roster()
+
self.send("""
<iq type="get" id="1">
<query xmlns="jabber:iq:roster" />
@@ -309,16 +272,14 @@ class TestStreamRoster(SleekTest):
<iq to="tester@localhost" type="result" id="1" />
""")
- t.join()
-
def testBootstrapRosterVer(self):
"""Test bootstrapping with roster versioning."""
self.stream_start()
self.xmpp.features.add('rosterver')
self.xmpp.client_roster.version = ''
- t = threading.Thread(name='get_roster', target=self.xmpp.get_roster)
- t.start()
+ self.xmpp.get_roster()
+
self.send("""
<iq type="get" id="1">
<query xmlns="jabber:iq:roster" ver="" />
@@ -328,8 +289,6 @@ class TestStreamRoster(SleekTest):
<iq to="tester@localhost" type="result" id="1" />
""")
- t.join()
-
def testExistingRosterVer(self):
"""Test using a stored roster version."""
@@ -337,8 +296,8 @@ class TestStreamRoster(SleekTest):
self.xmpp.features.add('rosterver')
self.xmpp.client_roster.version = '42'
- t = threading.Thread(name='get_roster', target=self.xmpp.get_roster)
- t.start()
+ self.xmpp.get_roster()
+
self.send("""
<iq type="get" id="1">
<query xmlns="jabber:iq:roster" ver="42" />
@@ -348,7 +307,5 @@ class TestStreamRoster(SleekTest):
<iq to="tester@localhost" type="result" id="1" />
""")
- t.join()
-
suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamRoster)
diff --git a/tests/test_stream_xep_0030.py b/tests/test_stream_xep_0030.py
index 37d29d33..de0bd414 100644
--- a/tests/test_stream_xep_0030.py
+++ b/tests/test_stream_xep_0030.py
@@ -2,10 +2,10 @@ import time
import threading
import unittest
-from sleekxmpp.test import SleekTest
+from slixmpp.test import SlixTest
-class TestStreamDisco(SleekTest):
+class TestStreamDisco(SlixTest):
"""
Test using the XEP-0030 plugin.
@@ -75,7 +75,7 @@ class TestStreamDisco(SleekTest):
self.xmpp['xep_0030'].static.add_node(node='testing')
self.recv("""
- <iq to="tester@localhost" type="get" id="test">
+ <iq to="tester@localhost/resource" type="get" id="test">
<query xmlns="http://jabber.org/protocol/disco#info"
node="testing" />
</iq>
@@ -101,7 +101,7 @@ class TestStreamDisco(SleekTest):
self.xmpp['xep_0030'].static.add_node(node='testing')
self.recv("""
- <iq to="tester@localhost" type="get" id="test">
+ <iq to="tester@localhost/resource" type="get" id="test">
<query xmlns="http://jabber.org/protocol/disco#items"
node="testing" />
</iq>
@@ -288,10 +288,7 @@ class TestStreamDisco(SleekTest):
self.xmpp.add_event_handler('disco_info', handle_disco_info)
- t = threading.Thread(name="get_info",
- target=self.xmpp['xep_0030'].get_info,
- args=('user@localhost', 'foo'))
- t.start()
+ self.xmpp['xep_0030'].get_info('user@localhost', 'foo')
self.send("""
<iq type="get" to="user@localhost" id="1">
@@ -310,11 +307,6 @@ class TestStreamDisco(SleekTest):
</iq>
""")
- # Wait for disco#info request to be received.
- t.join()
-
- time.sleep(0.1)
-
self.assertEqual(events, set(('disco_info',)),
"Disco info event was not triggered: %s" % events)
@@ -491,10 +483,7 @@ class TestStreamDisco(SleekTest):
self.xmpp.add_event_handler('disco_items', handle_disco_items)
- t = threading.Thread(name="get_items",
- target=self.xmpp['xep_0030'].get_items,
- args=('user@localhost', 'foo'))
- t.start()
+ self.xmpp['xep_0030'].get_items('user@localhost', 'foo')
self.send("""
<iq type="get" to="user@localhost" id="1">
@@ -513,11 +502,6 @@ class TestStreamDisco(SleekTest):
</iq>
""")
- # Wait for disco#items request to be received.
- t.join()
-
- time.sleep(0.1)
-
items = set([('user@localhost', 'bar', 'Test'),
('user@localhost', 'baz', 'Test 2')])
self.assertEqual(events, set(('disco_items',)),
@@ -525,6 +509,7 @@ class TestStreamDisco(SleekTest):
self.assertEqual(results, items,
"Unexpected items: %s" % results)
+ '''
def testGetItemsIterator(self):
"""Test interaction between XEP-0030 and XEP-0059 plugins."""
@@ -571,6 +556,7 @@ class TestStreamDisco(SleekTest):
self.assertEqual(raised_exceptions, [True],
"StopIteration was not raised: %s" % raised_exceptions)
+ '''
suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamDisco)
diff --git a/tests/test_stream_xep_0047.py b/tests/test_stream_xep_0047.py
index 0515bca5..ecba2445 100644
--- a/tests/test_stream_xep_0047.py
+++ b/tests/test_stream_xep_0047.py
@@ -1,11 +1,12 @@
+import asyncio
import threading
import time
import unittest
-from sleekxmpp.test import SleekTest
+from slixmpp.test import SlixTest
-class TestInBandByteStreams(SleekTest):
+class TestInBandByteStreams(SlixTest):
def setUp(self):
self.stream_start(plugins=['xep_0047', 'xep_0030'])
@@ -24,11 +25,8 @@ class TestInBandByteStreams(SleekTest):
self.xmpp.add_event_handler('ibb_stream_start', on_stream_start)
- t = threading.Thread(name='open_stream',
- target=self.xmpp['xep_0047'].open_stream,
- args=('tester@localhost/receiver',),
- kwargs={'sid': 'testing'})
- t.start()
+ self.xmpp['xep_0047'].open_stream('tester@localhost/receiver',
+ sid='testing')
self.send("""
<iq type="set" to="tester@localhost/receiver" id="1">
@@ -45,10 +43,6 @@ class TestInBandByteStreams(SleekTest):
from="tester@localhost/receiver" />
""")
- t.join()
-
- time.sleep(0.2)
-
self.assertEqual(events, ['ibb_stream_start'])
def testAysncOpenStream(self):
@@ -64,13 +58,9 @@ class TestInBandByteStreams(SleekTest):
self.xmpp.add_event_handler('ibb_stream_start', on_stream_start)
- t = threading.Thread(name='open_stream',
- target=self.xmpp['xep_0047'].open_stream,
- args=('tester@localhost/receiver',),
- kwargs={'sid': 'testing',
- 'block': False,
- 'callback': stream_callback})
- t.start()
+ self.xmpp['xep_0047'].open_stream('tester@localhost/receiver',
+ sid='testing',
+ callback=stream_callback)
self.send("""
<iq type="set" to="tester@localhost/receiver" id="1">
@@ -87,12 +77,9 @@ class TestInBandByteStreams(SleekTest):
from="tester@localhost/receiver" />
""")
- t.join()
-
- time.sleep(0.2)
-
self.assertEqual(events, set(['ibb_stream_start', 'callback']))
+ @asyncio.coroutine
def testSendData(self):
"""Test sending data over an in-band bytestream."""
@@ -108,11 +95,8 @@ class TestInBandByteStreams(SleekTest):
self.xmpp.add_event_handler('ibb_stream_start', on_stream_start)
self.xmpp.add_event_handler('ibb_stream_data', on_stream_data)
- t = threading.Thread(name='open_stream',
- target=self.xmpp['xep_0047'].open_stream,
- args=('tester@localhost/receiver',),
- kwargs={'sid': 'testing'})
- t.start()
+ self.xmpp['xep_0047'].open_stream('tester@localhost/receiver',
+ sid='testing')
self.send("""
<iq type="set" to="tester@localhost/receiver" id="1">
@@ -129,15 +113,11 @@ class TestInBandByteStreams(SleekTest):
from="tester@localhost/receiver" />
""")
- t.join()
-
- time.sleep(0.2)
-
stream = streams[0]
# Test sending data out
- stream.send("Testing")
+ yield from stream.send("Testing")
self.send("""
<iq type="set" id="2"
diff --git a/tests/test_stream_xep_0050.py b/tests/test_stream_xep_0050.py
index e38c4add..6ebf88a9 100644
--- a/tests/test_stream_xep_0050.py
+++ b/tests/test_stream_xep_0050.py
@@ -2,11 +2,11 @@ import time
import logging
import unittest
-from sleekxmpp.test import SleekTest
-from sleekxmpp.xmlstream import ElementBase, register_stanza_plugin
+from slixmpp.test import SlixTest
+from slixmpp.xmlstream import ElementBase, register_stanza_plugin
-class TestAdHocCommands(SleekTest):
+class TestAdHocCommands(SlixTest):
def setUp(self):
self.stream_start(mode='client',
@@ -626,9 +626,6 @@ class TestAdHocCommands(SleekTest):
</iq>
""")
- # Give the event queue time to process
- time.sleep(0.3)
-
self.failUnless(results == ['foo', 'bar', 'baz'],
'Incomplete command workflow: %s' % results)
@@ -692,9 +689,6 @@ class TestAdHocCommands(SleekTest):
</iq>
""")
- # Give the event queue time to process
- time.sleep(0.3)
-
self.failUnless(results == ['foo', 'bar'],
'Incomplete command workflow: %s' % results)
@@ -733,9 +727,6 @@ class TestAdHocCommands(SleekTest):
</iq>
""")
- # Give the event queue time to process
- time.sleep(0.3)
-
self.failUnless(results == ['foo'],
'Incomplete command workflow: %s' % results)
@@ -771,14 +762,8 @@ class TestAdHocCommands(SleekTest):
</iq>
""")
- # Give the event queue time to process
- time.sleep(0.3)
-
self.failUnless(results == ['foo'],
'Incomplete command workflow: %s' % results)
-
-
-
suite = unittest.TestLoader().loadTestsFromTestCase(TestAdHocCommands)
diff --git a/tests/test_stream_xep_0059.py b/tests/test_stream_xep_0059.py
deleted file mode 100644
index 5f3ea079..00000000
--- a/tests/test_stream_xep_0059.py
+++ /dev/null
@@ -1,163 +0,0 @@
-import threading
-
-import unittest
-from sleekxmpp.test import SleekTest
-from sleekxmpp.xmlstream import register_stanza_plugin
-from sleekxmpp.plugins.xep_0030 import DiscoItems
-from sleekxmpp.plugins.xep_0059 import ResultIterator, Set
-
-
-class TestStreamSet(SleekTest):
-
- def setUp(self):
- register_stanza_plugin(DiscoItems, Set)
-
- def tearDown(self):
- self.stream_close()
-
- def iter(self, rev=False):
- q = self.xmpp.Iq()
- q['type'] = 'get'
- it = ResultIterator(q, 'disco_items', amount='1', reverse=rev)
- for i in it:
- for j in i['disco_items']['items']:
- self.items.append(j[0])
-
- def testResultIterator(self):
- self.items = []
- self.stream_start(mode='client')
- t = threading.Thread(target=self.iter)
- t.start()
- self.send("""
- <iq type="get" id="2">
- <query xmlns="http://jabber.org/protocol/disco#items">
- <set xmlns="http://jabber.org/protocol/rsm">
- <max>1</max>
- </set>
- </query>
- </iq>
- """)
- self.recv("""
- <iq type="result" id="2">
- <query xmlns="http://jabber.org/protocol/disco#items">
- <item jid="item1" />
- <set xmlns="http://jabber.org/protocol/rsm">
- <last>item1</last>
- </set>
- </query>
- </iq>
- """)
- self.send("""
- <iq type="get" id="3">
- <query xmlns="http://jabber.org/protocol/disco#items">
- <set xmlns="http://jabber.org/protocol/rsm">
- <max>1</max>
- <after>item1</after>
- </set>
- </query>
- </iq>
- """)
- self.recv("""
- <iq type="result" id="3">
- <query xmlns="http://jabber.org/protocol/disco#items">
- <item jid="item2" />
- <set xmlns="http://jabber.org/protocol/rsm">
- <last>item2</last>
- </set>
- </query>
- </iq>
- """)
- self.send("""
- <iq type="get" id="4">
- <query xmlns="http://jabber.org/protocol/disco#items">
- <set xmlns="http://jabber.org/protocol/rsm">
- <max>1</max>
- <after>item2</after>
- </set>
- </query>
- </iq>
- """)
- self.recv("""
- <iq type="result" id="4">
- <query xmlns="http://jabber.org/protocol/disco#items">
- <item jid="item2" />
- <set xmlns="http://jabber.org/protocol/rsm">
- </set>
- </query>
- </iq>
- """)
- t.join()
- self.failUnless(self.items == ['item1', 'item2'])
-
- def testResultIteratorReverse(self):
- self.items = []
- self.stream_start(mode='client')
-
- t = threading.Thread(target=self.iter, args=(True,))
- t.start()
-
- self.send("""
- <iq type="get" id="2">
- <query xmlns="http://jabber.org/protocol/disco#items">
- <set xmlns="http://jabber.org/protocol/rsm">
- <max>1</max>
- <before />
- </set>
- </query>
- </iq>
- """)
- self.recv("""
- <iq type="result" id="2">
- <query xmlns="http://jabber.org/protocol/disco#items">
- <item jid="item2" />
- <set xmlns="http://jabber.org/protocol/rsm">
- <first>item2</first>
- </set>
- </query>
- </iq>
- """)
- self.send("""
- <iq type="get" id="3">
- <query xmlns="http://jabber.org/protocol/disco#items">
- <set xmlns="http://jabber.org/protocol/rsm">
- <max>1</max>
- <before>item2</before>
- </set>
- </query>
- </iq>
- """)
- self.recv("""
- <iq type="result" id="3">
- <query xmlns="http://jabber.org/protocol/disco#items">
- <item jid="item1" />
- <set xmlns="http://jabber.org/protocol/rsm">
- <first>item1</first>
- </set>
- </query>
- </iq>
- """)
- self.send("""
- <iq type="get" id="4">
- <query xmlns="http://jabber.org/protocol/disco#items">
- <set xmlns="http://jabber.org/protocol/rsm">
- <max>1</max>
- <before>item1</before>
- </set>
- </query>
- </iq>
- """)
- self.recv("""
- <iq type="result" id="4">
- <query xmlns="http://jabber.org/protocol/disco#items">
- <item jid="item1" />
- <set xmlns="http://jabber.org/protocol/rsm">
- </set>
- </query>
- </iq>
- """)
-
- t.join()
- self.failUnless(self.items == ['item2', 'item1'])
-
-
-suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamSet)
diff --git a/tests/test_stream_xep_0060.py b/tests/test_stream_xep_0060.py
index 581d5d00..da543f96 100644
--- a/tests/test_stream_xep_0060.py
+++ b/tests/test_stream_xep_0060.py
@@ -1,12 +1,12 @@
import threading
import unittest
-from sleekxmpp.test import SleekTest
-from sleekxmpp.stanza.atom import AtomEntry
-from sleekxmpp.xmlstream import register_stanza_plugin
+from slixmpp.test import SlixTest
+from slixmpp.stanza.atom import AtomEntry
+from slixmpp.xmlstream import register_stanza_plugin
-class TestStreamPubsub(SleekTest):
+class TestStreamPubsub(SlixTest):
"""
Test using the XEP-0030 plugin.
@@ -20,10 +20,7 @@ class TestStreamPubsub(SleekTest):
def testCreateInstantNode(self):
"""Test creating an instant node"""
- t = threading.Thread(name='create_node',
- target=self.xmpp['xep_0060'].create_node,
- args=('pubsub.example.com', None))
- t.start()
+ self.xmpp['xep_0060'].create_node('pubsub.example.com', None)
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
@@ -42,14 +39,11 @@ class TestStreamPubsub(SleekTest):
</iq>
""")
- t.join()
-
def testCreateNodeNoConfig(self):
"""Test creating a node without a config"""
self.xmpp['xep_0060'].create_node(
'pubsub.example.com',
- 'princely_musings',
- block=False)
+ 'princely_musings')
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -67,7 +61,7 @@ class TestStreamPubsub(SleekTest):
self.xmpp['xep_0060'].create_node(
'pubsub.example.com',
'princely_musings',
- config=form, block=False)
+ config=form)
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
@@ -91,8 +85,7 @@ class TestStreamPubsub(SleekTest):
"""Test deleting a node"""
self.xmpp['xep_0060'].delete_node(
'pubsub.example.com',
- 'some_node',
- block=False)
+ 'some_node')
self.send("""
<iq type="set" to="pubsub.example.com" id="1">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
@@ -108,8 +101,7 @@ class TestStreamPubsub(SleekTest):
"""
self.xmpp['xep_0060'].subscribe(
'pubsub.example.com',
- 'somenode',
- block=False)
+ 'somenode')
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -126,8 +118,7 @@ class TestStreamPubsub(SleekTest):
self.xmpp['xep_0060'].subscribe(
'pubsub.example.com',
'somenode',
- ifrom='foo@comp.example.com/bar',
- block=False)
+ ifrom='foo@comp.example.com/bar')
self.send("""
<iq type="set" id="1"
to="pubsub.example.com" from="foo@comp.example.com/bar">
@@ -146,8 +137,7 @@ class TestStreamPubsub(SleekTest):
'pubsub.example.com',
'somenode',
ifrom='foo@comp.example.com/bar',
- bare=False,
- block=False)
+ bare=False)
self.send("""
<iq type="set" id="1"
to="pubsub.example.com" from="foo@comp.example.com/bar">
@@ -168,8 +158,7 @@ class TestStreamPubsub(SleekTest):
self.xmpp['xep_0060'].subscribe(
'pubsub.example.com',
'somenode',
- bare=False,
- block=False)
+ bare=False)
self.send("""
<iq type="set" id="1"
to="pubsub.example.com">
@@ -188,8 +177,7 @@ class TestStreamPubsub(SleekTest):
'pubsub.example.com',
'somenode',
subscribee='user@example.com/foo',
- ifrom='foo@comp.example.com/bar',
- block=False)
+ ifrom='foo@comp.example.com/bar')
self.send("""
<iq type="set" id="1"
to="pubsub.example.com" from="foo@comp.example.com/bar">
@@ -215,8 +203,7 @@ class TestStreamPubsub(SleekTest):
self.xmpp['xep_0060'].subscribe(
'pubsub.example.com',
'somenode',
- options=opts,
- block=False)
+ options=opts)
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -242,8 +229,7 @@ class TestStreamPubsub(SleekTest):
"""
self.xmpp['xep_0060'].unsubscribe(
'pubsub.example.com',
- 'somenode',
- block=False)
+ 'somenode')
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -260,8 +246,7 @@ class TestStreamPubsub(SleekTest):
self.xmpp['xep_0060'].unsubscribe(
'pubsub.example.com',
'somenode',
- ifrom='foo@comp.example.com/bar',
- block=False)
+ ifrom='foo@comp.example.com/bar')
self.send("""
<iq type="set" id="1"
to="pubsub.example.com" from="foo@comp.example.com/bar">
@@ -280,8 +265,7 @@ class TestStreamPubsub(SleekTest):
'pubsub.example.com',
'somenode',
ifrom='foo@comp.example.com/bar',
- bare=False,
- block=False)
+ bare=False)
self.send("""
<iq type="set" id="1"
to="pubsub.example.com" from="foo@comp.example.com/bar">
@@ -302,8 +286,7 @@ class TestStreamPubsub(SleekTest):
self.xmpp['xep_0060'].unsubscribe(
'pubsub.example.com',
'somenode',
- bare=False,
- block=False)
+ bare=False)
self.send("""
<iq type="set" id="1"
to="pubsub.example.com">
@@ -322,8 +305,7 @@ class TestStreamPubsub(SleekTest):
'pubsub.example.com',
'somenode',
subscribee='user@example.com/foo',
- ifrom='foo@comp.example.com/bar',
- block=False)
+ ifrom='foo@comp.example.com/bar')
self.send("""
<iq type="set" id="1"
to="pubsub.example.com" from="foo@comp.example.com/bar">
@@ -336,8 +318,7 @@ class TestStreamPubsub(SleekTest):
def testGetDefaultNodeConfig(self):
"""Test retrieving the default node config for a pubsub service."""
self.xmpp['xep_0060'].get_node_config(
- 'pubsub.example.com',
- block=False)
+ 'pubsub.example.com')
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
@@ -350,8 +331,7 @@ class TestStreamPubsub(SleekTest):
"""Test getting the config for a given node."""
self.xmpp['xep_0060'].get_node_config(
'pubsub.example.com',
- 'somenode',
- block=False)
+ 'somenode')
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
@@ -372,8 +352,7 @@ class TestStreamPubsub(SleekTest):
self.xmpp['xep_0060'].set_node_config(
'pubsub.example.com',
'somenode',
- form,
- block=False)
+ form)
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
@@ -395,8 +374,7 @@ class TestStreamPubsub(SleekTest):
"""Test publishing no items (in order to generate events)"""
self.xmpp['xep_0060'].publish(
'pubsub.example.com',
- 'somenode',
- block=False)
+ 'somenode')
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -416,8 +394,7 @@ class TestStreamPubsub(SleekTest):
'pubsub.example.com',
'somenode',
id='id42',
- payload=payload,
- block=False)
+ payload=payload)
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -451,8 +428,7 @@ class TestStreamPubsub(SleekTest):
'somenode',
id='ID42',
payload=payload,
- options=options,
- block=False)
+ options=options)
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -483,8 +459,7 @@ class TestStreamPubsub(SleekTest):
'pubsub.example.com',
'somenode',
'ID1',
- notify=True,
- block=False)
+ notify=True)
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -500,8 +475,7 @@ class TestStreamPubsub(SleekTest):
self.xmpp['xep_0060'].retract(
'pubsub.example.com',
'somenode',
- 'ID1',
- block=False)
+ 'ID1')
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -516,8 +490,7 @@ class TestStreamPubsub(SleekTest):
"""Test removing all items from a node."""
self.xmpp['xep_0060'].purge(
'pubsub.example.com',
- 'somenode',
- block=False)
+ 'somenode')
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
@@ -531,8 +504,7 @@ class TestStreamPubsub(SleekTest):
self.xmpp['xep_0060'].get_item(
'pubsub.example.com',
'somenode',
- 'id42',
- block=False)
+ 'id42')
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -548,8 +520,7 @@ class TestStreamPubsub(SleekTest):
self.xmpp['xep_0060'].get_items(
'pubsub.example.com',
'somenode',
- max_items=3,
- block=False)
+ max_items=3)
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -562,8 +533,7 @@ class TestStreamPubsub(SleekTest):
"""Test retrieving all items."""
self.xmpp['xep_0060'].get_items(
'pubsub.example.com',
- 'somenode',
- block=False)
+ 'somenode')
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -577,8 +547,7 @@ class TestStreamPubsub(SleekTest):
self.xmpp['xep_0060'].get_items(
'pubsub.example.com',
'somenode',
- item_ids=['A', 'B', 'C'],
- block=False)
+ item_ids=['A', 'B', 'C'])
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -594,8 +563,7 @@ class TestStreamPubsub(SleekTest):
def testGetSubscriptionGlobalDefaultOptions(self):
"""Test getting the subscription options for a node/JID."""
self.xmpp['xep_0060'].get_subscription_options(
- 'pubsub.example.com',
- block=False)
+ 'pubsub.example.com')
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -608,8 +576,7 @@ class TestStreamPubsub(SleekTest):
"""Test getting the subscription options for a node/JID."""
self.xmpp['xep_0060'].get_subscription_options(
'pubsub.example.com',
- node='somenode',
- block=False)
+ node='somenode')
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -623,8 +590,7 @@ class TestStreamPubsub(SleekTest):
self.xmpp['xep_0060'].get_subscription_options(
'pubsub.example.com',
'somenode',
- 'tester@localhost',
- block=False)
+ 'tester@localhost')
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -650,8 +616,7 @@ class TestStreamPubsub(SleekTest):
'pubsub.example.com',
'somenode',
'tester@localhost',
- opts,
- block=False)
+ opts)
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -673,8 +638,7 @@ class TestStreamPubsub(SleekTest):
"""Test retrieving all subscriptions for a node."""
self.xmpp['xep_0060'].get_node_subscriptions(
'pubsub.example.com',
- 'somenode',
- block=False)
+ 'somenode')
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
@@ -686,8 +650,7 @@ class TestStreamPubsub(SleekTest):
def testGetSubscriptions(self):
"""Test retrieving a users's subscriptions."""
self.xmpp['xep_0060'].get_subscriptions(
- 'pubsub.example.com',
- block=False)
+ 'pubsub.example.com')
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -700,8 +663,7 @@ class TestStreamPubsub(SleekTest):
"""Test retrieving a users's subscriptions for a given node."""
self.xmpp['xep_0060'].get_subscriptions(
'pubsub.example.com',
- node='somenode',
- block=False)
+ node='somenode')
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -713,8 +675,7 @@ class TestStreamPubsub(SleekTest):
def testGetAffiliations(self):
"""Test retrieving a users's affiliations."""
self.xmpp['xep_0060'].get_affiliations(
- 'pubsub.example.com',
- block=False)
+ 'pubsub.example.com')
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -727,8 +688,7 @@ class TestStreamPubsub(SleekTest):
"""Test retrieving a users's affiliations for a given node."""
self.xmpp['xep_0060'].get_affiliations(
'pubsub.example.com',
- node='somenode',
- block=False)
+ node='somenode')
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
@@ -741,8 +701,7 @@ class TestStreamPubsub(SleekTest):
"""Test getting the affiliations for a node."""
self.xmpp['xep_0060'].get_node_affiliations(
'pubsub.example.com',
- 'somenode',
- block=False)
+ 'somenode')
self.send("""
<iq type="get" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
@@ -757,8 +716,7 @@ class TestStreamPubsub(SleekTest):
'pubsub.example.com',
'somenode',
subscriptions=[('user@example.com', 'subscribed'),
- ('foo@example.net', 'none')],
- block=False)
+ ('foo@example.net', 'none')])
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
@@ -776,8 +734,7 @@ class TestStreamPubsub(SleekTest):
'pubsub.example.com',
'somenode',
affiliations=[('user@example.com', 'publisher'),
- ('foo@example.net', 'none')],
- block=False)
+ ('foo@example.net', 'none')])
self.send("""
<iq type="set" id="1" to="pubsub.example.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
diff --git a/tests/test_stream_xep_0066.py b/tests/test_stream_xep_0066.py
index 175026d2..159333c7 100644
--- a/tests/test_stream_xep_0066.py
+++ b/tests/test_stream_xep_0066.py
@@ -1,10 +1,10 @@
import threading
import unittest
-from sleekxmpp.test import SleekTest
+from slixmpp.test import SlixTest
-class TestOOB(SleekTest):
+class TestOOB(SlixTest):
def tearDown(self):
self.stream_close()
@@ -13,21 +13,16 @@ class TestOOB(SleekTest):
"""Test sending an OOB transfer request."""
self.stream_start(plugins=['xep_0066', 'xep_0030'])
- url = 'http://github.com/fritzy/SleekXMPP/blob/master/README'
+ url = 'http://github.com/fritzy/Slixmpp/blob/master/README'
- t = threading.Thread(
- name='send_oob',
- target=self.xmpp['xep_0066'].send_oob,
- args=('user@example.com', url),
- kwargs={'desc': 'SleekXMPP README'})
-
- t.start()
+ self.xmpp['xep_0066'].send_oob('user@example.com', url,
+ desc='Slixmpp README')
self.send("""
<iq to="user@example.com" type="set" id="1">
<query xmlns="jabber:iq:oob">
- <url>http://github.com/fritzy/SleekXMPP/blob/master/README</url>
- <desc>SleekXMPP README</desc>
+ <url>http://github.com/fritzy/Slixmpp/blob/master/README</url>
+ <desc>Slixmpp README</desc>
</query>
</iq>
""")
@@ -38,7 +33,5 @@ class TestOOB(SleekTest):
from="user@example.com" />
""")
- t.join()
-
suite = unittest.TestLoader().loadTestsFromTestCase(TestOOB)
diff --git a/tests/test_stream_xep_0085.py b/tests/test_stream_xep_0085.py
index 54e7e15f..9e3a2dd5 100644
--- a/tests/test_stream_xep_0085.py
+++ b/tests/test_stream_xep_0085.py
@@ -1,10 +1,10 @@
import time
import unittest
-from sleekxmpp.test import SleekTest
+from slixmpp.test import SlixTest
-class TestStreamChatStates(SleekTest):
+class TestStreamChatStates(SlixTest):
def tearDown(self):
self.stream_close()
@@ -49,8 +49,6 @@ class TestStreamChatStates(SleekTest):
</message>
""")
- # Give event queue time to process
- time.sleep(0.3)
expected = ['active', 'inactive', 'paused', 'composing', 'gone']
self.failUnless(results == expected,
"Chat state event not handled: %s" % results)
diff --git a/tests/test_stream_xep_0092.py b/tests/test_stream_xep_0092.py
index c0748697..1f1eac00 100644
--- a/tests/test_stream_xep_0092.py
+++ b/tests/test_stream_xep_0092.py
@@ -1,10 +1,10 @@
import threading
import unittest
-from sleekxmpp.test import SleekTest
+from slixmpp.test import SlixTest
-class TestStreamSet(SleekTest):
+class TestStreamSet(SlixTest):
def tearDown(self):
self.stream_close()
@@ -12,7 +12,7 @@ class TestStreamSet(SleekTest):
def testHandleSoftwareVersionRequest(self):
self.stream_start(mode='client', plugins=['xep_0030', 'xep_0092'])
- self.xmpp['xep_0092'].name = 'SleekXMPP'
+ self.xmpp['xep_0092'].name = 'Slixmpp'
self.xmpp['xep_0092'].version = 'dev'
self.xmpp['xep_0092'].os = 'Linux'
@@ -25,7 +25,7 @@ class TestStreamSet(SleekTest):
self.send("""
<iq type="result" id="1">
<query xmlns="jabber:iq:version">
- <name>SleekXMPP</name>
+ <name>Slixmpp</name>
<version>dev</version>
<os>Linux</os>
</query>
@@ -35,16 +35,14 @@ class TestStreamSet(SleekTest):
def testMakeSoftwareVersionRequest(self):
results = []
- def query():
- r = self.xmpp['xep_0092'].get_version('foo@bar')
- results.append((r['software_version']['name'],
- r['software_version']['version'],
- r['software_version']['os']))
+ def callback(result):
+ results.append((result['software_version']['name'],
+ result['software_version']['version'],
+ result['software_version']['os']))
self.stream_start(mode='client', plugins=['xep_0030', 'xep_0092'])
- t = threading.Thread(target=query)
- t.start()
+ self.xmpp['xep_0092'].get_version('foo@bar', callback=callback)
self.send("""
<iq type="get" id="1" to="foo@bar">
@@ -62,8 +60,6 @@ class TestStreamSet(SleekTest):
</iq>
""")
- t.join()
-
expected = [('Foo', '1.0', 'Linux')]
self.assertEqual(results, expected,
"Did not receive expected results: %s" % results)
diff --git a/tests/test_stream_xep_0128.py b/tests/test_stream_xep_0128.py
index 10222d9b..1c1da88f 100644
--- a/tests/test_stream_xep_0128.py
+++ b/tests/test_stream_xep_0128.py
@@ -1,8 +1,8 @@
import unittest
-from sleekxmpp.test import SleekTest
+from slixmpp.test import SlixTest
-class TestStreamExtendedDisco(SleekTest):
+class TestStreamExtendedDisco(SlixTest):
"""
Test using the XEP-0128 plugin.
diff --git a/tests/test_stream_xep_0249.py b/tests/test_stream_xep_0249.py
index 8edea270..f12978a8 100644
--- a/tests/test_stream_xep_0249.py
+++ b/tests/test_stream_xep_0249.py
@@ -1,10 +1,10 @@
import time
import unittest
-from sleekxmpp.test import SleekTest
+from slixmpp.test import SlixTest
-class TestStreamDirectInvite(SleekTest):
+class TestStreamDirectInvite(SlixTest):
"""
Test using the XEP-0249 plugin.
@@ -35,8 +35,6 @@ class TestStreamDirectInvite(SleekTest):
</message>
""")
- time.sleep(.5)
-
self.failUnless(events == [True],
"Event not raised: %s" % events)
@@ -47,13 +45,13 @@ class TestStreamDirectInvite(SleekTest):
self.xmpp['xep_0249'].send_invitation('user@example.com',
'sleek@conference.jabber.org',
- reason='Need to test Sleek')
+ reason='Need to test Slixmpp')
self.send("""
<message to="user@example.com">
<x xmlns="jabber:x:conference"
jid="sleek@conference.jabber.org"
- reason="Need to test Sleek" />
+ reason="Need to test Slixmpp" />
</message>
""")
diff --git a/tests/test_stream_xep_0323.py b/tests/test_stream_xep_0323.py
index 94f1d638..42230e1f 100644
--- a/tests/test_stream_xep_0323.py
+++ b/tests/test_stream_xep_0323.py
@@ -5,12 +5,12 @@ import datetime
import time
import threading
-from sleekxmpp.test import *
-from sleekxmpp.xmlstream import ElementBase
-from sleekxmpp.plugins.xep_0323.device import Device
+from slixmpp.test import *
+from slixmpp.xmlstream import ElementBase
+from slixmpp.plugins.xep_0323.device import Device
-class TestStreamSensorData(SleekTest):
+class TestStreamSensorData(SlixTest):
"""
Test using the XEP-0323 plugin.
@@ -455,8 +455,6 @@ class TestStreamSensorData(SleekTest):
</iq>
""")
- time.sleep(.1)
-
self.failUnless(results == ["rejected"],
"Rejected callback was not properly executed")
@@ -494,8 +492,6 @@ class TestStreamSensorData(SleekTest):
</iq>
""")
- time.sleep(.1)
-
self.failUnless(results == ["accepted"],
"Accepted callback was not properly executed")
@@ -517,13 +513,10 @@ class TestStreamSensorData(SleekTest):
for f in fields:
callback_data["field_" + f['name']] = f
- t1= threading.Thread(name="request_data",
- target=self.xmpp['xep_0323'].request_data,
- kwargs={"from_jid": "tester@localhost",
- "to_jid": "you@google.com",
- "nodeIds": ['Device33'],
- "callback": my_callback})
- t1.start()
+ self.xmpp['xep_0323'].request_data(from_jid="tester@localhost",
+ to_jid="you@google.com",
+ nodeIds=['Device33'],
+ callback=my_callback)
#self.xmpp['xep_0323'].request_data(from_jid="tester@localhost", to_jid="you@google.com", nodeIds=['Device33'], callback=my_callback);
self.send("""
@@ -567,9 +560,6 @@ class TestStreamSensorData(SleekTest):
</message>
""")
- t1.join()
- time.sleep(.5)
-
self.failUnlessEqual(results, ["accepted","fields","done"])
# self.assertIn("nodeId", callback_data);
self.assertTrue("nodeId" in callback_data)
@@ -592,7 +582,7 @@ class TestStreamSensorData(SleekTest):
self.recv("""
<iq type='get'
from='master@clayster.com/amr'
- to='tester@localhost'
+ to='tester@localhost/resource'
id='disco1'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
@@ -617,7 +607,7 @@ class TestStreamSensorData(SleekTest):
self.recv("""
<iq type='get'
from='master@clayster.com/amr'
- to='tester@localhost'
+ to='tester@localhost/resource'
id='disco1'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
@@ -625,7 +615,7 @@ class TestStreamSensorData(SleekTest):
self.send("""
<iq type='result'
- from='tester@localhost'
+ from='tester@localhost/resource'
to='master@clayster.com/amr'
id='disco1'>
<query xmlns='http://jabber.org/protocol/disco#info'>
@@ -651,14 +641,10 @@ class TestStreamSensorData(SleekTest):
callback_data["timestamp"] = timestamp
callback_data["error_msg"] = error_msg
- t1= threading.Thread(name="request_data",
- target=self.xmpp['xep_0323'].request_data,
- kwargs={"from_jid": "tester@localhost",
- "to_jid": "you@google.com",
- "nodeIds": ['Device33'],
- "callback": my_callback})
- t1.start()
-
+ self.xmpp['xep_0323'].request_data(from_jid="tester@localhost",
+ to_jid="you@google.com",
+ nodeIds=['Device33'],
+ callback=my_callback)
self.send("""
<iq type='get'
from='tester@localhost'
@@ -688,10 +674,7 @@ class TestStreamSensorData(SleekTest):
</message>
""")
- t1.join()
- time.sleep(.5)
-
- self.failUnlessEqual(results, ["accepted","failure"])
+ self.failUnlessEqual(results, ["accepted","failure"]);
# self.assertIn("nodeId", callback_data);
self.assertTrue("nodeId" in callback_data)
self.failUnlessEqual(callback_data["nodeId"], "Device33")
@@ -737,7 +720,7 @@ class TestStreamSensorData(SleekTest):
</iq>
""")
- time.sleep(2)
+ time.sleep(1)
self.send("""
<message from='device@clayster.com'
@@ -1033,13 +1016,10 @@ class TestStreamSensorData(SleekTest):
for f in fields:
callback_data["field_" + f['name']] = f
- t1= threading.Thread(name="request_data",
- target=self.xmpp['xep_0323'].request_data,
- kwargs={"from_jid": "tester@localhost",
- "to_jid": "you@google.com",
- "nodeIds": ['Device33'],
- "callback": my_callback})
- t1.start()
+ self.xmpp['xep_0323'].request_data(from_jid="tester@localhost",
+ to_jid="you@google.com",
+ nodeIds=['Device33'],
+ callback=my_callback)
#self.xmpp['xep_0323'].request_data(from_jid="tester@localhost", to_jid="you@google.com", nodeIds=['Device33'], callback=my_callback);
self.send("""
@@ -1090,10 +1070,7 @@ class TestStreamSensorData(SleekTest):
</message>
""")
- t1.join()
- time.sleep(.5)
-
- self.failUnlessEqual(results, ["queued","started","fields","done"])
+ self.failUnlessEqual(results, ["queued","started","fields","done"]);
# self.assertIn("nodeId", callback_data);
self.assertTrue("nodeId" in callback_data)
self.failUnlessEqual(callback_data["nodeId"], "Device33")
@@ -1161,8 +1138,6 @@ class TestStreamSensorData(SleekTest):
</iq>
""")
- time.sleep(.5)
-
self.failUnlessEqual(results, ["accepted","cancelled"])
def testDelayedRequestCancel(self):
@@ -1239,8 +1214,6 @@ class TestStreamSensorData(SleekTest):
</iq>
""")
- time.sleep(2)
-
# Ensure we don't get anything after cancellation
self.send(None)
diff --git a/tests/test_stream_xep_0325.py b/tests/test_stream_xep_0325.py
index 2ebdd121..600bfa64 100644
--- a/tests/test_stream_xep_0325.py
+++ b/tests/test_stream_xep_0325.py
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
"""
- SleekXMPP: The Sleek XMPP Library
+ Slixmpp: The Slick 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, bjorn.westrom@consoden.se
- This file is part of SleekXMPP.
+ This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
@@ -14,12 +14,12 @@ import datetime
import time
import threading
-from sleekxmpp.test import *
-from sleekxmpp.xmlstream import ElementBase
-from sleekxmpp.plugins.xep_0325.device import Device
+from slixmpp.test import *
+from slixmpp.xmlstream import ElementBase
+from slixmpp.plugins.xep_0325.device import Device
-class TestStreamControl(SleekTest):
+class TestStreamControl(SlixTest):
"""
Test using the XEP-0325 plugin.
@@ -189,7 +189,7 @@ class TestStreamControl(SleekTest):
</message>
""")
- time.sleep(.5)
+ time.sleep(0.5)
self.assertEqual(myDevice._get_field_value("Temperature"), "17")
@@ -213,10 +213,8 @@ class TestStreamControl(SleekTest):
</message>
""")
- time.sleep(.5)
-
- self.assertEqual(myDevice._get_field_value("Temperature"), "15")
- self.assertFalse(myDevice.has_control_field("Voltage", "int"))
+ self.assertEqual(myDevice._get_field_value("Temperature"), "15");
+ self.assertFalse(myDevice.has_control_field("Voltage", "int"));
def testRequestSetOkAPI(self):
@@ -259,9 +257,7 @@ class TestStreamControl(SleekTest):
</iq>
""")
- time.sleep(.5)
-
- self.assertEqual(results, ["OK"])
+ self.assertEqual(results, ["OK"]);
def testRequestSetErrorAPI(self):
@@ -305,8 +301,6 @@ class TestStreamControl(SleekTest):
</iq>
""")
- time.sleep(.5)
-
self.assertEqual(results, ["OtherError"])
def testServiceDiscoveryClient(self):
@@ -317,7 +311,7 @@ class TestStreamControl(SleekTest):
self.recv("""
<iq type='get'
from='master@clayster.com/amr'
- to='tester@localhost'
+ to='tester@localhost/resource'
id='disco1'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
@@ -342,7 +336,7 @@ class TestStreamControl(SleekTest):
self.recv("""
<iq type='get'
from='master@clayster.com/amr'
- to='tester@localhost'
+ to='tester@localhost/resource'
id='disco1'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
@@ -350,7 +344,7 @@ class TestStreamControl(SleekTest):
self.send("""
<iq type='result'
- from='tester@localhost'
+ from='tester@localhost/resource'
to='master@clayster.com/amr'
id='disco1'>
<query xmlns='http://jabber.org/protocol/disco#info'>
diff --git a/tests/test_tostring.py b/tests/test_tostring.py
index e6148533..72718beb 100644
--- a/tests/test_tostring.py
+++ b/tests/test_tostring.py
@@ -1,13 +1,13 @@
import unittest
-from sleekxmpp.test import SleekTest
-from sleekxmpp.xmlstream.stanzabase import ET
-from sleekxmpp.xmlstream.tostring import tostring, escape
+from slixmpp.test import SlixTest
+from slixmpp.xmlstream.stanzabase import ET
+from slixmpp.xmlstream.tostring import tostring, escape
-class TestToString(SleekTest):
+class TestToString(SlixTest):
"""
- Test the implementation of sleekxmpp.xmlstream.tostring
+ Test the implementation of slixmpp.xmlstream.tostring
"""
def tearDown(self):
diff --git a/tox.ini b/tox.ini
index e0e79ff4..8e55625b 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py26,py27,py34
+envlist = py34
[testenv]
deps = nose
-commands = nosetests --where=tests --exclude=live -i sleektest.py
+commands = nosetests --where=tests --exclude=live -i slixtest.py