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,19 @@
|
|
|
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/iq'
|
|
6
|
+
|
|
7
|
+
module Jabber
|
|
8
|
+
module PubSub
|
|
9
|
+
NS_PUBSUB = 'http://jabber.org/protocol/pubsub'
|
|
10
|
+
class IqPubSub < XMPPElement
|
|
11
|
+
name_xmlns 'pubsub', NS_PUBSUB
|
|
12
|
+
force_xmlns true
|
|
13
|
+
end
|
|
14
|
+
class IqPubSubOwner < XMPPElement
|
|
15
|
+
name_xmlns 'pubsub', NS_PUBSUB + '#owner'
|
|
16
|
+
force_xmlns true
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
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/xmppelement'
|
|
6
|
+
|
|
7
|
+
module Jabber
|
|
8
|
+
##
|
|
9
|
+
# A class used to build/parse IQ Query requests/responses
|
|
10
|
+
#
|
|
11
|
+
class IqQuery < XMPPElement
|
|
12
|
+
name_xmlns 'query'
|
|
13
|
+
force_xmlns true
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,151 @@
|
|
|
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 'rexml/document'
|
|
6
|
+
require 'rexml/parsers/xpathparser'
|
|
7
|
+
require 'rexml/source'
|
|
8
|
+
|
|
9
|
+
# Turn $VERBOSE off to suppress warnings about redefinition
|
|
10
|
+
oldverbose = $VERBOSE
|
|
11
|
+
$VERBOSE = false
|
|
12
|
+
|
|
13
|
+
# REXML : Adds custom helper methods to the REXML module.
|
|
14
|
+
#
|
|
15
|
+
module REXML
|
|
16
|
+
|
|
17
|
+
# this class adds a few helper methods to REXML::Element
|
|
18
|
+
class Element
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# Replaces or adds a child element of name <tt>e</tt> with text <tt>t</tt>.
|
|
22
|
+
def replace_element_text(e, t)
|
|
23
|
+
el = first_element(e)
|
|
24
|
+
if el.nil?
|
|
25
|
+
el = REXML::Element.new(e)
|
|
26
|
+
add_element(el)
|
|
27
|
+
end
|
|
28
|
+
if t
|
|
29
|
+
el.text = t
|
|
30
|
+
end
|
|
31
|
+
self
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
# Returns first element of name <tt>e</tt>
|
|
36
|
+
def first_element(e)
|
|
37
|
+
each_element(e) { |el| return el }
|
|
38
|
+
return nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
##
|
|
42
|
+
# Returns text of first element of name <tt>e</tt>
|
|
43
|
+
def first_element_text(e)
|
|
44
|
+
el = first_element(e)
|
|
45
|
+
if el
|
|
46
|
+
return el.text
|
|
47
|
+
else
|
|
48
|
+
return nil
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# This method does exactly the same thing as add(), but it can be
|
|
53
|
+
# overriden by subclasses to provide on-the-fly object creations.
|
|
54
|
+
# For example, if you import a REXML::Element of name 'plop', and you
|
|
55
|
+
# have a Plop class that subclasses REXML::Element, with typed_add you
|
|
56
|
+
# can get your REXML::Element to be "magically" converted to Plop.
|
|
57
|
+
def typed_add(e)
|
|
58
|
+
add(e)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
##
|
|
62
|
+
# import this element's children and attributes
|
|
63
|
+
def import(xmlelement)
|
|
64
|
+
if @name and @name != xmlelement.name
|
|
65
|
+
raise "Trying to import an #{xmlelement.name} to a #{@name} !"
|
|
66
|
+
end
|
|
67
|
+
add_attributes(xmlelement.attributes.clone)
|
|
68
|
+
@context = xmlelement.context
|
|
69
|
+
xmlelement.each do |e|
|
|
70
|
+
if e.kind_of? REXML::Element
|
|
71
|
+
typed_add(e.deep_clone)
|
|
72
|
+
elsif e.kind_of? REXML::Text
|
|
73
|
+
add_text(e.value)
|
|
74
|
+
else
|
|
75
|
+
add(e.clone)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
self
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def self.import(xmlelement)
|
|
82
|
+
self.new(xmlelement.name).import(xmlelement)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
##
|
|
86
|
+
# Deletes one or more children elements,
|
|
87
|
+
# not just one like REXML::Element#delete_element
|
|
88
|
+
def delete_elements(element)
|
|
89
|
+
while(delete_element(element)) do end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
##
|
|
93
|
+
# Test for equality of two elements, useful for assert_equal in
|
|
94
|
+
# test cases. Tries to parse String o as XML.
|
|
95
|
+
#
|
|
96
|
+
# See Test::Unit::Assertions
|
|
97
|
+
def ==(o)
|
|
98
|
+
return false unless self.kind_of? REXML::Element
|
|
99
|
+
if o.kind_of? REXML::Element
|
|
100
|
+
# Ok
|
|
101
|
+
elsif o.kind_of? String
|
|
102
|
+
# Parse o
|
|
103
|
+
begin
|
|
104
|
+
o = REXML::Document.new(o).root
|
|
105
|
+
rescue REXML::ParseException
|
|
106
|
+
return false
|
|
107
|
+
end
|
|
108
|
+
else
|
|
109
|
+
# Cannot compare with anything other than Elements or Strings
|
|
110
|
+
return false
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
return false unless name == o.name
|
|
114
|
+
|
|
115
|
+
attributes.each_attribute do |attr|
|
|
116
|
+
return false unless attr.value == o.attributes[attr.name]
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
o.attributes.each_attribute do |attr|
|
|
120
|
+
return false unless attributes[attr.name] == attr.value
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
children.each_with_index do |child,i|
|
|
124
|
+
return false unless child == o.children[i]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
return true
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
end # class Element
|
|
131
|
+
|
|
132
|
+
# FIXME : Is this still needed now that we're a bit past Ruby 1.8.3??
|
|
133
|
+
# Very dirty fix for the :progress problem in REXML from Ruby 1.8.3
|
|
134
|
+
# http://www.germane-software.com/projects/rexml/ticket/34
|
|
135
|
+
# the fix proposed in REXML changeset 1145 only fixes this for pipes, not for
|
|
136
|
+
# TCP sockets, so we have to keep this.
|
|
137
|
+
class IOSource
|
|
138
|
+
def position
|
|
139
|
+
0
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def current_line
|
|
143
|
+
[0, 0, ""]
|
|
144
|
+
end
|
|
145
|
+
end # class IOSource
|
|
146
|
+
|
|
147
|
+
end # module REXML
|
|
148
|
+
|
|
149
|
+
# Restore the old $VERBOSE setting
|
|
150
|
+
$VERBOSE = oldverbose
|
|
151
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
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/roster/iq/roster.rb'
|
|
6
|
+
require 'xmpp4r/roster/helper/roster.rb'
|
|
7
|
+
require 'xmpp4r/roster/x/roster.rb'
|
|
@@ -0,0 +1,519 @@
|
|
|
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 'thread'
|
|
7
|
+
require 'xmpp4r/roster/iq/roster'
|
|
8
|
+
|
|
9
|
+
module Jabber
|
|
10
|
+
module Roster
|
|
11
|
+
##
|
|
12
|
+
# The Roster helper intercepts <tt><iq/></tt> stanzas with Jabber::IqQueryRoster
|
|
13
|
+
# and <tt><presence/></tt> stanzas, but provides cbs which allow the programmer
|
|
14
|
+
# to keep track of updates.
|
|
15
|
+
#
|
|
16
|
+
# A thread for any received stanza is spawned, so the user can invoke
|
|
17
|
+
# accept_subscription et al in the callback blocks, without stopping
|
|
18
|
+
# the current (= parser) thread when waiting for a reply.
|
|
19
|
+
class Helper
|
|
20
|
+
##
|
|
21
|
+
# All items in your roster
|
|
22
|
+
# items:: [Hash] ([JID] => [Roster::Helper::RosterItem])
|
|
23
|
+
attr_reader :items
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# Initialize a new Roster helper
|
|
27
|
+
#
|
|
28
|
+
# Registers its cbs (prio = 120, ref = self)
|
|
29
|
+
#
|
|
30
|
+
# Request a roster
|
|
31
|
+
# (Remember to send initial presence afterwards!)
|
|
32
|
+
#
|
|
33
|
+
# The initialization will not wait for the roster being received,
|
|
34
|
+
# use wait_for_roster.
|
|
35
|
+
#
|
|
36
|
+
# <b>Attention:</b> If you send presence and receive presences
|
|
37
|
+
# before the roster has arrived, the Roster helper will let them
|
|
38
|
+
# pass through and does *not* keep them!
|
|
39
|
+
def initialize(stream)
|
|
40
|
+
@stream = stream
|
|
41
|
+
@items = {}
|
|
42
|
+
@items_lock = Mutex.new
|
|
43
|
+
@roster_wait = Semaphore.new
|
|
44
|
+
@query_cbs = CallbackList.new
|
|
45
|
+
@update_cbs = CallbackList.new
|
|
46
|
+
@presence_cbs = CallbackList.new
|
|
47
|
+
@subscription_cbs = CallbackList.new
|
|
48
|
+
@subscription_request_cbs = CallbackList.new
|
|
49
|
+
|
|
50
|
+
# Register cbs
|
|
51
|
+
stream.add_iq_callback(120, self) { |iq|
|
|
52
|
+
if iq.query.kind_of?(IqQueryRoster)
|
|
53
|
+
Thread.new do
|
|
54
|
+
Thread.current.abort_on_exception = true
|
|
55
|
+
handle_iq_query_roster(iq)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
true
|
|
59
|
+
else
|
|
60
|
+
false
|
|
61
|
+
end
|
|
62
|
+
}
|
|
63
|
+
stream.add_presence_callback(120, self) { |pres|
|
|
64
|
+
Thread.new do
|
|
65
|
+
Thread.current.abort_on_exception = true
|
|
66
|
+
handle_presence(pres)
|
|
67
|
+
end
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
# Request the roster
|
|
71
|
+
rosterget = Iq.new_rosterget
|
|
72
|
+
stream.send(rosterget)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
##
|
|
76
|
+
# Wait for first roster query result to arrive
|
|
77
|
+
def wait_for_roster
|
|
78
|
+
@roster_wait.wait
|
|
79
|
+
@roster_wait.run
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
##
|
|
83
|
+
# Add a callback to be called when a query has been processed
|
|
84
|
+
#
|
|
85
|
+
# Because update callbacks are called for each roster item,
|
|
86
|
+
# this may be appropriate to notify that *anything* has updated.
|
|
87
|
+
#
|
|
88
|
+
# Arguments for callback block: The received <tt><iq/></tt> stanza
|
|
89
|
+
def add_query_callback(prio = 0, ref = nil, &block)
|
|
90
|
+
@query_cbs.add(prio, ref, block)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
##
|
|
94
|
+
# Add a callback for Jabber::Roster::Helper::RosterItem updates
|
|
95
|
+
#
|
|
96
|
+
# Note that this will be called much after initialization
|
|
97
|
+
# for the answer of the initial roster request
|
|
98
|
+
#
|
|
99
|
+
# The block receives two objects:
|
|
100
|
+
# * the old Jabber::Roster::Helper::RosterItem
|
|
101
|
+
# * the new Jabber::Roster::Helper::RosterItem
|
|
102
|
+
def add_update_callback(prio = 0, ref = nil, &block)
|
|
103
|
+
@update_cbs.add(prio, ref, block)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
##
|
|
107
|
+
# Add a callback for Jabber::Presence updates
|
|
108
|
+
#
|
|
109
|
+
# This will be called for <tt><presence/></tt> stanzas for known RosterItems.
|
|
110
|
+
# Unknown JIDs may still pass and can be caught via Jabber::Stream#add_presence_callback.
|
|
111
|
+
#
|
|
112
|
+
# The block receives three objects:
|
|
113
|
+
# * the Jabber::Roster::Helper::RosterItem
|
|
114
|
+
# * the old Jabber::Presence (or nil)
|
|
115
|
+
# * the new Jabber::Presence (or nil)
|
|
116
|
+
def add_presence_callback(prio = 0, ref = nil, &block)
|
|
117
|
+
@presence_cbs.add(prio, ref, block)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
##
|
|
121
|
+
# Add a callback for subscription updates,
|
|
122
|
+
# which will be called upon receiving a <tt><presence/></tt> stanza
|
|
123
|
+
# with type:
|
|
124
|
+
# * :subscribed
|
|
125
|
+
# * :unsubscribe
|
|
126
|
+
# * :unsubscribed
|
|
127
|
+
#
|
|
128
|
+
# The block receives two objects:
|
|
129
|
+
# * the Jabber::Roster::Helper::RosterItem (or nil)
|
|
130
|
+
# * the <tt><presence/></tt> stanza
|
|
131
|
+
def add_subscription_callback(prio = 0, ref = nil, &block)
|
|
132
|
+
@subscription_cbs.add(prio, ref, block)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
##
|
|
136
|
+
# Add a callback for subscription requests,
|
|
137
|
+
# which will be called upon receiving a <tt><presence type='subscribe'/></tt> stanza
|
|
138
|
+
#
|
|
139
|
+
# The block receives two objects:
|
|
140
|
+
# * the Jabber::Roster::Helper::RosterItem (or nil)
|
|
141
|
+
# * the <tt><presence/></tt> stanza
|
|
142
|
+
#
|
|
143
|
+
# Response to this event can be taken with accept_subscription
|
|
144
|
+
# and decline_subscription.
|
|
145
|
+
#
|
|
146
|
+
# Example usage:
|
|
147
|
+
# my_roster.add_subscription_request_callback do |item,presence|
|
|
148
|
+
# if accept_subscription_requests
|
|
149
|
+
# my_roster.accept_subscription(presence.from)
|
|
150
|
+
# else
|
|
151
|
+
# my_roster.decline_subscription(presence.from)
|
|
152
|
+
# end
|
|
153
|
+
# end
|
|
154
|
+
def add_subscription_request_callback(prio = 0, ref = nil, &block)
|
|
155
|
+
@subscription_request_cbs.add(prio, ref, block)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
private
|
|
159
|
+
|
|
160
|
+
##
|
|
161
|
+
# Handle received <tt><iq/></tt> stanzas,
|
|
162
|
+
# used internally
|
|
163
|
+
def handle_iq_query_roster(iq)
|
|
164
|
+
# If the <iq/> contains <error/> we just ignore that
|
|
165
|
+
# and assume an empty roster
|
|
166
|
+
iq.query.each_element('item') do |item|
|
|
167
|
+
olditem, newitem = nil, nil
|
|
168
|
+
|
|
169
|
+
@items_lock.synchronize {
|
|
170
|
+
olditem = @items[item.jid]
|
|
171
|
+
|
|
172
|
+
# Handle deletion of item
|
|
173
|
+
if item.subscription == :remove
|
|
174
|
+
@items.delete(item.jid)
|
|
175
|
+
else
|
|
176
|
+
newitem = @items[item.jid] = RosterItem.new(@stream).import(item)
|
|
177
|
+
end
|
|
178
|
+
}
|
|
179
|
+
@update_cbs.process(olditem, newitem)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
@roster_wait.run
|
|
183
|
+
@query_cbs.process(iq)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
##
|
|
187
|
+
# Handle received <tt><presence/></tt> stanzas,
|
|
188
|
+
# used internally
|
|
189
|
+
def handle_presence(pres)
|
|
190
|
+
item = self[pres.from]
|
|
191
|
+
|
|
192
|
+
if [:subscribed, :unsubscribe, :unsubscribed].include?(pres.type)
|
|
193
|
+
@subscription_cbs.process(item, pres)
|
|
194
|
+
true
|
|
195
|
+
|
|
196
|
+
elsif pres.type == :subscribe
|
|
197
|
+
@subscription_request_cbs.process(item, pres)
|
|
198
|
+
true
|
|
199
|
+
|
|
200
|
+
else
|
|
201
|
+
unless item.nil?
|
|
202
|
+
update_presence(item, pres)
|
|
203
|
+
true # Callback consumed stanza
|
|
204
|
+
else
|
|
205
|
+
false # Callback did not consume stanza
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
##
|
|
211
|
+
# Update the presence of an item,
|
|
212
|
+
# used internally
|
|
213
|
+
#
|
|
214
|
+
# Callbacks are called here
|
|
215
|
+
def update_presence(item, pres)
|
|
216
|
+
|
|
217
|
+
# This requires special handling, to announce all resources offline
|
|
218
|
+
if pres.from.resource.nil? and pres.type == :error
|
|
219
|
+
oldpresences = []
|
|
220
|
+
item.each_presence do |oldpres|
|
|
221
|
+
oldpresences << oldpres
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
item.add_presence(pres)
|
|
225
|
+
oldpresences.each { |oldpres|
|
|
226
|
+
@presence_cbs.process(item, oldpres, pres)
|
|
227
|
+
}
|
|
228
|
+
else
|
|
229
|
+
oldpres = item.presence(pres.from).nil? ?
|
|
230
|
+
nil :
|
|
231
|
+
Presence.new.import(item.presence(pres.from))
|
|
232
|
+
|
|
233
|
+
item.add_presence(pres)
|
|
234
|
+
@presence_cbs.process(item, oldpres, pres)
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
public
|
|
239
|
+
|
|
240
|
+
##
|
|
241
|
+
# Get an item by jid
|
|
242
|
+
#
|
|
243
|
+
# If not available tries to look for it with the resource stripped
|
|
244
|
+
def [](jid)
|
|
245
|
+
jid = JID.new(jid) unless jid.kind_of? JID
|
|
246
|
+
|
|
247
|
+
@items_lock.synchronize {
|
|
248
|
+
if @items.has_key?(jid)
|
|
249
|
+
@items[jid]
|
|
250
|
+
elsif @items.has_key?(jid.strip)
|
|
251
|
+
@items[jid.strip]
|
|
252
|
+
else
|
|
253
|
+
nil
|
|
254
|
+
end
|
|
255
|
+
}
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
##
|
|
259
|
+
# Returns the list of RosterItems which, stripped, are equal to the
|
|
260
|
+
# one you are looking for.
|
|
261
|
+
def find(jid)
|
|
262
|
+
jid = JID.new(jid) unless jid.kind_of? JID
|
|
263
|
+
|
|
264
|
+
j = jid.strip
|
|
265
|
+
l = {}
|
|
266
|
+
@items_lock.synchronize {
|
|
267
|
+
@items.each_pair do |k, v|
|
|
268
|
+
l[k] = v if k.strip == j
|
|
269
|
+
end
|
|
270
|
+
}
|
|
271
|
+
l
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
##
|
|
275
|
+
# Groups in this Roster,
|
|
276
|
+
# sorted by name
|
|
277
|
+
#
|
|
278
|
+
# Contains +nil+ if there are ungrouped items
|
|
279
|
+
# result:: [Array] containing group names (String)
|
|
280
|
+
def groups
|
|
281
|
+
res = []
|
|
282
|
+
@items_lock.synchronize {
|
|
283
|
+
@items.each_pair do |jid,item|
|
|
284
|
+
res += item.groups
|
|
285
|
+
res += [nil] if item.groups == []
|
|
286
|
+
end
|
|
287
|
+
}
|
|
288
|
+
res.uniq.sort { |a,b| a.to_s <=> b.to_s }
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
##
|
|
292
|
+
# Get items in a group
|
|
293
|
+
#
|
|
294
|
+
# When group is nil, return ungrouped items
|
|
295
|
+
# group:: [String] Group name
|
|
296
|
+
# result:: Array of [RosterItem]
|
|
297
|
+
def find_by_group(group)
|
|
298
|
+
res = []
|
|
299
|
+
@items_lock.synchronize {
|
|
300
|
+
@items.each_pair do |jid,item|
|
|
301
|
+
res.push(item) if item.groups.include?(group)
|
|
302
|
+
res.push(item) if item.groups == [] and group.nil?
|
|
303
|
+
end
|
|
304
|
+
}
|
|
305
|
+
res
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
##
|
|
309
|
+
# Add a user to your roster
|
|
310
|
+
#
|
|
311
|
+
# Threading is encouraged as the function waits for
|
|
312
|
+
# a result. ServerError is thrown upon error.
|
|
313
|
+
#
|
|
314
|
+
# See Jabber::Roster::Helper::RosterItem#subscribe for details
|
|
315
|
+
# about subscribing. (This method isn't used here but the
|
|
316
|
+
# same functionality applies.)
|
|
317
|
+
#
|
|
318
|
+
# If the item is already in the local roster
|
|
319
|
+
# it will simply send itself
|
|
320
|
+
# jid:: [JID] to add
|
|
321
|
+
# iname:: [String] Optional item name
|
|
322
|
+
# subscribe:: [Boolean] Whether to subscribe to this jid
|
|
323
|
+
def add(jid, iname=nil, subscribe=false)
|
|
324
|
+
if self[jid]
|
|
325
|
+
self[jid].send
|
|
326
|
+
else
|
|
327
|
+
request = Iq.new_rosterset
|
|
328
|
+
request.query.add(Jabber::Roster::RosterItem.new(jid, iname))
|
|
329
|
+
@stream.send_with_id(request)
|
|
330
|
+
# Adding to list is handled by handle_iq_query_roster
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
if subscribe
|
|
334
|
+
# Actually the item *should* already be known now,
|
|
335
|
+
# but we do it manually to exclude conditions.
|
|
336
|
+
pres = Presence.new.set_type(:subscribe).set_to(jid.strip)
|
|
337
|
+
@stream.send(pres)
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
##
|
|
342
|
+
# Accept a subscription request
|
|
343
|
+
# * Sends a <presence type='subscribed'/> stanza
|
|
344
|
+
# * Adds the contact to your roster
|
|
345
|
+
# jid:: [JID] of contact
|
|
346
|
+
# iname:: [String] Optional roster item name
|
|
347
|
+
def accept_subscription(jid, iname=nil)
|
|
348
|
+
pres = Presence.new.set_type(:subscribed).set_to(jid.strip)
|
|
349
|
+
@stream.send(pres)
|
|
350
|
+
|
|
351
|
+
unless self[jid.strip]
|
|
352
|
+
request = Iq.new_rosterset
|
|
353
|
+
request.query.add(Jabber::Roster::RosterItem.new(jid.strip, iname))
|
|
354
|
+
@stream.send_with_id(request)
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
##
|
|
359
|
+
# Decline a subscription request
|
|
360
|
+
# * Sends a <presence type='unsubscribed'/> stanza
|
|
361
|
+
def decline_subscription(jid)
|
|
362
|
+
pres = Presence.new.set_type(:unsubscribed).set_to(jid.strip)
|
|
363
|
+
@stream.send(pres)
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
##
|
|
367
|
+
# These are extensions to RosterItem to carry presence information.
|
|
368
|
+
# This information is *not* stored in XML!
|
|
369
|
+
class RosterItem < Jabber::Roster::RosterItem
|
|
370
|
+
##
|
|
371
|
+
# Tracked (online) presences of this RosterItem
|
|
372
|
+
attr_reader :presences
|
|
373
|
+
|
|
374
|
+
##
|
|
375
|
+
# Initialize an empty RosterItem
|
|
376
|
+
def initialize(stream)
|
|
377
|
+
super()
|
|
378
|
+
@stream = stream
|
|
379
|
+
@presences = []
|
|
380
|
+
@presences_lock = Mutex.new
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
##
|
|
384
|
+
# Send the updated RosterItem to the server,
|
|
385
|
+
# i.e. if you modified iname, groups, ...
|
|
386
|
+
def send
|
|
387
|
+
request = Iq.new_rosterset
|
|
388
|
+
request.query.add(self)
|
|
389
|
+
@stream.send(request)
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
##
|
|
393
|
+
# Remove item
|
|
394
|
+
#
|
|
395
|
+
# This cancels both subscription *from* the contact to you
|
|
396
|
+
# and from you *to* the contact.
|
|
397
|
+
#
|
|
398
|
+
# The methods waits for a roster push from the server (success)
|
|
399
|
+
# or throws ServerError upon failure.
|
|
400
|
+
def remove
|
|
401
|
+
request = Iq.new_rosterset
|
|
402
|
+
request.query.add(Jabber::Roster::RosterItem.new(jid, nil, :remove))
|
|
403
|
+
@stream.send_with_id(request)
|
|
404
|
+
# Removing from list is handled by Roster#handle_iq_query_roster
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
##
|
|
408
|
+
# Is any presence of this person on-line?
|
|
409
|
+
#
|
|
410
|
+
# (Or is there any presence? Unavailable presences are
|
|
411
|
+
# deleted.)
|
|
412
|
+
def online?
|
|
413
|
+
@presences_lock.synchronize {
|
|
414
|
+
@presences.select { |pres|
|
|
415
|
+
pres.type.nil?
|
|
416
|
+
}.size > 0
|
|
417
|
+
}
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
##
|
|
421
|
+
# Iterate through all received <tt><presence/></tt> stanzas
|
|
422
|
+
def each_presence(&block)
|
|
423
|
+
# Don't lock here, we don't know what block does...
|
|
424
|
+
@presences.each { |pres|
|
|
425
|
+
yield(pres)
|
|
426
|
+
}
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
##
|
|
430
|
+
# Get specific presence
|
|
431
|
+
# jid:: [JID] Full JID
|
|
432
|
+
def presence(jid)
|
|
433
|
+
@presences_lock.synchronize {
|
|
434
|
+
@presences.each { |pres|
|
|
435
|
+
return(pres) if pres.from == jid
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
nil
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
##
|
|
442
|
+
# Add presence and sort presences
|
|
443
|
+
# (unless type is :unavailable or :error)
|
|
444
|
+
#
|
|
445
|
+
# This overwrites previous stanzas with the same destination
|
|
446
|
+
# JID to keep track of resources. Presence stanzas with
|
|
447
|
+
# <tt>type == :unavailable</tt> or <tt>type == :error</tt> will
|
|
448
|
+
# be deleted as this indicates that this resource has gone
|
|
449
|
+
# offline.
|
|
450
|
+
#
|
|
451
|
+
# If <tt>type == :error</tt> and the presence's origin has no
|
|
452
|
+
# specific resource the contact is treated completely offline.
|
|
453
|
+
def add_presence(newpres)
|
|
454
|
+
@presences_lock.synchronize {
|
|
455
|
+
# Delete old presences with the same JID
|
|
456
|
+
@presences.delete_if do |pres|
|
|
457
|
+
pres.from == newpres.from or pres.from.resource.nil?
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
if newpres.type == :error and newpres.from.resource.nil?
|
|
461
|
+
# Replace by single error presence
|
|
462
|
+
@presences = [newpres]
|
|
463
|
+
else
|
|
464
|
+
# Add new presence
|
|
465
|
+
@presences.push(newpres)
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
@presences.sort!
|
|
469
|
+
}
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
##
|
|
473
|
+
# Send subscription request to the user
|
|
474
|
+
#
|
|
475
|
+
# The block given to Jabber::Roster::Roster#add_update_callback will
|
|
476
|
+
# be called, carrying the RosterItem with ask="subscribe"
|
|
477
|
+
#
|
|
478
|
+
# This function returns immediately after sending the subscription
|
|
479
|
+
# request and will not wait of approval or declination as it may
|
|
480
|
+
# take months for the contact to decide. ;-)
|
|
481
|
+
def subscribe
|
|
482
|
+
pres = Presence.new.set_type(:subscribe).set_to(jid.strip)
|
|
483
|
+
@stream.send(pres)
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
##
|
|
487
|
+
# Unsubscribe from a contact's presence
|
|
488
|
+
#
|
|
489
|
+
# This method waits for a presence with type='unsubscribed'
|
|
490
|
+
# from the contact. It may throw ServerError upon failure.
|
|
491
|
+
#
|
|
492
|
+
# subscription attribute of the item is *from* or *none*
|
|
493
|
+
# afterwards. As long as you don't remove that item and
|
|
494
|
+
# subscription='from' the contact is subscribed to your
|
|
495
|
+
# presence.
|
|
496
|
+
def unsubscribe
|
|
497
|
+
pres = Presence.new.set_type(:unsubscribe).set_to(jid.strip)
|
|
498
|
+
@stream.send(pres) { |answer|
|
|
499
|
+
answer.type == :unsubscribed and
|
|
500
|
+
answer.from.strip == pres.to
|
|
501
|
+
}
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
##
|
|
505
|
+
# Deny the contact to see your presence.
|
|
506
|
+
#
|
|
507
|
+
# This method will not wait and returns immediately
|
|
508
|
+
# as you will need no confirmation for this action.
|
|
509
|
+
#
|
|
510
|
+
# Though, you will get a roster update for that item,
|
|
511
|
+
# carrying either subscription='to' or 'none'.
|
|
512
|
+
def cancel_subscription
|
|
513
|
+
pres = Presence.new.set_type(:unsubscribed).set_to(jid)
|
|
514
|
+
@stream.send(pres)
|
|
515
|
+
end
|
|
516
|
+
end
|
|
517
|
+
end #Class Roster
|
|
518
|
+
end #Module Roster
|
|
519
|
+
end #Module Jabber
|