diff --git a/airtime_mvc/application/controllers/LibraryController.php b/airtime_mvc/application/controllers/LibraryController.php
index 2b38349dd..15ae12944 100644
--- a/airtime_mvc/application/controllers/LibraryController.php
+++ b/airtime_mvc/application/controllers/LibraryController.php
@@ -385,6 +385,15 @@ class LibraryController extends Zend_Controller_Action
//TODO move this to the datatables row callback.
foreach ($r["aaData"] as &$data) {
+ foreach ($data as $k => &$v) {
+ if ($k != "image" && $k != "checkbox") {
+ $v = htmlspecialchars($v);
+ }
+ }
+ //TODO: Replace the above foreach loop with the line below when ticket
+ //CC-4896 is completed.
+ //$data = array_map('htmlspecialchars', $data);
+
if ($data['ftype'] == 'audioclip') {
$file = Application_Model_StoredFile::Recall($data['id']);
$scid = $file->getSoundCloudId();
@@ -429,7 +438,7 @@ class LibraryController extends Zend_Controller_Action
$formValues = $this->_getParam('data', null);
$formdata = array();
foreach ($formValues as $val) {
- $formdata[$val["name"]] = $val["value"];
+ $formdata[$val["name"]] = htmlspecialchars($val["value"]);
}
$file->setDbColMetadata($formdata);
diff --git a/airtime_mvc/application/controllers/PreferenceController.php b/airtime_mvc/application/controllers/PreferenceController.php
index 8617787df..11f036b25 100644
--- a/airtime_mvc/application/controllers/PreferenceController.php
+++ b/airtime_mvc/application/controllers/PreferenceController.php
@@ -238,7 +238,8 @@ class PreferenceController extends Zend_Controller_Action
Application_Model_Preference::SetEnableReplayGain($values["enableReplayGain"]);
Application_Model_Preference::setReplayGainModifier($values["replayGainModifier"]);
$md = array('schedule' => Application_Model_Schedule::getSchedule());
- Application_Model_RabbitMq::PushSchedule();
+ Application_Model_RabbitMq::SendMessageToPypo("update_schedule", $md);
+ //Application_Model_RabbitMq::PushSchedule();
}
Application_Model_StreamSetting::setOffAirMeta($values['offAirMeta']);
diff --git a/airtime_mvc/application/controllers/UserController.php b/airtime_mvc/application/controllers/UserController.php
index 395156f97..3faa1477f 100644
--- a/airtime_mvc/application/controllers/UserController.php
+++ b/airtime_mvc/application/controllers/UserController.php
@@ -115,7 +115,7 @@ class UserController extends Zend_Controller_Action
$post = $this->getRequest()->getPost();
$users = Application_Model_User::getUsersDataTablesInfo($post);
- die(json_encode($users));
+ $this->_helper->json->sendJson($users);
}
public function getUserDataAction()
diff --git a/airtime_mvc/application/layouts/scripts/layout.phtml b/airtime_mvc/application/layouts/scripts/layout.phtml
index 29d04c0d6..dedda7c88 100644
--- a/airtime_mvc/application/layouts/scripts/layout.phtml
+++ b/airtime_mvc/application/layouts/scripts/layout.phtml
@@ -24,7 +24,7 @@
diff --git a/airtime_mvc/application/logging/Logging.php b/airtime_mvc/application/logging/Logging.php
index dfe7e1fbe..65a8f6dc2 100644
--- a/airtime_mvc/application/logging/Logging.php
+++ b/airtime_mvc/application/logging/Logging.php
@@ -32,6 +32,8 @@ class Logging {
{
if (is_array($p_msg) || is_object($p_msg)) {
return print_r($p_msg, true);
+ } else if (is_bool($p_msg)) {
+ return $p_msg ? "true" : "false";
} else {
return $p_msg;
}
diff --git a/airtime_mvc/application/models/Schedule.php b/airtime_mvc/application/models/Schedule.php
index 09f66cd99..b4754d7f9 100644
--- a/airtime_mvc/application/models/Schedule.php
+++ b/airtime_mvc/application/models/Schedule.php
@@ -696,6 +696,10 @@ SQL;
'replay_gain' => $replay_gain,
'independent_event' => $independent_event,
);
+
+ if ($schedule_item['cue_in'] > $schedule_item['cue_out']) {
+ $schedule_item['cue_in'] = $schedule_item['cue_out'];
+ }
self::appendScheduleItem($data, $start, $schedule_item);
}
@@ -906,7 +910,6 @@ SQL;
self::createScheduledEvents($data, $range_start, $range_end);
self::foldData($data["media"]);
-
return $data;
}
diff --git a/airtime_mvc/application/models/Scheduler.php b/airtime_mvc/application/models/Scheduler.php
index 2530eb7bf..be9930402 100644
--- a/airtime_mvc/application/models/Scheduler.php
+++ b/airtime_mvc/application/models/Scheduler.php
@@ -136,13 +136,17 @@ class Application_Model_Scheduler
if ($type === "audioclip") {
$file = CcFilesQuery::create()->findPK($id, $this->con);
+ $storedFile = new Application_Model_StoredFile($file->getDbId());
if (is_null($file) || !$file->visible()) {
throw new Exception(_("A selected File does not exist!"));
} else {
$data = $this->fileInfo;
$data["id"] = $id;
- $data["cliplength"] = $file->getDbLength();
+ $data["cliplength"] = $storedFile->getRealClipLength(
+ $file->getDbCuein(),
+ $file->getDbCueout());
+
$data["cuein"] = $file->getDbCuein();
$data["cueout"] = $file->getDbCueout();
@@ -438,7 +442,6 @@ class Application_Model_Scheduler
}
foreach ($schedFiles as $file) {
-
$endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
//item existed previously and is being moved.
diff --git a/airtime_mvc/application/models/ShowBuilder.php b/airtime_mvc/application/models/ShowBuilder.php
index a1ef7c588..72a5f6ab0 100644
--- a/airtime_mvc/application/models/ShowBuilder.php
+++ b/airtime_mvc/application/models/ShowBuilder.php
@@ -227,7 +227,7 @@ class Application_Model_ShowBuilder
$row["endDate"] = $showEndDT->format("Y-m-d");
$row["endTime"] = $showEndDT->format("H:i");
$row["duration"] = floatval($showEndDT->format("U.u")) - floatval($showStartDT->format("U.u"));
- $row["title"] = $p_item["show_name"];
+ $row["title"] = htmlspecialchars($p_item["show_name"]);
$row["instance"] = intval($p_item["si_id"]);
$row["image"] = '';
diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php
index bd50f2826..9ca6ff32c 100644
--- a/airtime_mvc/application/models/StoredFile.php
+++ b/airtime_mvc/application/models/StoredFile.php
@@ -1285,6 +1285,14 @@ SQL;
}
}
}
+
+ public function getRealClipLength($p_cuein, $p_cueout) {
+ $sql = "SELECT :cueout::INTERVAL - :cuein::INTERVAL";
+
+ return Application_Common_Database::prepareAndExecute($sql, array(
+ ':cueout' => $p_cueout,
+ ':cuein' => $p_cuein), 'column');
+ }
}
class DeleteScheduledFileException extends Exception {}
diff --git a/airtime_mvc/application/models/User.php b/airtime_mvc/application/models/User.php
index 48a4c3e2f..f35c2fcec 100644
--- a/airtime_mvc/application/models/User.php
+++ b/airtime_mvc/application/models/User.php
@@ -343,6 +343,8 @@ class Application_Model_User
$res['iTotalDisplayRecords']--;
$res['iTotalRecords']--;
}
+
+ $record = array_map('htmlspecialchars', $record);
}
$res['aaData'] = array_values($res['aaData']);
diff --git a/airtime_mvc/application/views/scripts/form/edit-user.phtml b/airtime_mvc/application/views/scripts/form/edit-user.phtml
index cd4b70bd9..79a0081fc 100644
--- a/airtime_mvc/application/views/scripts/form/edit-user.phtml
+++ b/airtime_mvc/application/views/scripts/form/edit-user.phtml
@@ -1,4 +1,4 @@
- echo sprintf(_("%s's Settings"), $this->currentUser) ?>
+ echo sprintf(_("%s's Settings"), $this->escape($this->currentUser)) ?>
\ No newline at end of file
+
diff --git a/airtime_mvc/application/views/scripts/form/preferences_watched_dirs.phtml b/airtime_mvc/application/views/scripts/form/preferences_watched_dirs.phtml
index 4889892dd..ad8e77797 100644
--- a/airtime_mvc/application/views/scripts/form/preferences_watched_dirs.phtml
+++ b/airtime_mvc/application/views/scripts/form/preferences_watched_dirs.phtml
@@ -11,7 +11,7 @@
element->getElement('storageFolder')->hasErrors()) : ?>
element->getElement('storageFolder')->getMessages() as $error): ?>
-
+ - escape($error); ?>
@@ -29,7 +29,7 @@
element->getElement('watchedFolder')->hasErrors()) : ?>
element->getElement('watchedFolder')->getMessages() as $error): ?>
-
+ - escape($error); ?>
diff --git a/airtime_mvc/application/views/scripts/playlist/playlist.phtml b/airtime_mvc/application/views/scripts/playlist/playlist.phtml
index f8496d926..a516f2746 100644
--- a/airtime_mvc/application/views/scripts/playlist/playlist.phtml
+++ b/airtime_mvc/application/views/scripts/playlist/playlist.phtml
@@ -39,7 +39,7 @@ if (isset($this->obj)) {
diff --git a/airtime_mvc/public/js/airtime/preferences/streamsetting.js b/airtime_mvc/public/js/airtime/preferences/streamsetting.js
index 54bb986ca..6e76b693c 100644
--- a/airtime_mvc/public/js/airtime/preferences/streamsetting.js
+++ b/airtime_mvc/public/js/airtime/preferences/streamsetting.js
@@ -28,7 +28,7 @@ function rebuildStreamURL(ele){
}else{
streamurl = "http://"+host+":"+port+"/"
}
- div.find("#stream_url").html(streamurl)
+ div.find("#stream_url").text(streamurl)
}
function restrictOggBitrate(ele, on){
var div = ele.closest("div")
diff --git a/install_minimal/upgrades/airtime-2.3.0/data/upgrade.sql b/install_minimal/upgrades/airtime-2.3.0/data/upgrade.sql
index c2d176b23..cd34a28bb 100644
--- a/install_minimal/upgrades/airtime-2.3.0/data/upgrade.sql
+++ b/install_minimal/upgrades/airtime-2.3.0/data/upgrade.sql
@@ -15,6 +15,8 @@ INSERT INTO cc_stream_setting ("keyname", "value", "type") VALUES ('s3_admin_pas
UPDATE cc_music_dirs SET directory = directory || '/' where id in (select id from cc_music_dirs where substr(directory, length(directory)) != '/');
UPDATE cc_files SET filepath = substring(filepath from 2) where id in (select id from cc_files where substring(filepath from 1 for 1) = '/');
+UPDATE cc_files SET cueout = length where cueout = '00:00:00';
+
INSERT INTO cc_pref("keystr", "valstr") VALUES('locale', 'en_CA');
INSERT INTO cc_pref("subjid", "keystr", "valstr") VALUES(1, 'user_locale', 'en_CA');
diff --git a/python_apps/api_clients/api_client.py b/python_apps/api_clients/api_client.py
index 517870e45..b28a4ca5a 100644
--- a/python_apps/api_clients/api_client.py
+++ b/python_apps/api_clients/api_client.py
@@ -73,17 +73,26 @@ class ApcUrl(object):
else: return self.base_url
class ApiRequest(object):
- def __init__(self, name, url):
+ def __init__(self, name, url, logger=None):
self.name = name
self.url = url
self.__req = None
+ if logger is None: self.logger = logging
+ else: self.logger = logger
def __call__(self,_post_data=None, **kwargs):
# TODO : get rid of god damn urllib and replace everything with
# grequests or requests at least
final_url = self.url.params(**kwargs).url()
if _post_data is not None: _post_data = urllib.urlencode(_post_data)
- req = urllib2.Request(final_url, _post_data)
- response = urllib2.urlopen(req).read()
+ try:
+ req = urllib2.Request(final_url, _post_data)
+ response = urllib2.urlopen(req).read()
+ except Exception, e:
+ self.logger.error('Exception: %s', e)
+ import traceback
+ top = traceback.format_exc()
+ self.logger.error("traceback: %s", top)
+ response = ""
# Ghetto hack for now because we don't the content type we are getting
# (Pointless to look at mime since it's not being set correctly always)
try: return json.loads(response)
diff --git a/python_apps/pypo/airtime-liquidsoap-init-d b/python_apps/pypo/airtime-liquidsoap-init-d
index 4180d5c67..7096bc59c 100755
--- a/python_apps/pypo/airtime-liquidsoap-init-d
+++ b/python_apps/pypo/airtime-liquidsoap-init-d
@@ -28,10 +28,10 @@ start () {
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 signal after 10 seconds
+ timeout 10 /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
+ start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --pidfile $PIDFILE
rm -f $PIDFILE
}
diff --git a/python_apps/pypo/liquidsoap_scripts/liquidsoap_prepare_terminate.py b/python_apps/pypo/liquidsoap_scripts/liquidsoap_prepare_terminate.py
index e1dac82b6..2f632d9c7 100644
--- a/python_apps/pypo/liquidsoap_scripts/liquidsoap_prepare_terminate.py
+++ b/python_apps/pypo/liquidsoap_scripts/liquidsoap_prepare_terminate.py
@@ -6,14 +6,14 @@ try:
config = ConfigObj('/etc/airtime/pypo.cfg')
LS_HOST = config['ls_host']
LS_PORT = config['ls_port']
-
+
tn = telnetlib.Telnet(LS_HOST, LS_PORT)
tn.write("master_harbor.stop\n")
tn.write("live_dj_harbor.stop\n")
tn.write('exit\n')
tn.read_all()
-
+
except Exception, e:
print('Error loading config file: %s', e)
sys.exit()
-
\ No newline at end of file
+
diff --git a/python_apps/pypo/liquidsoap_scripts/ls_script.liq b/python_apps/pypo/liquidsoap_scripts/ls_script.liq
index cd01ad453..489d494a3 100644
--- a/python_apps/pypo/liquidsoap_scripts/ls_script.liq
+++ b/python_apps/pypo/liquidsoap_scripts/ls_script.liq
@@ -195,28 +195,81 @@ def check_dj_client(user,password) =
hd == "True"
end
-def append_dj_inputs(master_harbor_input_port, master_harbor_input_mount_point, dj_harbor_input_port, dj_harbor_input_mount_point, s) =
- if master_harbor_input_port != 0 and master_harbor_input_mount_point != "" and dj_harbor_input_port != 0 and dj_harbor_input_mount_point != "" then
- master_dj = mksafe(audio_to_stereo(input.harbor(id="master_harbor", master_harbor_input_mount_point, port=master_harbor_input_port, auth=check_master_dj_client,
- max=40., on_connect=master_dj_connect, on_disconnect=master_dj_disconnect)))
- dj_live = mksafe(audio_to_stereo(input.harbor(id="live_dj_harbor", dj_harbor_input_mount_point, port=dj_harbor_input_port, auth=check_dj_client,
- max=40., on_connect=live_dj_connect, on_disconnect=live_dj_disconnect)))
+def append_dj_inputs(master_harbor_input_port,
+ master_harbor_input_mount_point,
+ dj_harbor_input_port,
+ dj_harbor_input_mount_point,
+ s) =
+ if master_harbor_input_port != 0
+ and master_harbor_input_mount_point != ""
+ and dj_harbor_input_port != 0
+ and dj_harbor_input_mount_point != "" then
+
+ master_dj = mksafe(
+ audio_to_stereo(
+ input.harbor(id="master_harbor",
+ master_harbor_input_mount_point,
+ port=master_harbor_input_port,
+ auth=check_master_dj_client,
+ max=40.,
+ on_connect=master_dj_connect,
+ on_disconnect=master_dj_disconnect)))
+
+ dj_live = mksafe(
+ audio_to_stereo(
+ input.harbor(id="live_dj_harbor",
+ dj_harbor_input_mount_point,
+ port=dj_harbor_input_port,
+ auth=check_dj_client,
+ max=40.,
+ on_connect=live_dj_connect,
+ on_disconnect=live_dj_disconnect)))
ignore(output.dummy(master_dj, fallible=true))
ignore(output.dummy(dj_live, fallible=true))
- switch(id="master_dj_switch", track_sensitive=false, transitions=[transition, transition, transition], [({!master_dj_enabled},master_dj), ({!live_dj_enabled},dj_live), ({true}, s)])
+
+ switch(id="master_dj_switch",
+ track_sensitive=false,
+ transitions=[transition, transition, transition],
+ [({!master_dj_enabled},master_dj),
+ ({!live_dj_enabled},dj_live),
+ ({true}, s)])
+
elsif master_harbor_input_port != 0 and master_harbor_input_mount_point != "" then
- master_dj = mksafe(audio_to_stereo(input.harbor(id="master_harbor", master_harbor_input_mount_point, port=master_harbor_input_port, auth=check_master_dj_client,
- max=40., on_connect=master_dj_connect, on_disconnect=master_dj_disconnect)))
+ master_dj = mksafe(
+ audio_to_stereo(
+ input.harbor(id="master_harbor",
+ master_harbor_input_mount_point,
+ port=master_harbor_input_port,
+ auth=check_master_dj_client,
+ max=40.,
+ on_connect=master_dj_connect,
+ on_disconnect=master_dj_disconnect)))
+
ignore(output.dummy(master_dj, fallible=true))
- switch(id="master_dj_switch", track_sensitive=false, transitions=[transition, transition], [({!master_dj_enabled},master_dj), ({true}, s)])
+ switch(id="master_dj_switch",
+ track_sensitive=false,
+ transitions=[transition, transition],
+ [({!master_dj_enabled},master_dj), ({true}, s)])
+
elsif dj_harbor_input_port != 0 and dj_harbor_input_mount_point != "" then
- dj_live = mksafe(audio_to_stereo(input.harbor(id="live_dj_harbor", dj_harbor_input_mount_point, port=dj_harbor_input_port, auth=check_dj_client,
- max=40., on_connect=live_dj_connect, on_disconnect=live_dj_disconnect)))
+ dj_live = mksafe(
+ audio_to_stereo(
+ input.harbor(id="live_dj_harbor",
+ dj_harbor_input_mount_point,
+ port=dj_harbor_input_port,
+ auth=check_dj_client,
+ max=40.,
+ on_connect=live_dj_connect,
+ on_disconnect=live_dj_disconnect)))
ignore(output.dummy(dj_live, fallible=true))
- switch(id="live_dj_switch", track_sensitive=false, transitions=[transition, transition], [({!live_dj_enabled},dj_live), ({true}, s)])
+
+ switch(id="live_dj_switch",
+ track_sensitive=false,
+ transitions=[transition, transition],
+ [({!live_dj_enabled},dj_live), ({true}, s)])
else
s
end
diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py
index 1448c65da..b0cbdc69a 100644
--- a/python_apps/pypo/pypofetch.py
+++ b/python_apps/pypo/pypofetch.py
@@ -135,6 +135,7 @@ class PypoFetch(Thread):
try:
lock.acquire()
tn = telnetlib.Telnet(LS_HOST, LS_PORT)
+ self.logger.info(command)
tn.write(command)
tn.write('exit\n')
tn.read_all()
@@ -143,6 +144,24 @@ class PypoFetch(Thread):
finally:
lock.release()
+ @staticmethod
+ def telnet_send(logger, lock, commands):
+ try:
+ lock.acquire()
+
+ tn = telnetlib.Telnet(LS_HOST, LS_PORT)
+ for i in commands:
+ logger.info(i)
+ tn.write(i)
+
+ tn.write('exit\n')
+ tn.read_all()
+ except Exception, e:
+ logger.error(str(e))
+ finally:
+ lock.release()
+
+
@staticmethod
def switch_source(logger, lock, sourcename, status):
logger.debug('Switching source: %s to "%s" status', sourcename, status)
@@ -159,17 +178,26 @@ class PypoFetch(Thread):
else:
command += "stop\n"
- try:
- lock.acquire()
+ PypoFetch.telnet_send(logger, lock, [command])
- tn = telnetlib.Telnet(LS_HOST, LS_PORT)
- tn.write(command)
- tn.write('exit\n')
- tn.read_all()
- except Exception, e:
- logger.error(str(e))
- finally:
- lock.release()
+
+ #TODO: Merge this with switch_source
+ def switch_source_temp(self, sourcename, status):
+ self.logger.debug('Switching source: %s to "%s" status', sourcename, status)
+ command = "streams."
+ if sourcename == "master_dj":
+ command += "master_dj_"
+ elif sourcename == "live_dj":
+ command += "live_dj_"
+ elif sourcename == "scheduled_play":
+ command += "scheduled_play_"
+
+ if status == "on":
+ command += "start\n"
+ else:
+ command += "stop\n"
+
+ return command
"""
grabs some information that are needed to be set on bootstrap time
@@ -182,11 +210,18 @@ class PypoFetch(Thread):
self.logger.error('Unable to get bootstrap info.. Exiting pypo...')
else:
self.logger.debug('info:%s', info)
+ commands = []
for k, v in info['switch_status'].iteritems():
- self.switch_source(self.logger, self.telnet_lock, k, v)
- self.update_liquidsoap_stream_format(info['stream_label'])
- self.update_liquidsoap_station_name(info['station_name'])
- self.update_liquidsoap_transition_fade(info['transition_fade'])
+ commands.append(self.switch_source_temp(k, v))
+
+ stream_format = info['stream_label']
+ station_name = info['station_name']
+ fade = info['transition_fade']
+
+ commands.append(('vars.stream_metadata_type %s\n' % stream_format).encode('utf-8'))
+ commands.append(('vars.station_name %s\n' % station_name).encode('utf-8'))
+ commands.append(('vars.default_dj_fade %s\n' % fade).encode('utf-8'))
+ PypoFetch.telnet_send(self.logger, self.telnet_lock, commands)
def restart_liquidsoap(self):
@@ -330,8 +365,13 @@ class PypoFetch(Thread):
# updated.
current_time = time.time()
boot_up_time_command = "vars.bootup_time " + str(current_time) + "\n"
+ self.logger.info(boot_up_time_command)
tn.write(boot_up_time_command)
- tn.write("streams.connection_status\n")
+
+ connection_status = "streams.connection_status\n"
+ self.logger.info(connection_status)
+ tn.write(connection_status)
+
tn.write('exit\n')
output = tn.read_all()
@@ -356,6 +396,7 @@ class PypoFetch(Thread):
if(status == "true"):
self.api_client.notify_liquidsoap_status("OK", stream_id, str(fake_time))
+
def update_liquidsoap_stream_format(self, stream_format):
# Push stream metadata to liquidsoap
# TODO: THIS LIQUIDSOAP STUFF NEEDS TO BE MOVED TO PYPO-PUSH!!!