blather 0.6.2 → 0.7.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/.rspec +3 -0
- data/.travis.yml +1 -8
- data/CHANGELOG.md +230 -0
- data/Guardfile +4 -4
- data/README.md +2 -8
- data/Rakefile +14 -27
- data/blather.gemspec +8 -18
- data/lib/blather.rb +1 -0
- data/lib/blather/client/client.rb +8 -0
- data/lib/blather/roster.rb +7 -0
- data/lib/blather/stanza/iq/roster.rb +1 -1
- data/lib/blather/stanza/message/muc_user.rb +2 -0
- data/lib/blather/stanza/muc/muc_user_base.rb +4 -3
- data/lib/blather/stanza/presence.rb +12 -14
- data/lib/blather/stanza/presence/c.rb +58 -62
- data/lib/blather/stanza/presence/muc.rb +14 -10
- data/lib/blather/stanza/presence/muc_user.rb +47 -36
- data/lib/blather/stanza/presence/status.rb +106 -101
- data/lib/blather/stanza/presence/subscription.rb +59 -60
- data/lib/blather/stream.rb +1 -3
- data/lib/blather/stream/features/resource.rb +0 -1
- data/lib/blather/version.rb +1 -2
- data/lib/blather/xmpp_node.rb +24 -3
- data/spec/blather/client/client_spec.rb +64 -64
- data/spec/blather/client/dsl/pubsub_spec.rb +127 -127
- data/spec/blather/client/dsl_spec.rb +11 -11
- data/spec/blather/errors/sasl_error_spec.rb +3 -3
- data/spec/blather/errors/stanza_error_spec.rb +26 -26
- data/spec/blather/errors/stream_error_spec.rb +22 -22
- data/spec/blather/errors_spec.rb +7 -7
- data/spec/blather/file_transfer_spec.rb +16 -18
- data/spec/blather/jid_spec.rb +29 -29
- data/spec/blather/roster_item_spec.rb +18 -18
- data/spec/blather/roster_spec.rb +18 -18
- data/spec/blather/stanza/discos/disco_info_spec.rb +56 -57
- data/spec/blather/stanza/discos/disco_items_spec.rb +33 -33
- data/spec/blather/stanza/iq/command_spec.rb +57 -57
- data/spec/blather/stanza/iq/ibb_spec.rb +27 -39
- data/spec/blather/stanza/iq/ping_spec.rb +13 -9
- data/spec/blather/stanza/iq/query_spec.rb +16 -16
- data/spec/blather/stanza/iq/roster_spec.rb +29 -30
- data/spec/blather/stanza/iq/s5b_spec.rb +10 -13
- data/spec/blather/stanza/iq/si_spec.rb +20 -23
- data/spec/blather/stanza/iq/vcard_spec.rb +22 -25
- data/spec/blather/stanza/iq_spec.rb +12 -12
- data/spec/blather/stanza/message/muc_user_spec.rb +36 -36
- data/spec/blather/stanza/message_spec.rb +56 -56
- data/spec/blather/stanza/presence/c_spec.rb +17 -7
- data/spec/blather/stanza/presence/muc_spec.rb +8 -8
- data/spec/blather/stanza/presence/muc_user_spec.rb +23 -23
- data/spec/blather/stanza/presence/status_spec.rb +42 -30
- data/spec/blather/stanza/presence/subscription_spec.rb +22 -23
- data/spec/blather/stanza/presence_spec.rb +72 -34
- data/spec/blather/stanza/pubsub/affiliations_spec.rb +12 -12
- data/spec/blather/stanza/pubsub/create_spec.rb +10 -10
- data/spec/blather/stanza/pubsub/event_spec.rb +31 -31
- data/spec/blather/stanza/pubsub/items_spec.rb +21 -21
- data/spec/blather/stanza/pubsub/publish_spec.rb +21 -21
- data/spec/blather/stanza/pubsub/retract_spec.rb +20 -20
- data/spec/blather/stanza/pubsub/subscribe_spec.rb +17 -17
- data/spec/blather/stanza/pubsub/subscription_spec.rb +28 -28
- data/spec/blather/stanza/pubsub/subscriptions_spec.rb +11 -11
- data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +22 -22
- data/spec/blather/stanza/pubsub_owner/delete_spec.rb +9 -9
- data/spec/blather/stanza/pubsub_owner/purge_spec.rb +9 -9
- data/spec/blather/stanza/pubsub_owner_spec.rb +6 -6
- data/spec/blather/stanza/pubsub_spec.rb +16 -16
- data/spec/blather/stanza/x_spec.rb +53 -53
- data/spec/blather/stanza_spec.rb +39 -39
- data/spec/blather/stream/client_spec.rb +133 -133
- data/spec/blather/stream/component_spec.rb +7 -7
- data/spec/blather/stream/parser_spec.rb +24 -24
- data/spec/blather/stream/ssl_spec.rb +7 -7
- data/spec/blather/xmpp_node_spec.rb +17 -7
- data/spec/blather_spec.rb +4 -4
- data/spec/spec_helper.rb +6 -54
- metadata +53 -68
- data/CHANGELOG +0 -220
@@ -85,27 +85,25 @@ class Stanza
|
|
85
85
|
# either a Status or Subscription object is created based
|
86
86
|
# on the type attribute.
|
87
87
|
# If neither is found it instantiates a Presence object
|
88
|
-
def self.import(node) # :nodoc:
|
89
|
-
|
90
|
-
node.children.detect do |e|
|
88
|
+
def self.import(node, *decorators) # :nodoc:
|
89
|
+
node.children.each do |e|
|
91
90
|
ns = e.namespace ? e.namespace.href : nil
|
92
|
-
klass = class_from_registration
|
91
|
+
klass = class_from_registration e.element_name, ns
|
92
|
+
decorators << klass if klass
|
93
93
|
end
|
94
94
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
when /subscribe/ then Subscription
|
101
|
-
else self
|
102
|
-
end
|
103
|
-
klass.new.inherit(node)
|
95
|
+
case node['type']
|
96
|
+
when nil, 'unavailable'
|
97
|
+
decorators << Status
|
98
|
+
when /subscribe/
|
99
|
+
decorators << Subscription
|
104
100
|
end
|
101
|
+
|
102
|
+
super
|
105
103
|
end
|
106
104
|
|
107
105
|
# Ensure element_name is "presence" for all subclasses
|
108
|
-
def self.new
|
106
|
+
def self.new(*args)
|
109
107
|
super :presence
|
110
108
|
end
|
111
109
|
|
@@ -22,82 +22,78 @@ class Presence
|
|
22
22
|
new_node.hash = hash
|
23
23
|
new_node.node = node
|
24
24
|
new_node.ver = ver
|
25
|
-
new_node
|
25
|
+
parse new_node.to_xml
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
self.new.inherit(node)
|
30
|
-
end
|
31
|
-
|
32
|
-
# @private
|
33
|
-
def inherit(node)
|
34
|
-
inherit_attrs node.attributes
|
35
|
-
self
|
36
|
-
end
|
28
|
+
module InstanceMethods
|
37
29
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
30
|
+
# @private
|
31
|
+
def inherit(node)
|
32
|
+
c.remove
|
33
|
+
super
|
34
|
+
self
|
35
|
+
end
|
44
36
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
37
|
+
# Get the name of the node
|
38
|
+
#
|
39
|
+
# @return [String, nil]
|
40
|
+
def node
|
41
|
+
c[:node]
|
42
|
+
end
|
51
43
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
44
|
+
# Set the name of the node
|
45
|
+
#
|
46
|
+
# @param [String, nil] node the new node name
|
47
|
+
def node=(node)
|
48
|
+
c[:node] = node
|
49
|
+
end
|
58
50
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
raise ArgumentError, "Invalid Hash Type (#{hash}), use: #{VALID_HASH_TYPES*' '}"
|
51
|
+
# Get the name of the hash
|
52
|
+
#
|
53
|
+
# @return [Symbol, nil]
|
54
|
+
def hash
|
55
|
+
c[:hash] && c[:hash].to_sym
|
65
56
|
end
|
66
|
-
c[:hash] = hash
|
67
|
-
end
|
68
57
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
58
|
+
# Set the name of the hash
|
59
|
+
#
|
60
|
+
# @param [String, nil] hash the new hash name
|
61
|
+
def hash=(hash)
|
62
|
+
if hash && !VALID_HASH_TYPES.include?(hash.to_s)
|
63
|
+
raise ArgumentError, "Invalid Hash Type (#{hash}), use: #{VALID_HASH_TYPES*' '}"
|
64
|
+
end
|
65
|
+
c[:hash] = hash
|
66
|
+
end
|
75
67
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
68
|
+
# Get the ver
|
69
|
+
#
|
70
|
+
# @return [String, nil]
|
71
|
+
def ver
|
72
|
+
c[:ver]
|
73
|
+
end
|
82
74
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
def c
|
89
|
-
c = if self.class.registered_ns
|
90
|
-
find_first('ns:c', :ns => self.class.registered_ns)
|
91
|
-
else
|
92
|
-
find_first('c')
|
75
|
+
# Set the ver
|
76
|
+
#
|
77
|
+
# @param [String, nil] ver the new ver
|
78
|
+
def ver=(ver)
|
79
|
+
c[:ver] = ver
|
93
80
|
end
|
94
81
|
|
95
|
-
|
96
|
-
|
97
|
-
|
82
|
+
# C node accessor
|
83
|
+
# If a c node exists it will be returned.
|
84
|
+
# Otherwise a new node will be created and returned
|
85
|
+
#
|
86
|
+
# @return [Blather::XMPPNode]
|
87
|
+
def c
|
88
|
+
unless c = find_first('ns:c', :ns => C.registered_ns)
|
89
|
+
self << (c = XMPPNode.new('c', self.document))
|
90
|
+
c.namespace = self.class.registered_ns
|
91
|
+
end
|
92
|
+
c
|
98
93
|
end
|
99
|
-
c
|
100
94
|
end
|
95
|
+
|
96
|
+
include InstanceMethods
|
101
97
|
end # C
|
102
98
|
end #Presence
|
103
99
|
end #Stanza
|
@@ -11,19 +11,23 @@ class Presence
|
|
11
11
|
new_node
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
module InstanceMethods
|
15
|
+
def inherit(node)
|
16
|
+
muc.remove
|
17
|
+
super
|
18
|
+
self
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
def muc
|
22
|
+
unless muc = find_first('ns:x', :ns => MUC.registered_ns)
|
23
|
+
self << (muc = XMPPNode.new('x', self.document))
|
24
|
+
muc.namespace = self.class.registered_ns
|
25
|
+
end
|
26
|
+
muc
|
24
27
|
end
|
25
|
-
muc
|
26
28
|
end
|
29
|
+
|
30
|
+
include InstanceMethods
|
27
31
|
end # MUC
|
28
32
|
|
29
33
|
end # Presence
|
@@ -4,59 +4,70 @@ module Blather
|
|
4
4
|
class Stanza
|
5
5
|
class Presence
|
6
6
|
|
7
|
-
class MUCUser <
|
7
|
+
class MUCUser < Presence
|
8
8
|
include Blather::Stanza::MUC::MUCUserBase
|
9
9
|
|
10
|
-
def
|
11
|
-
|
10
|
+
def self.decorator_modules
|
11
|
+
super + [Blather::Stanza::MUC::MUCUserBase]
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
item.affiliation = val
|
16
|
-
end
|
14
|
+
register :muc_user_presence, :x, MUC_USER_NAMESPACE
|
17
15
|
|
18
|
-
|
19
|
-
item.role
|
20
|
-
end
|
16
|
+
module InstanceMethods
|
21
17
|
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
def affiliation
|
19
|
+
item.affiliation
|
20
|
+
end
|
25
21
|
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
def affiliation=(val)
|
23
|
+
item.affiliation = val
|
24
|
+
end
|
29
25
|
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
def role
|
27
|
+
item.role
|
28
|
+
end
|
33
29
|
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
def role=(val)
|
31
|
+
item.role = val
|
32
|
+
end
|
37
33
|
|
38
|
-
|
39
|
-
|
40
|
-
val.each do |code|
|
41
|
-
muc_user << Status.new(code)
|
34
|
+
def jid
|
35
|
+
item.jid
|
42
36
|
end
|
43
|
-
end
|
44
37
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
38
|
+
def jid=(val)
|
39
|
+
item.jid = val
|
40
|
+
end
|
41
|
+
|
42
|
+
def status_codes
|
43
|
+
status.map &:code
|
44
|
+
end
|
45
|
+
|
46
|
+
def status_codes=(val)
|
47
|
+
muc_user.remove_children :status
|
48
|
+
val.each do |code|
|
49
|
+
muc_user << Status.new(code)
|
50
|
+
end
|
51
51
|
end
|
52
|
-
end
|
53
52
|
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
def item
|
54
|
+
if item = muc_user.find_first('ns:item', :ns => MUCUser.registered_ns)
|
55
|
+
Item.new item
|
56
|
+
else
|
57
|
+
muc_user << (item = Item.new nil, nil, nil, self.document)
|
58
|
+
item
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def status
|
63
|
+
muc_user.find('ns:status', :ns => MUCUser.registered_ns).map do |status|
|
64
|
+
Status.new status
|
65
|
+
end
|
57
66
|
end
|
58
67
|
end
|
59
68
|
|
69
|
+
include InstanceMethods
|
70
|
+
|
60
71
|
class Item < XMPPNode
|
61
72
|
def self.new(affiliation = nil, role = nil, jid = nil, document = nil)
|
62
73
|
new_node = super :item, document
|
@@ -93,127 +93,132 @@ class Presence
|
|
93
93
|
node
|
94
94
|
end
|
95
95
|
|
96
|
-
|
97
|
-
#
|
98
|
-
# @return [true, false]
|
99
|
-
def available?
|
100
|
-
self.state == :available
|
101
|
-
end
|
102
|
-
|
103
|
-
# Check if the state is away
|
104
|
-
#
|
105
|
-
# @return [true, false]
|
106
|
-
def away?
|
107
|
-
self.state == :away
|
108
|
-
end
|
96
|
+
module InstanceMethods
|
109
97
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
98
|
+
# Check if the state is available
|
99
|
+
#
|
100
|
+
# @return [true, false]
|
101
|
+
def available?
|
102
|
+
self.state == :available
|
103
|
+
end
|
116
104
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
105
|
+
# Check if the state is away
|
106
|
+
#
|
107
|
+
# @return [true, false]
|
108
|
+
def away?
|
109
|
+
self.state == :away
|
110
|
+
end
|
123
111
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
112
|
+
# Check if the state is chat
|
113
|
+
#
|
114
|
+
# @return [true, false]
|
115
|
+
def chat?
|
116
|
+
self.state == :chat
|
117
|
+
end
|
130
118
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
if type && type.to_sym != :unavailable
|
137
|
-
raise ArgumentError, "Invalid type (#{type}). Must be nil or unavailable"
|
119
|
+
# Check if the state is dnd
|
120
|
+
#
|
121
|
+
# @return [true, false]
|
122
|
+
def dnd?
|
123
|
+
self.state == :dnd
|
138
124
|
end
|
139
|
-
super
|
140
|
-
end
|
141
125
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
state = state.to_sym if state
|
148
|
-
state = nil if state == :available
|
149
|
-
if state && !VALID_STATES.include?(state)
|
150
|
-
raise ArgumentError, "Invalid Status (#{state}), use: #{VALID_STATES*' '}"
|
126
|
+
# Check if the state is xa
|
127
|
+
#
|
128
|
+
# @return [true, false]
|
129
|
+
def xa?
|
130
|
+
self.state == :xa
|
151
131
|
end
|
152
132
|
|
153
|
-
|
154
|
-
|
133
|
+
# Set the type attribute
|
134
|
+
# Ensures type is nil or :unavailable
|
135
|
+
#
|
136
|
+
# @param [<:unavailable, nil>] type the type
|
137
|
+
def type=(type)
|
138
|
+
if type && type.to_sym != :unavailable
|
139
|
+
raise ArgumentError, "Invalid type (#{type}). Must be nil or unavailable"
|
140
|
+
end
|
141
|
+
super
|
142
|
+
end
|
155
143
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
state
|
161
|
-
|
162
|
-
|
163
|
-
|
144
|
+
# Set the state
|
145
|
+
# Ensure state is one of :available, :away, :chat, :dnd, :xa or nil
|
146
|
+
#
|
147
|
+
# @param [<:available, :away, :chat, :dnd, :xa, nil>] state
|
148
|
+
def state=(state) # :nodoc:
|
149
|
+
state = state.to_sym if state
|
150
|
+
state = nil if state == :available
|
151
|
+
if state && !VALID_STATES.include?(state)
|
152
|
+
raise ArgumentError, "Invalid Status (#{state}), use: #{VALID_STATES*' '}"
|
153
|
+
end
|
154
|
+
|
155
|
+
set_content_for :show, state
|
156
|
+
end
|
164
157
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
158
|
+
# Get the state of the status
|
159
|
+
#
|
160
|
+
# @return [<:available, :away, :chat, :dnd, :xa>]
|
161
|
+
def state
|
162
|
+
state = type || content_from(:show)
|
163
|
+
state = :available if state.blank?
|
164
|
+
state.to_sym
|
172
165
|
end
|
173
|
-
set_content_for :priority, new_priority
|
174
|
-
end
|
175
166
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
167
|
+
# Set the priority of the status
|
168
|
+
# Ensures priority is between -128 and 127
|
169
|
+
#
|
170
|
+
# @param [Fixnum<-128...127>] new_priority
|
171
|
+
def priority=(new_priority) # :nodoc:
|
172
|
+
if new_priority && !(-128..127).include?(new_priority.to_i)
|
173
|
+
raise ArgumentError, 'Priority must be between -128 and +127'
|
174
|
+
end
|
175
|
+
set_content_for :priority, new_priority
|
176
|
+
end
|
182
177
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
178
|
+
# Get the priority of the status
|
179
|
+
#
|
180
|
+
# @return [Fixnum<-128...127>]
|
181
|
+
def priority
|
182
|
+
read_content(:priority).to_i
|
183
|
+
end
|
189
184
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
185
|
+
# Get the status message
|
186
|
+
#
|
187
|
+
# @return [String, nil]
|
188
|
+
def message
|
189
|
+
read_content :status
|
190
|
+
end
|
196
191
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
# @return [true,false]
|
203
|
-
def <=>(o)
|
204
|
-
unless self.from && o.from && self.from.stripped == o.from.stripped
|
205
|
-
raise ArgumentError, "Cannot compare status from different JIDs: #{[self.from, o.from].inspect}"
|
192
|
+
# Set the status message
|
193
|
+
#
|
194
|
+
# @param [String, nil] message
|
195
|
+
def message=(message)
|
196
|
+
set_content_for :status, message
|
206
197
|
end
|
207
198
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
199
|
+
# Compare status based on priority and state:
|
200
|
+
# unavailable status is always less valuable than others
|
201
|
+
# Raises an error if the JIDs aren't the same
|
202
|
+
#
|
203
|
+
# @param [Blather::Stanza::Presence::Status] o
|
204
|
+
# @return [true,false]
|
205
|
+
def <=>(o)
|
206
|
+
unless self.from && o.from && self.from.stripped == o.from.stripped
|
207
|
+
raise ArgumentError, "Cannot compare status from different JIDs: #{[self.from, o.from].inspect}"
|
208
|
+
end
|
209
|
+
|
210
|
+
if (self.type.nil? && o.type.nil?) || (!self.type.nil? && !o.type.nil?)
|
211
|
+
self.priority <=> o.priority
|
212
|
+
elsif self.type.nil? && !o.type.nil?
|
213
|
+
1
|
214
|
+
elsif !self.type.nil? && o.type.nil?
|
215
|
+
-1
|
216
|
+
end
|
214
217
|
end
|
215
218
|
end
|
216
219
|
|
220
|
+
include InstanceMethods
|
221
|
+
|
217
222
|
end #Status
|
218
223
|
|
219
224
|
end #Presence
|