Merge branch 'release/0.4'
commit
7493c64c9b
|
@ -1,3 +1,7 @@
|
|||
2011-05-31 Randall Degges <rdegges@gmail.com
|
||||
* BUGFIX: Fixing issue that prevented manager.status command from returning
|
||||
proper output.
|
||||
|
||||
2007-01-26 Matthew Nicholson <mnicholson@digium.com>
|
||||
|
||||
* asterisk/manager.py: Make get_header() functions work like
|
||||
|
@ -28,14 +32,14 @@
|
|||
and quoted arguments.
|
||||
|
||||
2006-10-24 Matthew Nicholson <mnicholson@digium.com>
|
||||
|
||||
|
||||
* asterisk/agi.py: Added get_variable_full command.
|
||||
|
||||
2006-10-18 Matthew Nicholson <mnicholson@digium.com>
|
||||
|
||||
* asterisk/agitb.py: Make error output default to sys.stderr instead
|
||||
of sys.stdout.
|
||||
|
||||
|
||||
2006-09-19 Matthew Nicholson <mnicholson@digium.com>
|
||||
|
||||
* debian/control: Removed XS-Python-Versions header to make it default
|
10
MANIFEST.in
10
MANIFEST.in
|
@ -1,11 +1,3 @@
|
|||
include debian/watch
|
||||
include debian/rules
|
||||
include debian/changelog
|
||||
include debian/control
|
||||
include debian/compat
|
||||
include debian/copyright
|
||||
include rpm/python-pyst.spec
|
||||
include ChangeLog
|
||||
include CHANGELOG
|
||||
include README
|
||||
include README.html
|
||||
include MANIFEST.in
|
||||
|
|
21
README
21
README
|
@ -1,9 +1,3 @@
|
|||
.. image:: http://sflogo.sourceforge.net/sflogo.php?group_id=134329&type=7
|
||||
:height: 62
|
||||
:width: 210
|
||||
:alt: SourceForge.net Logo
|
||||
:target: http://sourceforge.net/projects/pyst/
|
||||
|
||||
pyst: A Python Interface to Asterisk
|
||||
====================================
|
||||
|
||||
|
@ -41,10 +35,21 @@ directly on the host where Asterisk is running. Since Asterisk doesn't
|
|||
run on windows platforms (and probably never will) the agi part of the
|
||||
package can only be run on Asterisk platforms.
|
||||
|
||||
.. note::
|
||||
This project has been forked because it was impossible for me to contact
|
||||
the project maintainer (after several attempts), and I'd like to bring the
|
||||
project up-to-date, fix bugs, and make it more usable overall.
|
||||
|
||||
My plans immediate plans include adding full documentation, re-writing some
|
||||
of the core routines, adding a test suite, and accepting pull requests.
|
||||
|
||||
If you are one of the current maintainers, and would like to take over the
|
||||
fork, please contact me: rdegges@gmail.com, so we can get that setup!
|
||||
|
||||
Credits
|
||||
-------
|
||||
|
||||
Thanks to Karl Putland for writing the original package.
|
||||
Thanks to Karl Putland for writing the original package.
|
||||
Thanks to Matthew Nicholson for maintaining the package for some years
|
||||
and for handing over maintenance when he was no longer interested.
|
||||
|
||||
|
@ -154,7 +159,7 @@ Version 0.3: Minor feature enhancements
|
|||
|
||||
New maintainer Ralf Schlatterbeck, this is my first release, please
|
||||
report any problems via the Sourceforge Bug-Tracker or email me
|
||||
directly. Thanks to Karl Putland for writing the original package.
|
||||
directly. Thanks to Karl Putland for writing the original package.
|
||||
Thanks to Matthew Nicholson for maintaining the package for some years
|
||||
and for handing over maintenance when he was no longer interested.
|
||||
The parsing of answers from asterisk was completely rewritten. This
|
||||
|
|
|
@ -11,4 +11,4 @@ manager - a module for interacting with the asterisk manager interface
|
|||
"""
|
||||
|
||||
__all__ = ['agi', 'agitb', 'config', 'manager']
|
||||
|
||||
__version__ = '0.4'
|
||||
|
|
|
@ -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)
|
||||
|
@ -274,6 +274,7 @@ class Manager(object):
|
|||
"""
|
||||
|
||||
multiline = False
|
||||
status = False
|
||||
wait_for_marker = False
|
||||
eolcount = 0
|
||||
# loop while we are sill running and connected
|
||||
|
@ -281,7 +282,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()
|
||||
|
@ -303,6 +304,11 @@ class Manager(object):
|
|||
break
|
||||
# ignore empty lines at start
|
||||
continue
|
||||
# If the user executed the status command, it's a special
|
||||
# case, so we need to look for a marker.
|
||||
if 'status will follow' in line:
|
||||
status = True
|
||||
wait_for_marker = True
|
||||
lines.append(line)
|
||||
# line not ending in \r\n or without ':' isn't a
|
||||
# valid header and starts multiline response
|
||||
|
@ -310,13 +316,17 @@ class Manager(object):
|
|||
multiline = True
|
||||
# Response: Follows indicates we should wait for end
|
||||
# marker --END COMMAND--
|
||||
if not multiline and line.startswith('Response') and \
|
||||
if not (multiline or status) and line.startswith('Response') and \
|
||||
line.split(':', 1)[1].strip() == 'Follows':
|
||||
wait_for_marker = True
|
||||
# same when seeing end of multiline response
|
||||
if multiline and line.startswith('--END COMMAND--'):
|
||||
wait_for_marker = False
|
||||
multiline = False
|
||||
# same when seeing end of status response
|
||||
if status and 'StatusComplete' in line:
|
||||
wait_for_marker = False
|
||||
status = False
|
||||
if not self._connected.isSet():
|
||||
break
|
||||
else:
|
||||
|
@ -333,7 +343,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 +405,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 +418,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 +465,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 +481,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 +510,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 +528,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 +541,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 +560,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 +580,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 +590,7 @@ class Manager(object):
|
|||
cdict['Exten'] = exten
|
||||
cdict['Context'] = context
|
||||
response = self.send_action(cdict)
|
||||
|
||||
|
||||
return response
|
||||
|
||||
def playdtmf (self, channel, digit) :
|
||||
|
@ -594,7 +604,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
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
pyst (0.2-1) unstable; urgency=low
|
||||
|
||||
* New release.
|
||||
* Package updated to reflect new python policy.
|
||||
|
||||
-- Matthew Nicholson <mnicholson@digium.com> Tue, 19 Sep 2006 19:22:51 -0500
|
||||
|
||||
pyst (0.1.0-1) unstable; urgency=low
|
||||
|
||||
* New release.
|
||||
|
||||
-- Matthew Nicholson <mnicholson@digium.com> Mon, 5 Jun 2006 15:11:24 -0500
|
||||
|
||||
pyst (0.0.4rc13-1) unstable; urgency=low
|
||||
|
||||
* New release.
|
||||
|
||||
-- Matthew Nicholson <mnicholson@digium.com> Tue, 21 Mar 2006 12:25:03 -0600
|
||||
|
||||
pyst (0.0.4rc12-1) unstable; urgency=low
|
||||
|
||||
* New release.
|
||||
|
||||
-- Matthew Nicholson <mnicholson@digium.com> Thu, 14 Apr 2005 17:15:46 -0500
|
||||
|
||||
pyst (0.0.4rc11-1) unstable; urgency=low
|
||||
|
||||
* New release.
|
||||
|
||||
-- Matthew Nicholson <mnicholson@digium.com> Thu, 3 Feb 2005 18:46:32 -0600
|
||||
|
||||
pyst (0.0.4rc10-1) unstable; urgency=low
|
||||
|
||||
* Bug fixes in config.py and more docs.
|
||||
* Version number correction.
|
||||
* Added line number tracking to config.py
|
||||
|
||||
-- Matthew Nicholson <mnicholson@digium.com> Tue, 11 Jan 2005 11:30:59 -0600
|
||||
|
||||
pyst (0.0.4rc9-1) unstable; urgency=low
|
||||
|
||||
* Removed DEBUG flag
|
||||
|
||||
-- Matthew Nicholson <mnicholson@digium.com> Mon, 10 Jan 2005 18:40:04 -0600
|
||||
|
||||
pyst (0.0.4rc8-1) unstable; urgency=low
|
||||
|
||||
* More manager.py updates
|
||||
|
||||
-- Matthew Nicholson <mnicholson@digium.com> Thu, 6 Jan 2005 12:19:42 -0600
|
||||
|
||||
pyst (0.0.4rc7-1) unstable; urgency=low
|
||||
|
||||
* A bunch of fixes to make the manager interface useable
|
||||
|
||||
-- Matthew Nicholson <mnicholson@digium.com> Wed, 5 Jan 2005 19:02:38 -0600
|
||||
|
||||
pyst (0.0.4rc6-1) unstable; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
-- Matthew Nicholson <mnicholson@digium.com> Mon, 29 Nov 2004 14:06:42 -0600
|
||||
|
|
@ -1 +0,0 @@
|
|||
4
|
|
@ -1,21 +0,0 @@
|
|||
Source: pyst
|
||||
Section: python
|
||||
Priority: optional
|
||||
Maintainer: Matthew Nicholson <mnicholson@digium.com>
|
||||
Build-Depends-Indep: debhelper (>= 5.0.37.2), cdbs (>= 0.4.43), python-all-dev (>= 2.3.5-11), python-support (>= 0.3)
|
||||
Standards-Version: 3.6.1
|
||||
|
||||
Package: python-pyst
|
||||
Architecture: all
|
||||
Depends: ${python:Depends}
|
||||
Provides: ${python:Provides}
|
||||
Replaces: python2.3-pyst (<< 0.2)
|
||||
Conflicts: python2.3-pyst (<< 0.2)
|
||||
XB-Python-Version: ${python:Versions}
|
||||
Suggests: asterisk
|
||||
Description: Python module for interacting with the Asterisk PBX (dummy)
|
||||
Pyst is a python module for interacting with the asterisk pbx through
|
||||
the manager interface and agi interface. This package also includes
|
||||
debugging tools such as the agitb module, and tools to parse asterisk
|
||||
config files.
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
This package was debianized by Matthew Nicholson <mnicholson@digium.com> on
|
||||
Mon, 29 Nov 2004 14:06:42 -0600.
|
||||
|
||||
It was downloaded from http://ftp1.sourceforge.net/pyst/pyst-0.0.4.tar.gz
|
||||
|
||||
Copyright (C) 2004 Karl Putland
|
||||
|
||||
Upstream Author: Karl Putland <kputland@users.sourceforge.net>
|
||||
|
||||
License:
|
||||
|
||||
Most of pyst is licensed under the terms of the GNU LGPL.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
The agitb.py modules is licensed under the terms of the Python Software
|
||||
Foundation License:
|
||||
|
||||
PSF LICENSE AGREEMENT FOR PYTHON 2.3
|
||||
------------------------------------
|
||||
|
||||
1. This LICENSE AGREEMENT is between the Python Software Foundation
|
||||
("PSF"), and the Individual or Organization ("Licensee") accessing and
|
||||
otherwise using Python 2.3 software in source or binary form and its
|
||||
associated documentation.
|
||||
|
||||
2. Subject to the terms and conditions of this License Agreement, PSF
|
||||
hereby grants Licensee a nonexclusive, royalty-free, world-wide
|
||||
license to reproduce, analyze, test, perform and/or display publicly,
|
||||
prepare derivative works, distribute, and otherwise use Python 2.3
|
||||
alone or in any derivative version, provided, however, that PSF's
|
||||
License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
|
||||
2001, 2002 Python Software Foundation; All Rights Reserved" are
|
||||
retained in Python 2.3 alone or in any derivative version prepared by
|
||||
Licensee.
|
||||
|
||||
3. In the event Licensee prepares a derivative work that is based on
|
||||
or incorporates Python 2.3 or any part thereof, and wants to make
|
||||
the derivative work available to others as provided herein, then
|
||||
Licensee hereby agrees to include in any such work a brief summary of
|
||||
the changes made to Python 2.3.
|
||||
|
||||
4. PSF is making Python 2.3 available to Licensee on an "AS IS"
|
||||
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
|
||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT
|
||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
|
||||
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||
2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3,
|
||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
6. This License Agreement will automatically terminate upon a material
|
||||
breach of its terms and conditions.
|
||||
|
||||
7. Nothing in this License Agreement shall be deemed to create any
|
||||
relationship of agency, partnership, or joint venture between PSF and
|
||||
Licensee. This License Agreement does not grant permission to use PSF
|
||||
trademarks or trade name in a trademark sense to endorse or promote
|
||||
products or services of Licensee, or any third party.
|
||||
|
||||
8. By copying, installing or otherwise using Python 2.3, Licensee
|
||||
agrees to be bound by the terms and conditions of this License
|
||||
Agreement.
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
DEB_PYTHON_SYSTEM=pysupport
|
||||
|
||||
include /usr/share/cdbs/1/rules/debhelper.mk
|
||||
include /usr/share/cdbs/1/class/python-distutils.mk
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# Site Directory Pattern Version Script
|
||||
version=2
|
||||
http://ftp1.sourceforge.net/pyst/pyst-(.*)\.tar\.gz debian uupdate
|
|
@ -1,48 +0,0 @@
|
|||
Summary: An interface to AGI
|
||||
Name: python-pyst
|
||||
Version: 0.0.5
|
||||
Release: 2.centos4.0
|
||||
Source0: http://prdownloads.sourceforge.net/pyst/pyst-%{version}.tar.gz
|
||||
License: LGPL
|
||||
Group: Development/Libraries
|
||||
BuildRoot: %{_tmppath}/%{name}-buildroot
|
||||
URL: http://sourceforge.net/projects/pyst
|
||||
Requires: python
|
||||
BuildRequires: python-devel
|
||||
BuildRequires: python Distutils
|
||||
|
||||
%description
|
||||
Pyst consists of a set of interfaces and libraries to allow
|
||||
programming of Asterisk from python. The library currently
|
||||
supports AGI, AMI, and the parsing of Asterisk configuration
|
||||
files. The library also includes debugging facilities for AGI.
|
||||
|
||||
%prep
|
||||
%setup -q -n pyst-%{version}
|
||||
|
||||
%build
|
||||
CFLAGS="$RPM_OPT_FLAGS" python setup.py build
|
||||
|
||||
%install
|
||||
python setup.py install --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/share/doc/python-pyst
|
||||
cp debian/copyright $RPM_BUILD_ROOT/usr/share/doc/python-pyst
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files -f INSTALLED_FILES
|
||||
%defattr(-,root,root)
|
||||
%doc /usr/share/doc/python-pyst/*
|
||||
%{_libdir}/python*/site-packages/asterisk/
|
||||
|
||||
%changelog
|
||||
* Tue Mar 21 2006 Matthew Nicholson <mnicholson@digium.com> el4.3
|
||||
- Bumped version number.
|
||||
|
||||
* Thu Feb 23 2006 Antoine Brenner <http://www.gymglish.com> el4.2
|
||||
- Fixed source0 line
|
||||
|
||||
* Tue Feb 9 2006 Antoine Brenner <http://www.gymglish.com> el4.1
|
||||
- Initial Package
|
||||
|
14
setup.py
14
setup.py
|
@ -2,10 +2,8 @@
|
|||
|
||||
from distutils.core import setup
|
||||
|
||||
try :
|
||||
from asterisk.Version import VERSION
|
||||
except :
|
||||
VERSION = None
|
||||
from asterisk import __version__ as version
|
||||
|
||||
|
||||
description = []
|
||||
f = open ('README')
|
||||
|
@ -22,14 +20,14 @@ licenses = ( 'Python Software Foundation License'
|
|||
|
||||
|
||||
setup \
|
||||
( name = 'pyst'
|
||||
, version = VERSION
|
||||
( name = 'pyst2'
|
||||
, version = version
|
||||
, description = 'A Python Interface to Asterisk'
|
||||
, long_description = ''.join (description)
|
||||
, author = 'Karl Putland'
|
||||
, author_email = 'kputland@users.sourceforge.net'
|
||||
, maintainer = 'Ralf Schlatterbeck'
|
||||
, maintainer_email = 'rsc@runtux.com'
|
||||
, maintainer = 'Randall Degges'
|
||||
, maintainer_email = 'rdegges@gmail.com'
|
||||
, url = 'http://www.sourceforge.net/projects/pyst/'
|
||||
, packages = ['asterisk']
|
||||
, license = ', '.join (licenses)
|
||||
|
|
Loading…
Reference in New Issue