minor rewrite for Python 3 support. Some other fixes in corresponding files.
parent
6bd0cc9bd6
commit
5efe3f4593
|
@ -1,6 +1,6 @@
|
||||||
# Temporary files.
|
# Temporary files.
|
||||||
*.pyc
|
*.py[cod]
|
||||||
*.swp
|
*.sw?
|
||||||
*~
|
*~
|
||||||
.coverage
|
.coverage
|
||||||
|
|
||||||
|
@ -10,5 +10,11 @@ build
|
||||||
_build
|
_build
|
||||||
*.egg-info
|
*.egg-info
|
||||||
|
|
||||||
|
# Python-related stuff
|
||||||
|
env/
|
||||||
|
.env/
|
||||||
|
venv/
|
||||||
|
__pycache__/
|
||||||
|
|
||||||
# Auto-generated files.
|
# Auto-generated files.
|
||||||
MANIFEST
|
MANIFEST
|
||||||
|
|
30
CHANGELOG
30
CHANGELOG
|
@ -1,3 +1,21 @@
|
||||||
|
2014-10-08 Timur Tuchkovenko <eill@yandex.ru>
|
||||||
|
* UPGRADE: initial Python 3 support. Now pyst2 requires
|
||||||
|
Python 'six' module. Some minor changes in other files.
|
||||||
|
|
||||||
|
2014-09-14 Sp1tF1r3 <https://github.com/Sp1tF1r3>
|
||||||
|
* asterisk/manager.py: added action 'Reload' for Asterisk Manager
|
||||||
|
Interface (AMI).
|
||||||
|
|
||||||
|
2013-12-03 Ludovic Gasc <gmludo@gmail.com>
|
||||||
|
* examples/agi_script.py: added example script to explain AGI
|
||||||
|
functionality.
|
||||||
|
* README: renamed to REAMDE.rst for Github's Markdown support.
|
||||||
|
* setup.py: minor changes.
|
||||||
|
|
||||||
|
2012-11-12 Arezqui Belaid <areski@gmail.com>
|
||||||
|
* asterisk/manager.py: minor empty line enhancements.
|
||||||
|
* examples/show_channels.py: added example script to show information via
|
||||||
|
Asterisk Manager Interface (AMI).
|
||||||
|
|
||||||
2012-11-11 Arezqui Belaid <areski@gmail.com>
|
2012-11-11 Arezqui Belaid <areski@gmail.com>
|
||||||
* PEP8 Fixes
|
* PEP8 Fixes
|
||||||
|
@ -8,18 +26,18 @@
|
||||||
|
|
||||||
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
|
||||||
dict.get().
|
dict.get().
|
||||||
* UPGRADE: Updated.
|
* UPGRADE: Updated.
|
||||||
|
|
||||||
2007-01-16 Matthew Nicholson <mnicholson@digium.com>
|
2007-01-16 Matthew Nicholson <mnicholson@digium.com>
|
||||||
|
|
||||||
* asterisk/manager.py: Fix support for Manager.command(). Patch from
|
* asterisk/manager.py: Fix support for Manager.command(). Patch from
|
||||||
Karl Putland <karl@klasstek.com>.
|
Karl Putland <karl@klasstek.com>.
|
||||||
|
|
||||||
2007-01-02 Matthew Nicholson <mnicholson@digium.com>
|
2007-01-02 Matthew Nicholson <mnicholson@digium.com>
|
||||||
|
|
||||||
* asterisk/agi.py (AGI.set_autohangup): Fixed syntax error.
|
* asterisk/agi.py (AGI.set_autohangup): Fixed syntax error.
|
||||||
|
|
||||||
2006-11-28 Matthew Nicholson <mnicholson@digium.com>
|
2006-11-28 Matthew Nicholson <mnicholson@digium.com>
|
||||||
|
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -9,7 +9,7 @@ VERSION=$(VERSIONPY)
|
||||||
LASTRELEASE:=$(shell ../svntools/lastrelease -n)
|
LASTRELEASE:=$(shell ../svntools/lastrelease -n)
|
||||||
|
|
||||||
USERNAME=schlatterbeck
|
USERNAME=schlatterbeck
|
||||||
PROJECT=pyst
|
PROJECT=pyst2
|
||||||
PACKAGE=${PROJECT}
|
PACKAGE=${PROJECT}
|
||||||
CHANGES=changes
|
CHANGES=changes
|
||||||
NOTES=notes
|
NOTES=notes
|
||||||
|
|
92
README.rst
92
README.rst
|
@ -1,21 +1,43 @@
|
||||||
pyst: A Python Interface to Asterisk
|
pyst2: A Python Interface to Asterisk
|
||||||
====================================
|
====================================
|
||||||
|
|
||||||
Pyst consists of a set of interfaces and libraries to allow programming of
|
Pyst2 consists of a set of interfaces and libraries to allow programming of
|
||||||
Asterisk from python. The library currently supports AGI, AMI, and the parsing
|
Asterisk from python. The library currently supports AGI, AMI, and the parsing
|
||||||
of Asterisk configuration files. The library also includes debugging facilities
|
of Asterisk configuration files. The library also includes debugging facilities
|
||||||
for AGI.
|
for AGI.
|
||||||
|
|
||||||
Download from `Sourceforge project page`_.
|
This project has been forked from pyst (http://sf.net/projects/pyst/) 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.
|
||||||
|
|
||||||
.. _`Sourceforge project page`: http://sourceforge.net/projects/pyst/
|
My 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!
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
1. six
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
Download from `Github project page`_.
|
||||||
|
|
||||||
|
.. _`Github project page`: https://github.com/rdegges/pyst2
|
||||||
|
|
||||||
Installation is the standard python install::
|
Installation is the standard python install::
|
||||||
|
|
||||||
tar xvf pyst.tar.gz
|
git clone https://github.com/rdegges/pyst2.git
|
||||||
cd pyst
|
cd pyst2
|
||||||
python setup.py install --prefix=/usr/local
|
python setup.py install --prefix=/usr/local
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
|
||||||
Documentation is currently only in python docstrings, you can use
|
Documentation is currently only in python docstrings, you can use
|
||||||
pythons built-in help facility::
|
pythons built-in help facility::
|
||||||
|
|
||||||
|
@ -35,23 +57,14 @@ 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.
|
||||||
|
Thanks to Randall Degges for maintaining this for and accepting
|
||||||
|
pull requests.
|
||||||
|
|
||||||
Things to do for pyst
|
Things to do for pyst
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -59,9 +72,8 @@ Things to do for pyst
|
||||||
This is the original changelog merged into the readme file. I'm not so
|
This is the original changelog merged into the readme file. I'm not so
|
||||||
sure I really want to change all these things (in particular the
|
sure I really want to change all these things (in particular the
|
||||||
threaded implementation looks good to me). I will maintain a section
|
threaded implementation looks good to me). I will maintain a section
|
||||||
summarizing the changes in this README, the ChangeLog won't be
|
summarizing the changes in this README. Detailed changes will be
|
||||||
maintained any longer. Detailed changes will be available in the version
|
available in the version control tool (currently git).
|
||||||
control tool (currently svn).
|
|
||||||
|
|
||||||
* ChangeLog:
|
* ChangeLog:
|
||||||
The ChangeLog needs to be updated from the monotone logs.
|
The ChangeLog needs to be updated from the monotone logs.
|
||||||
|
@ -82,28 +94,28 @@ control tool (currently svn).
|
||||||
Matthew Nicholson writes on the mailinglist (note that I'm not sure I'll do
|
Matthew Nicholson writes on the mailinglist (note that I'm not sure I'll do
|
||||||
this, I'm currently satisfied with the threaded implementation):
|
this, I'm currently satisfied with the threaded implementation):
|
||||||
|
|
||||||
For pyst 0.3 I am planning to clean up the manager.py. There are
|
For pyst 0.3 I am planning to clean up the manager.py. There are
|
||||||
several know issues with the code. No one has actually reported these
|
several know issues with the code. No one has actually reported these
|
||||||
as problems, but I have personally had trouble with these. Currently
|
as problems, but I have personally had trouble with these. Currently
|
||||||
manager.py runs in several threads, the main program thread, a thread to
|
manager.py runs in several threads, the main program thread, a thread to
|
||||||
read from the network, and an event distribution thread. This causes
|
read from the network, and an event distribution thread. This causes
|
||||||
problems with non thread safe code such as the MySQLdb libraries. This
|
problems with non thread safe code such as the MySQLdb libraries. This
|
||||||
design also causes problems when an event handler throws an exception
|
design also causes problems when an event handler throws an exception
|
||||||
that causes the event processing thread to terminate.
|
that causes the event processing thread to terminate.
|
||||||
|
|
||||||
The second problem is with the way actions are sent. Each action has a
|
The second problem is with the way actions are sent. Each action has a
|
||||||
specific function associated with it in the manager object that takes
|
specific function associated with it in the manager object that takes
|
||||||
all possible arguments that may ever be passed to that action. This
|
all possible arguments that may ever be passed to that action. This
|
||||||
makes the api somewhat rigid and the Manager object cluttered.
|
makes the api somewhat rigid and the Manager object cluttered.
|
||||||
|
|
||||||
To solve these problems I am basically going to copy the design of my
|
To solve these problems I am basically going to copy the design of my
|
||||||
Astxx manager library (written in c++) and make it more python like.
|
Astxx manager library (written in c++) and make it more python like.
|
||||||
Each action will be a different object with certain methods to handle
|
Each action will be a different object with certain methods to handle
|
||||||
various tasks, with one function in the actual Manager class to send the
|
various tasks, with one function in the actual Manager class to send the
|
||||||
action. This will make the Manager class much smaller and much more
|
action. This will make the Manager class much smaller and much more
|
||||||
flexible. The current code will be consolidated into a single threaded
|
flexible. The current code will be consolidated into a single threaded
|
||||||
design with hooks to have the library process events and such. These
|
design with hooks to have the library process events and such. These
|
||||||
hooks will be called from the host application's main loop.
|
hooks will be called from the host application's main loop.
|
||||||
|
|
||||||
|
|
||||||
Upgrading from older versions
|
Upgrading from older versions
|
||||||
|
|
|
@ -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'
|
__version__ = '0.4.1'
|
||||||
|
|
|
@ -22,7 +22,6 @@ pyvr
|
||||||
import sys
|
import sys
|
||||||
import pprint
|
import pprint
|
||||||
import re
|
import re
|
||||||
from types import ListType
|
|
||||||
import signal
|
import signal
|
||||||
|
|
||||||
DEFAULT_TIMEOUT = 2000 # 2sec timeout used as default for functions that take timeouts
|
DEFAULT_TIMEOUT = 2000 # 2sec timeout used as default for functions that take timeouts
|
||||||
|
@ -131,7 +130,7 @@ class AGI:
|
||||||
try:
|
try:
|
||||||
self.send_command(command, *args)
|
self.send_command(command, *args)
|
||||||
return self.get_result()
|
return self.get_result()
|
||||||
except IOError, e:
|
except IOError as e:
|
||||||
if e.errno == 32:
|
if e.errno == 32:
|
||||||
# Broken Pipe * let us go
|
# Broken Pipe * let us go
|
||||||
raise AGISIGPIPEHangup("Received SIGPIPE")
|
raise AGISIGPIPEHangup("Received SIGPIPE")
|
||||||
|
@ -188,7 +187,7 @@ class AGI:
|
||||||
raise AGIUnknownError(code, 'Unhandled code or undefined response')
|
raise AGIUnknownError(code, 'Unhandled code or undefined response')
|
||||||
|
|
||||||
def _process_digit_list(self, digits):
|
def _process_digit_list(self, digits):
|
||||||
if type(digits) == ListType:
|
if type(digits) is list:
|
||||||
digits = ''.join(map(str, digits))
|
digits = ''.join(map(str, digits))
|
||||||
return self._quote(digits)
|
return self._quote(digits)
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ def scanvars(reader, frame, locals):
|
||||||
return vars
|
return vars
|
||||||
|
|
||||||
|
|
||||||
def text((etype, evalue, etb), context=5):
|
def text(eparams, context=5):
|
||||||
"""Return a plain text document describing a given traceback."""
|
"""Return a plain text document describing a given traceback."""
|
||||||
import os
|
import os
|
||||||
import types
|
import types
|
||||||
|
@ -89,6 +89,7 @@ def text((etype, evalue, etb), context=5):
|
||||||
import inspect
|
import inspect
|
||||||
import pydoc
|
import pydoc
|
||||||
|
|
||||||
|
etype, evalue, etb = eparams
|
||||||
if isinstance(etype, types.ClassType):
|
if isinstance(etype, types.ClassType):
|
||||||
etype = etype.__name__
|
etype = etype.__name__
|
||||||
pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
|
pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
|
||||||
|
|
|
@ -11,11 +11,11 @@ This module provides parsing functionality for asterisk config files.
|
||||||
# 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')
|
||||||
except asterisk.config.ParseError, (line, reason):
|
except asterisk.config.ParseError as e:
|
||||||
print "Parse Error line: %s: %s" % (line, reason)
|
print "Parse Error line: %s: %s" % (e.line, e.strerror)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except IOError, reason:
|
except IOError as e:
|
||||||
print "Error opening file: %s" % reason
|
print "Error opening file: %s" % e.strerror
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# print our parsed output
|
# print our parsed output
|
||||||
|
|
|
@ -32,14 +32,14 @@ This module provides a Python API for interfacing with the asterisk manager.
|
||||||
response = manager.status()
|
response = manager.status()
|
||||||
|
|
||||||
manager.logoff()
|
manager.logoff()
|
||||||
except asterisk.manager.ManagerSocketException, (errno, reason):
|
except asterisk.manager.ManagerSocketException as e:
|
||||||
print "Error connecting to the manager: %s" % reason
|
print "Error connecting to the manager: %s" % e.strerror
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except asterisk.manager.ManagerAuthException, reason:
|
except asterisk.manager.ManagerAuthException as e:
|
||||||
print "Error logging in to the manager: %s" % reason
|
print "Error logging in to the manager: %s" % e.strerror
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except asterisk.manager.ManagerException, reason:
|
except asterisk.manager.ManagerException as e:
|
||||||
print "Error: %s" % reason
|
print "Error: %s" % e.strerror
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
@ -56,9 +56,8 @@ import sys
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
import threading
|
import threading
|
||||||
import Queue
|
from six.moves import queue
|
||||||
import re
|
import re
|
||||||
from cStringIO import StringIO
|
|
||||||
from types import *
|
from types import *
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
|
@ -181,9 +180,9 @@ class Manager(object):
|
||||||
self.hostname = socket.gethostname()
|
self.hostname = socket.gethostname()
|
||||||
|
|
||||||
# our queues
|
# our queues
|
||||||
self._message_queue = Queue.Queue()
|
self._message_queue = queue.Queue()
|
||||||
self._response_queue = Queue.Queue()
|
self._response_queue = queue.Queue()
|
||||||
self._event_queue = Queue.Queue()
|
self._event_queue = queue.Queue()
|
||||||
|
|
||||||
# callbacks for events
|
# callbacks for events
|
||||||
self._event_callbacks = {}
|
self._event_callbacks = {}
|
||||||
|
@ -265,8 +264,8 @@ class Manager(object):
|
||||||
try:
|
try:
|
||||||
self._sock.write(command)
|
self._sock.write(command)
|
||||||
self._sock.flush()
|
self._sock.flush()
|
||||||
except socket.error, (errno, reason):
|
except socket.error as e:
|
||||||
raise ManagerSocketException(errno, reason)
|
raise ManagerSocketException(e.errno, e.strerror)
|
||||||
|
|
||||||
self._reswaiting.insert(0, 1)
|
self._reswaiting.insert(0, 1)
|
||||||
response = self._response_queue.get()
|
response = self._response_queue.get()
|
||||||
|
@ -410,7 +409,7 @@ class Manager(object):
|
||||||
elif message.has_header('Response'):
|
elif message.has_header('Response'):
|
||||||
self._response_queue.put(message)
|
self._response_queue.put(message)
|
||||||
else:
|
else:
|
||||||
print 'No clue what we got\n%s' % message.data
|
print('No clue what we got\n%s' % message.data)
|
||||||
finally:
|
finally:
|
||||||
# wait for our data receiving thread to exit
|
# wait for our data receiving thread to exit
|
||||||
t.join()
|
t.join()
|
||||||
|
@ -445,7 +444,7 @@ class Manager(object):
|
||||||
raise ManagerException('Already connected to manager')
|
raise ManagerException('Already connected to manager')
|
||||||
|
|
||||||
# make sure host is a string
|
# make sure host is a string
|
||||||
assert type(host) in StringTypes
|
assert type(host) is str
|
||||||
|
|
||||||
port = int(port) # make sure port is an int
|
port = int(port) # make sure port is an int
|
||||||
|
|
||||||
|
@ -455,8 +454,8 @@ class Manager(object):
|
||||||
_sock.connect((host, port))
|
_sock.connect((host, port))
|
||||||
self._sock = _sock.makefile()
|
self._sock = _sock.makefile()
|
||||||
_sock.close()
|
_sock.close()
|
||||||
except socket.error, (errno, reason):
|
except socket.error as e:
|
||||||
raise ManagerSocketException(errno, reason)
|
raise ManagerSocketException(e.errno, e.strerror)
|
||||||
|
|
||||||
# we are connected and running
|
# we are connected and running
|
||||||
self._connected.set()
|
self._connected.set()
|
||||||
|
|
|
@ -14,20 +14,20 @@ try:
|
||||||
|
|
||||||
# get a status report
|
# get a status report
|
||||||
response = manager.status()
|
response = manager.status()
|
||||||
print response
|
print(response)
|
||||||
|
|
||||||
response = manager.command('core show channels concise')
|
response = manager.command('core show channels concise')
|
||||||
print response.data
|
print(response.data)
|
||||||
|
|
||||||
manager.logoff()
|
manager.logoff()
|
||||||
except asterisk.manager.ManagerSocketException, (errno, reason):
|
except asterisk.manager.ManagerSocketException as e:
|
||||||
print "Error connecting to the manager: %s" % reason
|
print "Error connecting to the manager: %s" % e.strerror
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except asterisk.manager.ManagerAuthException, reason:
|
except asterisk.manager.ManagerAuthException as e:
|
||||||
print "Error logging in to the manager: %s" % reason
|
print "Error logging in to the manager: %s" % e.strerror
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except asterisk.manager.ManagerException, reason:
|
except asterisk.manager.ManagerException as e:
|
||||||
print "Error: %s" % reason
|
print "Error: %s" % e.strerror
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
|
4
setup.py
4
setup.py
|
@ -41,6 +41,10 @@ setup(
|
||||||
'Programming Language :: Python :: 2.5',
|
'Programming Language :: Python :: 2.5',
|
||||||
'Programming Language :: Python :: 2.6',
|
'Programming Language :: Python :: 2.6',
|
||||||
'Programming Language :: Python :: 2.7',
|
'Programming Language :: Python :: 2.7',
|
||||||
|
'Programming Language :: Python :: 3',
|
||||||
|
'Programming Language :: Python :: 3.2',
|
||||||
|
'Programming Language :: Python :: 3.3',
|
||||||
|
'Programming Language :: Python :: 3.4',
|
||||||
'Topic :: Communications :: Internet Phone',
|
'Topic :: Communications :: Internet Phone',
|
||||||
'Topic :: Communications :: Telephony',
|
'Topic :: Communications :: Telephony',
|
||||||
'Topic :: Software Development :: Libraries :: Python Modules'
|
'Topic :: Software Development :: Libraries :: Python Modules'
|
||||||
|
|
Loading…
Reference in New Issue