From 09af403cf53cc4554ea1e42bf158b398700c6495 Mon Sep 17 00:00:00 2001
From: Martin Konecny <martin.konecny@gmail.com>
Date: Tue, 21 Feb 2012 21:38:25 -0500
Subject: [PATCH] CC-3075: Create airtime-test-soundcard and
 airtime-test-icecast utils

-Done
---
 install_minimal/include/airtime-copy-files.sh |  2 +
 .../include/airtime-remove-files.sh           |  2 +
 utils/airtime-test-soundcard                  | 33 ++++++++++++
 utils/airtime-test-soundcard.py               | 54 ++++++++++++++++---
 utils/airtime-test-stream                     | 33 ++++++++++++
 utils/airtime-test-stream.py                  | 48 +++++++++++++++--
 6 files changed, 159 insertions(+), 13 deletions(-)
 create mode 100755 utils/airtime-test-soundcard
 create mode 100755 utils/airtime-test-stream

diff --git a/install_minimal/include/airtime-copy-files.sh b/install_minimal/include/airtime-copy-files.sh
index 5eab4a4ef..9a8520566 100755
--- a/install_minimal/include/airtime-copy-files.sh
+++ b/install_minimal/include/airtime-copy-files.sh
@@ -77,6 +77,8 @@ ln -sf /usr/lib/airtime/utils/airtime-import/airtime-import /usr/bin/airtime-imp
 ln -sf /usr/lib/airtime/utils/airtime-update-db-settings /usr/bin/airtime-update-db-settings
 ln -sf /usr/lib/airtime/utils/airtime-check-system /usr/bin/airtime-check-system
 ln -sf /usr/lib/airtime/utils/airtime-log /usr/bin/airtime-log
+ln -sf /usr/lib/airtime/utils/airtime-test-soundcard /usr/bin/airtime-test-soundcard
+ln -sf /usr/lib/airtime/utils/airtime-test-stream /usr/bin/airtime-test-stream
 
 if [ "$web" = "t" ]; then
     echo "* Creating /usr/share/airtime"
diff --git a/install_minimal/include/airtime-remove-files.sh b/install_minimal/include/airtime-remove-files.sh
index b7c6c54b8..330f2b0c7 100755
--- a/install_minimal/include/airtime-remove-files.sh
+++ b/install_minimal/include/airtime-remove-files.sh
@@ -46,6 +46,8 @@ rm -f /usr/bin/airtime-import
 rm -f /usr/bin/airtime-update-db-settings
 rm -f /usr/bin/airtime-check-system
 rm -f /usr/bin/airtime-log
+rm -f /usr/bin/airtime-test-soundcard
+rm -f /usr/bin/airtime-test-stream
 
 rm -rf /usr/lib/airtime
 rm -rf /usr/share/airtime
diff --git a/utils/airtime-test-soundcard b/utils/airtime-test-soundcard
new file mode 100755
index 000000000..018697724
--- /dev/null
+++ b/utils/airtime-test-soundcard
@@ -0,0 +1,33 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+#   Copyright (c) 2011 Sourcefabric O.P.S.
+#
+#   This file is part of the Airtime project.
+#   http://airtime.sourcefabric.org/
+#
+#   Airtime 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.
+#
+#   Airtime 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 Airtime; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+#  This script send data to data collection server
+#
+# Absolute path to this script
+SCRIPT=`readlink -f $0`
+# Absolute directory this script is in
+SCRIPTPATH=`dirname $SCRIPT`
+
+cd $SCRIPTPATH
+
+python airtime-test-soundcard.py "$@" || exit 1
diff --git a/utils/airtime-test-soundcard.py b/utils/airtime-test-soundcard.py
index 4978cebce..5d1ce95c9 100644
--- a/utils/airtime-test-soundcard.py
+++ b/utils/airtime-test-soundcard.py
@@ -6,18 +6,44 @@ import sys
 
 import getopt
 
+"""
+we need to run the program as non-root because Liquidsoap refuses to run as root.
+It is possible to run change the effective user id (seteuid) before calling Liquidsoap
+but this introduces other problems (fake root user is not part of audio group after calling seteuid)
+"""
 if os.geteuid() == 0:
     print "Please run this program as non-root"
     sys.exit(1)
 
 def printUsage():
-    print "airtime-test-soundcard [-v] [-o alsa | ao | oss | portaudio | pulseaudio ]"
+    print "airtime-test-soundcard [-v] [-o alsa | ao | oss | portaudio | pulseaudio ] [-h]"
     print " Where: "
-    print "     -v verbose mode "
-    print "     -o Linux Sound API "
+    print "     -v verbose mode"
+    print "     -o Linux Sound API (default: alsa)"
+    print "     -h show help menu "
+    
+def find_liquidsoap_binary():
+    """
+    Starting with Airtime 2.0, we don't know the exact location of the Liquidsoap
+    binary because it may have been installed through a debian package. Let's find
+    the location of this binary.
+    """
+    
+    rv = subprocess.call("which liquidsoap > /dev/null", shell=True)
+    if rv == 0:
+        return "liquidsoap"
+    else:
+        if os.path.exists("/usr/lib/airtime/pypo/bin/liquidsoap_bin/liquidsoap"):
+            return "/usr/lib/airtime/pypo/bin/liquidsoap_bin/liquidsoap"
 
+    return None
 
-optlist, args = getopt.getopt(sys.argv[1:], 'hvo:')
+try:
+    optlist, args = getopt.getopt(sys.argv[1:], 'hvo:')
+except getopt.GetoptError, g:
+    printUsage()
+    sys.exit(1)
+    
 sound_api_types = set(["alsa", "ao", "oss", "portaudio", "pulseaudio"])
 
 verbose = False
@@ -32,14 +58,20 @@ for o, a in optlist:
             print "Unknown sound api type\n"
             printUsage()
             sys.exit(1)
-    if "-h" == o:
+    if "-h" == o and len(optlist) == 1:
         printUsage()
         sys.exit(0)
 
 try:
-    print "Outputting to soundcard with '%s' sound API. You should be able to hear a monotonous tone. Press ctrl-c to quit." % sound_api
+    print "Sound API: %s" % sound_api
+    print "Outputting to soundcard. You should be able to hear a monotonous tone. Press ctrl-c to quit."
         
-    command = "/usr/lib/airtime/pypo/bin/liquidsoap_bin/liquidsoap 'output.%s(sine())'" % sound_api
+    liquidsoap_exe = find_liquidsoap_binary()
+    
+    if liquidsoap_exe is None:
+        raise Exception("Liquidsoap not found!")
+        
+    command = "%s 'output.%s(sine())'" % (liquidsoap_exe, sound_api)
     
     if not verbose:
         command += " > /dev/null"
@@ -47,7 +79,13 @@ try:
     #print command
     rv = subprocess.call(command, shell=True)
     
+    #if we reach this point, it means that our subprocess exited without the user
+    #doing a keyboard interrupt. This means there was a problem outputting to the 
+    #soundcard. Print appropriate message.
+    print "There was an error using the selected sound API. Please select a different API " + \
+        "and run this program again. Use the -h option for help"
+    
 except KeyboardInterrupt, ki:
-    print "Exiting"
+    print "\nExiting"
 except Exception, e:
     raise
diff --git a/utils/airtime-test-stream b/utils/airtime-test-stream
new file mode 100755
index 000000000..4c49fe27c
--- /dev/null
+++ b/utils/airtime-test-stream
@@ -0,0 +1,33 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+#   Copyright (c) 2011 Sourcefabric O.P.S.
+#
+#   This file is part of the Airtime project.
+#   http://airtime.sourcefabric.org/
+#
+#   Airtime 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.
+#
+#   Airtime 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 Airtime; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+#  This script send data to data collection server
+#
+# Absolute path to this script
+SCRIPT=`readlink -f $0`
+# Absolute directory this script is in
+SCRIPTPATH=`dirname $SCRIPT`
+
+cd $SCRIPTPATH
+
+python airtime-test-stream.py "$@" || exit 1
diff --git a/utils/airtime-test-stream.py b/utils/airtime-test-stream.py
index 3c47b77ab..2f349c592 100644
--- a/utils/airtime-test-stream.py
+++ b/utils/airtime-test-stream.py
@@ -6,6 +6,11 @@ import sys
 
 import getopt
 
+"""
+we need to run the program as non-root because Liquidsoap refuses to run as root.
+It is possible to run change the effective user id (seteuid) before calling Liquidsoap
+but this introduces other problems (fake root user is not part of audio group after calling seteuid)
+"""
 if os.geteuid() == 0:
     print "Please run this program as non-root"
     sys.exit(1)
@@ -20,7 +25,22 @@ def printUsage():
     print "     -u port (default: source) "
     print "     -p password (default: hackme) "
     print "     -m mount (default: test) "
+        
+def find_liquidsoap_binary():
+    """
+    Starting with Airtime 2.0, we don't know the exact location of the Liquidsoap
+    binary because it may have been installed through a debian package. Let's find
+    the location of this binary.
+    """
+    
+    rv = subprocess.call("which liquidsoap > /dev/null", shell=True)
+    if rv == 0:
+        return "liquidsoap"
+    else:
+        if os.path.exists("/usr/lib/airtime/pypo/bin/liquidsoap_bin/liquidsoap"):
+            return "/usr/lib/airtime/pypo/bin/liquidsoap_bin/liquidsoap"
 
+    return None
 
 optlist, args = getopt.getopt(sys.argv[1:], 'hvo:H:P:u:p:')
 stream_types = set(["shoutcast", "icecast"])
@@ -60,21 +80,39 @@ for o, a in optlist:
 
 try:
     
+    print "Protocol: %s " % stream_type
+    print "Host: %s" % host
+    print "Port: %s" % port
+    print "User: %s" % user
+    print "Password: %s" % password
+    print "Mount: %s\n" % mount
+    
     url = "http://%s:%s/%s" % (host, port, mount)
-    print "Outputting to %s streaming server. You should be able to hear a monotonous tone on %s. Press ctrl-c to quit." % (stream_type, url)
+    print "Outputting to %s streaming server. You should be able to hear a monotonous tone on '%s'. Press ctrl-c to quit." % (stream_type, url)
+    
+    liquidsoap_exe = find_liquidsoap_binary()
+    
+    if liquidsoap_exe is None:
+        raise Exception("Liquidsoap not found!")
         
     if stream_type == "icecast":
-        command = "liquidsoap 'output.icecast(%%vorbis, host = \"%s\", port = %s, user= \"%s\", password = \"%s\", mount=\"%s\", sine())'" % (host, port, user, password, mount)
+        command = "%s 'output.icecast(%%vorbis, host = \"%s\", port = %s, user= \"%s\", password = \"%s\", mount=\"%s\", sine())'" % (liquidsoap_exe, host, port, user, password, mount)
     else:
-        command = "liquidsoap 'output.shoutcast(%%mp3, host=\"%s\", port = %s, user= \"%s\", password = \"%s\", mount=\"%s\",  sine())'" % (host, port, user, password, mount)
+        command = "%s 'output.shoutcast(%%mp3, host=\"%s\", port = %s, user= \"%s\", password = \"%s\", mount=\"%s\",  sine())'" % (liquidsoap_exe, host, port, user, password, mount)
         
     if not verbose:
-        command += " > /dev/null"
+        command += " 2>/dev/null | grep \"failed\""
     
     #print command
     rv = subprocess.call(command, shell=True)
     
+    #if we reach this point, it means that our subprocess exited without the user
+    #doing a keyboard interrupt. This means there was a problem outputting to the 
+    #stream server. Print appropriate message.
+    print "There was an error with your stream configuration. Please review your configuration " + \
+        "and run this program again. Use the -h option for help"
+    
 except KeyboardInterrupt, ki:
-    print "Exiting"
+    print "\nExiting"
 except Exception, e:
     raise