From c5ce86bd407d09cac559738090ba4232c5158b4e Mon Sep 17 00:00:00 2001 From: Naomi Date: Mon, 25 Apr 2011 12:49:01 -0400 Subject: [PATCH] CC-1799 : Live Studio Playout from media library (pytagsfs) set up daemontools process for the media monitor script. --- .../application/controllers/ApiController.php | 13 ++ install/airtime-install.php | 3 + install/airtime-uninstall.php | 4 + install/include/AirtimeIni.php | 13 +- python_apps/api_clients/api_client.py | 21 +++ python_apps/pytag-fs/MediaMonitor.cfg | 8 +- python_apps/pytag-fs/MediaMonitor.py | 18 ++- .../pytag-fs/airtime-media-monitor-start | 16 +++ .../pytag-fs/airtime-media-monitor-stop | 27 ++++ .../media-monitor-daemontools-logger.sh | 2 + .../install/media-monitor-daemontools.sh | 16 +++ .../pytag-fs/install/media-monitor-install.py | 125 ++++++++++++++++++ .../install/media-monitor-uninstall.py | 58 ++++++++ 13 files changed, 315 insertions(+), 9 deletions(-) create mode 100755 python_apps/pytag-fs/airtime-media-monitor-start create mode 100755 python_apps/pytag-fs/airtime-media-monitor-stop create mode 100755 python_apps/pytag-fs/install/media-monitor-daemontools-logger.sh create mode 100755 python_apps/pytag-fs/install/media-monitor-daemontools.sh create mode 100755 python_apps/pytag-fs/install/media-monitor-install.py create mode 100755 python_apps/pytag-fs/install/media-monitor-uninstall.py diff --git a/airtime_mvc/application/controllers/ApiController.php b/airtime_mvc/application/controllers/ApiController.php index 7bd4397ee..7e0597214 100644 --- a/airtime_mvc/application/controllers/ApiController.php +++ b/airtime_mvc/application/controllers/ApiController.php @@ -316,5 +316,18 @@ class ApiController extends Zend_Controller_Action $this->view->id = $file->getId(); } + + public function reloadMetadataAction() { + + global $CC_CONFIG; + + $api_key = $this->_getParam('api_key'); + if (!in_array($api_key, $CC_CONFIG["apiKey"])) + { + header('HTTP/1.0 401 Unauthorized'); + print 'You are not allowed to access this resource.'; + exit; + } + } } diff --git a/install/airtime-install.php b/install/airtime-install.php index 51ff49f81..2349b2fa7 100644 --- a/install/airtime-install.php +++ b/install/airtime-install.php @@ -98,6 +98,9 @@ system("python ".__DIR__."/../python_apps/pypo/install/pypo-install.py"); echo PHP_EOL."*** Recorder Installation ***".PHP_EOL; system("python ".__DIR__."/../python_apps/show-recorder/install/recorder-install.py"); +echo PHP_EOL."*** Media Monitor Installation ***".PHP_EOL; +system("python ".__DIR__."/../python_apps/pytag-fs/install/media-monitor-install.py"); + AirtimeInstall::SetAirtimeVersion(AIRTIME_VERSION); echo "******************************* Install Complete *******************************".PHP_EOL; diff --git a/install/airtime-uninstall.php b/install/airtime-uninstall.php index 3da55df11..7513c874a 100644 --- a/install/airtime-uninstall.php +++ b/install/airtime-uninstall.php @@ -85,6 +85,10 @@ echo PHP_EOL."*** Uninstalling Show Recorder ***".PHP_EOL; $command = "python ".__DIR__."/../python_apps/show-recorder/install/recorder-uninstall.py"; system($command); +echo PHP_EOL."*** Uninstalling Media Monitor ***".PHP_EOL; +$command = "python ".__DIR__."/../python_apps/pytag-fs/install/media-monitor-uninstall.py"; +system($command); + #Disabled as this should be a manual process #AirtimeIni::RemoveIniFiles(); diff --git a/install/include/AirtimeIni.php b/install/include/AirtimeIni.php index 930b6260d..70c059af2 100644 --- a/install/include/AirtimeIni.php +++ b/install/include/AirtimeIni.php @@ -26,13 +26,15 @@ class AirtimeIni const CONF_FILE_PYPO = "/etc/airtime/pypo.cfg"; const CONF_FILE_RECORDER = "/etc/airtime/recorder.cfg"; const CONF_FILE_LIQUIDSOAP = "/etc/airtime/liquidsoap.cfg"; + const CONF_FILE_MEDIAMONITOR = "/etc/airtime/MediaMonitor.cfg"; public static function IniFilesExist() { $configFiles = array(AirtimeIni::CONF_FILE_AIRTIME, AirtimeIni::CONF_FILE_PYPO, AirtimeIni::CONF_FILE_RECORDER, - AirtimeIni::CONF_FILE_LIQUIDSOAP); + AirtimeIni::CONF_FILE_LIQUIDSOAP, + AirtimeIni::CONF_FILE_MEDIAMONITOR); $exist = false; foreach ($configFiles as $conf) { if (file_exists($conf)) { @@ -72,6 +74,10 @@ class AirtimeIni echo "Could not copy liquidsoap.cfg to /etc/airtime/. Exiting."; exit(1); } + if (!copy(__DIR__."/../../python_apps/pytag-fs/MediaMonitor.cfg", AirtimeIni::CONF_FILE_MEDIAMONITOR)){ + echo "Could not copy MediaMonitor.cfg to /etc/airtime/. Exiting."; + exit(1); + } } /** @@ -96,6 +102,10 @@ class AirtimeIni unlink(AirtimeIni::CONF_FILE_LIQUIDSOAP); } + if (file_exists(AirtimeIni::CONF_FILE_MEDIAMONITOR)){ + unlink(AirtimeIni::CONF_FILE_MEDIAMONITOR); + } + if (file_exists("etc/airtime")){ rmdir("/etc/airtime/"); } @@ -171,6 +181,7 @@ class AirtimeIni AirtimeIni::UpdateIniValue(AirtimeIni::CONF_FILE_AIRTIME, 'airtime_dir', AirtimeInstall::CONF_DIR_WWW); AirtimeIni::UpdateIniValue(AirtimeIni::CONF_FILE_PYPO, 'api_key', "'$api_key'"); AirtimeIni::UpdateIniValue(AirtimeIni::CONF_FILE_RECORDER, 'api_key', "'$api_key'"); + AirtimeIni::UpdateIniValue(AirtimeIni::CONF_FILE_MEDIAMONITOR, 'api_key', "'$api_key'"); AirtimeIni::UpdateIniValue(AirtimeInstall::CONF_DIR_WWW.'/build/build.properties', 'project.home', AirtimeInstall::CONF_DIR_WWW); } } diff --git a/python_apps/api_clients/api_client.py b/python_apps/api_clients/api_client.py index f551ebc5f..197e67aae 100644 --- a/python_apps/api_clients/api_client.py +++ b/python_apps/api_clients/api_client.py @@ -97,6 +97,9 @@ class ApiClientInterface: def upload_recorded_show(self): pass + + def update_media_metadata(self): + pass # Put here whatever tests you want to run to make sure your API is working def test(self): @@ -346,6 +349,24 @@ class AirTimeApiClient(ApiClientInterface): time.sleep(retries_wait) return response + + def update_media_metadata(self): + logger = logging.getLogger() + response = None + try: + url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["show_schedule_url"]) + #url = self.config["base_url"] + self.config["api_base"] + self.config["show_schedule_url"] + logger.debug(url) + url = url.replace("%%api_key%%", self.config["api_key"]) + + response = urllib.urlopen(url) + response = json.loads(response.read()) + logger.info("shows %s", response) + + except Exception, e: + logger.error("Exception: %s", e) + + return response diff --git a/python_apps/pytag-fs/MediaMonitor.cfg b/python_apps/pytag-fs/MediaMonitor.cfg index e4610b720..d32a6d4b1 100644 --- a/python_apps/pytag-fs/MediaMonitor.cfg +++ b/python_apps/pytag-fs/MediaMonitor.cfg @@ -7,11 +7,8 @@ base_port = 80 # where the binary files live bin_dir = '/usr/lib/airtime/media-monitor' -# base path to store recordered shows at -base_recorded_files = '/var/tmp/airtime/show-recorder/' - # where the logging files live -log_dir = '/var/log/airtime/show-recorder' +log_dir = '/var/log/airtime/media-monitor' # Value needed to access the API api_key = 'AAA' @@ -24,6 +21,3 @@ version_url = 'version/api_key/%%api_key%%' # URL to get the schedule of shows set to record show_schedule_url = 'recorded-shows/format/json/api_key/%%api_key%%' - -# URL to upload the recorded show's file to Airtime -upload_file_url = 'upload-recorded/format/json/api_key/%%api_key%%' diff --git a/python_apps/pytag-fs/MediaMonitor.py b/python_apps/pytag-fs/MediaMonitor.py index 2bdf148aa..c84cc3abf 100644 --- a/python_apps/pytag-fs/MediaMonitor.py +++ b/python_apps/pytag-fs/MediaMonitor.py @@ -1,7 +1,21 @@ +#!/usr/local/bin/python +import urllib +import urllib2 +import logging +import logging.config +import json +import time +import datetime import os +import sys + +from configobj import ConfigObj + import pyinotify from pyinotify import WatchManager, Notifier, ThreadedNotifier, EventsCodes, ProcessEvent +from api_clients import api_client + # configure logging try: logging.config.fileConfig("logging.cfg") @@ -11,7 +25,7 @@ except Exception, e: # loading config file try: - config = ConfigObj('/etc/airtime/recorder.cfg') + config = ConfigObj('/etc/airtime/MediaMonitor.cfg') except Exception, e: print 'Error loading config file: ', e sys.exit() @@ -42,6 +56,8 @@ class PTmp(ProcessEvent): if __name__ == '__main__': + print 'Media Monitor' + try: notifier = Notifier(wm, PTmp(), read_freq=2, timeout=1) notifier.coalesce_events() diff --git a/python_apps/pytag-fs/airtime-media-monitor-start b/python_apps/pytag-fs/airtime-media-monitor-start new file mode 100755 index 000000000..084b2b1ad --- /dev/null +++ b/python_apps/pytag-fs/airtime-media-monitor-start @@ -0,0 +1,16 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import sys + +if os.geteuid() != 0: + print "Please run this as root." + sys.exit(1) + +try: + print "Starting daemontool script recorder" + os.system("svc -u /etc/service/recorder") + +except Exception, e: + print "exception:" + str(e) diff --git a/python_apps/pytag-fs/airtime-media-monitor-stop b/python_apps/pytag-fs/airtime-media-monitor-stop new file mode 100755 index 000000000..b51b1ba6a --- /dev/null +++ b/python_apps/pytag-fs/airtime-media-monitor-stop @@ -0,0 +1,27 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import sys +import subprocess + +if os.geteuid() != 0: + print "Please run this as root." + sys.exit(1) + +try: + print "Stopping daemontool script recorder" + + p1 = subprocess.Popen(["ps", "aux"], stdout=subprocess.PIPE) + p2 = subprocess.Popen(["awk", "/recorder.py/ && !/awk/ {print $2}"], stdin=p1.stdout, stdout=subprocess.PIPE) + recorder_pid = p2.communicate()[0].strip(" \n\r\t") + if (len(recorder_pid) > 0): + os.system("svc -d /etc/service/recorder 1>/dev/null 2>&1") + os.system("svc -d /etc/service/recorder/log 1>/dev/null 2>&1") + os.system("kill -2 %s" % recorder_pid) + print "Success." + else: + print "Not Running." + +except Exception, e: + print "exception:" + str(e) diff --git a/python_apps/pytag-fs/install/media-monitor-daemontools-logger.sh b/python_apps/pytag-fs/install/media-monitor-daemontools-logger.sh new file mode 100755 index 000000000..6819f837d --- /dev/null +++ b/python_apps/pytag-fs/install/media-monitor-daemontools-logger.sh @@ -0,0 +1,2 @@ +#!/bin/sh +exec setuidgid pypo multilog t /var/log/airtime/media-monitor/main diff --git a/python_apps/pytag-fs/install/media-monitor-daemontools.sh b/python_apps/pytag-fs/install/media-monitor-daemontools.sh new file mode 100755 index 000000000..0f6fa39e7 --- /dev/null +++ b/python_apps/pytag-fs/install/media-monitor-daemontools.sh @@ -0,0 +1,16 @@ +#!/bin/sh +media_monitor_user="pypo" + +# Location of pypo_cli.py Python script +media_monitor_path="/usr/lib/airtime/media-monitor/" +media_monitor_script="MediaMonitor.py" + +api_client_path="/usr/lib/airtime/pypo/" +cd ${media_monitor_path} + +echo "*** Daemontools: starting daemon" +exec 2>&1 +# Note the -u when calling python! we need it to get unbuffered binary stdout and stderr + +sudo PYTHONPATH=${api_client_path} -u ${media_monitor_user} python -u ${media_monitor_path}${media_monitor_script} +# EOF diff --git a/python_apps/pytag-fs/install/media-monitor-install.py b/python_apps/pytag-fs/install/media-monitor-install.py new file mode 100755 index 000000000..f0bb2adc0 --- /dev/null +++ b/python_apps/pytag-fs/install/media-monitor-install.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import time +import os +import traceback +from optparse import * +import sys +import time +import datetime +import logging +import logging.config +import shutil +import string +import platform +from configobj import ConfigObj +from subprocess import Popen, PIPE, STDOUT + +if os.geteuid() != 0: + print "Please run this as root." + sys.exit(1) + +PATH_INI_FILE = '/etc/airtime/MediaMonitor.cfg' + +def create_path(path): + if not (os.path.exists(path)): + print "Creating directory " + path + os.makedirs(path) + +def create_user(username): + print "Checking for user "+username + p = Popen('id '+username, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) + output = p.stdout.read() + if (output[0:3] != "uid"): + # Make the pypo user + print "Creating user "+username + os.system("adduser --system --quiet --group --shell /bin/bash "+username) + + #set pypo password + p = os.popen('/usr/bin/passwd pypo 1>/dev/null 2>&1', 'w') + p.write('pypo\n') + p.write('pypo\n') + p.close() + else: + print "User already exists." + #add pypo to audio group + os.system("adduser " + username + " audio 1>/dev/null 2>&1") + +def copy_dir(src_dir, dest_dir): + if (os.path.exists(dest_dir)) and (dest_dir != "/"): + print "Removing old directory "+dest_dir + shutil.rmtree(dest_dir) + if not (os.path.exists(dest_dir)): + print "Copying directory "+os.path.realpath(src_dir)+" to "+os.path.realpath(dest_dir) + shutil.copytree(src_dir, dest_dir) + +def get_current_script_dir(): + current_script_dir = os.path.realpath(__file__) + index = current_script_dir.rindex('/') + #print current_script_dir[0:index] + return current_script_dir[0:index] + + +try: + # load config file + try: + config = ConfigObj(PATH_INI_FILE) + except Exception, e: + print 'Error loading config file: ', e + sys.exit() + + current_script_dir = get_current_script_dir() + print "Checking and removing any existing media monitor processes" + os.system("python %s/media-monitor-uninstall.py 1>/dev/null 2>&1"% current_script_dir) + time.sleep(5) + + # Create users + create_user("pypo") + + print "Creating log directories" + create_path(config["log_dir"]) + os.system("chmod -R 755 " + config["log_dir"]) + os.system("chown -R pypo:pypo "+config["log_dir"]) + + copy_dir("%s/.."%current_script_dir, config["bin_dir"]) + + print "Setting permissions" + os.system("chmod -R 755 "+config["bin_dir"]) + os.system("chown -R pypo:pypo "+config["bin_dir"]) + + print "Creating symbolic links" + os.system("rm -f /usr/bin/airtime-media-monitor-start") + os.system("ln -s "+config["bin_dir"]+"/airtime-media-monitor-start /usr/bin/") + os.system("rm -f /usr/bin/airtime-media-monitor-stop") + os.system("ln -s "+config["bin_dir"]+"/airtime-media-monitor-stop /usr/bin/") + + print "Installing recorder daemon" + create_path("/etc/service/media-monitor") + create_path("/etc/service/media-monitor/log") + shutil.copy("%s/media-monitor-daemontools.sh"%current_script_dir, "/etc/service/media-monitor/run") + shutil.copy("%s/media-monitor-daemontools-logger.sh"%current_script_dir, "/etc/service/media-monitor/log/run") + os.system("chmod -R 755 /etc/service/media-monitor") + os.system("chown -R pypo:pypo /etc/service/media-monitor") + + print "Waiting for processes to start..." + time.sleep(5) + os.system("python /usr/bin/airtime-media-monitor-start") + time.sleep(2) + + found = True + + p = Popen('svstat /etc/service/media-monitor', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) + output = p.stdout.read() + if (output.find("unable to open supervise/ok: file does not exist") >= 0): + found = False + print output + + if not found: + print "Media monitor install has completed, but daemontools is not running, please make sure you have it installed and then reboot." +except Exception, e: + print "exception:" + str(e) + sys.exit(1) + + + diff --git a/python_apps/pytag-fs/install/media-monitor-uninstall.py b/python_apps/pytag-fs/install/media-monitor-uninstall.py new file mode 100755 index 000000000..e0a5ca262 --- /dev/null +++ b/python_apps/pytag-fs/install/media-monitor-uninstall.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import sys +import time +from configobj import ConfigObj + +if os.geteuid() != 0: + print "Please run this as root." + sys.exit(1) + +PATH_INI_FILE = '/etc/airtime/MediaMonitor.cfg' + +def remove_path(path): + os.system("rm -rf " + path) + +def remove_user(username): + os.system("killall -u %s 1>/dev/null 2>&1" % username) + + #allow all process to be completely closed before we attempt to delete user + print "Waiting for processes to close..." + time.sleep(5) + + os.system("deluser --remove-home " + username + " 1>/dev/null 2>&1") + +def get_current_script_dir(): + current_script_dir = os.path.realpath(__file__) + index = current_script_dir.rindex('/') + return current_script_dir[0:index] + +try: + # load config file + try: + config = ConfigObj(PATH_INI_FILE) + except Exception, e: + print 'Error loading config file: ', e + sys.exit() + + os.system("python /usr/bin/airtime-media-monitor-stop") + + print "Removing log directories" + remove_path(config["log_dir"]) + + print "Removing symlinks" + os.system("rm -f /usr/bin/airtime-media-monitor-start") + os.system("rm -f /usr/bin/airtime-media-monitor-stop") + + print "Removing application files" + remove_path(config["bin_dir"]) + + print "Removing daemontool script media-monitor" + remove_path("rm -rf /etc/service/media-monitor") + + remove_user("pypo") + print "Uninstall complete." +except Exception, e: + print "exception:" + str(e)