blather 0.4.7 → 0.4.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/README.md +162 -0
  2. data/examples/{print_heirarchy.rb → print_hierarchy.rb} +5 -5
  3. data/examples/stream_only.rb +27 -0
  4. data/lib/blather.rb +4 -0
  5. data/lib/blather/client/client.rb +91 -73
  6. data/lib/blather/client/dsl.rb +156 -32
  7. data/lib/blather/client/dsl/pubsub.rb +86 -54
  8. data/lib/blather/core_ext/active_support.rb +9 -9
  9. data/lib/blather/core_ext/active_support/inheritable_attributes.rb +2 -2
  10. data/lib/blather/core_ext/nokogiri.rb +12 -7
  11. data/lib/blather/errors.rb +25 -14
  12. data/lib/blather/errors/sasl_error.rb +21 -3
  13. data/lib/blather/errors/stanza_error.rb +37 -21
  14. data/lib/blather/errors/stream_error.rb +27 -17
  15. data/lib/blather/jid.rb +79 -24
  16. data/lib/blather/roster.rb +39 -21
  17. data/lib/blather/roster_item.rb +43 -21
  18. data/lib/blather/stanza.rb +88 -40
  19. data/lib/blather/stanza/disco.rb +12 -2
  20. data/lib/blather/stanza/disco/disco_info.rb +112 -20
  21. data/lib/blather/stanza/disco/disco_items.rb +81 -12
  22. data/lib/blather/stanza/iq.rb +94 -38
  23. data/lib/blather/stanza/iq/query.rb +16 -22
  24. data/lib/blather/stanza/iq/roster.rb +98 -20
  25. data/lib/blather/stanza/message.rb +266 -111
  26. data/lib/blather/stanza/presence.rb +118 -42
  27. data/lib/blather/stanza/presence/status.rb +140 -60
  28. data/lib/blather/stanza/presence/subscription.rb +44 -10
  29. data/lib/blather/stanza/pubsub.rb +70 -15
  30. data/lib/blather/stanza/pubsub/affiliations.rb +36 -7
  31. data/lib/blather/stanza/pubsub/create.rb +26 -4
  32. data/lib/blather/stanza/pubsub/errors.rb +13 -4
  33. data/lib/blather/stanza/pubsub/event.rb +56 -10
  34. data/lib/blather/stanza/pubsub/items.rb +46 -6
  35. data/lib/blather/stanza/pubsub/publish.rb +52 -7
  36. data/lib/blather/stanza/pubsub/retract.rb +45 -6
  37. data/lib/blather/stanza/pubsub/subscribe.rb +30 -4
  38. data/lib/blather/stanza/pubsub/subscription.rb +74 -6
  39. data/lib/blather/stanza/pubsub/subscriptions.rb +35 -9
  40. data/lib/blather/stanza/pubsub/unsubscribe.rb +30 -4
  41. data/lib/blather/stanza/pubsub_owner.rb +17 -7
  42. data/lib/blather/stanza/pubsub_owner/delete.rb +23 -5
  43. data/lib/blather/stanza/pubsub_owner/purge.rb +23 -5
  44. data/lib/blather/stream.rb +96 -29
  45. data/lib/blather/stream/parser.rb +6 -9
  46. data/lib/blather/xmpp_node.rb +101 -153
  47. data/spec/blather/client/client_spec.rb +1 -1
  48. data/spec/blather/errors_spec.rb +5 -5
  49. data/spec/blather/stanza/message_spec.rb +56 -0
  50. data/spec/blather/stanza/presence/status_spec.rb +1 -1
  51. data/spec/blather/stanza_spec.rb +3 -3
  52. data/spec/blather/xmpp_node_spec.rb +19 -74
  53. metadata +6 -10
  54. data/README.rdoc +0 -185
  55. data/examples/drb_client.rb +0 -5
  56. data/examples/ping.rb +0 -11
  57. data/examples/pong.rb +0 -6
  58. data/examples/pubsub/cli.rb +0 -64
  59. data/examples/pubsub/ping_pong.rb +0 -18
@@ -2,53 +2,93 @@ module Blather
2
2
  class Stanza
3
3
  class PubSub
4
4
 
5
+ # # PubSub Items Stanza
6
+ #
7
+ # [XEP-0060 Section 6.5 - Retrieve Items from a Node](http://xmpp.org/extensions/xep-0060.html#subscriber-retrieve)
8
+ #
9
+ # @handler :pubsub_items
5
10
  class Items < PubSub
6
11
  register :pubsub_items, :items, self.registered_ns
7
12
 
8
13
  include Enumerable
9
14
  alias_method :find, :xpath
10
15
 
16
+ # Create a new Items request
17
+ #
18
+ # @param [String] host the pubsub host to send the request to
19
+ # @param [String] path the path of the node
20
+ # @param [Array<String>] list an array of IDs to request
21
+ # @param [#to_s] max the maximum number of items to return
22
+ #
23
+ # @return [Blather::Stanza::PubSub::Items]
11
24
  def self.request(host, path, list = [], max = nil)
12
25
  node = self.new :get, host
13
26
 
14
27
  node.node = path
15
28
  node.max_items = max
16
29
 
17
- (list || []).each { |id| node.items_node << PubSubItem.new(id, nil, node.document) }
30
+ (list || []).each do |id|
31
+ node.items_node << PubSubItem.new(id, nil, node.document)
32
+ end
18
33
 
19
34
  node
20
35
  end
21
36
 
37
+ # Overrides the parent to ensure an items node is created
38
+ # @private
22
39
  def self.new(type = nil, host = nil)
23
40
  new_node = super
24
41
  new_node.items
25
42
  new_node
26
43
  end
27
44
 
45
+ # Get the node name
46
+ #
47
+ # @return [String]
28
48
  def node
29
49
  items_node[:node]
30
50
  end
31
51
 
52
+ # Set the node name
53
+ #
54
+ # @param [String, nil] node
32
55
  def node=(node)
33
56
  items_node[:node] = node
34
57
  end
35
58
 
59
+ # Get the max number of items requested
60
+ #
61
+ # @return [Fixnum, nil]
36
62
  def max_items
37
63
  items_node[:max_items].to_i if items_node[:max_items]
38
64
  end
39
65
 
66
+ # Set the max number of items requested
67
+ #
68
+ # @param [Fixnum, nil] max_items
40
69
  def max_items=(max_items)
41
70
  items_node[:max_items] = max_items
42
71
  end
43
72
 
73
+ # Iterate over the list of items
74
+ #
75
+ # @yieldparam [Blather::Stanza::PubSub::PubSubItem] item
44
76
  def each(&block)
45
77
  items.each &block
46
78
  end
47
79
 
80
+ # Get the list of items on this stanza
81
+ #
82
+ # @return [Array<Blather::Stanza::PubSub::PubSubItem>]
48
83
  def items
49
- items_node.find('ns:item', :ns => self.class.registered_ns).map { |i| PubSubItem.new(nil,nil,self.document).inherit i }
84
+ items_node.find('ns:item', :ns => self.class.registered_ns).map do |i|
85
+ PubSubItem.new(nil,nil,self.document).inherit i
86
+ end
50
87
  end
51
88
 
89
+ # Get or create the actual items node
90
+ #
91
+ # @return [Blather::XMPPNode]
52
92
  def items_node
53
93
  unless node = self.pubsub.find_first('ns:items', :ns => self.class.registered_ns)
54
94
  (self.pubsub << (node = XMPPNode.new('items', self.document)))
@@ -56,8 +96,8 @@ class PubSub
56
96
  end
57
97
  node
58
98
  end
59
- end
99
+ end # Items
60
100
 
61
- end #PubSub
62
- end #Stanza
63
- end #Blather
101
+ end # PubSub
102
+ end # Stanza
103
+ end # Blather
@@ -2,12 +2,23 @@ module Blather
2
2
  class Stanza
3
3
  class PubSub
4
4
 
5
+ # # PubSub Publish Stanza
6
+ #
7
+ # [XEP-0060 Section 7.1 - Publish an Item to a Node](http://xmpp.org/extensions/xep-0060.html#publisher-publish)
8
+ #
9
+ # @handler :pubsub_publish
5
10
  class Publish < PubSub
6
11
  register :pubsub_publish, :publish, self.registered_ns
7
12
 
8
13
  include Enumerable
9
14
  alias_method :find, :xpath
10
15
 
16
+ # Create a new publish node
17
+ #
18
+ # @param [String, nil] host the host to pushlish the node to
19
+ # @param [String, nil] node the name of the node to publish to
20
+ # @param [Blather::Stanza::Iq::VALID_TYPES] type the node type
21
+ # @param [#to_s] payload the payload to publish see {#payload=}
11
22
  def self.new(host = nil, node = nil, type = :set, payload = nil)
12
23
  new_node = super(type, host)
13
24
  new_node.node = node
@@ -15,23 +26,45 @@ class PubSub
15
26
  new_node
16
27
  end
17
28
 
29
+ # Set the payload to publish
30
+ #
31
+ # @overload payload=(hash)
32
+ # Set the payload as a set of ID => payload entries
33
+ # @param [Hash<id => payload>] hash
34
+ # @overload payload=(array)
35
+ # Set the list of payloads all at once
36
+ # @param [Array<#to_s>] array
37
+ # @overload payload=(string)
38
+ # Set the payload as a string
39
+ # @param [#to_s] string
18
40
  def payload=(payload)
19
41
  payload = case payload
20
42
  when Hash then payload.to_a
21
43
  when Array then payload.map { |v| [nil, v] }
22
- else [[nil, payload.to_s]]
44
+ else [[nil, payload]]
45
+ end
46
+ payload.each do |id, value|
47
+ self.publish << PubSubItem.new(id, value, self.document)
23
48
  end
24
- payload.each { |id,value| self.publish << PubSubItem.new(id, value, self.document) }
25
49
  end
26
50
 
51
+ # Get the name of the node to publish to
52
+ #
53
+ # @return [String, nil]
27
54
  def node
28
55
  publish[:node]
29
56
  end
30
57
 
58
+ # Set the name of the node to publish to
59
+ #
60
+ # @param [String, nil] node
31
61
  def node=(node)
32
62
  publish[:node] = node
33
63
  end
34
64
 
65
+ # Get or create the actual publish node
66
+ #
67
+ # @return [Blather::XMPPNode]
35
68
  def publish
36
69
  unless publish = pubsub.find_first('ns:publish', :ns => self.class.registered_ns)
37
70
  self.pubsub << (publish = XMPPNode.new('publish', self.document))
@@ -40,19 +73,31 @@ class PubSub
40
73
  publish
41
74
  end
42
75
 
76
+ # Get the list of items
77
+ #
78
+ # @return [Array<Blather::Stanza::PubSub::PubSubItem>]
43
79
  def items
44
- publish.find('ns:item', :ns => self.class.registered_ns).map { |i| PubSubItem.new(nil,nil,self.document).inherit i }
80
+ publish.find('ns:item', :ns => self.class.registered_ns).map do |i|
81
+ PubSubItem.new(nil,nil,self.document).inherit i
82
+ end
45
83
  end
46
84
 
85
+ # Iterate over the list of items
86
+ #
87
+ # @yield [item] a block to accept each item
88
+ # @yieldparam [Blather::Stanza::PubSub::PubSubItem]
47
89
  def each(&block)
48
90
  items.each &block
49
91
  end
50
92
 
93
+ # Get the size of the items list
94
+ #
95
+ # @return [Fixnum]
51
96
  def size
52
97
  items.size
53
98
  end
54
- end #Publish
99
+ end # Publish
55
100
 
56
- end #PubSub
57
- end #Stanza
58
- end #Blather
101
+ end # PubSub
102
+ end # Stanza
103
+ end # Blather
@@ -2,12 +2,23 @@ module Blather
2
2
  class Stanza
3
3
  class PubSub
4
4
 
5
+ # # PubSub Retract Stanza
6
+ #
7
+ # [XEP-0060 Section 7.2 - Delete an Item from a Node](http://xmpp.org/extensions/xep-0060.html#publisher-delete)
8
+ #
9
+ # @handler :pubsub_retract
5
10
  class Retract < PubSub
6
11
  register :pubsub_retract, :retract, self.registered_ns
7
12
 
8
13
  include Enumerable
9
14
  alias_method :find, :xpath
10
15
 
16
+ # Createa new Retraction stanza
17
+ #
18
+ # @param [String] host the host to send the request to
19
+ # @param [String] node the node to retract items from
20
+ # @param [Blather::Stanza::Iq::VALID_TYPES] type the IQ stanza type
21
+ # @param [Array<String>] retractions an array of ids to retract
11
22
  def self.new(host = nil, node = nil, type = :set, retractions = [])
12
23
  new_node = super(type, host)
13
24
  new_node.node = node
@@ -15,14 +26,23 @@ class PubSub
15
26
  new_node
16
27
  end
17
28
 
29
+ # Get the name of the node to retract from
30
+ #
31
+ # @return [String]
18
32
  def node
19
33
  retract[:node]
20
34
  end
21
35
 
36
+ # Set the name of the node to retract from
37
+ #
38
+ # @param [String] node
22
39
  def node=(node)
23
40
  retract[:node] = node
24
41
  end
25
42
 
43
+ # Get or create the actual retract node
44
+ #
45
+ # @return [Blather::XMPPNode]
26
46
  def retract
27
47
  unless retract = pubsub.find_first('ns:retract', :ns => self.class.registered_ns)
28
48
  self.pubsub << (retract = XMPPNode.new('retract', self.document))
@@ -31,23 +51,42 @@ class PubSub
31
51
  retract
32
52
  end
33
53
 
54
+ # Set the retraction ids
55
+ #
56
+ # @overload retractions=(id)
57
+ # @param [String] id an ID to retract
58
+ # @overload retractions=(ids)
59
+ # @param [Array<String>] ids an array of IDs to retract
34
60
  def retractions=(retractions = [])
35
- [retractions].flatten.each { |id| self.retract << PubSubItem.new(id, nil, self.document) }
61
+ [retractions].flatten.each do |id|
62
+ self.retract << PubSubItem.new(id, nil, self.document)
63
+ end
36
64
  end
37
65
 
66
+ # Get the list of item IDs to retract
67
+ #
68
+ # @return [Array<String>]
38
69
  def retractions
39
- retract.find('ns:item', :ns => self.class.registered_ns).map { |i| i[:id] }
70
+ retract.find('ns:item', :ns => self.class.registered_ns).map do |i|
71
+ i[:id]
72
+ end
40
73
  end
41
74
 
75
+ # Iterate over each retraction ID
76
+ #
77
+ # @yieldparam [String] id an ID to retract
42
78
  def each(&block)
43
79
  retractions.each &block
44
80
  end
45
81
 
82
+ # The size of the retractions array
83
+ #
84
+ # @return [Fixnum]
46
85
  def size
47
86
  retractions.size
48
87
  end
49
- end #Retract
88
+ end # Retract
50
89
 
51
- end #PubSub
52
- end #Stanza
53
- end #Blather
90
+ end # PubSub
91
+ end # Stanza
92
+ end # Blather
@@ -2,9 +2,20 @@ module Blather
2
2
  class Stanza
3
3
  class PubSub
4
4
 
5
+ # # PubSub Subscribe Stanza
6
+ #
7
+ # [XEP-0060 Section 6.1 - Subscribe to a Node](http://xmpp.org/extensions/xep-0060.html#subscriber-subscribe)
8
+ #
9
+ # @handler :pubsub_subscribe
5
10
  class Subscribe < PubSub
6
11
  register :pubsub_subscribe, :subscribe, self.registered_ns
7
12
 
13
+ # Create a new subscription node
14
+ #
15
+ # @param [Blather::Stanza::Iq::VALID_TYPES] type the IQ stanza type
16
+ # @param [String] host the host name to send the request to
17
+ # @param [String] node the node to subscribe to
18
+ # @param [Blather::JID, #to_s] jid see {#jid=}
8
19
  def self.new(type = :set, host = nil, node = nil, jid = nil)
9
20
  new_node = super(type, host)
10
21
  new_node.node = node
@@ -12,22 +23,37 @@ class PubSub
12
23
  new_node
13
24
  end
14
25
 
26
+ # Get the JID of the entity to subscribe
27
+ #
28
+ # @return [Blather::JID]
15
29
  def jid
16
30
  JID.new(subscribe[:jid])
17
31
  end
18
32
 
33
+ # Set the JID of the entity to subscribe
34
+ #
35
+ # @param [Blather::JID, #to_s] jid
19
36
  def jid=(jid)
20
37
  subscribe[:jid] = jid
21
38
  end
22
39
 
40
+ # Get the name of the node to subscribe to
41
+ #
42
+ # @return [String]
23
43
  def node
24
44
  subscribe[:node]
25
45
  end
26
46
 
47
+ # Set the name of the node to subscribe to
48
+ #
49
+ # @param [String] node
27
50
  def node=(node)
28
51
  subscribe[:node] = node
29
52
  end
30
53
 
54
+ # Get or create the actual subscribe node on the stanza
55
+ #
56
+ # @return [Blather::XMPPNode]
31
57
  def subscribe
32
58
  unless subscribe = pubsub.find_first('ns:subscribe', :ns => self.class.registered_ns)
33
59
  self.pubsub << (subscribe = XMPPNode.new('subscribe', self.document))
@@ -35,8 +61,8 @@ class PubSub
35
61
  end
36
62
  subscribe
37
63
  end
38
- end #Subscribe
64
+ end # Subscribe
39
65
 
40
- end #PubSub
41
- end #Stanza
42
- end #Blather
66
+ end # PubSub
67
+ end # Stanza
68
+ end # Blather
@@ -2,11 +2,24 @@ module Blather
2
2
  class Stanza
3
3
  class PubSub
4
4
 
5
+ # # PubSub Subscription Stanza
6
+ #
7
+ # [XEP-0060 Section 8.8 Manage Subscriptions](http://xmpp.org/extensions/xep-0060.html#owner-subscriptions)
8
+ #
9
+ # @handler :pubsub_subscription
5
10
  class Subscription < PubSub
6
11
  VALID_TYPES = [:none, :pending, :subscribed, :unconfigured]
7
12
 
8
13
  register :pubsub_subscription, :subscription, self.registered_ns
9
14
 
15
+ # Create a new subscription request node
16
+ #
17
+ # @param [Blather::Stanza::Iq::VALID_TYPES] type the IQ type
18
+ # @param [String] host the host to send the request to
19
+ # @param [String] node the node to look for requests on
20
+ # @param [Blather::JID, #to_s] jid the JID of the subscriber
21
+ # @param [String] subid the subscription ID
22
+ # @param [VALID_TYPES] subscription the subscription type
10
23
  def self.new(type = :result, host = nil, node = nil, jid = nil, subid = nil, subscription = nil)
11
24
  new_node = super(type, host)
12
25
  new_node.node = node
@@ -16,42 +29,97 @@ class PubSub
16
29
  new_node
17
30
  end
18
31
 
19
- attribute_helpers_for :subscription, VALID_TYPES
32
+ # Check if the type is none
33
+ #
34
+ # @return [Boolean]
35
+ def none?
36
+ self.subscription == :none
37
+ end
38
+
39
+ # Check if the type is pending
40
+ #
41
+ # @return [Boolean]
42
+ def pending?
43
+ self.subscription == :pending
44
+ end
45
+
46
+ # Check if the type is subscribed
47
+ #
48
+ # @return [Boolean]
49
+ def subscribed?
50
+ self.subscription == :subscribed
51
+ end
52
+
53
+ # Check if the type is unconfigured
54
+ #
55
+ # @return [Boolean]
56
+ def unconfigured?
57
+ self.subscription == :unconfigured
58
+ end
20
59
 
60
+ # Get the JID of the subscriber
61
+ #
62
+ # @return [Blather::JID]
21
63
  def jid
22
64
  JID.new(subscription_node[:jid])
23
65
  end
24
66
 
67
+ # Set the JID of the subscriber
68
+ #
69
+ # @param [Blather::JID, #to_s] jid
25
70
  def jid=(jid)
26
71
  subscription_node[:jid] = jid
27
72
  end
28
73
 
74
+ # Get the name of the subscription node
75
+ #
76
+ # @return [String]
29
77
  def node
30
78
  subscription_node[:node]
31
79
  end
32
80
 
81
+ # Set the name of the subscription node
82
+ #
83
+ # @param [String] node
33
84
  def node=(node)
34
85
  subscription_node[:node] = node
35
86
  end
36
87
 
88
+ # Get the ID of the subscription
89
+ #
90
+ # @return [String]
37
91
  def subid
38
92
  subscription_node[:subid]
39
93
  end
40
94
 
95
+ # Set the ID of the subscription
96
+ #
97
+ # @param [String] subid
41
98
  def subid=(subid)
42
99
  subscription_node[:subid] = subid
43
100
  end
44
101
 
102
+ # Get the subscription type
103
+ #
104
+ # @return [VALID_TYPES, nil]
45
105
  def subscription
46
106
  s = subscription_node[:subscription]
47
107
  s.to_sym if s
48
108
  end
49
109
 
110
+ # Set the subscription type
111
+ #
112
+ # @param [VALID_TYPES, nil] subscription
50
113
  def subscription=(subscription)
51
- raise ArgumentError, "Invalid Type (#{type}), use: #{VALID_TYPES*' '}" if subscription && !VALID_TYPES.include?(subscription.to_sym)
114
+ if subscription && !VALID_TYPES.include?(subscription.to_sym)
115
+ raise ArgumentError, "Invalid Type (#{type}), use: #{VALID_TYPES*' '}"
116
+ end
52
117
  subscription_node[:subscription] = subscription
53
118
  end
54
119
 
120
+ # Get or create the actual subscription node
121
+ #
122
+ # @return [Blather::XMPPNode]
55
123
  def subscription_node
56
124
  unless subscription = pubsub.find_first('ns:subscription', :ns => self.class.registered_ns)
57
125
  self.pubsub << (subscription = XMPPNode.new('subscription', self.document))
@@ -59,8 +127,8 @@ class PubSub
59
127
  end
60
128
  subscription
61
129
  end
62
- end #Subscribe
130
+ end # Subscribe
63
131
 
64
- end #PubSub
65
- end #Stanza
66
- end #Blather
132
+ end # PubSub
133
+ end # Stanza
134
+ end # Blather