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>
|
2007-01-26 Matthew Nicholson <mnicholson@digium.com>
|
||||||
|
|
||||||
* asterisk/manager.py: Make get_header() functions work like
|
* asterisk/manager.py: Make get_header() functions work like
|
||||||
|
@ -28,14 +32,14 @@
|
||||||
and quoted arguments.
|
and quoted arguments.
|
||||||
|
|
||||||
2006-10-24 Matthew Nicholson <mnicholson@digium.com>
|
2006-10-24 Matthew Nicholson <mnicholson@digium.com>
|
||||||
|
|
||||||
* asterisk/agi.py: Added get_variable_full command.
|
* asterisk/agi.py: Added get_variable_full command.
|
||||||
|
|
||||||
2006-10-18 Matthew Nicholson <mnicholson@digium.com>
|
2006-10-18 Matthew Nicholson <mnicholson@digium.com>
|
||||||
|
|
||||||
* asterisk/agitb.py: Make error output default to sys.stderr instead
|
* asterisk/agitb.py: Make error output default to sys.stderr instead
|
||||||
of sys.stdout.
|
of sys.stdout.
|
||||||
|
|
||||||
2006-09-19 Matthew Nicholson <mnicholson@digium.com>
|
2006-09-19 Matthew Nicholson <mnicholson@digium.com>
|
||||||
|
|
||||||
* debian/control: Removed XS-Python-Versions header to make it default
|
* 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 CHANGELOG
|
||||||
include debian/rules
|
|
||||||
include debian/changelog
|
|
||||||
include debian/control
|
|
||||||
include debian/compat
|
|
||||||
include debian/copyright
|
|
||||||
include rpm/python-pyst.spec
|
|
||||||
include ChangeLog
|
|
||||||
include README
|
include README
|
||||||
include README.html
|
|
||||||
include MANIFEST.in
|
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
|
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
|
run on windows platforms (and probably never will) the agi part of the
|
||||||
package can only be run on Asterisk platforms.
|
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
|
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
|
Thanks to Matthew Nicholson for maintaining the package for some years
|
||||||
and for handing over maintenance when he was no longer interested.
|
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
|
New maintainer Ralf Schlatterbeck, this is my first release, please
|
||||||
report any problems via the Sourceforge Bug-Tracker or email me
|
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
|
Thanks to Matthew Nicholson for maintaining the package for some years
|
||||||
and for handing over maintenance when he was no longer interested.
|
and for handing over maintenance when he was no longer interested.
|
||||||
The parsing of answers from asterisk was completely rewritten. This
|
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']
|
__all__ = ['agi', 'agitb', 'config', 'manager']
|
||||||
|
__version__ = '0.4'
|
||||||
|
|
|
@ -52,9 +52,9 @@ class AGI:
|
||||||
"""
|
"""
|
||||||
This class encapsulates communication between Asterisk an a python script.
|
This class encapsulates communication between Asterisk an a python script.
|
||||||
It handles encoding commands to Asterisk and parsing responses from
|
It handles encoding commands to Asterisk and parsing responses from
|
||||||
Asterisk.
|
Asterisk.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._got_sighup = False
|
self._got_sighup = False
|
||||||
signal.signal(signal.SIGHUP, self._handle_sighup) # handle SIGHUP
|
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"""
|
"""This function throws AGIHangup if we have recieved a SIGHUP"""
|
||||||
if self._got_sighup:
|
if self._got_sighup:
|
||||||
raise AGISIGHUPHangup("Received SIGHUP from Asterisk")
|
raise AGISIGHUPHangup("Received SIGHUP from Asterisk")
|
||||||
|
|
||||||
def execute(self, command, *args):
|
def execute(self, command, *args):
|
||||||
self.test_hangup()
|
self.test_hangup()
|
||||||
|
|
||||||
|
@ -208,17 +208,17 @@ class AGI:
|
||||||
|
|
||||||
def tdd_mode(self, mode='off'):
|
def tdd_mode(self, mode='off'):
|
||||||
"""agi.tdd_mode(mode='on'|'off') --> None
|
"""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.
|
Throws AGIAppError if channel is not TDD-capable.
|
||||||
"""
|
"""
|
||||||
res = self.execute('TDD MODE', mode)['result'][0]
|
res = self.execute('TDD MODE', mode)['result'][0]
|
||||||
if res == '0':
|
if res == '0':
|
||||||
raise AGIAppError('Channel %s is not TDD-capable')
|
raise AGIAppError('Channel %s is not TDD-capable')
|
||||||
|
|
||||||
def stream_file(self, filename, escape_digits='', sample_offset=0):
|
def stream_file(self, filename, escape_digits='', sample_offset=0):
|
||||||
"""agi.stream_file(filename, escape_digits='', sample_offset=0) --> digit
|
"""agi.stream_file(filename, escape_digits='', sample_offset=0) --> digit
|
||||||
Send the given file, allowing playback to be interrupted by the given
|
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']
|
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
|
If sample offset is provided then the audio will seek to sample
|
||||||
offset before play starts. Returns digit if one was pressed.
|
offset before play starts. Returns digit if one was pressed.
|
||||||
|
@ -235,11 +235,11 @@ class AGI:
|
||||||
return chr(int(res))
|
return chr(int(res))
|
||||||
except:
|
except:
|
||||||
raise AGIError('Unable to convert result to char: %s' % res)
|
raise AGIError('Unable to convert result to char: %s' % res)
|
||||||
|
|
||||||
def control_stream_file(self, filename, escape_digits='', skipms=3000, fwd='', rew='', pause=''):
|
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
|
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']
|
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
|
If sample offset is provided then the audio will seek to sample
|
||||||
offset before play starts. Returns digit if one was pressed.
|
offset before play starts. Returns digit if one was pressed.
|
||||||
|
@ -270,7 +270,7 @@ class AGI:
|
||||||
def say_digits(self, digits, escape_digits=''):
|
def say_digits(self, digits, escape_digits=''):
|
||||||
"""agi.say_digits(digits, escape_digits='') --> digit
|
"""agi.say_digits(digits, escape_digits='') --> digit
|
||||||
Say a given digit string, returning early if any of the given DTMF digits
|
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
|
Throws AGIError on channel failure
|
||||||
"""
|
"""
|
||||||
digits = self._process_digit_list(digits)
|
digits = self._process_digit_list(digits)
|
||||||
|
@ -287,7 +287,7 @@ class AGI:
|
||||||
def say_number(self, number, escape_digits=''):
|
def say_number(self, number, escape_digits=''):
|
||||||
"""agi.say_number(number, escape_digits='') --> digit
|
"""agi.say_number(number, escape_digits='') --> digit
|
||||||
Say a given digit string, returning early if any of the given DTMF digits
|
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
|
Throws AGIError on channel failure
|
||||||
"""
|
"""
|
||||||
number = self._process_digit_list(number)
|
number = self._process_digit_list(number)
|
||||||
|
@ -304,7 +304,7 @@ class AGI:
|
||||||
def say_alpha(self, characters, escape_digits=''):
|
def say_alpha(self, characters, escape_digits=''):
|
||||||
"""agi.say_alpha(string, escape_digits='') --> digit
|
"""agi.say_alpha(string, escape_digits='') --> digit
|
||||||
Say a given character string, returning early if any of the given DTMF
|
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
|
Throws AGIError on channel failure
|
||||||
"""
|
"""
|
||||||
characters = self._process_digit_list(characters)
|
characters = self._process_digit_list(characters)
|
||||||
|
@ -321,7 +321,7 @@ class AGI:
|
||||||
def say_phonetic(self, characters, escape_digits=''):
|
def say_phonetic(self, characters, escape_digits=''):
|
||||||
"""agi.say_phonetic(string, escape_digits='') --> digit
|
"""agi.say_phonetic(string, escape_digits='') --> digit
|
||||||
Phonetically say a given character string, returning early if any of
|
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
|
Throws AGIError on channel failure
|
||||||
"""
|
"""
|
||||||
characters = self._process_digit_list(characters)
|
characters = self._process_digit_list(characters)
|
||||||
|
@ -364,7 +364,7 @@ class AGI:
|
||||||
return chr(int(res))
|
return chr(int(res))
|
||||||
except:
|
except:
|
||||||
raise AGIError('Unable to convert result to char: %s' % res)
|
raise AGIError('Unable to convert result to char: %s' % res)
|
||||||
|
|
||||||
def say_datetime(self, seconds, escape_digits='', format='', zone=''):
|
def say_datetime(self, seconds, escape_digits='', format='', zone=''):
|
||||||
"""agi.say_datetime(seconds, escape_digits='', format='', zone='') --> digit
|
"""agi.say_datetime(seconds, escape_digits='', format='', zone='') --> digit
|
||||||
Say a given date in the format specfied (see voicemail.conf), returning
|
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)
|
result = self.execute('GET DATA', filename, timeout, max_digits)
|
||||||
res, value = result['result']
|
res, value = result['result']
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def get_option(self, filename, escape_digits='', timeout=0):
|
def get_option(self, filename, escape_digits='', timeout=0):
|
||||||
"""agi.get_option(filename, escape_digits='', timeout=0) --> digit
|
"""agi.get_option(filename, escape_digits='', timeout=0) --> digit
|
||||||
Send the given file, allowing playback to be interrupted by the given
|
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']
|
ints [1,2,3,4,5] or strings ['1','2','3'] or mixed [1,'2',3,'4']
|
||||||
Returns digit if one was pressed.
|
Returns digit if one was pressed.
|
||||||
Throws AGIError if the channel was disconnected. Remember, the file
|
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'):
|
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
|
"""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
|
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
|
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
|
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
|
samples is optional, and if provided will seek to the offset without
|
||||||
exceeding the end of the file
|
exceeding the end of the file
|
||||||
"""
|
"""
|
||||||
escape_digits = self._process_digit_list(escape_digits)
|
escape_digits = self._process_digit_list(escape_digits)
|
||||||
|
@ -589,7 +589,7 @@ class AGI:
|
||||||
res, value = result['result']
|
res, value = result['result']
|
||||||
if res == '0':
|
if res == '0':
|
||||||
raise AGIDBError('Unable to put vaule in databale: family=%s, key=%s, value=%s' % (family, key, value))
|
raise AGIDBError('Unable to put vaule in databale: family=%s, key=%s, value=%s' % (family, key, value))
|
||||||
|
|
||||||
def database_del(self, family, key):
|
def database_del(self, family, key):
|
||||||
"""agi.database_del(family, key) --> None
|
"""agi.database_del(family, key) --> None
|
||||||
Deletes an entry in the Asterisk database for a
|
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
|
agi - the agi handle to write verbose messages to
|
||||||
display - if true, tracebacks are displayed on the asterisk console
|
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
|
logdir - if set, tracebacks are written to files in this directory
|
||||||
context - number of lines of source code to show for each stack frame
|
context - number of lines of source code to show for each stack frame
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ class Hook:
|
||||||
self.agi.verbose(msg, 4)
|
self.agi.verbose(msg, 4)
|
||||||
else:
|
else:
|
||||||
self.file.write(msg + '\n')
|
self.file.write(msg + '\n')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.file.flush()
|
self.file.flush()
|
||||||
except: pass
|
except: pass
|
||||||
|
@ -210,7 +210,7 @@ def enable(agi=None, display=1, logdir=None, context=5):
|
||||||
except_hook = Hook(display=display, logdir=logdir,
|
except_hook = Hook(display=display, logdir=logdir,
|
||||||
context=context, agi=agi)
|
context=context, agi=agi)
|
||||||
sys.excepthook = except_hook
|
sys.excepthook = except_hook
|
||||||
|
|
||||||
global handler
|
global handler
|
||||||
handler = except_hook.handle
|
handler = except_hook.handle
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ This module provides parsing functionality for asterisk config files.
|
||||||
|
|
||||||
import asterisk.config
|
import asterisk.config
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# load and parse the config file
|
# load and parse the config file
|
||||||
try:
|
try:
|
||||||
config = asterisk.config.Config('/etc/asterisk/extensions.conf')
|
config = asterisk.config.Config('/etc/asterisk/extensions.conf')
|
||||||
|
@ -68,7 +68,7 @@ class Category(Line):
|
||||||
|
|
||||||
self.items = []
|
self.items = []
|
||||||
self.comments = []
|
self.comments = []
|
||||||
|
|
||||||
def get_line(self):
|
def get_line(self):
|
||||||
if self.comment:
|
if self.comment:
|
||||||
return '[%s]\t;%s' % (self.name, self.comment)
|
return '[%s]\t;%s' % (self.name, self.comment)
|
||||||
|
@ -86,7 +86,7 @@ class Category(Line):
|
||||||
def remove(self, item):
|
def remove(self, item):
|
||||||
self.items.remove(item)
|
self.items.remove(item)
|
||||||
|
|
||||||
|
|
||||||
class Item(Line):
|
class Item(Line):
|
||||||
def __init__(self, line='', num=-1, name=None, value=None):
|
def __init__(self, line='', num=-1, name=None, value=None):
|
||||||
Line.__init__(self, line, num)
|
Line.__init__(self, line, num)
|
||||||
|
@ -98,7 +98,7 @@ class Item(Line):
|
||||||
self.value = value
|
self.value = value
|
||||||
else:
|
else:
|
||||||
raise Exception("Must provide name or value representing an item")
|
raise Exception("Must provide name or value representing an item")
|
||||||
|
|
||||||
def parse(self):
|
def parse(self):
|
||||||
try:
|
try:
|
||||||
name, value = self.line.split('=', 1)
|
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"
|
print "Recieved shutdown event"
|
||||||
manager.close()
|
manager.close()
|
||||||
# we could analize the event and reconnect here
|
# we could analize the event and reconnect here
|
||||||
|
|
||||||
def handle_event(event, manager):
|
def handle_event(event, manager):
|
||||||
print "Recieved event: %s" % event.name
|
print "Recieved event: %s" % event.name
|
||||||
|
|
||||||
manager = asterisk.manager.Manager()
|
manager = asterisk.manager.Manager()
|
||||||
try:
|
try:
|
||||||
# connect to the manager
|
# connect to the manager
|
||||||
try:
|
try:
|
||||||
manager.connect('host')
|
manager.connect('host')
|
||||||
manager.login('user', 'secret')
|
manager.login('user', 'secret')
|
||||||
|
|
||||||
# register some callbacks
|
# register some callbacks
|
||||||
manager.register_event('Shutdown', handle_shutdown) # shutdown
|
manager.register_event('Shutdown', handle_shutdown) # shutdown
|
||||||
manager.register_event('*', handle_event) # catch all
|
manager.register_event('*', handle_event) # catch all
|
||||||
|
|
||||||
# get a status report
|
# get a status report
|
||||||
response = manager.status()
|
response = manager.status()
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ This module provides a Python API for interfacing with the asterisk manager.
|
||||||
except asterisk.manager.ManagerException, reason:
|
except asterisk.manager.ManagerException, reason:
|
||||||
print "Error: %s" % reason
|
print "Error: %s" % reason
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
# remember to clean up
|
# remember to clean up
|
||||||
manager.close()
|
manager.close()
|
||||||
|
@ -63,14 +63,14 @@ from time import sleep
|
||||||
|
|
||||||
EOL = '\r\n'
|
EOL = '\r\n'
|
||||||
|
|
||||||
class ManagerMsg(object):
|
class ManagerMsg(object):
|
||||||
"""A manager interface message"""
|
"""A manager interface message"""
|
||||||
def __init__(self, response):
|
def __init__(self, response):
|
||||||
# the raw response, straight from the horse's mouth:
|
# the raw response, straight from the horse's mouth:
|
||||||
self.response = response
|
self.response = response
|
||||||
self.data = ''
|
self.data = ''
|
||||||
self.headers = {}
|
self.headers = {}
|
||||||
|
|
||||||
# parse the response
|
# parse the response
|
||||||
self.parse(response)
|
self.parse(response)
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ class ManagerMsg(object):
|
||||||
self.headers['Event'] = 'NoClue'
|
self.headers['Event'] = 'NoClue'
|
||||||
else:
|
else:
|
||||||
self.headers['Response'] = 'Generated Header'
|
self.headers['Response'] = 'Generated Header'
|
||||||
|
|
||||||
def parse(self, response):
|
def parse(self, response):
|
||||||
"""Parse a manager message"""
|
"""Parse a manager message"""
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ class Event(object):
|
||||||
|
|
||||||
# get the event name
|
# get the event name
|
||||||
self.name = message.get_header('Event')
|
self.name = message.get_header('Event')
|
||||||
|
|
||||||
def has_header(self, hname):
|
def has_header(self, hname):
|
||||||
"""Check for a header"""
|
"""Check for a header"""
|
||||||
return self.headers.has_key(hname)
|
return self.headers.has_key(hname)
|
||||||
|
@ -151,11 +151,11 @@ class Event(object):
|
||||||
def get_header(self, hname, defval = None):
|
def get_header(self, hname, defval = None):
|
||||||
"""Return the specfied header"""
|
"""Return the specfied header"""
|
||||||
return self.headers.get(hname, defval)
|
return self.headers.get(hname, defval)
|
||||||
|
|
||||||
def __getitem__(self, hname):
|
def __getitem__(self, hname):
|
||||||
"""Return the specfied header"""
|
"""Return the specfied header"""
|
||||||
return self.headers[hname]
|
return self.headers[hname]
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.headers['Event']
|
return self.headers['Event']
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ class Manager(object):
|
||||||
self.title = None # set by received greeting
|
self.title = None # set by received greeting
|
||||||
self._connected = threading.Event()
|
self._connected = threading.Event()
|
||||||
self._running = threading.Event()
|
self._running = threading.Event()
|
||||||
|
|
||||||
# our hostname
|
# our hostname
|
||||||
self.hostname = socket.gethostname()
|
self.hostname = socket.gethostname()
|
||||||
|
|
||||||
|
@ -185,11 +185,11 @@ class Manager(object):
|
||||||
# sequence stuff
|
# sequence stuff
|
||||||
self._seqlock = threading.Lock()
|
self._seqlock = threading.Lock()
|
||||||
self._seq = 0
|
self._seq = 0
|
||||||
|
|
||||||
# some threads
|
# some threads
|
||||||
self.message_thread = threading.Thread(target=self.message_loop)
|
self.message_thread = threading.Thread(target=self.message_loop)
|
||||||
self.event_dispatch_thread = threading.Thread(target=self.event_dispatch)
|
self.event_dispatch_thread = threading.Thread(target=self.event_dispatch)
|
||||||
|
|
||||||
self.message_thread.setDaemon(True)
|
self.message_thread.setDaemon(True)
|
||||||
self.event_dispatch_thread.setDaemon(True)
|
self.event_dispatch_thread.setDaemon(True)
|
||||||
|
|
||||||
|
@ -211,11 +211,11 @@ class Manager(object):
|
||||||
finally:
|
finally:
|
||||||
self._seq += 1
|
self._seq += 1
|
||||||
self._seqlock.release()
|
self._seqlock.release()
|
||||||
|
|
||||||
def send_action(self, cdict={}, **kwargs):
|
def send_action(self, cdict={}, **kwargs):
|
||||||
"""
|
"""
|
||||||
Send a command to the manager
|
Send a command to the manager
|
||||||
|
|
||||||
If a list is passed to the cdict argument, each item in the list will
|
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:
|
be sent to asterisk under the same header in the following manner:
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ class Manager(object):
|
||||||
|
|
||||||
if not self._connected.isSet():
|
if not self._connected.isSet():
|
||||||
raise ManagerException("Not connected")
|
raise ManagerException("Not connected")
|
||||||
|
|
||||||
# fill in our args
|
# fill in our args
|
||||||
cdict.update(kwargs)
|
cdict.update(kwargs)
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ class Manager(object):
|
||||||
self._sock.flush()
|
self._sock.flush()
|
||||||
except socket.error, (errno, reason):
|
except socket.error, (errno, reason):
|
||||||
raise ManagerSocketException(errno, reason)
|
raise ManagerSocketException(errno, reason)
|
||||||
|
|
||||||
self._reswaiting.insert(0,1)
|
self._reswaiting.insert(0,1)
|
||||||
response = self._response_queue.get()
|
response = self._response_queue.get()
|
||||||
self._reswaiting.pop(0)
|
self._reswaiting.pop(0)
|
||||||
|
@ -274,6 +274,7 @@ class Manager(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
multiline = False
|
multiline = False
|
||||||
|
status = False
|
||||||
wait_for_marker = False
|
wait_for_marker = False
|
||||||
eolcount = 0
|
eolcount = 0
|
||||||
# loop while we are sill running and connected
|
# loop while we are sill running and connected
|
||||||
|
@ -281,7 +282,7 @@ class Manager(object):
|
||||||
try:
|
try:
|
||||||
lines = []
|
lines = []
|
||||||
for line in self._sock :
|
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:
|
if not self.title and '/' in line and not ':' in line:
|
||||||
# store the title of the manager we are connecting to:
|
# store the title of the manager we are connecting to:
|
||||||
self.title = line.split('/')[0].strip()
|
self.title = line.split('/')[0].strip()
|
||||||
|
@ -303,6 +304,11 @@ class Manager(object):
|
||||||
break
|
break
|
||||||
# ignore empty lines at start
|
# ignore empty lines at start
|
||||||
continue
|
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)
|
lines.append(line)
|
||||||
# line not ending in \r\n or without ':' isn't a
|
# line not ending in \r\n or without ':' isn't a
|
||||||
# valid header and starts multiline response
|
# valid header and starts multiline response
|
||||||
|
@ -310,13 +316,17 @@ class Manager(object):
|
||||||
multiline = True
|
multiline = True
|
||||||
# Response: Follows indicates we should wait for end
|
# Response: Follows indicates we should wait for end
|
||||||
# marker --END COMMAND--
|
# 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':
|
line.split(':', 1)[1].strip() == 'Follows':
|
||||||
wait_for_marker = True
|
wait_for_marker = True
|
||||||
# same when seeing end of multiline response
|
# same when seeing end of multiline response
|
||||||
if multiline and line.startswith('--END COMMAND--'):
|
if multiline and line.startswith('--END COMMAND--'):
|
||||||
wait_for_marker = False
|
wait_for_marker = False
|
||||||
multiline = 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():
|
if not self._connected.isSet():
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
@ -333,7 +343,7 @@ class Manager(object):
|
||||||
self._connected.clear()
|
self._connected.clear()
|
||||||
self._message_queue.put(None)
|
self._message_queue.put(None)
|
||||||
|
|
||||||
|
|
||||||
def register_event(self, event, function):
|
def register_event(self, event, function):
|
||||||
"""
|
"""
|
||||||
Register a callback for the specfied event.
|
Register a callback for the specfied event.
|
||||||
|
@ -395,7 +405,7 @@ class Manager(object):
|
||||||
finally:
|
finally:
|
||||||
# wait for our data receiving thread to exit
|
# wait for our data receiving thread to exit
|
||||||
t.join()
|
t.join()
|
||||||
|
|
||||||
|
|
||||||
def event_dispatch(self):
|
def event_dispatch(self):
|
||||||
"""This thread is responsible for dispatching events"""
|
"""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 we got None as an event, we are finished
|
||||||
if not ev:
|
if not ev:
|
||||||
break
|
break
|
||||||
|
|
||||||
# dispatch our events
|
# dispatch our events
|
||||||
|
|
||||||
# first build a list of the functions to execute
|
# first build a list of the functions to execute
|
||||||
callbacks = (self._event_callbacks.get(ev.name, [])
|
callbacks = (self._event_callbacks.get(ev.name, [])
|
||||||
+ self._event_callbacks.get('*', []))
|
+ self._event_callbacks.get('*', []))
|
||||||
|
|
||||||
# now execute the functions
|
# now execute the functions
|
||||||
for callback in callbacks:
|
for callback in callbacks:
|
||||||
if callback(ev, self):
|
if callback(ev, self):
|
||||||
break
|
break
|
||||||
|
@ -455,11 +465,11 @@ class Manager(object):
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""Shutdown the connection to the manager"""
|
"""Shutdown the connection to the manager"""
|
||||||
|
|
||||||
# if we are still running, logout
|
# if we are still running, logout
|
||||||
if self._running.isSet() and self._connected.isSet():
|
if self._running.isSet() and self._connected.isSet():
|
||||||
self.logoff()
|
self.logoff()
|
||||||
|
|
||||||
if self._running.isSet():
|
if self._running.isSet():
|
||||||
# put None in the message_queue to kill our threads
|
# put None in the message_queue to kill our threads
|
||||||
self._message_queue.put(None)
|
self._message_queue.put(None)
|
||||||
|
@ -471,22 +481,22 @@ class Manager(object):
|
||||||
if threading.currentThread() != self.event_dispatch_thread:
|
if threading.currentThread() != self.event_dispatch_thread:
|
||||||
# wait for the dispatch thread to exit
|
# wait for the dispatch thread to exit
|
||||||
self.event_dispatch_thread.join()
|
self.event_dispatch_thread.join()
|
||||||
|
|
||||||
self._running.clear()
|
self._running.clear()
|
||||||
|
|
||||||
# Manager actions
|
# Manager actions
|
||||||
|
|
||||||
def login(self, username, secret):
|
def login(self, username, secret):
|
||||||
"""Login to the manager, throws ManagerAuthException when login falis"""
|
"""Login to the manager, throws ManagerAuthException when login falis"""
|
||||||
|
|
||||||
cdict = {'Action':'Login'}
|
cdict = {'Action':'Login'}
|
||||||
cdict['Username'] = username
|
cdict['Username'] = username
|
||||||
cdict['Secret'] = secret
|
cdict['Secret'] = secret
|
||||||
response = self.send_action(cdict)
|
response = self.send_action(cdict)
|
||||||
|
|
||||||
if response.get_header('Response') == 'Error':
|
if response.get_header('Response') == 'Error':
|
||||||
raise ManagerAuthException(response.get_header('Message'))
|
raise ManagerAuthException(response.get_header('Message'))
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def ping(self):
|
def ping(self):
|
||||||
|
@ -500,16 +510,16 @@ class Manager(object):
|
||||||
|
|
||||||
cdict = {'Action':'Logoff'}
|
cdict = {'Action':'Logoff'}
|
||||||
response = self.send_action(cdict)
|
response = self.send_action(cdict)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def hangup(self, channel):
|
def hangup(self, channel):
|
||||||
"""Hangup the specified channel"""
|
"""Hangup the specified channel"""
|
||||||
|
|
||||||
cdict = {'Action':'Hangup'}
|
cdict = {'Action':'Hangup'}
|
||||||
cdict['Channel'] = channel
|
cdict['Channel'] = channel
|
||||||
response = self.send_action(cdict)
|
response = self.send_action(cdict)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def status(self, channel = ''):
|
def status(self, channel = ''):
|
||||||
|
@ -518,12 +528,12 @@ class Manager(object):
|
||||||
cdict = {'Action':'Status'}
|
cdict = {'Action':'Status'}
|
||||||
cdict['Channel'] = channel
|
cdict['Channel'] = channel
|
||||||
response = self.send_action(cdict)
|
response = self.send_action(cdict)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def redirect(self, channel, exten, priority='1', extra_channel='', context=''):
|
def redirect(self, channel, exten, priority='1', extra_channel='', context=''):
|
||||||
"""Redirect a channel"""
|
"""Redirect a channel"""
|
||||||
|
|
||||||
cdict = {'Action':'Redirect'}
|
cdict = {'Action':'Redirect'}
|
||||||
cdict['Channel'] = channel
|
cdict['Channel'] = channel
|
||||||
cdict['Exten'] = exten
|
cdict['Exten'] = exten
|
||||||
|
@ -531,7 +541,7 @@ class Manager(object):
|
||||||
if context: cdict['Context'] = context
|
if context: cdict['Context'] = context
|
||||||
if extra_channel: cdict['ExtraChannel'] = extra_channel
|
if extra_channel: cdict['ExtraChannel'] = extra_channel
|
||||||
response = self.send_action(cdict)
|
response = self.send_action(cdict)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def originate(self, channel, exten, context='', priority='', timeout='', caller_id='', async=False, account='', variables={}):
|
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
|
# 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(['='.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()]
|
if variables: cdict['Variable'] = ['='.join((str(key), str(value))) for key, value in variables.items()]
|
||||||
|
|
||||||
response = self.send_action(cdict)
|
response = self.send_action(cdict)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def mailbox_status(self, mailbox):
|
def mailbox_status(self, mailbox):
|
||||||
"""Get the status of the specfied mailbox"""
|
"""Get the status of the specfied mailbox"""
|
||||||
|
|
||||||
cdict = {'Action':'MailboxStatus'}
|
cdict = {'Action':'MailboxStatus'}
|
||||||
cdict['Mailbox'] = mailbox
|
cdict['Mailbox'] = mailbox
|
||||||
response = self.send_action(cdict)
|
response = self.send_action(cdict)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def command(self, command):
|
def command(self, command):
|
||||||
|
@ -570,7 +580,7 @@ class Manager(object):
|
||||||
cdict = {'Action':'Command'}
|
cdict = {'Action':'Command'}
|
||||||
cdict['Command'] = command
|
cdict['Command'] = command
|
||||||
response = self.send_action(cdict)
|
response = self.send_action(cdict)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def extension_state(self, exten, context):
|
def extension_state(self, exten, context):
|
||||||
|
@ -580,7 +590,7 @@ class Manager(object):
|
||||||
cdict['Exten'] = exten
|
cdict['Exten'] = exten
|
||||||
cdict['Context'] = context
|
cdict['Context'] = context
|
||||||
response = self.send_action(cdict)
|
response = self.send_action(cdict)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def playdtmf (self, channel, digit) :
|
def playdtmf (self, channel, digit) :
|
||||||
|
@ -594,7 +604,7 @@ class Manager(object):
|
||||||
|
|
||||||
def absolute_timeout(self, channel, timeout):
|
def absolute_timeout(self, channel, timeout):
|
||||||
"""Set an absolute timeout on a channel"""
|
"""Set an absolute timeout on a channel"""
|
||||||
|
|
||||||
cdict = {'Action':'AbsoluteTimeout'}
|
cdict = {'Action':'AbsoluteTimeout'}
|
||||||
cdict['Channel'] = channel
|
cdict['Channel'] = channel
|
||||||
cdict['Timeout'] = timeout
|
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
|
from distutils.core import setup
|
||||||
|
|
||||||
try :
|
from asterisk import __version__ as version
|
||||||
from asterisk.Version import VERSION
|
|
||||||
except :
|
|
||||||
VERSION = None
|
|
||||||
|
|
||||||
description = []
|
description = []
|
||||||
f = open ('README')
|
f = open ('README')
|
||||||
|
@ -22,14 +20,14 @@ licenses = ( 'Python Software Foundation License'
|
||||||
|
|
||||||
|
|
||||||
setup \
|
setup \
|
||||||
( name = 'pyst'
|
( name = 'pyst2'
|
||||||
, version = VERSION
|
, version = version
|
||||||
, description = 'A Python Interface to Asterisk'
|
, description = 'A Python Interface to Asterisk'
|
||||||
, long_description = ''.join (description)
|
, long_description = ''.join (description)
|
||||||
, author = 'Karl Putland'
|
, author = 'Karl Putland'
|
||||||
, author_email = 'kputland@users.sourceforge.net'
|
, author_email = 'kputland@users.sourceforge.net'
|
||||||
, maintainer = 'Ralf Schlatterbeck'
|
, maintainer = 'Randall Degges'
|
||||||
, maintainer_email = 'rsc@runtux.com'
|
, maintainer_email = 'rdegges@gmail.com'
|
||||||
, url = 'http://www.sourceforge.net/projects/pyst/'
|
, url = 'http://www.sourceforge.net/projects/pyst/'
|
||||||
, packages = ['asterisk']
|
, packages = ['asterisk']
|
||||||
, license = ', '.join (licenses)
|
, license = ', '.join (licenses)
|
||||||
|
|
Loading…
Reference in New Issue