tp-blather 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +13 -0
- data/.gemtest +0 -0
- data/.gitignore +19 -0
- data/.rspec +3 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +249 -0
- data/Gemfile +4 -0
- data/Guardfile +5 -0
- data/LICENSE +22 -0
- data/README.md +413 -0
- data/Rakefile +20 -0
- data/TODO.md +2 -0
- data/blather.gemspec +51 -0
- data/examples/certs/README +20 -0
- data/examples/certs/ca-bundle.crt +3987 -0
- data/examples/echo.rb +19 -0
- data/examples/execute.rb +17 -0
- data/examples/ping_pong.rb +38 -0
- data/examples/print_hierarchy.rb +77 -0
- data/examples/rosterprint.rb +15 -0
- data/examples/stream_only.rb +28 -0
- data/examples/trusted_echo.rb +21 -0
- data/examples/xmpp4r/echo.rb +36 -0
- data/lib/blather.rb +112 -0
- data/lib/blather/cert_store.rb +53 -0
- data/lib/blather/client.rb +95 -0
- data/lib/blather/client/client.rb +345 -0
- data/lib/blather/client/dsl.rb +320 -0
- data/lib/blather/client/dsl/pubsub.rb +174 -0
- data/lib/blather/core_ext/eventmachine.rb +125 -0
- data/lib/blather/core_ext/ipaddr.rb +20 -0
- data/lib/blather/errors.rb +69 -0
- data/lib/blather/errors/sasl_error.rb +44 -0
- data/lib/blather/errors/stanza_error.rb +110 -0
- data/lib/blather/errors/stream_error.rb +84 -0
- data/lib/blather/file_transfer.rb +107 -0
- data/lib/blather/file_transfer/ibb.rb +68 -0
- data/lib/blather/file_transfer/s5b.rb +114 -0
- data/lib/blather/jid.rb +141 -0
- data/lib/blather/roster.rb +118 -0
- data/lib/blather/roster_item.rb +146 -0
- data/lib/blather/stanza.rb +167 -0
- data/lib/blather/stanza/disco.rb +32 -0
- data/lib/blather/stanza/disco/capabilities.rb +161 -0
- data/lib/blather/stanza/disco/disco_info.rb +205 -0
- data/lib/blather/stanza/disco/disco_items.rb +134 -0
- data/lib/blather/stanza/iq.rb +144 -0
- data/lib/blather/stanza/iq/command.rb +339 -0
- data/lib/blather/stanza/iq/ibb.rb +86 -0
- data/lib/blather/stanza/iq/ping.rb +50 -0
- data/lib/blather/stanza/iq/query.rb +53 -0
- data/lib/blather/stanza/iq/roster.rb +185 -0
- data/lib/blather/stanza/iq/s5b.rb +208 -0
- data/lib/blather/stanza/iq/si.rb +415 -0
- data/lib/blather/stanza/iq/vcard.rb +149 -0
- data/lib/blather/stanza/message.rb +428 -0
- data/lib/blather/stanza/message/muc_user.rb +119 -0
- data/lib/blather/stanza/muc/muc_user_base.rb +54 -0
- data/lib/blather/stanza/presence.rb +172 -0
- data/lib/blather/stanza/presence/c.rb +100 -0
- data/lib/blather/stanza/presence/muc.rb +35 -0
- data/lib/blather/stanza/presence/muc_user.rb +147 -0
- data/lib/blather/stanza/presence/status.rb +218 -0
- data/lib/blather/stanza/presence/subscription.rb +100 -0
- data/lib/blather/stanza/pubsub.rb +119 -0
- data/lib/blather/stanza/pubsub/affiliations.rb +79 -0
- data/lib/blather/stanza/pubsub/create.rb +65 -0
- data/lib/blather/stanza/pubsub/errors.rb +18 -0
- data/lib/blather/stanza/pubsub/event.rb +139 -0
- data/lib/blather/stanza/pubsub/items.rb +103 -0
- data/lib/blather/stanza/pubsub/publish.rb +103 -0
- data/lib/blather/stanza/pubsub/retract.rb +92 -0
- data/lib/blather/stanza/pubsub/subscribe.rb +68 -0
- data/lib/blather/stanza/pubsub/subscription.rb +135 -0
- data/lib/blather/stanza/pubsub/subscriptions.rb +83 -0
- data/lib/blather/stanza/pubsub/unsubscribe.rb +84 -0
- data/lib/blather/stanza/pubsub_owner.rb +51 -0
- data/lib/blather/stanza/pubsub_owner/delete.rb +52 -0
- data/lib/blather/stanza/pubsub_owner/purge.rb +52 -0
- data/lib/blather/stanza/x.rb +416 -0
- data/lib/blather/stream.rb +266 -0
- data/lib/blather/stream/client.rb +32 -0
- data/lib/blather/stream/component.rb +39 -0
- data/lib/blather/stream/features.rb +70 -0
- data/lib/blather/stream/features/register.rb +38 -0
- data/lib/blather/stream/features/resource.rb +63 -0
- data/lib/blather/stream/features/sasl.rb +190 -0
- data/lib/blather/stream/features/session.rb +45 -0
- data/lib/blather/stream/features/tls.rb +29 -0
- data/lib/blather/stream/parser.rb +102 -0
- data/lib/blather/version.rb +3 -0
- data/lib/blather/xmpp_node.rb +94 -0
- data/spec/blather/client/client_spec.rb +687 -0
- data/spec/blather/client/dsl/pubsub_spec.rb +492 -0
- data/spec/blather/client/dsl_spec.rb +266 -0
- data/spec/blather/errors/sasl_error_spec.rb +33 -0
- data/spec/blather/errors/stanza_error_spec.rb +129 -0
- data/spec/blather/errors/stream_error_spec.rb +108 -0
- data/spec/blather/errors_spec.rb +33 -0
- data/spec/blather/file_transfer_spec.rb +135 -0
- data/spec/blather/jid_spec.rb +87 -0
- data/spec/blather/roster_item_spec.rb +134 -0
- data/spec/blather/roster_spec.rb +107 -0
- data/spec/blather/stanza/discos/disco_info_spec.rb +247 -0
- data/spec/blather/stanza/discos/disco_items_spec.rb +154 -0
- data/spec/blather/stanza/iq/command_spec.rb +206 -0
- data/spec/blather/stanza/iq/ibb_spec.rb +124 -0
- data/spec/blather/stanza/iq/ping_spec.rb +45 -0
- data/spec/blather/stanza/iq/query_spec.rb +64 -0
- data/spec/blather/stanza/iq/roster_spec.rb +139 -0
- data/spec/blather/stanza/iq/s5b_spec.rb +57 -0
- data/spec/blather/stanza/iq/si_spec.rb +98 -0
- data/spec/blather/stanza/iq/vcard_spec.rb +93 -0
- data/spec/blather/stanza/iq_spec.rb +61 -0
- data/spec/blather/stanza/message/muc_user_spec.rb +152 -0
- data/spec/blather/stanza/message_spec.rb +282 -0
- data/spec/blather/stanza/presence/c_spec.rb +56 -0
- data/spec/blather/stanza/presence/muc_spec.rb +37 -0
- data/spec/blather/stanza/presence/muc_user_spec.rb +83 -0
- data/spec/blather/stanza/presence/status_spec.rb +144 -0
- data/spec/blather/stanza/presence/subscription_spec.rb +102 -0
- data/spec/blather/stanza/presence_spec.rb +125 -0
- 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 +98 -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 +74 -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 +68 -0
- data/spec/blather/stanza/x_spec.rb +231 -0
- data/spec/blather/stanza_spec.rb +134 -0
- data/spec/blather/stream/client_spec.rb +1090 -0
- data/spec/blather/stream/component_spec.rb +108 -0
- data/spec/blather/stream/parser_spec.rb +152 -0
- data/spec/blather/stream/ssl_spec.rb +32 -0
- data/spec/blather/xmpp_node_spec.rb +47 -0
- data/spec/blather_spec.rb +34 -0
- data/spec/fixtures/pubsub.rb +311 -0
- data/spec/spec_helper.rb +17 -0
- data/yard/templates/default/class/html/handlers.erb +18 -0
- data/yard/templates/default/class/setup.rb +10 -0
- data/yard/templates/default/class/text/handlers.erb +1 -0
- metadata +459 -0
@@ -0,0 +1,161 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
|
4
|
+
# # Capabilities Stanza
|
5
|
+
#
|
6
|
+
# [XEP-0115 Entity Capabilities](http://xmpp.org/extensions/xep-0115.html)
|
7
|
+
#
|
8
|
+
# XMPP protocol extension for broadcasting and dynamically discovering client, device, or generic entity capabilities.
|
9
|
+
#
|
10
|
+
class Capabilities < Blather::Stanza::DiscoInfo
|
11
|
+
def self.new
|
12
|
+
super :result
|
13
|
+
end
|
14
|
+
|
15
|
+
# A string that is used to verify the identity and supported features of the entity.
|
16
|
+
#
|
17
|
+
# @return [String]
|
18
|
+
def ver
|
19
|
+
generate_ver identities, features
|
20
|
+
end
|
21
|
+
|
22
|
+
# A URI that uniquely identifies a software application, typically a URL at the
|
23
|
+
# website of the project or company that produces the software.
|
24
|
+
#
|
25
|
+
# @param [String] node the node URI
|
26
|
+
def node=(node)
|
27
|
+
@bare_node = node
|
28
|
+
super "#{node}##{ver}"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Add an array of identities
|
32
|
+
# @param identities the array of identities, passed directly to Identity.new
|
33
|
+
def identities=(identities)
|
34
|
+
super identities
|
35
|
+
regenerate_full_node
|
36
|
+
end
|
37
|
+
|
38
|
+
# Add an array of features
|
39
|
+
# @param features the array of features, passed directly to Feature.new
|
40
|
+
def features=(features)
|
41
|
+
super features
|
42
|
+
regenerate_full_node
|
43
|
+
end
|
44
|
+
|
45
|
+
# The generated Presence::C node
|
46
|
+
#
|
47
|
+
# @return [Blather::Stanza::Presence::C]
|
48
|
+
def c
|
49
|
+
Blather::Stanza::Presence::C.new @bare_node, ver
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def regenerate_full_node
|
55
|
+
self.node = @bare_node
|
56
|
+
end
|
57
|
+
|
58
|
+
def generate_ver_str(identities, features, forms = [])
|
59
|
+
# 1. Initialize an empty string S.
|
60
|
+
s = ''
|
61
|
+
|
62
|
+
# 2. Sort the service discovery identities by category and
|
63
|
+
# then by type (if it exists) and then by xml:lang (if it
|
64
|
+
# exists), formatted as CATEGORY '/' [TYPE] '/' [LANG] '/'
|
65
|
+
# [NAME]. Note that each slash is included even if the TYPE,
|
66
|
+
# LANG, or NAME is not included.
|
67
|
+
identities.sort! do |identity1, identity2|
|
68
|
+
cmp_result = nil
|
69
|
+
[:category, :type, :xml_lang, :name].each do |field|
|
70
|
+
value1 = identity1.send(field)
|
71
|
+
value2 = identity2.send(field)
|
72
|
+
|
73
|
+
if value1 != value2
|
74
|
+
cmp_result = value1 <=> value2
|
75
|
+
break
|
76
|
+
end
|
77
|
+
end
|
78
|
+
cmp_result
|
79
|
+
end
|
80
|
+
|
81
|
+
# 3. For each identity, append the 'category/type/lang/name' to
|
82
|
+
# S, followed by the '<' character.
|
83
|
+
s += identities.collect do |identity|
|
84
|
+
[:category, :type, :xml_lang, :name].collect do |field|
|
85
|
+
identity.send(field).to_s
|
86
|
+
end.join('/') + '<'
|
87
|
+
end.join
|
88
|
+
|
89
|
+
# 4. Sort the supported service discovery features.
|
90
|
+
features.sort! { |feature1, feature2| feature1.var <=> feature2.var }
|
91
|
+
|
92
|
+
# 5. For each feature, append the feature to S, followed by the
|
93
|
+
# '<' character.
|
94
|
+
s += features.collect { |feature| feature.var.to_s + '<' }.join
|
95
|
+
|
96
|
+
# 6. If the service discovery information response includes
|
97
|
+
# XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e., by
|
98
|
+
# the XML character data of the <value/> element).
|
99
|
+
forms.sort! do |form1, form2|
|
100
|
+
fform_type1 = form1.field 'FORM_TYPE'
|
101
|
+
fform_type2 = form2.field 'FORM_TYPE'
|
102
|
+
form_type1 = fform_type1 ? fform_type1.values.to_s : nil
|
103
|
+
form_type2 = fform_type2 ? fform_type2.values.to_s : nil
|
104
|
+
form_type1 <=> form_type2
|
105
|
+
end
|
106
|
+
|
107
|
+
# 7. For each extended service discovery information form:
|
108
|
+
forms.each do |form|
|
109
|
+
# 7.1. Append the XML character data of the FORM_TYPE field's
|
110
|
+
# <value/> element, followed by the '<' character.
|
111
|
+
fform_type = form.field 'FORM_TYPE'
|
112
|
+
form_type = fform_type ? fform_type.values.to_s : nil
|
113
|
+
s += "#{form_type}<"
|
114
|
+
|
115
|
+
# 7.2. Sort the fields by the value of the "var" attribute
|
116
|
+
fields = form.fields.sort { |field1, field2| field1.var <=> field2.var }
|
117
|
+
|
118
|
+
# 7.3. For each field:
|
119
|
+
fields.each do |field|
|
120
|
+
# 7.3.1. Append the value of the "var" attribute, followed by
|
121
|
+
# the '<' character.
|
122
|
+
s += "#{field.var}<"
|
123
|
+
|
124
|
+
# 7.3.2. Sort values by the XML character data of the <value/> element
|
125
|
+
# values = field.values.sort { |value1, value2| value1 <=> value2 }
|
126
|
+
|
127
|
+
# 7.3.3. For each <value/> element, append the XML character
|
128
|
+
# data, followed by the '<' character.
|
129
|
+
# s += values.collect { |value| "#{value}<" }.join
|
130
|
+
s += "#{field.value}<"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
s
|
134
|
+
end
|
135
|
+
|
136
|
+
def generate_ver(identities, features, forms = [], hash = 'sha-1')
|
137
|
+
s = generate_ver_str identities, features, forms
|
138
|
+
|
139
|
+
# 9. Compute the verification string by hashing S using the
|
140
|
+
# algorithm specified in the 'hash' attribute (e.g., SHA-1 as
|
141
|
+
# defined in RFC 3174). The hashed data MUST be generated
|
142
|
+
# with binary output and encoded using Base64 as specified in
|
143
|
+
# Section 4 of RFC 4648 (note: the Base64 output MUST NOT
|
144
|
+
# include whitespace and MUST set padding bits to zero).
|
145
|
+
|
146
|
+
# See http://www.iana.org/assignments/hash-function-text-names
|
147
|
+
hash_klass = case hash
|
148
|
+
when 'md2' then nil
|
149
|
+
when 'md5' then Digest::MD5
|
150
|
+
when 'sha-1' then Digest::SHA1
|
151
|
+
when 'sha-224' then nil
|
152
|
+
when 'sha-256' then Digest::SHA256
|
153
|
+
when 'sha-384' then Digest::SHA384
|
154
|
+
when 'sha-512' then Digest::SHA512
|
155
|
+
end
|
156
|
+
hash_klass ? [hash_klass::digest(s)].pack('m').strip : nil
|
157
|
+
end
|
158
|
+
end # Caps
|
159
|
+
|
160
|
+
end # Stanza
|
161
|
+
end # Blather
|
@@ -0,0 +1,205 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
|
4
|
+
# # DiscoInfo Stanza
|
5
|
+
#
|
6
|
+
# [XEP-0030 Disco Info](http://xmpp.org/extensions/xep-0030.html#info)
|
7
|
+
#
|
8
|
+
# Disco Info node that provides or retreives information about a jabber entity
|
9
|
+
#
|
10
|
+
# @handler :disco_info
|
11
|
+
class DiscoInfo < Disco
|
12
|
+
register :disco_info, nil, 'http://jabber.org/protocol/disco#info'
|
13
|
+
|
14
|
+
# Create a new DiscoInfo stanza
|
15
|
+
# @param [:get, :set, :result, :error, nil] type the Iq stanza type
|
16
|
+
# @param [String, nil] node the name of the node the info belongs to
|
17
|
+
# @param [Array<Array, DiscoInfo::Identity>, nil] identities a list of
|
18
|
+
# identities. these are passed directly to DiscoInfo::Identity.new
|
19
|
+
# @param [Array<Array, DiscoInfo::Identity>, nil] features a list of
|
20
|
+
# features. these are passed directly to DiscoInfo::Feature.new
|
21
|
+
# @return [DiscoInfo] a new DiscoInfo stanza
|
22
|
+
def self.new(type = nil, node = nil, identities = [], features = [])
|
23
|
+
new_node = super type
|
24
|
+
new_node.node = node
|
25
|
+
new_node.identities = [identities]
|
26
|
+
new_node.features = [features]
|
27
|
+
new_node
|
28
|
+
end
|
29
|
+
|
30
|
+
# List of identity objects
|
31
|
+
def identities
|
32
|
+
query.find('//ns:identity', :ns => self.class.registered_ns).map do |i|
|
33
|
+
Identity.new i
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Add an array of identities
|
38
|
+
# @param identities the array of identities, passed directly to Identity.new
|
39
|
+
def identities=(identities)
|
40
|
+
query.find('//ns:identity', :ns => self.class.registered_ns).each &:remove
|
41
|
+
if identities
|
42
|
+
[identities].flatten.each { |i| self.query << Identity.new(i) }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# List of feature objects
|
47
|
+
def features
|
48
|
+
query.find('//ns:feature', :ns => self.class.registered_ns).map do |f|
|
49
|
+
Feature.new f
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Add an array of features
|
54
|
+
# @param features the array of features, passed directly to Feature.new
|
55
|
+
def features=(features)
|
56
|
+
query.find('//ns:feature', :ns => self.class.registered_ns).each &:remove
|
57
|
+
if features
|
58
|
+
[features].flatten.each { |f| self.query << Feature.new(f) }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Compare two DiscoInfo objects by name, type and category
|
63
|
+
# @param [DiscoInfo] o the Identity object to compare against
|
64
|
+
# @return [true, false]
|
65
|
+
def eql?(o, *fields)
|
66
|
+
super o, *(fields + [:identities, :features])
|
67
|
+
end
|
68
|
+
|
69
|
+
# DiscoInfo::Identity
|
70
|
+
class Identity < XMPPNode
|
71
|
+
# Create a new DiscoInfo::Identity
|
72
|
+
# @overload new(node)
|
73
|
+
# Imports the XML::Node to create a Identity object
|
74
|
+
# @param [XML::Node] node the node object to import
|
75
|
+
# @overload new(opts = {})
|
76
|
+
# Creates a new Identity using a hash of options
|
77
|
+
# @param [Hash] opts a hash of options
|
78
|
+
# @option opts [String] :name the name of the identity
|
79
|
+
# @option opts [String] :type the type of the identity
|
80
|
+
# @option opts [String] :category the category of the identity
|
81
|
+
# @overload new(name, type = nil, category = nil)
|
82
|
+
# Create a new Identity by name
|
83
|
+
# @param [String] name the name of the Identity
|
84
|
+
# @param [String, nil] type the type of the Identity
|
85
|
+
# @param [String, nil] category the category of the Identity
|
86
|
+
def self.new(name, type = nil, category = nil, xml_lang = nil)
|
87
|
+
new_node = super :identity
|
88
|
+
|
89
|
+
case name
|
90
|
+
when Nokogiri::XML::Node
|
91
|
+
new_node.inherit name
|
92
|
+
when Hash
|
93
|
+
new_node.name = name[:name]
|
94
|
+
new_node.type = name[:type]
|
95
|
+
new_node.category = name[:category]
|
96
|
+
new_node.xml_lang = name[:xml_lang]
|
97
|
+
else
|
98
|
+
new_node.name = name
|
99
|
+
new_node.type = type
|
100
|
+
new_node.category = category
|
101
|
+
new_node.xml_lang = xml_lang
|
102
|
+
end
|
103
|
+
new_node
|
104
|
+
end
|
105
|
+
|
106
|
+
# The Identity's category
|
107
|
+
# @return [Symbol, nil]
|
108
|
+
def category
|
109
|
+
read_attr :category, :to_sym
|
110
|
+
end
|
111
|
+
|
112
|
+
# Set the Identity's category
|
113
|
+
# @param [String, Symbol] category the new category
|
114
|
+
def category=(category)
|
115
|
+
write_attr :category, category
|
116
|
+
end
|
117
|
+
|
118
|
+
# The Identity's type
|
119
|
+
# @return [Symbol, nil]
|
120
|
+
def type
|
121
|
+
read_attr :type, :to_sym
|
122
|
+
end
|
123
|
+
|
124
|
+
# Set the Identity's type
|
125
|
+
# @param [String, Symbol] type the new category
|
126
|
+
def type=(type)
|
127
|
+
write_attr :type, type
|
128
|
+
end
|
129
|
+
|
130
|
+
# The Identity's name
|
131
|
+
# @return [String]
|
132
|
+
def name
|
133
|
+
read_attr :name
|
134
|
+
end
|
135
|
+
|
136
|
+
# Set the Identity's name
|
137
|
+
# @param [String] name the new name for the identity
|
138
|
+
def name=(name)
|
139
|
+
write_attr :name, name
|
140
|
+
end
|
141
|
+
|
142
|
+
# The Identity's xml_lang
|
143
|
+
# @return [String]
|
144
|
+
def xml_lang
|
145
|
+
read_attr "lang"
|
146
|
+
end
|
147
|
+
|
148
|
+
# Set the Identity's name
|
149
|
+
# @param [String] name the new name for the identity
|
150
|
+
def xml_lang=(xml_lang)
|
151
|
+
write_attr "xml:lang", xml_lang
|
152
|
+
end
|
153
|
+
|
154
|
+
# Compare two Identity objects by name, type and category
|
155
|
+
# @param [DiscoInfo::Identity] o the Identity object to compare against
|
156
|
+
# @return [true, false]
|
157
|
+
def eql?(o, *fields)
|
158
|
+
super o, *(fields + [:name, :type, :category, :xml_lang])
|
159
|
+
end
|
160
|
+
end # Identity
|
161
|
+
|
162
|
+
# DiscoInfo::Feature
|
163
|
+
class Feature < XMPPNode
|
164
|
+
# Create a new DiscoInfo::Feature object
|
165
|
+
# @overload new(node)
|
166
|
+
# Create a new Feature by importing an XML::Node
|
167
|
+
# @param [XML::Node] node an XML::Node to import
|
168
|
+
# @overload new(var)
|
169
|
+
# Create a new feature by var
|
170
|
+
# @param [String] var a the Feautre's var
|
171
|
+
# @return [DiscoInfo::Feature]
|
172
|
+
def self.new(var)
|
173
|
+
new_node = super :feature
|
174
|
+
case var
|
175
|
+
when Nokogiri::XML::Node
|
176
|
+
new_node.inherit var
|
177
|
+
else
|
178
|
+
new_node.var = var
|
179
|
+
end
|
180
|
+
new_node
|
181
|
+
end
|
182
|
+
|
183
|
+
# The Feature's var
|
184
|
+
# @return [String]
|
185
|
+
def var
|
186
|
+
read_attr :var
|
187
|
+
end
|
188
|
+
|
189
|
+
# Set the Feature's var
|
190
|
+
# @param [String] var the new var
|
191
|
+
def var=(var)
|
192
|
+
write_attr :var, var
|
193
|
+
end
|
194
|
+
|
195
|
+
# Compare two DiscoInfo::Feature objects by name, type and category
|
196
|
+
# @param [DiscoInfo::Feature] o the Identity object to compare against
|
197
|
+
# @return [true, false]
|
198
|
+
def eql?(o, *fields)
|
199
|
+
super o, *(fields + [:var])
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end # Feature
|
203
|
+
|
204
|
+
end # Stanza
|
205
|
+
end # Blather
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
|
4
|
+
# # DiscoItems Stanza
|
5
|
+
#
|
6
|
+
# [XEP-0030 Disco Info](http://xmpp.org/extensions/xep-0030.html#items)
|
7
|
+
#
|
8
|
+
# Disco Items node that provides or retreives items associated with a
|
9
|
+
# jabbery entity
|
10
|
+
#
|
11
|
+
# @handler :disco_items
|
12
|
+
class DiscoItems < Disco
|
13
|
+
register :disco_items, nil, 'http://jabber.org/protocol/disco#items'
|
14
|
+
|
15
|
+
# Create a new DiscoItems node
|
16
|
+
#
|
17
|
+
# @param [#to_s] type the IQ type
|
18
|
+
# @param [#to_s] node the node the items are associated with
|
19
|
+
# @param [Array<Blather::XMPPNode>] items an array of Disco::Items
|
20
|
+
# @return [Blather::Stanza::DiscoItems]
|
21
|
+
def self.new(type = nil, node = nil, items = [])
|
22
|
+
new_node = super type
|
23
|
+
new_node.node = node
|
24
|
+
new_node.items = [items]
|
25
|
+
new_node
|
26
|
+
end
|
27
|
+
|
28
|
+
# Set of items associated with the node
|
29
|
+
#
|
30
|
+
# @return [Array<Blather::Stanza::DiscoItems::Item>]
|
31
|
+
def items
|
32
|
+
query.find('//ns:item', :ns => self.class.registered_ns).map do |i|
|
33
|
+
Item.new i
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Add an array of items
|
38
|
+
# @param items the array of items, passed directly to Item.new
|
39
|
+
def items=(items)
|
40
|
+
query.find('//ns:item', :ns => self.class.registered_ns).each &:remove
|
41
|
+
if items
|
42
|
+
[items].flatten.each { |i| self.query << Item.new(i) }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# An individual Disco Item
|
47
|
+
class Item < XMPPNode
|
48
|
+
# Create a new Blather::Stanza::DiscoItems::Item
|
49
|
+
#
|
50
|
+
# @overload new(node)
|
51
|
+
# Create a new Item by inheriting an existing node
|
52
|
+
# @param [XML::Node] node an XML::Node to inherit from
|
53
|
+
# @overload new(opts)
|
54
|
+
# Create a new Item through a hash of options
|
55
|
+
# @param [Hash] opts a hash options
|
56
|
+
# @option opts [Blather::JID, String] :jid the JID to attach to the item
|
57
|
+
# @option opts [#to_s] :node the node the item is attached to
|
58
|
+
# @option opts [#to_S] :name the name of the Item
|
59
|
+
# @overload new(jid, node = nil, name = nil)
|
60
|
+
# Create a new Item
|
61
|
+
# @param [Blather::JID, String] jid the JID to attach to the item
|
62
|
+
# @param [#to_s] node the node the item is attached to
|
63
|
+
# @param [#to_s] name the name of the Item
|
64
|
+
def self.new(jid, node = nil, name = nil)
|
65
|
+
new_node = super :item
|
66
|
+
|
67
|
+
case jid
|
68
|
+
when Nokogiri::XML::Node
|
69
|
+
new_node.inherit jid
|
70
|
+
when Hash
|
71
|
+
new_node.jid = jid[:jid]
|
72
|
+
new_node.node = jid[:node]
|
73
|
+
new_node.name = jid[:name]
|
74
|
+
else
|
75
|
+
new_node.jid = jid
|
76
|
+
new_node.node = node
|
77
|
+
new_node.name = name
|
78
|
+
end
|
79
|
+
new_node
|
80
|
+
end
|
81
|
+
|
82
|
+
# Get the JID attached to the node
|
83
|
+
#
|
84
|
+
# @return [Blather::JID, nil]
|
85
|
+
def jid
|
86
|
+
(j = self[:jid]) ? JID.new(j) : nil
|
87
|
+
end
|
88
|
+
|
89
|
+
# Set the JID of the node
|
90
|
+
#
|
91
|
+
# @param [Blather::JID, String, nil] jid the new JID
|
92
|
+
def jid=(jid)
|
93
|
+
write_attr :jid, jid
|
94
|
+
end
|
95
|
+
|
96
|
+
# Get the name of the node
|
97
|
+
#
|
98
|
+
# @return [String, nil]
|
99
|
+
def node
|
100
|
+
read_attr :node
|
101
|
+
end
|
102
|
+
|
103
|
+
# Set the name of the node
|
104
|
+
#
|
105
|
+
# @param [String, nil] node the new node name
|
106
|
+
def node=(node)
|
107
|
+
write_attr :node, node
|
108
|
+
end
|
109
|
+
|
110
|
+
# Get the Item name
|
111
|
+
#
|
112
|
+
# @return [String, nil]
|
113
|
+
def name
|
114
|
+
read_attr :name
|
115
|
+
end
|
116
|
+
|
117
|
+
# Set the Item name
|
118
|
+
#
|
119
|
+
# @param [#to_s] name the Item name
|
120
|
+
def name=(name)
|
121
|
+
write_attr :name, name
|
122
|
+
end
|
123
|
+
|
124
|
+
# Compare two DiscoItems::Item objects by name, type and category
|
125
|
+
# @param [DiscoItems::Item] o the Identity object to compare against
|
126
|
+
# @return [true, false]
|
127
|
+
def eql?(o, *fields)
|
128
|
+
super o, *(fields + [:jid, :node, :name])
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end #Stanza
|
134
|
+
end #Blather
|