2010-11-05 15:54:15 +01:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Python part of radio playout ( pypo )
2010-11-08 22:54:54 +01:00
The main functions are " fetch " ( . / pypo_cli . py - f ) and " push " ( . / pypo_cli . py - p )
2010-11-05 15:54:15 +01:00
"""
# python defaults (debian default)
import time
2011-03-03 06:22:28 +01:00
#import calendar
2011-01-17 20:36:52 +01:00
2011-03-03 06:22:28 +01:00
#import traceback
2010-11-05 15:54:15 +01:00
from optparse import *
import sys
2011-03-03 06:22:28 +01:00
#import datetime
2010-11-05 15:54:15 +01:00
import logging
import logging . config
2011-03-03 06:22:28 +01:00
#import shutil
#import urllib
#import urllib2
#import pickle
#import telnetlib
#import random
#import string
#import operator
#import inspect
from pypopush import PypoPush
from pypofetch import PypoFetch
2010-11-05 15:54:15 +01:00
# additional modules (should be checked)
from configobj import ConfigObj
# custom imports
2011-03-03 06:22:28 +01:00
from util import CueFile
from api_clients import api_client
2010-11-05 15:54:15 +01:00
2011-03-02 23:26:39 +01:00
PYPO_VERSION = ' 1.1 '
2010-11-05 15:54:15 +01:00
2010-11-08 22:54:54 +01:00
# Set up command-line options
2010-11-05 15:54:15 +01:00
parser = OptionParser ( )
2011-03-02 22:43:46 +01:00
# help screen / info
2010-11-05 15:54:15 +01:00
usage = " % prog [options] " + " - python playout system "
parser = OptionParser ( usage = usage )
2010-11-08 22:54:54 +01:00
# Options
parser . add_option ( " -v " , " --compat " , help = " Check compatibility with server API version " , default = False , action = " store_true " , dest = " check_compat " )
2010-11-19 00:00:13 +01:00
parser . add_option ( " -t " , " --test " , help = " Do a test to make sure everything is working properly. " , default = False , action = " store_true " , dest = " test " )
2010-11-30 00:34:22 +01:00
parser . add_option ( " -f " , " --fetch-scheduler " , help = " Fetch the schedule from server. This is a polling process that runs forever. " , default = False , action = " store_true " , dest = " fetch_scheduler " )
parser . add_option ( " -p " , " --push-scheduler " , help = " Push the schedule to Liquidsoap. This is a polling process that runs forever. " , default = False , action = " store_true " , dest = " push_scheduler " )
2010-11-05 15:54:15 +01:00
2010-11-08 22:54:54 +01:00
parser . add_option ( " -b " , " --cleanup " , help = " Cleanup " , default = False , action = " store_true " , dest = " cleanup " )
2010-11-05 15:54:15 +01:00
parser . add_option ( " -c " , " --check " , help = " Check the cached schedule and exit " , default = False , action = " store_true " , dest = " check " )
# parse options
( options , args ) = parser . parse_args ( )
# configure logging
logging . config . fileConfig ( " logging.cfg " )
# loading config file
try :
config = ConfigObj ( ' config.cfg ' )
POLL_INTERVAL = float ( config [ ' poll_interval ' ] )
2011-03-10 22:41:41 +01:00
PUSH_INTERVAL = float ( config [ ' push_interval ' ] )
2010-11-05 15:54:15 +01:00
LS_HOST = config [ ' ls_host ' ]
LS_PORT = config [ ' ls_port ' ]
except Exception , e :
2010-11-08 22:54:54 +01:00
print ' Error loading config file: ' , e
2010-11-05 15:54:15 +01:00
sys . exit ( )
2011-03-02 22:43:46 +01:00
2010-11-05 15:54:15 +01:00
class Global :
def __init__ ( self ) :
2011-03-02 23:26:39 +01:00
self . api_client = api_client . api_client_factory ( config )
self . cue_file = CueFile ( )
self . set_export_source ( ' scheduler ' )
2011-03-02 22:43:46 +01:00
def selfcheck ( self ) :
2010-11-08 22:54:54 +01:00
self . api_client = api_client . api_client_factory ( config )
2010-12-15 01:09:13 +01:00
if ( not self . api_client . is_server_compatible ( ) ) :
2010-12-22 00:28:17 +01:00
sys . exit ( )
2011-03-02 22:43:46 +01:00
2011-03-02 23:26:39 +01:00
def set_export_source ( self , export_source ) :
self . export_source = export_source
self . cache_dir = config [ " cache_dir " ] + self . export_source + ' / '
self . schedule_file = self . cache_dir + ' schedule.pickle '
self . schedule_tracker_file = self . cache_dir + " schedule_tracker.pickle "
def test_api ( self ) :
self . api_client . test ( )
def check_schedule ( self , export_source ) :
logger = logging . getLogger ( )
try :
schedule_file = open ( self . schedule_file , " r " )
schedule = pickle . load ( schedule_file )
schedule_file . close ( )
except Exception , e :
logger . error ( " %s " , e )
schedule = None
for pkey in sorted ( schedule . iterkeys ( ) ) :
playlist = schedule [ pkey ]
print ' ***************************************** '
print ' \033 [0;32m %s %s \033 [m ' % ( ' scheduled at: ' , str ( pkey ) )
print ' cached at : ' + self . cache_dir + str ( pkey )
print ' subtype: ' + str ( playlist [ ' subtype ' ] )
print ' played: ' + str ( playlist [ ' played ' ] )
print ' schedule id: ' + str ( playlist [ ' schedule_id ' ] )
print ' duration: ' + str ( playlist [ ' duration ' ] )
print ' source id: ' + str ( playlist [ ' x_ident ' ] )
print ' ----------------------------------------- '
for media in playlist [ ' medias ' ] :
print media
2011-03-02 22:43:46 +01:00
2011-03-02 23:26:39 +01:00
2011-03-02 22:43:46 +01:00
2010-11-05 15:54:15 +01:00
if __name__ == ' __main__ ' :
2010-11-08 22:54:54 +01:00
print ' ########################################### '
print ' # *** pypo *** # '
print ' # Liquidsoap + External Scheduler # '
print ' # Playout System # '
print ' ########################################### '
2011-03-02 22:43:46 +01:00
2010-11-05 15:54:15 +01:00
# initialize
g = Global ( )
g . selfcheck ( )
2011-03-02 23:26:39 +01:00
2011-03-03 06:22:28 +01:00
logger = logging . getLogger ( )
loops = 0
2010-11-05 15:54:15 +01:00
2011-03-03 06:22:28 +01:00
if options . test :
g . test_api ( )
sys . exit ( )
2011-03-02 22:43:46 +01:00
2011-03-03 06:22:28 +01:00
if options . fetch_scheduler :
pf = PypoFetch ( )
while True :
2011-03-02 23:26:39 +01:00
try : pf . fetch ( ' scheduler ' )
2011-03-02 22:43:46 +01:00
except Exception , e :
print e
sys . exit ( )
if ( loops % 2 == 0 ) :
2011-03-02 23:26:39 +01:00
logger . info ( " heartbeat " )
2011-03-02 22:43:46 +01:00
loops + = 1
time . sleep ( POLL_INTERVAL )
2011-03-03 06:22:28 +01:00
if options . push_scheduler :
pp = PypoPush ( )
while True :
2011-03-02 23:26:39 +01:00
try : pp . push ( ' scheduler ' )
2011-03-02 22:43:46 +01:00
except Exception , e :
print ' PUSH ERROR!! WILL EXIT NOW:( '
print e
sys . exit ( )
if ( loops % 60 == 0 ) :
logger . info ( " heartbeat " )
loops + = 1
time . sleep ( PUSH_INTERVAL )
2011-03-03 06:22:28 +01:00
if options . check :
try : g . check_schedule ( )
except Exception , e :
print e
2011-03-02 22:43:46 +01:00
2011-03-03 06:22:28 +01:00
if options . cleanup :
try : pf . cleanup ( ' scheduler ' )
except Exception , e :
print e
2010-11-05 15:54:15 +01:00
sys . exit ( )