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,144 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
|
4
|
+
# # Iq Stanza
|
5
|
+
#
|
6
|
+
# [RFC 3920 Section 9.2.3 - IQ Semantics](http://xmpp.org/rfcs/rfc3920.html#rfc.section.9.2.3)
|
7
|
+
#
|
8
|
+
# Info/Query, or IQ, is a request-response mechanism, similar in some ways
|
9
|
+
# to HTTP. The semantics of IQ enable an entity to make a request of, and
|
10
|
+
# receive a response from, another entity. The data content of the request
|
11
|
+
# and response is defined by the namespace declaration of a direct child
|
12
|
+
# element of the IQ element, and the interaction is tracked by the
|
13
|
+
# requesting entity through use of the 'id' attribute. Thus, IQ interactions
|
14
|
+
# follow a common pattern of structured data exchange such as get/result or
|
15
|
+
# set/result (although an error may be returned in reply to a request if
|
16
|
+
# appropriate).
|
17
|
+
#
|
18
|
+
# ## "ID" Attribute
|
19
|
+
#
|
20
|
+
# Iq Stanzas require the ID attribute be set. Blather will handle this
|
21
|
+
# automatically when a new Iq is created.
|
22
|
+
#
|
23
|
+
# ## "Type" Attribute
|
24
|
+
#
|
25
|
+
# * `:get` -- The stanza is a request for information or requirements.
|
26
|
+
#
|
27
|
+
# * `:set` -- The stanza provides required data, sets new values, or
|
28
|
+
# replaces existing values.
|
29
|
+
#
|
30
|
+
# * `:result` -- The stanza is a response to a successful get or set request.
|
31
|
+
#
|
32
|
+
# * `:error` -- An error has occurred regarding processing or delivery of a
|
33
|
+
# previously-sent get or set (see Stanza Errors).
|
34
|
+
#
|
35
|
+
# Blather provides a helper for each possible type:
|
36
|
+
#
|
37
|
+
# Iq#get?
|
38
|
+
# Iq#set?
|
39
|
+
# Iq#result?
|
40
|
+
# Iq#error?
|
41
|
+
#
|
42
|
+
# Blather treats the `type` attribute like a normal ruby object attribute
|
43
|
+
# providing a getter and setter. The default `type` is `get`.
|
44
|
+
#
|
45
|
+
# iq = Iq.new
|
46
|
+
# iq.type # => :get
|
47
|
+
# iq.get? # => true
|
48
|
+
# iq.type = :set
|
49
|
+
# iq.set? # => true
|
50
|
+
# iq.get? # => false
|
51
|
+
#
|
52
|
+
# iq.type = :invalid # => RuntimeError
|
53
|
+
#
|
54
|
+
# @handler :iq
|
55
|
+
class Iq < Stanza
|
56
|
+
# @private
|
57
|
+
VALID_TYPES = [:get, :set, :result, :error].freeze
|
58
|
+
|
59
|
+
register :iq
|
60
|
+
|
61
|
+
# @private
|
62
|
+
def self.import(node)
|
63
|
+
klass = nil
|
64
|
+
node.children.detect do |e|
|
65
|
+
ns = e.namespace ? e.namespace.href : nil
|
66
|
+
klass = class_from_registration(e.element_name, ns)
|
67
|
+
end
|
68
|
+
|
69
|
+
if klass && klass != self
|
70
|
+
klass.import(node)
|
71
|
+
else
|
72
|
+
new(node[:type]).inherit(node)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Create a new Iq
|
77
|
+
#
|
78
|
+
# @param [Symbol, nil] type the type of stanza (:get, :set, :result, :error)
|
79
|
+
# @param [Blather::JID, String, nil] jid the JID of the inteded recipient
|
80
|
+
# @param [#to_s] id the stanza's ID. Leaving this nil will set the ID to
|
81
|
+
# the next unique number
|
82
|
+
def self.new(type = nil, to = nil, id = nil)
|
83
|
+
node = super :iq
|
84
|
+
node.type = type || :get
|
85
|
+
node.to = to
|
86
|
+
node.id = id || self.next_id
|
87
|
+
node
|
88
|
+
end
|
89
|
+
|
90
|
+
# Check if the IQ is of type :get
|
91
|
+
#
|
92
|
+
# @return [true, false]
|
93
|
+
def get?
|
94
|
+
self.type == :get
|
95
|
+
end
|
96
|
+
|
97
|
+
# Check if the IQ is of type :set
|
98
|
+
#
|
99
|
+
# @return [true, false]
|
100
|
+
def set?
|
101
|
+
self.type == :set
|
102
|
+
end
|
103
|
+
|
104
|
+
# Check if the IQ is of type :result
|
105
|
+
#
|
106
|
+
# @return [true, false]
|
107
|
+
def result?
|
108
|
+
self.type == :result
|
109
|
+
end
|
110
|
+
|
111
|
+
# Check if the IQ is of type :error
|
112
|
+
#
|
113
|
+
# @return [true, false]
|
114
|
+
def error?
|
115
|
+
self.type == :error
|
116
|
+
end
|
117
|
+
|
118
|
+
# Ensures type is :get, :set, :result or :error
|
119
|
+
#
|
120
|
+
# @param [#to_sym] type the Iq type. Must be one of VALID_TYPES
|
121
|
+
def type=(type)
|
122
|
+
if type && !VALID_TYPES.include?(type.to_sym)
|
123
|
+
raise ArgumentError, "Invalid Type (#{type}), use: #{VALID_TYPES*' '}"
|
124
|
+
end
|
125
|
+
super
|
126
|
+
end
|
127
|
+
|
128
|
+
# Overrides the parent method to ensure the reply is of type :result and that
|
129
|
+
# all children are removed.
|
130
|
+
#
|
131
|
+
# @param [Hash] opts options to pass to reply!
|
132
|
+
# @option opts [Boolean] :remove_children Wether or not to remove child nodes when replying
|
133
|
+
#
|
134
|
+
# @return [self]
|
135
|
+
def reply!(opts = {})
|
136
|
+
opts = {:remove_children => true}.merge opts
|
137
|
+
super
|
138
|
+
self.type = :result
|
139
|
+
self
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,339 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stanza
|
3
|
+
class Iq
|
4
|
+
|
5
|
+
# # Command Stanza
|
6
|
+
#
|
7
|
+
# [XEP-0050 Ad-Hoc Commands](http://xmpp.org/extensions/xep-0050.html)
|
8
|
+
#
|
9
|
+
# This is a base class for any command based Iq stanzas. It provides a base set
|
10
|
+
# of methods for working with command stanzas
|
11
|
+
#
|
12
|
+
# @handler :command
|
13
|
+
class Command < Iq
|
14
|
+
# @private
|
15
|
+
VALID_ACTIONS = [:cancel, :execute, :complete, :next, :prev].freeze
|
16
|
+
# @private
|
17
|
+
VALID_STATUS = [:executing, :completed, :canceled].freeze
|
18
|
+
# @private
|
19
|
+
VALID_NOTE_TYPES = [:info, :warn, :error].freeze
|
20
|
+
|
21
|
+
register :command, :command, 'http://jabber.org/protocol/commands'
|
22
|
+
|
23
|
+
# Overrides the parent method to ensure a command node is created
|
24
|
+
#
|
25
|
+
# @param [:get, :set, :result, :error, nil] type the IQ type
|
26
|
+
# @param [String] node the name of the node
|
27
|
+
# @param [:cancel, :execute, :complete, :next, :prev, nil] action the command's action
|
28
|
+
# @return [Command] a new Command stanza
|
29
|
+
def self.new(type = :set, node = nil, action = :execute)
|
30
|
+
new_node = super type
|
31
|
+
new_node.command
|
32
|
+
new_node.node = node
|
33
|
+
new_node.action = action
|
34
|
+
new_node
|
35
|
+
end
|
36
|
+
|
37
|
+
# Overrides the parent method to ensure the current command node is destroyed
|
38
|
+
# and the action is set to execute if no action provided
|
39
|
+
#
|
40
|
+
# @see Blather::Stanza::Iq#inherit
|
41
|
+
def inherit(node)
|
42
|
+
command.remove
|
43
|
+
super
|
44
|
+
self.action = :execute unless self.action
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
# Overrides the parent method to ensure the reply has no action
|
49
|
+
#
|
50
|
+
# @param [Hash] opts options to pass to reply!
|
51
|
+
# @option opts [Boolean] :remove_children Wether or not to remove child nodes when replying
|
52
|
+
#
|
53
|
+
# @return [self]
|
54
|
+
def reply!(opts = {})
|
55
|
+
super
|
56
|
+
self.action = nil
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
# Command node accessor
|
61
|
+
# If a command node exists it will be returned.
|
62
|
+
# Otherwise a new node will be created and returned
|
63
|
+
#
|
64
|
+
# @return [Blather::XMPPNode]
|
65
|
+
def command
|
66
|
+
c = if self.class.registered_ns
|
67
|
+
find_first('ns:command', :ns => self.class.registered_ns)
|
68
|
+
else
|
69
|
+
find_first('command')
|
70
|
+
end
|
71
|
+
|
72
|
+
unless c
|
73
|
+
(self << (c = XMPPNode.new('command', self.document)))
|
74
|
+
c.namespace = self.class.registered_ns
|
75
|
+
end
|
76
|
+
c
|
77
|
+
end
|
78
|
+
|
79
|
+
# Get the name of the node
|
80
|
+
#
|
81
|
+
# @return [String, nil]
|
82
|
+
def node
|
83
|
+
command[:node]
|
84
|
+
end
|
85
|
+
|
86
|
+
# Set the name of the node
|
87
|
+
#
|
88
|
+
# @param [String, nil] node the new node name
|
89
|
+
def node=(node)
|
90
|
+
command[:node] = node
|
91
|
+
end
|
92
|
+
|
93
|
+
# Get the sessionid of the command
|
94
|
+
#
|
95
|
+
# @return [String, nil]
|
96
|
+
def sessionid
|
97
|
+
command[:sessionid]
|
98
|
+
end
|
99
|
+
|
100
|
+
# Check if there is a sessionid set
|
101
|
+
#
|
102
|
+
# @return [true, false]
|
103
|
+
def sessionid?
|
104
|
+
!sessionid.nil?
|
105
|
+
end
|
106
|
+
|
107
|
+
# Set the sessionid of the command
|
108
|
+
#
|
109
|
+
# @param [String, nil] sessionid the new sessionid
|
110
|
+
def sessionid=(sessionid)
|
111
|
+
command[:sessionid] = Digest::SHA1.hexdigest(sessionid)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Generate a new session ID (SHA-1 hash)
|
115
|
+
def new_sessionid!
|
116
|
+
self.sessionid = "commandsession-#{id}"
|
117
|
+
end
|
118
|
+
|
119
|
+
# Get the action of the command
|
120
|
+
#
|
121
|
+
# @return [Symbol, nil]
|
122
|
+
def action
|
123
|
+
(val = command[:action]) && val.to_sym
|
124
|
+
end
|
125
|
+
|
126
|
+
# Check if the command action is :cancel
|
127
|
+
#
|
128
|
+
# @return [true, false]
|
129
|
+
def cancel?
|
130
|
+
self.action == :cancel
|
131
|
+
end
|
132
|
+
|
133
|
+
# Check if the command action is :execute
|
134
|
+
#
|
135
|
+
# @return [true, false]
|
136
|
+
def execute?
|
137
|
+
self.action == :execute
|
138
|
+
end
|
139
|
+
|
140
|
+
# Check if the command action is :complete
|
141
|
+
#
|
142
|
+
# @return [true, false]
|
143
|
+
def complete?
|
144
|
+
self.action == :complete
|
145
|
+
end
|
146
|
+
|
147
|
+
# Check if the command action is :next
|
148
|
+
#
|
149
|
+
# @return [true, false]
|
150
|
+
def next?
|
151
|
+
self.action == :next
|
152
|
+
end
|
153
|
+
|
154
|
+
# Check if the command action is :prev
|
155
|
+
#
|
156
|
+
# @return [true, false]
|
157
|
+
def prev?
|
158
|
+
self.action == :prev
|
159
|
+
end
|
160
|
+
|
161
|
+
# Set the action of the command
|
162
|
+
#
|
163
|
+
# @param [:cancel, :execute, :complete, :next, :prev] action the new action
|
164
|
+
def action=(action)
|
165
|
+
if action && !VALID_ACTIONS.include?(action.to_sym)
|
166
|
+
raise ArgumentError, "Invalid Action (#{action}), use: #{VALID_ACTIONS*' '}"
|
167
|
+
end
|
168
|
+
command[:action] = action
|
169
|
+
end
|
170
|
+
|
171
|
+
# Get the status of the command
|
172
|
+
#
|
173
|
+
# @return [Symbol, nil]
|
174
|
+
def status
|
175
|
+
((val = command[:status]) && val.to_sym) || :executing
|
176
|
+
end
|
177
|
+
|
178
|
+
# Check if the command status is :executing
|
179
|
+
#
|
180
|
+
# @return [true, false]
|
181
|
+
def executing?
|
182
|
+
self.status == :executing
|
183
|
+
end
|
184
|
+
|
185
|
+
# Check if the command status is :completed
|
186
|
+
#
|
187
|
+
# @return [true, false]
|
188
|
+
def completed?
|
189
|
+
self.status == :completed
|
190
|
+
end
|
191
|
+
|
192
|
+
# Check if the command status is :canceled
|
193
|
+
#
|
194
|
+
# @return [true, false]
|
195
|
+
def canceled?
|
196
|
+
self.status == :canceled
|
197
|
+
end
|
198
|
+
|
199
|
+
# Set the status of the command
|
200
|
+
#
|
201
|
+
# @param [:executing, :completed, :canceled] status the new status
|
202
|
+
def status=(status)
|
203
|
+
if status && !VALID_STATUS.include?(status.to_sym)
|
204
|
+
raise ArgumentError, "Invalid Action (#{status}), use: #{VALID_STATUS*' '}"
|
205
|
+
end
|
206
|
+
command[:status] = status
|
207
|
+
end
|
208
|
+
|
209
|
+
# Command actions accessor
|
210
|
+
# If a command actions element exists it will be returned.
|
211
|
+
# Otherwise a new actions element will be created and returned
|
212
|
+
#
|
213
|
+
# @return [Blather::XMPPNode]
|
214
|
+
def actions
|
215
|
+
unless a = self.command.find_first('ns:actions', :ns => self.class.registered_ns)
|
216
|
+
(self.command << (a = XMPPNode.new('actions', self.document)))
|
217
|
+
a.namespace = self.command.namespace
|
218
|
+
end
|
219
|
+
a
|
220
|
+
end
|
221
|
+
|
222
|
+
# Get the command's allowed actions
|
223
|
+
#
|
224
|
+
# @return [Array<Symbol>]
|
225
|
+
def allowed_actions
|
226
|
+
([:execute] + actions.children.map { |action| action.name.to_sym }).uniq
|
227
|
+
end
|
228
|
+
|
229
|
+
# Get the primary allowed action
|
230
|
+
#
|
231
|
+
# @return [Symbol]
|
232
|
+
def primary_allowed_action
|
233
|
+
(actions[:execute] || :execute).to_sym
|
234
|
+
end
|
235
|
+
|
236
|
+
# Set the primary allowed action
|
237
|
+
#
|
238
|
+
# This must be one of :prev, :next, :complete or :execute
|
239
|
+
#
|
240
|
+
# @param [#to_sym] a the primary allowed action
|
241
|
+
def primary_allowed_action=(a)
|
242
|
+
a = a.to_sym
|
243
|
+
if a && ![:prev, :next, :complete, :execute].include?(a)
|
244
|
+
raise ArgumentError, "Invalid Action (#{a}), use: #{[:prev, :next, :complete, :execute]*' '}"
|
245
|
+
end
|
246
|
+
actions[:execute] = a
|
247
|
+
end
|
248
|
+
|
249
|
+
# Add allowed actions to the command
|
250
|
+
#
|
251
|
+
# @param [[:prev, :next, :complete]] allowed_actions the new allowed actions
|
252
|
+
def allowed_actions=(allowed_actions)
|
253
|
+
allowed_actions = ([allowed_actions].flatten.map(&:to_sym) + [:execute]).uniq
|
254
|
+
if (invalid_actions = allowed_actions - VALID_ACTIONS).size > 0
|
255
|
+
raise ArgumentError, "Invalid Action(s) (#{invalid_actions*' '}), use: #{VALID_ACTIONS*' '}"
|
256
|
+
end
|
257
|
+
actions.children.map(&:remove)
|
258
|
+
allowed_actions.each { |action| actions << XMPPNode.new(action.to_s) }
|
259
|
+
end
|
260
|
+
|
261
|
+
# Remove allowed actions from the command
|
262
|
+
#
|
263
|
+
# @param [[:prev, :next, :complete]] disallowed_actions the allowed actions to remove
|
264
|
+
def remove_allowed_actions!
|
265
|
+
actions.remove
|
266
|
+
end
|
267
|
+
|
268
|
+
# Command note accessor
|
269
|
+
# If a command note exists it will be returned.
|
270
|
+
# Otherwise a new note will be created and returned
|
271
|
+
#
|
272
|
+
# @return [Blather::XMPPNode]
|
273
|
+
def note
|
274
|
+
unless n = self.command.find_first('ns:note', :ns => self.class.registered_ns)
|
275
|
+
(self.command << (n = XMPPNode.new('note', self.document)))
|
276
|
+
n.namespace = self.command.namespace
|
277
|
+
end
|
278
|
+
n
|
279
|
+
end
|
280
|
+
|
281
|
+
# Get the note_type of the command
|
282
|
+
#
|
283
|
+
# @return [Symbol, nil]
|
284
|
+
def note_type
|
285
|
+
(val = note[:type]) && val.to_sym
|
286
|
+
end
|
287
|
+
|
288
|
+
# Check if the command status is :info
|
289
|
+
#
|
290
|
+
# @return [true, false]
|
291
|
+
def info?
|
292
|
+
self.note_type == :info
|
293
|
+
end
|
294
|
+
|
295
|
+
# Check if the command status is :warn
|
296
|
+
#
|
297
|
+
# @return [true, false]
|
298
|
+
def warn?
|
299
|
+
self.status == :warn
|
300
|
+
end
|
301
|
+
|
302
|
+
# Check if the command status is :error
|
303
|
+
#
|
304
|
+
# @return [true, false]
|
305
|
+
def error?
|
306
|
+
self.status == :error
|
307
|
+
end
|
308
|
+
|
309
|
+
# Set the note_type of the command
|
310
|
+
#
|
311
|
+
# @param [:executing, :completed, :canceled] note_type the new note_type
|
312
|
+
def note_type=(note_type)
|
313
|
+
if note_type && !VALID_NOTE_TYPES.include?(note_type.to_sym)
|
314
|
+
raise ArgumentError, "Invalid Action (#{note_type}), use: #{VALID_NOTE_TYPES*' '}"
|
315
|
+
end
|
316
|
+
note[:type] = note_type
|
317
|
+
end
|
318
|
+
|
319
|
+
# Get the text of the command's note
|
320
|
+
def note_text
|
321
|
+
content_from :note
|
322
|
+
end
|
323
|
+
|
324
|
+
# Set the command's note text
|
325
|
+
#
|
326
|
+
# @param [String] note_text the command's new note text
|
327
|
+
def note_text=(note_text)
|
328
|
+
set_content_for :note, note_text
|
329
|
+
end
|
330
|
+
|
331
|
+
# Returns the command's x:data form child
|
332
|
+
def form
|
333
|
+
X.find_or_create command
|
334
|
+
end
|
335
|
+
end #Command
|
336
|
+
|
337
|
+
end #Iq
|
338
|
+
end #Stanza
|
339
|
+
end #Blather
|