shingara-blather 0.4.8

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 (100) hide show
  1. data/LICENSE +22 -0
  2. data/README.md +162 -0
  3. data/examples/echo.rb +18 -0
  4. data/examples/execute.rb +16 -0
  5. data/examples/ping_pong.rb +37 -0
  6. data/examples/print_hierarchy.rb +76 -0
  7. data/examples/rosterprint.rb +14 -0
  8. data/examples/stream_only.rb +27 -0
  9. data/examples/xmpp4r/echo.rb +35 -0
  10. data/lib/blather/client/client.rb +310 -0
  11. data/lib/blather/client/dsl/pubsub.rb +170 -0
  12. data/lib/blather/client/dsl.rb +264 -0
  13. data/lib/blather/client.rb +87 -0
  14. data/lib/blather/core_ext/nokogiri.rb +40 -0
  15. data/lib/blather/errors/sasl_error.rb +43 -0
  16. data/lib/blather/errors/stanza_error.rb +107 -0
  17. data/lib/blather/errors/stream_error.rb +82 -0
  18. data/lib/blather/errors.rb +69 -0
  19. data/lib/blather/jid.rb +142 -0
  20. data/lib/blather/roster.rb +111 -0
  21. data/lib/blather/roster_item.rb +122 -0
  22. data/lib/blather/stanza/disco/disco_info.rb +176 -0
  23. data/lib/blather/stanza/disco/disco_items.rb +132 -0
  24. data/lib/blather/stanza/disco.rb +25 -0
  25. data/lib/blather/stanza/iq/query.rb +53 -0
  26. data/lib/blather/stanza/iq/roster.rb +179 -0
  27. data/lib/blather/stanza/iq.rb +138 -0
  28. data/lib/blather/stanza/message.rb +332 -0
  29. data/lib/blather/stanza/presence/status.rb +212 -0
  30. data/lib/blather/stanza/presence/subscription.rb +101 -0
  31. data/lib/blather/stanza/presence.rb +163 -0
  32. data/lib/blather/stanza/pubsub/affiliations.rb +79 -0
  33. data/lib/blather/stanza/pubsub/create.rb +65 -0
  34. data/lib/blather/stanza/pubsub/errors.rb +18 -0
  35. data/lib/blather/stanza/pubsub/event.rb +123 -0
  36. data/lib/blather/stanza/pubsub/items.rb +103 -0
  37. data/lib/blather/stanza/pubsub/publish.rb +103 -0
  38. data/lib/blather/stanza/pubsub/retract.rb +92 -0
  39. data/lib/blather/stanza/pubsub/subscribe.rb +68 -0
  40. data/lib/blather/stanza/pubsub/subscription.rb +134 -0
  41. data/lib/blather/stanza/pubsub/subscriptions.rb +81 -0
  42. data/lib/blather/stanza/pubsub/unsubscribe.rb +68 -0
  43. data/lib/blather/stanza/pubsub.rb +129 -0
  44. data/lib/blather/stanza/pubsub_owner/delete.rb +52 -0
  45. data/lib/blather/stanza/pubsub_owner/purge.rb +52 -0
  46. data/lib/blather/stanza/pubsub_owner.rb +51 -0
  47. data/lib/blather/stanza.rb +149 -0
  48. data/lib/blather/stream/client.rb +31 -0
  49. data/lib/blather/stream/component.rb +38 -0
  50. data/lib/blather/stream/features/resource.rb +63 -0
  51. data/lib/blather/stream/features/sasl.rb +187 -0
  52. data/lib/blather/stream/features/session.rb +44 -0
  53. data/lib/blather/stream/features/tls.rb +28 -0
  54. data/lib/blather/stream/features.rb +53 -0
  55. data/lib/blather/stream/parser.rb +102 -0
  56. data/lib/blather/stream.rb +231 -0
  57. data/lib/blather/xmpp_node.rb +218 -0
  58. data/lib/blather.rb +78 -0
  59. data/spec/blather/client/client_spec.rb +559 -0
  60. data/spec/blather/client/dsl/pubsub_spec.rb +462 -0
  61. data/spec/blather/client/dsl_spec.rb +143 -0
  62. data/spec/blather/core_ext/nokogiri_spec.rb +83 -0
  63. data/spec/blather/errors/sasl_error_spec.rb +33 -0
  64. data/spec/blather/errors/stanza_error_spec.rb +129 -0
  65. data/spec/blather/errors/stream_error_spec.rb +108 -0
  66. data/spec/blather/errors_spec.rb +33 -0
  67. data/spec/blather/jid_spec.rb +87 -0
  68. data/spec/blather/roster_item_spec.rb +96 -0
  69. data/spec/blather/roster_spec.rb +103 -0
  70. data/spec/blather/stanza/discos/disco_info_spec.rb +226 -0
  71. data/spec/blather/stanza/discos/disco_items_spec.rb +148 -0
  72. data/spec/blather/stanza/iq/query_spec.rb +64 -0
  73. data/spec/blather/stanza/iq/roster_spec.rb +140 -0
  74. data/spec/blather/stanza/iq_spec.rb +45 -0
  75. data/spec/blather/stanza/message_spec.rb +132 -0
  76. data/spec/blather/stanza/presence/status_spec.rb +132 -0
  77. data/spec/blather/stanza/presence/subscription_spec.rb +105 -0
  78. data/spec/blather/stanza/presence_spec.rb +66 -0
  79. data/spec/blather/stanza/pubsub/affiliations_spec.rb +57 -0
  80. data/spec/blather/stanza/pubsub/create_spec.rb +56 -0
  81. data/spec/blather/stanza/pubsub/event_spec.rb +84 -0
  82. data/spec/blather/stanza/pubsub/items_spec.rb +79 -0
  83. data/spec/blather/stanza/pubsub/publish_spec.rb +83 -0
  84. data/spec/blather/stanza/pubsub/retract_spec.rb +75 -0
  85. data/spec/blather/stanza/pubsub/subscribe_spec.rb +61 -0
  86. data/spec/blather/stanza/pubsub/subscription_spec.rb +97 -0
  87. data/spec/blather/stanza/pubsub/subscriptions_spec.rb +59 -0
  88. data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +61 -0
  89. data/spec/blather/stanza/pubsub_owner/delete_spec.rb +50 -0
  90. data/spec/blather/stanza/pubsub_owner/purge_spec.rb +50 -0
  91. data/spec/blather/stanza/pubsub_owner_spec.rb +27 -0
  92. data/spec/blather/stanza/pubsub_spec.rb +67 -0
  93. data/spec/blather/stanza_spec.rb +116 -0
  94. data/spec/blather/stream/client_spec.rb +1011 -0
  95. data/spec/blather/stream/component_spec.rb +95 -0
  96. data/spec/blather/stream/parser_spec.rb +145 -0
  97. data/spec/blather/xmpp_node_spec.rb +231 -0
  98. data/spec/fixtures/pubsub.rb +311 -0
  99. data/spec/spec_helper.rb +43 -0
  100. metadata +249 -0
@@ -0,0 +1,123 @@
1
+ module Blather
2
+ class Stanza
3
+ class PubSub
4
+
5
+ # # PubSub Event Stanza
6
+ #
7
+ # [XEP-0060](http://xmpp.org/extensions/xep-0060.html)
8
+ #
9
+ # The PubSub Event stanza is used in many places. Please see the XEP for more
10
+ # information.
11
+ #
12
+ # @handler :pubsub_event
13
+ class Event < Message
14
+ SHIM_NS = 'http://jabber.org/protocol/shim'.freeze
15
+
16
+ register :pubsub_event, :event, 'http://jabber.org/protocol/pubsub#event'
17
+
18
+ # Ensures the event_node is created
19
+ # @private
20
+ def self.new(type = nil)
21
+ node = super
22
+ node.event_node
23
+ node
24
+ end
25
+
26
+ # Kill the event_node node before running inherit
27
+ # @private
28
+ def inherit(node)
29
+ event_node.remove
30
+ super
31
+ end
32
+
33
+ # Get the name of the node
34
+ #
35
+ # @return [String, nil]
36
+ def node
37
+ !purge? ? items_node[:node] : purge_node[:node]
38
+ end
39
+
40
+ # Get a list of retractions
41
+ #
42
+ # @return [Array<String>]
43
+ def retractions
44
+ items_node.find('//ns:retract', :ns => self.class.registered_ns).map do |i|
45
+ i[:id]
46
+ end
47
+ end
48
+
49
+ # Check if this is a retractions stanza
50
+ #
51
+ # @return [Boolean]
52
+ def retractions?
53
+ !retractions.empty?
54
+ end
55
+
56
+ # Get the list of items attached to this event
57
+ #
58
+ # @return [Array<Blather::Stanza::PubSub::PubSubItem>]
59
+ def items
60
+ items_node.find('//ns:item', :ns => self.class.registered_ns).map do |i|
61
+ PubSubItem.new(nil,nil,self.document).inherit i
62
+ end
63
+ end
64
+
65
+ # Check if this stanza has items
66
+ #
67
+ # @return [Boolean]
68
+ def items?
69
+ !items.empty?
70
+ end
71
+
72
+ # Check if this is a purge stanza
73
+ #
74
+ # @return [XML::Node, nil]
75
+ def purge?
76
+ purge_node
77
+ end
78
+
79
+ # Get or create the actual event node
80
+ #
81
+ # @return [Blather::XMPPNode]
82
+ def event_node
83
+ node = find_first('//ns:event', :ns => self.class.registered_ns)
84
+ node = find_first('//event', self.class.registered_ns) unless node
85
+ unless node
86
+ (self << (node = XMPPNode.new('event', self.document)))
87
+ node.namespace = self.class.registered_ns
88
+ end
89
+ node
90
+ end
91
+
92
+ # Get or create the actual items node
93
+ #
94
+ # @return [Blather::XMPPNode]
95
+ def items_node
96
+ node = find_first('ns:event/ns:items', :ns => self.class.registered_ns)
97
+ unless node
98
+ (self.event_node << (node = XMPPNode.new('items', self.document)))
99
+ node.namespace = event_node.namespace
100
+ end
101
+ node
102
+ end
103
+
104
+ # Get the actual purge node
105
+ #
106
+ # @return [Blather::XMPPNode]
107
+ def purge_node
108
+ event_node.find_first('//ns:purge', :ns => self.class.registered_ns)
109
+ end
110
+
111
+ # Get the subscription IDs associated with this event
112
+ #
113
+ # @return [Array<String>]
114
+ def subscription_ids
115
+ find('//ns:header[@name="SubID"]', :ns => SHIM_NS).map do |n|
116
+ n.content
117
+ end
118
+ end
119
+ end # Event
120
+
121
+ end # PubSub
122
+ end # Stanza
123
+ end # Blather
@@ -0,0 +1,103 @@
1
+ module Blather
2
+ class Stanza
3
+ class PubSub
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
10
+ class Items < PubSub
11
+ register :pubsub_items, :items, self.registered_ns
12
+
13
+ include Enumerable
14
+ alias_method :find, :xpath
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]
24
+ def self.request(host, path, list = [], max = nil)
25
+ node = self.new :get, host
26
+
27
+ node.node = path
28
+ node.max_items = max
29
+
30
+ (list || []).each do |id|
31
+ node.items_node << PubSubItem.new(id, nil, node.document)
32
+ end
33
+
34
+ node
35
+ end
36
+
37
+ # Overrides the parent to ensure an items node is created
38
+ # @private
39
+ def self.new(type = nil, host = nil)
40
+ new_node = super
41
+ new_node.items
42
+ new_node
43
+ end
44
+
45
+ # Get the node name
46
+ #
47
+ # @return [String]
48
+ def node
49
+ items_node[:node]
50
+ end
51
+
52
+ # Set the node name
53
+ #
54
+ # @param [String, nil] node
55
+ def node=(node)
56
+ items_node[:node] = node
57
+ end
58
+
59
+ # Get the max number of items requested
60
+ #
61
+ # @return [Fixnum, nil]
62
+ def max_items
63
+ items_node[:max_items].to_i if items_node[:max_items]
64
+ end
65
+
66
+ # Set the max number of items requested
67
+ #
68
+ # @param [Fixnum, nil] max_items
69
+ def max_items=(max_items)
70
+ items_node[:max_items] = max_items
71
+ end
72
+
73
+ # Iterate over the list of items
74
+ #
75
+ # @yieldparam [Blather::Stanza::PubSub::PubSubItem] item
76
+ def each(&block)
77
+ items.each &block
78
+ end
79
+
80
+ # Get the list of items on this stanza
81
+ #
82
+ # @return [Array<Blather::Stanza::PubSub::PubSubItem>]
83
+ def items
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
87
+ end
88
+
89
+ # Get or create the actual items node
90
+ #
91
+ # @return [Blather::XMPPNode]
92
+ def items_node
93
+ unless node = self.pubsub.find_first('ns:items', :ns => self.class.registered_ns)
94
+ (self.pubsub << (node = XMPPNode.new('items', self.document)))
95
+ node.namespace = self.pubsub.namespace
96
+ end
97
+ node
98
+ end
99
+ end # Items
100
+
101
+ end # PubSub
102
+ end # Stanza
103
+ end # Blather
@@ -0,0 +1,103 @@
1
+ module Blather
2
+ class Stanza
3
+ class PubSub
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
10
+ class Publish < PubSub
11
+ register :pubsub_publish, :publish, self.registered_ns
12
+
13
+ include Enumerable
14
+ alias_method :find, :xpath
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=}
22
+ def self.new(host = nil, node = nil, type = :set, payload = nil)
23
+ new_node = super(type, host)
24
+ new_node.node = node
25
+ new_node.payload = payload if payload
26
+ new_node
27
+ end
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
40
+ def payload=(payload)
41
+ payload = case payload
42
+ when Hash then payload.to_a
43
+ when Array then payload.map { |v| [nil, v] }
44
+ else [[nil, payload]]
45
+ end
46
+ payload.each do |id, value|
47
+ self.publish << PubSubItem.new(id, value, self.document)
48
+ end
49
+ end
50
+
51
+ # Get the name of the node to publish to
52
+ #
53
+ # @return [String, nil]
54
+ def node
55
+ publish[:node]
56
+ end
57
+
58
+ # Set the name of the node to publish to
59
+ #
60
+ # @param [String, nil] node
61
+ def node=(node)
62
+ publish[:node] = node
63
+ end
64
+
65
+ # Get or create the actual publish node
66
+ #
67
+ # @return [Blather::XMPPNode]
68
+ def publish
69
+ unless publish = pubsub.find_first('ns:publish', :ns => self.class.registered_ns)
70
+ self.pubsub << (publish = XMPPNode.new('publish', self.document))
71
+ publish.namespace = self.pubsub.namespace
72
+ end
73
+ publish
74
+ end
75
+
76
+ # Get the list of items
77
+ #
78
+ # @return [Array<Blather::Stanza::PubSub::PubSubItem>]
79
+ def items
80
+ publish.find('ns:item', :ns => self.class.registered_ns).map do |i|
81
+ PubSubItem.new(nil,nil,self.document).inherit i
82
+ end
83
+ end
84
+
85
+ # Iterate over the list of items
86
+ #
87
+ # @yield [item] a block to accept each item
88
+ # @yieldparam [Blather::Stanza::PubSub::PubSubItem]
89
+ def each(&block)
90
+ items.each &block
91
+ end
92
+
93
+ # Get the size of the items list
94
+ #
95
+ # @return [Fixnum]
96
+ def size
97
+ items.size
98
+ end
99
+ end # Publish
100
+
101
+ end # PubSub
102
+ end # Stanza
103
+ end # Blather
@@ -0,0 +1,92 @@
1
+ module Blather
2
+ class Stanza
3
+ class PubSub
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
10
+ class Retract < PubSub
11
+ register :pubsub_retract, :retract, self.registered_ns
12
+
13
+ include Enumerable
14
+ alias_method :find, :xpath
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
22
+ def self.new(host = nil, node = nil, type = :set, retractions = [])
23
+ new_node = super(type, host)
24
+ new_node.node = node
25
+ new_node.retractions = retractions
26
+ new_node
27
+ end
28
+
29
+ # Get the name of the node to retract from
30
+ #
31
+ # @return [String]
32
+ def node
33
+ retract[:node]
34
+ end
35
+
36
+ # Set the name of the node to retract from
37
+ #
38
+ # @param [String] node
39
+ def node=(node)
40
+ retract[:node] = node
41
+ end
42
+
43
+ # Get or create the actual retract node
44
+ #
45
+ # @return [Blather::XMPPNode]
46
+ def retract
47
+ unless retract = pubsub.find_first('ns:retract', :ns => self.class.registered_ns)
48
+ self.pubsub << (retract = XMPPNode.new('retract', self.document))
49
+ retract.namespace = self.pubsub.namespace
50
+ end
51
+ retract
52
+ end
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
60
+ def retractions=(retractions = [])
61
+ [retractions].flatten.each do |id|
62
+ self.retract << PubSubItem.new(id, nil, self.document)
63
+ end
64
+ end
65
+
66
+ # Get the list of item IDs to retract
67
+ #
68
+ # @return [Array<String>]
69
+ def retractions
70
+ retract.find('ns:item', :ns => self.class.registered_ns).map do |i|
71
+ i[:id]
72
+ end
73
+ end
74
+
75
+ # Iterate over each retraction ID
76
+ #
77
+ # @yieldparam [String] id an ID to retract
78
+ def each(&block)
79
+ retractions.each &block
80
+ end
81
+
82
+ # The size of the retractions array
83
+ #
84
+ # @return [Fixnum]
85
+ def size
86
+ retractions.size
87
+ end
88
+ end # Retract
89
+
90
+ end # PubSub
91
+ end # Stanza
92
+ end # Blather
@@ -0,0 +1,68 @@
1
+ module Blather
2
+ class Stanza
3
+ class PubSub
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
10
+ class Subscribe < PubSub
11
+ register :pubsub_subscribe, :subscribe, self.registered_ns
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=}
19
+ def self.new(type = :set, host = nil, node = nil, jid = nil)
20
+ new_node = super(type, host)
21
+ new_node.node = node
22
+ new_node.jid = jid
23
+ new_node
24
+ end
25
+
26
+ # Get the JID of the entity to subscribe
27
+ #
28
+ # @return [Blather::JID]
29
+ def jid
30
+ JID.new(subscribe[:jid])
31
+ end
32
+
33
+ # Set the JID of the entity to subscribe
34
+ #
35
+ # @param [Blather::JID, #to_s] jid
36
+ def jid=(jid)
37
+ subscribe[:jid] = jid
38
+ end
39
+
40
+ # Get the name of the node to subscribe to
41
+ #
42
+ # @return [String]
43
+ def node
44
+ subscribe[:node]
45
+ end
46
+
47
+ # Set the name of the node to subscribe to
48
+ #
49
+ # @param [String] node
50
+ def node=(node)
51
+ subscribe[:node] = node
52
+ end
53
+
54
+ # Get or create the actual subscribe node on the stanza
55
+ #
56
+ # @return [Blather::XMPPNode]
57
+ def subscribe
58
+ unless subscribe = pubsub.find_first('ns:subscribe', :ns => self.class.registered_ns)
59
+ self.pubsub << (subscribe = XMPPNode.new('subscribe', self.document))
60
+ subscribe.namespace = self.pubsub.namespace
61
+ end
62
+ subscribe
63
+ end
64
+ end # Subscribe
65
+
66
+ end # PubSub
67
+ end # Stanza
68
+ end # Blather
@@ -0,0 +1,134 @@
1
+ module Blather
2
+ class Stanza
3
+ class PubSub
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
10
+ class Subscription < PubSub
11
+ VALID_TYPES = [:none, :pending, :subscribed, :unconfigured]
12
+
13
+ register :pubsub_subscription, :subscription, self.registered_ns
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
23
+ def self.new(type = :result, host = nil, node = nil, jid = nil, subid = nil, subscription = nil)
24
+ new_node = super(type, host)
25
+ new_node.node = node
26
+ new_node.jid = jid
27
+ new_node.subid = subid
28
+ new_node.subscription = subscription
29
+ new_node
30
+ end
31
+
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
59
+
60
+ # Get the JID of the subscriber
61
+ #
62
+ # @return [Blather::JID]
63
+ def jid
64
+ JID.new(subscription_node[:jid])
65
+ end
66
+
67
+ # Set the JID of the subscriber
68
+ #
69
+ # @param [Blather::JID, #to_s] jid
70
+ def jid=(jid)
71
+ subscription_node[:jid] = jid
72
+ end
73
+
74
+ # Get the name of the subscription node
75
+ #
76
+ # @return [String]
77
+ def node
78
+ subscription_node[:node]
79
+ end
80
+
81
+ # Set the name of the subscription node
82
+ #
83
+ # @param [String] node
84
+ def node=(node)
85
+ subscription_node[:node] = node
86
+ end
87
+
88
+ # Get the ID of the subscription
89
+ #
90
+ # @return [String]
91
+ def subid
92
+ subscription_node[:subid]
93
+ end
94
+
95
+ # Set the ID of the subscription
96
+ #
97
+ # @param [String] subid
98
+ def subid=(subid)
99
+ subscription_node[:subid] = subid
100
+ end
101
+
102
+ # Get the subscription type
103
+ #
104
+ # @return [VALID_TYPES, nil]
105
+ def subscription
106
+ s = subscription_node[:subscription]
107
+ s.to_sym if s
108
+ end
109
+
110
+ # Set the subscription type
111
+ #
112
+ # @param [VALID_TYPES, nil] subscription
113
+ def subscription=(subscription)
114
+ if subscription && !VALID_TYPES.include?(subscription.to_sym)
115
+ raise ArgumentError, "Invalid Type (#{type}), use: #{VALID_TYPES*' '}"
116
+ end
117
+ subscription_node[:subscription] = subscription
118
+ end
119
+
120
+ # Get or create the actual subscription node
121
+ #
122
+ # @return [Blather::XMPPNode]
123
+ def subscription_node
124
+ unless subscription = pubsub.find_first('ns:subscription', :ns => self.class.registered_ns)
125
+ self.pubsub << (subscription = XMPPNode.new('subscription', self.document))
126
+ subscription.namespace = self.pubsub.namespace
127
+ end
128
+ subscription
129
+ end
130
+ end # Subscribe
131
+
132
+ end # PubSub
133
+ end # Stanza
134
+ end # Blather
@@ -0,0 +1,81 @@
1
+ module Blather
2
+ class Stanza
3
+ class PubSub
4
+
5
+ # # PubSub Subscriptions Stanza
6
+ #
7
+ # [XEP-0060 Section 5.6 Retrieve Subscriptions](http://xmpp.org/extensions/xep-0060.html#entity-subscriptions)
8
+ #
9
+ # @handler :pubsub_subscriptions
10
+ class Subscriptions < PubSub
11
+ register :pubsub_subscriptions, :subscriptions, self.registered_ns
12
+
13
+ include Enumerable
14
+ alias_method :find, :xpath
15
+
16
+ # Overrides the parent to ensure a subscriptions node is created
17
+ # @private
18
+ def self.new(type = nil, host = nil)
19
+ new_node = super type
20
+ new_node.to = host
21
+ new_node.subscriptions
22
+ new_node
23
+ end
24
+
25
+ # Overrides the parent to ensure the subscriptions node is destroyed
26
+ # @private
27
+ def inherit(node)
28
+ subscriptions.remove
29
+ super
30
+ end
31
+
32
+ # Get or create the actual subscriptions node
33
+ #
34
+ # @return [Blather::XMPPNode]
35
+ def subscriptions
36
+ aff = pubsub.find_first('subscriptions', self.class.registered_ns)
37
+ unless aff
38
+ (self.pubsub << (aff = XMPPNode.new('subscriptions', self.document)))
39
+ end
40
+ aff
41
+ end
42
+
43
+ # Iterate over the list of subscriptions
44
+ #
45
+ # @yieldparam [Hash] subscription
46
+ # @see {#list}
47
+ def each(&block)
48
+ list.each &block
49
+ end
50
+
51
+ # Get the size of the subscriptions list
52
+ #
53
+ # @return [Fixnum]
54
+ def size
55
+ list.size
56
+ end
57
+
58
+ # Get a hash of subscriptions
59
+ #
60
+ # @example
61
+ # { :subscribed => [{:node => 'node1', :jid => 'francisco@denmark.lit'}, {:node => 'node2', :jid => 'francisco@denmark.lit'}],
62
+ # :unconfigured => [{:node => 'node3', :jid => 'francisco@denmark.lit'}],
63
+ # :pending => [{:node => 'node4', :jid => 'francisco@denmark.lit'}],
64
+ # :none => [{:node => 'node5', :jid => 'francisco@denmark.lit'}] }
65
+ #
66
+ # @return [Hash]
67
+ def list
68
+ subscriptions.find('//ns:subscription', :ns => self.class.registered_ns).inject({}) do |hash, item|
69
+ hash[item[:subscription].to_sym] ||= []
70
+ hash[item[:subscription].to_sym] << {
71
+ :node => item[:node],
72
+ :jid => item[:jid]
73
+ }
74
+ hash
75
+ end
76
+ end
77
+ end # Subscriptions
78
+
79
+ end # PubSub
80
+ end # Stanza
81
+ end # Blather