Removing trailing whitespace from files.
parent
c1b0b6657f
commit
85fc17017e
|
@ -52,9 +52,9 @@ class AGI:
|
|||
"""
|
||||
This class encapsulates communication between Asterisk an a python script.
|
||||
It handles encoding commands to Asterisk and parsing responses from
|
||||
Asterisk.
|
||||
Asterisk.
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self._got_sighup = False
|
||||
signal.signal(signal.SIGHUP, self._handle_sighup) # handle SIGHUP
|
||||
|
@ -93,7 +93,7 @@ class AGI:
|
|||
"""This function throws AGIHangup if we have recieved a SIGHUP"""
|
||||
if self._got_sighup:
|
||||
raise AGISIGHUPHangup("Received SIGHUP from Asterisk")
|
||||
|
||||
|
||||
def execute(self, command, *args):
|
||||
self.test_hangup()
|
||||
|
||||
|
@ -208,17 +208,17 @@ class AGI:
|
|||
|
||||
def tdd_mode(self, mode='off'):
|
||||
"""agi.tdd_mode(mode='on'|'off') --> None
|
||||
Enable/Disable TDD transmission/reception on a channel.
|
||||
Enable/Disable TDD transmission/reception on a channel.
|
||||
Throws AGIAppError if channel is not TDD-capable.
|
||||
"""
|
||||
res = self.execute('TDD MODE', mode)['result'][0]
|
||||
if res == '0':
|
||||
raise AGIAppError('Channel %s is not TDD-capable')
|
||||
|
||||
|
||||
def stream_file(self, filename, escape_digits='', sample_offset=0):
|
||||
"""agi.stream_file(filename, escape_digits='', sample_offset=0) --> digit
|
||||
Send the given file, allowing playback to be interrupted by the given
|
||||
digits, if any. escape_digits is a string '12345' or a list of
|
||||
digits, if any. escape_digits is a string '12345' or a list of
|
||||
ints [1,2,3,4,5] or strings ['1','2','3'] or mixed [1,'2',3,'4']
|
||||
If sample offset is provided then the audio will seek to sample
|
||||
offset before play starts. Returns digit if one was pressed.
|
||||
|
@ -235,11 +235,11 @@ class AGI:
|
|||
return chr(int(res))
|
||||
except:
|
||||
raise AGIError('Unable to convert result to char: %s' % res)
|
||||
|
||||
|
||||
def control_stream_file(self, filename, escape_digits='', skipms=3000, fwd='', rew='', pause=''):
|
||||
"""
|
||||
Send the given file, allowing playback to be interrupted by the given
|
||||
digits, if any. escape_digits is a string '12345' or a list of
|
||||
digits, if any. escape_digits is a string '12345' or a list of
|
||||
ints [1,2,3,4,5] or strings ['1','2','3'] or mixed [1,'2',3,'4']
|
||||
If sample offset is provided then the audio will seek to sample
|
||||
offset before play starts. Returns digit if one was pressed.
|
||||
|
@ -270,7 +270,7 @@ class AGI:
|
|||
def say_digits(self, digits, escape_digits=''):
|
||||
"""agi.say_digits(digits, escape_digits='') --> digit
|
||||
Say a given digit string, returning early if any of the given DTMF digits
|
||||
are received on the channel.
|
||||
are received on the channel.
|
||||
Throws AGIError on channel failure
|
||||
"""
|
||||
digits = self._process_digit_list(digits)
|
||||
|
@ -287,7 +287,7 @@ class AGI:
|
|||
def say_number(self, number, escape_digits=''):
|
||||
"""agi.say_number(number, escape_digits='') --> digit
|
||||
Say a given digit string, returning early if any of the given DTMF digits
|
||||
are received on the channel.
|
||||
are received on the channel.
|
||||
Throws AGIError on channel failure
|
||||
"""
|
||||
number = self._process_digit_list(number)
|
||||
|
@ -304,7 +304,7 @@ class AGI:
|
|||
def say_alpha(self, characters, escape_digits=''):
|
||||
"""agi.say_alpha(string, escape_digits='') --> digit
|
||||
Say a given character string, returning early if any of the given DTMF
|
||||
digits are received on the channel.
|
||||
digits are received on the channel.
|
||||
Throws AGIError on channel failure
|
||||
"""
|
||||
characters = self._process_digit_list(characters)
|
||||
|
@ -321,7 +321,7 @@ class AGI:
|
|||
def say_phonetic(self, characters, escape_digits=''):
|
||||
"""agi.say_phonetic(string, escape_digits='') --> digit
|
||||
Phonetically say a given character string, returning early if any of
|
||||
the given DTMF digits are received on the channel.
|
||||
the given DTMF digits are received on the channel.
|
||||
Throws AGIError on channel failure
|
||||
"""
|
||||
characters = self._process_digit_list(characters)
|
||||
|
@ -364,7 +364,7 @@ class AGI:
|
|||
return chr(int(res))
|
||||
except:
|
||||
raise AGIError('Unable to convert result to char: %s' % res)
|
||||
|
||||
|
||||
def say_datetime(self, seconds, escape_digits='', format='', zone=''):
|
||||
"""agi.say_datetime(seconds, escape_digits='', format='', zone='') --> digit
|
||||
Say a given date in the format specfied (see voicemail.conf), returning
|
||||
|
@ -389,11 +389,11 @@ class AGI:
|
|||
result = self.execute('GET DATA', filename, timeout, max_digits)
|
||||
res, value = result['result']
|
||||
return res
|
||||
|
||||
|
||||
def get_option(self, filename, escape_digits='', timeout=0):
|
||||
"""agi.get_option(filename, escape_digits='', timeout=0) --> digit
|
||||
Send the given file, allowing playback to be interrupted by the given
|
||||
digits, if any. escape_digits is a string '12345' or a list of
|
||||
digits, if any. escape_digits is a string '12345' or a list of
|
||||
ints [1,2,3,4,5] or strings ['1','2','3'] or mixed [1,'2',3,'4']
|
||||
Returns digit if one was pressed.
|
||||
Throws AGIError if the channel was disconnected. Remember, the file
|
||||
|
@ -449,9 +449,9 @@ class AGI:
|
|||
def record_file(self, filename, format='gsm', escape_digits='#', timeout=DEFAULT_RECORD, offset=0, beep='beep'):
|
||||
"""agi.record_file(filename, format, escape_digits, timeout=DEFAULT_TIMEOUT, offset=0, beep='beep') --> None
|
||||
Record to a file until a given dtmf digit in the sequence is received
|
||||
The format will specify what kind of file will be recorded. The timeout
|
||||
is the maximum record time in milliseconds, or -1 for no timeout. Offset
|
||||
samples is optional, and if provided will seek to the offset without
|
||||
The format will specify what kind of file will be recorded. The timeout
|
||||
is the maximum record time in milliseconds, or -1 for no timeout. Offset
|
||||
samples is optional, and if provided will seek to the offset without
|
||||
exceeding the end of the file
|
||||
"""
|
||||
escape_digits = self._process_digit_list(escape_digits)
|
||||
|
@ -589,7 +589,7 @@ class AGI:
|
|||
res, value = result['result']
|
||||
if res == '0':
|
||||
raise AGIDBError('Unable to put vaule in databale: family=%s, key=%s, value=%s' % (family, key, value))
|
||||
|
||||
|
||||
def database_del(self, family, key):
|
||||
"""agi.database_del(family, key) --> None
|
||||
Deletes an entry in the Asterisk database for a
|
||||
|
|
|
@ -12,7 +12,7 @@ at the top of your script. The optional arguments to enable() are:
|
|||
|
||||
agi - the agi handle to write verbose messages to
|
||||
display - if true, tracebacks are displayed on the asterisk console
|
||||
(used with the agi option)
|
||||
(used with the agi option)
|
||||
logdir - if set, tracebacks are written to files in this directory
|
||||
context - number of lines of source code to show for each stack frame
|
||||
|
||||
|
@ -194,7 +194,7 @@ class Hook:
|
|||
self.agi.verbose(msg, 4)
|
||||
else:
|
||||
self.file.write(msg + '\n')
|
||||
|
||||
|
||||
try:
|
||||
self.file.flush()
|
||||
except: pass
|
||||
|
@ -210,7 +210,7 @@ def enable(agi=None, display=1, logdir=None, context=5):
|
|||
except_hook = Hook(display=display, logdir=logdir,
|
||||
context=context, agi=agi)
|
||||
sys.excepthook = except_hook
|
||||
|
||||
|
||||
global handler
|
||||
handler = except_hook.handle
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ This module provides parsing functionality for asterisk config files.
|
|||
|
||||
import asterisk.config
|
||||
import sys
|
||||
|
||||
|
||||
# load and parse the config file
|
||||
try:
|
||||
config = asterisk.config.Config('/etc/asterisk/extensions.conf')
|
||||
|
@ -68,7 +68,7 @@ class Category(Line):
|
|||
|
||||
self.items = []
|
||||
self.comments = []
|
||||
|
||||
|
||||
def get_line(self):
|
||||
if self.comment:
|
||||
return '[%s]\t;%s' % (self.name, self.comment)
|
||||
|
@ -86,7 +86,7 @@ class Category(Line):
|
|||
def remove(self, item):
|
||||
self.items.remove(item)
|
||||
|
||||
|
||||
|
||||
class Item(Line):
|
||||
def __init__(self, line='', num=-1, name=None, value=None):
|
||||
Line.__init__(self, line, num)
|
||||
|
@ -98,7 +98,7 @@ class Item(Line):
|
|||
self.value = value
|
||||
else:
|
||||
raise Exception("Must provide name or value representing an item")
|
||||
|
||||
|
||||
def parse(self):
|
||||
try:
|
||||
name, value = self.line.split('=', 1)
|
||||
|
|
|
@ -13,21 +13,21 @@ This module provides a Python API for interfacing with the asterisk manager.
|
|||
print "Recieved shutdown event"
|
||||
manager.close()
|
||||
# we could analize the event and reconnect here
|
||||
|
||||
|
||||
def handle_event(event, manager):
|
||||
print "Recieved event: %s" % event.name
|
||||
|
||||
|
||||
manager = asterisk.manager.Manager()
|
||||
try:
|
||||
# connect to the manager
|
||||
try:
|
||||
manager.connect('host')
|
||||
manager.connect('host')
|
||||
manager.login('user', 'secret')
|
||||
|
||||
# register some callbacks
|
||||
manager.register_event('Shutdown', handle_shutdown) # shutdown
|
||||
manager.register_event('*', handle_event) # catch all
|
||||
|
||||
|
||||
# get a status report
|
||||
response = manager.status()
|
||||
|
||||
|
@ -41,7 +41,7 @@ This module provides a Python API for interfacing with the asterisk manager.
|
|||
except asterisk.manager.ManagerException, reason:
|
||||
print "Error: %s" % reason
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
finally:
|
||||
# remember to clean up
|
||||
manager.close()
|
||||
|
@ -63,14 +63,14 @@ from time import sleep
|
|||
|
||||
EOL = '\r\n'
|
||||
|
||||
class ManagerMsg(object):
|
||||
class ManagerMsg(object):
|
||||
"""A manager interface message"""
|
||||
def __init__(self, response):
|
||||
# the raw response, straight from the horse's mouth:
|
||||
self.response = response
|
||||
self.data = ''
|
||||
self.headers = {}
|
||||
|
||||
|
||||
# parse the response
|
||||
self.parse(response)
|
||||
|
||||
|
@ -94,7 +94,7 @@ class ManagerMsg(object):
|
|||
self.headers['Event'] = 'NoClue'
|
||||
else:
|
||||
self.headers['Response'] = 'Generated Header'
|
||||
|
||||
|
||||
def parse(self, response):
|
||||
"""Parse a manager message"""
|
||||
|
||||
|
@ -143,7 +143,7 @@ class Event(object):
|
|||
|
||||
# get the event name
|
||||
self.name = message.get_header('Event')
|
||||
|
||||
|
||||
def has_header(self, hname):
|
||||
"""Check for a header"""
|
||||
return self.headers.has_key(hname)
|
||||
|
@ -151,11 +151,11 @@ class Event(object):
|
|||
def get_header(self, hname, defval = None):
|
||||
"""Return the specfied header"""
|
||||
return self.headers.get(hname, defval)
|
||||
|
||||
|
||||
def __getitem__(self, hname):
|
||||
"""Return the specfied header"""
|
||||
return self.headers[hname]
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.headers['Event']
|
||||
|
||||
|
@ -168,7 +168,7 @@ class Manager(object):
|
|||
self.title = None # set by received greeting
|
||||
self._connected = threading.Event()
|
||||
self._running = threading.Event()
|
||||
|
||||
|
||||
# our hostname
|
||||
self.hostname = socket.gethostname()
|
||||
|
||||
|
@ -185,11 +185,11 @@ class Manager(object):
|
|||
# sequence stuff
|
||||
self._seqlock = threading.Lock()
|
||||
self._seq = 0
|
||||
|
||||
|
||||
# some threads
|
||||
self.message_thread = threading.Thread(target=self.message_loop)
|
||||
self.event_dispatch_thread = threading.Thread(target=self.event_dispatch)
|
||||
|
||||
|
||||
self.message_thread.setDaemon(True)
|
||||
self.event_dispatch_thread.setDaemon(True)
|
||||
|
||||
|
@ -211,11 +211,11 @@ class Manager(object):
|
|||
finally:
|
||||
self._seq += 1
|
||||
self._seqlock.release()
|
||||
|
||||
|
||||
def send_action(self, cdict={}, **kwargs):
|
||||
"""
|
||||
Send a command to the manager
|
||||
|
||||
|
||||
If a list is passed to the cdict argument, each item in the list will
|
||||
be sent to asterisk under the same header in the following manner:
|
||||
|
||||
|
@ -232,7 +232,7 @@ class Manager(object):
|
|||
|
||||
if not self._connected.isSet():
|
||||
raise ManagerException("Not connected")
|
||||
|
||||
|
||||
# fill in our args
|
||||
cdict.update(kwargs)
|
||||
|
||||
|
@ -258,7 +258,7 @@ class Manager(object):
|
|||
self._sock.flush()
|
||||
except socket.error, (errno, reason):
|
||||
raise ManagerSocketException(errno, reason)
|
||||
|
||||
|
||||
self._reswaiting.insert(0,1)
|
||||
response = self._response_queue.get()
|
||||
self._reswaiting.pop(0)
|
||||
|
@ -281,7 +281,7 @@ class Manager(object):
|
|||
try:
|
||||
lines = []
|
||||
for line in self._sock :
|
||||
# check to see if this is the greeting line
|
||||
# check to see if this is the greeting line
|
||||
if not self.title and '/' in line and not ':' in line:
|
||||
# store the title of the manager we are connecting to:
|
||||
self.title = line.split('/')[0].strip()
|
||||
|
@ -333,7 +333,7 @@ class Manager(object):
|
|||
self._connected.clear()
|
||||
self._message_queue.put(None)
|
||||
|
||||
|
||||
|
||||
def register_event(self, event, function):
|
||||
"""
|
||||
Register a callback for the specfied event.
|
||||
|
@ -395,7 +395,7 @@ class Manager(object):
|
|||
finally:
|
||||
# wait for our data receiving thread to exit
|
||||
t.join()
|
||||
|
||||
|
||||
|
||||
def event_dispatch(self):
|
||||
"""This thread is responsible for dispatching events"""
|
||||
|
@ -408,14 +408,14 @@ class Manager(object):
|
|||
# if we got None as an event, we are finished
|
||||
if not ev:
|
||||
break
|
||||
|
||||
|
||||
# dispatch our events
|
||||
|
||||
# first build a list of the functions to execute
|
||||
callbacks = (self._event_callbacks.get(ev.name, [])
|
||||
+ self._event_callbacks.get('*', []))
|
||||
|
||||
# now execute the functions
|
||||
# now execute the functions
|
||||
for callback in callbacks:
|
||||
if callback(ev, self):
|
||||
break
|
||||
|
@ -455,11 +455,11 @@ class Manager(object):
|
|||
|
||||
def close(self):
|
||||
"""Shutdown the connection to the manager"""
|
||||
|
||||
|
||||
# if we are still running, logout
|
||||
if self._running.isSet() and self._connected.isSet():
|
||||
self.logoff()
|
||||
|
||||
|
||||
if self._running.isSet():
|
||||
# put None in the message_queue to kill our threads
|
||||
self._message_queue.put(None)
|
||||
|
@ -471,22 +471,22 @@ class Manager(object):
|
|||
if threading.currentThread() != self.event_dispatch_thread:
|
||||
# wait for the dispatch thread to exit
|
||||
self.event_dispatch_thread.join()
|
||||
|
||||
|
||||
self._running.clear()
|
||||
|
||||
# Manager actions
|
||||
|
||||
def login(self, username, secret):
|
||||
"""Login to the manager, throws ManagerAuthException when login falis"""
|
||||
|
||||
|
||||
cdict = {'Action':'Login'}
|
||||
cdict['Username'] = username
|
||||
cdict['Secret'] = secret
|
||||
response = self.send_action(cdict)
|
||||
|
||||
|
||||
if response.get_header('Response') == 'Error':
|
||||
raise ManagerAuthException(response.get_header('Message'))
|
||||
|
||||
|
||||
return response
|
||||
|
||||
def ping(self):
|
||||
|
@ -500,16 +500,16 @@ class Manager(object):
|
|||
|
||||
cdict = {'Action':'Logoff'}
|
||||
response = self.send_action(cdict)
|
||||
|
||||
|
||||
return response
|
||||
|
||||
def hangup(self, channel):
|
||||
"""Hangup the specified channel"""
|
||||
|
||||
|
||||
cdict = {'Action':'Hangup'}
|
||||
cdict['Channel'] = channel
|
||||
response = self.send_action(cdict)
|
||||
|
||||
|
||||
return response
|
||||
|
||||
def status(self, channel = ''):
|
||||
|
@ -518,12 +518,12 @@ class Manager(object):
|
|||
cdict = {'Action':'Status'}
|
||||
cdict['Channel'] = channel
|
||||
response = self.send_action(cdict)
|
||||
|
||||
|
||||
return response
|
||||
|
||||
def redirect(self, channel, exten, priority='1', extra_channel='', context=''):
|
||||
"""Redirect a channel"""
|
||||
|
||||
|
||||
cdict = {'Action':'Redirect'}
|
||||
cdict['Channel'] = channel
|
||||
cdict['Exten'] = exten
|
||||
|
@ -531,7 +531,7 @@ class Manager(object):
|
|||
if context: cdict['Context'] = context
|
||||
if extra_channel: cdict['ExtraChannel'] = extra_channel
|
||||
response = self.send_action(cdict)
|
||||
|
||||
|
||||
return response
|
||||
|
||||
def originate(self, channel, exten, context='', priority='', timeout='', caller_id='', async=False, account='', variables={}):
|
||||
|
@ -550,18 +550,18 @@ class Manager(object):
|
|||
# with the latest CVS HEAD this is no longer necessary
|
||||
# if variables: cdict['Variable'] = '|'.join(['='.join((str(key), str(value))) for key, value in variables.items()])
|
||||
if variables: cdict['Variable'] = ['='.join((str(key), str(value))) for key, value in variables.items()]
|
||||
|
||||
|
||||
response = self.send_action(cdict)
|
||||
|
||||
|
||||
return response
|
||||
|
||||
def mailbox_status(self, mailbox):
|
||||
"""Get the status of the specfied mailbox"""
|
||||
|
||||
|
||||
cdict = {'Action':'MailboxStatus'}
|
||||
cdict['Mailbox'] = mailbox
|
||||
response = self.send_action(cdict)
|
||||
|
||||
|
||||
return response
|
||||
|
||||
def command(self, command):
|
||||
|
@ -570,7 +570,7 @@ class Manager(object):
|
|||
cdict = {'Action':'Command'}
|
||||
cdict['Command'] = command
|
||||
response = self.send_action(cdict)
|
||||
|
||||
|
||||
return response
|
||||
|
||||
def extension_state(self, exten, context):
|
||||
|
@ -580,7 +580,7 @@ class Manager(object):
|
|||
cdict['Exten'] = exten
|
||||
cdict['Context'] = context
|
||||
response = self.send_action(cdict)
|
||||
|
||||
|
||||
return response
|
||||
|
||||
def playdtmf (self, channel, digit) :
|
||||
|
@ -594,7 +594,7 @@ class Manager(object):
|
|||
|
||||
def absolute_timeout(self, channel, timeout):
|
||||
"""Set an absolute timeout on a channel"""
|
||||
|
||||
|
||||
cdict = {'Action':'AbsoluteTimeout'}
|
||||
cdict['Channel'] = channel
|
||||
cdict['Timeout'] = timeout
|
||||
|
|
Loading…
Reference in New Issue