Started integration of pypo with Campcaster. Refactored pypo so that
it can work with either OBP or Campcaster. Added the liquidsoap binary. Started to add the PHP API scripts to send the correct data to pypo (those these are not pretty - all one-off scripts for each API command). Added Zend to the default path.
This commit is contained in:
parent
d6eb1412b7
commit
4a055dde50
Binary file not shown.
|
@ -1,3 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from api_client import *
|
__all__ = ["api_client"]
|
|
@ -0,0 +1,355 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import urllib
|
||||||
|
import logging
|
||||||
|
from util import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
def api_client_factory(config):
|
||||||
|
if config["api_client"] == "campcaster":
|
||||||
|
return CampcasterApiClient(config)
|
||||||
|
elif config["api_client"] == "obp":
|
||||||
|
return ObpApiClient(config)
|
||||||
|
else:
|
||||||
|
print 'API Client "'+config["api_client"]+'" not supported. Please check your config file.'
|
||||||
|
print
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
class ApiClientInterface:
|
||||||
|
|
||||||
|
# This is optional.
|
||||||
|
# Should exit the program if this version of pypo is not compatible with
|
||||||
|
# 3rd party software.
|
||||||
|
def check_version(self):
|
||||||
|
nil
|
||||||
|
|
||||||
|
# This is the main method you need to implement when creating a new API client.
|
||||||
|
def get_schedule(self):
|
||||||
|
return 0, []
|
||||||
|
|
||||||
|
# This is optional.
|
||||||
|
# You dont actually have to implement this function for the liquidsoap playout to work.
|
||||||
|
def update_scheduled_item(self, item_id, value):
|
||||||
|
nil
|
||||||
|
|
||||||
|
# This is optional.
|
||||||
|
# You dont actually have to implement this function for the liquidsoap playout to work.
|
||||||
|
def update_start_playing(self, playlist_type, export_source, media_id, playlist_id, transmission_id):
|
||||||
|
nil
|
||||||
|
|
||||||
|
def generate_range_dp(self):
|
||||||
|
nil
|
||||||
|
|
||||||
|
|
||||||
|
class CampcasterApiClient(ApiClientInterface):
|
||||||
|
|
||||||
|
def __init__(self, config):
|
||||||
|
self.config = config
|
||||||
|
#self.api_auth = api_auth
|
||||||
|
|
||||||
|
def __get_campcaster_version(self):
|
||||||
|
logger = logging.getLogger("CampcasterApiClient.get_campcaster_version")
|
||||||
|
url = self.config["base_url"] + self.config["api_base"] + self.config["version_url"]
|
||||||
|
url = url.replace("%%api_key%%", self.config["api_key"])
|
||||||
|
|
||||||
|
try:
|
||||||
|
logger.debug("Trying to contact %s", url)
|
||||||
|
response = urllib.urlopen(url)
|
||||||
|
data = response.read()
|
||||||
|
response_json = json.read(data)
|
||||||
|
version = response_json['version']
|
||||||
|
logger.debug("Campcaster Version %s detected", version)
|
||||||
|
except Exception, e:
|
||||||
|
try:
|
||||||
|
if e[1] == 401:
|
||||||
|
print '#####################################'
|
||||||
|
print '# YOUR API KEY SEEMS TO BE INVALID:'
|
||||||
|
print '# ' + self.config["api_key"]
|
||||||
|
print '#####################################'
|
||||||
|
sys.exit()
|
||||||
|
except Exception, e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
if e[1] == 404:
|
||||||
|
print '#####################################'
|
||||||
|
print '# Unable to contact the OBP-API'
|
||||||
|
print '# ' + url
|
||||||
|
print '#####################################'
|
||||||
|
sys.exit()
|
||||||
|
except Exception, e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
version = 0
|
||||||
|
logger.error("Unable to detect Campcaster Version - %s", e)
|
||||||
|
|
||||||
|
return version
|
||||||
|
|
||||||
|
def check_version(self):
|
||||||
|
version = self.__get_campcaster_version()
|
||||||
|
if (version == 0):
|
||||||
|
print 'Unable to get Campcaster version number.'
|
||||||
|
print
|
||||||
|
sys.exit()
|
||||||
|
elif (version[0:4] != "1.6."):
|
||||||
|
print 'Campcaster version: ' + str(version)
|
||||||
|
print 'pypo not compatible with this version of Campcaster.'
|
||||||
|
print
|
||||||
|
sys.exit()
|
||||||
|
else:
|
||||||
|
print 'Campcaster version: ' + str(version)
|
||||||
|
print 'pypo is compatible with this version of Campcaster.'
|
||||||
|
print
|
||||||
|
|
||||||
|
def get_schedule(self):
|
||||||
|
logger = logging.getLogger("CampcasterApiClient.get_schedule")
|
||||||
|
|
||||||
|
"""
|
||||||
|
calculate start/end time range (format: YYYY-DD-MM-hh-mm-ss,YYYY-DD-MM-hh-mm-ss)
|
||||||
|
(seconds are ignored, just here for consistency)
|
||||||
|
"""
|
||||||
|
tnow = time.localtime(time.time())
|
||||||
|
tstart = time.localtime(time.time() - 3600 * int(self.config["cache_for"]))
|
||||||
|
tend = time.localtime(time.time() + 3600 * int(self.config["prepare_ahead"]))
|
||||||
|
|
||||||
|
range = {}
|
||||||
|
range['start'] = "%04d-%02d-%02d-%02d-%02d" % (tstart[0], tstart[1], tstart[2], tstart[3], tstart[4])
|
||||||
|
range['end'] = "%04d-%02d-%02d-%02d-%02d" % (tend[0], tend[1], tend[2], tend[3], tend[4])
|
||||||
|
|
||||||
|
# Construct the URL
|
||||||
|
export_url = self.config["base_url"] + self.config["api_base"] + self.config["export_url"]
|
||||||
|
|
||||||
|
# Insert the start and end times into the URL
|
||||||
|
export_url = export_url.replace('%%api_key%%', self.config["api_key"])
|
||||||
|
export_url = export_url.replace('%%from%%', range['start'])
|
||||||
|
export_url = export_url.replace('%%to%%', range['end'])
|
||||||
|
logger.info("export from %s", export_url)
|
||||||
|
|
||||||
|
response = ""
|
||||||
|
status = 0
|
||||||
|
try:
|
||||||
|
response_json = urllib.urlopen(export_url).read()
|
||||||
|
response = json.read(response_json)
|
||||||
|
logger.info("export status %s", response['check'])
|
||||||
|
status = response['check']
|
||||||
|
except Exception, e:
|
||||||
|
print e
|
||||||
|
|
||||||
|
return status, response
|
||||||
|
|
||||||
|
def update_scheduled_item(self, item_id, value):
|
||||||
|
logger = logging.getLogger("CampcasterApiClient.update_scheduled_item")
|
||||||
|
|
||||||
|
url = self.config["base_url"] + self.config["api_base"] + self.config["update_item_url"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = urllib.urlopen(url, self.api_auth)
|
||||||
|
response = json.read(response.read())
|
||||||
|
logger.info("API-Status %s", response['status'])
|
||||||
|
logger.info("API-Message %s", response['message'])
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
print e
|
||||||
|
api_status = False
|
||||||
|
logger.critical("Unable to connect - %s", e)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def update_start_playing(self, playlist_type, export_source, media_id, playlist_id, transmission_id):
|
||||||
|
return
|
||||||
|
logger = logging.getLogger("ApiClient.update_scheduled_item")
|
||||||
|
|
||||||
|
url = self.api_url + 'schedule/update_start_playing.php' \
|
||||||
|
+ '?playlist_type=' + str(playlist_type) \
|
||||||
|
+ '&export_source=' + str(export_source) \
|
||||||
|
+ '&media_id=' + str(media_id) \
|
||||||
|
+ '&playlist_id=' + str(playlist_id) \
|
||||||
|
+ '&transmission_id=' + str(transmission_id)
|
||||||
|
|
||||||
|
print url
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = urllib.urlopen(url, self.api_auth)
|
||||||
|
response = json.read(response.read())
|
||||||
|
logger.info("API-Status %s", response['status'])
|
||||||
|
logger.info("API-Message %s", response['message'])
|
||||||
|
logger.info("TXT %s", response['str_dls'])
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
print e
|
||||||
|
api_status = False
|
||||||
|
logger.critical("Unable to connect - %s", e)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def generate_range_dp(self):
|
||||||
|
logger = logging.getLogger("ApiClient.generate_range_dp")
|
||||||
|
|
||||||
|
url = self.api_url + 'schedule/generate_range_dp.php'
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = urllib.urlopen(url, self.api_auth)
|
||||||
|
response = json.read(response.read())
|
||||||
|
logger.debug("Trying to contact %s", url)
|
||||||
|
logger.info("API-Status %s", response['status'])
|
||||||
|
logger.info("API-Message %s", response['message'])
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
print e
|
||||||
|
api_status = False
|
||||||
|
logger.critical("Unable to handle the request - %s", e)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
OBP_MIN_VERSION = 2010100101 # required obp version
|
||||||
|
|
||||||
|
class ObpApiClient():
|
||||||
|
|
||||||
|
def __init__(self, config):
|
||||||
|
self.config = config
|
||||||
|
#self.api_url = api_url
|
||||||
|
#self.api_auth = api_auth
|
||||||
|
|
||||||
|
def check_version(self):
|
||||||
|
obp_version = self.get_obp_version()
|
||||||
|
|
||||||
|
if obp_version == 0:
|
||||||
|
print '#################################################'
|
||||||
|
print 'Unable to get OBP version. Is OBP up and running?'
|
||||||
|
print '#################################################'
|
||||||
|
print
|
||||||
|
sys.exit()
|
||||||
|
elif obp_version < OBP_MIN_VERSION:
|
||||||
|
print 'OBP version: ' + str(obp_version)
|
||||||
|
print 'OBP min-version: ' + str(OBP_MIN_VERSION)
|
||||||
|
print 'pypo not compatible with this version of OBP'
|
||||||
|
print
|
||||||
|
sys.exit()
|
||||||
|
else:
|
||||||
|
print 'OBP API: ' + str(API_BASE)
|
||||||
|
print 'OBP version: ' + str(obp_version)
|
||||||
|
print 'OBP min-version: ' + str(OBP_MIN_VERSION)
|
||||||
|
print 'pypo is compatible with this version of OBP'
|
||||||
|
print
|
||||||
|
|
||||||
|
def get_obp_version(self):
|
||||||
|
logger = logging.getLogger("ApiClient.get_obp_version")
|
||||||
|
# lookup OBP version
|
||||||
|
|
||||||
|
url = self.api_url + 'api/pypo/status/json'
|
||||||
|
|
||||||
|
try:
|
||||||
|
logger.debug("Trying to contact %s", url)
|
||||||
|
response = urllib.urlopen(url, self.api_auth)
|
||||||
|
response_json = json.read(response.read())
|
||||||
|
obp_version = int(response_json['version'])
|
||||||
|
logger.debug("OBP Version %s detected", obp_version)
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
try:
|
||||||
|
if e[1] == 401:
|
||||||
|
print '#####################################'
|
||||||
|
print '# YOUR API KEY SEEMS TO BE INVALID'
|
||||||
|
print '# ' + self.api_auth
|
||||||
|
print '#####################################'
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
if e[1] == 404:
|
||||||
|
print '#####################################'
|
||||||
|
print '# Unable to contact the OBP-API'
|
||||||
|
print '# ' + url
|
||||||
|
print '#####################################'
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
obp_version = 0
|
||||||
|
logger.error("Unable to detect OBP Version - %s", e)
|
||||||
|
|
||||||
|
|
||||||
|
return obp_version
|
||||||
|
|
||||||
|
|
||||||
|
def update_scheduled_item(self, item_id, value):
|
||||||
|
logger = logging.getLogger("ApiClient.update_shedueled_item")
|
||||||
|
# lookup OBP version
|
||||||
|
|
||||||
|
url = self.api_url + 'api/pypo/update_scheduled_item/' + str(item_id) + '?played=' + str(value)
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = urllib.urlopen(url, self.api_auth)
|
||||||
|
response = json.read(response.read())
|
||||||
|
logger.info("API-Status %s", response['status'])
|
||||||
|
logger.info("API-Message %s", response['message'])
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
print e
|
||||||
|
api_status = False
|
||||||
|
logger.critical("Unable to connect to the OBP API - %s", e)
|
||||||
|
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def update_start_playing(self, playlist_type, export_source, media_id, playlist_id, transmission_id):
|
||||||
|
|
||||||
|
logger = logging.getLogger("ApiClient.update_shedueled_item")
|
||||||
|
|
||||||
|
url = self.api_url + 'api/pypo/update_start_playing/' \
|
||||||
|
+ '?playlist_type=' + str(playlist_type) \
|
||||||
|
+ '&export_source=' + str(export_source) \
|
||||||
|
+ '&export_source=' + str(export_source) \
|
||||||
|
+ '&media_id=' + str(media_id) \
|
||||||
|
+ '&playlist_id=' + str(playlist_id) \
|
||||||
|
+ '&transmission_id=' + str(transmission_id)
|
||||||
|
|
||||||
|
print url
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = urllib.urlopen(url, self.api_auth)
|
||||||
|
response = json.read(response.read())
|
||||||
|
logger.info("API-Status %s", response['status'])
|
||||||
|
logger.info("API-Message %s", response['message'])
|
||||||
|
logger.info("TXT %s", response['str_dls'])
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
print e
|
||||||
|
api_status = False
|
||||||
|
logger.critical("Unable to connect to the OBP API - %s", e)
|
||||||
|
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def generate_range_dp(self):
|
||||||
|
logger = logging.getLogger("ApiClient.generate_range_dp")
|
||||||
|
|
||||||
|
url = self.api_url + 'api/pypo/generate_range_dp/'
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = urllib.urlopen(url, self.api_auth)
|
||||||
|
response = json.read(response.read())
|
||||||
|
logger.debug("Trying to contact %s", url)
|
||||||
|
logger.info("API-Status %s", response['status'])
|
||||||
|
logger.info("API-Message %s", response['message'])
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
print e
|
||||||
|
api_status = False
|
||||||
|
logger.critical("Unable to handle the OBP API request - %s", e)
|
||||||
|
|
||||||
|
|
||||||
|
return response
|
|
@ -0,0 +1,9 @@
|
||||||
|
import campcaster_api_client
|
||||||
|
import obp_api_client
|
||||||
|
|
||||||
|
def create_api_client(config):
|
||||||
|
if config["api_client"] == "campcaster":
|
||||||
|
return campcaster_api_client.CampcasterApiClient(config)
|
||||||
|
elif config["api_client"] == "obp":
|
||||||
|
return obp_api_client.ObpApiClient(config)
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import urllib
|
||||||
|
import logging
|
||||||
|
from util import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
class CampcasterApiClient():
|
||||||
|
|
||||||
|
def __init__(self, config):
|
||||||
|
self.config = config
|
||||||
|
#self.api_auth = api_auth
|
||||||
|
|
||||||
|
def check_version(self):
|
||||||
|
version = self.get_campcaster_version()
|
||||||
|
if (version == 0):
|
||||||
|
print 'Unable to get Campcaster version number.'
|
||||||
|
print
|
||||||
|
sys.exit()
|
||||||
|
elif (version[0:4] != "1.6."):
|
||||||
|
print 'Campcaster version: ' + str(version)
|
||||||
|
print 'pypo not compatible with this version of Campcaster'
|
||||||
|
print
|
||||||
|
sys.exit()
|
||||||
|
else:
|
||||||
|
print 'Campcaster version: ' + str(version)
|
||||||
|
print 'pypo is compatible with this version of OBP'
|
||||||
|
print
|
||||||
|
|
||||||
|
def get_campcaster_version(self):
|
||||||
|
logger = logging.getLogger("ApiClient.get_campcaster_version")
|
||||||
|
url = self.config["base_url"] + self.config["api_base"] + self.config["version_url"]
|
||||||
|
url = url.replace("%%api_key%%", self.config["api_key"])
|
||||||
|
|
||||||
|
try:
|
||||||
|
logger.debug("Trying to contact %s", url)
|
||||||
|
response = urllib.urlopen(url)
|
||||||
|
data = response.read()
|
||||||
|
response_json = json.read(data)
|
||||||
|
version = response_json['version']
|
||||||
|
logger.debug("Campcaster Version %s detected", version)
|
||||||
|
except Exception, e:
|
||||||
|
try:
|
||||||
|
if e[1] == 401:
|
||||||
|
print '#####################################'
|
||||||
|
print '# YOUR API KEY SEEMS TO BE INVALID:'
|
||||||
|
print '# ' + self.config["api_key"]
|
||||||
|
print '#####################################'
|
||||||
|
sys.exit()
|
||||||
|
except Exception, e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
if e[1] == 404:
|
||||||
|
print '#####################################'
|
||||||
|
print '# Unable to contact the OBP-API'
|
||||||
|
print '# ' + url
|
||||||
|
print '#####################################'
|
||||||
|
sys.exit()
|
||||||
|
except Exception, e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
version = 0
|
||||||
|
logger.error("Unable to detect Campcaster Version - %s", e)
|
||||||
|
|
||||||
|
return version
|
||||||
|
|
||||||
|
|
||||||
|
def update_scheduled_item(self, item_id, value):
|
||||||
|
logger = logging.getLogger("ApiClient.update_scheduled_item")
|
||||||
|
url = self.api_url + 'schedule/schedule.php?item_id=' + str(item_id) + '&played=' + str(value)
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = urllib.urlopen(url, self.api_auth)
|
||||||
|
response = json.read(response.read())
|
||||||
|
logger.info("API-Status %s", response['status'])
|
||||||
|
logger.info("API-Message %s", response['message'])
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
print e
|
||||||
|
api_status = False
|
||||||
|
logger.critical("Unable to connect - %s", e)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def update_start_playing(self, playlist_type, export_source, media_id, playlist_id, transmission_id):
|
||||||
|
logger = logging.getLogger("ApiClient.update_scheduled_item")
|
||||||
|
|
||||||
|
url = self.api_url + 'schedule/update_start_playing.php' \
|
||||||
|
+ '?playlist_type=' + str(playlist_type) \
|
||||||
|
+ '&export_source=' + str(export_source) \
|
||||||
|
+ '&export_source=' + str(export_source) \
|
||||||
|
+ '&media_id=' + str(media_id) \
|
||||||
|
+ '&playlist_id=' + str(playlist_id) \
|
||||||
|
+ '&transmission_id=' + str(transmission_id)
|
||||||
|
|
||||||
|
print url
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = urllib.urlopen(url, self.api_auth)
|
||||||
|
response = json.read(response.read())
|
||||||
|
logger.info("API-Status %s", response['status'])
|
||||||
|
logger.info("API-Message %s", response['message'])
|
||||||
|
logger.info("TXT %s", response['str_dls'])
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
print e
|
||||||
|
api_status = False
|
||||||
|
logger.critical("Unable to connect - %s", e)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def generate_range_dp(self):
|
||||||
|
logger = logging.getLogger("ApiClient.generate_range_dp")
|
||||||
|
|
||||||
|
url = self.api_url + 'schedule/generate_range_dp.php'
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = urllib.urlopen(url, self.api_auth)
|
||||||
|
response = json.read(response.read())
|
||||||
|
logger.debug("Trying to contact %s", url)
|
||||||
|
logger.info("API-Status %s", response['status'])
|
||||||
|
logger.info("API-Message %s", response['message'])
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
print e
|
||||||
|
api_status = False
|
||||||
|
logger.critical("Unable to handle the request - %s", e)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
|
@ -6,31 +6,52 @@
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from util import json
|
from util import json
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
OBP_MIN_VERSION = 2010100101 # required obp version
|
||||||
|
|
||||||
class ApiClient():
|
class ObpApiClient():
|
||||||
|
|
||||||
def __init__(self, api_url, api_auth):
|
def __init__(self, config):
|
||||||
self.api_url = api_url
|
self.config = config
|
||||||
self.api_auth = api_auth
|
#self.api_url = api_url
|
||||||
|
#self.api_auth = api_auth
|
||||||
|
|
||||||
|
def check_version(self):
|
||||||
|
obp_version = self.get_obp_version()
|
||||||
|
|
||||||
|
if obp_version == 0:
|
||||||
|
print '#################################################'
|
||||||
|
print 'Unable to get OBP version. Is OBP up and running?'
|
||||||
|
print '#################################################'
|
||||||
|
print
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
elif obp_version < OBP_MIN_VERSION:
|
||||||
|
print 'OBP version: ' + str(obp_version)
|
||||||
|
print 'OBP min-version: ' + str(OBP_MIN_VERSION)
|
||||||
|
print 'pypo not compatible with this version of OBP'
|
||||||
|
print
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
else:
|
||||||
|
print 'OBP API: ' + str(API_BASE)
|
||||||
|
print 'OBP version: ' + str(obp_version)
|
||||||
|
print 'OBP min-version: ' + str(OBP_MIN_VERSION)
|
||||||
|
print 'pypo is compatible with this version of OBP'
|
||||||
|
print
|
||||||
|
|
||||||
|
|
||||||
def get_obp_version(self):
|
def get_obp_version(self):
|
||||||
logger = logging.getLogger("ApiClient.get_obp_version")
|
logger = logging.getLogger("ApiClient.get_obp_version")
|
||||||
# lookup OBP version
|
# lookup OBP version
|
||||||
|
|
||||||
url = self.api_url + 'api/pypo/status/json'
|
url = self.api_url + 'api/pypo/status/json'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
logger.debug("Trying to contact %s", url)
|
logger.debug("Trying to contact %s", url)
|
||||||
|
|
||||||
response = urllib.urlopen(url, self.api_auth)
|
response = urllib.urlopen(url, self.api_auth)
|
||||||
response_json = json.read(response.read())
|
response_json = json.read(response.read())
|
||||||
obp_version = int(response_json['version'])
|
obp_version = int(response_json['version'])
|
||||||
|
@ -67,11 +88,11 @@ class ApiClient():
|
||||||
return obp_version
|
return obp_version
|
||||||
|
|
||||||
|
|
||||||
def update_shedueled_item(self, item_id, value):
|
def update_scheduled_item(self, item_id, value):
|
||||||
logger = logging.getLogger("ApiClient.update_shedueled_item")
|
logger = logging.getLogger("ApiClient.update_shedueled_item")
|
||||||
# lookup OBP version
|
# lookup OBP version
|
||||||
|
|
||||||
url = self.api_url + 'api/pypo/update_shedueled_item/' + str(item_id) + '?played=' + str(value)
|
url = self.api_url + 'api/pypo/update_scheduled_item/' + str(item_id) + '?played=' + str(value)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = urllib.urlopen(url, self.api_auth)
|
response = urllib.urlopen(url, self.api_auth)
|
|
@ -2,29 +2,63 @@
|
||||||
# pypo - configuration #
|
# pypo - configuration #
|
||||||
############################################
|
############################################
|
||||||
|
|
||||||
|
# Set the type of client you are using.
|
||||||
|
# Currently supported types:
|
||||||
|
# 1) "obp" = Open Broadcast Platform
|
||||||
|
# 2) "campcaster"
|
||||||
|
#
|
||||||
|
api_client = "campcaster"
|
||||||
|
|
||||||
############################################
|
############################################
|
||||||
# Directories / Hosts #
|
# Directories / Hosts #
|
||||||
# _include_ trailing slash !! #
|
# _include_ trailing slash !! #
|
||||||
############################################
|
############################################
|
||||||
cache_dir = '/storage/pypo/cache/'
|
cache_dir = '/opt/pypo/cache/'
|
||||||
file_dir = '/storage/pypo/files/'
|
schedule_dir = '/opt/pypo/cache/schedule'
|
||||||
tmp_dir = '/var/tmp/obp/'
|
file_dir = '/opt/pypo/files/'
|
||||||
|
tmp_dir = '/tmp/pypo/'
|
||||||
|
|
||||||
############################################
|
############################################
|
||||||
# API path & co #
|
# API path & co #
|
||||||
############################################
|
############################################
|
||||||
base_url = 'http://vdeb.openbroadcast.ch/'
|
# Value needed to access the API
|
||||||
obp_api_key = 'AAA-BBB-CCC-EEE'
|
api_key = 'AAA'
|
||||||
|
|
||||||
# stage config
|
# Hostname
|
||||||
#base_url = 'http://stage.openbroadcast.ch/'
|
base_url = 'http://localhost/'
|
||||||
#obp_api_key = 'EMMKM-PMXWV-NIGOA-KHGWPP
|
|
||||||
|
#####################
|
||||||
|
# Campcaster Config #
|
||||||
|
#####################
|
||||||
|
# Path to the base of the API
|
||||||
|
api_base = 'campcaster/'
|
||||||
|
|
||||||
|
# URL to get the version number of the API
|
||||||
|
version_url = 'schedule/api_version.php?api_key=%%api_key%%'
|
||||||
|
|
||||||
|
# Schedule export path.
|
||||||
|
# YYYY-MM-DD-hh-mm will be substituted for the tokens %%from%% and %%to%%
|
||||||
|
export_url = 'schedule/schedule.php?from=%%from%%&to=%%to%%&api_key=%%api_key%%'
|
||||||
|
|
||||||
|
update_item_url = 'schedule/schedule.php?item_id=%%item_id%%&played=%%played%%'
|
||||||
|
|
||||||
|
update_start_playing_url = 'schedule/update_start_playing.php?playlist_type=%%playlist_type%%&export_source=%%export_source%%&media_id=%%media_id%%&playlist_id=%%playlist_id%%&transmission_id=%%transmission_id%%'
|
||||||
|
|
||||||
|
generate_range_url = 'schedule/generate_range_dp.php'
|
||||||
|
|
||||||
|
|
||||||
|
##############
|
||||||
|
# OBP config #
|
||||||
|
##############
|
||||||
|
#base_url = 'http://localhost/'
|
||||||
|
#api_base = BASE_URL
|
||||||
|
#version_url = api_base + 'api/pypo/status/json'
|
||||||
|
#update_item_url = api_base + 'api/pypo/update_shedueled_item/$$item_id%%?played=%%played%%'
|
||||||
|
|
||||||
# prod config
|
# prod config
|
||||||
#base_url = 'http://openbroadcast.ch/'
|
#base_url = ''
|
||||||
#obp_api_key = 'XWQWP-XIHJU-ZHENT-NGSAW'
|
#api_key = ''
|
||||||
|
|
||||||
export_path = 'api/pypo/export_range/' # YYYY-MM-DD-hh-mm will be added in script, exports json
|
|
||||||
|
|
||||||
############################################
|
############################################
|
||||||
# Liquidsoap settings #
|
# Liquidsoap settings #
|
||||||
|
@ -41,7 +75,7 @@ cache_for = 24 #how long to hold the cache, in hours
|
||||||
poll_interval = 10 # in seconds
|
poll_interval = 10 # in seconds
|
||||||
push_interval = 1 # in seconds
|
push_interval = 1 # in seconds
|
||||||
|
|
||||||
# 'pre' or 'otf'. 'pre' cues while pplaylist preparation
|
# 'pre' or 'otf'. 'pre' cues while playlist preparation
|
||||||
# while 'otf' (on the fly) cues while loading into ls
|
# while 'otf' (on the fly) cues while loading into ls
|
||||||
# (needs the post_processor patch)
|
# (needs the post_processor patch)
|
||||||
cue_style = 'pre'
|
cue_style = 'pre'
|
||||||
|
|
|
@ -21,7 +21,7 @@ propagate=0
|
||||||
|
|
||||||
[handler_consoleHandler]
|
[handler_consoleHandler]
|
||||||
class=StreamHandler
|
class=StreamHandler
|
||||||
level=ERROR
|
level=DEBUG
|
||||||
formatter=simpleFormatter
|
formatter=simpleFormatter
|
||||||
args=(sys.stdout,)
|
args=(sys.stdout,)
|
||||||
|
|
||||||
|
@ -29,13 +29,13 @@ args=(sys.stdout,)
|
||||||
class=FileHandler
|
class=FileHandler
|
||||||
level=WARNING
|
level=WARNING
|
||||||
formatter=simpleFormatter
|
formatter=simpleFormatter
|
||||||
args=("/var/log/obp/pypo/error.log",)
|
args=("./error.log",)
|
||||||
|
|
||||||
[handler_fileHandlerDEBUG]
|
[handler_fileHandlerDEBUG]
|
||||||
class=FileHandler
|
class=FileHandler
|
||||||
level=DEBUG
|
level=DEBUG
|
||||||
formatter=simpleFormatter
|
formatter=simpleFormatter
|
||||||
args=("/var/log/obp/pypo/debug.log",)
|
args=("./debug.log",)
|
||||||
|
|
||||||
[handler_nullHandler]
|
[handler_nullHandler]
|
||||||
class=FileHandler
|
class=FileHandler
|
||||||
|
@ -44,8 +44,6 @@ formatter=simpleFormatter
|
||||||
args=("/tmp/sessionlog_null.log",)
|
args=("/tmp/sessionlog_null.log",)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[formatter_simpleFormatter]
|
[formatter_simpleFormatter]
|
||||||
format=%(asctime)s %(levelname)s - [%(name)s] - %(message)s
|
format=%(asctime)s %(levelname)s - [%(name)s] - %(message)s
|
||||||
datefmt=
|
datefmt=
|
||||||
|
|
|
@ -52,8 +52,6 @@ from obp import *
|
||||||
|
|
||||||
|
|
||||||
PYPO_VERSION = '0.1'
|
PYPO_VERSION = '0.1'
|
||||||
OBP_MIN_VERSION = 2010100101 # required obp version
|
|
||||||
|
|
||||||
|
|
||||||
#set up command-line options
|
#set up command-line options
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
|
@ -84,13 +82,9 @@ try:
|
||||||
FILE_DIR = config['file_dir']
|
FILE_DIR = config['file_dir']
|
||||||
TMP_DIR = config['tmp_dir']
|
TMP_DIR = config['tmp_dir']
|
||||||
BASE_URL = config['base_url']
|
BASE_URL = config['base_url']
|
||||||
OBP_API_BASE = BASE_URL + 'mod/medialibrary/'
|
API_BASE = config['api_base']
|
||||||
EXPORT_URL = OBP_API_BASE + config['export_path']
|
|
||||||
EXPORT_SOURCE = config['export_source']
|
EXPORT_SOURCE = config['export_source']
|
||||||
|
OBP_API_KEY = config['api_key']
|
||||||
OBP_STATUS_URL = OBP_API_BASE + 'status/version/json'
|
|
||||||
OBP_API_KEY = config['obp_api_key']
|
|
||||||
|
|
||||||
POLL_INTERVAL = float(config['poll_interval'])
|
POLL_INTERVAL = float(config['poll_interval'])
|
||||||
PUSH_INTERVAL = float(config['push_interval'])
|
PUSH_INTERVAL = float(config['push_interval'])
|
||||||
LS_HOST = config['ls_host']
|
LS_HOST = config['ls_host']
|
||||||
|
@ -106,9 +100,6 @@ except Exception, e:
|
||||||
#TIME = time.localtime(time.time())
|
#TIME = time.localtime(time.time())
|
||||||
TIME = (2010, 6, 26, 15, 33, 23, 2, 322, 0)
|
TIME = (2010, 6, 26, 15, 33, 23, 2, 322, 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Global:
|
class Global:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -117,33 +108,9 @@ class Global:
|
||||||
|
|
||||||
def selfcheck(self):
|
def selfcheck(self):
|
||||||
|
|
||||||
self.api_auth = urllib.urlencode({'api_key': OBP_API_KEY})
|
self.api_auth = urllib.urlencode({'api_key': API_KEY})
|
||||||
self.api_client = ApiClient(OBP_API_BASE, self.api_auth)
|
self.api_client = ApiClient(API_BASE, self.api_auth)
|
||||||
|
self.api_client.check_version()
|
||||||
obp_version = self.api_client.get_obp_version()
|
|
||||||
|
|
||||||
|
|
||||||
if obp_version == 0:
|
|
||||||
print '#################################################'
|
|
||||||
print 'Unable to get OBP version. Is OBP up and running?'
|
|
||||||
print '#################################################'
|
|
||||||
print
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
elif obp_version < OBP_MIN_VERSION:
|
|
||||||
print 'OBP version: ' + str(obp_version)
|
|
||||||
print 'OBP min-version: ' + str(OBP_MIN_VERSION)
|
|
||||||
print 'pypo not compatible with this version of OBP'
|
|
||||||
print
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
else:
|
|
||||||
print 'OBP API: ' + str(OBP_API_BASE)
|
|
||||||
print 'OBP version: ' + str(obp_version)
|
|
||||||
print 'OBP min-version: ' + str(OBP_MIN_VERSION)
|
|
||||||
print 'pypo is compatible with this version of OBP'
|
|
||||||
print
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Uncomment the following lines to let pypo check if
|
Uncomment the following lines to let pypo check if
|
||||||
|
@ -165,42 +132,32 @@ class Playout:
|
||||||
self.cache_dir = CACHE_DIR
|
self.cache_dir = CACHE_DIR
|
||||||
self.file_dir = FILE_DIR
|
self.file_dir = FILE_DIR
|
||||||
self.tmp_dir = TMP_DIR
|
self.tmp_dir = TMP_DIR
|
||||||
self.export_url = EXPORT_URL
|
|
||||||
self.export_source = EXPORT_SOURCE
|
self.export_source = EXPORT_SOURCE
|
||||||
|
|
||||||
self.api_auth = urllib.urlencode({'api_key': OBP_API_KEY})
|
self.api_auth = urllib.urlencode({'api_key': API_KEY})
|
||||||
self.api_client = ApiClient(OBP_API_BASE, self.api_auth)
|
self.api_client = ApiClient(API_BASE, self.api_auth)
|
||||||
self.cue_file = CueFile()
|
self.cue_file = CueFile()
|
||||||
|
|
||||||
self.schedule_file = CACHE_DIR + 'schedule'
|
self.schedule_file = CACHE_DIR + 'schedule'
|
||||||
|
|
||||||
# set initial state
|
# set initial state
|
||||||
self.range_updated = False
|
self.range_updated = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def push_liquidsoap(self,options):
|
def push_liquidsoap(self,options):
|
||||||
logger = logging.getLogger("push_liquidsoap")
|
logger = logging.getLogger("push_liquidsoap")
|
||||||
|
|
||||||
print options
|
print options
|
||||||
|
|
||||||
#pkey = '2010-10-26-21-00-00'
|
#pkey = '2010-10-26-21-00-00'
|
||||||
|
|
||||||
pkey = options
|
pkey = options
|
||||||
|
|
||||||
src = self.cache_dir + str(pkey) + '/list.lsp'
|
src = self.cache_dir + str(pkey) + '/list.lsp'
|
||||||
|
|
||||||
print src
|
print src
|
||||||
|
s
|
||||||
|
|
||||||
if True == os.access(src, os.R_OK):
|
if True == os.access(src, os.R_OK):
|
||||||
print 'OK - Can read'
|
print 'OK - Can read'
|
||||||
|
|
||||||
pl_file = open(src, "r")
|
pl_file = open(src, "r")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
i know this could be wrapped, maybe later..
|
i know this could be wrapped, maybe later..
|
||||||
"""
|
"""
|
||||||
|
@ -209,30 +166,21 @@ class Playout:
|
||||||
|
|
||||||
for line in pl_file.readlines():
|
for line in pl_file.readlines():
|
||||||
print line.strip()
|
print line.strip()
|
||||||
|
|
||||||
#tn.write('q.push ' + pl_entry)
|
#tn.write('q.push ' + pl_entry)
|
||||||
#tn.write("\n")
|
#tn.write("\n")
|
||||||
|
|
||||||
tn.write('scheduler.push %s' % (line.strip()))
|
tn.write('scheduler.push %s' % (line.strip()))
|
||||||
tn.write("\n")
|
tn.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tn.write("scheduler_q0.queue \n")
|
tn.write("scheduler_q0.queue \n")
|
||||||
|
|
||||||
tn.write("scheduler_q1.queue \n")
|
tn.write("scheduler_q1.queue \n")
|
||||||
#time.sleep(2)
|
#time.sleep(2)
|
||||||
|
|
||||||
|
|
||||||
#print tn.read_all()
|
#print tn.read_all()
|
||||||
|
|
||||||
print 'sending "flip"'
|
print 'sending "flip"'
|
||||||
|
|
||||||
tn.write('scheduler.flip')
|
tn.write('scheduler.flip')
|
||||||
tn.write("\n")
|
tn.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#tn.write("live_in.stop\n")
|
#tn.write("live_in.stop\n")
|
||||||
#tn.write("stream_disable\n")
|
#tn.write("stream_disable\n")
|
||||||
|
@ -263,9 +211,7 @@ class Playout:
|
||||||
|
|
||||||
|
|
||||||
tn.write("exit\n")
|
tn.write("exit\n")
|
||||||
|
|
||||||
print tn.read_all()
|
print tn.read_all()
|
||||||
|
|
||||||
status = 1
|
status = 1
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
"""
|
"""
|
||||||
Python part of radio playout (pypo)
|
Python part of radio playout (pypo)
|
||||||
|
|
||||||
The main functionas are "fetch" (./pypo_cli.py -f) and "push" (./pypo_cli.py -p)
|
The main functions are "fetch" (./pypo_cli.py -f) and "push" (./pypo_cli.py -p)
|
||||||
|
|
||||||
Also check out the php counterpart that handles the api requests:
|
Also check out the php counterpart that handles the api requests:
|
||||||
https://lab.digris.ch/svn/elgg/trunk/unstable/mod/medialibrary/application/controllers/api/pypo.php
|
https://lab.digris.ch/svn/elgg/trunk/unstable/mod/medialibrary/application/controllers/api/pypo.php
|
||||||
|
@ -20,7 +20,7 @@ Attention & ToDos
|
||||||
made for python version 2.5!!
|
made for python version 2.5!!
|
||||||
should work with 2.6 as well with a bit of adaption. for
|
should work with 2.6 as well with a bit of adaption. for
|
||||||
sure the json parsing has to be changed
|
sure the json parsing has to be changed
|
||||||
(2.6 has an parser, pypo brigs it's own -> util/json.py)
|
(2.6 has an parser, pypo brings it's own -> util/json.py)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# python defaults (debian default)
|
# python defaults (debian default)
|
||||||
|
@ -41,36 +41,35 @@ import telnetlib
|
||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
import operator
|
import operator
|
||||||
|
import inspect
|
||||||
|
|
||||||
# additional modules (should be checked)
|
# additional modules (should be checked)
|
||||||
from configobj import ConfigObj
|
from configobj import ConfigObj
|
||||||
|
|
||||||
# custom imports
|
# custom imports
|
||||||
from util import *
|
from util import *
|
||||||
from obp import *
|
from api_clients import *
|
||||||
|
|
||||||
|
PYPO_VERSION = '0.2'
|
||||||
|
|
||||||
|
# Set up command-line options
|
||||||
PYPO_VERSION = '0.1'
|
|
||||||
OBP_MIN_VERSION = 2010100101 # required obp version
|
|
||||||
|
|
||||||
|
|
||||||
#set up command-line options
|
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
|
|
||||||
# help screeen / info
|
# help screeen / info
|
||||||
usage = "%prog [options]" + " - python playout system"
|
usage = "%prog [options]" + " - python playout system"
|
||||||
parser = OptionParser(usage=usage)
|
parser = OptionParser(usage=usage)
|
||||||
|
|
||||||
#options
|
# Options
|
||||||
|
parser.add_option("-v", "--compat", help="Check compatibility with server API version", default=False, action="store_true", dest="check_compat")
|
||||||
|
|
||||||
parser.add_option("-f", "--fetch-scheduler", help="Fetch from scheduler - scheduler (loop, interval in config file)", default=False, action="store_true", dest="fetch_scheduler")
|
parser.add_option("-f", "--fetch-scheduler", help="Fetch from scheduler - scheduler (loop, interval in config file)", default=False, action="store_true", dest="fetch_scheduler")
|
||||||
parser.add_option("-p", "--push-scheduler", help="Push scheduler to Liquidsoap (loop, interval in config file)", default=False, action="store_true", dest="push_scheduler")
|
parser.add_option("-p", "--push-scheduler", help="Push scheduler to Liquidsoap (loop, interval in config file)", default=False, action="store_true", dest="push_scheduler")
|
||||||
|
|
||||||
parser.add_option("-F", "--fetch-daypart", help="Fetch from daypart - scheduler (loop, interval in config file)", default=False, action="store_true", dest="fetch_daypart")
|
parser.add_option("-F", "--fetch-daypart", help="Fetch from daypart - scheduler (loop, interval in config file)", default=False, action="store_true", dest="fetch_daypart")
|
||||||
parser.add_option("-P", "--push-daypart", help="Push daypart to Liquidsoap (loop, interval in config file)", default=False, action="store_true", dest="push_daypart")
|
parser.add_option("-P", "--push-daypart", help="Push daypart to Liquidsoap (loop, interval in config file)", default=False, action="store_true", dest="push_daypart")
|
||||||
|
|
||||||
parser.add_option("-b", "--cleanup", help="Faeili Butzae aka cleanup", default=False, action="store_true", dest="cleanup")
|
parser.add_option("-b", "--cleanup", help="Cleanup", default=False, action="store_true", dest="cleanup")
|
||||||
parser.add_option("-j", "--jingles", help="Get new jungles from obp, comma separated list if jingle-id's as argument", metavar="LIST")
|
parser.add_option("-j", "--jingles", help="Get new jingles from obp, comma separated list if jingle-id's as argument", metavar="LIST")
|
||||||
parser.add_option("-c", "--check", help="Check the cached schedule and exit", default=False, action="store_true", dest="check")
|
parser.add_option("-c", "--check", help="Check the cached schedule and exit", default=False, action="store_true", dest="check")
|
||||||
|
|
||||||
# parse options
|
# parse options
|
||||||
|
@ -85,66 +84,37 @@ try:
|
||||||
CACHE_DIR = config['cache_dir']
|
CACHE_DIR = config['cache_dir']
|
||||||
FILE_DIR = config['file_dir']
|
FILE_DIR = config['file_dir']
|
||||||
TMP_DIR = config['tmp_dir']
|
TMP_DIR = config['tmp_dir']
|
||||||
BASE_URL = config['base_url']
|
API_BASE = config['api_base']
|
||||||
OBP_API_BASE = BASE_URL + 'mod/medialibrary/'
|
API_KEY = config['api_key']
|
||||||
EXPORT_URL = OBP_API_BASE + config['export_path']
|
|
||||||
|
|
||||||
OBP_STATUS_URL = OBP_API_BASE + 'status/version/json'
|
|
||||||
OBP_API_KEY = config['obp_api_key']
|
|
||||||
|
|
||||||
POLL_INTERVAL = float(config['poll_interval'])
|
POLL_INTERVAL = float(config['poll_interval'])
|
||||||
PUSH_INTERVAL = float(config['push_interval'])
|
PUSH_INTERVAL = float(config['push_interval'])
|
||||||
LS_HOST = config['ls_host']
|
LS_HOST = config['ls_host']
|
||||||
LS_PORT = config['ls_port']
|
LS_PORT = config['ls_port']
|
||||||
PREPARE_AHEAD = config['prepare_ahead']
|
#PREPARE_AHEAD = config['prepare_ahead']
|
||||||
CACHE_FOR = config['cache_for']
|
CACHE_FOR = config['cache_for']
|
||||||
CUE_STYLE = config['cue_style']
|
CUE_STYLE = config['cue_style']
|
||||||
|
#print config
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print 'error: ', e
|
print 'Error loading config file: ', e
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
#TIME = time.localtime(time.time())
|
#TIME = time.localtime(time.time())
|
||||||
TIME = (2010, 6, 26, 15, 33, 23, 2, 322, 0)
|
TIME = (2010, 6, 26, 15, 33, 23, 2, 322, 0)
|
||||||
|
|
||||||
|
# to help with debugging - get the current line number
|
||||||
|
def lineno():
|
||||||
|
"""Returns the current function name and line number in our program."""
|
||||||
|
return "File " +inspect.currentframe().f_code.co_filename + " / Line " + str(inspect.currentframe().f_back.f_lineno) + ": "
|
||||||
|
|
||||||
class Global:
|
class Global:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
#print '# global initialisation'
|
#print '# global initialisation'
|
||||||
print
|
print
|
||||||
|
|
||||||
def selfcheck(self):
|
def selfcheck(self):
|
||||||
|
self.api_auth = urllib.urlencode({'api_key': API_KEY})
|
||||||
self.api_auth = urllib.urlencode({'api_key': OBP_API_KEY})
|
self.api_client = api_client.api_client_factory(config)
|
||||||
self.api_client = ApiClient(OBP_API_BASE, self.api_auth)
|
self.api_client.check_version()
|
||||||
|
|
||||||
obp_version = self.api_client.get_obp_version()
|
|
||||||
|
|
||||||
|
|
||||||
if obp_version == 0:
|
|
||||||
print '#################################################'
|
|
||||||
print 'Unable to get OBP version. Is OBP up and running?'
|
|
||||||
print '#################################################'
|
|
||||||
print
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
elif obp_version < OBP_MIN_VERSION:
|
|
||||||
print 'OBP version: ' + str(obp_version)
|
|
||||||
print 'OBP min-version: ' + str(OBP_MIN_VERSION)
|
|
||||||
print 'pypo not compatible with this version of OBP'
|
|
||||||
print
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
else:
|
|
||||||
print 'OBP API: ' + str(OBP_API_BASE)
|
|
||||||
print 'OBP version: ' + str(obp_version)
|
|
||||||
print 'OBP min-version: ' + str(OBP_MIN_VERSION)
|
|
||||||
print 'pypo is compatible with this version of OBP'
|
|
||||||
print
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Uncomment the following lines to let pypo check if
|
Uncomment the following lines to let pypo check if
|
||||||
|
@ -153,8 +123,7 @@ class Global:
|
||||||
# while self.status.check_ls(LS_HOST, LS_PORT) == 0:
|
# while self.status.check_ls(LS_HOST, LS_PORT) == 0:
|
||||||
# print 'Unable to connect to liquidsoap. Is it up and running?'
|
# print 'Unable to connect to liquidsoap. Is it up and running?'
|
||||||
# time.sleep(2)
|
# time.sleep(2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -162,39 +131,31 @@ class Global:
|
||||||
class Playout:
|
class Playout:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
#print '# init fallback'
|
#print '# init fallback'
|
||||||
|
|
||||||
|
|
||||||
self.file_dir = FILE_DIR
|
self.file_dir = FILE_DIR
|
||||||
self.tmp_dir = TMP_DIR
|
self.tmp_dir = TMP_DIR
|
||||||
self.export_url = EXPORT_URL
|
|
||||||
|
|
||||||
self.api_auth = urllib.urlencode({'api_key': OBP_API_KEY})
|
self.api_auth = urllib.urlencode({'api_key': API_KEY})
|
||||||
self.api_client = ApiClient(OBP_API_BASE, self.api_auth)
|
self.api_client = api_client.api_client_factory(config)
|
||||||
self.cue_file = CueFile()
|
self.cue_file = CueFile()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# set initial state
|
# set initial state
|
||||||
self.range_updated = False
|
self.range_updated = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Fetching part of pypo
|
Fetching part of pypo
|
||||||
- Reads the scheduled entries of a given range (actual time +/- "prepare_ahead" / "cache_for")
|
- Reads the scheduled entries of a given range (actual time +/- "prepare_ahead" / "cache_for")
|
||||||
- Saves a serialized file of the schedule
|
- Saves a serialized file of the schedule
|
||||||
- playlists are prepared. (brought to ls format) and, if not mounted via nsf, files are copied
|
- playlists are prepared. (brought to liquidsoap format) and, if not mounted via nsf, files are copied
|
||||||
to the cache dir (Folder-structure: cache/YYYY-MM-DD-hh-mm-ss)
|
to the cache dir (Folder-structure: cache/YYYY-MM-DD-hh-mm-ss)
|
||||||
- runs the cleanup routine, to get rid of unused cashed files
|
- runs the cleanup routine, to get rid of unused cashed files
|
||||||
"""
|
"""
|
||||||
def fetch(self, export_source):
|
def fetch(self, export_source):
|
||||||
"""
|
"""
|
||||||
wrapper script for fetchin whole shedule (in json)
|
wrapper script for fetching the whole schedule (in json)
|
||||||
"""
|
"""
|
||||||
logger = logging.getLogger("fetch")
|
logger = logging.getLogger("fetch")
|
||||||
|
|
||||||
|
|
||||||
self.export_source = export_source
|
self.export_source = export_source
|
||||||
self.cache_dir = CACHE_DIR + self.export_source + '/'
|
self.cache_dir = CACHE_DIR + self.export_source + '/'
|
||||||
self.schedule_file = self.cache_dir + 'schedule'
|
self.schedule_file = self.cache_dir + 'schedule'
|
||||||
|
@ -215,34 +176,30 @@ class Playout:
|
||||||
try:
|
try:
|
||||||
self.generate_range_dp()
|
self.generate_range_dp()
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
logger.error("%s", e)
|
logger.error(lineno() + "%s", e)
|
||||||
|
|
||||||
|
# get schedule
|
||||||
# get shedule
|
|
||||||
try:
|
try:
|
||||||
while self.get_schedule(self.export_source) != 1:
|
while self.get_schedule() != 1:
|
||||||
logger.warning("failed to read from export url")
|
logger.warning("failed to read from export url")
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
except Exception, e: logger.error("%s", e)
|
except Exception, e: logger.error(lineno() +"%s", e)
|
||||||
|
|
||||||
# prepare the playlists
|
# prepare the playlists
|
||||||
if CUE_STYLE == 'pre':
|
if CUE_STYLE == 'pre':
|
||||||
try: self.prepare_playlists_cue(self.export_source)
|
try: self.prepare_playlists_cue(self.export_source)
|
||||||
except Exception, e: logger.error("%s", e)
|
except Exception, e: logger.error(lineno() + "%s", e)
|
||||||
elif CUE_STYLE == 'otf':
|
elif CUE_STYLE == 'otf':
|
||||||
try: self.prepare_playlists(self.export_source)
|
try: self.prepare_playlists(self.export_source)
|
||||||
except Exception, e: logger.error("%s", e)
|
except Exception, e: logger.error(lineno() + "%s", e)
|
||||||
|
|
||||||
# cleanup
|
# cleanup
|
||||||
try: self.cleanup(self.export_source)
|
try: self.cleanup(self.export_source)
|
||||||
except Exception, e: logger.error("%s", e)
|
except Exception, e: logger.error(lineno() + "%s", e)
|
||||||
|
|
||||||
logger.info("fetch loop completed")
|
logger.info("fetch loop completed")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This is actually a bit ugly (again feel free to improve!!)
|
This is actually a bit ugly (again feel free to improve!!)
|
||||||
|
@ -250,9 +207,7 @@ class Playout:
|
||||||
we do this at 18h. The hour before the state is set back to 'False'
|
we do this at 18h. The hour before the state is set back to 'False'
|
||||||
"""
|
"""
|
||||||
def generate_range_dp(self):
|
def generate_range_dp(self):
|
||||||
|
|
||||||
logger = logging.getLogger("generate_range_dp")
|
logger = logging.getLogger("generate_range_dp")
|
||||||
|
|
||||||
logger.debug("trying to trigger daypart update")
|
logger.debug("trying to trigger daypart update")
|
||||||
|
|
||||||
tnow = time.localtime(time.time())
|
tnow = time.localtime(time.time())
|
||||||
|
@ -261,7 +216,6 @@ class Playout:
|
||||||
self.range_updated = False
|
self.range_updated = False
|
||||||
|
|
||||||
if(tnow[3] == 17 and self.range_updated == False):
|
if(tnow[3] == 17 and self.range_updated == False):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print self.api_client.generate_range_dp()
|
print self.api_client.generate_range_dp()
|
||||||
logger.info("daypart updated")
|
logger.info("daypart updated")
|
||||||
|
@ -269,61 +223,25 @@ class Playout:
|
||||||
|
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print e
|
print e
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_schedule(self, export_source):
|
def get_schedule(self):
|
||||||
|
logger = logging.getLogger("Playout.get_schedule")
|
||||||
logger = logging.getLogger("fetch.get_schedule")
|
status, response = self.api_client.get_schedule();
|
||||||
|
|
||||||
"""
|
|
||||||
calculate start/end time range (format: YYYY-DD-MM-hh-mm-ss,YYYY-DD-MM-hh-mm-ss)
|
|
||||||
(seconds are ignored, just here for consistency)
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
self.export_source = export_source
|
|
||||||
|
|
||||||
tnow = time.localtime(time.time())
|
|
||||||
tstart = time.localtime(time.time() - 3600 * int(CACHE_FOR))
|
|
||||||
tend = time.localtime(time.time() + 3600 * int(PREPARE_AHEAD))
|
|
||||||
|
|
||||||
range = {}
|
|
||||||
range['start'] = "%04d-%02d-%02d-%02d-%02d" % (tstart[0], tstart[1], tstart[2], tstart[3], tstart[4])
|
|
||||||
range['end'] = "%04d-%02d-%02d-%02d-%02d" % (tend[0], tend[1], tend[2], tend[3], tend[4])
|
|
||||||
|
|
||||||
|
|
||||||
export_url = self.export_url + range['start'] + ',' + range['end'] + '/' + self.export_source
|
|
||||||
logger.info("export from %s", export_url)
|
|
||||||
|
|
||||||
try:
|
|
||||||
response_json = urllib.urlopen(export_url, self.api_auth).read()
|
|
||||||
response = json.read(response_json)
|
|
||||||
logger.info("export status %s", response['check'])
|
|
||||||
status = response['check']
|
|
||||||
schedule = response['playlists']
|
|
||||||
|
|
||||||
except Exception, e:
|
|
||||||
print e
|
|
||||||
status = 0
|
|
||||||
|
|
||||||
if status == 1:
|
if status == 1:
|
||||||
|
logger.info("dump serialized schedule to %s", self.schedule_file)
|
||||||
logger.info("dump serialized shedule to %s", self.schedule_file)
|
schedule = response['playlists']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
schedule_file = open(self.schedule_file, "w")
|
schedule_file = open(self.schedule_file, "w")
|
||||||
pickle.dump(schedule, schedule_file)
|
pickle.dump(schedule, schedule_file)
|
||||||
schedule_file.close()
|
schedule_file.close()
|
||||||
|
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print e
|
print lineno() + e
|
||||||
status = 0
|
status = 0
|
||||||
|
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -674,13 +592,12 @@ class Playout:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
The counterpart - the push loop periodically (minimal 1/2 of the playlist-grid)
|
The counterpart - the push loop periodically (minimal 1/2 of the playlist-grid)
|
||||||
checks if there is a playlist that should be sheduled at the current time.
|
checks if there is a playlist that should be scheduled at the current time.
|
||||||
If yes, the temporary liquidsoap playlist gets replaced with the corresponding one,
|
If yes, the temporary liquidsoap playlist gets replaced with the corresponding one,
|
||||||
then liquid is asked (via telnet) to reload and immediately play it
|
then liquidsoap is asked (via telnet) to reload and immediately play it.
|
||||||
"""
|
"""
|
||||||
def push(self, export_source):
|
def push(self, export_source):
|
||||||
logger = logging.getLogger("push")
|
logger = logging.getLogger("push")
|
||||||
|
|
||||||
|
|
||||||
self.export_source = export_source
|
self.export_source = export_source
|
||||||
self.cache_dir = CACHE_DIR + self.export_source + '/'
|
self.cache_dir = CACHE_DIR + self.export_source + '/'
|
||||||
|
@ -710,12 +627,10 @@ class Playout:
|
||||||
str_tcomming = "%04d-%02d-%02d-%02d-%02d" % (tcomming[0], tcomming[1], tcomming[2], tcomming[3], tcomming[4])
|
str_tcomming = "%04d-%02d-%02d-%02d-%02d" % (tcomming[0], tcomming[1], tcomming[2], tcomming[3], tcomming[4])
|
||||||
str_tcomming_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcomming[0], tcomming[1], tcomming[2], tcomming[3], tcomming[4], tcomming[5])
|
str_tcomming_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcomming[0], tcomming[1], tcomming[2], tcomming[3], tcomming[4], tcomming[5])
|
||||||
|
|
||||||
|
|
||||||
print '--'
|
print '--'
|
||||||
print str_tnow_s + ' now'
|
print str_tnow_s + ' now'
|
||||||
print str_tcomming_s + ' comming'
|
print str_tcomming_s + ' comming'
|
||||||
|
|
||||||
|
|
||||||
playnow = None
|
playnow = None
|
||||||
|
|
||||||
if self.schedule == None:
|
if self.schedule == None:
|
||||||
|
@ -731,19 +646,15 @@ class Playout:
|
||||||
playlist = self.schedule[pkey]
|
playlist = self.schedule[pkey]
|
||||||
|
|
||||||
if int(playlist['played']) != 1:
|
if int(playlist['played']) != 1:
|
||||||
|
|
||||||
print '!!!!!!!!!!!!!!!!!!!'
|
print '!!!!!!!!!!!!!!!!!!!'
|
||||||
print 'MATCH'
|
print 'MATCH'
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
ok we have a match, replace the current playlist and
|
ok we have a match, replace the current playlist and
|
||||||
force liquidsoap to refresh
|
force liquidsoap to refresh
|
||||||
Add a 'played' state to the list in schedule, so it is not called again
|
Add a 'played' state to the list in schedule, so it is not called again
|
||||||
in the next push loop
|
in the next push loop
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
ptype = playlist['subtype']
|
ptype = playlist['subtype']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -757,17 +668,15 @@ class Playout:
|
||||||
transmission_id = 0
|
transmission_id = 0
|
||||||
print e
|
print e
|
||||||
|
|
||||||
|
|
||||||
print 'Playlist id:',
|
print 'Playlist id:',
|
||||||
|
|
||||||
|
|
||||||
if(self.push_liquidsoap(pkey, ptype, user_id, playlist_id, transmission_id, self.push_ahead) == 1):
|
if(self.push_liquidsoap(pkey, ptype, user_id, playlist_id, transmission_id, self.push_ahead) == 1):
|
||||||
self.schedule[pkey]['played'] = 1
|
self.schedule[pkey]['played'] = 1
|
||||||
"""
|
"""
|
||||||
Call api to update schedule states and
|
Call api to update schedule states and
|
||||||
write changes back to cache file
|
write changes back to cache file
|
||||||
"""
|
"""
|
||||||
self.api_client.update_shedueled_item(int(playlist['schedule_id']), 1)
|
self.api_client.update_scheduled_item(int(playlist['schedule_id']), 1)
|
||||||
schedule_file = open(self.schedule_file, "w")
|
schedule_file = open(self.schedule_file, "w")
|
||||||
pickle.dump(self.schedule, schedule_file)
|
pickle.dump(self.schedule, schedule_file)
|
||||||
schedule_file.close()
|
schedule_file.close()
|
||||||
|
@ -779,7 +688,6 @@ class Playout:
|
||||||
|
|
||||||
|
|
||||||
def push_init(self, export_source):
|
def push_init(self, export_source):
|
||||||
|
|
||||||
logger = logging.getLogger("push_init")
|
logger = logging.getLogger("push_init")
|
||||||
|
|
||||||
self.export_source = export_source
|
self.export_source = export_source
|
||||||
|
@ -800,7 +708,6 @@ class Playout:
|
||||||
return schedule
|
return schedule
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def push_liquidsoap(self, pkey, ptype, user_id, playlist_id, transmission_id, push_ahead):
|
def push_liquidsoap(self, pkey, ptype, user_id, playlist_id, transmission_id, push_ahead):
|
||||||
logger = logging.getLogger("push_liquidsoap")
|
logger = logging.getLogger("push_liquidsoap")
|
||||||
|
|
||||||
|
@ -841,17 +748,9 @@ class Playout:
|
||||||
|
|
||||||
tn.write("exit\n")
|
tn.write("exit\n")
|
||||||
print tn.read_all()
|
print tn.read_all()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print 'sleeping for %s s' % (self.push_ahead)
|
print 'sleeping for %s s' % (self.push_ahead)
|
||||||
time.sleep(self.push_ahead)
|
time.sleep(self.push_ahead)
|
||||||
|
|
||||||
|
|
||||||
print 'sending "flip"'
|
print 'sending "flip"'
|
||||||
tn = telnetlib.Telnet(LS_HOST, 1234)
|
tn = telnetlib.Telnet(LS_HOST, 1234)
|
||||||
|
|
||||||
|
@ -868,7 +767,6 @@ class Playout:
|
||||||
tn.write("vars.transmission_id %s\n" % transmission_id)
|
tn.write("vars.transmission_id %s\n" % transmission_id)
|
||||||
tn.write("vars.playlist_type %s\n" % ptype)
|
tn.write("vars.playlist_type %s\n" % ptype)
|
||||||
|
|
||||||
|
|
||||||
# if(int(ptype) < 5):
|
# if(int(ptype) < 5):
|
||||||
# tn.write(self.export_source + '.flip')
|
# tn.write(self.export_source + '.flip')
|
||||||
# tn.write("\n")
|
# tn.write("\n")
|
||||||
|
@ -885,7 +783,6 @@ class Playout:
|
||||||
tn.write("live_in.stop")
|
tn.write("live_in.stop")
|
||||||
tn.write("\n")
|
tn.write("\n")
|
||||||
|
|
||||||
|
|
||||||
tn.write("exit\n")
|
tn.write("exit\n")
|
||||||
|
|
||||||
print tn.read_all()
|
print tn.read_all()
|
||||||
|
@ -899,7 +796,6 @@ class Playout:
|
||||||
|
|
||||||
def push_liquidsoap_legacy(self, pkey, ptype, p_id, user_id):
|
def push_liquidsoap_legacy(self, pkey, ptype, p_id, user_id):
|
||||||
logger = logging.getLogger("push_liquidsoap")
|
logger = logging.getLogger("push_liquidsoap")
|
||||||
|
|
||||||
logger.debug('trying to push %s to liquidsoap', pkey)
|
logger.debug('trying to push %s to liquidsoap', pkey)
|
||||||
|
|
||||||
self.export_source = export_source
|
self.export_source = export_source
|
||||||
|
@ -957,9 +853,6 @@ class Playout:
|
||||||
"""
|
"""
|
||||||
tn.write("pl.pl_id '%s'\n" % p_id)
|
tn.write("pl.pl_id '%s'\n" % p_id)
|
||||||
tn.write("pl.user_id '%s'\n" % user_id)
|
tn.write("pl.user_id '%s'\n" % user_id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tn.write("exit\n")
|
tn.write("exit\n")
|
||||||
|
|
||||||
print tn.read_all()
|
print tn.read_all()
|
||||||
|
@ -976,7 +869,7 @@ class Playout:
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Updates the jinles. Give comma separated list of jingle tracks
|
Updates the jingles. Give comma separated list of jingle tracks.
|
||||||
"""
|
"""
|
||||||
def update_jingles(self, options):
|
def update_jingles(self, options):
|
||||||
print 'jingles'
|
print 'jingles'
|
||||||
|
@ -985,7 +878,7 @@ class Playout:
|
||||||
print jingle_list
|
print jingle_list
|
||||||
for media_id in jingle_list:
|
for media_id in jingle_list:
|
||||||
# api path maybe should not be hard-coded
|
# api path maybe should not be hard-coded
|
||||||
src = OBP_API_BASE + 'api/pypo/get_media/' + str(media_id)
|
src = API_BASE + 'api/pypo/get_media/' + str(media_id)
|
||||||
print src
|
print src
|
||||||
# include the hourly jungles for the moment
|
# include the hourly jungles for the moment
|
||||||
dst = "%s%s/%s.mp3" % (self.file_dir, 'jingles/hourly', str(media_id))
|
dst = "%s%s/%s.mp3" % (self.file_dir, 'jingles/hourly', str(media_id))
|
||||||
|
@ -1001,9 +894,6 @@ class Playout:
|
||||||
print e
|
print e
|
||||||
logger.error("%s", e)
|
logger.error("%s", e)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def check_schedule(self, export_source):
|
def check_schedule(self, export_source):
|
||||||
logger = logging.getLogger("check_schedule")
|
logger = logging.getLogger("check_schedule")
|
||||||
|
@ -1021,8 +911,6 @@ class Playout:
|
||||||
logger.error("%s", e)
|
logger.error("%s", e)
|
||||||
schedule = None
|
schedule = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#for pkey in schedule:
|
#for pkey in schedule:
|
||||||
for pkey in sorted(schedule.iterkeys()):
|
for pkey in sorted(schedule.iterkeys()):
|
||||||
|
|
||||||
|
@ -1042,18 +930,17 @@ class Playout:
|
||||||
for media in playlist['medias']:
|
for media in playlist['medias']:
|
||||||
print media
|
print media
|
||||||
|
|
||||||
|
|
||||||
print
|
print
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
print
|
print
|
||||||
print '#########################################'
|
print '###########################################'
|
||||||
print '# *** pypo *** #'
|
print '# *** pypo *** #'
|
||||||
print '# obp python playout #'
|
print '# Liquidsoap + External Scheduler #'
|
||||||
print '#########################################'
|
print '# Playout System #'
|
||||||
|
print '###########################################'
|
||||||
print
|
print
|
||||||
|
|
||||||
# initialize
|
# initialize
|
||||||
|
@ -1141,5 +1028,5 @@ while run == True:
|
||||||
print e
|
print e
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
|
@ -10,8 +10,8 @@ This function acts as a gateway between liquidsoap and the obp-api.
|
||||||
Mainliy used to tell the plattform what pypo/LS does.
|
Mainliy used to tell the plattform what pypo/LS does.
|
||||||
|
|
||||||
Main case:
|
Main case:
|
||||||
- whenever LS starts playing a new track, its on_metadata callback calls
|
- whenever Liquidsoap starts playing a new track, its on_metadata callback calls
|
||||||
a function in ls (notify(m)) which then calls the pythin script here
|
a function in liquidsoap (notify(m)) which then calls the python script here
|
||||||
with the currently starting filename as parameter
|
with the currently starting filename as parameter
|
||||||
- this python script takes this parameter, tries to extract the actual
|
- this python script takes this parameter, tries to extract the actual
|
||||||
media id from it, and then calls back to obp via api to tell about
|
media id from it, and then calls back to obp via api to tell about
|
||||||
|
@ -42,11 +42,7 @@ from configobj import ConfigObj
|
||||||
from util import *
|
from util import *
|
||||||
from obp import *
|
from obp import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PYPO_VERSION = '0.9'
|
PYPO_VERSION = '0.9'
|
||||||
OBP_MIN_VERSION = 2010040501 # required obp version
|
|
||||||
|
|
||||||
|
|
||||||
#set up command-line options
|
#set up command-line options
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
|
@ -69,11 +65,9 @@ try:
|
||||||
config = ConfigObj('config.cfg')
|
config = ConfigObj('config.cfg')
|
||||||
TMP_DIR = config['tmp_dir']
|
TMP_DIR = config['tmp_dir']
|
||||||
BASE_URL = config['base_url']
|
BASE_URL = config['base_url']
|
||||||
OBP_API_BASE = BASE_URL + 'mod/medialibrary/'
|
API_BASE = BASE_URL + 'mod/medialibrary/'
|
||||||
EXPORT_SOURCE = config['export_source']
|
EXPORT_SOURCE = config['export_source']
|
||||||
|
API_KEY = config['api_key']
|
||||||
OBP_STATUS_URL = OBP_API_BASE + 'status/version/json'
|
|
||||||
OBP_API_KEY = config['obp_api_key']
|
|
||||||
|
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print 'error: ', e
|
print 'error: ', e
|
||||||
|
@ -86,31 +80,9 @@ class Global:
|
||||||
|
|
||||||
def selfcheck(self):
|
def selfcheck(self):
|
||||||
|
|
||||||
self.api_auth = urllib.urlencode({'api_key': OBP_API_KEY})
|
self.api_auth = urllib.urlencode({'api_key': API_KEY})
|
||||||
self.api_client = ApiClient(OBP_API_BASE, self.api_auth)
|
self.api_client = api_client.api_client_factory(config)
|
||||||
|
self.api_client.check_version()
|
||||||
obp_version = self.api_client.get_obp_version()
|
|
||||||
|
|
||||||
if obp_version == 0:
|
|
||||||
print '#################################################'
|
|
||||||
print 'Unable to get OBP version. Is OBP up and running?'
|
|
||||||
print '#################################################'
|
|
||||||
print
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
elif obp_version < OBP_MIN_VERSION:
|
|
||||||
print 'OBP version: ' + str(obp_version)
|
|
||||||
print 'OBP min-version: ' + str(OBP_MIN_VERSION)
|
|
||||||
print 'pypo not compatible with this version of OBP'
|
|
||||||
print
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
else:
|
|
||||||
print 'OBP API: ' + str(OBP_API_BASE)
|
|
||||||
print 'OBP version: ' + str(obp_version)
|
|
||||||
print 'OBP min-version: ' + str(OBP_MIN_VERSION)
|
|
||||||
print 'pypo is compatible with this version of OBP'
|
|
||||||
print
|
|
||||||
|
|
||||||
class Notify:
|
class Notify:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -118,8 +90,8 @@ class Notify:
|
||||||
self.tmp_dir = TMP_DIR
|
self.tmp_dir = TMP_DIR
|
||||||
self.export_source = EXPORT_SOURCE
|
self.export_source = EXPORT_SOURCE
|
||||||
|
|
||||||
self.api_auth = urllib.urlencode({'api_key': OBP_API_KEY})
|
self.api_auth = urllib.urlencode({'api_key': API_KEY})
|
||||||
self.api_client = ApiClient(OBP_API_BASE, self.api_auth)
|
self.api_client = api_client.api_client_factory(config)
|
||||||
|
|
||||||
|
|
||||||
def start_playing(self, options):
|
def start_playing(self, options):
|
||||||
|
@ -127,7 +99,6 @@ class Notify:
|
||||||
|
|
||||||
tnow = time.localtime(time.time())
|
tnow = time.localtime(time.time())
|
||||||
|
|
||||||
|
|
||||||
path = options
|
path = options
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -151,17 +122,10 @@ class Notify:
|
||||||
print "Media ID: ",
|
print "Media ID: ",
|
||||||
print id
|
print id
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# self.api_client.update_start_playing(id, self.export_source, path)
|
# self.api_client.update_start_playing(id, self.export_source, path)
|
||||||
|
|
||||||
txt = "test this update"
|
txt = "test this update"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Echo client program
|
# Echo client program
|
||||||
|
|
||||||
|
|
||||||
HOST = '172.16.16.128' # The remote host
|
HOST = '172.16.16.128' # The remote host
|
||||||
PORT = 50008 # The same port as used by the server
|
PORT = 50008 # The same port as used by the server
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
@ -200,12 +164,7 @@ class Notify:
|
||||||
if data == "session":
|
if data == "session":
|
||||||
print 'KKK'
|
print 'KKK'
|
||||||
|
|
||||||
|
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print 'DONE'
|
print 'DONE'
|
||||||
|
|
||||||
|
|
||||||
|
@ -237,7 +196,4 @@ while run == True:
|
||||||
print e
|
print e
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
|
@ -41,27 +41,20 @@ from util import *
|
||||||
from obp import *
|
from obp import *
|
||||||
from dls import *
|
from dls import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PYPO_VERSION = '0.9'
|
PYPO_VERSION = '0.9'
|
||||||
OBP_MIN_VERSION = 2010040501 # required obp version
|
|
||||||
|
|
||||||
|
|
||||||
#set up command-line options
|
# Set up command-line options
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
|
|
||||||
# help screeen / info
|
# help screeen / info
|
||||||
usage = "%prog [options]" + " - notification gateway"
|
usage = "%prog [options]" + " - notification gateway"
|
||||||
parser = OptionParser(usage=usage)
|
parser = OptionParser(usage=usage)
|
||||||
|
|
||||||
#options
|
# Options
|
||||||
#parser.add_option("-p", "--playing", help="Tell daddy what is playing right now", dest="playing", default=False, metavar=False)
|
#parser.add_option("-p", "--playing", help="Tell daddy what is playing right now", dest="playing", default=False, metavar=False)
|
||||||
|
|
||||||
parser.add_option("-p", "--playing", help="Tell daddy what is playing right now", default=False, action="store_true", dest="playing")
|
parser.add_option("-p", "--playing", help="Tell daddy what is playing right now", default=False, action="store_true", dest="playing")
|
||||||
|
|
||||||
|
|
||||||
parser.add_option("-t", "--playlist-type", help="Tell daddy what is playing right now", metavar="playlist_type")
|
parser.add_option("-t", "--playlist-type", help="Tell daddy what is playing right now", metavar="playlist_type")
|
||||||
|
|
||||||
parser.add_option("-M", "--media-id", help="Tell daddy what is playing right now", metavar="media_id")
|
parser.add_option("-M", "--media-id", help="Tell daddy what is playing right now", metavar="media_id")
|
||||||
parser.add_option("-U", "--user-id", help="Tell daddy what is playing right now", metavar="user_id")
|
parser.add_option("-U", "--user-id", help="Tell daddy what is playing right now", metavar="user_id")
|
||||||
parser.add_option("-P", "--playlist-id", help="Tell daddy what is playing right now", metavar="playlist_id")
|
parser.add_option("-P", "--playlist-id", help="Tell daddy what is playing right now", metavar="playlist_id")
|
||||||
|
@ -79,10 +72,8 @@ try:
|
||||||
config = ConfigObj('config.cfg')
|
config = ConfigObj('config.cfg')
|
||||||
TMP_DIR = config['tmp_dir']
|
TMP_DIR = config['tmp_dir']
|
||||||
BASE_URL = config['base_url']
|
BASE_URL = config['base_url']
|
||||||
OBP_API_BASE = BASE_URL + 'mod/medialibrary/'
|
API_BASE = BASE_URL + 'mod/medialibrary/'
|
||||||
|
API_KEY = config['api_key']
|
||||||
OBP_STATUS_URL = OBP_API_BASE + 'status/version/json'
|
|
||||||
OBP_API_KEY = config['obp_api_key']
|
|
||||||
|
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print 'error: ', e
|
print 'error: ', e
|
||||||
|
@ -95,54 +86,24 @@ class Global:
|
||||||
|
|
||||||
def selfcheck(self):
|
def selfcheck(self):
|
||||||
|
|
||||||
self.api_auth = urllib.urlencode({'api_key': OBP_API_KEY})
|
self.api_auth = urllib.urlencode({'api_key': API_KEY})
|
||||||
self.api_client = ApiClient(OBP_API_BASE, self.api_auth)
|
self.api_client = api_client.api_client_factory(config)
|
||||||
|
self.api_client.check_version()
|
||||||
|
|
||||||
obp_version = self.api_client.get_obp_version()
|
|
||||||
|
|
||||||
if obp_version == 0:
|
|
||||||
print '#################################################'
|
|
||||||
print 'Unable to get OBP version. Is OBP up and running?'
|
|
||||||
print '#################################################'
|
|
||||||
print
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
elif obp_version < OBP_MIN_VERSION:
|
|
||||||
print 'OBP version: ' + str(obp_version)
|
|
||||||
print 'OBP min-version: ' + str(OBP_MIN_VERSION)
|
|
||||||
print 'pypo not compatible with this version of OBP'
|
|
||||||
print
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
else:
|
|
||||||
print 'OBP API: ' + str(OBP_API_BASE)
|
|
||||||
print 'OBP version: ' + str(obp_version)
|
|
||||||
print 'OBP min-version: ' + str(OBP_MIN_VERSION)
|
|
||||||
print 'pypo is compatible with this version of OBP'
|
|
||||||
print
|
|
||||||
|
|
||||||
class Notify:
|
class Notify:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.tmp_dir = TMP_DIR
|
||||||
self.tmp_dir = TMP_DIR
|
self.api_auth = urllib.urlencode({'api_key': API_KEY})
|
||||||
|
self.api_client = api_client.api_client_factory(config)
|
||||||
self.api_auth = urllib.urlencode({'api_key': OBP_API_KEY})
|
|
||||||
self.api_client = ApiClient(OBP_API_BASE, self.api_auth)
|
|
||||||
|
|
||||||
self.dls_client = DlsClient('127.0.0.128', 50008, 'myusername', 'mypass')
|
self.dls_client = DlsClient('127.0.0.128', 50008, 'myusername', 'mypass')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def start_playing(self, options):
|
def start_playing(self, options):
|
||||||
logger = logging.getLogger("start_playing")
|
logger = logging.getLogger("start_playing")
|
||||||
|
|
||||||
tnow = time.localtime(time.time())
|
tnow = time.localtime(time.time())
|
||||||
|
|
||||||
#print options
|
#print options
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print '#################################################'
|
print '#################################################'
|
||||||
print '# calling obp to tell about what\'s playing #'
|
print '# calling obp to tell about what\'s playing #'
|
||||||
print '#################################################'
|
print '#################################################'
|
||||||
|
@ -170,23 +131,13 @@ class Notify:
|
||||||
response = self.api_client.update_start_playing(options.playlist_type, options.export_source, media_id, options.playlist_id, options.transmission_id)
|
response = self.api_client.update_start_playing(options.playlist_type, options.export_source, media_id, options.playlist_id, options.transmission_id)
|
||||||
|
|
||||||
print response
|
print response
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def start_playing_legacy(self, options):
|
def start_playing_legacy(self, options):
|
||||||
logger = logging.getLogger("start_playing")
|
logger = logging.getLogger("start_playing")
|
||||||
|
|
||||||
tnow = time.localtime(time.time())
|
tnow = time.localtime(time.time())
|
||||||
|
|
||||||
|
|
||||||
print '#################################################'
|
print '#################################################'
|
||||||
print '# calling obp to tell about what\'s playing #'
|
print '# calling obp to tell about what\'s playing #'
|
||||||
|
@ -248,10 +199,6 @@ class Notify:
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print e
|
print e
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
@ -270,7 +217,6 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
run = True
|
run = True
|
||||||
while run == True:
|
while run == True:
|
||||||
|
|
||||||
logger = logging.getLogger("pypo notify")
|
logger = logging.getLogger("pypo notify")
|
||||||
|
|
||||||
if options.playing:
|
if options.playing:
|
||||||
|
@ -278,8 +224,5 @@ while run == True:
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print e
|
print e
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
Binary file not shown.
|
@ -1,4 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
require_once("StoredFile.php");
|
||||||
|
require_once("BasicStor.php");
|
||||||
|
|
||||||
class ScheduleGroup {
|
class ScheduleGroup {
|
||||||
|
|
||||||
|
@ -320,6 +322,11 @@ class Schedule {
|
||||||
return $p_time;
|
return $p_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function PypoTimeToCcTime($p_time) {
|
||||||
|
$t = explode("-", $p_time);
|
||||||
|
return $t[0]."-".$t[1]."-".$t[2]." ".$t[3].":".$t[4].":00";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export the schedule in json formatted for pypo (the liquidsoap scheduler)
|
* Export the schedule in json formatted for pypo (the liquidsoap scheduler)
|
||||||
*
|
*
|
||||||
|
@ -330,35 +337,29 @@ class Schedule {
|
||||||
*/
|
*/
|
||||||
public static function ExportRangeAsJson($p_fromDateTime, $p_toDateTime)
|
public static function ExportRangeAsJson($p_fromDateTime, $p_toDateTime)
|
||||||
{
|
{
|
||||||
global $CC_CONFIG, $CC_DBC;
|
global $CC_CONFIG, $CC_DBC;
|
||||||
// $api_key = $this->input->post('api_key');
|
$range_start = Schedule::PypoTimeToCcTime($p_fromDateTime);
|
||||||
// if(!in_array($api_key, $CFG->ml_api_keys))
|
$range_end = Schedule::PypoTimeToCcTime($p_toDateTime);
|
||||||
// {
|
$range_dt = array('start' => $range_start, 'end' => $range_end);
|
||||||
// //header('HTTP/1.0 401 Unauthorized');
|
//var_dump($range_dt);
|
||||||
// //print 'You are not allowed to access this ressource. Sorry.';
|
|
||||||
// //exit;
|
|
||||||
// }
|
|
||||||
$range_start = Schedule::CcTimeToPypoTime($p_fromDateTime);
|
|
||||||
$range_end = Schedule::CcTimeToPypoTime($p_toDateTime);
|
|
||||||
$range_dt = array('start' => $range_start, 'end' => $range_end);
|
|
||||||
|
|
||||||
// Scheduler wants everything in a playlist
|
// Scheduler wants everything in a playlist
|
||||||
$data = Schedule::GetItems($p_fromDateTime, $p_toDateTime, true);
|
$data = Schedule::GetItems($range_start, $range_end, true);
|
||||||
//var_dump($data);
|
//echo "<pre>";var_dump($data);
|
||||||
$playlists = array();
|
$playlists = array();
|
||||||
|
|
||||||
if (is_array($data) && count($data) > 0)
|
if (is_array($data) && count($data) > 0)
|
||||||
{
|
{
|
||||||
foreach ($data as $dx)
|
foreach ($data as $dx)
|
||||||
{
|
{
|
||||||
// Is this the first item in the playlist?
|
// Is this the first item in the playlist?
|
||||||
$start = $dx['start'];
|
$start = $dx['start'];
|
||||||
// chop off subseconds
|
// chop off subseconds
|
||||||
$start = substr($start, 0, 19);
|
$start = substr($start, 0, 19);
|
||||||
|
|
||||||
// Start time is the array key, needs to be in the format "YYYY-MM-DD-HH-mm-ss"
|
// Start time is the array key, needs to be in the format "YYYY-MM-DD-HH-mm-ss"
|
||||||
$pkey = Schedule::CcTimeToPypoTime($start);
|
$pkey = Schedule::CcTimeToPypoTime($start);
|
||||||
$timestamp = strtotime($start);
|
$timestamp = strtotime($start);
|
||||||
$playlists[$pkey]['source'] = "PLAYLIST";
|
$playlists[$pkey]['source'] = "PLAYLIST";
|
||||||
$playlists[$pkey]['x_ident'] = $dx["playlist_id"];
|
$playlists[$pkey]['x_ident'] = $dx["playlist_id"];
|
||||||
$playlists[$pkey]['subtype'] = '1'; // Just needs to be between 1 and 4 inclusive
|
$playlists[$pkey]['subtype'] = '1'; // Just needs to be between 1 and 4 inclusive
|
||||||
|
@ -371,14 +372,14 @@ class Schedule {
|
||||||
|
|
||||||
foreach ($playlists as &$playlist)
|
foreach ($playlists as &$playlist)
|
||||||
{
|
{
|
||||||
$scheduleGroup = new ScheduleGroup($playlist["schedule_id"]);
|
$scheduleGroup = new ScheduleGroup($playlist["schedule_id"]);
|
||||||
$items = $scheduleGroup->getItems();
|
$items = $scheduleGroup->getItems();
|
||||||
$medias = array();
|
$medias = array();
|
||||||
$playlist['subtype'] = '1';
|
$playlist['subtype'] = '1';
|
||||||
foreach ($items as $item)
|
foreach ($items as $item)
|
||||||
{
|
{
|
||||||
$storedFile = StoredFile::Recall($item["file_id"]);
|
$storedFile = StoredFile::Recall($item["file_id"]);
|
||||||
$uri = $storedFile->getFileUrl();
|
$uri = $storedFile->getFileUrl();
|
||||||
$medias[] = array(
|
$medias[] = array(
|
||||||
'id' => $item["file_id"],
|
'id' => $item["file_id"],
|
||||||
'uri' => $uri,
|
'uri' => $uri,
|
||||||
|
@ -393,7 +394,7 @@ class Schedule {
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = array();
|
$result = array();
|
||||||
$result['status'] = array('range' => $range_dt, 'version' => 0.1);
|
$result['status'] = array('range' => $range_dt, 'version' => 0.2);
|
||||||
$result['playlists'] = $playlists;
|
$result['playlists'] = $playlists;
|
||||||
$result['check'] = 1;
|
$result['check'] = 1;
|
||||||
|
|
||||||
|
|
13
conf.php
13
conf.php
|
@ -23,6 +23,8 @@ $CC_CONFIG = array(
|
||||||
|
|
||||||
/* ================================================ storage configuration */
|
/* ================================================ storage configuration */
|
||||||
|
|
||||||
|
'apiKey' => array('AAA'),
|
||||||
|
|
||||||
// main directory for storing binary media files
|
// main directory for storing binary media files
|
||||||
'storageDir' => dirname(__FILE__).'/stor',
|
'storageDir' => dirname(__FILE__).'/stor',
|
||||||
|
|
||||||
|
@ -40,7 +42,8 @@ $CC_CONFIG = array(
|
||||||
"smartyTemplate" => dirname(__FILE__)."/htmlUI/templates",
|
"smartyTemplate" => dirname(__FILE__)."/htmlUI/templates",
|
||||||
"smartyTemplateCompiled" => dirname(__FILE__)."/htmlUI/templates_c",
|
"smartyTemplateCompiled" => dirname(__FILE__)."/htmlUI/templates_c",
|
||||||
'pearPath' => dirname(__FILE__).'/3rd_party/php/pear',
|
'pearPath' => dirname(__FILE__).'/3rd_party/php/pear',
|
||||||
|
'zendPath' => dirname(__FILE__).'/3rd_party/php/Zend',
|
||||||
|
|
||||||
// secret token cookie name
|
// secret token cookie name
|
||||||
'authCookieName'=> 'campcaster_session_id',
|
'authCookieName'=> 'campcaster_session_id',
|
||||||
|
|
||||||
|
@ -148,14 +151,16 @@ $CC_CONFIG['permSequence'] = $CC_CONFIG['permTable'].'_id';
|
||||||
$CC_CONFIG['subjSequence'] = $CC_CONFIG['subjTable'].'_id';
|
$CC_CONFIG['subjSequence'] = $CC_CONFIG['subjTable'].'_id';
|
||||||
$CC_CONFIG['smembSequence'] = $CC_CONFIG['smembTable'].'_id';
|
$CC_CONFIG['smembSequence'] = $CC_CONFIG['smembTable'].'_id';
|
||||||
|
|
||||||
// system users/groups - cannot be deleted
|
// System users/groups - they cannot be deleted
|
||||||
$CC_CONFIG['sysSubjs'] = array(
|
$CC_CONFIG['sysSubjs'] = array(
|
||||||
'root', /*$CC_CONFIG['AdminsGr'],*/ /*$CC_CONFIG['AllGr'],*/ $CC_CONFIG['StationPrefsGr']
|
'root', /*$CC_CONFIG['AdminsGr'],*/ /*$CC_CONFIG['AllGr'],*/ $CC_CONFIG['StationPrefsGr']
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add PEAR to the PHP path
|
// Add libs to the PHP path
|
||||||
$old_include_path = get_include_path();
|
$old_include_path = get_include_path();
|
||||||
set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath'].PATH_SEPARATOR.$old_include_path);
|
set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath']
|
||||||
|
.PATH_SEPARATOR.$CC_CONFIG['zendPath']
|
||||||
|
.PATH_SEPARATOR.$old_include_path);
|
||||||
|
|
||||||
// Check that all the required directories exist.
|
// Check that all the required directories exist.
|
||||||
//foreach (array('storageDir', 'bufferDir', 'transDir', 'accessDir', 'cronDir') as $d) {
|
//foreach (array('storageDir', 'bufferDir', 'transDir', 'accessDir', 'cronDir') as $d) {
|
||||||
|
|
|
@ -237,12 +237,12 @@ $start = intval(date('U'));
|
||||||
if ($DEBUG_IMPORT) {
|
if ($DEBUG_IMPORT) {
|
||||||
$testonly = false;
|
$testonly = false;
|
||||||
$importMode = "link";
|
$importMode = "link";
|
||||||
$files = array("/home/paul/music/Tom Petty/Anthology - Through the Years disc 2/13 - Into The Great Wide Open.ogg");
|
$files = array("/path/to/your/test/file.mp3");
|
||||||
$dsn = array('username' => 'test',
|
$dsn = array('username' => 'campcaster',
|
||||||
'password' => 'test',
|
'password' => 'campcaster',
|
||||||
'hostspec' => 'localhost',
|
'hostspec' => 'localhost',
|
||||||
'phptype' => 'pgsql',
|
'phptype' => 'pgsql',
|
||||||
'database' => 'Campcaster-paul');
|
'database' => 'campcaster');
|
||||||
} else {
|
} else {
|
||||||
$dsn = $CC_CONFIG['dsn'];
|
$dsn = $CC_CONFIG['dsn'];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue