diff --git a/python_apps/media-monitor/MediaMonitor.py b/python_apps/media-monitor/MediaMonitor.py index 172af7f6a..cd56ff707 100644 --- a/python_apps/media-monitor/MediaMonitor.py +++ b/python_apps/media-monitor/MediaMonitor.py @@ -3,6 +3,7 @@ import time import logging import logging.config import sys +import os import signal from multiprocessing import Process @@ -10,13 +11,14 @@ from multiprocessing import Process from airtimefilemonitor.airtimenotifier import AirtimeNotifier from airtimefilemonitor.airtimeprocessevent import AirtimeProcessEvent from airtimefilemonitor.mediaconfig import AirtimeMediaConfig +from airtimefilemonitor.airtimemediamonitorbootstrap import AirtimeMediaMonitorBootstrap def handleSigTERM(signum, frame): logger = logging.getLogger() - logger.info("Main Process Shutdown, TERM signal caught. %d") + logger.info("Main Process Shutdown, TERM signal caught.") for p in processes: - p.terminate() logger.info("Killed process. %d", p.pid) + p.terminate() sys.exit(0) @@ -26,13 +28,17 @@ try: logging.config.fileConfig("logging.cfg") except Exception, e: print 'Error configuring logging: ', e - sys.exit() + sys.exit(1) logger = logging.getLogger() processes = [] try: - config = AirtimeMediaConfig() + config = AirtimeMediaConfig(logger) + + bootstrap = AirtimeMediaMonitorBootstrap(logger) + bootstrap.scan() + logger.info("Initializing event processor") pe = AirtimeProcessEvent(airtime_config=config) @@ -45,8 +51,6 @@ try: processes.append(p) p.start() - signal.signal(signal.SIGTERM, handleSigTERM) - logger.info("Setting up monitor") response = None while response is None: @@ -61,14 +65,16 @@ try: logger.info("Added watch to %s", storage_directory) logger.info("wdd result %s", wdd[storage_directory]) + + #register signal before process forks and exits. + signal.signal(signal.SIGTERM, handleSigTERM) notifier.loop(callback=pe.notifier_loop_callback) - for p in processes: - p.join() + except KeyboardInterrupt: notifier.stop() + logger.info("Keyboard Interrupt") except Exception, e: - notifier.stop() + #notifier.stop() logger.error('Exception: %s', e) - diff --git a/python_apps/media-monitor/airtime-media-monitor-init-d b/python_apps/media-monitor/airtime-media-monitor-init-d index 8bf311161..38dc92895 100755 --- a/python_apps/media-monitor/airtime-media-monitor-init-d +++ b/python_apps/media-monitor/airtime-media-monitor-init-d @@ -17,13 +17,13 @@ DAEMON=/usr/lib/airtime/media-monitor/airtime-media-monitor PIDFILE=/var/run/airtime-media-monitor.pid start () { - monit monitor airtime-media-monitor >/dev/null 2>&1 + #monit monitor airtime-media-monitor >/dev/null 2>&1 start-stop-daemon --start --background --quiet --chuid $USERID:$GROUPID --make-pidfile --pidfile $PIDFILE --startas $DAEMON } stop () { # Send TERM after 5 seconds, wait at most 30 seconds. - monit unmonitor airtime-media-monitor >/dev/null 2>&1 + #monit unmonitor airtime-media-monitor >/dev/null 2>&1 start-stop-daemon --stop --oknodo --retry TERM/5/0/30 --quiet --pidfile $PIDFILE rm -f $PIDFILE } diff --git a/python_apps/media-monitor/airtimefilemonitor/airtimemediamonitorbootstrap.py b/python_apps/media-monitor/airtimefilemonitor/airtimemediamonitorbootstrap.py new file mode 100644 index 000000000..96399a006 --- /dev/null +++ b/python_apps/media-monitor/airtimefilemonitor/airtimemediamonitorbootstrap.py @@ -0,0 +1,74 @@ +import os + +from subprocess import Popen, PIPE + + +class AirtimeMediaMonitorBootstrap(): + + def __init__(self, logger): + self.logger = logger + + """ + on bootup we want to scan all directories and look for files that + weren't there or files that changed before media-monitor process + went offline. We can do this by doing a hash of the directory metadata. + """ + def scan(self): + directories = ['/srv/airtime/stor'] + + for dir in directories: + self.check_for_diff(dir) + + def check_for_diff(self, dir): + airtime_tmp = '/var/tmp/airtime' + + if os.path.exists(airtime_tmp + '/.airtime_media_index'): + #a previous index exists, we can do a diff between this + #file and the current state to see whether anything has + #changed. + self.logger.info("Previous index file found.") + + + #find files that have been modified since the last time + #media-monitor process was running. + command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable -mmin -30" % dir + stdout = self.execCommandAndReturnStdOut(command) + self.logger.info("Files modified since last checkin: \n%s\n", stdout) + + + #find deleted files + command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable > %s/.airtime_media_index.tmp" % (dir, airtime_tmp) + self.execCommand(command) + + command = "diff %s/.airtime_media_index.tmp %s/.airtime_media_index" % (airtime_tmp, airtime_tmp) + stdout = self.execCommandAndReturnStdOut(command) + self.logger.info("Deleted files since last checkin:\n%s\n", stdout) + + else: + #a previous index does not exist. Most likely means that + #media monitor has never seen this directory before. Let's + #notify airtime server about each of these files + self.logger.info("Previous index file does not exist. Creating a new one") + + #create a new index file. + command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable > %s/.airtime_media_index" % (dir, airtime_tmp) + self.execCommand(command) + + def execCommand(self, command): + p = Popen(command, shell=True) + sts = os.waitpid(p.pid, 0)[1] + if sts != 0: + self.logger.warn("command \n%s\n return with a non-zero return value", command) + + def execCommandAndReturnStdOut(self, command): + p = Popen(command, shell=True, stdout=PIPE) + stdout = p.communicate()[0] + if p.returncode != 0: + self.logger.warn("command \n%s\n return with a non-zero return value", command) + return stdout + + +if __name__ == '__main__': + + mmb = AirtimeMediaMonitorBootstrap() + mmb.scan() \ No newline at end of file diff --git a/python_apps/media-monitor/airtimefilemonitor/mediaconfig.py b/python_apps/media-monitor/airtimefilemonitor/mediaconfig.py index d1a4e04ae..2b1197e24 100644 --- a/python_apps/media-monitor/airtimefilemonitor/mediaconfig.py +++ b/python_apps/media-monitor/airtimefilemonitor/mediaconfig.py @@ -9,14 +9,14 @@ class AirtimeMediaConfig: MODE_MOVED = "moved" MODE_DELETE = "delete" - def __init__(self): + def __init__(self, logger): # loading config file try: config = ConfigObj('/etc/airtime/media-monitor.cfg') self.cfg = config except Exception, e: - print 'Error loading config: ', e + logger.info('Error loading config: ', e) sys.exit() self.storage_directory = None diff --git a/python_apps/monit/airtime-monit.cfg b/python_apps/monit/airtime-monit.cfg index 647fffd10..22f05e2ca 100644 --- a/python_apps/monit/airtime-monit.cfg +++ b/python_apps/monit/airtime-monit.cfg @@ -13,10 +13,10 @@ with pidfile "/var/run/airtime-liquidsoap.pid" start program = "/etc/init.d/airtime-playout start" with timeout 10 seconds stop program = "/etc/init.d/airtime-playout stop" - check process airtime-media-monitor - with pidfile "/var/run/airtime-media-monitor.pid" - start program = "/etc/init.d/airtime-media-monitor start" with timeout 10 seconds - stop program = "/etc/init.d/airtime-media-monitor stop" +# check process airtime-media-monitor +# with pidfile "/var/run/airtime-media-monitor.pid" +# start program = "/etc/init.d/airtime-media-monitor start" with timeout 10 seconds +# stop program = "/etc/init.d/airtime-media-monitor stop" check process airtime-show-recorder with pidfile "/var/run/airtime-show-recorder.pid" start program = "/etc/init.d/airtime-show-recorder start" with timeout 10 seconds