Merge branch 'devel' of dev.sourcefabric.org:airtime into devel
This commit is contained in:
commit
a993691c6a
|
@ -27,6 +27,7 @@ class WebstreamController extends Zend_Controller_Action
|
||||||
$webstream->setDbName("Untitled Webstream");
|
$webstream->setDbName("Untitled Webstream");
|
||||||
|
|
||||||
$this->view->ws = new Application_Model_Webstream($webstream);
|
$this->view->ws = new Application_Model_Webstream($webstream);
|
||||||
|
$this->view->action = "new";
|
||||||
$this->view->html = $this->view->render('webstream/webstream.phtml');
|
$this->view->html = $this->view->render('webstream/webstream.phtml');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +42,7 @@ class WebstreamController extends Zend_Controller_Action
|
||||||
|
|
||||||
$webstream = CcWebstreamQuery::create()->findPK($id);
|
$webstream = CcWebstreamQuery::create()->findPK($id);
|
||||||
$this->view->ws = new Application_Model_Webstream($webstream);
|
$this->view->ws = new Application_Model_Webstream($webstream);
|
||||||
|
$this->view->action = "edit";
|
||||||
$this->view->html = $this->view->render('webstream/webstream.phtml');
|
$this->view->html = $this->view->render('webstream/webstream.phtml');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -893,7 +893,7 @@ class Application_Model_StoredFile
|
||||||
#something went wrong likely there wasn't enough space in the audio_stor to move the file too.
|
#something went wrong likely there wasn't enough space in the audio_stor to move the file too.
|
||||||
#warn the user that the file wasn't uploaded and they should check if there is enough disk space.
|
#warn the user that the file wasn't uploaded and they should check if there is enough disk space.
|
||||||
unlink($audio_file);//remove the file after failed rename
|
unlink($audio_file);//remove the file after failed rename
|
||||||
$result = array("code" => 108, "message" => "The file was not uploaded, this error can occur if the computer hard drive does not have enough disk space.");
|
$result = array("code" => 108, "message" => "The file was not uploaded, this error can occur if the computer hard drive does not have enough disk space or the stor directory does not have correct write permissions.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$result = array("code" => 110, "message" => "This file appears to be corrupted and will not be added to media library.");
|
$result = array("code" => 110, "message" => "This file appears to be corrupted and will not be added to media library.");
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<button id="ws_new" class="ui-button ui-widget ui-state-default" role="button" aria-disabled="false">New</button>
|
<button id="ws_new" class="ui-button ui-widget ui-state-default" role="button" aria-disabled="false">New</button>
|
||||||
<?php if (isset($this->ws)) : ?>
|
<?php if (isset($this->ws)) : ?>
|
||||||
<button id="ws_delete" class="ui-button ui-widget ui-state-default" role="button" aria-disabled="false">Delete</button>
|
<button id="ws_delete" class="ui-button ui-widget ui-state-default" <?php if ($this->action == "new"): ?>style="display:none;"<?php endif; ?> role="button" aria-disabled="false">Delete</button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (isset($this->ws)) : ?>
|
<?php if (isset($this->ws)) : ?>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
/var/log/airtime/zendphp.log {
|
||||||
|
compress
|
||||||
|
rotate 10
|
||||||
|
size 1000k
|
||||||
|
missingok
|
||||||
|
notifempty
|
||||||
|
sharedscripts
|
||||||
|
postrotate
|
||||||
|
chown www-data:www-data /var/log/airtime/
|
||||||
|
endscript
|
||||||
|
}
|
|
@ -360,7 +360,6 @@ var AIRTIME = (function(AIRTIME){
|
||||||
appendAddButton();
|
appendAddButton();
|
||||||
appendModAddButton();
|
appendModAddButton();
|
||||||
removeButtonCheck();
|
removeButtonCheck();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//sets events dynamically for playlist entries (each row in the playlist)
|
//sets events dynamically for playlist entries (each row in the playlist)
|
||||||
|
@ -600,6 +599,9 @@ var AIRTIME = (function(AIRTIME){
|
||||||
var $ws_id = $("#ws_id");
|
var $ws_id = $("#ws_id");
|
||||||
$ws_id.attr("value", json.streamId);
|
$ws_id.attr("value", json.streamId);
|
||||||
|
|
||||||
|
var $ws_id = $("#ws_delete");
|
||||||
|
$ws_id.show();
|
||||||
|
|
||||||
//redraw the library to show the new webstream
|
//redraw the library to show the new webstream
|
||||||
redrawLib();
|
redrawLib();
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,6 +178,9 @@ fi
|
||||||
if [ -e /etc/init.d/airtime-playout ]; then
|
if [ -e /etc/init.d/airtime-playout ]; then
|
||||||
invoke-rc.d airtime-playout stop > /dev/null 2>&1
|
invoke-rc.d airtime-playout stop > /dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
|
if [ -e /etc/init.d/airtime-playout ]; then
|
||||||
|
invoke-rc.d airtime-liquidsoap stop > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
#export these variables to make them available in sub bash scripts
|
#export these variables to make them available in sub bash scripts
|
||||||
export DO_UPGRADE
|
export DO_UPGRADE
|
||||||
|
|
|
@ -88,15 +88,16 @@ ln -sf /usr/lib/airtime/utils/airtime-test-stream /usr/bin/airtime-test-stream
|
||||||
echo "* Creating /var/log/airtime"
|
echo "* Creating /var/log/airtime"
|
||||||
mkdir -p /var/log/airtime
|
mkdir -p /var/log/airtime
|
||||||
chmod a+x /var/log/airtime
|
chmod a+x /var/log/airtime
|
||||||
touch /var/log/airtime/zendphp.log
|
chown www-data:www-data /var/log/airtime/
|
||||||
chown www-data:www-data /var/log/airtime/zendphp.log
|
|
||||||
chmod 644 /var/log/airtime/zendphp.log
|
|
||||||
|
|
||||||
if [ "$web" = "t" ]; then
|
if [ "$web" = "t" ]; then
|
||||||
echo "* Creating /usr/share/airtime"
|
echo "* Creating /usr/share/airtime"
|
||||||
rm -rf "/usr/share/airtime"
|
rm -rf "/usr/share/airtime"
|
||||||
mkdir -p /usr/share/airtime
|
mkdir -p /usr/share/airtime
|
||||||
cp -R $AIRTIMEROOT/airtime_mvc/* /usr/share/airtime/
|
cp -R $AIRTIMEROOT/airtime_mvc/* /usr/share/airtime/
|
||||||
|
rm -f /etc/logrotate.d/airtime-php
|
||||||
|
cp $AIRTIMEROOT/airtime_mvc/build/airtime-php.logrotate /etc/logrotate.d/airtime-php
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "* Creating /var/log/airtime"
|
echo "* Creating /var/log/airtime"
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: airtime-playout
|
||||||
|
# Required-Start: $local_fs $remote_fs $network $syslog
|
||||||
|
# Required-Stop: $local_fs $remote_fs $network $syslog
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: Liquidsoap daemon
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
USERID=pypo
|
||||||
|
GROUPID=pypo
|
||||||
|
NAME="Liquidsoap Playout Engine"
|
||||||
|
|
||||||
|
DAEMON=/usr/lib/airtime/pypo/bin/airtime-liquidsoap
|
||||||
|
PIDFILE=/var/run/airtime-liquidsoap.pid
|
||||||
|
|
||||||
|
start () {
|
||||||
|
start-stop-daemon --start --background --quiet --chuid $USERID:$GROUPID \
|
||||||
|
--nicelevel -15 --make-pidfile --pidfile $PIDFILE --startas $DAEMON
|
||||||
|
|
||||||
|
monit monitor airtime-liquidsoap >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
stop () {
|
||||||
|
monit unmonitor airtime-liquidsoap >/dev/null 2>&1
|
||||||
|
/usr/lib/airtime/airtime_virtualenv/bin/python /usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py
|
||||||
|
|
||||||
|
# Send TERM after 5 seconds, wait at most 30 seconds.
|
||||||
|
start-stop-daemon --stop --oknodo --retry 5 --quiet --pidfile $PIDFILE
|
||||||
|
rm -f $PIDFILE
|
||||||
|
}
|
||||||
|
|
||||||
|
start_no_monit() {
|
||||||
|
start-stop-daemon --start --background --quiet --chuid $USERID:$USERID --make-pidfile --pidfile $PIDFILE --startas $DAEMON
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case "${1:-''}" in
|
||||||
|
'stop')
|
||||||
|
echo -n "Stopping Liquidsoap: "
|
||||||
|
stop
|
||||||
|
echo "Done."
|
||||||
|
;;
|
||||||
|
'start')
|
||||||
|
echo -n "Starting Liquidsoap: "
|
||||||
|
start
|
||||||
|
echo "Done."
|
||||||
|
;;
|
||||||
|
'restart')
|
||||||
|
# restart commands here
|
||||||
|
echo -n "Restarting Liquidsoap: "
|
||||||
|
stop
|
||||||
|
start
|
||||||
|
echo "Done."
|
||||||
|
;;
|
||||||
|
'start-no-monit')
|
||||||
|
# restart commands here
|
||||||
|
echo -n "Starting $NAME: "
|
||||||
|
start_no_monit
|
||||||
|
echo "Done."
|
||||||
|
;;
|
||||||
|
|
||||||
|
*) # no parameter specified
|
||||||
|
echo "Usage: $SELF start|stop|restart"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
|
@ -9,80 +9,30 @@
|
||||||
# Short-Description: Manage airtime-playout daemon
|
# Short-Description: Manage airtime-playout daemon
|
||||||
### END INIT INFO
|
### END INIT INFO
|
||||||
|
|
||||||
USERID=pypo
|
USERID=root
|
||||||
ROOTUSERID=root
|
NAME="Airtime Scheduler Engine"
|
||||||
GROUPID=pypo
|
|
||||||
NAME=Airtime\ Playout
|
|
||||||
|
|
||||||
DAEMON0=/usr/lib/airtime/pypo/bin/airtime-playout
|
DAEMON=/usr/lib/airtime/pypo/bin/airtime-playout
|
||||||
PIDFILE0=/var/run/airtime-playout.pid
|
PIDFILE=/var/run/airtime-playout.pid
|
||||||
|
|
||||||
DAEMON1=/usr/lib/airtime/pypo/bin/airtime-liquidsoap
|
|
||||||
PIDFILE1=/var/run/airtime-liquidsoap.pid
|
|
||||||
|
|
||||||
liquidsoap_start () {
|
|
||||||
start-stop-daemon --start --background --quiet --chuid $USERID:$GROUPID \
|
|
||||||
--nicelevel -15 --make-pidfile --pidfile $PIDFILE1 --startas $DAEMON1
|
|
||||||
|
|
||||||
monit monitor airtime-liquidsoap >/dev/null 2>&1
|
|
||||||
}
|
|
||||||
|
|
||||||
liquidsoap_stop () {
|
|
||||||
monit unmonitor airtime-liquidsoap >/dev/null 2>&1
|
|
||||||
/usr/lib/airtime/airtime_virtualenv/bin/python /usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py
|
|
||||||
|
|
||||||
# Send TERM after 5 seconds, wait at most 30 seconds.
|
|
||||||
start-stop-daemon --stop --oknodo --retry TERM/5/0/30 --quiet --pidfile $PIDFILE1
|
|
||||||
rm -f $PIDFILE1
|
|
||||||
}
|
|
||||||
|
|
||||||
stop_pypo () {
|
|
||||||
monit unmonitor airtime-playout >/dev/null 2>&1
|
|
||||||
|
|
||||||
# Send TERM after 5 seconds, wait at most 30 seconds.
|
|
||||||
start-stop-daemon --stop --oknodo --retry TERM/5/0/30 --quiet --pidfile $PIDFILE0
|
|
||||||
rm -f $PIDFILE0
|
|
||||||
}
|
|
||||||
|
|
||||||
start () {
|
start () {
|
||||||
chown pypo:pypo /etc/airtime
|
chown pypo:pypo /etc/airtime
|
||||||
chown pypo:pypo /etc/airtime/liquidsoap.cfg
|
chown pypo:pypo /etc/airtime/liquidsoap.cfg
|
||||||
|
|
||||||
start-stop-daemon --start --background --quiet --chuid $ROOTUSERID:$ROOTUSERID --make-pidfile --pidfile $PIDFILE0 --startas $DAEMON0
|
start-stop-daemon --start --background --quiet --chuid $USERID:$USERID --make-pidfile --pidfile $PIDFILE --startas $DAEMON
|
||||||
monit monitor airtime-playout >/dev/null 2>&1
|
monit monitor airtime-playout >/dev/null 2>&1
|
||||||
|
|
||||||
liquidsoap_start
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stop () {
|
stop () {
|
||||||
# Send TERM after 5 seconds, wait at most 30 seconds.
|
# Send TERM after 5 seconds, wait at most 30 seconds.
|
||||||
|
|
||||||
monit unmonitor airtime-playout >/dev/null 2>&1
|
monit unmonitor airtime-playout >/dev/null 2>&1
|
||||||
start-stop-daemon --stop --oknodo --retry TERM/5/0/30 --quiet --pidfile $PIDFILE0
|
start-stop-daemon --stop --oknodo --retry TERM/5/0/30 --quiet --pidfile $PIDFILE
|
||||||
rm -f $PIDFILE0
|
rm -f $PIDFILE
|
||||||
|
|
||||||
liquidsoap_stop
|
|
||||||
}
|
|
||||||
|
|
||||||
monit_restart() {
|
|
||||||
|
|
||||||
start-stop-daemon --stop --oknodo --retry TERM/5/0/30 --quiet --pidfile $PIDFILE0
|
|
||||||
rm -f $PIDFILE0
|
|
||||||
|
|
||||||
/usr/lib/airtime/airtime_virtualenv/bin/python /usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py
|
|
||||||
start-stop-daemon --stop --oknodo --retry TERM/5/0/30 --quiet --pidfile $PIDFILE1
|
|
||||||
rm -f $PIDFILE1
|
|
||||||
|
|
||||||
start-stop-daemon --start --background --quiet --chuid $ROOTUSERID:$ROOTUSERID --make-pidfile --pidfile $PIDFILE0 --startas $DAEMON0
|
|
||||||
|
|
||||||
start-stop-daemon --start --background --quiet --chuid $USERID:$GROUPID \
|
|
||||||
--nicelevel -15 --make-pidfile --pidfile $PIDFILE1 --startas $DAEMON1
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
start_no_monit() {
|
start_no_monit() {
|
||||||
start-stop-daemon --start --background --quiet --chuid $ROOTUSERID:$ROOTUSERID --make-pidfile --pidfile $PIDFILE0 --startas $DAEMON0
|
start-stop-daemon --start --background --quiet --chuid $USERID:$USERID --make-pidfile --pidfile $PIDFILE --startas $DAEMON
|
||||||
liquidsoap_start
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case "${1:-''}" in
|
case "${1:-''}" in
|
||||||
|
@ -111,41 +61,13 @@ case "${1:-''}" in
|
||||||
start_no_monit
|
start_no_monit
|
||||||
echo "Done."
|
echo "Done."
|
||||||
;;
|
;;
|
||||||
'monit-restart')
|
|
||||||
# restart commands here
|
|
||||||
echo -n "Monit Restarting $NAME: "
|
|
||||||
monit_restart
|
|
||||||
echo "Done."
|
|
||||||
;;
|
|
||||||
'status')
|
'status')
|
||||||
# status commands here
|
# status commands here
|
||||||
/usr/bin/airtime-check-system
|
/usr/bin/airtime-check-system
|
||||||
;;
|
;;
|
||||||
'stop-liquidsoap')
|
|
||||||
echo -n "Stopping Liquidsoap: "
|
|
||||||
liquidsoap_stop
|
|
||||||
echo "Done."
|
|
||||||
;;
|
|
||||||
'start-liquidsoap')
|
|
||||||
echo -n "Starting Liquidsoap: "
|
|
||||||
liquidsoap_start
|
|
||||||
echo "Done."
|
|
||||||
;;
|
|
||||||
'restart-liquidsoap')
|
|
||||||
# restart commands here
|
|
||||||
echo -n "Restarting Liquidsoap: "
|
|
||||||
liquidsoap_stop
|
|
||||||
liquidsoap_start
|
|
||||||
echo "Done."
|
|
||||||
;;
|
|
||||||
'pypo-stop')
|
|
||||||
# restart commands here
|
|
||||||
echo -n "Restarting Pypo: "
|
|
||||||
stop_pypo
|
|
||||||
echo "Done."
|
|
||||||
;;
|
|
||||||
*) # no parameter specified
|
*) # no parameter specified
|
||||||
echo "Usage: $SELF start|stop|restart|status"
|
echo "Usage: $SELF start|stop|restart|status"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
esac
|
esac
|
||||||
|
|
|
@ -98,6 +98,7 @@ try:
|
||||||
|
|
||||||
#copy init.d script
|
#copy init.d script
|
||||||
shutil.copy(config["bin_dir"]+"/bin/airtime-playout-init-d", "/etc/init.d/airtime-playout")
|
shutil.copy(config["bin_dir"]+"/bin/airtime-playout-init-d", "/etc/init.d/airtime-playout")
|
||||||
|
shutil.copy(config["bin_dir"]+"/bin/airtime-liquidsoap-init-d", "/etc/init.d/airtime-liquidsoap")
|
||||||
|
|
||||||
#copy log rotate script
|
#copy log rotate script
|
||||||
shutil.copy(config["bin_dir"]+"/bin/liquidsoap_scripts/airtime-liquidsoap.logrotate", "/etc/logrotate.d/airtime-liquidsoap")
|
shutil.copy(config["bin_dir"]+"/bin/liquidsoap_scripts/airtime-liquidsoap.logrotate", "/etc/logrotate.d/airtime-liquidsoap")
|
||||||
|
|
|
@ -109,6 +109,7 @@ try:
|
||||||
|
|
||||||
if "airtime_service_start" in os.environ and os.environ["airtime_service_start"] == "t":
|
if "airtime_service_start" in os.environ and os.environ["airtime_service_start"] == "t":
|
||||||
print "* Waiting for pypo processes to start..."
|
print "* Waiting for pypo processes to start..."
|
||||||
|
subprocess.call("invoke-rc.d airtime-liquidsoap start-no-monit > /dev/null 2>&1", shell=True)
|
||||||
subprocess.call("invoke-rc.d airtime-playout start-no-monit > /dev/null 2>&1", shell=True)
|
subprocess.call("invoke-rc.d airtime-playout start-no-monit > /dev/null 2>&1", shell=True)
|
||||||
|
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
|
|
|
@ -13,6 +13,6 @@ if dj_type == '--master':
|
||||||
elif dj_type == '--dj':
|
elif dj_type == '--dj':
|
||||||
source_type = 'dj'
|
source_type = 'dj'
|
||||||
|
|
||||||
response = api_clients.check_live_stream_auth(username, password, type)
|
response = api_clients.check_live_stream_auth(username, password, source_type)
|
||||||
|
|
||||||
print response['msg']
|
print response['msg']
|
||||||
|
|
|
@ -237,7 +237,7 @@ def add_skip_command(s)
|
||||||
server.register(namespace="source",
|
server.register(namespace="source",
|
||||||
usage="skip",
|
usage="skip",
|
||||||
description="Skip the current song.",
|
description="Skip the current song.",
|
||||||
"skip",skip)
|
"skip",fun(s) -> begin log("source.skip") skip(s) end)
|
||||||
end
|
end
|
||||||
|
|
||||||
dyn_out = output.icecast(%wav,
|
dyn_out = output.icecast(%wav,
|
||||||
|
|
|
@ -57,55 +57,55 @@ ignore(output.dummy(stream_queue, fallible=true))
|
||||||
|
|
||||||
server.register(namespace="vars",
|
server.register(namespace="vars",
|
||||||
"pypo_data",
|
"pypo_data",
|
||||||
fun (s) -> begin pypo_data := s "Done" end)
|
fun (s) -> begin log("vars.pypo_data") pypo_data := s "Done" end)
|
||||||
server.register(namespace="vars",
|
server.register(namespace="vars",
|
||||||
"stream_metadata_type",
|
"stream_metadata_type",
|
||||||
fun (s) -> begin stream_metadata_type := int_of_string(s) s end)
|
fun (s) -> begin log("vars.stream_metadata_type") stream_metadata_type := int_of_string(s) s end)
|
||||||
server.register(namespace="vars",
|
server.register(namespace="vars",
|
||||||
"show_name",
|
"show_name",
|
||||||
fun (s) -> begin show_name := s s end)
|
fun (s) -> begin log("vars.show_name") show_name := s s end)
|
||||||
server.register(namespace="vars",
|
server.register(namespace="vars",
|
||||||
"station_name",
|
"station_name",
|
||||||
fun (s) -> begin station_name := s s end)
|
fun (s) -> begin log("vars.station_name") station_name := s s end)
|
||||||
server.register(namespace="vars",
|
server.register(namespace="vars",
|
||||||
"bootup_time",
|
"bootup_time",
|
||||||
fun (s) -> begin time := s s end)
|
fun (s) -> begin log("vars.bootup_time") time := s s end)
|
||||||
server.register(namespace="streams",
|
server.register(namespace="streams",
|
||||||
"connection_status",
|
"connection_status",
|
||||||
fun (s) -> begin "1:#{!s1_connected},2:#{!s2_connected},3:#{!s3_connected}" end)
|
fun (s) -> begin log("streams.connection_status") "1:#{!s1_connected},2:#{!s2_connected},3:#{!s3_connected}" end)
|
||||||
server.register(namespace="vars",
|
server.register(namespace="vars",
|
||||||
"default_dj_fade",
|
"default_dj_fade",
|
||||||
fun (s) -> begin default_dj_fade := float_of_string(s) s end)
|
fun (s) -> begin log("vars.default_dj_fade") default_dj_fade := float_of_string(s) s end)
|
||||||
|
|
||||||
server.register(namespace="dynamic_source",
|
server.register(namespace="dynamic_source",
|
||||||
description="Enable webstream output",
|
description="Enable webstream output",
|
||||||
usage='start',
|
usage='start',
|
||||||
"output_start",
|
"output_start",
|
||||||
fun (s) -> begin webstream_enabled := true "enabled" end)
|
fun (s) -> begin log("dynamic_source.output_start") webstream_enabled := true "enabled" end)
|
||||||
server.register(namespace="dynamic_source",
|
server.register(namespace="dynamic_source",
|
||||||
description="Enable webstream output",
|
description="Enable webstream output",
|
||||||
usage='stop',
|
usage='stop',
|
||||||
"output_stop",
|
"output_stop",
|
||||||
fun (s) -> begin webstream_enabled := false "disabled" end)
|
fun (s) -> begin log("dynamic_source.output_stop") webstream_enabled := false "disabled" end)
|
||||||
|
|
||||||
server.register(namespace="dynamic_source",
|
server.register(namespace="dynamic_source",
|
||||||
description="Set the cc_schedule row id",
|
description="Set the cc_schedule row id",
|
||||||
usage="id <id>",
|
usage="id <id>",
|
||||||
"id",
|
"id",
|
||||||
set_dynamic_source_id)
|
fun (s) -> begin log("dynamic_source.id") set_dynamic_source_id(s) end)
|
||||||
server.register(namespace="dynamic_source",
|
server.register(namespace="dynamic_source",
|
||||||
description="Start a new dynamic source.",
|
description="Start a new dynamic source.",
|
||||||
usage="start <uri>",
|
usage="start <uri>",
|
||||||
"read_start",
|
"read_start",
|
||||||
create_dynamic_source)
|
fun (s) -> begin log("dynamic_source.read_start") create_dynamic_source(s) end)
|
||||||
server.register(namespace="dynamic_source",
|
server.register(namespace="dynamic_source",
|
||||||
description="Stop a dynamic source.",
|
description="Stop a dynamic source.",
|
||||||
usage="stop <uri>",
|
usage="stop <uri>",
|
||||||
"read_stop",
|
"read_stop",
|
||||||
destroy_dynamic_source)
|
fun (s) -> begin log("dynamic_source.read_stop") destroy_dynamic_source(s) end)
|
||||||
|
|
||||||
default = amplify(id="silence_src", 0.00001, noise())
|
default = amplify(id="silence_src", 0.00001, noise())
|
||||||
default = rewrite_metadata([("artist","Airtime"), ("title", "offline")],default)
|
default = rewrite_metadata([("artist","Airtime"), ("title", "offline")], default)
|
||||||
ignore(output.dummy(default, fallible=true))
|
ignore(output.dummy(default, fallible=true))
|
||||||
|
|
||||||
master_dj_enabled = ref false
|
master_dj_enabled = ref false
|
||||||
|
@ -160,19 +160,18 @@ end
|
||||||
|
|
||||||
#auth function for live stream
|
#auth function for live stream
|
||||||
def check_master_dj_client(user,password) =
|
def check_master_dj_client(user,password) =
|
||||||
|
log("master connected")
|
||||||
#get the output of the php script
|
#get the output of the php script
|
||||||
ret = get_process_lines("python /usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_auth.py --master #{user} #{password}")
|
ret = get_process_lines("python /usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_auth.py --master #{user} #{password}")
|
||||||
#ret has now the value of the live client (dj1,dj2, or djx), or "ERROR"/"unknown" ...
|
#ret has now the value of the live client (dj1,dj2, or djx), or "ERROR"/"unknown" ...
|
||||||
ret = list.hd(ret)
|
ret = list.hd(ret)
|
||||||
|
|
||||||
#return true to let the client transmit data, or false to tell harbor to decline
|
#return true to let the client transmit data, or false to tell harbor to decline
|
||||||
if (ret == "True") then
|
ret == "True"
|
||||||
true
|
|
||||||
else
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_dj_client(user,password) =
|
def check_dj_client(user,password) =
|
||||||
|
log("live dj connected")
|
||||||
#get the output of the php script
|
#get the output of the php script
|
||||||
ret = get_process_lines("python /usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_auth.py --dj #{user} #{password}")
|
ret = get_process_lines("python /usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_auth.py --dj #{user} #{password}")
|
||||||
#ret has now the value of the live client (dj1,dj2, or djx), or "ERROR"/"unknown" ...
|
#ret has now the value of the live client (dj1,dj2, or djx), or "ERROR"/"unknown" ...
|
||||||
|
@ -223,32 +222,32 @@ server.register(namespace="streams",
|
||||||
description="Stop Master DJ source.",
|
description="Stop Master DJ source.",
|
||||||
usage="master_dj_stop",
|
usage="master_dj_stop",
|
||||||
"master_dj_stop",
|
"master_dj_stop",
|
||||||
fun (s) -> begin make_master_dj_unavailable() "Done." end)
|
fun (s) -> begin log("streams.master_dj_stop") make_master_dj_unavailable() "Done." end)
|
||||||
server.register(namespace="streams",
|
server.register(namespace="streams",
|
||||||
description="Start Master DJ source.",
|
description="Start Master DJ source.",
|
||||||
usage="master_dj_start",
|
usage="master_dj_start",
|
||||||
"master_dj_start",
|
"master_dj_start",
|
||||||
fun (s) -> begin make_master_dj_available() "Done." end)
|
fun (s) -> begin log("streams.master_dj_start") make_master_dj_available() "Done." end)
|
||||||
server.register(namespace="streams",
|
server.register(namespace="streams",
|
||||||
description="Stop Live DJ source.",
|
description="Stop Live DJ source.",
|
||||||
usage="live_dj_stop",
|
usage="live_dj_stop",
|
||||||
"live_dj_stop",
|
"live_dj_stop",
|
||||||
fun (s) -> begin make_live_dj_unavailable() "Done." end)
|
fun (s) -> begin log("streams.live_dj_stop") make_live_dj_unavailable() "Done." end)
|
||||||
server.register(namespace="streams",
|
server.register(namespace="streams",
|
||||||
description="Start Live DJ source.",
|
description="Start Live DJ source.",
|
||||||
usage="live_dj_start",
|
usage="live_dj_start",
|
||||||
"live_dj_start",
|
"live_dj_start",
|
||||||
fun (s) -> begin make_live_dj_available() "Done." end)
|
fun (s) -> begin log("streams.live_dj_start") make_live_dj_available() "Done." end)
|
||||||
server.register(namespace="streams",
|
server.register(namespace="streams",
|
||||||
description="Stop Scheduled Play source.",
|
description="Stop Scheduled Play source.",
|
||||||
usage="scheduled_play_stop",
|
usage="scheduled_play_stop",
|
||||||
"scheduled_play_stop",
|
"scheduled_play_stop",
|
||||||
fun (s) -> begin make_scheduled_play_unavailable() "Done." end)
|
fun (s) -> begin log("streams.scheduled_play_stop") make_scheduled_play_unavailable() "Done." end)
|
||||||
server.register(namespace="streams",
|
server.register(namespace="streams",
|
||||||
description="Start Scheduled Play source.",
|
description="Start Scheduled Play source.",
|
||||||
usage="scheduled_play_start",
|
usage="scheduled_play_start",
|
||||||
"scheduled_play_start",
|
"scheduled_play_start",
|
||||||
fun (s) -> begin make_scheduled_play_available() "Done." end)
|
fun (s) -> begin log("streams.scheduled_play_start") make_scheduled_play_available() "Done." end)
|
||||||
|
|
||||||
if output_sound_device then
|
if output_sound_device then
|
||||||
|
|
||||||
|
@ -303,7 +302,7 @@ if s1_enable == true then
|
||||||
else
|
else
|
||||||
s1_namespace := s1_mount
|
s1_namespace := s1_mount
|
||||||
end
|
end
|
||||||
server.register(namespace=!s1_namespace, "connected", fun (s) -> begin !s1_connected end)
|
server.register(namespace=!s1_namespace, "connected", fun (s) -> begin log("#{!s1_namespace}.connected") !s1_connected end)
|
||||||
output_to(s1_output, s1_type, s1_bitrate, s1_host, s1_port, s1_pass, s1_mount, s1_url, s1_description, s1_genre, s1_user, s, "1", s1_connected, s1_description)
|
output_to(s1_output, s1_type, s1_bitrate, s1_host, s1_port, s1_pass, s1_mount, s1_url, s1_description, s1_genre, s1_user, s, "1", s1_connected, s1_description)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -313,7 +312,7 @@ if s2_enable == true then
|
||||||
else
|
else
|
||||||
s2_namespace := s2_mount
|
s2_namespace := s2_mount
|
||||||
end
|
end
|
||||||
server.register(namespace=!s2_namespace, "connected", fun (s) -> begin !s2_connected end)
|
server.register(namespace=!s2_namespace, "connected", fun (s) -> begin log("#{!s2_namespace}.connected") !s2_connected end)
|
||||||
output_to(s2_output, s2_type, s2_bitrate, s2_host, s2_port, s2_pass, s2_mount, s2_url, s2_description, s2_genre, s2_user, s, "2", s2_connected, s2_description)
|
output_to(s2_output, s2_type, s2_bitrate, s2_host, s2_port, s2_pass, s2_mount, s2_url, s2_description, s2_genre, s2_user, s, "2", s2_connected, s2_description)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -324,7 +323,7 @@ if s3_enable == true then
|
||||||
else
|
else
|
||||||
s3_namespace := s3_mount
|
s3_namespace := s3_mount
|
||||||
end
|
end
|
||||||
server.register(namespace=!s3_namespace, "connected", fun (s) -> begin !s3_connected end)
|
server.register(namespace=!s3_namespace, "connected", fun (s) -> begin log("#{!s3_namespace}.connected") !s3_connected end)
|
||||||
output_to(s3_output, s3_type, s3_bitrate, s3_host, s3_port, s3_pass, s3_mount, s3_url, s3_description, s3_genre, s3_user, s, "3", s3_connected, s3_description)
|
output_to(s3_output, s3_type, s3_bitrate, s3_host, s3_port, s3_pass, s3_mount, s3_url, s3_description, s3_genre, s3_user, s, "3", s3_connected, s3_description)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
|
|
||||||
check process airtime-liquidsoap
|
check process airtime-liquidsoap
|
||||||
with pidfile "/var/run/airtime-liquidsoap.pid"
|
with pidfile "/var/run/airtime-liquidsoap.pid"
|
||||||
start program = "/etc/init.d/airtime-playout monit-restart" with timeout 5 seconds
|
start program = "/etc/init.d/airtime-liquidsoap start" with timeout 5 seconds
|
||||||
stop program = "/etc/init.d/airtime-playout stop"
|
stop program = "/etc/init.d/airtime-playout stop"
|
||||||
|
|
|
@ -130,7 +130,7 @@ def liquidsoap_running_test(telnet_lock, host, port, logger):
|
||||||
msg = "version\n"
|
msg = "version\n"
|
||||||
tn.write(msg)
|
tn.write(msg)
|
||||||
tn.write("exit\n")
|
tn.write("exit\n")
|
||||||
logger.info("Liquidsoap version %s", tn.read_all())
|
logger.info("Found: %s", tn.read_all())
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
logger.error(str(e))
|
logger.error(str(e))
|
||||||
success = False
|
success = False
|
||||||
|
@ -210,7 +210,7 @@ if __name__ == '__main__':
|
||||||
recorder.start()
|
recorder.start()
|
||||||
|
|
||||||
# all join() are commented out because we want to exit entire pypo
|
# all join() are commented out because we want to exit entire pypo
|
||||||
# if pypofetch is exiting
|
# if pypofetch is exiting
|
||||||
#pmh.join()
|
#pmh.join()
|
||||||
#recorder.join()
|
#recorder.join()
|
||||||
#pp.join()
|
#pp.join()
|
||||||
|
|
|
@ -8,6 +8,7 @@ import json
|
||||||
import telnetlib
|
import telnetlib
|
||||||
import copy
|
import copy
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
import subprocess
|
||||||
|
|
||||||
from Queue import Empty
|
from Queue import Empty
|
||||||
|
|
||||||
|
@ -86,7 +87,7 @@ class PypoFetch(Thread):
|
||||||
self.process_schedule(self.schedule_data)
|
self.process_schedule(self.schedule_data)
|
||||||
elif command == 'update_stream_setting':
|
elif command == 'update_stream_setting':
|
||||||
self.logger.info("Updating stream setting...")
|
self.logger.info("Updating stream setting...")
|
||||||
self.regenerateLiquidsoapConf(m['setting'])
|
self.regenerate_liquidsoap_conf(m['setting'])
|
||||||
elif command == 'update_stream_format':
|
elif command == 'update_stream_format':
|
||||||
self.logger.info("Updating stream format...")
|
self.logger.info("Updating stream format...")
|
||||||
self.update_liquidsoap_stream_format(m['stream_format'])
|
self.update_liquidsoap_stream_format(m['stream_format'])
|
||||||
|
@ -142,14 +143,14 @@ class PypoFetch(Thread):
|
||||||
def switch_source(logger, lock, sourcename, status):
|
def switch_source(logger, lock, sourcename, status):
|
||||||
logger.debug('Switching source: %s to "%s" status', sourcename, status)
|
logger.debug('Switching source: %s to "%s" status', sourcename, status)
|
||||||
command = "streams."
|
command = "streams."
|
||||||
if(sourcename == "master_dj"):
|
if sourcename == "master_dj":
|
||||||
command += "master_dj_"
|
command += "master_dj_"
|
||||||
elif(sourcename == "live_dj"):
|
elif sourcename == "live_dj":
|
||||||
command += "live_dj_"
|
command += "live_dj_"
|
||||||
elif(sourcename == "scheduled_play"):
|
elif sourcename == "scheduled_play":
|
||||||
command += "scheduled_play_"
|
command += "scheduled_play_"
|
||||||
|
|
||||||
if(status == "on"):
|
if status == "on":
|
||||||
command += "start\n"
|
command += "start\n"
|
||||||
else:
|
else:
|
||||||
command += "stop\n"
|
command += "stop\n"
|
||||||
|
@ -204,12 +205,41 @@ class PypoFetch(Thread):
|
||||||
fh.write(api_client.encode_to(buffer_str))
|
fh.write(api_client.encode_to(buffer_str))
|
||||||
fh.write("log_file = \"/var/log/airtime/pypo-liquidsoap/<script>.log\"\n");
|
fh.write("log_file = \"/var/log/airtime/pypo-liquidsoap/<script>.log\"\n");
|
||||||
fh.close()
|
fh.close()
|
||||||
# restarting pypo.
|
|
||||||
# we could just restart liquidsoap but it take more time somehow.
|
|
||||||
self.logger.info("Restarting pypo...")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
def regenerateLiquidsoapConf(self, setting):
|
def restart_liquidsoap(self):
|
||||||
|
|
||||||
|
self.telnet_lock.acquire()
|
||||||
|
try:
|
||||||
|
self.logger.info("Restarting Liquidsoap")
|
||||||
|
subprocess.call('/etc/init.d/airtime-liquidsoap restart', shell=True)
|
||||||
|
|
||||||
|
#Wait here and poll Liquidsoap until it has started up
|
||||||
|
self.logger.info("Waiting for Liquidsoap to start")
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
tn = telnetlib.Telnet(LS_HOST, LS_PORT)
|
||||||
|
tn.write("exit\n")
|
||||||
|
tn.read_all()
|
||||||
|
self.logger.info("Liquidsoap is up and running")
|
||||||
|
break
|
||||||
|
except Exception, e:
|
||||||
|
#sleep 0.5 seconds and try again
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
self.logger.error(e)
|
||||||
|
finally:
|
||||||
|
self.telnet_lock.release()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.set_bootstrap_variables()
|
||||||
|
#get the most up to date schedule, which will #initiate the process
|
||||||
|
#of making sure Liquidsoap is playing the schedule
|
||||||
|
self.manual_schedule_fetch()
|
||||||
|
except Exception, e:
|
||||||
|
self.logger.error(str(e))
|
||||||
|
|
||||||
|
def regenerate_liquidsoap_conf(self, setting):
|
||||||
existing = {}
|
existing = {}
|
||||||
# create a temp file
|
# create a temp file
|
||||||
|
|
||||||
|
@ -218,7 +248,8 @@ class PypoFetch(Thread):
|
||||||
fh = open('/etc/airtime/liquidsoap.cfg', 'r')
|
fh = open('/etc/airtime/liquidsoap.cfg', 'r')
|
||||||
except IOError, e:
|
except IOError, e:
|
||||||
#file does not exist
|
#file does not exist
|
||||||
self.write_liquidsoap_config(setting)
|
self.restart_liquidsoap()
|
||||||
|
return
|
||||||
|
|
||||||
self.logger.info("Reading existing config...")
|
self.logger.info("Reading existing config...")
|
||||||
# read existing conf file and build dict
|
# read existing conf file and build dict
|
||||||
|
@ -246,10 +277,10 @@ class PypoFetch(Thread):
|
||||||
existing[key] = value
|
existing[key] = value
|
||||||
fh.close()
|
fh.close()
|
||||||
|
|
||||||
# dict flag for any change in cofig
|
# dict flag for any change in config
|
||||||
change = {}
|
change = {}
|
||||||
# this flag is to detect disable -> disable change
|
# this flag is to detect disable -> disable change
|
||||||
# in that case, we don't want to restart even if there are chnges.
|
# in that case, we don't want to restart even if there are changes.
|
||||||
state_change_restart = {}
|
state_change_restart = {}
|
||||||
#restart flag
|
#restart flag
|
||||||
restart = False
|
restart = False
|
||||||
|
@ -284,7 +315,7 @@ class PypoFetch(Thread):
|
||||||
if stream not in change:
|
if stream not in change:
|
||||||
change[stream] = False
|
change[stream] = False
|
||||||
if not (s[u'value'] == existing[s[u'keyname']]):
|
if not (s[u'value'] == existing[s[u'keyname']]):
|
||||||
self.logger.info("Keyname: %s, Curent value: %s, New Value: %s", s[u'keyname'], existing[s[u'keyname']], s[u'value'])
|
self.logger.info("Keyname: %s, Current value: %s, New Value: %s", s[u'keyname'], existing[s[u'keyname']], s[u'value'])
|
||||||
change[stream] = True
|
change[stream] = True
|
||||||
|
|
||||||
# set flag change for sound_device alway True
|
# set flag change for sound_device alway True
|
||||||
|
@ -298,21 +329,21 @@ class PypoFetch(Thread):
|
||||||
restart = True
|
restart = True
|
||||||
# rewrite
|
# rewrite
|
||||||
if restart:
|
if restart:
|
||||||
self.write_liquidsoap_config(setting)
|
self.restart_liquidsoap()
|
||||||
else:
|
else:
|
||||||
self.logger.info("No change detected in setting...")
|
self.logger.info("No change detected in setting...")
|
||||||
self.update_liquidsoap_connection_status()
|
self.update_liquidsoap_connection_status()
|
||||||
|
|
||||||
def update_liquidsoap_connection_status(self):
|
def update_liquidsoap_connection_status(self):
|
||||||
"""
|
"""
|
||||||
updates the status of liquidsoap connection to the streaming server
|
updates the status of Liquidsoap connection to the streaming server
|
||||||
This fucntion updates the bootup time variable in liquidsoap script
|
This function updates the bootup time variable in Liquidsoap script
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.telnet_lock.acquire()
|
self.telnet_lock.acquire()
|
||||||
try:
|
try:
|
||||||
tn = telnetlib.Telnet(LS_HOST, LS_PORT)
|
tn = telnetlib.Telnet(LS_HOST, LS_PORT)
|
||||||
# update the boot up time of liquidsoap. Since liquidsoap is not restarting,
|
# update the boot up time of Liquidsoap. Since Liquidsoap is not restarting,
|
||||||
# we are manually adjusting the bootup time variable so the status msg will get
|
# we are manually adjusting the bootup time variable so the status msg will get
|
||||||
# updated.
|
# updated.
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
|
@ -474,13 +505,18 @@ class PypoFetch(Thread):
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
|
|
||||||
|
def manual_schedule_fetch(self):
|
||||||
|
success, self.schedule_data = self.api_client.get_schedule()
|
||||||
|
if success:
|
||||||
|
self.process_schedule(self.schedule_data)
|
||||||
|
return success
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
# Bootstrap: since we are just starting up, we need to grab the
|
# Bootstrap: since we are just starting up, we need to grab the
|
||||||
# most recent schedule. After that we can just wait for updates.
|
# most recent schedule. After that we can just wait for updates.
|
||||||
success, self.schedule_data = self.api_client.get_schedule()
|
success = self.manual_schedule_fetch()
|
||||||
if success:
|
if success:
|
||||||
self.logger.info("Bootstrap schedule received: %s", self.schedule_data)
|
self.logger.info("Bootstrap schedule received: %s", self.schedule_data)
|
||||||
self.process_schedule(self.schedule_data)
|
|
||||||
self.set_bootstrap_variables()
|
self.set_bootstrap_variables()
|
||||||
|
|
||||||
loops = 1
|
loops = 1
|
||||||
|
@ -506,9 +542,7 @@ class PypoFetch(Thread):
|
||||||
self.handle_message(message)
|
self.handle_message(message)
|
||||||
except Empty, e:
|
except Empty, e:
|
||||||
self.logger.info("Queue timeout. Fetching schedule manually")
|
self.logger.info("Queue timeout. Fetching schedule manually")
|
||||||
success, self.schedule_data = self.api_client.get_schedule()
|
self.manual_schedule_fetch()
|
||||||
if success:
|
|
||||||
self.process_schedule(self.schedule_data)
|
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
import traceback
|
import traceback
|
||||||
top = traceback.format_exc()
|
top = traceback.format_exc()
|
||||||
|
|
|
@ -390,7 +390,7 @@ class PypoPush(Thread):
|
||||||
elif media_item['type'] == 'stream_buffer_start':
|
elif media_item['type'] == 'stream_buffer_start':
|
||||||
self.start_web_stream_buffer(media_item)
|
self.start_web_stream_buffer(media_item)
|
||||||
elif media_item['type'] == "stream":
|
elif media_item['type'] == "stream":
|
||||||
if media_item['row_id'] != self.current_prebuffering_stream_id
|
if media_item['row_id'] != self.current_prebuffering_stream_id:
|
||||||
#this is called if the stream wasn't scheduled sufficiently ahead of time
|
#this is called if the stream wasn't scheduled sufficiently ahead of time
|
||||||
#so that the prebuffering stage could take effect. Let's do the prebuffering now.
|
#so that the prebuffering stage could take effect. Let's do the prebuffering now.
|
||||||
self.start_web_stream_buffer(media_item)
|
self.start_web_stream_buffer(media_item)
|
||||||
|
|
Loading…
Reference in New Issue