minor rewrite for Python 3 support. Some other fixes in corresponding files.

develop
Timur Tuchkovenko 2014-10-08 00:49:54 +06:00
parent 6bd0cc9bd6
commit 5efe3f4593
11 changed files with 122 additions and 83 deletions

10
.gitignore vendored
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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