sprsquish-blather 0.3.4 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +1 -1
- data/README.rdoc +41 -12
- data/examples/echo.rb +1 -1
- data/examples/execute.rb +0 -5
- data/examples/pubsub/cli.rb +64 -0
- data/examples/pubsub/ping_pong.rb +18 -0
- data/examples/rosterprint.rb +14 -0
- data/examples/xmpp4r/echo.rb +35 -0
- data/lib/blather/client/client.rb +19 -13
- data/lib/blather/client/dsl/pubsub.rb +133 -0
- data/lib/blather/client/dsl.rb +16 -0
- data/lib/blather/client.rb +1 -1
- data/lib/blather/core_ext/active_support/inheritable_attributes.rb +117 -0
- data/lib/blather/core_ext/active_support.rb +1 -117
- data/lib/blather/core_ext/nokogiri.rb +35 -0
- data/lib/blather/errors/sasl_error.rb +3 -1
- data/lib/blather/errors/stanza_error.rb +10 -17
- data/lib/blather/errors/stream_error.rb +11 -14
- data/lib/blather/errors.rb +3 -20
- data/lib/blather/jid.rb +1 -0
- data/lib/blather/roster.rb +9 -0
- data/lib/blather/roster_item.rb +6 -1
- data/lib/blather/stanza/disco/disco_info.rb +45 -33
- data/lib/blather/stanza/disco/disco_items.rb +32 -21
- data/lib/blather/stanza/disco.rb +7 -1
- data/lib/blather/stanza/iq/query.rb +16 -8
- data/lib/blather/stanza/iq/roster.rb +33 -22
- data/lib/blather/stanza/iq.rb +13 -8
- data/lib/blather/stanza/message.rb +20 -31
- data/lib/blather/stanza/presence/status.rb +13 -21
- data/lib/blather/stanza/presence/subscription.rb +11 -16
- data/lib/blather/stanza/presence.rb +3 -5
- data/lib/blather/stanza/pubsub/affiliations.rb +50 -0
- data/lib/blather/stanza/pubsub/create.rb +43 -0
- data/lib/blather/stanza/pubsub/errors.rb +9 -0
- data/lib/blather/stanza/pubsub/event.rb +77 -0
- data/lib/blather/stanza/pubsub/items.rb +63 -0
- data/lib/blather/stanza/pubsub/publish.rb +58 -0
- data/lib/blather/stanza/pubsub/retract.rb +53 -0
- data/lib/blather/stanza/pubsub/subscribe.rb +42 -0
- data/lib/blather/stanza/pubsub/subscription.rb +66 -0
- data/lib/blather/stanza/pubsub/subscriptions.rb +55 -0
- data/lib/blather/stanza/pubsub/unsubscribe.rb +42 -0
- data/lib/blather/stanza/pubsub.rb +63 -0
- data/lib/blather/stanza/pubsub_owner/delete.rb +34 -0
- data/lib/blather/stanza/pubsub_owner/purge.rb +34 -0
- data/lib/blather/stanza/pubsub_owner.rb +41 -0
- data/lib/blather/stanza.rb +35 -18
- data/lib/blather/stream/client.rb +1 -2
- data/lib/blather/stream/component.rb +9 -5
- data/lib/blather/stream/features/resource.rb +63 -0
- data/lib/blather/stream/{sasl.rb → features/sasl.rb} +53 -52
- data/lib/blather/stream/features/session.rb +44 -0
- data/lib/blather/stream/features/tls.rb +28 -0
- data/lib/blather/stream/features.rb +53 -0
- data/lib/blather/stream/parser.rb +70 -46
- data/lib/blather/stream.rb +76 -168
- data/lib/blather/xmpp_node.rb +113 -52
- data/lib/blather.rb +35 -12
- data/spec/blather/client/client_spec.rb +44 -58
- data/spec/blather/client/dsl/pubsub_spec.rb +465 -0
- data/spec/blather/client/dsl_spec.rb +19 -6
- data/spec/blather/core_ext/nokogiri_spec.rb +83 -0
- data/spec/blather/errors/sasl_error_spec.rb +8 -8
- data/spec/blather/errors/stanza_error_spec.rb +25 -33
- data/spec/blather/errors/stream_error_spec.rb +21 -16
- data/spec/blather/errors_spec.rb +4 -11
- data/spec/blather/jid_spec.rb +31 -30
- data/spec/blather/roster_item_spec.rb +34 -23
- data/spec/blather/roster_spec.rb +27 -12
- data/spec/blather/stanza/discos/disco_info_spec.rb +61 -42
- data/spec/blather/stanza/discos/disco_items_spec.rb +47 -35
- data/spec/blather/stanza/iq/query_spec.rb +34 -11
- data/spec/blather/stanza/iq/roster_spec.rb +47 -30
- data/spec/blather/stanza/iq_spec.rb +19 -14
- data/spec/blather/stanza/message_spec.rb +30 -17
- data/spec/blather/stanza/presence/status_spec.rb +43 -20
- data/spec/blather/stanza/presence/subscription_spec.rb +41 -21
- data/spec/blather/stanza/presence_spec.rb +34 -21
- data/spec/blather/stanza/pubsub/affiliations_spec.rb +57 -0
- data/spec/blather/stanza/pubsub/create_spec.rb +56 -0
- data/spec/blather/stanza/pubsub/event_spec.rb +84 -0
- data/spec/blather/stanza/pubsub/items_spec.rb +79 -0
- data/spec/blather/stanza/pubsub/publish_spec.rb +83 -0
- data/spec/blather/stanza/pubsub/retract_spec.rb +75 -0
- data/spec/blather/stanza/pubsub/subscribe_spec.rb +61 -0
- data/spec/blather/stanza/pubsub/subscription_spec.rb +97 -0
- data/spec/blather/stanza/pubsub/subscriptions_spec.rb +59 -0
- data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +61 -0
- data/spec/blather/stanza/pubsub_owner/delete_spec.rb +50 -0
- data/spec/blather/stanza/pubsub_owner/purge_spec.rb +50 -0
- data/spec/blather/stanza/pubsub_owner_spec.rb +27 -0
- data/spec/blather/stanza/pubsub_spec.rb +62 -0
- data/spec/blather/stanza_spec.rb +53 -38
- data/spec/blather/stream/client_spec.rb +231 -88
- data/spec/blather/stream/component_spec.rb +14 -5
- data/spec/blather/stream/parser_spec.rb +145 -0
- data/spec/blather/xmpp_node_spec.rb +192 -96
- data/spec/fixtures/pubsub.rb +311 -0
- data/spec/spec_helper.rb +5 -4
- metadata +53 -17
- data/Rakefile +0 -139
- data/ext/extconf.rb +0 -65
- data/ext/push_parser.c +0 -209
- data/lib/blather/core_ext/libxml.rb +0 -28
- data/lib/blather/stream/resource.rb +0 -48
- data/lib/blather/stream/session.rb +0 -36
- data/lib/blather/stream/stream_handler.rb +0 -39
- data/lib/blather/stream/tls.rb +0 -33
- data/spec/blather/core_ext/libxml_spec.rb +0 -58
@@ -7,9 +7,10 @@ class Iq
|
|
7
7
|
|
8
8
|
##
|
9
9
|
# Any new items are added to the query
|
10
|
-
def
|
11
|
-
super type
|
12
|
-
query << item if item
|
10
|
+
def self.new(type = nil, item = nil)
|
11
|
+
node = super type
|
12
|
+
node.query << item if item
|
13
|
+
node
|
13
14
|
end
|
14
15
|
|
15
16
|
##
|
@@ -17,19 +18,17 @@ class Iq
|
|
17
18
|
# Creates RosterItem objects out of each roster item as well.
|
18
19
|
def inherit(node)
|
19
20
|
# remove the current set of nodes
|
20
|
-
|
21
|
+
remove_children :item
|
21
22
|
super
|
22
23
|
# transmogrify nodes into RosterItems
|
23
|
-
items.each { |i| query << RosterItem.new(i); i.remove
|
24
|
+
items.each { |i| query << RosterItem.new(i); i.remove }
|
24
25
|
self
|
25
26
|
end
|
26
27
|
|
27
28
|
##
|
28
29
|
# Roster items
|
29
30
|
def items
|
30
|
-
|
31
|
-
items = query.find('//query_ns:item', :query_ns => self.class.ns) if items.empty?
|
32
|
-
items.map { |i| RosterItem.new(i) }
|
31
|
+
query.find('//ns:item', :ns => self.class.registered_ns).map { |i| RosterItem.new(i) }
|
33
32
|
end
|
34
33
|
|
35
34
|
class RosterItem < XMPPNode
|
@@ -38,42 +37,54 @@ class Iq
|
|
38
37
|
# [name] name alias of the given JID
|
39
38
|
# [subscription] subscription type
|
40
39
|
# [ask] ask subscription sub-state
|
41
|
-
def
|
42
|
-
super :item
|
40
|
+
def self.new(jid = nil, name = nil, subscription = nil, ask = nil)
|
41
|
+
new_node = super :item
|
43
42
|
|
44
|
-
|
45
|
-
|
43
|
+
case jid
|
44
|
+
when Nokogiri::XML::Node
|
45
|
+
new_node.inherit jid
|
46
|
+
when Hash
|
47
|
+
new_node.jid = jid[:jid]
|
48
|
+
new_node.name = jid[:name]
|
49
|
+
new_node.subscription = jid[:subscription]
|
50
|
+
new_node.ask = jid[:ask]
|
46
51
|
else
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
52
|
+
new_node.jid = jid
|
53
|
+
new_node.name = name
|
54
|
+
new_node.subscription = subscription
|
55
|
+
new_node.ask = ask
|
51
56
|
end
|
57
|
+
new_node
|
52
58
|
end
|
53
59
|
|
54
60
|
##
|
55
61
|
# Roster item's JID
|
56
62
|
def jid
|
57
|
-
(j =
|
63
|
+
(j = self[:jid]) ? JID.new(j) : nil
|
58
64
|
end
|
59
65
|
attribute_writer :jid
|
60
66
|
|
61
|
-
attribute_accessor :name
|
67
|
+
attribute_accessor :name
|
62
68
|
|
63
|
-
attribute_accessor :subscription, :ask
|
69
|
+
attribute_accessor :subscription, :ask, :call => :to_sym
|
64
70
|
|
65
71
|
##
|
66
72
|
# The groups roster item belongs to
|
67
73
|
def groups
|
68
|
-
find(
|
74
|
+
find('child::*[local-name()="group"]').map { |g| g.content }
|
69
75
|
end
|
70
76
|
|
71
77
|
##
|
72
78
|
# Set the roster item's groups
|
73
79
|
# must be an array
|
74
80
|
def groups=(new_groups)
|
75
|
-
|
76
|
-
|
81
|
+
remove_children :group
|
82
|
+
if new_groups
|
83
|
+
new_groups.uniq.each do |g|
|
84
|
+
self << (group = XMPPNode.new(:group, self.document))
|
85
|
+
group.content = g
|
86
|
+
end
|
87
|
+
end
|
77
88
|
end
|
78
89
|
|
79
90
|
##
|
data/lib/blather/stanza/iq.rb
CHANGED
@@ -9,17 +9,22 @@ class Stanza
|
|
9
9
|
register :iq
|
10
10
|
|
11
11
|
def self.import(node)
|
12
|
-
raise(ArgumentError, "Import missmatch #{[node.element_name, self.name].inspect}") if node.element_name != self.name.to_s
|
13
12
|
klass = nil
|
14
|
-
node.children.each { |e| break if klass = class_from_registration(e.element_name, e.namespace) }
|
15
|
-
|
13
|
+
node.children.each { |e| break if klass = class_from_registration(e.element_name, (e.namespace.href if e.namespace)) }
|
14
|
+
|
15
|
+
if klass && klass != self
|
16
|
+
klass.import(node)
|
17
|
+
else
|
18
|
+
new(node[:type]).inherit(node)
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
|
-
def
|
19
|
-
super :iq
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
def self.new(type = nil, to = nil, id = nil)
|
23
|
+
node = super :iq
|
24
|
+
node.type = type || :get
|
25
|
+
node.to = to
|
26
|
+
node.id = id || self.next_id
|
27
|
+
node
|
23
28
|
end
|
24
29
|
|
25
30
|
VALID_TYPES.each do |valid_type|
|
@@ -8,11 +8,23 @@ class Stanza
|
|
8
8
|
|
9
9
|
register :message
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
def self.import(node)
|
12
|
+
klass = nil
|
13
|
+
node.children.each { |e| break if klass = class_from_registration(e.element_name, (e.namespace.href if e.namespace)) }
|
14
|
+
|
15
|
+
if klass && klass != self
|
16
|
+
klass.import(node)
|
17
|
+
else
|
18
|
+
new(node[:type]).inherit(node)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.new(to = nil, body = nil, type = :chat)
|
23
|
+
node = super(:message)
|
24
|
+
node.to = to
|
25
|
+
node.type = type
|
26
|
+
node.body = body
|
27
|
+
node
|
16
28
|
end
|
17
29
|
|
18
30
|
VALID_TYPES.each do |valid_type|
|
@@ -26,32 +38,9 @@ class Stanza
|
|
26
38
|
super
|
27
39
|
end
|
28
40
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
def body
|
35
|
-
content_from :body
|
36
|
-
end
|
37
|
-
|
38
|
-
def subject=(subject)
|
39
|
-
remove_child :subject
|
40
|
-
self << XMPPNode.new('subject', subject) if subject
|
41
|
-
end
|
42
|
-
|
43
|
-
def subject
|
44
|
-
content_from :subject
|
45
|
-
end
|
46
|
-
|
47
|
-
def thread=(thread)
|
48
|
-
remove_child :thread
|
49
|
-
self << XMPPNode.new('thread', thread) if thread
|
50
|
-
end
|
51
|
-
|
52
|
-
def thread
|
53
|
-
content_from :thread
|
54
|
-
end
|
41
|
+
content_attr_accessor :body
|
42
|
+
content_attr_accessor :subject
|
43
|
+
content_attr_accessor :thread
|
55
44
|
end
|
56
45
|
|
57
46
|
end #Stanza
|
@@ -9,12 +9,15 @@ class Presence
|
|
9
9
|
|
10
10
|
register :status, :status
|
11
11
|
|
12
|
-
def
|
13
|
-
super()
|
14
|
-
|
15
|
-
|
12
|
+
def self.new(state = nil, message = nil)
|
13
|
+
node = super()
|
14
|
+
node.state = state
|
15
|
+
node.message = message
|
16
|
+
node
|
16
17
|
end
|
17
18
|
|
19
|
+
attribute_helpers_for(:state, VALID_STATES)
|
20
|
+
|
18
21
|
##
|
19
22
|
# Ensures type is nil or :unavailable
|
20
23
|
def type=(type)
|
@@ -29,8 +32,7 @@ class Presence
|
|
29
32
|
state = nil if state == :available
|
30
33
|
raise ArgumentError, "Invalid Status (#{state}), use: #{VALID_STATES*' '}" if state && !VALID_STATES.include?(state)
|
31
34
|
|
32
|
-
|
33
|
-
self << XMPPNode.new('show', state) if state
|
35
|
+
set_content_for :show, state
|
34
36
|
end
|
35
37
|
|
36
38
|
##
|
@@ -43,23 +45,13 @@ class Presence
|
|
43
45
|
# Ensure priority is between -128 and 127
|
44
46
|
def priority=(new_priority)
|
45
47
|
raise ArgumentError, 'Priority must be between -128 and +127' if new_priority && !(-128..127).include?(new_priority.to_i)
|
46
|
-
|
47
|
-
|
48
|
-
self << XMPPNode.new('priority', new_priority) if new_priority
|
49
|
-
end
|
50
|
-
|
51
|
-
def priority
|
52
|
-
content_from(:priority).to_i
|
48
|
+
set_content_for :priority, new_priority
|
49
|
+
|
53
50
|
end
|
54
51
|
|
55
|
-
|
56
|
-
remove_child :status
|
57
|
-
self << XMPPNode.new('status', msg) if msg
|
58
|
-
end
|
52
|
+
content_attr_reader :priority, :to_i
|
59
53
|
|
60
|
-
|
61
|
-
content_from :status
|
62
|
-
end
|
54
|
+
content_attr_accessor :message, nil, :status
|
63
55
|
|
64
56
|
##
|
65
57
|
# Compare status based on priority
|
@@ -75,4 +67,4 @@ class Presence
|
|
75
67
|
|
76
68
|
end #Presence
|
77
69
|
end #Stanza
|
78
|
-
end #Blather
|
70
|
+
end #Blather
|
@@ -5,10 +5,11 @@ class Presence
|
|
5
5
|
class Subscription < Presence
|
6
6
|
register :subscription, :subscription
|
7
7
|
|
8
|
-
def
|
9
|
-
super()
|
10
|
-
|
11
|
-
|
8
|
+
def self.new(to = nil, type = nil)
|
9
|
+
node = super()
|
10
|
+
node.to = to
|
11
|
+
node.type = type
|
12
|
+
node
|
12
13
|
end
|
13
14
|
|
14
15
|
def inherit(node)
|
@@ -24,49 +25,43 @@ class Presence
|
|
24
25
|
# Create an approve stanza
|
25
26
|
def approve!
|
26
27
|
self.type = :subscribed
|
27
|
-
|
28
|
+
reply_if_needed!
|
28
29
|
end
|
29
30
|
|
30
31
|
##
|
31
32
|
# Create a refuse stanza
|
32
33
|
def refuse!
|
33
34
|
self.type = :unsubscribed
|
34
|
-
|
35
|
+
reply_if_needed!
|
35
36
|
end
|
36
37
|
|
37
38
|
##
|
38
39
|
# Create an unsubscribe stanza
|
39
40
|
def unsubscribe!
|
40
41
|
self.type = :unsubscribe
|
41
|
-
|
42
|
+
reply_if_needed!
|
42
43
|
end
|
43
44
|
|
44
45
|
##
|
45
46
|
# Create a cancel stanza
|
46
47
|
def cancel!
|
47
48
|
self.type = :unsubscribed
|
48
|
-
|
49
|
+
reply_if_needed!
|
49
50
|
end
|
50
51
|
|
51
52
|
##
|
52
53
|
# Create a request stanza
|
53
54
|
def request!
|
54
55
|
self.type = :subscribe
|
55
|
-
|
56
|
+
reply_if_needed!
|
56
57
|
end
|
57
58
|
|
58
59
|
def request?
|
59
60
|
self.type == :subscribe
|
60
61
|
end
|
61
62
|
|
62
|
-
private
|
63
|
-
def morph_to_reply
|
64
|
-
self.to = self.from if self.from
|
65
|
-
self.from = nil
|
66
|
-
self
|
67
|
-
end
|
68
63
|
end #Subscription
|
69
64
|
|
70
65
|
end #Presence
|
71
66
|
end #Stanza
|
72
|
-
end
|
67
|
+
end
|
@@ -24,13 +24,11 @@ class Stanza
|
|
24
24
|
|
25
25
|
##
|
26
26
|
# Ensure element_name is "presence" for all subclasses
|
27
|
-
def
|
27
|
+
def self.new
|
28
28
|
super :presence
|
29
29
|
end
|
30
30
|
|
31
|
-
VALID_TYPES
|
32
|
-
define_method("#{valid_type}?") { self.type == valid_type }
|
33
|
-
end
|
31
|
+
attribute_helpers_for(:type, VALID_TYPES)
|
34
32
|
|
35
33
|
##
|
36
34
|
# Ensures type is one of :unavailable, :subscribe, :subscribed, :unsubscribe, :unsubscribed, :probe or :error
|
@@ -42,4 +40,4 @@ class Stanza
|
|
42
40
|
end
|
43
41
|
|
44
42
|
end #Stanza
|
45
|
-
end
|
43
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
class PubSub
|
4
|
+
|
5
|
+
class Affiliations < PubSub
|
6
|
+
register :pubsub_affiliations, :affiliations, self.registered_ns
|
7
|
+
|
8
|
+
include Enumerable
|
9
|
+
alias_method :find, :xpath
|
10
|
+
|
11
|
+
def self.new(type = nil, host = nil)
|
12
|
+
new_node = super
|
13
|
+
new_node.affiliations
|
14
|
+
new_node
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Kill the affiliations node before running inherit
|
19
|
+
def inherit(node)
|
20
|
+
affiliations.remove
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def affiliations
|
25
|
+
aff = pubsub.find_first('pubsub_ns:affiliations', :pubsub_ns => self.class.registered_ns)
|
26
|
+
self.pubsub << (aff = XMPPNode.new('affiliations', self.document)) unless aff
|
27
|
+
aff
|
28
|
+
end
|
29
|
+
|
30
|
+
def each(&block)
|
31
|
+
list.each &block
|
32
|
+
end
|
33
|
+
|
34
|
+
def size
|
35
|
+
list.size
|
36
|
+
end
|
37
|
+
|
38
|
+
def list
|
39
|
+
items = affiliations.find('//ns:affiliation', :ns => self.class.registered_ns)
|
40
|
+
items.inject({}) do |hash, item|
|
41
|
+
hash[item[:affiliation].to_sym] ||= []
|
42
|
+
hash[item[:affiliation].to_sym] << item[:node]
|
43
|
+
hash
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end #Affiliations
|
47
|
+
|
48
|
+
end #PubSub
|
49
|
+
end #Stanza
|
50
|
+
end #Blather
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
class PubSub
|
4
|
+
|
5
|
+
class Create < PubSub
|
6
|
+
register :pubsub_create, :create, self.registered_ns
|
7
|
+
|
8
|
+
def self.new(type = :set, host = nil, node = nil)
|
9
|
+
new_node = super(type, host)
|
10
|
+
new_node.create_node
|
11
|
+
new_node.configure_node
|
12
|
+
new_node.node = node
|
13
|
+
new_node
|
14
|
+
end
|
15
|
+
|
16
|
+
def node
|
17
|
+
create_node[:node]
|
18
|
+
end
|
19
|
+
|
20
|
+
def node=(node)
|
21
|
+
create_node[:node] = node
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_node
|
25
|
+
unless create_node = pubsub.find_first('ns:create', :ns => self.class.registered_ns)
|
26
|
+
self.pubsub << (create_node = XMPPNode.new('create', self.document))
|
27
|
+
create_node.namespace = self.pubsub.namespace
|
28
|
+
end
|
29
|
+
create_node
|
30
|
+
end
|
31
|
+
|
32
|
+
def configure_node
|
33
|
+
unless configure_node = pubsub.find_first('ns:configure', :ns => self.class.registered_ns)
|
34
|
+
self.pubsub << (configure_node = XMPPNode.new('configure', self.document))
|
35
|
+
configure_node.namespace = self.pubsub.namespace
|
36
|
+
end
|
37
|
+
configure_node
|
38
|
+
end
|
39
|
+
end #Retract
|
40
|
+
|
41
|
+
end #PubSub
|
42
|
+
end #Stanza
|
43
|
+
end #Blather
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
class PubSub
|
4
|
+
|
5
|
+
class Event < Message
|
6
|
+
register :pubsub_event, :event, 'http://jabber.org/protocol/pubsub#event'
|
7
|
+
|
8
|
+
##
|
9
|
+
# Ensure the event_node is created
|
10
|
+
def self.new(type = nil)
|
11
|
+
node = super
|
12
|
+
node.event_node
|
13
|
+
node
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# Kill the event_node node before running inherit
|
18
|
+
def inherit(node)
|
19
|
+
event_node.remove
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def node
|
24
|
+
!purge? ? items_node[:node] : purge_node[:node]
|
25
|
+
end
|
26
|
+
|
27
|
+
def retractions
|
28
|
+
items_node.find('ns:retract', :ns => self.class.registered_ns).map { |i| i[:id] }
|
29
|
+
end
|
30
|
+
|
31
|
+
def retractions?
|
32
|
+
!retractions.empty?
|
33
|
+
end
|
34
|
+
|
35
|
+
def items
|
36
|
+
items_node.find('ns:item', :ns => self.class.registered_ns).map { |i| PubSubItem.new(nil,nil,self.document).inherit i }
|
37
|
+
end
|
38
|
+
|
39
|
+
def items?
|
40
|
+
!items.empty?
|
41
|
+
end
|
42
|
+
|
43
|
+
def purge?
|
44
|
+
purge_node
|
45
|
+
end
|
46
|
+
|
47
|
+
def event_node
|
48
|
+
node = find_first('ns:event', :ns => self.class.registered_ns)
|
49
|
+
node = find_first('event', self.class.registered_ns) unless node
|
50
|
+
unless node
|
51
|
+
(self << (node = XMPPNode.new('event', self.document)))
|
52
|
+
node.namespace = self.class.registered_ns
|
53
|
+
end
|
54
|
+
node
|
55
|
+
end
|
56
|
+
|
57
|
+
def items_node
|
58
|
+
node = find_first('event/ns:items', :ns => self.class.registered_ns)
|
59
|
+
unless node
|
60
|
+
(self.event_node << (node = XMPPNode.new('items', self.document)))
|
61
|
+
node.namespace = event_node.namespace
|
62
|
+
end
|
63
|
+
node
|
64
|
+
end
|
65
|
+
|
66
|
+
def purge_node
|
67
|
+
event_node.find_first('ns:purge', :ns => self.class.registered_ns)
|
68
|
+
end
|
69
|
+
|
70
|
+
def subscription_ids
|
71
|
+
find('//ns:header[@name="SubID"]', :ns => 'http://jabber.org/protocol/shim').map { |n| n.content }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end #PubSub
|
76
|
+
end #Stanza
|
77
|
+
end #Blather
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
class PubSub
|
4
|
+
|
5
|
+
class Items < PubSub
|
6
|
+
register :pubsub_items, :items, self.registered_ns
|
7
|
+
|
8
|
+
include Enumerable
|
9
|
+
alias_method :find, :xpath
|
10
|
+
|
11
|
+
def self.request(host, path, list = [], max = nil)
|
12
|
+
node = self.new :get, host
|
13
|
+
|
14
|
+
node.node = path
|
15
|
+
node.max_items = max
|
16
|
+
|
17
|
+
(list || []).each { |id| node.items_node << PubSubItem.new(id, nil, node.document) }
|
18
|
+
|
19
|
+
node
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.new(type = nil, host = nil)
|
23
|
+
new_node = super
|
24
|
+
new_node.items
|
25
|
+
new_node
|
26
|
+
end
|
27
|
+
|
28
|
+
def node
|
29
|
+
items_node[:node]
|
30
|
+
end
|
31
|
+
|
32
|
+
def node=(node)
|
33
|
+
items_node[:node] = node
|
34
|
+
end
|
35
|
+
|
36
|
+
def max_items
|
37
|
+
items_node[:max_items].to_i if items_node[:max_items]
|
38
|
+
end
|
39
|
+
|
40
|
+
def max_items=(max_items)
|
41
|
+
items_node[:max_items] = max_items
|
42
|
+
end
|
43
|
+
|
44
|
+
def each(&block)
|
45
|
+
items.each &block
|
46
|
+
end
|
47
|
+
|
48
|
+
def items
|
49
|
+
items_node.find('ns:item', :ns => self.class.registered_ns).map { |i| PubSubItem.new(nil,nil,self.document).inherit i }
|
50
|
+
end
|
51
|
+
|
52
|
+
def items_node
|
53
|
+
unless node = self.pubsub.find_first('ns:items', :ns => self.class.registered_ns)
|
54
|
+
(self.pubsub << (node = XMPPNode.new('items', self.document)))
|
55
|
+
node.namespace = self.pubsub.namespace
|
56
|
+
end
|
57
|
+
node
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end #PubSub
|
62
|
+
end #Stanza
|
63
|
+
end #Blather
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
class PubSub
|
4
|
+
|
5
|
+
class Publish < PubSub
|
6
|
+
register :pubsub_publish, :publish, self.registered_ns
|
7
|
+
|
8
|
+
include Enumerable
|
9
|
+
alias_method :find, :xpath
|
10
|
+
|
11
|
+
def self.new(host = nil, node = nil, type = :set, payload = nil)
|
12
|
+
new_node = super(type, host)
|
13
|
+
new_node.node = node
|
14
|
+
new_node.payload = payload if payload
|
15
|
+
new_node
|
16
|
+
end
|
17
|
+
|
18
|
+
def payload=(payload)
|
19
|
+
payload = case payload
|
20
|
+
when Hash then payload.to_a
|
21
|
+
when Array then payload.map { |v| [nil, v] }
|
22
|
+
else [[nil, payload.to_s]]
|
23
|
+
end
|
24
|
+
payload.each { |id,value| self.publish << PubSubItem.new(id, value, self.document) }
|
25
|
+
end
|
26
|
+
|
27
|
+
def node
|
28
|
+
publish[:node]
|
29
|
+
end
|
30
|
+
|
31
|
+
def node=(node)
|
32
|
+
publish[:node] = node
|
33
|
+
end
|
34
|
+
|
35
|
+
def publish
|
36
|
+
unless publish = pubsub.find_first('ns:publish', :ns => self.class.registered_ns)
|
37
|
+
self.pubsub << (publish = XMPPNode.new('publish', self.document))
|
38
|
+
publish.namespace = self.pubsub.namespace
|
39
|
+
end
|
40
|
+
publish
|
41
|
+
end
|
42
|
+
|
43
|
+
def items
|
44
|
+
publish.find('ns:item', :ns => self.class.registered_ns).map { |i| PubSubItem.new(nil,nil,self.document).inherit i }
|
45
|
+
end
|
46
|
+
|
47
|
+
def each(&block)
|
48
|
+
items.each &block
|
49
|
+
end
|
50
|
+
|
51
|
+
def size
|
52
|
+
items.size
|
53
|
+
end
|
54
|
+
end #Publish
|
55
|
+
|
56
|
+
end #PubSub
|
57
|
+
end #Stanza
|
58
|
+
end #Blather
|