Merge branch 'master' of dev.sourcefabric.org:airtime
This commit is contained in:
commit
299dfdc18a
|
@ -2,9 +2,11 @@
|
||||||
class Application_Common_Database
|
class Application_Common_Database
|
||||||
{
|
{
|
||||||
public static function prepareAndExecute($sql, array $paramValueMap,
|
public static function prepareAndExecute($sql, array $paramValueMap,
|
||||||
$type='all', $fetchType=PDO::FETCH_ASSOC)
|
$type='all', $fetchType=PDO::FETCH_ASSOC, $con=null)
|
||||||
{
|
{
|
||||||
$con = Propel::getConnection();
|
if (is_null($con)) {
|
||||||
|
$con = Propel::getConnection();
|
||||||
|
}
|
||||||
$stmt = $con->prepare($sql);
|
$stmt = $con->prepare($sql);
|
||||||
foreach ($paramValueMap as $param => $v) {
|
foreach ($paramValueMap as $param => $v) {
|
||||||
$stmt->bindValue($param, $v);
|
$stmt->bindValue($param, $v);
|
||||||
|
|
|
@ -11,6 +11,9 @@ class Application_Model_Preference
|
||||||
private static function setValue($key, $value, $isUserValue = false, $userId = null)
|
private static function setValue($key, $value, $isUserValue = false, $userId = null)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$con = Propel::getConnection(CcPrefPeer::DATABASE_NAME);
|
||||||
|
$con->beginTransaction();
|
||||||
|
|
||||||
//called from a daemon process
|
//called from a daemon process
|
||||||
if (!class_exists("Zend_Auth", false) || !Zend_Auth::getInstance()->hasIdentity()) {
|
if (!class_exists("Zend_Auth", false) || !Zend_Auth::getInstance()->hasIdentity()) {
|
||||||
$id = NULL;
|
$id = NULL;
|
||||||
|
@ -35,10 +38,18 @@ class Application_Model_Preference
|
||||||
$paramMap[':id'] = $userId;
|
$paramMap[':id'] = $userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = Application_Common_Database::prepareAndExecute($sql, $paramMap, 'column');
|
$result = Application_Common_Database::prepareAndExecute($sql,
|
||||||
|
$paramMap,
|
||||||
|
'column',
|
||||||
|
PDO::FETCH_ASSOC,
|
||||||
|
$con);
|
||||||
|
|
||||||
$paramMap = array();
|
$paramMap = array();
|
||||||
if ($result == 1) {
|
if ($result > 1) {
|
||||||
|
//this case should not happen.
|
||||||
|
throw new Exception("Invalid number of results returned. Should be ".
|
||||||
|
"0 or 1, but is '$result' instead");
|
||||||
|
} elseif ($result == 1) {
|
||||||
// result found
|
// result found
|
||||||
if (is_null($id) || !$isUserValue) {
|
if (is_null($id) || !$isUserValue) {
|
||||||
// system pref
|
// system pref
|
||||||
|
@ -76,11 +87,17 @@ class Application_Model_Preference
|
||||||
$paramMap[':key'] = $key;
|
$paramMap[':key'] = $key;
|
||||||
$paramMap[':value'] = $value;
|
$paramMap[':value'] = $value;
|
||||||
|
|
||||||
Application_Common_Database::prepareAndExecute($sql, $paramMap, 'execute');
|
Application_Common_Database::prepareAndExecute($sql,
|
||||||
|
$paramMap,
|
||||||
|
'execute',
|
||||||
|
PDO::FETCH_ASSOC,
|
||||||
|
$con);
|
||||||
|
|
||||||
|
$con->commit();
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
$con->rollback();
|
||||||
header('HTTP/1.0 503 Service Unavailable');
|
header('HTTP/1.0 503 Service Unavailable');
|
||||||
Logging::info("Could not connect to database: ".$e->getMessage());
|
Logging::info("Database error: ".$e->getMessage());
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -557,6 +557,7 @@ class Application_Model_Scheduler
|
||||||
*/
|
*/
|
||||||
$instances = $this->getInstances($schedule["instance"]);
|
$instances = $this->getInstances($schedule["instance"]);
|
||||||
foreach($instances as $instance) {
|
foreach($instances as $instance) {
|
||||||
|
$linked = $instance->getCcShow()->isLinked();
|
||||||
if ($id !== 0) {
|
if ($id !== 0) {
|
||||||
$schedItem = CcScheduleQuery::create()->findPK($id, $this->con);
|
$schedItem = CcScheduleQuery::create()->findPK($id, $this->con);
|
||||||
/* We use the selected cursor's position to find the same
|
/* We use the selected cursor's position to find the same
|
||||||
|
@ -609,12 +610,31 @@ class Application_Model_Scheduler
|
||||||
$filesToInsert = array_merge($filesToInsert, $this->retrieveMediaFiles($media["id"], $media["type"]));
|
$filesToInsert = array_merge($filesToInsert, $this->retrieveMediaFiles($media["id"], $media["type"]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($filesToInsert as $file) {
|
foreach ($filesToInsert as $file) {
|
||||||
//item existed previously and is being moved.
|
//item existed previously and is being moved.
|
||||||
//need to keep same id for resources if we want REST.
|
//need to keep same id for resources if we want REST.
|
||||||
if (isset($file['sched_id'])) {
|
if (isset($file['sched_id'])) {
|
||||||
$sched = CcScheduleQuery::create()->findPk($file["sched_id"]);
|
$sched = CcScheduleQuery::create()->findPk($file["sched_id"]);
|
||||||
|
|
||||||
|
/* We need to keep a record of the original positon a track
|
||||||
|
* is being moved from so we can use it to retrieve the correct
|
||||||
|
* items in linked instances
|
||||||
|
*/
|
||||||
|
if (!isset($originalPosition)) {
|
||||||
|
$originalPosition = $sched->getDbPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we are moving an item in a linked show we need to get
|
||||||
|
* the relative item to move in each instance. We know what the
|
||||||
|
* relative item is by its position
|
||||||
|
*/
|
||||||
|
if ($linked && $moveAction) {
|
||||||
|
$sched = CcScheduleQuery::create()
|
||||||
|
->filterByDbInstanceId($instance->getDbId())
|
||||||
|
->filterByDbPosition($originalPosition)
|
||||||
|
->findOne();
|
||||||
|
}
|
||||||
$excludeIds[] = intval($sched->getDbId());
|
$excludeIds[] = intval($sched->getDbId());
|
||||||
|
|
||||||
$file["cliplength"] = $sched->getDbClipLength();
|
$file["cliplength"] = $sched->getDbClipLength();
|
||||||
|
@ -694,7 +714,6 @@ class Application_Model_Scheduler
|
||||||
//recalculate the start/end times after the inserted items.
|
//recalculate the start/end times after the inserted items.
|
||||||
foreach ($followingSchedItems as $item) {
|
foreach ($followingSchedItems as $item) {
|
||||||
$endTimeDT = $this->findEndTime($nextStartDT, $item->getDbClipLength());
|
$endTimeDT = $this->findEndTime($nextStartDT, $item->getDbClipLength());
|
||||||
|
|
||||||
$item->setDbStarts($nextStartDT);
|
$item->setDbStarts($nextStartDT);
|
||||||
$item->setDbEnds($endTimeDT);
|
$item->setDbEnds($endTimeDT);
|
||||||
$item->setDbPosition($pos);
|
$item->setDbPosition($pos);
|
||||||
|
|
|
@ -976,7 +976,7 @@ SQL;
|
||||||
$this->createRebroadcastInstances($showDay, $date, $ccShowInstance->getDbId());
|
$this->createRebroadcastInstances($showDay, $date, $ccShowInstance->getDbId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$start = $this->getNextMonthlyMonthlyRepeatDate($start, $timezone);
|
$start = $this->getNextMonthlyMonthlyRepeatDate($start, $timezone, $showDay->getDbStartTime());
|
||||||
}
|
}
|
||||||
$this->setNextRepeatingShowDate($start->format("Y-m-d"), $day, $show_id);
|
$this->setNextRepeatingShowDate($start->format("Y-m-d"), $day, $show_id);
|
||||||
}
|
}
|
||||||
|
@ -1034,7 +1034,7 @@ SQL;
|
||||||
* Enter description here ...
|
* Enter description here ...
|
||||||
* @param $start
|
* @param $start
|
||||||
*/
|
*/
|
||||||
private function getNextMonthlyMonthlyRepeatDate($start, $timezone)
|
private function getNextMonthlyMonthlyRepeatDate($start, $timezone, $startTime)
|
||||||
{
|
{
|
||||||
$dt = new DateTime($start->format("Y-m"), new DateTimeZone($timezone));
|
$dt = new DateTime($start->format("Y-m"), new DateTimeZone($timezone));
|
||||||
do {
|
do {
|
||||||
|
@ -1042,6 +1042,12 @@ SQL;
|
||||||
} while (!checkdate($dt->format("m"), $start->format("d"), $dt->format("Y")));
|
} while (!checkdate($dt->format("m"), $start->format("d"), $dt->format("Y")));
|
||||||
|
|
||||||
$dt->setDate($dt->format("Y"), $dt->format("m"), $start->format("d"));
|
$dt->setDate($dt->format("Y"), $dt->format("m"), $start->format("d"));
|
||||||
|
|
||||||
|
$startTime = explode(":", $startTime);
|
||||||
|
$hours = isset($startTime[0]) ? $startTime[0] : "00";
|
||||||
|
$minutes = isset($startTime[1]) ? $startTime[1] : "00";
|
||||||
|
$seconds = isset($startTime[2]) ? $startTime[2] : "00";
|
||||||
|
$dt->setTime($hours, $minutes, $seconds);
|
||||||
return $dt;
|
return $dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -214,6 +214,57 @@ class AirtimeIni
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//stupid hack found on http://stackoverflow.com/a/1268642/276949
|
||||||
|
//with some modifications: 1) Spaces are inserted in between sections and
|
||||||
|
//2) numeric values are not quoted.
|
||||||
|
public static function write_ini_file($assoc_arr, $path, $has_sections = false) {
|
||||||
|
$content = "";
|
||||||
|
|
||||||
|
if ($has_sections) {
|
||||||
|
$first_line = true;
|
||||||
|
foreach ($assoc_arr as $key=>$elem) {
|
||||||
|
if ($first_line) {
|
||||||
|
$content .= "[".$key."]\n";
|
||||||
|
$first_line = false;
|
||||||
|
} else {
|
||||||
|
$content .= "\n[".$key."]\n";
|
||||||
|
}
|
||||||
|
foreach ($elem as $key2=>$elem2) {
|
||||||
|
if(is_array($elem2))
|
||||||
|
{
|
||||||
|
for($i=0;$i<count($elem2);$i++)
|
||||||
|
{
|
||||||
|
$content .= $key2."[] = \"".$elem2[$i]."\"\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if($elem2=="") $content .= $key2." = \n";
|
||||||
|
else $content .= $key2." = ".$elem2."\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($assoc_arr as $key=>$elem) {
|
||||||
|
if(is_array($elem))
|
||||||
|
{
|
||||||
|
for($i=0;$i<count($elem);$i++)
|
||||||
|
{
|
||||||
|
$content .= $key."[] = \"".$elem[$i]."\"\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if($elem=="") $content .= $key." = \n";
|
||||||
|
else $content .= $key." = ".$elem."\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$handle = fopen($path, 'w')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!fwrite($handle, $content)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fclose($handle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After the configuration files have been copied to /etc/airtime,
|
* After the configuration files have been copied to /etc/airtime,
|
||||||
* this function will update them to values unique to this
|
* this function will update them to values unique to this
|
||||||
|
@ -223,10 +274,17 @@ class AirtimeIni
|
||||||
{
|
{
|
||||||
$api_key = AirtimeIni::GenerateRandomString();
|
$api_key = AirtimeIni::GenerateRandomString();
|
||||||
if (getenv("web") == "t"){
|
if (getenv("web") == "t"){
|
||||||
AirtimeIni::UpdateIniValue(AirtimeIni::CONF_FILE_AIRTIME, 'api_key', $api_key);
|
$ini = parse_ini_file(AirtimeIni::CONF_FILE_AIRTIME, true);
|
||||||
AirtimeIni::UpdateIniValue(AirtimeIni::CONF_FILE_AIRTIME, 'airtime_dir', AirtimeInstall::CONF_DIR_WWW);
|
|
||||||
|
$ini['general']['api_key'] = $api_key;
|
||||||
|
$ini['general']['airtime_dir'] = AirtimeInstall::CONF_DIR_WWW;
|
||||||
|
|
||||||
|
AirtimeIni::write_ini_file($ini, AirtimeIni::CONF_FILE_AIRTIME, true);
|
||||||
}
|
}
|
||||||
AirtimeIni::UpdateIniValue(AirtimeIni::CONF_FILE_API_CLIENT, 'api_key', "'$api_key'");
|
|
||||||
|
$ini = parse_ini_file(AirtimeIni::CONF_FILE_API_CLIENT);
|
||||||
|
$ini['api_key'] = "'$api_key'";
|
||||||
|
AirtimeIni::write_ini_file($ini, AirtimeIni::CONF_FILE_API_CLIENT, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function ReadPythonConfig($p_filename)
|
public static function ReadPythonConfig($p_filename)
|
||||||
|
|
|
@ -432,6 +432,7 @@ class PypoFetch(Thread):
|
||||||
for key in media:
|
for key in media:
|
||||||
media_item = media[key]
|
media_item = media[key]
|
||||||
if (media_item['type'] == 'file'):
|
if (media_item['type'] == 'file'):
|
||||||
|
self.sanity_check_media_item(media_item)
|
||||||
fileExt = os.path.splitext(media_item['uri'])[1]
|
fileExt = os.path.splitext(media_item['uri'])[1]
|
||||||
dst = os.path.join(download_dir, unicode(media_item['id']) + fileExt)
|
dst = os.path.join(download_dir, unicode(media_item['id']) + fileExt)
|
||||||
media_item['dst'] = dst
|
media_item['dst'] = dst
|
||||||
|
@ -455,6 +456,20 @@ class PypoFetch(Thread):
|
||||||
try: self.cache_cleanup(media)
|
try: self.cache_cleanup(media)
|
||||||
except Exception, e: self.logger.error("%s", e)
|
except Exception, e: self.logger.error("%s", e)
|
||||||
|
|
||||||
|
#do basic validation of file parameters. Useful for debugging
|
||||||
|
#purposes
|
||||||
|
def sanity_check_media_item(self, media_item):
|
||||||
|
start = datetime.strptime(media_item['start'], "%Y-%m-%d-%H-%M-%S")
|
||||||
|
end = datetime.strptime(media_item['end'], "%Y-%m-%d-%H-%M-%S")
|
||||||
|
|
||||||
|
length1 = (end - start).total_seconds()
|
||||||
|
length2 = media_item['cue_out'] - media_item['cue_in']
|
||||||
|
|
||||||
|
if abs(length2 - length1) > 1:
|
||||||
|
self.logger.error("end - start length: %s", length1)
|
||||||
|
self.logger.error("cue_out - cue_in length: %s", length2)
|
||||||
|
self.logger.error("Two lengths are not equal!!!")
|
||||||
|
|
||||||
def is_file_opened(self, path):
|
def is_file_opened(self, path):
|
||||||
#Capture stderr to avoid polluting py-interpreter.log
|
#Capture stderr to avoid polluting py-interpreter.log
|
||||||
proc = Popen(["lsof", path], stdout=PIPE, stderr=PIPE)
|
proc = Popen(["lsof", path], stdout=PIPE, stderr=PIPE)
|
||||||
|
|
Loading…
Reference in New Issue