Merge branch '1.9.1' into devel

Conflicts:
	VERSION
	airtime_mvc/application/configs/constants.php
	airtime_mvc/application/controllers/ScheduleController.php
	install_minimal/airtime-install
	install_minimal/include/AirtimeInstall.php
	install_minimal/include/airtime-upgrade.php
	python_apps/api_clients/api_client.py
	python_apps/pypo/pypofetch.py
	python_apps/pypo/pypopush.py
This commit is contained in:
martin 2011-09-09 15:07:43 -04:00
commit 9c7bab616d
50 changed files with 205 additions and 125 deletions

0
python_apps/api_clients/api_client.py Normal file → Executable file
View file

View file

@ -1,4 +1,3 @@
#!/usr/local/bin/python
import time
import logging
import logging.config

View file

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
# Location of pypo_cli.py Python script

View file

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

View file

@ -2,14 +2,9 @@ import socket
import logging
import time
import pyinotify
from pyinotify import ProcessEvent
# For RabbitMQ
from kombu.connection import BrokerConnection
from kombu.messaging import Exchange, Queue, Consumer, Producer
from airtimemetadata import AirtimeMetadata
from airtimefilemonitor.mediaconfig import AirtimeMediaConfig
@ -186,8 +181,10 @@ class AirtimeProcessEvent(ProcessEvent):
self.mmc.touch_index_file()
self.file_events = []
#yeild to workder thread
#yield to worker thread
time.sleep(0)
#use items() because we are going to be modifying this
#dictionary while iterating over it.
for k, pair in self.cookies_IN_MOVED_FROM.items():
@ -206,7 +203,7 @@ class AirtimeProcessEvent(ProcessEvent):
self.handle_removed_file(False, event.pathname)
#check for any events recieved from Airtime.
#check for any events received from Airtime.
try:
notifier.connection.drain_events(timeout=0.1)
#avoid logging a bunch of timeout messages.
@ -214,4 +211,5 @@ class AirtimeProcessEvent(ProcessEvent):
pass
except Exception, e:
self.logger.info("%s", e)
time.sleep(3)

View file

View file

View file

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/"
. ${virtualenv_bin}activate

View file

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/"
. ${virtualenv_bin}activate

0
python_apps/pypo/install/pypo-install.py Executable file → Normal file
View file

0
python_apps/pypo/install/pypo-uninstall.py Executable file → Normal file
View file

View file

View file

View file

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
############################################
# just a wrapper to call the notifyer #
# needed here to keep dirs/configs clean #

0
python_apps/pypo/pypo-cli.py Executable file → Normal file
View file

0
python_apps/pypo/pypo-notify.py Executable file → Normal file
View file

42
python_apps/pypo/pypofetch.py Executable file → Normal file
View file

@ -10,6 +10,7 @@ import string
import json
import telnetlib
import math
import socket
from threading import Thread
from subprocess import Popen, PIPE
from datetime import datetime
@ -251,7 +252,7 @@ class PypoFetch(Thread):
scheduled_data = dict()
scheduled_data['liquidsoap_playlists'] = liquidsoap_playlists
scheduled_data['schedule'] = playlists
scheduled_data['stream_metadata'] = schedule_data["stream_metadata"]
scheduled_data['stream_metadata'] = schedule_data["stream_metadata"]
self.queue.put(scheduled_data)
# cleanup
@ -425,12 +426,7 @@ class PypoFetch(Thread):
logger.error(e)
"""
Main loop of the thread:
Wait for schedule updates from RabbitMQ, but in case there arent any,
poll the server to get the upcoming schedule.
"""
def run(self):
def main(self):
logger = logging.getLogger('fetch')
while not self.init_rabbit_mq():
@ -455,11 +451,33 @@ class PypoFetch(Thread):
# Wait for messages from RabbitMQ. Timeout if we
# dont get any after POLL_INTERVAL.
self.connection.drain_events(timeout=POLL_INTERVAL)
except Exception, e:
# Hooray for globals!
schedule_data = SCHEDULE_PUSH_MSG
status = 1
except socket.timeout, se:
# We didnt get a message for a while, so poll the server
# to get an updated schedule.
logger.info("Exception %s", e)
status, self.schedule_data = self.api_client.get_schedule()
self.process_schedule(self.schedule_data, "scheduler", False)
loops += 1
status, schedule_data = self.api_client.get_schedule()
except Exception, e:
"""
This Generic exception is thrown whenever the RabbitMQ
Service is stopped. In this case let's check every few
seconds to see if it has come back up
"""
logger.info("Unknown exception")
return
#return based on the exception
if status == 1:
self.process_schedule(schedule_data, "scheduler", False)
loops += 1
"""
Main loop of the thread:
Wait for schedule updates from RabbitMQ, but in case there arent any,
poll the server to get the upcoming schedule.
"""
def run(self):
while True:
self.main()

53
python_apps/pypo/pypopush.py Executable file → Normal file
View file

@ -41,13 +41,7 @@ class PypoPush(Thread):
self.playlists = dict()
self.stream_metadata = dict()
"""
push_ahead2 MUST be < push_ahead. The difference in these two values
gives the number of seconds of the window of opportunity for the scheduler
to catch when a playlist is to be played.
"""
self.push_ahead = 10
self.push_ahead2 = self.push_ahead -5
def set_export_source(self, export_source):
self.export_source = export_source
@ -77,22 +71,16 @@ class PypoPush(Thread):
playlists = self.playlists
if schedule:
playedItems = self.load_schedule_tracker()
timenow = time.time()
tcoming = time.gmtime(timenow + self.push_ahead)
str_tcoming_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcoming[0], tcoming[1], tcoming[2], tcoming[3], tcoming[4], tcoming[5])
tcoming2 = time.gmtime(timenow + self.push_ahead2)
str_tcoming2_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcoming2[0], tcoming2[1], tcoming2[2], tcoming2[3], tcoming2[4], tcoming2[5])
tnow = time.gmtime(timenow)
tcoming = time.gmtime(timenow + self.push_ahead)
str_tnow_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tnow[0], tnow[1], tnow[2], tnow[3], tnow[4], tnow[5])
str_tcoming_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcoming[0], tcoming[1], tcoming[2], tcoming[3], tcoming[4], tcoming[5])
for pkey in schedule:
plstart = schedule[pkey]['start'][0:19]
if plstart == str_tcoming_s or (plstart < str_tcoming_s and plstart > str_tcoming2_s):
if str_tnow_s <= plstart and plstart < str_tcoming_s:
logger.debug('Preparing to push playlist scheduled at: %s', pkey)
playlist = schedule[pkey]
@ -100,14 +88,6 @@ class PypoPush(Thread):
# force liquidsoap to refresh.
if (self.push_liquidsoap(pkey, schedule, playlists) == 1):
logger.debug("Pushed to liquidsoap, updating 'played' status.")
# Marked the current playlist as 'played' in the schedule tracker
# so it is not called again in the next push loop.
# Write changes back to tracker file.
playedItems[pkey] = playlist
playedItems[pkey]['played'] = 1
schedule_tracker = open(self.schedule_tracker_file, "w")
pickle.dump(playedItems, schedule_tracker)
schedule_tracker.close()
# Call API to update schedule states
logger.debug("Doing callback to server to update 'played' status.")
@ -115,8 +95,6 @@ class PypoPush(Thread):
show_start = schedule[pkey]['show_start']
show_end = schedule[pkey]['show_end']
else:
pass
def push_liquidsoap(self, pkey, schedule, playlists):
logger = logging.getLogger('push')
@ -172,29 +150,6 @@ class PypoPush(Thread):
status = 0
return status
def load_schedule_tracker(self):
logger = logging.getLogger('push')
playedItems = dict()
# create the file if it doesnt exist
if (not os.path.exists(self.schedule_tracker_file)):
try:
logger.debug('creating file ' + self.schedule_tracker_file)
schedule_tracker = open(self.schedule_tracker_file, 'w')
pickle.dump(playedItems, schedule_tracker)
schedule_tracker.close()
except Exception, e:
logger.error('Error creating schedule tracker file: %s', e)
else:
try:
schedule_tracker = open(self.schedule_tracker_file, "r")
playedItems = pickle.load(schedule_tracker)
schedule_tracker.close()
except Exception, e:
logger.error('Unable to load schedule tracker file: %s', e)
return playedItems
def run(self):
loops = 0
heartbeat_period = math.floor(30/PUSH_INTERVAL)

0
python_apps/pypo/test/pypo-api-validator.py Executable file → Normal file
View file

0
python_apps/pypo/util/__init__.py Executable file → Normal file
View file

0
python_apps/pypo/util/status.py Executable file → Normal file
View file

0
python_apps/python-virtualenv/3rd_party/setuptools-0.6c11-py2.6.egg vendored Normal file → Executable file
View file

View file

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/"
. ${virtualenv_bin}activate

0
python_apps/show-recorder/install/recorder-install.py Executable file → Normal file
View file

View file

View file

@ -1,4 +1,3 @@
#!/usr/local/bin/python
import urllib
import logging
import logging.config
@ -8,6 +7,7 @@ import datetime
import os
import sys
import shutil
import socket
from configobj import ConfigObj
@ -291,10 +291,12 @@ class CommandListener(Thread):
try:
# block until 5 seconds before the next show start
self.connection.drain_events(timeout=self.time_till_next_show)
except Exception, e:
self.logger.info(e)
except socket.timeout, s:
self.logger.info(s)
# start recording
self.start_record()
except Exception, e:
time.sleep(3)
loops += 1