[asterisk-commits] mjordan: testsuite/asterisk/trunk r3860 - /asterisk/trunk/lib/python/asterisk/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jun 18 16:14:45 CDT 2013


Author: mjordan
Date: Tue Jun 18 16:14:43 2013
New Revision: 3860

URL: http://svnview.digium.com/svn/testsuite?view=rev&rev=3860
Log:
Add a hangup event instance class to PluggableModules

It's a fairly common need to arbitrarily hang up channel. This patch
adds two modules to do this. The first will hangup a channel given an
AMI event that contains the channel to hang up. The second is less picky -
it tracks all channels and, upon matching on some arbitrary event - hangs
up everyone.

Modified:
    asterisk/trunk/lib/python/asterisk/PluggableModules.py
    asterisk/trunk/lib/python/asterisk/ami.py

Modified: asterisk/trunk/lib/python/asterisk/PluggableModules.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/lib/python/asterisk/PluggableModules.py?view=diff&rev=3860&r1=3859&r2=3860
==============================================================================
--- asterisk/trunk/lib/python/asterisk/PluggableModules.py (original)
+++ asterisk/trunk/lib/python/asterisk/PluggableModules.py Tue Jun 18 16:14:43 2013
@@ -103,6 +103,7 @@
         self.originate_call()
         return result
 
+
 class AMIPrivateCallbackInstance(AMIEventInstance):
     '''
     Subclass of AMIEventInstance that operates by calling a user-defined
@@ -121,3 +122,59 @@
     def check_result(self, callback_param):
         self.test_object.set_passed(self.passed)
         return callback_param
+
+
+class AMIChannelHangup(AMIEventInstance):
+    ''' An AMIEventInstance derived class that hangs up a channel when an
+    event is matched. '''
+
+    def __init__(self, instance_config, test_object):
+        ''' Constructor for pluggable modules '''
+        super(AMIChannelHangup, self).__init__(instance_config, test_object)
+        self.hungup_channel = False
+
+    def event_callback(self, ami, event):
+        ''' Override of the event callback '''
+        if self.hungup_channel:
+            return
+        if 'channel' not in event:
+            return
+        LOGGER.info('Hanging up channel %s' % event['channel'])
+        self.hungup_channel = True
+        ami.hangup(event['channel'])
+
+
+class AMIChannelHangupAll(AMIEventInstance):
+    ''' An AMIEventInstance derived class that hangs up all the channels when
+    an event is matched. '''
+
+    def __init__(self, instance_config, test_object):
+        ''' Constructor for pluggable modules '''
+        super(AMIChannelHangupAll, self).__init__(instance_config, test_object)
+        test_object.register_ami_observer(self.__ami_connect)
+        self.channels = []
+
+    def __ami_connect(self, ami):
+        if str(ami.id) in self.ids:
+            ami.registerEvent('Newchannel', self.__new_channel_handler)
+            ami.registerEvent('Hangup', self.__hangup_handler)
+
+    def __new_channel_handler(self, ami, event):
+        self.channels.append({'id': ami.id, 'channel': event['channel']})
+
+    def __hangup_handler(self, ami, event):
+        objects = [x for x in self.channels if x['id'] == ami.id and x['channel'] == event['channel']]
+        for obj in objects:
+            self.channels.remove(obj)
+
+    def event_callback(self, ami, event):
+        ''' Override of the event callback '''
+        def __hangup_ignore(result):
+            # Ignore hangup errors - if the channel is gone, we don't care
+            return
+
+        objects = [x for x in self.channels if x['id'] == ami.id]
+        for obj in objects:
+            LOGGER.info('Hanging up channel %s' % obj['channel'])
+            ami.hangup(obj['channel']).addErrback(__hangup_ignore)
+            self.channels.remove(obj)

Modified: asterisk/trunk/lib/python/asterisk/ami.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/lib/python/asterisk/ami.py?view=diff&rev=3860&r1=3859&r2=3860
==============================================================================
--- asterisk/trunk/lib/python/asterisk/ami.py (original)
+++ asterisk/trunk/lib/python/asterisk/ami.py Tue Jun 18 16:14:43 2013
@@ -23,6 +23,7 @@
         self.config = instance_config
         self.passed = True
         self._registered = False
+        self._event_observers = []
 
         if 'count' in instance_config:
             count = instance_config['count']
@@ -47,8 +48,7 @@
             self.count_max = float("inf")
 
         self.event_count = 0
-
-        if instance_config['type'] == 'cel':
+        if 'type' in instance_config and instance_config['type'] == 'cel':
             # If the type is 'cel' and no condition matches are defined in the
             # test's yaml then create the dict with setting the Event to 'CEL'.
             # Otherwise set Event to 'CEL' since it's the only Event we want.
@@ -81,6 +81,10 @@
             ami.registerEvent(self.match_conditions['Event'], self.__event_callback)
             self._registered = True
 
+    def register_event_observer(self, observer):
+        ''' Register an observer to be called when a matched event is received '''
+        self._event_observers.append(observer)
+
     def dispose(self, ami):
         ''' Dispose of this object's AMI event registrations '''
         if str(ami.id) not in self.ids:
@@ -130,7 +134,8 @@
         #Conditions have matched up as expected
         #so leave it to the individual types to determine
         #how to proceed
-
+        for observer in self._event_observers:
+            observer(ami, event)
         return self.event_callback(ami, event)
 
     def check_result(self, callback_param):




More information about the asterisk-commits mailing list