sintonia/library/ecasound-2.7.2/ecatools/ecamonitor

238 lines
7.8 KiB
Python
Executable File

#!/usr/bin/env python
# ------------------------------------------------------------------------
# ecamonitor: Ecasound monitor client implemented using NetECI
# Copyright (C) 2002-2003,2009 Kai Vehmanen
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# ------------------------------------------------------------------------
import curses
import re
import socket
import string
import sys
import time
ecamonitor_remote_host = "localhost"
ecamonitor_remote_port = 2868
ecamonitor_version = "v20090419-7"
# TODO:
# - nothing at the moment
# References:
# - http://www.python.org/doc/essays/styleguide.html
# - http://py-howto.sourceforge.net/curses/curses.html
# - http://www.python.org/doc/2.2.2/lib/module-curses.html
# - http://py-howto.sourceforge.net/regex/regex.html
# - http://www.python.org/doc/2.2.2/lib/module-re.html
# - http://py-howto.sourceforge.net/sockets/sockets.html
# - http://www.python.org/doc/2.2.2/lib/module-string.html
def connect_to_server(remote_host, remote_port):
"""Connects to the ecasound server.
@return Socket object for the connection.
"""
while 1:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((remote_host, remote_port))
s.setblocking(1)
return(s)
except Exception, e:
if e[0] == 111: # 111 = connection refused
time.sleep(1)
pass
else:
raise
def issue_eiam_command(s, cmd):
"""Sends a command to ecasound and waits for an response.
@param s socket for an active connection
@param cmd EIAM command to send
@return tuple of return value type and value
"""
tm = ''
counter = 0
s.send(cmd + '\r\n')
while counter < 16:
count = counter + 1
newdata = s.recv(4096)
if len(newdata) == 0:
return ('e','')
tm = tm + newdata
# lets test whether we have received a valid
# EIAM command
try:
m = expand_eiam_response(tm)
return parse_eiam_response(m, tm)
except Exception, e:
pass
return ('e','')
def expand_eiam_response(str):
"""Checks wheter 'str' is a valid EIAM response.
@return Regex match object.
"""
m = re.match('256 ([0-9]{1,5}) (.+)\r\n(.*)\r\n\r\n.*', str, re.MULTILINE | re.S)
return m
def parse_eiam_response(m, str):
"""Parses a valid EIAM response.
@param m Valid regex match object.
@param str The whole EIAM response.
@return tuple of return value type and value
"""
if not m:
m = re.match('256 ([0-9]{1,5}) (.+)\r\n(.*)', str, re.MULTILINE | re.S)
if not m:
raise Exception, 'Regexp failed!'
if m and len(m.groups()) == 0:
print "(ecamonitor) Matching groups failed: ", m.groups()
if m and len(m.groups()) == 3:
#print 'received=', len(m.group(3)), ', expected=', m.group(1)
if int(m.group(1)) != len(m.group(3)):
print "(ecamonitor) Response length error."
if m:
return (m.group(2), m.group(3))
return ('e','')
def main():
s = None
remote_host = ecamonitor_remote_host
remote_port = ecamonitor_remote_port
if not hasattr(sys, 'version_info') or (hasattr(sys, 'version_info') and sys.version_info[1] <2):
print 'Error! Ecamonitor requires python-2.0 or newer to run!'
return 1
if len(sys.argv) > 1:
destination = sys.argv[1]
address = string.split(destination, ':')
remote_host = address[0]
if len(address) > 1:
remote_port = int(address[1])
try:
stdscr = curses.initscr()
pad = curses.newpad(255, 80)
pad.nodelay(1) # to make getch() nonblocking
while 1:
try:
pad.erase()
pad.addstr(0, 0, "ecamonitor " + ecamonitor_version, curses.A_BOLD)
if s == None:
pad.addstr(2, 0, "No connection. Trying to connect to " + remote_host + ":" + str(remote_port) + ".\n")
pad.refresh(0, 0, 0, 0, stdscr.getmaxyx()[0]-1, stdscr.getmaxyx()[1]-1)
#time.sleep(3)
s = connect_to_server(remote_host, remote_port)
pad.addstr(3, 0, "Connection established.\n")
pad.refresh(0, 0, 0, 0, stdscr.getmaxyx()[0]-1, stdscr.getmaxyx()[1]-1)
pad.addstr(1, 0, "")
else:
pad.addstr("\n")
pad.addstr("\n------------------------------------------------------------")
pad.addstr("\nEngine status: ")
pad.addstr((issue_eiam_command(s, 'engine-status')[1]), curses.A_BOLD)
pad.addstr("\nConnected chainsetup: ")
pad.addstr(issue_eiam_command(s, 'cs-connected')[1], curses.A_BOLD)
pad.addstr("\nSelected chainsetup: ")
pad.addstr(issue_eiam_command(s, 'cs-selected')[1], curses.A_BOLD)
#pad.addstr("\nSelected chainsetup status:: ")
#pad.addstr(issue_eiam_command(s, 'cs-status')[1])
pad.addstr("\n\nPosition: ")
pad.addstr(issue_eiam_command(s, 'cs-get-position')[1] + "s", curses.A_BOLD)
pad.addstr(" / Length: ")
pad.addstr(issue_eiam_command(s, 'cs-get-length')[1] + "s", curses.A_BOLD)
pad.addstr("\nChains: ")
pad.addstr(str(len(string.split(issue_eiam_command(s, 'c-list')[1],','))), curses.A_BOLD)
pad.addstr(" / Inputs: ")
pad.addstr(str(len(string.split(issue_eiam_command(s, 'ai-list')[1],','))), curses.A_BOLD)
pad.addstr(" / Outputs: ")
pad.addstr(str(len(string.split(issue_eiam_command(s, 'ao-list')[1],','))), curses.A_BOLD)
pad.addstr("\n\n------------------------------------------------------------\n")
res = issue_eiam_command(s, 'aio-status')
pad.addstr(res[1])
pad.addstr("\n\n------------------------------------------------------------\n")
res = issue_eiam_command(s, 'cop-status')
pad.addstr(res[1])
pad.addstr("\n\n------------------------------------------------------------\n")
res = issue_eiam_command(s, 'ctrl-status')
pad.addstr(res[1])
pad.addstr("\n\n------------------------------------------------------------\n")
pad.refresh(0, 0, 0, 0, stdscr.getmaxyx()[0]-1, stdscr.getmaxyx()[1]-1)
time.sleep(1.0)
ch=pad.getch()
if ch == ord('q'):
break
except curses.error:
raise
except socket.error, e:
if e[0] == 32 or e[0] == 104 or e[0] == 111:
s = None
pass
else:
curses.endwin()
print "Exception!" , e
raise
except KeyboardInterrupt:
break
finally:
if s != None:
s.close()
curses.endwin()
if __name__ == '__main__':
main()