Class: Adhearsion::VoIP::Asterisk::AMI::Actions::Action
- Defined in:
- lib/adhearsion/voip/asterisk/ami/actions.rb
Direct Known Subclasses
Constant Summary collapse
- @@subclasses =
[]
- @@actions =
{}
Instance Attribute Summary collapse
-
#action ⇒ Object
Returns the value of attribute action.
-
#action_id ⇒ Object
Returns the value of attribute action_id.
Class Method Summary collapse
- .[](key) ⇒ Object
- .[]=(key, action) ⇒ Object
-
.build(name, hash, &block) ⇒ Object
Return a new instance of the command.
-
.inherited(klass) ⇒ Object
Keep a list of the subclasses.
Instance Method Summary collapse
- #<<(packet) ⇒ Object
-
#async? ⇒ Boolean
Return true if this action returns matching events that we will not wait on, but can access at a later time.
- #check_error! ⇒ Object
- #complete! ⇒ Object
- #complete_async! ⇒ Object
- #complete_sync! ⇒ Object
-
#completed_by?(packet) ⇒ Boolean
Return true if this packet completes the command, i.e., there is no more synchronous response data to receive for this command.
-
#completed_by_async?(packet) ⇒ Boolean
Return true if this packet completes the matching asynchronous events for this command.
- #done? ⇒ Boolean
-
#follows? ⇒ Boolean
Actions of the form “Response: <Action> results will follow”.
-
#has_response? ⇒ Boolean
Virtually all commands return a response.
-
#immediate? ⇒ Boolean
Return true if this is an ‘immediate’ command, i.e., it returns raw results synchronously without a response header.
-
#initialize(name, hash, &block) ⇒ Action
constructor
A new instance of Action.
-
#keep?(packet) ⇒ Boolean
Return true if the packet should be included in the response.
-
#keep_event?(packet) ⇒ Boolean
By default, we keep any event packet, unless it is the completion packet for a ‘follows’ command.
- #packets! ⇒ Object
- #to_s ⇒ Object
-
#waits_for_events? ⇒ Boolean
Return true if this action will return matching events that we will wait on.
Constructor Details
#initialize(name, hash, &block) ⇒ Action
Returns a new instance of Action.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 38 def initialize(name, hash, &block) @action = name.downcase @action_id = __action_id @arguments = {} @packets = [] @sync_complete = false @error = nil # Normalize the keys hash.each_pair { |k,v| @arguments[k.to_s.downcase] = v } if block and not async? raise RuntimeError, "Cannot specify completion callback for synchronous command" end @async_completion_callback = block end |
Instance Attribute Details
#action ⇒ Object
Returns the value of attribute action.
10 11 12 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 10 def action @action end |
#action_id ⇒ Object
Returns the value of attribute action_id.
11 12 13 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 11 def action_id @action_id end |
Class Method Details
.[](key) ⇒ Object
29 30 31 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 29 def [](key) @@actions[key] end |
.[]=(key, action) ⇒ Object
33 34 35 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 33 def []=(key, action) @@actions[key] = action end |
.build(name, hash, &block) ⇒ Object
Return a new instance of the command. Make sure to return an instance of the command-specific subclass if it exists.
16 17 18 19 20 21 22 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 16 def build(name, hash, &block) name = name.to_s entry = @@subclasses.find { |klass| klass.downcase == name.downcase } klass = entry ? Actions.const_get("#{entry}Action") : self obj = klass.new(name, hash, &block) self[obj.action_id] = obj end |
.inherited(klass) ⇒ Object
Keep a list of the subclasses.
25 26 27 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 25 def inherited(klass) @@subclasses << klass.to_s.split("::").last.match(/(.*?)Action/)[1] end |
Instance Method Details
#<<(packet) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 55 def <<(packet) if packet.error? @error = packet. complete_sync! end # We don't keep every packet, just the important ones. @packets << packet if keep?(packet) # Check if the synchronous portion of the action is done. if completed_by?(packet) # The synchronous portion is done. complete_sync! # We're totally done if it is not asynchronous. complete! if not async? end # Check if this is an asynchronous action, and we have received the last event complete_async! if completed_by_async?(packet) end |
#async? ⇒ Boolean
Return true if this action returns matching events that we will not wait on, but can access at a later time.
111 112 113 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 111 def async? false end |
#check_error! ⇒ Object
93 94 95 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 93 def check_error! raise ActionError, @error if @error end |
#complete! ⇒ Object
152 153 154 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 152 def complete! Action[@action_id] = nil end |
#complete_async! ⇒ Object
147 148 149 150 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 147 def complete_async! @async_completion_callback.call(self.packets!) if @async_completion_callback complete! end |
#complete_sync! ⇒ Object
143 144 145 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 143 def complete_sync! @sync_complete = true end |
#completed_by?(packet) ⇒ Boolean
Return true if this packet completes the command, i.e., there is no more synchronous response data to receive for this command.
128 129 130 131 132 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 128 def completed_by?(packet) return true if not waits_for_events? return false if not packet.is_event? packet.event.downcase == "#{@action}complete" end |
#completed_by_async?(packet) ⇒ Boolean
Return true if this packet completes the matching asynchronous events for this command.
136 137 138 139 140 141 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 136 def completed_by_async?(packet) return false if not async? return false if not packet.is_event? statuses = %w(success failure).collect { |status| "#{@action}#{status}" } statuses.include?(packet.event.downcase) end |
#done? ⇒ Boolean
77 78 79 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 77 def done? @sync_complete end |
#follows? ⇒ Boolean
Actions of the form “Response: <Action> results will follow”
116 117 118 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 116 def follows? %w(parkedcalls queuestatus agents status sippeers zapshowchannels).include? @action end |
#has_response? ⇒ Boolean
Virtually all commands return a response. There is at least one exception, handled with a command-specific subclass.
122 123 124 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 122 def has_response? true end |
#immediate? ⇒ Boolean
Return true if this is an ‘immediate’ command, i.e., it returns raw results synchronously without a response header. Don’t bother doing this in subclasses. It is easy enough.
100 101 102 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 100 def immediate? %w(iaxpeers queues).include? @action end |
#keep?(packet) ⇒ Boolean
Return true if the packet should be included in the response. Raw and synchronous responses are kept. Some event responses are rejected.
158 159 160 161 162 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 158 def keep?(packet) return true if not waits_for_events? return false if not packet.is_event? return keep_event?(packet) end |
#keep_event?(packet) ⇒ Boolean
By default, we keep any event packet, unless it is the completion packet for a ‘follows’ command. These are just marker packets that signify the end of the event stream for the response. TODO: They do contain a count of the events generated, which perhaps we want to verify matches the number we think we have received?
169 170 171 172 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 169 def keep_event?(packet) return false if (follows? and completed_by?(packet)) true end |
#packets! ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 81 def packets! packets, @packets = @packets, [] packets.inject([]) do |arr, pkt| pkt = pkt.body.inject({}) do |hash, (k, v)| hash[k] = v hash end arr << pkt if not pkt.blank? arr end end |
#to_s ⇒ Object
174 175 176 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 174 def to_s __args_to_str end |
#waits_for_events? ⇒ Boolean
Return true if this action will return matching events that we will wait on.
105 106 107 |
# File 'lib/adhearsion/voip/asterisk/ami/actions.rb', line 105 def waits_for_events? follows? or %w(dbget).include? @action end |