Merge branch 'release/0.4'

develop
Randall Degges 2011-05-31 17:24:21 -07:00
commit 7493c64c9b
16 changed files with 107 additions and 323 deletions

View File

@ -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

View File

@ -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
View File

@ -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

View File

@ -11,4 +11,4 @@ manager - a module for interacting with the asterisk manager interface
"""
__all__ = ['agi', 'agitb', 'config', 'manager']
__version__ = '0.4'

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

63
debian/changelog vendored
View File

@ -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
debian/compat vendored
View File

@ -1 +0,0 @@
4

21
debian/control vendored
View File

@ -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.

79
debian/copyright vendored
View File

@ -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.

10
debian/rules vendored
View File

@ -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

3
debian/watch vendored
View File

@ -1,3 +0,0 @@
# Site Directory Pattern Version Script
version=2
http://ftp1.sourceforge.net/pyst/pyst-(.*)\.tar\.gz debian uupdate

View File

@ -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

View File

@ -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)