tp-blather 0.8.2
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/.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
|