blather 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. data/LICENSE +1 -1
  2. data/README.rdoc +41 -12
  3. data/examples/echo.rb +1 -1
  4. data/examples/execute.rb +0 -5
  5. data/examples/pubsub/cli.rb +64 -0
  6. data/examples/pubsub/ping_pong.rb +18 -0
  7. data/examples/rosterprint.rb +14 -0
  8. data/examples/xmpp4r/echo.rb +35 -0
  9. data/lib/blather.rb +35 -12
  10. data/lib/blather/client.rb +1 -1
  11. data/lib/blather/client/client.rb +19 -13
  12. data/lib/blather/client/dsl.rb +16 -0
  13. data/lib/blather/client/dsl/pubsub.rb +133 -0
  14. data/lib/blather/core_ext/active_support.rb +1 -117
  15. data/lib/blather/core_ext/active_support/inheritable_attributes.rb +117 -0
  16. data/lib/blather/core_ext/nokogiri.rb +35 -0
  17. data/lib/blather/errors.rb +3 -20
  18. data/lib/blather/errors/sasl_error.rb +3 -1
  19. data/lib/blather/errors/stanza_error.rb +10 -17
  20. data/lib/blather/errors/stream_error.rb +11 -14
  21. data/lib/blather/jid.rb +1 -0
  22. data/lib/blather/roster.rb +9 -0
  23. data/lib/blather/roster_item.rb +6 -1
  24. data/lib/blather/stanza.rb +35 -18
  25. data/lib/blather/stanza/disco.rb +7 -1
  26. data/lib/blather/stanza/disco/disco_info.rb +45 -33
  27. data/lib/blather/stanza/disco/disco_items.rb +32 -21
  28. data/lib/blather/stanza/iq.rb +13 -8
  29. data/lib/blather/stanza/iq/query.rb +16 -8
  30. data/lib/blather/stanza/iq/roster.rb +33 -22
  31. data/lib/blather/stanza/message.rb +20 -31
  32. data/lib/blather/stanza/presence.rb +3 -5
  33. data/lib/blather/stanza/presence/status.rb +13 -21
  34. data/lib/blather/stanza/presence/subscription.rb +11 -16
  35. data/lib/blather/stanza/pubsub.rb +63 -0
  36. data/lib/blather/stanza/pubsub/affiliations.rb +50 -0
  37. data/lib/blather/stanza/pubsub/create.rb +43 -0
  38. data/lib/blather/stanza/pubsub/errors.rb +9 -0
  39. data/lib/blather/stanza/pubsub/event.rb +77 -0
  40. data/lib/blather/stanza/pubsub/items.rb +63 -0
  41. data/lib/blather/stanza/pubsub/publish.rb +58 -0
  42. data/lib/blather/stanza/pubsub/retract.rb +53 -0
  43. data/lib/blather/stanza/pubsub/subscribe.rb +42 -0
  44. data/lib/blather/stanza/pubsub/subscription.rb +66 -0
  45. data/lib/blather/stanza/pubsub/subscriptions.rb +55 -0
  46. data/lib/blather/stanza/pubsub/unsubscribe.rb +42 -0
  47. data/lib/blather/stanza/pubsub_owner.rb +41 -0
  48. data/lib/blather/stanza/pubsub_owner/delete.rb +34 -0
  49. data/lib/blather/stanza/pubsub_owner/purge.rb +34 -0
  50. data/lib/blather/stream.rb +76 -168
  51. data/lib/blather/stream/client.rb +1 -2
  52. data/lib/blather/stream/component.rb +9 -5
  53. data/lib/blather/stream/features.rb +53 -0
  54. data/lib/blather/stream/features/resource.rb +63 -0
  55. data/lib/blather/stream/{sasl.rb → features/sasl.rb} +53 -52
  56. data/lib/blather/stream/features/session.rb +44 -0
  57. data/lib/blather/stream/features/tls.rb +28 -0
  58. data/lib/blather/stream/parser.rb +70 -46
  59. data/lib/blather/xmpp_node.rb +113 -52
  60. data/spec/blather/client/client_spec.rb +44 -58
  61. data/spec/blather/client/dsl/pubsub_spec.rb +465 -0
  62. data/spec/blather/client/dsl_spec.rb +19 -6
  63. data/spec/blather/core_ext/nokogiri_spec.rb +83 -0
  64. data/spec/blather/errors/sasl_error_spec.rb +8 -8
  65. data/spec/blather/errors/stanza_error_spec.rb +25 -33
  66. data/spec/blather/errors/stream_error_spec.rb +21 -16
  67. data/spec/blather/errors_spec.rb +4 -11
  68. data/spec/blather/jid_spec.rb +31 -30
  69. data/spec/blather/roster_item_spec.rb +34 -23
  70. data/spec/blather/roster_spec.rb +27 -12
  71. data/spec/blather/stanza/discos/disco_info_spec.rb +61 -42
  72. data/spec/blather/stanza/discos/disco_items_spec.rb +47 -35
  73. data/spec/blather/stanza/iq/query_spec.rb +34 -11
  74. data/spec/blather/stanza/iq/roster_spec.rb +47 -30
  75. data/spec/blather/stanza/iq_spec.rb +19 -14
  76. data/spec/blather/stanza/message_spec.rb +30 -17
  77. data/spec/blather/stanza/presence/status_spec.rb +43 -20
  78. data/spec/blather/stanza/presence/subscription_spec.rb +41 -21
  79. data/spec/blather/stanza/presence_spec.rb +34 -21
  80. data/spec/blather/stanza/pubsub/affiliations_spec.rb +57 -0
  81. data/spec/blather/stanza/pubsub/create_spec.rb +56 -0
  82. data/spec/blather/stanza/pubsub/event_spec.rb +84 -0
  83. data/spec/blather/stanza/pubsub/items_spec.rb +79 -0
  84. data/spec/blather/stanza/pubsub/publish_spec.rb +83 -0
  85. data/spec/blather/stanza/pubsub/retract_spec.rb +75 -0
  86. data/spec/blather/stanza/pubsub/subscribe_spec.rb +61 -0
  87. data/spec/blather/stanza/pubsub/subscription_spec.rb +97 -0
  88. data/spec/blather/stanza/pubsub/subscriptions_spec.rb +59 -0
  89. data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +61 -0
  90. data/spec/blather/stanza/pubsub_owner/delete_spec.rb +50 -0
  91. data/spec/blather/stanza/pubsub_owner/purge_spec.rb +50 -0
  92. data/spec/blather/stanza/pubsub_owner_spec.rb +27 -0
  93. data/spec/blather/stanza/pubsub_spec.rb +62 -0
  94. data/spec/blather/stanza_spec.rb +53 -38
  95. data/spec/blather/stream/client_spec.rb +231 -88
  96. data/spec/blather/stream/component_spec.rb +14 -5
  97. data/spec/blather/stream/parser_spec.rb +145 -0
  98. data/spec/blather/xmpp_node_spec.rb +192 -96
  99. data/spec/fixtures/pubsub.rb +311 -0
  100. data/spec/spec_helper.rb +5 -4
  101. metadata +54 -18
  102. data/Rakefile +0 -139
  103. data/ext/extconf.rb +0 -65
  104. data/ext/push_parser.c +0 -209
  105. data/lib/blather/core_ext/libxml.rb +0 -28
  106. data/lib/blather/stream/resource.rb +0 -48
  107. data/lib/blather/stream/session.rb +0 -36
  108. data/lib/blather/stream/stream_handler.rb +0 -39
  109. data/lib/blather/stream/tls.rb +0 -33
  110. data/spec/blather/core_ext/libxml_spec.rb +0 -58
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  Blather
2
2
 
3
- Copyright (c) 2008 Jeff Smick
3
+ Copyright (c) 2009 Jeff Smick
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
@@ -1,11 +1,11 @@
1
1
  = Blather
2
2
 
3
- An evented XMPP library
3
+ XMPP DSL (and more) for Ruby written on EventMachine and Nokogiri.
4
4
 
5
5
  == Features
6
6
 
7
7
  * evented architecture
8
- * uses libxml
8
+ * uses Nokogiri
9
9
  * simplified starting point
10
10
 
11
11
  == Project Pages
@@ -18,11 +18,7 @@ GitHub Docs:: http://docs.github.com/sprsquish/blather
18
18
 
19
19
  RubyForge:: http://rubyforge.org/projects/squishtech
20
20
 
21
- RDocs:: http://squishtech.rubyforge.org/blather/
22
-
23
- == Author
24
-
25
- Jeff Smick <sprsquish@gmail.com>
21
+ RDocs:: http://squishtech.rubyforge.org/blather
26
22
 
27
23
  = Usage
28
24
 
@@ -32,7 +28,7 @@ Jeff Smick <sprsquish@gmail.com>
32
28
 
33
29
  == Example
34
30
 
35
- See the /examples directory for more advanced examples.
31
+ See the examples directory for more advanced examples.
36
32
 
37
33
  This will auto-accept any subscription requests and echo back any chat messages.
38
34
 
@@ -73,7 +69,7 @@ The different types of guards are:
73
69
  # Equivalent to stanza.chat?
74
70
  message :chat?
75
71
 
76
- # Hash with value (:body => 'exit')
72
+ # Hash with any value (:body => 'exit')
77
73
  # Calls the key on the stanza and checks for equality
78
74
  # Equivalent to stanza.body == 'exit'
79
75
  message :body => 'exit'
@@ -99,6 +95,12 @@ The different types of guards are:
99
95
  # Equivalent to stanza.body == 'foo' || stanza.body == 'baz'
100
96
  message [{:body => 'foo'}, {:body => 'baz'}]
101
97
 
98
+ # XPath
99
+ # Runs the xpath query on the stanza and checks for results
100
+ # This guard type cannot be combined with other guards
101
+ # Equivalent to !stanza.find('/iq/ns:pubsub', :ns => 'pubsub:namespace').empty?
102
+ iq '/iq/ns:pubsub', :ns => 'pubsub:namespace'
103
+
102
104
  == On the Command Line:
103
105
 
104
106
  Default usage is:
@@ -117,11 +119,38 @@ Command line options:
117
119
 
118
120
  = TODO
119
121
 
120
- * Add XPath guard that passes the result to the handler
121
122
  * Add Disco the the DSL
122
- * PubSub (XEP-0060: http://xmpp.org/extensions/xep-0060.html)
123
123
  * More examples (Re-write XMPP4R examples into Blather)
124
124
 
125
+ = Author
126
+
127
+ Jeff Smick <sprsquish@gmail.com>
128
+
129
+ = Contributors
130
+
131
+ Nolan Darilek <nolan@thewordnerd.info>
132
+
125
133
  = License
126
134
 
127
- Please see LICENSE
135
+ Blather
136
+
137
+ Copyright (c) 2009 Jeff Smick
138
+
139
+ Permission is hereby granted, free of charge, to any person obtaining
140
+ a copy of this software and associated documentation files (the
141
+ "Software"), to deal in the Software without restriction, including
142
+ without limitation the rights to use, copy, modify, merge, publish,
143
+ distribute, sublicense, and/or sell copies of the Software, and to
144
+ permit persons to whom the Software is furnished to do so, subject to
145
+ the following conditions:
146
+
147
+ The above copyright notice and this permission notice shall be
148
+ included in all copies or substantial portions of the Software.
149
+
150
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
151
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
152
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
153
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
154
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
155
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
156
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'blather/client'
4
-
4
+ Blather.logger.level = Logger::DEBUG
5
5
  when_ready { puts "Connected ! send messages to #{jid.stripped}." }
6
6
 
7
7
  subscription :request? do |s|
@@ -1,11 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'blather/client'
4
- require 'blather/client/pubsub'
5
-
6
- setup 'echo@jabber.local', 'echo'
7
-
8
- Blather::LOG.level = Logger::DEBUG
9
4
 
10
5
  message :chat?, :body => 'exit' do |m|
11
6
  say m.from, 'Exiting ...'
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'blather/client'
4
+
5
+ #ls
6
+ #cd
7
+ #cat
8
+ #Blather::LOG.level = Logger::DEBUG
9
+ module CliHandler
10
+ include EM::Protocols::LineText2
11
+
12
+ def ls(node)
13
+ pubsub.node(parse_dir(node)) do |result|
14
+ cur = node.split('/')
15
+ puts
16
+ puts result.items.map { |i| (i.node.split('/') - cur).join('/') }.join("\n")
17
+ start_line
18
+ end
19
+ end
20
+
21
+ def cd(node)
22
+ @node = parse_dir(node)
23
+ start_line
24
+ end
25
+
26
+ def cat(item)
27
+ end
28
+
29
+ def connect(who)
30
+ @who = who
31
+ puts "connected to '#{who}'"
32
+ end
33
+
34
+ def exit(_)
35
+ EM.stop
36
+ end
37
+
38
+ def initialize
39
+ $stdout.sync = true
40
+ @node = ''
41
+ @who = ''
42
+ start_line
43
+ end
44
+
45
+ def start_line
46
+ puts "\n/#{@node}> "
47
+ end
48
+
49
+ def receive_line(line)
50
+ return unless line =~ /(connect|exit|ls|cd|cat)\s?(.*)/i
51
+ __send__ $1, $2
52
+ end
53
+
54
+ def parse_dir(list)
55
+ return '' if list == '/'
56
+ cur = @node.split('/')
57
+ list.split('/').each { |dir| dir == '..' ? cur.pop : (cur << dir) }
58
+ cur * '/'
59
+ end
60
+ end
61
+
62
+ setup 'echo@jabber.local', 'echo'
63
+ pubsub_host 'pubsub.jabber.local'
64
+ when_ready { EM.open_keyboard CliHandler }
@@ -0,0 +1,18 @@
1
+ setup 'ping-pong@jabber.local', 'ping-pong'
2
+
3
+ pubsub.host = 'pubsub.jabber.local'
4
+
5
+ pubsub_event :node => 'ping' do |node|
6
+ pubsub.publish 'pong', node.payload
7
+ end
8
+
9
+ pubsub_event :node => 'pong' do |node|
10
+ x = node.payload.to_i
11
+ if x > 0
12
+ pubsub.publish 'ping', (x - 1)
13
+ else
14
+ shutdown
15
+ end
16
+ end
17
+
18
+ when_ready { pubsub.publish 'ping', 3 }
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Prints out each roster entry
4
+
5
+ require 'blather/client'
6
+
7
+ when_ready do
8
+ roster.grouped.each do |group, items|
9
+ puts "#{'*'*3} #{group || 'Ungrouped'} #{'*'*3}"
10
+ items.each { |item| puts "- #{item.name} (#{item.jid})" }
11
+ puts
12
+ end
13
+ shutdown
14
+ end
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # This bot will reply to every message it receives. To end the game, send 'exit'
4
+
5
+ require 'xmpp4r/client'
6
+ include Jabber
7
+
8
+ # settings
9
+ if ARGV.length != 2
10
+ puts "Run with ./echo_thread.rb user@server/resource password"
11
+ exit 1
12
+ end
13
+ myJID = JID.new(ARGV[0])
14
+ myPassword = ARGV[1]
15
+ cl = Client.new(myJID)
16
+ cl.connect
17
+ cl.auth(myPassword)
18
+ cl.send(Presence.new)
19
+ puts "Connected ! send messages to #{myJID.strip.to_s}."
20
+ mainthread = Thread.current
21
+ cl.add_message_callback do |m|
22
+ if m.type != :error
23
+ m2 = Message.new(m.from, "You sent: #{m.body}")
24
+ m2.type = m.type
25
+ cl.send(m2)
26
+ if m.body == 'exit'
27
+ m2 = Message.new(m.from, "Exiting ...")
28
+ m2.type = m.type
29
+ cl.send(m2)
30
+ mainthread.wakeup
31
+ end
32
+ end
33
+ end
34
+ Thread.stop
35
+ cl.close
@@ -1,14 +1,13 @@
1
1
  # Require the necessary files
2
- require File.join(File.dirname(__FILE__), *%w[.. ext push_parser])
3
2
  %w[
4
3
  rubygems
5
4
  eventmachine
6
- xml/libxml
5
+ nokogiri
7
6
  digest/md5
8
7
  logger
9
8
 
10
9
  blather/core_ext/active_support
11
- blather/core_ext/libxml
10
+ blather/core_ext/nokogiri
12
11
 
13
12
  blather/errors
14
13
  blather/errors/sasl_error
@@ -31,20 +30,44 @@ require File.join(File.dirname(__FILE__), *%w[.. ext push_parser])
31
30
  blather/stanza/presence/status
32
31
  blather/stanza/presence/subscription
33
32
 
33
+ blather/stanza/pubsub
34
+ blather/stanza/pubsub/affiliations
35
+ blather/stanza/pubsub/create
36
+ blather/stanza/pubsub/event
37
+ blather/stanza/pubsub/items
38
+ blather/stanza/pubsub/publish
39
+ blather/stanza/pubsub/retract
40
+ blather/stanza/pubsub/subscribe
41
+ blather/stanza/pubsub/subscription
42
+ blather/stanza/pubsub/subscriptions
43
+ blather/stanza/pubsub/unsubscribe
44
+
45
+ blather/stanza/pubsub_owner
46
+ blather/stanza/pubsub_owner/delete
47
+ blather/stanza/pubsub_owner/purge
48
+
34
49
  blather/stream
35
50
  blather/stream/client
36
51
  blather/stream/component
37
- blather/stream/stream_handler
38
52
  blather/stream/parser
39
- blather/stream/resource
40
- blather/stream/sasl
41
- blather/stream/session
42
- blather/stream/tls
53
+ blather/stream/features
54
+ blather/stream/features/resource
55
+ blather/stream/features/sasl
56
+ blather/stream/features/session
57
+ blather/stream/features/tls
43
58
  ].each { |r| require r }
44
59
 
45
- XML.indent_tree_output = false
46
-
47
60
  module Blather
48
- LOG = Logger.new($stdout) unless const_defined?(:LOG)
49
- LOG.level = Logger::INFO
61
+ @@logger = nil
62
+ def self.logger
63
+ unless @@logger
64
+ self.logger = Logger.new($stdout)
65
+ self.logger.level = Logger::INFO
66
+ end
67
+ @@logger
68
+ end
69
+
70
+ def self.logger=(logger)
71
+ @@logger = logger
72
+ end
50
73
  end
@@ -60,7 +60,7 @@ at_exit do
60
60
  if options[:log]
61
61
  log = File.new(options[:log], 'a')
62
62
  log.sync = options[:debug]
63
- Blather::LOG.level = Logger::DEBUG if options[:debug]
63
+ Blather.logger.level = Logger::DEBUG if options[:debug]
64
64
  $stdout.reopen log
65
65
  $stderr.reopen $stdout
66
66
  end
@@ -40,7 +40,8 @@ module Blather #:nodoc:
40
40
  end
41
41
 
42
42
  def setup(jid, password, host = nil, port = nil)
43
- @setup = [JID.new(jid), password]
43
+ @jid = JID.new(jid)
44
+ @setup = [@jid, password]
44
45
  @setup << host if host
45
46
  @setup << port if port
46
47
  self
@@ -63,7 +64,6 @@ module Blather #:nodoc:
63
64
  end
64
65
 
65
66
  def write(stanza)
66
- stanza.from ||= jid if stanza.respond_to?(:from)
67
67
  @stream.send(stanza) if @stream
68
68
  end
69
69
 
@@ -73,11 +73,7 @@ module Blather #:nodoc:
73
73
  end
74
74
 
75
75
  def post_init
76
- case @stream
77
- when Stream::Component then ready!
78
- when Stream::Client then client_post_init
79
- else raise "Don't know #{@stream.class} stream type. How the hell did this happen!?"
80
- end
76
+ self.jid.node ? client_post_init : ready!
81
77
  end
82
78
 
83
79
  def close
@@ -93,7 +89,7 @@ module Blather #:nodoc:
93
89
  handler.call stanza
94
90
  else
95
91
  stanza.handler_heirarchy.each do |type|
96
- break if call_handler_for(type, stanza) && (stanza.is_a?(BlatherError) || stanza.type == :iq)
92
+ break if call_handler_for(type, stanza)# && (stanza.is_a?(BlatherError) || stanza.type == :iq)
97
93
  end
98
94
  end
99
95
  end
@@ -132,8 +128,15 @@ module Blather #:nodoc:
132
128
 
133
129
  def call_handler_for(type, stanza)
134
130
  if @handlers[type]
135
- @handlers[type].find { |guards, handler| handler.call(stanza) unless guarded?(guards, stanza) }
136
- true
131
+ @handlers[type].find do |guards, handler|
132
+ if guards.first.is_a?(String)
133
+ unless (result = stanza.find(*guards)).empty?
134
+ handler.call(stanza, result)
135
+ end
136
+ elsif !guarded?(guards, stanza)
137
+ handler.call(stanza)
138
+ end
139
+ end
137
140
  end
138
141
  end
139
142
 
@@ -171,9 +174,12 @@ module Blather #:nodoc:
171
174
  def check_guards(guards)
172
175
  guards.each do |guard|
173
176
  case guard
174
- when Array then guard.each { |g| check_guards([g]) }
175
- when Symbol, Proc, Hash then nil
176
- else raise "Bad guard: #{guard.inspect}"
177
+ when Array
178
+ guard.each { |g| check_guards([g]) }
179
+ when Symbol, Proc, Hash, String
180
+ nil
181
+ else
182
+ raise "Bad guard: #{guard.inspect}"
177
183
  end
178
184
  end
179
185
  end
@@ -2,11 +2,27 @@ require File.join(File.dirname(__FILE__), 'client')
2
2
 
3
3
  module Blather
4
4
  module DSL
5
+
6
+ autoload :PubSub, File.expand_path(File.join(File.dirname(__FILE__), *%w[dsl pubsub]))
7
+
5
8
  def client
6
9
  @client ||= Client.new
7
10
  end
8
11
  module_function :client
9
12
 
13
+ def pubsub
14
+ @pubsub ||= PubSub.new jid.domain
15
+ end
16
+
17
+ ##
18
+ # Push data to the stream
19
+ # This works such that it can be chained:
20
+ # self << stanza1 << stanza2 << "raw data"
21
+ def <<(stanza)
22
+ write stanza
23
+ self
24
+ end
25
+
10
26
  ##
11
27
  # Prepare server settings
12
28
  # setup [node@domain/resource], [password], [host], [port]
@@ -0,0 +1,133 @@
1
+ module Blather
2
+ module DSL
3
+
4
+ class PubSub
5
+ attr_accessor :host
6
+
7
+ def initialize(host)
8
+ @host = host
9
+ end
10
+
11
+ ##
12
+ # Retrieve Affiliations
13
+ # Yields a hash of affiliations in the form:
14
+ # {:aff_type => ['node1', 'node2']}
15
+ def affiliations(host = nil, &callback)
16
+ request Stanza::PubSub::Affiliations.new(:get, send_to(host)), :list, callback
17
+ end
18
+
19
+ ##
20
+ # Retrieve Subscriptions
21
+ # Yields a hash of subscriptions in the form:
22
+ # {:sub_type => [{:node => 'node1', :jid => 'j@d'}]}
23
+ def subscriptions(host = nil, &callback)
24
+ request Stanza::PubSub::Subscriptions.new(:get, send_to(host)), :list, callback
25
+ end
26
+
27
+ ##
28
+ # Discover Nodes
29
+ # Yields a list of DiscoItem::Item objects
30
+ # +path+ is the node's path. Default is '/'
31
+ def nodes(path = nil, host = nil, &callback)
32
+ path ||= '/'
33
+ stanza = Stanza::DiscoItems.new(:get, path)
34
+ stanza.to = send_to(host)
35
+ request stanza, :items, callback
36
+ end
37
+
38
+ ##
39
+ # Discover node information
40
+ # Yields a DiscoInfo node
41
+ # +path+ is the node's path
42
+ def node(path, host = nil, &callback)
43
+ stanza = Stanza::DiscoInfo.new(:get, path)
44
+ stanza.to = send_to(host)
45
+ request stanza, nil, callback
46
+ end
47
+
48
+ ##
49
+ # Retrieve items for a node
50
+ # +path+ is the node's path
51
+ # +list+ can be an array of items to retrieve
52
+ # +max+ can be the maximum number of items to return
53
+ def items(path, list = [], max = nil, host = nil, &callback)
54
+ request Stanza::PubSub::Items.request(send_to(host), path, list, max), :items, callback
55
+ end
56
+
57
+ ##
58
+ # Subscribe to a node
59
+ # Yields the resulting Subscription object
60
+ # +node+ is the node to subscribe to
61
+ # +jid+ is the jid that should be used. Defaults to the stripped current JID
62
+ def subscribe(node, jid = nil, host = nil)
63
+ jid ||= DSL.client.jid.stripped
64
+ request(Stanza::PubSub::Subscribe.new(:set, send_to(host), node, jid)) { |n| yield n if block_given? }
65
+ end
66
+
67
+ ##
68
+ # Unsubscribe from a node
69
+ # Yields the resulting Unsubscribe object
70
+ # +node+ is the node to subscribe to
71
+ # +jid+ is the jid that should be used. Defaults to the stripped current JID
72
+ def unsubscribe(node, jid = nil, host = nil)
73
+ jid ||= DSL.client.jid.stripped
74
+ request(Stanza::PubSub::Unsubscribe.new(:set, send_to(host), node, jid)) { |n| yield n if block_given? }
75
+ end
76
+
77
+ ##
78
+ # Publish an item to a node
79
+ # Yields the resulting Publish node
80
+ # +node+ is the node to publish to
81
+ # +payload+ is the payload to send (see Blather::Stanza::PubSub::Publish for details)
82
+ def publish(node, payload, host = nil)
83
+ request(Stanza::PubSub::Publish.new(send_to(host), node, :set, payload)) { |n| yield n if block_given? }
84
+ end
85
+
86
+ ##
87
+ # Delete items from a node
88
+ # Yields the resulting node
89
+ # +node+ is the node to retract items from
90
+ # +ids+ is a list of ids to retract. This can also be a single id
91
+ def retract(node, ids = [], host = nil)
92
+ request(Stanza::PubSub::Retract.new(send_to(host), node, :set, ids)) { |n| yield n if block_given? }
93
+ end
94
+
95
+ ##
96
+ # Create a node
97
+ # Yields the resulting node
98
+ # This does not (yet) handle configuration
99
+ # +node+ is the node to create
100
+ def create(node, host = nil)
101
+ request(Stanza::PubSub::Create.new(:set, send_to(host), node)) { |n| yield n if block_given? }
102
+ end
103
+
104
+ ##
105
+ # Purge all node items
106
+ # Yields the resulting node
107
+ # +node+ is the node to purge
108
+ def purge(node, host = nil)
109
+ request(Stanza::PubSubOwner::Purge.new(:set, send_to(host), node)) { |n| yield n if block_given? }
110
+ end
111
+
112
+ ##
113
+ # Delete a node
114
+ # Yields the resulting node
115
+ # +node+ is the node to delete
116
+ def delete(node, host = nil)
117
+ request(Stanza::PubSubOwner::Delete.new(:set, send_to(host), node)) { |n| yield n if block_given? }
118
+ end
119
+
120
+ private
121
+ def request(node, method = nil, callback = nil, &block)
122
+ block = lambda { |node| callback.call(method ? node.__send__(method) : node) } unless block_given?
123
+ DSL.client.write_with_handler(node, &block)
124
+ end
125
+
126
+ def send_to(host = nil)
127
+ raise 'You must provide a host' unless (host ||= @host)
128
+ host
129
+ end
130
+ end
131
+
132
+ end
133
+ end