cerberus 0.6 → 0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Authors.txt +4 -0
- data/Changelog.txt +11 -0
- data/Copyright.txt +16 -0
- data/Rakefile +16 -25
- data/Readme.markdown +1 -3
- data/bin/cerberus +5 -0
- data/lib/cerberus/builder/bjam.rb +1 -3
- data/lib/cerberus/builder/maven2.rb +0 -1
- data/lib/cerberus/builder/rake.rb +1 -1
- data/lib/cerberus/builder/rspec.rb +0 -1
- data/lib/cerberus/builder/ruby_base.rb +0 -1
- data/lib/cerberus/component_lazy_loader.rb +6 -2
- data/lib/cerberus/config.example.yml +1 -0
- data/lib/cerberus/constants.rb +2 -2
- data/lib/cerberus/manager.rb +7 -1
- data/lib/cerberus/publisher/mail.rb +4 -4
- data/lib/cerberus/publisher/twitter.rb +0 -1
- data/lib/cerberus/scm/base.rb +19 -0
- data/lib/cerberus/scm/bzr.rb +62 -0
- data/lib/cerberus/scm/cvs.rb +2 -7
- data/lib/cerberus/scm/darcs.rb +2 -11
- data/lib/cerberus/scm/git.rb +6 -14
- data/lib/cerberus/scm/perforce.rb +4 -4
- data/lib/cerberus/scm/svn.rb +2 -7
- data/lib/cerberus/utils.rb +5 -0
- data/lib/vendor/irc/README +23 -0
- data/lib/vendor/irc/lib/IRC.rb +164 -0
- data/lib/vendor/irc/lib/IRCChannel.rb +33 -0
- data/lib/vendor/irc/lib/IRCConnection.rb +134 -0
- data/lib/vendor/irc/lib/IRCEvent.rb +91 -0
- data/lib/vendor/irc/lib/IRCUser.rb +23 -0
- data/lib/vendor/irc/lib/IRCUtil.rb +49 -0
- data/lib/vendor/irc/lib/eventmap.yml +247 -0
- data/lib/vendor/twitter/CHANGES +129 -0
- data/lib/vendor/twitter/MIT-LICENSE +20 -0
- data/lib/vendor/twitter/README +37 -0
- data/lib/vendor/twitter/TODO +7 -0
- data/lib/vendor/twitter/lib/twitter.rb +34 -0
- data/lib/vendor/twitter/lib/twitter/client.rb +24 -0
- data/lib/vendor/twitter/lib/twitter/client/account.rb +24 -0
- data/lib/vendor/twitter/lib/twitter/client/auth.rb +27 -0
- data/lib/vendor/twitter/lib/twitter/client/base.rb +93 -0
- data/lib/vendor/twitter/lib/twitter/client/blocks.rb +35 -0
- data/lib/vendor/twitter/lib/twitter/client/favorites.rb +53 -0
- data/lib/vendor/twitter/lib/twitter/client/friendship.rb +35 -0
- data/lib/vendor/twitter/lib/twitter/client/graph.rb +37 -0
- data/lib/vendor/twitter/lib/twitter/client/messaging.rb +79 -0
- data/lib/vendor/twitter/lib/twitter/client/profile.rb +29 -0
- data/lib/vendor/twitter/lib/twitter/client/search.rb +27 -0
- data/lib/vendor/twitter/lib/twitter/client/status.rb +51 -0
- data/lib/vendor/twitter/lib/twitter/client/timeline.rb +72 -0
- data/lib/vendor/twitter/lib/twitter/client/user.rb +65 -0
- data/lib/vendor/twitter/lib/twitter/config.rb +77 -0
- data/lib/vendor/twitter/lib/twitter/console.rb +31 -0
- data/lib/vendor/twitter/lib/twitter/core.rb +137 -0
- data/lib/vendor/twitter/lib/twitter/ext.rb +2 -0
- data/lib/vendor/twitter/lib/twitter/ext/stdlib.rb +52 -0
- data/lib/vendor/twitter/lib/twitter/extras.rb +39 -0
- data/lib/vendor/twitter/lib/twitter/meta.rb +56 -0
- data/lib/vendor/twitter/lib/twitter/model.rb +360 -0
- data/lib/vendor/twitter/lib/twitter/version.rb +19 -0
- data/lib/vendor/twitter/spec/twitter/client/account_spec.rb +28 -0
- data/lib/vendor/twitter/spec/twitter/client/auth_spec.rb +34 -0
- data/lib/vendor/twitter/spec/twitter/client/base_spec.rb +242 -0
- data/lib/vendor/twitter/spec/twitter/client/blocks_spec.rb +76 -0
- data/lib/vendor/twitter/spec/twitter/client/favorites_spec.rb +183 -0
- data/lib/vendor/twitter/spec/twitter/client/friendship_spec.rb +76 -0
- data/lib/vendor/twitter/spec/twitter/client/graph_spec.rb +67 -0
- data/lib/vendor/twitter/spec/twitter/client/messaging_spec.rb +135 -0
- data/lib/vendor/twitter/spec/twitter/client/profile_spec.rb +91 -0
- data/lib/vendor/twitter/spec/twitter/client/search_spec.rb +68 -0
- data/lib/vendor/twitter/spec/twitter/client/status_spec.rb +119 -0
- data/lib/vendor/twitter/spec/twitter/client/timeline_spec.rb +79 -0
- data/lib/vendor/twitter/spec/twitter/client/user_spec.rb +203 -0
- data/lib/vendor/twitter/spec/twitter/client_spec.rb +2 -0
- data/lib/vendor/twitter/spec/twitter/config_spec.rb +86 -0
- data/lib/vendor/twitter/spec/twitter/console_spec.rb +15 -0
- data/lib/vendor/twitter/spec/twitter/core_spec.rb +127 -0
- data/lib/vendor/twitter/spec/twitter/ext/stdlib_spec.rb +59 -0
- data/lib/vendor/twitter/spec/twitter/extras_spec.rb +46 -0
- data/lib/vendor/twitter/spec/twitter/meta_spec.rb +90 -0
- data/lib/vendor/twitter/spec/twitter/model_spec.rb +508 -0
- data/lib/vendor/twitter/spec/twitter/version_spec.rb +19 -0
- data/lib/vendor/xmpp4r/CHANGELOG +83 -0
- data/lib/vendor/xmpp4r/COPYING +340 -0
- data/lib/vendor/xmpp4r/LICENSE +59 -0
- data/lib/vendor/xmpp4r/README.rdoc +110 -0
- data/lib/vendor/xmpp4r/README_ruby19.txt +43 -0
- data/lib/vendor/xmpp4r/Rakefile +262 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/adventure/README +56 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/adventure/adventure.rb +23 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/adventure/adventuremuc.rb +136 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/adventure/cube.xml +15 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/adventure/tower.xml +69 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/adventure/world.rb +424 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/fileserve.conf +11 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/fileserve.rb +346 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/getonline.rb +56 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/gtkmucclient.rb +315 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/migrate.rb +88 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/minimuc.rb +266 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/pep-aggregator/index.xsl +235 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/pep-aggregator/pep-aggregator.rb +147 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/recvfile.rb +84 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/rosterdiscovery.rb +129 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/sendfile.conf +10 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/sendfile.rb +72 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr.rb +51 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_jabber.rb +43 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_test.rb +10 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/versionpoll.rb +90 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/xmpping.rb +146 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/xmppingrc.sample +14 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/change_password.rb +41 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/client.rb +70 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/component.rb +11 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/echo.rb +37 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/jabbersend.rb +41 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/mass_sender.rb +68 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/muc_owner_config.rb +12 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/mucinfo.rb +41 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/mucsimplebot.rb +82 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/register.rb +42 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/remove_registration.rb +18 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/roster.rb +44 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/rosterprint.rb +50 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/rosterrename.rb +34 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/rosterwatch.rb +171 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/send_vcard.rb +67 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/tune_client.rb +56 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/tune_server.rb +58 -0
- data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/versionbot.rb +75 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r.rb +116 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/base64.rb +32 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams.rb +15 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/filetransfer.rb +319 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/ibb/base.rb +257 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/ibb/initiator.rb +31 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/ibb/target.rb +47 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb +152 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb +86 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb +198 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb +65 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb +73 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb.orig +62 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/iq/bytestreams.rb +170 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/iq/si.rb +206 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/callbacks.rb +124 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/caps.rb +1 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/caps/c.rb +53 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/caps/helper/generator.rb +160 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/caps/helper/helper.rb +87 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/client.rb +317 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/command/helper/responder.rb +53 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/command/iq/command.rb +154 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/component.rb +103 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/connection.rb +219 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/dataforms.rb +5 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/dataforms/x/data.rb +297 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/debuglog.rb +42 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/delay.rb +5 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/delay/x/delay.rb +99 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/discovery.rb +7 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/discovery/helper/responder.rb +165 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/discovery/iq/discoinfo.rb +211 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/discovery/iq/discoitems.rb +147 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/errors.rb +281 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/feature_negotiation.rb +5 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/feature_negotiation/iq/feature.rb +28 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/framework/base.rb +55 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/framework/bot.rb +148 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/httpbinding.rb +5 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/httpbinding/client.rb +285 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/idgenerator.rb +37 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/iq.rb +221 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/jid.rb +167 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/message.rb +148 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/muc.rb +14 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/muc/helper/mucbrowser.rb +92 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/muc/helper/mucclient.rb +462 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/muc/helper/simplemucclient.rb +332 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/muc/iq/mucadmin.rb +23 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/muc/iq/mucadminitem.rb +20 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/muc/iq/mucowner.rb +15 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/muc/item.rb +143 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/muc/x/muc.rb +70 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/muc/x/mucuserinvite.rb +60 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/muc/x/mucuseritem.rb +36 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/presence.rb +232 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub.rb +8 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/configuration.rb +86 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/event.rb +49 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/item.rb +35 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/items.rb +44 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/node_config.rb +48 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/publish.rb +24 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/subscription.rb +62 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/subscription_config.rb +67 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/unsubscribe.rb +48 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/helper/nodebrowser.rb +130 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/helper/nodehelper.rb +156 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/helper/servicehelper.rb +417 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/iq/pubsub.rb +19 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/query.rb +15 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/rexmladdons.rb +151 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/roster.rb +7 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb +519 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/roster/iq/roster.rb +215 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/roster/x/roster.rb +138 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/rpc.rb +2 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/rpc/helper/client.rb +123 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/rpc/helper/server.rb +74 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/rpc/helper/xmlrpcaddons.rb +67 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/rpc/iq/rpc.rb +23 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/sasl.rb +237 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/semaphore.rb +38 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/stream.rb +497 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/streamparser.rb +77 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/tune.rb +2 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/tune/helper/helper.rb +58 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/tune/tune.rb +113 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/vcard.rb +6 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/vcard/helper/vcard.rb +84 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/vcard/iq/vcard.rb +109 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/version.rb +7 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/version/helper/responder.rb +72 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/version/helper/simpleresponder.rb +44 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/version/iq/version.rb +105 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/x.rb +37 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/xhtml.rb +1 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/xhtml/html.rb +115 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/xmpp4r.rb +18 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/xmppelement.rb +168 -0
- data/lib/vendor/xmpp4r/lib/xmpp4r/xmppstanza.rb +162 -0
- data/lib/vendor/xmpp4r/setup.rb +1586 -0
- data/lib/vendor/xmpp4r/test/bytestreams/tc_ibb.rb +186 -0
- data/lib/vendor/xmpp4r/test/bytestreams/tc_socks5bytestreams.rb +113 -0
- data/lib/vendor/xmpp4r/test/caps/tc_helper.rb +156 -0
- data/lib/vendor/xmpp4r/test/dataforms/tc_data.rb +81 -0
- data/lib/vendor/xmpp4r/test/delay/tc_xdelay.rb +51 -0
- data/lib/vendor/xmpp4r/test/discovery/tc_responder.rb +91 -0
- data/lib/vendor/xmpp4r/test/lib/assert_equal_xml.rb +14 -0
- data/lib/vendor/xmpp4r/test/lib/clienttester.rb +120 -0
- data/lib/vendor/xmpp4r/test/muc/tc_muc_mucclient.rb +830 -0
- data/lib/vendor/xmpp4r/test/muc/tc_muc_simplemucclient.rb +114 -0
- data/lib/vendor/xmpp4r/test/muc/tc_mucowner.rb +50 -0
- data/lib/vendor/xmpp4r/test/pubsub/tc_helper.rb +662 -0
- data/lib/vendor/xmpp4r/test/pubsub/tc_nodeconfig.rb +54 -0
- data/lib/vendor/xmpp4r/test/pubsub/tc_subscriptionconfig.rb +41 -0
- data/lib/vendor/xmpp4r/test/roster/tc_helper.rb +514 -0
- data/lib/vendor/xmpp4r/test/roster/tc_iqqueryroster.rb +173 -0
- data/lib/vendor/xmpp4r/test/roster/tc_xroster.rb +73 -0
- data/lib/vendor/xmpp4r/test/rpc/tc_helper.rb +96 -0
- data/lib/vendor/xmpp4r/test/tc_callbacks.rb +129 -0
- data/lib/vendor/xmpp4r/test/tc_class_names.rb +146 -0
- data/lib/vendor/xmpp4r/test/tc_client.rb +30 -0
- data/lib/vendor/xmpp4r/test/tc_errors.rb +146 -0
- data/lib/vendor/xmpp4r/test/tc_idgenerator.rb +30 -0
- data/lib/vendor/xmpp4r/test/tc_iq.rb +113 -0
- data/lib/vendor/xmpp4r/test/tc_iqquery.rb +31 -0
- data/lib/vendor/xmpp4r/test/tc_jid.rb +204 -0
- data/lib/vendor/xmpp4r/test/tc_message.rb +116 -0
- data/lib/vendor/xmpp4r/test/tc_presence.rb +150 -0
- data/lib/vendor/xmpp4r/test/tc_rexml.rb +139 -0
- data/lib/vendor/xmpp4r/test/tc_stream.rb +229 -0
- data/lib/vendor/xmpp4r/test/tc_streamComponent.rb +95 -0
- data/lib/vendor/xmpp4r/test/tc_streamError.rb +131 -0
- data/lib/vendor/xmpp4r/test/tc_streamSend.rb +59 -0
- data/lib/vendor/xmpp4r/test/tc_streamparser.rb +112 -0
- data/lib/vendor/xmpp4r/test/tc_xmppstanza.rb +135 -0
- data/lib/vendor/xmpp4r/test/ts_xmpp4r.rb +53 -0
- data/lib/vendor/xmpp4r/test/tune/tc_helper_recv.rb +84 -0
- data/lib/vendor/xmpp4r/test/tune/tc_helper_send.rb +74 -0
- data/lib/vendor/xmpp4r/test/tune/tc_tune.rb +79 -0
- data/lib/vendor/xmpp4r/test/vcard/tc_helper.rb +49 -0
- data/lib/vendor/xmpp4r/test/vcard/tc_iqvcard.rb +62 -0
- data/lib/vendor/xmpp4r/test/version/tc_helper.rb +60 -0
- data/lib/vendor/xmpp4r/test/version/tc_iqqueryversion.rb +97 -0
- data/lib/vendor/xmpp4r/test/xhtml/tc_html.rb +41 -0
- data/lib/vendor/xmpp4r/tools/gen_requires.bash +31 -0
- data/lib/vendor/xmpp4r/tools/xmpp4r-gemspec-test.rb +11 -0
- data/lib/vendor/xmpp4r/xmpp4r.gemspec +291 -0
- data/test/jabber_publisher_test.rb +1 -1
- data/test/mail_publisher_test.rb +2 -2
- data/test/mock/twitter.rb +0 -1
- data/test/rspec_builder_test.rb +39 -2
- data/test/rss_publisher_test.rb +1 -1
- data/test/twitter_publisher_test.rb +1 -1
- metadata +268 -53
- data/lib/cerberus/publisher/gmailer.rb +0 -17
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
# Demonstration of the Vcard helper class
|
|
4
|
+
#
|
|
5
|
+
# * Retrieves your own vCard
|
|
6
|
+
# * Modify fields given on the command line
|
|
7
|
+
# * Dumps the vCard
|
|
8
|
+
# * Send your vCard to the server
|
|
9
|
+
|
|
10
|
+
$:.unshift('../../../../../lib')
|
|
11
|
+
|
|
12
|
+
require 'xmpp4r'
|
|
13
|
+
require 'xmpp4r/vcard/helper/vcard'
|
|
14
|
+
include Jabber
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# settings
|
|
18
|
+
if ARGV.length < 2
|
|
19
|
+
puts "Usage:\t./send_vcard.rb <jid> <password> [<field1>=<value1> [... <fieldN>=<valueN>] ]"
|
|
20
|
+
puts "Example:\t./send_vcard.rb user@server/resource password NICKNAME=User \"FN=A user\""
|
|
21
|
+
exit 1
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Do the client stuff...
|
|
25
|
+
myJID = JID.new(ARGV.shift)
|
|
26
|
+
myPassword = ARGV.shift
|
|
27
|
+
cl = Client.new(myJID)
|
|
28
|
+
cl.connect
|
|
29
|
+
cl.auth(myPassword)
|
|
30
|
+
|
|
31
|
+
# The Vcard helper
|
|
32
|
+
vcard_helper = Vcard::Helper.new(cl)
|
|
33
|
+
|
|
34
|
+
begin
|
|
35
|
+
puts "Retrieving vCard information for #{cl.jid.strip}"
|
|
36
|
+
vcard = vcard_helper.get
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# Inspect the command line for vCard fields to be changed
|
|
40
|
+
ARGV.each { |arg|
|
|
41
|
+
arg.scan(/^(.+?)=(.*)$/) { |field,text|
|
|
42
|
+
puts "field #{field}: #{vcard[field].inspect} => #{text.inspect}"
|
|
43
|
+
vcard[field] = text
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# Dump the vCard
|
|
48
|
+
vcard.fields.each { |field|
|
|
49
|
+
if field.split(/\//).pop == 'BINVAL'
|
|
50
|
+
puts "#{field}:\tBINVAL"
|
|
51
|
+
else
|
|
52
|
+
puts "#{field}:\t#{vcard[field].inspect}"
|
|
53
|
+
end
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
begin
|
|
57
|
+
puts "Sending vCard information for #{cl.jid.strip}"
|
|
58
|
+
vcard_helper.set(vcard)
|
|
59
|
+
rescue Exception => e
|
|
60
|
+
puts "Sorry, we stumbled upon the following when sending the vCard of #{cl.jid.strip}: #{e.to_s.inspect}"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
rescue Exception => e
|
|
64
|
+
puts "Sorry, we stumbled upon the following when requesting the vCard of #{cl.jid.strip}: #{e.to_s.inspect}"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
cl.close
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$:.unshift '../../../../../lib'
|
|
4
|
+
|
|
5
|
+
require 'xmpp4r'
|
|
6
|
+
require 'xmpp4r/roster'
|
|
7
|
+
require 'xmpp4r/discovery'
|
|
8
|
+
require 'xmpp4r/caps'
|
|
9
|
+
require 'xmpp4r/tune'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
# Echo tunes received via XEP-0118 User Tune notifications
|
|
14
|
+
#
|
|
15
|
+
# See Jabber::UserTune::Helper for the gory details
|
|
16
|
+
#
|
|
17
|
+
|
|
18
|
+
if ARGV.length != 3
|
|
19
|
+
puts "Usage: ruby tune_client.rb <jid> <pw> <tune-playing-jid>"
|
|
20
|
+
exit 1
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
jid = ARGV[0]
|
|
24
|
+
pw = ARGV[1]
|
|
25
|
+
dj_jid = ARGV[2]
|
|
26
|
+
|
|
27
|
+
#Jabber::debug=true
|
|
28
|
+
cl = Jabber::Client.new(Jabber::JID.new(jid))
|
|
29
|
+
cl.connect
|
|
30
|
+
cl.auth(pw)
|
|
31
|
+
|
|
32
|
+
# PEP (XEP-0163 says we need:
|
|
33
|
+
# - a 'both' subscription to the dj
|
|
34
|
+
# - told the server that we support the '...tune+notify' feature
|
|
35
|
+
# before we can receive events
|
|
36
|
+
roster = Jabber::Roster::Helper.new(cl)
|
|
37
|
+
roster.add_subscription_request_callback(0, nil) do |item,pres|
|
|
38
|
+
roster.accept_subscription(pres.from)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
caps = Jabber::Caps::Helper.new(cl,
|
|
42
|
+
[Jabber::Discovery::Identity.new('client', nil, 'pc')],
|
|
43
|
+
[Jabber::Discovery::Feature.new('http://jabber.org/protocol/tune+notify')]
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
t = Jabber::UserTune::Helper.new(cl, dj_jid)
|
|
47
|
+
t.add_usertune_callback do |tune|
|
|
48
|
+
puts "from:#{dj_jid} tune:#{tune.artist} plays #{tune.title}"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
p = Jabber::Presence.new()
|
|
52
|
+
p.type = :subscribe
|
|
53
|
+
p.to = dj_jid
|
|
54
|
+
cl.send p
|
|
55
|
+
|
|
56
|
+
Thread.stop
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$:.unshift '../../../../../lib'
|
|
4
|
+
|
|
5
|
+
require 'xmpp4r'
|
|
6
|
+
require 'xmpp4r/roster'
|
|
7
|
+
require 'xmpp4r/tune'
|
|
8
|
+
require 'rbosa'
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# Send XEP-0118 User Tune events...
|
|
12
|
+
#
|
|
13
|
+
# See Jabber::UserTune::Helper for the gory details...
|
|
14
|
+
#
|
|
15
|
+
# NB needs rbosa library to access iTunes - only on MacOSX
|
|
16
|
+
#
|
|
17
|
+
|
|
18
|
+
if ARGV.length != 2:
|
|
19
|
+
puts "Usage: ruby tune_server.rb <jid> <pw>"
|
|
20
|
+
exit 1
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
jid=ARGV[0]
|
|
24
|
+
pw=ARGV[1]
|
|
25
|
+
|
|
26
|
+
Jabber::debug=true
|
|
27
|
+
|
|
28
|
+
cl = Jabber::Client.new(jid)
|
|
29
|
+
cl.connect
|
|
30
|
+
cl.auth(pw)
|
|
31
|
+
|
|
32
|
+
# Following XEP-0163 PEP we need to
|
|
33
|
+
# ensure we have a 'both' subscription to the Tune client
|
|
34
|
+
roster = Jabber::Roster::Helper.new(cl)
|
|
35
|
+
roster.add_subscription_request_callback do |item,pres|
|
|
36
|
+
roster.accept_subscription(pres.from)
|
|
37
|
+
|
|
38
|
+
reply = pres.answer
|
|
39
|
+
reply.type = :subscribe
|
|
40
|
+
cl.send(reply)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
cl.send(Jabber::Presence.new.set_show(:chat))
|
|
44
|
+
|
|
45
|
+
t=Jabber::UserTune::Helper.new(cl, nil)
|
|
46
|
+
|
|
47
|
+
itunes=OSA.app('iTunes')
|
|
48
|
+
|
|
49
|
+
loop do
|
|
50
|
+
track = itunes.current_track
|
|
51
|
+
|
|
52
|
+
if track
|
|
53
|
+
puts "Now playing: #{track.name} by #{track.artist}"
|
|
54
|
+
t.now_playing(Jabber::UserTune::Tune.new(track.artist, track.name))
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
sleep 5
|
|
58
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
$:.unshift '../../../../../lib'
|
|
4
|
+
|
|
5
|
+
require 'xmpp4r'
|
|
6
|
+
require 'xmpp4r/version/iq/version'
|
|
7
|
+
require 'xmpp4r/version/helper/simpleresponder'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# A Hash containing all Version Query answers with their JIDs as keys:
|
|
11
|
+
versions = {}
|
|
12
|
+
|
|
13
|
+
# Command line argument checking
|
|
14
|
+
|
|
15
|
+
if ARGV.size != 2
|
|
16
|
+
puts("Usage: ./versionbot.rb <jid> <password>")
|
|
17
|
+
exit
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Building up the connection
|
|
21
|
+
|
|
22
|
+
#Jabber::debug = true
|
|
23
|
+
|
|
24
|
+
jid = Jabber::JID.new(ARGV[0])
|
|
25
|
+
|
|
26
|
+
cl = Jabber::Client.new(jid)
|
|
27
|
+
cl.connect
|
|
28
|
+
cl.auth(ARGV[1])
|
|
29
|
+
|
|
30
|
+
cl.on_exception { |*a|
|
|
31
|
+
p a[0].backtrace
|
|
32
|
+
exit!
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# I'm not sure about the portability of 'uname -sr' here ;-)
|
|
36
|
+
# but that's all needed to answer version queries:
|
|
37
|
+
Jabber::Version::SimpleResponder.new(cl, 'xmpp4r Versionbot example', Jabber::XMPP4R_VERSION, IO.popen('uname -sr').readlines.to_s.strip)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
cl.add_iq_callback { |iq|
|
|
41
|
+
# Filter for version query results
|
|
42
|
+
if (iq.type == :result) && iq.query.kind_of?(Jabber::Version::IqQueryVersion)
|
|
43
|
+
puts "Version query result from #{iq.from}"
|
|
44
|
+
# Keep track of results per JID
|
|
45
|
+
versions[iq.from] = iq.query
|
|
46
|
+
# Print details
|
|
47
|
+
puts " Name: #{iq.query.iname.inspect}"
|
|
48
|
+
puts " Version: #{iq.query.version.inspect}"
|
|
49
|
+
puts " OS: #{iq.query.os.inspect}"
|
|
50
|
+
end
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
cl.add_presence_callback { |pres|
|
|
54
|
+
# Already fingerprinted or offline?
|
|
55
|
+
unless versions.has_key?(pres.from) || (pres.type == :unavailable) || (pres.type == :error)
|
|
56
|
+
# Construct a new query
|
|
57
|
+
iq = Jabber::Iq.new(:get, pres.from)
|
|
58
|
+
# and ask for the version
|
|
59
|
+
iq.query = Jabber::Version::IqQueryVersion.new
|
|
60
|
+
puts "Asking #{iq.to} for his/her/its version"
|
|
61
|
+
versions[pres.from] = :asking
|
|
62
|
+
cl.send(iq)
|
|
63
|
+
end
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# Send initial presence
|
|
67
|
+
cl.send(Jabber::Presence.new.set_show(:xa).set_status('I am the evil fingerprinting robot'))
|
|
68
|
+
|
|
69
|
+
# Main loop:
|
|
70
|
+
loop do
|
|
71
|
+
cl.process
|
|
72
|
+
sleep(1)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
cl.close
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# =XMPP4R - XMPP Library for Ruby
|
|
2
|
+
# License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
|
|
3
|
+
# Website::http://home.gna.org/xmpp4r/
|
|
4
|
+
#
|
|
5
|
+
# ==Introduction
|
|
6
|
+
#
|
|
7
|
+
# XMPP4R is a XMPP/Jabber library for Ruby. It can be used to build scripts
|
|
8
|
+
# using Jabber, full-featured Jabber clients, and components. It is written
|
|
9
|
+
# with extensibility in mind.
|
|
10
|
+
#
|
|
11
|
+
# ==XML management
|
|
12
|
+
#
|
|
13
|
+
# All the XML parsing is REXML's, and XML stanzas like <message/> (class
|
|
14
|
+
# <tt>Jabber::Message</tt>) or <iq/> (class <tt>Jabber::Iq</tt>) are indirect
|
|
15
|
+
# derivatives from REXML's Element class. This provide a maximum flexibity:
|
|
16
|
+
# the user can access attributes and childs using either the XMPP4R's helpers
|
|
17
|
+
# or directly using REXML's methods.
|
|
18
|
+
#
|
|
19
|
+
# ===Automatic element casting
|
|
20
|
+
#
|
|
21
|
+
# Because there are special classes derived from REXML::Element to ease
|
|
22
|
+
# development on the protocol level, Elements must be cast to them. This is
|
|
23
|
+
# done via REXML::Element.import. This method is also used in import class
|
|
24
|
+
# methods of some Element classes.
|
|
25
|
+
#
|
|
26
|
+
# The first occurance of this feature is in Jabber::Stream::receive:
|
|
27
|
+
# * <tt><message/></tt> stanzas are cast to Jabber::Message class
|
|
28
|
+
# * <tt><presence/></tt> stanzas are cast to Jabber::Presence class
|
|
29
|
+
# * <tt><iq/></tt> stanzas are cast to Jabber::Iq class
|
|
30
|
+
#
|
|
31
|
+
# This is not only useful for stanzas but all other XML processing, too:
|
|
32
|
+
# * <tt><x/></tt> children elements of <tt><message/></tt> and <tt><presence/></tt> are converted to Jabber::X
|
|
33
|
+
# * <tt><error/></tt> children elements of all three stanzas are converted to Jabber::ErrorResponse
|
|
34
|
+
# * <tt><query/></tt> children elements of <tt><iq/></tt> are converted to Jabber::IqQuery
|
|
35
|
+
# * <tt><vCard/></tt> children elements of <tt><iq/></tt> are converted to Jabber::IqVcard
|
|
36
|
+
#
|
|
37
|
+
# The following conversion facilities are only executed if the respective
|
|
38
|
+
# library parts are loaded. See below for more details on Non-basic features.
|
|
39
|
+
# * Jabber::IqQuery elements are converted to Jabber::Roster::IqQueryRoster if their
|
|
40
|
+
# namespace is 'jabber:iq:roster'
|
|
41
|
+
# * Jabber::IqQuery elements are converted to Jabber::Version::IqQueryVersion if their
|
|
42
|
+
# namespace is 'jabber:iq:version'
|
|
43
|
+
# * Jabber::IqQuery elements are converted to Jabber::Discovery::IqQueryDiscoInfo if their
|
|
44
|
+
# namespace is 'http://jabber.org/protocol/disco#info'
|
|
45
|
+
# * Jabber::IqQuery elements are converted to Jabber::Discovery::IqQueryDiscoItems if their
|
|
46
|
+
# namespace is 'http://jabber.org/protocol/disco#items'
|
|
47
|
+
# * <tt><item/></tt> children elements of Jabber::Roster::IqQueryRoster are converted
|
|
48
|
+
# to Jabber::Roster::RosterItem
|
|
49
|
+
# * <tt><identity/></tt> children elements of Jabber::IqQueryDiscoInfo are converted
|
|
50
|
+
# to Jabber::Discovery::DiscoIdentity
|
|
51
|
+
# * <tt><feature/></tt> children elements of Jabber::IqQueryDiscoInfo are converted
|
|
52
|
+
# to Jabber::Discovery::DiscoFeature
|
|
53
|
+
# * <tt><item/></tt> children elements of Jabber::IqQueryDiscoItems are converted
|
|
54
|
+
# to Jabber::Discovery::DiscoItem
|
|
55
|
+
#
|
|
56
|
+
# To use this, don't check for:
|
|
57
|
+
# <tt>iq.queryns == 'http://jabber.org/protocol/disco#info'</tt>
|
|
58
|
+
#
|
|
59
|
+
# But instead check for the query's class:
|
|
60
|
+
# <tt>iq.query.kind_of?(Jabber::IqQueryDiscoInfo)</tt>
|
|
61
|
+
#
|
|
62
|
+
# ==Where to begin?
|
|
63
|
+
#
|
|
64
|
+
# Because it is built in an extensible way, it might be hard for newcomers to
|
|
65
|
+
# understand where to look at documentation for a specific method. For example,
|
|
66
|
+
# Client inherits from Connection, which itself inherits from Stream.
|
|
67
|
+
#
|
|
68
|
+
# A newcomer should have a look at the <tt>Jabber::Client</tt> and
|
|
69
|
+
# <tt>Jabber::Component</tt> classes, and their parent classes
|
|
70
|
+
# <tt>Jabber::Connection</tt> and <tt>Jabber::Stream</tt>. The best way to
|
|
71
|
+
# understand how to use them is probably to look at the examples in the
|
|
72
|
+
# <tt>examples/</tt> dir.
|
|
73
|
+
#
|
|
74
|
+
# ==Non-basic features
|
|
75
|
+
#
|
|
76
|
+
# <tt>require 'xmpp4r'</tt> only includes basic functionality for
|
|
77
|
+
# Connections, Authentication, Stream processing, Callbacks, Stanza handling
|
|
78
|
+
# and Debugging to keep the library's footprint small.
|
|
79
|
+
#
|
|
80
|
+
# There is code for features that aren't required by a *basic* client. These
|
|
81
|
+
# must be additionally included to use them.
|
|
82
|
+
#
|
|
83
|
+
# ===Protocol-level features
|
|
84
|
+
#
|
|
85
|
+
# You're highly advised to read the according RFCs and JEPs if you intend to
|
|
86
|
+
# use them. The benefit will be that you'll understand the protocols and be
|
|
87
|
+
# going to be more efficient when programming with them.
|
|
88
|
+
#
|
|
89
|
+
# * Jabber::Bytestreams, Jabber::FileTransfer: <tt>require 'xmpp4r/bytestreams'</tt>
|
|
90
|
+
# * Jabber::Dataforms: <tt>require 'xmpp4r/dataforms'</tt>
|
|
91
|
+
# * Jabber::Delay: <tt>require 'xmpp4r/delay'</tt>
|
|
92
|
+
# * Jabber::Discovery: <tt>require 'xmpp4r/discovery'</tt>
|
|
93
|
+
# * Jabber::FeatureNegotiation: <tt>require 'xmpp4r/feature_negotiation'</tt>
|
|
94
|
+
# * Jabber::MUC: <tt>require 'xmpp4r/muc'</tt>
|
|
95
|
+
# * Jabber::Roster: <tt>require 'xmpp4r/roster'</tt>
|
|
96
|
+
# * Jabber::Vcard: <tt>require 'xmpp4r/vcard'</tt>
|
|
97
|
+
# * Jabber::Version: <tt>require 'xmpp4r/version'</tt>
|
|
98
|
+
#
|
|
99
|
+
# ===Helpers
|
|
100
|
+
#
|
|
101
|
+
# Helpers are intended to give more simplistic interfaces to various tasks
|
|
102
|
+
# of Jabber clients at the cost of flexibility. But you won't need that
|
|
103
|
+
# level of flexibility in most cases.
|
|
104
|
+
#
|
|
105
|
+
# * Jabber::Roster::Helper: <tt>require 'xmpp4r/roster'</tt>
|
|
106
|
+
# * Jabber::MUC::MUCBrowser, Jabber::MUC::MUCClient, Jabber::MUC::SimpleMUCClient: <tt>require 'xmpp4r/muc'</tt>
|
|
107
|
+
# * Jabber::Version::SimpleResponder, Jabber::Version::Responder: <tt>require 'xmpp4r/version'</tt>
|
|
108
|
+
# * Jabber::Vcard::Helper: <tt>require 'xmpp4r/vcard'</tt>
|
|
109
|
+
# * Jabber::FileTransfer::Helper, Jabber::Bytestreams::SOCKS5BytestreamsServer: <tt>require 'xmpp4r/bytestreams'</tt>
|
|
110
|
+
#
|
|
111
|
+
# ==Debugging
|
|
112
|
+
#
|
|
113
|
+
# Dumping your Jabber stream can be enabled this way:
|
|
114
|
+
# Jabber::debug = true
|
|
115
|
+
|
|
116
|
+
require 'xmpp4r/xmpp4r'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# =XMPP4R - XMPP Library for Ruby
|
|
2
|
+
# License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
|
|
3
|
+
# Website::http://home.gna.org/xmpp4r/
|
|
4
|
+
|
|
5
|
+
begin
|
|
6
|
+
require 'base64'
|
|
7
|
+
rescue LoadError
|
|
8
|
+
##
|
|
9
|
+
# Ruby 1.9 has dropped the Base64 module,
|
|
10
|
+
# this is a replacement
|
|
11
|
+
#
|
|
12
|
+
# We could replace all call by Array#pack('m')
|
|
13
|
+
# and String#unpack('m'), but this module
|
|
14
|
+
# improves readability.
|
|
15
|
+
module Base64
|
|
16
|
+
##
|
|
17
|
+
# Encode a String
|
|
18
|
+
# data:: [String] Binary
|
|
19
|
+
# result:: [String] Binary in Base64
|
|
20
|
+
def self.encode64(data)
|
|
21
|
+
[data].pack('m')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
##
|
|
25
|
+
# Decode a Base64-encoded String
|
|
26
|
+
# data64:: [String] Binary in Base64
|
|
27
|
+
# result:: [String] Binary
|
|
28
|
+
def self.decode64(data64)
|
|
29
|
+
data64.unpack('m').first
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# =XMPP4R - XMPP Library for Ruby
|
|
2
|
+
# License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
|
|
3
|
+
# Website::http://home.gna.org/xmpp4r/
|
|
4
|
+
|
|
5
|
+
require 'xmpp4r/bytestreams/iq/si.rb'
|
|
6
|
+
require 'xmpp4r/bytestreams/iq/bytestreams.rb'
|
|
7
|
+
require 'xmpp4r/bytestreams/helper/ibb/base.rb'
|
|
8
|
+
require 'xmpp4r/bytestreams/helper/ibb/initiator.rb'
|
|
9
|
+
require 'xmpp4r/bytestreams/helper/ibb/target.rb'
|
|
10
|
+
require 'xmpp4r/bytestreams/helper/filetransfer.rb'
|
|
11
|
+
require 'xmpp4r/bytestreams/helper/socks5bytestreams/base.rb'
|
|
12
|
+
require 'xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb'
|
|
13
|
+
require 'xmpp4r/bytestreams/helper/socks5bytestreams/server.rb'
|
|
14
|
+
require 'xmpp4r/bytestreams/helper/socks5bytestreams/target.rb'
|
|
15
|
+
require 'xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb'
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# =XMPP4R - XMPP Library for Ruby
|
|
2
|
+
# License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
|
|
3
|
+
# Website::http://home.gna.org/xmpp4r/
|
|
4
|
+
|
|
5
|
+
require 'xmpp4r/callbacks'
|
|
6
|
+
require 'xmpp4r/bytestreams/iq/si'
|
|
7
|
+
require 'xmpp4r/dataforms/x/data'
|
|
8
|
+
require 'xmpp4r/bytestreams/helper/ibb/base'
|
|
9
|
+
require 'xmpp4r/bytestreams/helper/socks5bytestreams/base'
|
|
10
|
+
|
|
11
|
+
module Jabber
|
|
12
|
+
module FileTransfer
|
|
13
|
+
##
|
|
14
|
+
# The TransferSource is an interface (Mix-in)
|
|
15
|
+
# which sources for FileTransfer#offer should include
|
|
16
|
+
module TransferSource
|
|
17
|
+
##
|
|
18
|
+
# Filename of the offered file
|
|
19
|
+
def filename
|
|
20
|
+
end
|
|
21
|
+
##
|
|
22
|
+
# Mime-type of the offered file, can be nil
|
|
23
|
+
def mime
|
|
24
|
+
end
|
|
25
|
+
##
|
|
26
|
+
# Size of the offered file
|
|
27
|
+
def size
|
|
28
|
+
end
|
|
29
|
+
##
|
|
30
|
+
# MD5-Sum of the offered file, can be nil
|
|
31
|
+
def md5
|
|
32
|
+
end
|
|
33
|
+
##
|
|
34
|
+
# Date of the offered file, can be nil
|
|
35
|
+
def date
|
|
36
|
+
end
|
|
37
|
+
##
|
|
38
|
+
# Read a chunk from the source
|
|
39
|
+
#
|
|
40
|
+
# If this is a ranged transfer, it should
|
|
41
|
+
# implement length checking
|
|
42
|
+
# length:: [Fixnum]
|
|
43
|
+
def read(length=nil)
|
|
44
|
+
end
|
|
45
|
+
##
|
|
46
|
+
# Seek in the source for ranged transfers
|
|
47
|
+
def seek(position)
|
|
48
|
+
end
|
|
49
|
+
##
|
|
50
|
+
# Set the amount of data to send for ranged transfers
|
|
51
|
+
def length=(l)
|
|
52
|
+
end
|
|
53
|
+
##
|
|
54
|
+
# Does implement the methods seek and length= ?
|
|
55
|
+
#
|
|
56
|
+
# FileTransfer will only then offer a ranged transfer.
|
|
57
|
+
# result:: [false] or [true]
|
|
58
|
+
def can_range?
|
|
59
|
+
false
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
##
|
|
64
|
+
# Simple implementation of TransferSource
|
|
65
|
+
# for sending simple files
|
|
66
|
+
# (supports ranged transfers)
|
|
67
|
+
class FileSource
|
|
68
|
+
include TransferSource
|
|
69
|
+
|
|
70
|
+
def initialize(filename)
|
|
71
|
+
@file = File.new(filename)
|
|
72
|
+
@filename = filename
|
|
73
|
+
@bytes_read = 0
|
|
74
|
+
@length = nil
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def filename
|
|
78
|
+
File::basename @filename
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
##
|
|
82
|
+
# Everything is 'application/octet-stream'
|
|
83
|
+
def mime
|
|
84
|
+
'application/octet-stream'
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def size
|
|
88
|
+
File.size @filename
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def date
|
|
92
|
+
@file.mtime
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
##
|
|
96
|
+
# Because it can_range?, this method implements length checking
|
|
97
|
+
def read(length=512)
|
|
98
|
+
if @length
|
|
99
|
+
return nil if @bytes_read >= @length # Already read everything requested
|
|
100
|
+
if @bytes_read + length > @length # Will we read more than requested?
|
|
101
|
+
length = @length - @bytes_read # Truncate it!
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
buf = @file.read(length)
|
|
106
|
+
@bytes_read += buf.size if buf
|
|
107
|
+
buf
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def seek(position)
|
|
111
|
+
@file.seek(position)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def length=(l)
|
|
115
|
+
@length = l
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def can_range?
|
|
119
|
+
true
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
##
|
|
124
|
+
# The FileTransfer helper provides the ability to respond
|
|
125
|
+
# to incoming and to offer outgoing file-transfers.
|
|
126
|
+
class Helper
|
|
127
|
+
##
|
|
128
|
+
# Set this if you want to use this helper in a Component
|
|
129
|
+
attr_accessor :my_jid
|
|
130
|
+
##
|
|
131
|
+
# Set this to false if you don't want to use SOCKS5Bytestreams
|
|
132
|
+
attr_accessor :allow_bytestreams
|
|
133
|
+
##
|
|
134
|
+
# Set this to false if you don't want to use IBB
|
|
135
|
+
attr_accessor :allow_ibb
|
|
136
|
+
|
|
137
|
+
##
|
|
138
|
+
# Create a new FileTransfer instance
|
|
139
|
+
def initialize(stream)
|
|
140
|
+
@stream = stream
|
|
141
|
+
@my_jid = nil
|
|
142
|
+
@allow_bytestreams = true
|
|
143
|
+
@allow_ibb = true
|
|
144
|
+
|
|
145
|
+
@incoming_cbs = CallbackList.new
|
|
146
|
+
|
|
147
|
+
@stream.add_iq_callback(150, self) { |iq|
|
|
148
|
+
if iq.type == :set
|
|
149
|
+
file = iq.first_element('si/file')
|
|
150
|
+
field = nil
|
|
151
|
+
iq.each_element('si/feature/x') { |e| field = e.field('stream-method') }
|
|
152
|
+
|
|
153
|
+
if file and field
|
|
154
|
+
@incoming_cbs.process(iq, file)
|
|
155
|
+
true
|
|
156
|
+
else
|
|
157
|
+
false
|
|
158
|
+
end
|
|
159
|
+
else
|
|
160
|
+
false
|
|
161
|
+
end
|
|
162
|
+
}
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
##
|
|
166
|
+
# Add a callback which will be invoked upon an incoming file-transfer
|
|
167
|
+
#
|
|
168
|
+
# block takes two arguments:
|
|
169
|
+
# * Iq
|
|
170
|
+
# * Bytestreams::IqSiFile in the Iq
|
|
171
|
+
# You may then invoke accept or decline
|
|
172
|
+
def add_incoming_callback(priority = 0, ref = nil, &block)
|
|
173
|
+
@incoming_cbs.add(priority, ref, block)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
##
|
|
177
|
+
# Accept an incoming file-transfer,
|
|
178
|
+
# to be used in a block given to add_incoming_callback
|
|
179
|
+
#
|
|
180
|
+
# offset and length will be ignored if there is no
|
|
181
|
+
# 'si/file/range' in iq.
|
|
182
|
+
# iq:: [Iq] of file-transfer we want to accept
|
|
183
|
+
# offset:: [Fixnum] or [nil]
|
|
184
|
+
# length:: [Fixnum] or [nil]
|
|
185
|
+
# result:: [Bytestreams::SOCKS5BytestreamsTarget] or [Bytestreams::IBBTarget] or [nil] if no valid stream-method
|
|
186
|
+
def accept(iq, offset=nil, length=nil)
|
|
187
|
+
oldsi = iq.first_element('si')
|
|
188
|
+
|
|
189
|
+
answer = iq.answer(false)
|
|
190
|
+
answer.type = :result
|
|
191
|
+
|
|
192
|
+
si = answer.add(Bytestreams::IqSi.new)
|
|
193
|
+
if (offset or length) and oldsi.file.range
|
|
194
|
+
si.add(Bytestreams::IqSiFile.new)
|
|
195
|
+
si.file.add(Bytestreams::IqSiFileRange.new(offset, length))
|
|
196
|
+
end
|
|
197
|
+
si.add(FeatureNegotiation::IqFeature.new.import(oldsi.feature))
|
|
198
|
+
si.feature.x.type = :submit
|
|
199
|
+
stream_method = si.feature.x.field('stream-method')
|
|
200
|
+
|
|
201
|
+
if stream_method.options.keys.include?(Bytestreams::NS_BYTESTREAMS) and @allow_bytestreams
|
|
202
|
+
stream_method.values = [Bytestreams::NS_BYTESTREAMS]
|
|
203
|
+
stream_method.options = []
|
|
204
|
+
@stream.send(answer)
|
|
205
|
+
|
|
206
|
+
Bytestreams::SOCKS5BytestreamsTarget.new(@stream, oldsi.id, iq.from, iq.to)
|
|
207
|
+
elsif stream_method.options.keys.include?(Bytestreams::IBB::NS_IBB) and @allow_ibb
|
|
208
|
+
stream_method.values = [Bytestreams::IBB::NS_IBB]
|
|
209
|
+
stream_method.options = []
|
|
210
|
+
@stream.send(answer)
|
|
211
|
+
|
|
212
|
+
Bytestreams::IBBTarget.new(@stream, oldsi.id, iq.from, iq.to)
|
|
213
|
+
else
|
|
214
|
+
eanswer = iq.answer(false)
|
|
215
|
+
eanswer.type = :error
|
|
216
|
+
eanswer.add(ErrorResponse.new('bad-request')).type = :cancel
|
|
217
|
+
eanswer.error.add(REXML::Element.new('no-valid-streams')).add_namespace('http://jabber.org/protocol/si')
|
|
218
|
+
@stream.send(eanswer)
|
|
219
|
+
|
|
220
|
+
nil
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
##
|
|
225
|
+
# Decline an incoming file-transfer,
|
|
226
|
+
# to be used in a block given to add_incoming_callback
|
|
227
|
+
# iq:: [Iq] of file-transfer we want to decline
|
|
228
|
+
def decline(iq)
|
|
229
|
+
answer = iq.answer(false)
|
|
230
|
+
answer.type = :error
|
|
231
|
+
error = answer.add(ErrorResponse.new('forbidden', 'Offer declined'))
|
|
232
|
+
error.type = :cancel
|
|
233
|
+
@stream.send(answer)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
##
|
|
237
|
+
# Offer a file to somebody
|
|
238
|
+
#
|
|
239
|
+
# Will wait for a response from the peer
|
|
240
|
+
#
|
|
241
|
+
# The result is a stream which you can configure, or nil
|
|
242
|
+
# if the peer responded with an invalid stream-method.
|
|
243
|
+
#
|
|
244
|
+
# May raise an ServerError
|
|
245
|
+
# jid:: [JID] to send the file to
|
|
246
|
+
# source:: File-transfer source, implementing the FileSource interface
|
|
247
|
+
# desc:: [String] or [nil] Optional file description
|
|
248
|
+
# from:: [String] or [nil] Optional jid for components
|
|
249
|
+
# result:: [Bytestreams::SOCKS5BytestreamsInitiator] or [Bytestreams::IBBInitiator] or [nil]
|
|
250
|
+
def offer(jid, source, desc=nil, from=nil)
|
|
251
|
+
from = from || @my_jid || @stream.jid
|
|
252
|
+
session_id = Jabber::IdGenerator.instance.generate_id
|
|
253
|
+
|
|
254
|
+
offered_methods = {}
|
|
255
|
+
if @allow_bytestreams
|
|
256
|
+
offered_methods[Bytestreams::NS_BYTESTREAMS] = nil
|
|
257
|
+
end
|
|
258
|
+
if @allow_ibb
|
|
259
|
+
offered_methods[Bytestreams::IBB::NS_IBB] = nil
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
iq = Iq.new(:set, jid)
|
|
263
|
+
iq.from = from
|
|
264
|
+
si = iq.add(Bytestreams::IqSi.new(session_id, Bytestreams::PROFILE_FILETRANSFER, source.mime))
|
|
265
|
+
|
|
266
|
+
file = si.add(Bytestreams::IqSiFile.new(source.filename, source.size))
|
|
267
|
+
file.hash = source.md5
|
|
268
|
+
file.date = source.date
|
|
269
|
+
file.description = desc if desc
|
|
270
|
+
file.add(Bytestreams::IqSiFileRange.new) if source.can_range?
|
|
271
|
+
|
|
272
|
+
feature = si.add(REXML::Element.new('feature'))
|
|
273
|
+
feature.add_namespace 'http://jabber.org/protocol/feature-neg'
|
|
274
|
+
x = feature.add(Dataforms::XData.new(:form))
|
|
275
|
+
stream_method_field = x.add(Dataforms::XDataField.new('stream-method', :list_single))
|
|
276
|
+
stream_method_field.options = offered_methods
|
|
277
|
+
|
|
278
|
+
begin
|
|
279
|
+
stream_method = nil
|
|
280
|
+
response = nil
|
|
281
|
+
@stream.send_with_id(iq) do |r|
|
|
282
|
+
response = r
|
|
283
|
+
si = response.first_element('si')
|
|
284
|
+
if si and si.feature and si.feature.x
|
|
285
|
+
stream_method = si.feature.x.field('stream-method').values.first
|
|
286
|
+
|
|
287
|
+
if si.file and si.file.range
|
|
288
|
+
if source.can_range?
|
|
289
|
+
source.seek(si.file.range.offset) if si.file.range.offset
|
|
290
|
+
source.length = si.file.range.length if si.file.range.length
|
|
291
|
+
else
|
|
292
|
+
source.read(si.file.range.offset)
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
rescue ServerError => e
|
|
298
|
+
if e.error.code == 403 # Declined
|
|
299
|
+
return false
|
|
300
|
+
else
|
|
301
|
+
raise e
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
if stream_method == Bytestreams::NS_BYTESTREAMS and @allow_bytestreams
|
|
306
|
+
Bytestreams::SOCKS5BytestreamsInitiator.new(@stream, session_id, from, jid)
|
|
307
|
+
elsif stream_method == Bytestreams::IBB::NS_IBB and @allow_ibb
|
|
308
|
+
Bytestreams::IBBInitiator.new(@stream, session_id, from, jid)
|
|
309
|
+
else # Target responded with a stream_method we didn't offer
|
|
310
|
+
eanswer = response.answer
|
|
311
|
+
eanswer.type = :error
|
|
312
|
+
eanswer.add ErrorResponse.new('bad-request')
|
|
313
|
+
@stream.send(eanswer)
|
|
314
|
+
nil
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end
|