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.
Files changed (290) hide show
  1. data/Authors.txt +4 -0
  2. data/Changelog.txt +11 -0
  3. data/Copyright.txt +16 -0
  4. data/Rakefile +16 -25
  5. data/Readme.markdown +1 -3
  6. data/bin/cerberus +5 -0
  7. data/lib/cerberus/builder/bjam.rb +1 -3
  8. data/lib/cerberus/builder/maven2.rb +0 -1
  9. data/lib/cerberus/builder/rake.rb +1 -1
  10. data/lib/cerberus/builder/rspec.rb +0 -1
  11. data/lib/cerberus/builder/ruby_base.rb +0 -1
  12. data/lib/cerberus/component_lazy_loader.rb +6 -2
  13. data/lib/cerberus/config.example.yml +1 -0
  14. data/lib/cerberus/constants.rb +2 -2
  15. data/lib/cerberus/manager.rb +7 -1
  16. data/lib/cerberus/publisher/mail.rb +4 -4
  17. data/lib/cerberus/publisher/twitter.rb +0 -1
  18. data/lib/cerberus/scm/base.rb +19 -0
  19. data/lib/cerberus/scm/bzr.rb +62 -0
  20. data/lib/cerberus/scm/cvs.rb +2 -7
  21. data/lib/cerberus/scm/darcs.rb +2 -11
  22. data/lib/cerberus/scm/git.rb +6 -14
  23. data/lib/cerberus/scm/perforce.rb +4 -4
  24. data/lib/cerberus/scm/svn.rb +2 -7
  25. data/lib/cerberus/utils.rb +5 -0
  26. data/lib/vendor/irc/README +23 -0
  27. data/lib/vendor/irc/lib/IRC.rb +164 -0
  28. data/lib/vendor/irc/lib/IRCChannel.rb +33 -0
  29. data/lib/vendor/irc/lib/IRCConnection.rb +134 -0
  30. data/lib/vendor/irc/lib/IRCEvent.rb +91 -0
  31. data/lib/vendor/irc/lib/IRCUser.rb +23 -0
  32. data/lib/vendor/irc/lib/IRCUtil.rb +49 -0
  33. data/lib/vendor/irc/lib/eventmap.yml +247 -0
  34. data/lib/vendor/twitter/CHANGES +129 -0
  35. data/lib/vendor/twitter/MIT-LICENSE +20 -0
  36. data/lib/vendor/twitter/README +37 -0
  37. data/lib/vendor/twitter/TODO +7 -0
  38. data/lib/vendor/twitter/lib/twitter.rb +34 -0
  39. data/lib/vendor/twitter/lib/twitter/client.rb +24 -0
  40. data/lib/vendor/twitter/lib/twitter/client/account.rb +24 -0
  41. data/lib/vendor/twitter/lib/twitter/client/auth.rb +27 -0
  42. data/lib/vendor/twitter/lib/twitter/client/base.rb +93 -0
  43. data/lib/vendor/twitter/lib/twitter/client/blocks.rb +35 -0
  44. data/lib/vendor/twitter/lib/twitter/client/favorites.rb +53 -0
  45. data/lib/vendor/twitter/lib/twitter/client/friendship.rb +35 -0
  46. data/lib/vendor/twitter/lib/twitter/client/graph.rb +37 -0
  47. data/lib/vendor/twitter/lib/twitter/client/messaging.rb +79 -0
  48. data/lib/vendor/twitter/lib/twitter/client/profile.rb +29 -0
  49. data/lib/vendor/twitter/lib/twitter/client/search.rb +27 -0
  50. data/lib/vendor/twitter/lib/twitter/client/status.rb +51 -0
  51. data/lib/vendor/twitter/lib/twitter/client/timeline.rb +72 -0
  52. data/lib/vendor/twitter/lib/twitter/client/user.rb +65 -0
  53. data/lib/vendor/twitter/lib/twitter/config.rb +77 -0
  54. data/lib/vendor/twitter/lib/twitter/console.rb +31 -0
  55. data/lib/vendor/twitter/lib/twitter/core.rb +137 -0
  56. data/lib/vendor/twitter/lib/twitter/ext.rb +2 -0
  57. data/lib/vendor/twitter/lib/twitter/ext/stdlib.rb +52 -0
  58. data/lib/vendor/twitter/lib/twitter/extras.rb +39 -0
  59. data/lib/vendor/twitter/lib/twitter/meta.rb +56 -0
  60. data/lib/vendor/twitter/lib/twitter/model.rb +360 -0
  61. data/lib/vendor/twitter/lib/twitter/version.rb +19 -0
  62. data/lib/vendor/twitter/spec/twitter/client/account_spec.rb +28 -0
  63. data/lib/vendor/twitter/spec/twitter/client/auth_spec.rb +34 -0
  64. data/lib/vendor/twitter/spec/twitter/client/base_spec.rb +242 -0
  65. data/lib/vendor/twitter/spec/twitter/client/blocks_spec.rb +76 -0
  66. data/lib/vendor/twitter/spec/twitter/client/favorites_spec.rb +183 -0
  67. data/lib/vendor/twitter/spec/twitter/client/friendship_spec.rb +76 -0
  68. data/lib/vendor/twitter/spec/twitter/client/graph_spec.rb +67 -0
  69. data/lib/vendor/twitter/spec/twitter/client/messaging_spec.rb +135 -0
  70. data/lib/vendor/twitter/spec/twitter/client/profile_spec.rb +91 -0
  71. data/lib/vendor/twitter/spec/twitter/client/search_spec.rb +68 -0
  72. data/lib/vendor/twitter/spec/twitter/client/status_spec.rb +119 -0
  73. data/lib/vendor/twitter/spec/twitter/client/timeline_spec.rb +79 -0
  74. data/lib/vendor/twitter/spec/twitter/client/user_spec.rb +203 -0
  75. data/lib/vendor/twitter/spec/twitter/client_spec.rb +2 -0
  76. data/lib/vendor/twitter/spec/twitter/config_spec.rb +86 -0
  77. data/lib/vendor/twitter/spec/twitter/console_spec.rb +15 -0
  78. data/lib/vendor/twitter/spec/twitter/core_spec.rb +127 -0
  79. data/lib/vendor/twitter/spec/twitter/ext/stdlib_spec.rb +59 -0
  80. data/lib/vendor/twitter/spec/twitter/extras_spec.rb +46 -0
  81. data/lib/vendor/twitter/spec/twitter/meta_spec.rb +90 -0
  82. data/lib/vendor/twitter/spec/twitter/model_spec.rb +508 -0
  83. data/lib/vendor/twitter/spec/twitter/version_spec.rb +19 -0
  84. data/lib/vendor/xmpp4r/CHANGELOG +83 -0
  85. data/lib/vendor/xmpp4r/COPYING +340 -0
  86. data/lib/vendor/xmpp4r/LICENSE +59 -0
  87. data/lib/vendor/xmpp4r/README.rdoc +110 -0
  88. data/lib/vendor/xmpp4r/README_ruby19.txt +43 -0
  89. data/lib/vendor/xmpp4r/Rakefile +262 -0
  90. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/adventure/README +56 -0
  91. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/adventure/adventure.rb +23 -0
  92. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/adventure/adventuremuc.rb +136 -0
  93. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/adventure/cube.xml +15 -0
  94. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/adventure/tower.xml +69 -0
  95. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/adventure/world.rb +424 -0
  96. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/fileserve.conf +11 -0
  97. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/fileserve.rb +346 -0
  98. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/getonline.rb +56 -0
  99. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/gtkmucclient.rb +315 -0
  100. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/migrate.rb +88 -0
  101. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/minimuc.rb +266 -0
  102. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/pep-aggregator/index.xsl +235 -0
  103. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/pep-aggregator/pep-aggregator.rb +147 -0
  104. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/recvfile.rb +84 -0
  105. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/rosterdiscovery.rb +129 -0
  106. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/sendfile.conf +10 -0
  107. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/sendfile.rb +72 -0
  108. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr.rb +51 -0
  109. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_jabber.rb +43 -0
  110. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_test.rb +10 -0
  111. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/versionpoll.rb +90 -0
  112. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/xmpping.rb +146 -0
  113. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/advanced/xmppingrc.sample +14 -0
  114. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/change_password.rb +41 -0
  115. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/client.rb +70 -0
  116. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/component.rb +11 -0
  117. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/echo.rb +37 -0
  118. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/jabbersend.rb +41 -0
  119. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/mass_sender.rb +68 -0
  120. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/muc_owner_config.rb +12 -0
  121. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/mucinfo.rb +41 -0
  122. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/mucsimplebot.rb +82 -0
  123. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/register.rb +42 -0
  124. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/remove_registration.rb +18 -0
  125. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/roster.rb +44 -0
  126. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/rosterprint.rb +50 -0
  127. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/rosterrename.rb +34 -0
  128. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/rosterwatch.rb +171 -0
  129. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/send_vcard.rb +67 -0
  130. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/tune_client.rb +56 -0
  131. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/tune_server.rb +58 -0
  132. data/lib/vendor/xmpp4r/data/doc/xmpp4r/examples/basic/versionbot.rb +75 -0
  133. data/lib/vendor/xmpp4r/lib/xmpp4r.rb +116 -0
  134. data/lib/vendor/xmpp4r/lib/xmpp4r/base64.rb +32 -0
  135. data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams.rb +15 -0
  136. data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/filetransfer.rb +319 -0
  137. data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/ibb/base.rb +257 -0
  138. data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/ibb/initiator.rb +31 -0
  139. data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/ibb/target.rb +47 -0
  140. data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb +152 -0
  141. data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb +86 -0
  142. data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb +198 -0
  143. data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb +65 -0
  144. data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb +73 -0
  145. data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb.orig +62 -0
  146. data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/iq/bytestreams.rb +170 -0
  147. data/lib/vendor/xmpp4r/lib/xmpp4r/bytestreams/iq/si.rb +206 -0
  148. data/lib/vendor/xmpp4r/lib/xmpp4r/callbacks.rb +124 -0
  149. data/lib/vendor/xmpp4r/lib/xmpp4r/caps.rb +1 -0
  150. data/lib/vendor/xmpp4r/lib/xmpp4r/caps/c.rb +53 -0
  151. data/lib/vendor/xmpp4r/lib/xmpp4r/caps/helper/generator.rb +160 -0
  152. data/lib/vendor/xmpp4r/lib/xmpp4r/caps/helper/helper.rb +87 -0
  153. data/lib/vendor/xmpp4r/lib/xmpp4r/client.rb +317 -0
  154. data/lib/vendor/xmpp4r/lib/xmpp4r/command/helper/responder.rb +53 -0
  155. data/lib/vendor/xmpp4r/lib/xmpp4r/command/iq/command.rb +154 -0
  156. data/lib/vendor/xmpp4r/lib/xmpp4r/component.rb +103 -0
  157. data/lib/vendor/xmpp4r/lib/xmpp4r/connection.rb +219 -0
  158. data/lib/vendor/xmpp4r/lib/xmpp4r/dataforms.rb +5 -0
  159. data/lib/vendor/xmpp4r/lib/xmpp4r/dataforms/x/data.rb +297 -0
  160. data/lib/vendor/xmpp4r/lib/xmpp4r/debuglog.rb +42 -0
  161. data/lib/vendor/xmpp4r/lib/xmpp4r/delay.rb +5 -0
  162. data/lib/vendor/xmpp4r/lib/xmpp4r/delay/x/delay.rb +99 -0
  163. data/lib/vendor/xmpp4r/lib/xmpp4r/discovery.rb +7 -0
  164. data/lib/vendor/xmpp4r/lib/xmpp4r/discovery/helper/responder.rb +165 -0
  165. data/lib/vendor/xmpp4r/lib/xmpp4r/discovery/iq/discoinfo.rb +211 -0
  166. data/lib/vendor/xmpp4r/lib/xmpp4r/discovery/iq/discoitems.rb +147 -0
  167. data/lib/vendor/xmpp4r/lib/xmpp4r/errors.rb +281 -0
  168. data/lib/vendor/xmpp4r/lib/xmpp4r/feature_negotiation.rb +5 -0
  169. data/lib/vendor/xmpp4r/lib/xmpp4r/feature_negotiation/iq/feature.rb +28 -0
  170. data/lib/vendor/xmpp4r/lib/xmpp4r/framework/base.rb +55 -0
  171. data/lib/vendor/xmpp4r/lib/xmpp4r/framework/bot.rb +148 -0
  172. data/lib/vendor/xmpp4r/lib/xmpp4r/httpbinding.rb +5 -0
  173. data/lib/vendor/xmpp4r/lib/xmpp4r/httpbinding/client.rb +285 -0
  174. data/lib/vendor/xmpp4r/lib/xmpp4r/idgenerator.rb +37 -0
  175. data/lib/vendor/xmpp4r/lib/xmpp4r/iq.rb +221 -0
  176. data/lib/vendor/xmpp4r/lib/xmpp4r/jid.rb +167 -0
  177. data/lib/vendor/xmpp4r/lib/xmpp4r/message.rb +148 -0
  178. data/lib/vendor/xmpp4r/lib/xmpp4r/muc.rb +14 -0
  179. data/lib/vendor/xmpp4r/lib/xmpp4r/muc/helper/mucbrowser.rb +92 -0
  180. data/lib/vendor/xmpp4r/lib/xmpp4r/muc/helper/mucclient.rb +462 -0
  181. data/lib/vendor/xmpp4r/lib/xmpp4r/muc/helper/simplemucclient.rb +332 -0
  182. data/lib/vendor/xmpp4r/lib/xmpp4r/muc/iq/mucadmin.rb +23 -0
  183. data/lib/vendor/xmpp4r/lib/xmpp4r/muc/iq/mucadminitem.rb +20 -0
  184. data/lib/vendor/xmpp4r/lib/xmpp4r/muc/iq/mucowner.rb +15 -0
  185. data/lib/vendor/xmpp4r/lib/xmpp4r/muc/item.rb +143 -0
  186. data/lib/vendor/xmpp4r/lib/xmpp4r/muc/x/muc.rb +70 -0
  187. data/lib/vendor/xmpp4r/lib/xmpp4r/muc/x/mucuserinvite.rb +60 -0
  188. data/lib/vendor/xmpp4r/lib/xmpp4r/muc/x/mucuseritem.rb +36 -0
  189. data/lib/vendor/xmpp4r/lib/xmpp4r/presence.rb +232 -0
  190. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub.rb +8 -0
  191. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/configuration.rb +86 -0
  192. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/event.rb +49 -0
  193. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/item.rb +35 -0
  194. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/items.rb +44 -0
  195. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/node_config.rb +48 -0
  196. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/publish.rb +24 -0
  197. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/subscription.rb +62 -0
  198. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/subscription_config.rb +67 -0
  199. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/children/unsubscribe.rb +48 -0
  200. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/helper/nodebrowser.rb +130 -0
  201. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/helper/nodehelper.rb +156 -0
  202. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/helper/servicehelper.rb +417 -0
  203. data/lib/vendor/xmpp4r/lib/xmpp4r/pubsub/iq/pubsub.rb +19 -0
  204. data/lib/vendor/xmpp4r/lib/xmpp4r/query.rb +15 -0
  205. data/lib/vendor/xmpp4r/lib/xmpp4r/rexmladdons.rb +151 -0
  206. data/lib/vendor/xmpp4r/lib/xmpp4r/roster.rb +7 -0
  207. data/lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb +519 -0
  208. data/lib/vendor/xmpp4r/lib/xmpp4r/roster/iq/roster.rb +215 -0
  209. data/lib/vendor/xmpp4r/lib/xmpp4r/roster/x/roster.rb +138 -0
  210. data/lib/vendor/xmpp4r/lib/xmpp4r/rpc.rb +2 -0
  211. data/lib/vendor/xmpp4r/lib/xmpp4r/rpc/helper/client.rb +123 -0
  212. data/lib/vendor/xmpp4r/lib/xmpp4r/rpc/helper/server.rb +74 -0
  213. data/lib/vendor/xmpp4r/lib/xmpp4r/rpc/helper/xmlrpcaddons.rb +67 -0
  214. data/lib/vendor/xmpp4r/lib/xmpp4r/rpc/iq/rpc.rb +23 -0
  215. data/lib/vendor/xmpp4r/lib/xmpp4r/sasl.rb +237 -0
  216. data/lib/vendor/xmpp4r/lib/xmpp4r/semaphore.rb +38 -0
  217. data/lib/vendor/xmpp4r/lib/xmpp4r/stream.rb +497 -0
  218. data/lib/vendor/xmpp4r/lib/xmpp4r/streamparser.rb +77 -0
  219. data/lib/vendor/xmpp4r/lib/xmpp4r/tune.rb +2 -0
  220. data/lib/vendor/xmpp4r/lib/xmpp4r/tune/helper/helper.rb +58 -0
  221. data/lib/vendor/xmpp4r/lib/xmpp4r/tune/tune.rb +113 -0
  222. data/lib/vendor/xmpp4r/lib/xmpp4r/vcard.rb +6 -0
  223. data/lib/vendor/xmpp4r/lib/xmpp4r/vcard/helper/vcard.rb +84 -0
  224. data/lib/vendor/xmpp4r/lib/xmpp4r/vcard/iq/vcard.rb +109 -0
  225. data/lib/vendor/xmpp4r/lib/xmpp4r/version.rb +7 -0
  226. data/lib/vendor/xmpp4r/lib/xmpp4r/version/helper/responder.rb +72 -0
  227. data/lib/vendor/xmpp4r/lib/xmpp4r/version/helper/simpleresponder.rb +44 -0
  228. data/lib/vendor/xmpp4r/lib/xmpp4r/version/iq/version.rb +105 -0
  229. data/lib/vendor/xmpp4r/lib/xmpp4r/x.rb +37 -0
  230. data/lib/vendor/xmpp4r/lib/xmpp4r/xhtml.rb +1 -0
  231. data/lib/vendor/xmpp4r/lib/xmpp4r/xhtml/html.rb +115 -0
  232. data/lib/vendor/xmpp4r/lib/xmpp4r/xmpp4r.rb +18 -0
  233. data/lib/vendor/xmpp4r/lib/xmpp4r/xmppelement.rb +168 -0
  234. data/lib/vendor/xmpp4r/lib/xmpp4r/xmppstanza.rb +162 -0
  235. data/lib/vendor/xmpp4r/setup.rb +1586 -0
  236. data/lib/vendor/xmpp4r/test/bytestreams/tc_ibb.rb +186 -0
  237. data/lib/vendor/xmpp4r/test/bytestreams/tc_socks5bytestreams.rb +113 -0
  238. data/lib/vendor/xmpp4r/test/caps/tc_helper.rb +156 -0
  239. data/lib/vendor/xmpp4r/test/dataforms/tc_data.rb +81 -0
  240. data/lib/vendor/xmpp4r/test/delay/tc_xdelay.rb +51 -0
  241. data/lib/vendor/xmpp4r/test/discovery/tc_responder.rb +91 -0
  242. data/lib/vendor/xmpp4r/test/lib/assert_equal_xml.rb +14 -0
  243. data/lib/vendor/xmpp4r/test/lib/clienttester.rb +120 -0
  244. data/lib/vendor/xmpp4r/test/muc/tc_muc_mucclient.rb +830 -0
  245. data/lib/vendor/xmpp4r/test/muc/tc_muc_simplemucclient.rb +114 -0
  246. data/lib/vendor/xmpp4r/test/muc/tc_mucowner.rb +50 -0
  247. data/lib/vendor/xmpp4r/test/pubsub/tc_helper.rb +662 -0
  248. data/lib/vendor/xmpp4r/test/pubsub/tc_nodeconfig.rb +54 -0
  249. data/lib/vendor/xmpp4r/test/pubsub/tc_subscriptionconfig.rb +41 -0
  250. data/lib/vendor/xmpp4r/test/roster/tc_helper.rb +514 -0
  251. data/lib/vendor/xmpp4r/test/roster/tc_iqqueryroster.rb +173 -0
  252. data/lib/vendor/xmpp4r/test/roster/tc_xroster.rb +73 -0
  253. data/lib/vendor/xmpp4r/test/rpc/tc_helper.rb +96 -0
  254. data/lib/vendor/xmpp4r/test/tc_callbacks.rb +129 -0
  255. data/lib/vendor/xmpp4r/test/tc_class_names.rb +146 -0
  256. data/lib/vendor/xmpp4r/test/tc_client.rb +30 -0
  257. data/lib/vendor/xmpp4r/test/tc_errors.rb +146 -0
  258. data/lib/vendor/xmpp4r/test/tc_idgenerator.rb +30 -0
  259. data/lib/vendor/xmpp4r/test/tc_iq.rb +113 -0
  260. data/lib/vendor/xmpp4r/test/tc_iqquery.rb +31 -0
  261. data/lib/vendor/xmpp4r/test/tc_jid.rb +204 -0
  262. data/lib/vendor/xmpp4r/test/tc_message.rb +116 -0
  263. data/lib/vendor/xmpp4r/test/tc_presence.rb +150 -0
  264. data/lib/vendor/xmpp4r/test/tc_rexml.rb +139 -0
  265. data/lib/vendor/xmpp4r/test/tc_stream.rb +229 -0
  266. data/lib/vendor/xmpp4r/test/tc_streamComponent.rb +95 -0
  267. data/lib/vendor/xmpp4r/test/tc_streamError.rb +131 -0
  268. data/lib/vendor/xmpp4r/test/tc_streamSend.rb +59 -0
  269. data/lib/vendor/xmpp4r/test/tc_streamparser.rb +112 -0
  270. data/lib/vendor/xmpp4r/test/tc_xmppstanza.rb +135 -0
  271. data/lib/vendor/xmpp4r/test/ts_xmpp4r.rb +53 -0
  272. data/lib/vendor/xmpp4r/test/tune/tc_helper_recv.rb +84 -0
  273. data/lib/vendor/xmpp4r/test/tune/tc_helper_send.rb +74 -0
  274. data/lib/vendor/xmpp4r/test/tune/tc_tune.rb +79 -0
  275. data/lib/vendor/xmpp4r/test/vcard/tc_helper.rb +49 -0
  276. data/lib/vendor/xmpp4r/test/vcard/tc_iqvcard.rb +62 -0
  277. data/lib/vendor/xmpp4r/test/version/tc_helper.rb +60 -0
  278. data/lib/vendor/xmpp4r/test/version/tc_iqqueryversion.rb +97 -0
  279. data/lib/vendor/xmpp4r/test/xhtml/tc_html.rb +41 -0
  280. data/lib/vendor/xmpp4r/tools/gen_requires.bash +31 -0
  281. data/lib/vendor/xmpp4r/tools/xmpp4r-gemspec-test.rb +11 -0
  282. data/lib/vendor/xmpp4r/xmpp4r.gemspec +291 -0
  283. data/test/jabber_publisher_test.rb +1 -1
  284. data/test/mail_publisher_test.rb +2 -2
  285. data/test/mock/twitter.rb +0 -1
  286. data/test/rspec_builder_test.rb +39 -2
  287. data/test/rss_publisher_test.rb +1 -1
  288. data/test/twitter_publisher_test.rb +1 -1
  289. metadata +268 -53
  290. data/lib/cerberus/publisher/gmailer.rb +0 -17
@@ -0,0 +1,167 @@
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
+ module Jabber
6
+ ##
7
+ # The JID class represents a Jabber Identifier as described by
8
+ # RFC3920 section 3.1.
9
+ #
10
+ # Note that you can use JIDs also for Sorting, Hash keys, ...
11
+ class JID
12
+ include Comparable
13
+
14
+ PATTERN = /^(?:([^@]*)@)??([^@\/]*)(?:\/(.*?))?$/
15
+
16
+ begin
17
+ require 'idn'
18
+ USE_STRINGPREP = true
19
+ rescue LoadError
20
+ USE_STRINGPREP = false
21
+ end
22
+
23
+ ##
24
+ # Create a new JID. If called as new('a@b/c'), parse the string and
25
+ # split (node, domain, resource)
26
+ def initialize(node = "", domain = nil, resource = nil)
27
+ @resource = resource
28
+ @domain = domain
29
+ @node = node
30
+ if @domain.nil? and @resource.nil? and @node
31
+ @node, @domain, @resource = @node.to_s.scan(PATTERN).first
32
+ end
33
+
34
+ if USE_STRINGPREP
35
+ @node = IDN::Stringprep.nodeprep(@node) if @node
36
+ @domain = IDN::Stringprep.nameprep(@domain) if @domain
37
+ @resource = IDN::Stringprep.resourceprep(@resource) if @resource
38
+ else
39
+ @node.downcase! if @node
40
+ @domain.downcase! if @domain
41
+ end
42
+
43
+ raise ArgumentError, 'Node too long' if (@node || '').length > 1023
44
+ raise ArgumentError, 'Domain too long' if (@domain || '').length > 1023
45
+ raise ArgumentError, 'Resource too long' if (@resource || '').length > 1023
46
+ end
47
+
48
+ ##
49
+ # Returns a string representation of the JID
50
+ # * ""
51
+ # * "domain"
52
+ # * "node@domain"
53
+ # * "domain/resource"
54
+ # * "node@domain/resource"
55
+ def to_s
56
+ s = @domain
57
+ s = "#{@node}@#{s}" if @node
58
+ s += "/#{@resource}" if @resource
59
+ return s
60
+ end
61
+
62
+ ##
63
+ # Returns a new JID with resource removed.
64
+ # return:: [JID]
65
+ def strip
66
+ JID.new(@node, @domain)
67
+ end
68
+ alias_method :bare, :strip
69
+
70
+ ##
71
+ # Removes the resource (sets it to nil)
72
+ # return:: [JID] self
73
+ def strip!
74
+ @resource = nil
75
+ self
76
+ end
77
+ alias_method :bare!, :strip!
78
+
79
+ ##
80
+ # Returns a hash value of the String representation
81
+ # (see JID#to_s)
82
+ def hash
83
+ return to_s.hash
84
+ end
85
+
86
+ ##
87
+ # Ccompare to another JID
88
+ #
89
+ # String representations are compared, see JID#to_s
90
+ def eql?(o)
91
+ to_s.eql?(o.to_s)
92
+ end
93
+
94
+ ##
95
+ # Ccompare to another JID
96
+ #
97
+ # String representations are compared, see JID#to_s
98
+ def ==(o)
99
+ to_s == o.to_s
100
+ end
101
+
102
+ ##
103
+ # Compare two JIDs,
104
+ # helpful for sorting etc.
105
+ #
106
+ # String representations are compared, see JID#to_s
107
+ def <=>(o)
108
+ to_s <=> o.to_s
109
+ end
110
+
111
+ # Get the JID's node
112
+ def node
113
+ @node
114
+ end
115
+
116
+ # Set the JID's node
117
+ def node=(v)
118
+ @node = v.to_s
119
+ if USE_STRINGPREP
120
+ @node = IDN::Stringprep.nodeprep(@node) if @node
121
+ end
122
+ end
123
+
124
+ # Get the JID's domain
125
+ def domain
126
+ return nil if @domain.empty?
127
+ @domain
128
+ end
129
+
130
+ # Set the JID's domain
131
+ def domain=(v)
132
+ @domain = v.to_s
133
+ if USE_STRINGPREP
134
+ @domain = IDN::Stringprep.nodeprep(@domain)
135
+ end
136
+ end
137
+
138
+ # Get the JID's resource
139
+ def resource
140
+ @resource
141
+ end
142
+
143
+ # Set the JID's resource
144
+ def resource=(v)
145
+ @resource = v.to_s
146
+ if USE_STRINGPREP
147
+ @resource = IDN::Stringprep.nodeprep(@resource)
148
+ end
149
+ end
150
+
151
+ # Escape JID
152
+ def JID::escape(jid)
153
+ return jid.to_s.gsub('@', '%')
154
+ end
155
+
156
+ # Test if jid is empty
157
+ def empty?
158
+ to_s.empty?
159
+ end
160
+
161
+ # Test id jid is strepped
162
+ def stripped?
163
+ @resource.nil?
164
+ end
165
+ alias_method :bared?, :stripped?
166
+ end
167
+ end
@@ -0,0 +1,148 @@
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/xmppstanza'
6
+ require 'xmpp4r/x'
7
+
8
+ module Jabber
9
+ ##
10
+ # The Message class manages the <message/> stanzas,
11
+ # which is used for all messaging communication.
12
+ class Message < XMPPStanza
13
+
14
+ name_xmlns 'message', 'jabber:client'
15
+ force_xmlns true
16
+
17
+ include XParent
18
+
19
+ ##
20
+ # Create a new message
21
+ # >to:: a JID or a String object to send the message to.
22
+ # >body:: the message's body
23
+ def initialize(to = nil, body = nil)
24
+ super()
25
+ if not to.nil?
26
+ set_to(to)
27
+ end
28
+ if !body.nil?
29
+ add_element(REXML::Element.new("body").add_text(body))
30
+ end
31
+ end
32
+
33
+ ##
34
+ # Get the type of the Message stanza
35
+ #
36
+ # The following Symbols are allowed:
37
+ # * :chat
38
+ # * :error
39
+ # * :groupchat
40
+ # * :headline
41
+ # * :normal
42
+ # result:: [Symbol] or nil
43
+ def type
44
+ case super
45
+ when 'chat' then :chat
46
+ when 'error' then :error
47
+ when 'groupchat' then :groupchat
48
+ when 'headline' then :headline
49
+ when 'normal' then :normal
50
+ else nil
51
+ end
52
+ end
53
+
54
+ ##
55
+ # Set the type of the Message stanza (see Message#type for details)
56
+ # v:: [Symbol] or nil
57
+ def type=(v)
58
+ case v
59
+ when :chat then super('chat')
60
+ when :error then super('error')
61
+ when :groupchat then super('groupchat')
62
+ when :headline then super('headline')
63
+ when :normal then super('normal')
64
+ else super(nil)
65
+ end
66
+ end
67
+
68
+ ##
69
+ # Set the type of the Message stanza (chaining-friendly)
70
+ # v:: [Symbol] or nil
71
+ def set_type(v)
72
+ self.type = v
73
+ self
74
+ end
75
+
76
+ ##
77
+ # Returns the message's body, or nil.
78
+ # This is the message's plain-text content.
79
+ def body
80
+ first_element_text('body')
81
+ end
82
+
83
+ ##
84
+ # Sets the message's body
85
+ #
86
+ # b:: [String] body to set
87
+ def body=(b)
88
+ replace_element_text('body', b)
89
+ end
90
+
91
+ ##
92
+ # Sets the message's body
93
+ #
94
+ # b:: [String] body to set
95
+ # return:: [REXML::Element] self for chaining
96
+ def set_body(b)
97
+ self.body = b
98
+ self
99
+ end
100
+
101
+ ##
102
+ # sets the message's subject
103
+ #
104
+ # s:: [String] subject to set
105
+ def subject=(s)
106
+ replace_element_text('subject', s)
107
+ end
108
+
109
+ ##
110
+ # sets the message's subject
111
+ #
112
+ # s:: [String] subject to set
113
+ # return:: [REXML::Element] self for chaining
114
+ def set_subject(s)
115
+ self.subject = s
116
+ self
117
+ end
118
+
119
+ ##
120
+ # Returns the message's subject, or nil
121
+ def subject
122
+ first_element_text('subject')
123
+ end
124
+
125
+ ##
126
+ # sets the message's thread
127
+ # s:: [String] thread to set
128
+ def thread=(s)
129
+ delete_elements('thread')
130
+ replace_element_text('thread', s) unless s.nil?
131
+ end
132
+
133
+ ##
134
+ # gets the message's thread (chaining-friendly)
135
+ # Please note that this are not [Thread] but a [String]-Identifier to track conversations
136
+ # s:: [String] thread to set
137
+ def set_thread(s)
138
+ self.thread = s
139
+ self
140
+ end
141
+
142
+ ##
143
+ # Returns the message's thread, or nil
144
+ def thread
145
+ first_element_text('thread')
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,14 @@
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/dataforms'
6
+ require 'xmpp4r/muc/x/muc'
7
+ require 'xmpp4r/muc/x/mucuserinvite'
8
+ require 'xmpp4r/muc/x/mucuseritem'
9
+ require 'xmpp4r/muc/iq/mucowner'
10
+ require 'xmpp4r/muc/iq/mucadmin'
11
+ require 'xmpp4r/muc/iq/mucadminitem'
12
+ require 'xmpp4r/muc/helper/mucbrowser'
13
+ require 'xmpp4r/muc/helper/mucclient'
14
+ require 'xmpp4r/muc/helper/simplemucclient'
@@ -0,0 +1,92 @@
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/discovery'
6
+
7
+ module Jabber
8
+ module MUC
9
+ ##
10
+ # The MUCBrowser helper can be used to discover
11
+ # Multi-User-Chat components via Service Discovery
12
+ #
13
+ # See JEP 0045 sections 6.1. and 6.2.
14
+ #
15
+ # Usage of its functions should be threaded as
16
+ # responses can take a while
17
+ class MUCBrowser
18
+ ##
19
+ # Initialize a new MUCBrowser helper
20
+ def initialize(stream)
21
+ @stream = stream
22
+ end
23
+
24
+ ##
25
+ # Retrieve the name of a MUC component,
26
+ # depending upon whether the target entity supports
27
+ # the MUC protocol.
28
+ #
29
+ # A return-value of nil does *not* mean that the entity
30
+ # does not exist or does not support Service Discovery!
31
+ # nil just means that this is not a MUC-compliant service.
32
+ #
33
+ # Throws an ServerError when receiving
34
+ # <tt><iq type='error'/></tt>
35
+ # jid:: [JID] Target entity (set only domain!)
36
+ # return:: [String] or [nil]
37
+ def muc_name(jid)
38
+ iq = Iq.new(:get, jid)
39
+ iq.from = @stream.jid # Enable components to use this
40
+ iq.add(Discovery::IqQueryDiscoInfo.new)
41
+
42
+ res = nil
43
+
44
+ @stream.send_with_id(iq) do |answer|
45
+ if answer.type == :result
46
+ answer.query.each_element('feature') { |feature|
47
+ # Look if the component has a MUC or Groupchat feature
48
+ if feature.var == 'http://jabber.org/protocol/muc' or feature.var == 'gc-1.0'
49
+ # If so, get the identity
50
+ if answer.query.first_element('identity')
51
+ res = answer.query.first_element('identity').iname
52
+ end
53
+ end
54
+ }
55
+ true
56
+ else
57
+ false
58
+ end
59
+ end
60
+
61
+ res
62
+ end
63
+
64
+ ##
65
+ # Retrieve the existing rooms of a MUC component
66
+ #
67
+ # The resulting Hash contains pairs of room JID and room name
68
+ #
69
+ # Usage:
70
+ # my_mucbrowse_helper.muc_rooms('conference.jabber.org').each { |jid,name| ... }
71
+ #
72
+ # Throws an exception when receiving <tt><iq type='error'/></tt>
73
+ # jid:: [JID] Target entity (set only domain!)
74
+ # return:: [Hash]
75
+ def muc_rooms(jid)
76
+ iq = Iq.new(:get, jid)
77
+ iq.from = @stream.jid # Enable components to use this
78
+ iq.add(Discovery::IqQueryDiscoItems.new)
79
+
80
+ rooms = {}
81
+
82
+ @stream.send_with_id(iq) do |answer|
83
+ answer.query.each_element('item') { |item|
84
+ rooms[item.jid] = item.iname
85
+ }
86
+ end
87
+
88
+ rooms
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,462 @@
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/muc/x/muc'
6
+ require 'xmpp4r/muc/iq/mucowner'
7
+ require 'xmpp4r/muc/iq/mucadmin'
8
+ require 'xmpp4r/dataforms'
9
+
10
+ module Jabber
11
+ module MUC
12
+ ##
13
+ # The MUCClient Helper handles low-level stuff of the
14
+ # Multi-User Chat (JEP 0045).
15
+ #
16
+ # Use one instance per room.
17
+ #
18
+ # Note that one client cannot join a single room multiple
19
+ # times. At least the clients' resources must be different.
20
+ # This is a protocol design issue. But don't consider it as
21
+ # a bug, it is just a clone-preventing feature.
22
+ class MUCClient
23
+ ##
24
+ # Sender JID, set this to use MUCClient from Components
25
+ # my_jid:: [JID] Defaults to nil
26
+ attr_accessor :my_jid
27
+
28
+ ##
29
+ # MUC room roster
30
+ # roster:: [Hash] of [String] Nick => [Presence]
31
+ attr_reader :roster
32
+
33
+ ##
34
+ # MUC JID
35
+ # jid:: [JID] room@component/nick
36
+ attr_reader :jid
37
+
38
+ ##
39
+ # Initialize a MUCClient
40
+ #
41
+ # Call MUCClient#join *after* you have registered your
42
+ # callbacks to avoid reception of stanzas after joining
43
+ # and before registration of callbacks.
44
+ # stream:: [Stream] to operate on
45
+ def initialize(stream)
46
+ # Attributes initialization
47
+ @stream = stream
48
+ @my_jid = nil
49
+ @jid = nil
50
+ @roster = {}
51
+ @roster_lock = Mutex.new
52
+
53
+ @active = false
54
+
55
+ @join_cbs = CallbackList.new
56
+ @leave_cbs = CallbackList.new
57
+ @presence_cbs = CallbackList.new
58
+ @message_cbs = CallbackList.new
59
+ @private_message_cbs = CallbackList.new
60
+ end
61
+
62
+ ##
63
+ # Join a room
64
+ #
65
+ # This registers its own callbacks on the stream
66
+ # provided to initialize and sends initial presence
67
+ # to the room. May throw ServerError if joining
68
+ # fails.
69
+ # jid:: [JID] room@component/nick
70
+ # password:: [String] Optional password
71
+ # return:: [MUCClient] self (chain-able)
72
+ def join(jid, password=nil)
73
+ if active?
74
+ raise "MUCClient already active"
75
+ end
76
+
77
+ @jid = (jid.kind_of?(JID) ? jid : JID.new(jid))
78
+ activate
79
+
80
+ # Joining
81
+ pres = Presence.new
82
+ pres.to = @jid
83
+ pres.from = @my_jid
84
+ xmuc = XMUC.new
85
+ xmuc.password = password
86
+ pres.add(xmuc)
87
+
88
+ # We don't use Stream#send_with_id here as it's unknown
89
+ # if the MUC component *always* uses our stanza id.
90
+ error = nil
91
+ @stream.send(pres) { |r|
92
+ if from_room?(r.from) and r.kind_of?(Presence) and r.type == :error
93
+ # Error from room
94
+ error = r.error
95
+ true
96
+ # type='unavailable' may occur when the MUC kills our previous instance,
97
+ # but all join-failures should be type='error'
98
+ elsif r.from == jid and r.kind_of?(Presence) and r.type != :unavailable
99
+ # Our own presence reflected back - success
100
+ if r.x(XMUCUser) and (i = r.x(XMUCUser).items.first)
101
+ @affiliation = i.affiliation # we're interested in if it's :owner
102
+ @role = i.role # :moderator ?
103
+ end
104
+
105
+ handle_presence(r, false)
106
+ true
107
+ else
108
+ # Everything else
109
+ false
110
+ end
111
+ }
112
+
113
+ if error
114
+ deactivate
115
+ raise ServerError.new(error)
116
+ end
117
+
118
+ self
119
+ end
120
+
121
+ ##
122
+ # Exit the room
123
+ #
124
+ # * Sends presence with type='unavailable' with an optional
125
+ # reason in <tt><status/></tt>,
126
+ # * then waits for a reply from the MUC component (will be
127
+ # processed by leave-callbacks),
128
+ # * then deletes callbacks from the stream.
129
+ # reason:: [String] Optional custom exit message
130
+ def exit(reason=nil)
131
+ unless active?
132
+ raise "MUCClient hasn't yet joined"
133
+ end
134
+
135
+ pres = Presence.new
136
+ pres.type = :unavailable
137
+ pres.to = jid
138
+ pres.from = @my_jid
139
+ pres.status = reason if reason
140
+ @stream.send(pres) { |r|
141
+ Jabber::debuglog "exit: #{r.to_s.inspect}"
142
+ if r.kind_of?(Presence) and r.type == :unavailable and r.from == jid
143
+ @leave_cbs.process(r)
144
+ true
145
+ else
146
+ false
147
+ end
148
+ }
149
+
150
+ deactivate
151
+
152
+ self
153
+ end
154
+
155
+ ##
156
+ # Is the MUC client active?
157
+ #
158
+ # This is false after initialization,
159
+ # true after joining and
160
+ # false after exit/kick
161
+ def active?
162
+ @active
163
+ end
164
+
165
+ ##
166
+ # The MUCClient's own nick
167
+ # (= resource)
168
+ # result:: [String] Nickname
169
+ def nick
170
+ @jid ? @jid.resource : nil
171
+ end
172
+
173
+ ##
174
+ # Change nick
175
+ #
176
+ # Threading is, again, suggested. This method waits for two
177
+ # <presence/> stanzas, one indicating unavailabilty of the old
178
+ # transient JID, one indicating availability of the new
179
+ # transient JID.
180
+ #
181
+ # If the service denies nick-change, ServerError will be raised.
182
+ def nick=(new_nick)
183
+ unless active?
184
+ raise "MUCClient not active"
185
+ end
186
+
187
+ new_jid = JID.new(@jid.node, @jid.domain, new_nick)
188
+
189
+ # Joining
190
+ pres = Presence.new
191
+ pres.to = new_jid
192
+ pres.from = @my_jid
193
+
194
+ error = nil
195
+ # Keeping track of the two stanzas enables us to process stanzas
196
+ # which don't arrive in the order specified by JEP-0045
197
+ presence_unavailable = false
198
+ presence_available = false
199
+ # We don't use Stream#send_with_id here as it's unknown
200
+ # if the MUC component *always* uses our stanza id.
201
+ @stream.send(pres) { |r|
202
+ if from_room?(r.from) and r.kind_of?(Presence) and r.type == :error
203
+ # Error from room
204
+ error = r.error
205
+ elsif r.from == @jid and r.kind_of?(Presence) and r.type == :unavailable and
206
+ r.x and r.x.kind_of?(XMUCUser) and r.x.status_code == 303
207
+ # Old JID is offline, but wait for the new JID and let stanza be handled
208
+ # by the standard callback
209
+ presence_unavailable = true
210
+ handle_presence(r)
211
+ elsif r.from == new_jid and r.kind_of?(Presence) and r.type != :unavailable
212
+ # Our own presence reflected back - success
213
+ presence_available = true
214
+ handle_presence(r)
215
+ end
216
+
217
+ if error or (presence_available and presence_unavailable)
218
+ true
219
+ else
220
+ false
221
+ end
222
+ }
223
+
224
+ if error
225
+ raise ServerError.new(error)
226
+ end
227
+
228
+ # Apply new JID
229
+ @jid = new_jid
230
+ end
231
+
232
+ ##
233
+ # The room name
234
+ # (= node)
235
+ # result:: [String] Room name
236
+ def room
237
+ @jid ? @jid.node : nil
238
+ end
239
+
240
+ ##
241
+ # Send a stanza to the room
242
+ #
243
+ # If stanza is a Jabber::Message, <tt>stanza.type</tt> will be
244
+ # automatically set to :groupchat if directed to room or :chat
245
+ # if directed to participant.
246
+ # stanza:: [XMPPStanza] to send
247
+ # to:: [String] Stanza destination recipient, or room if +nil+
248
+ def send(stanza, to=nil)
249
+ if stanza.kind_of? Message
250
+ stanza.type = to ? :chat : :groupchat
251
+ end
252
+ stanza.from = @my_jid
253
+ stanza.to = JID.new(jid.node, jid.domain, to)
254
+ @stream.send(stanza)
255
+ end
256
+
257
+ ##
258
+ # Add a callback for <presence/> stanzas indicating availability
259
+ # of a MUC participant
260
+ #
261
+ # This callback will *not* be called for initial presences when
262
+ # a client joins a room, but only for the presences afterwards.
263
+ #
264
+ # The callback will be called from MUCClient#handle_presence with
265
+ # one argument: the <presence/> stanza.
266
+ # Note that this stanza will have been already inserted into
267
+ # MUCClient#roster.
268
+ def add_join_callback(prio = 0, ref = nil, &block)
269
+ @join_cbs.add(prio, ref, block)
270
+ end
271
+
272
+ ##
273
+ # Add a callback for <presence/> stanzas indicating unavailability
274
+ # of a MUC participant
275
+ #
276
+ # The callback will be called with one argument: the <presence/> stanza.
277
+ #
278
+ # Note that this is called just *before* the stanza is removed from
279
+ # MUCClient#roster, so it is still possible to see the last presence
280
+ # in the given block.
281
+ #
282
+ # If the presence's origin is your MUC JID, the MUCClient will be
283
+ # deactivated *afterwards*.
284
+ def add_leave_callback(prio = 0, ref = nil, &block)
285
+ @leave_cbs.add(prio, ref, block)
286
+ end
287
+
288
+ ##
289
+ # Add a callback for a <presence/> stanza which is neither a join
290
+ # nor a leave. This will be called when a room participant simply
291
+ # changes his status.
292
+ def add_presence_callback(prio = 0, ref = nil, &block)
293
+ @presence_cbs.add(prio, ref, block)
294
+ end
295
+
296
+ ##
297
+ # Add a callback for <message/> stanza directed to the whole room.
298
+ #
299
+ # See MUCClient#add_private_message_callback for private messages
300
+ # between MUC participants.
301
+ def add_message_callback(prio = 0, ref = nil, &block)
302
+ @message_cbs.add(prio, ref, block)
303
+ end
304
+
305
+ ##
306
+ # Add a callback for <message/> stanza with type='chat'.
307
+ #
308
+ # These stanza are normally not broadcasted to all room occupants
309
+ # but are some sort of private messaging.
310
+ def add_private_message_callback(prio = 0, ref = nil, &block)
311
+ @private_message_cbs.add(prio, ref, block)
312
+ end
313
+
314
+ ##
315
+ # Does this JID belong to that room?
316
+ # jid:: [JID]
317
+ # result:: [true] or [false]
318
+ def from_room?(jid)
319
+ @jid.strip == jid.strip
320
+ end
321
+
322
+ private
323
+
324
+ ##
325
+ # call_join_cbs:: [Bool] Do not call them if we receive initial presences from room
326
+ def handle_presence(pres, call_join_cbs=true) # :nodoc:
327
+ if pres.type == :unavailable or pres.type == :error
328
+ @leave_cbs.process(pres)
329
+ @roster_lock.synchronize {
330
+ @roster.delete(pres.from.resource)
331
+ }
332
+
333
+ if pres.from == jid and !(pres.x and pres.x.kind_of?(XMUCUser) and pres.x.status_code == 303)
334
+ deactivate
335
+ end
336
+ else
337
+ is_join = ! @roster.has_key?(pres.from.resource)
338
+ @roster_lock.synchronize {
339
+ @roster[pres.from.resource] = pres
340
+ }
341
+ if is_join
342
+ @join_cbs.process(pres) if call_join_cbs
343
+ else
344
+ @presence_cbs.process(pres)
345
+ end
346
+ end
347
+ end
348
+
349
+ def handle_message(msg) # :nodoc:
350
+ if msg.type == :chat
351
+ @private_message_cbs.process(msg)
352
+ else # type == :groupchat or anything else
353
+ @message_cbs.process(msg)
354
+ end
355
+ end
356
+
357
+ def activate # :nodoc:
358
+ @active = true
359
+
360
+ # Callbacks
361
+ @stream.add_presence_callback(150, self) { |presence|
362
+ if from_room?(presence.from)
363
+ handle_presence(presence)
364
+ true
365
+ else
366
+ false
367
+ end
368
+ }
369
+
370
+ @stream.add_message_callback(150, self) { |message|
371
+ if from_room?(message.from)
372
+ handle_message(message)
373
+ true
374
+ else
375
+ false
376
+ end
377
+ }
378
+ end
379
+
380
+ def deactivate # :nodoc:
381
+ @active = false
382
+ @jid = nil
383
+
384
+ # Callbacks
385
+ @stream.delete_presence_callback(self)
386
+ @stream.delete_message_callback(self)
387
+ end
388
+
389
+ public
390
+ def owner?
391
+ @affiliation == :owner
392
+ end
393
+
394
+ ##
395
+ # Use this method to configure a MUC room of which you are the owner.
396
+ #
397
+ # options:: [Hash] where keys are the features of the room you wish
398
+ # to configure. See http://www.xmpp.org/extensions/xep-0045.html#registrar-formtype-owner
399
+ def configure(options={})
400
+ get_room_configuration
401
+ submit_room_configuration(options)
402
+ end
403
+
404
+ def get_room_configuration
405
+ raise 'You are not the owner' unless owner?
406
+
407
+ iq = Iq.new(:get, jid.strip)
408
+ iq.from = my_jid
409
+ iq.add(IqQueryMUCOwner.new)
410
+
411
+ fields = []
412
+
413
+ @stream.send_with_id(iq) do |answer|
414
+ raise "Configuration not possible for this room" unless answer.query && answer.query.x(Dataforms::XData)
415
+
416
+ answer.query.x(Dataforms::XData).fields.each do |field|
417
+ if (var = field.attributes['var'])
418
+ fields << var
419
+ end
420
+ end
421
+ end
422
+
423
+ fields
424
+ end
425
+
426
+ def submit_room_configuration(options)
427
+ # fill out the reply form
428
+ iq = Iq.new(:set, jid.strip)
429
+ iq.from = my_jid
430
+ query = IqQueryMUCOwner.new
431
+ form = Dataforms::XData.new
432
+ form.type = :submit
433
+ options.each do |var, values|
434
+ field = Dataforms::XDataField.new
435
+ values = [values] unless values.is_a?(Array)
436
+ field.var, field.values = var, values
437
+ form.add(field)
438
+ end
439
+ query.add(form)
440
+ iq.add(query)
441
+
442
+ @stream.send_with_id(iq)
443
+ end
444
+
445
+ ##
446
+ # Push a list of new affiliations to the room
447
+ # items:: [Array] of, or single [IqQueryMUCAdminItem]
448
+ def send_affiliations(items)
449
+ iq = Iq.new(:set, jid.strip)
450
+ iq.from = my_jid
451
+ iq.add(IqQueryMUCAdmin.new)
452
+
453
+ items = [item] unless items.kind_of? Array
454
+ items.each { |item|
455
+ iq.query.add(item)
456
+ }
457
+
458
+ @stream.send_with_id(iq)
459
+ end
460
+ end
461
+ end
462
+ end