From a9fd71454b06a11bcb077dd40dddfab96c1d55a5 Mon Sep 17 00:00:00 2001 From: "paul.baranowski" <paul.baranowski@sourcefabric.org> Date: Sun, 6 Mar 2011 22:42:52 -0500 Subject: [PATCH 1/4] Removed BasicStor.php, it is no longer needed. --- application/models/BasicStor.php | 774 ------------------------------ application/models/Schedule.php | 5 +- application/models/StoredFile.php | 96 ---- 3 files changed, 2 insertions(+), 873 deletions(-) delete mode 100644 application/models/BasicStor.php diff --git a/application/models/BasicStor.php b/application/models/BasicStor.php deleted file mode 100644 index 6bc484131..000000000 --- a/application/models/BasicStor.php +++ /dev/null @@ -1,774 +0,0 @@ -<?php -/* - * Format of search criteria: hash, with following structure:<br> - * <ul> - * <li>filetype - string, type of searched files, - * meaningful values: 'audioclip', 'webstream', 'playlist', 'all'</li> - * <li>operator - string, type of conditions join - * (any condition matches / all conditions match), - * meaningful values: 'and', 'or', '' - * (may be empty or ommited only with less then 2 items in - * "conditions" field) - * </li> - * <li>orderby : string - metadata category for sorting (optional) - * or array of strings for multicolumn orderby - * [default: dc:creator, dc:source, dc:title] - * </li> - * <li>desc : boolean - flag for descending order (optional) - * or array of boolean for multicolumn orderby - * (it corresponds to elements of orderby field) - * [default: all ascending] - * </li> - * <li>conditions - array of hashes with structure: - * <ul> - * <li>cat - string, metadata category name</li> - * <li>op - string, operator - meaningful values: - * 'full', 'partial', 'prefix', '=', '<', - * '<=', '>', '>='</li> - * <li>val - string, search value</li> - * </ul> - * </li> - * </ul> - * <p> - * Format of search/browse results: hash, with following structure:<br> - * <ul> - * <li>results : array of gunids have found</li> - * <li>cnt : integer - number of matching items</li> - * </ul> - * - */ -define('GBERR_DENY', 40); -define('GBERR_FILEIO', 41); -define('GBERR_FILENEX', 42); -define('GBERR_FOBJNEX', 43); -define('GBERR_WRTYPE', 44); -define('GBERR_NONE', 45); -define('GBERR_AOBJNEX', 46); -define('GBERR_NOTF', 47); -define('GBERR_SESS', 48); -define('GBERR_PREF', 49); -define('GBERR_TOKEN', 50); -define('GBERR_PUT', 51); -define('GBERR_LOCK', 52); -define('GBERR_GUNID', 53); -define('GBERR_BGERR', 54); -define('GBERR_NOTIMPL', 69); - -require_once(dirname(__FILE__)."/Alib.php"); -require_once(dirname(__FILE__)."/StoredFile.php"); -require_once(dirname(__FILE__)."/Playlist.php"); - -/** - * Core of Airtime file storage module - * - * @package Airtime - * @subpackage StorageServer - * @copyright 2010 Sourcefabric O.P.S. - * @license http://www.gnu.org/licenses/gpl.txt - * @see Alib - */ -class BasicStor { - public $storId; - private $fileTypes; - - public function __construct() - { - $this->filetypes = array( - 'all'=>NULL, - 'audioclip'=>'audioclip', - 'webstream'=>'webstream', - 'playlist'=>'playlist', - ); - } - - - /* ----------------------------------------------------- put, access etc. */ - /** - * Check validity of access/put token - * - * @param string $token - * Access/put token - * @param string $type - * 'put'|'access'|'download' - * @return boolean - */ - public static function bsCheckToken($token, $type='put') - { - global $CC_CONFIG, $CC_DBC; - $cnt = $CC_DBC->getOne(" - SELECT count(token) FROM ".$CC_CONFIG['accessTable']." - WHERE token=x'{$token}'::bigint AND type='$type' - "); - if (PEAR::isError($cnt)) { - return FALSE; - } - return ($cnt == 1); - } - - - /** - * Create and return access link to real file - * - * @param string $realFname - * Local filepath to accessed file - * (NULL for only increase access counter, no symlink) - * @param string $ext - * Useful filename extension for accessed file - * @param int $gunid - * Global unique id - * (NULL for special files such exported playlists) - * @param string $type - * 'access'|'download' - * @param int $parent - * parent token (recursive access/release) - * @param int $owner - * Local user id - owner of token - * @return array - * array with: seekable filehandle, access token - */ - public static function bsAccess($realFname, $ext, $gunid, $type='access', - $parent='0', $owner=NULL) - { - global $CC_CONFIG, $CC_DBC; - if (!is_null($gunid)) { - $gunid = StoredFile::NormalizeGunid($gunid); - } - $token = StoredFile::CreateGunid(); - if (!is_null($realFname)) { - $linkFname = $CC_CONFIG['accessDir']."/$token.$ext"; - //broken links are ignored by the player, do not worry about it here - /* if (!is_file($realFname) && !is_link($realFname)) { - return PEAR::raiseError( - "BasicStor::bsAccess: real file not found ($realFname)", - GBERR_FILEIO); - } - */ - if (! @symlink($realFname, $linkFname)) { - return PEAR::raiseError( - "BasicStor::bsAccess: symlink create failed ($linkFname)", - GBERR_FILEIO); - } - } else { - $linkFname = NULL; - } - $escapedExt = pg_escape_string($ext); - $escapedType = pg_escape_string($type); - $CC_DBC->query("BEGIN"); - $gunidSql = (is_null($gunid) ? "NULL" : "x'{$gunid}'::bigint" ); - $ownerSql = (is_null($owner) ? "NULL" : "$owner" ); - $res = $CC_DBC->query(" - INSERT INTO ".$CC_CONFIG['accessTable']." - (gunid, token, ext, type, parent, owner, ts) - VALUES - ($gunidSql, x'$token'::bigint, - '$escapedExt', '$escapedType', x'{$parent}'::bigint, $ownerSql, now()) - "); - if (PEAR::isError($res)) { - $CC_DBC->query("ROLLBACK"); - return $res; - } - if (!is_null($gunid)) { - $res = $CC_DBC->query(" - UPDATE ".$CC_CONFIG['filesTable']." - SET currentlyAccessing=currentlyAccessing+1, mtime=now() - WHERE gunid=x'{$gunid}'::bigint - "); - } - if (PEAR::isError($res)) { - $CC_DBC->query("ROLLBACK"); - return $res; - } - $res = $CC_DBC->query("COMMIT"); - if (PEAR::isError($res)) { - return $res; - } - return array('fname'=>$linkFname, 'token'=>$token); - } - - - /** - * Release access link to real file - * - * @param string $token - * Access token - * @param string $type - * 'access'|'download' - * @return array - * gunid: string, global unique ID or real pathname of special file - * owner: int, local subject id of token owner - * realFname: string, real local pathname of accessed file - */ - public static function bsRelease($token, $type='access') - { - global $CC_CONFIG, $CC_DBC; - if (!BasicStor::bsCheckToken($token, $type)) { - return PEAR::raiseError( - "BasicStor::bsRelease: invalid token ($token)" - ); - } - $acc = $CC_DBC->getRow(" - SELECT to_hex(gunid)as gunid, ext, owner FROM ".$CC_CONFIG['accessTable']." - WHERE token=x'{$token}'::bigint AND type='$type' - "); - if (PEAR::isError($acc)) { - return $acc; - } - $ext = $acc['ext']; - $owner = $acc['owner']; - $linkFname = $CC_CONFIG['accessDir']."/$token.$ext"; - $realFname = readlink($linkFname); - if (file_exists($linkFname)) { - if(! @unlink($linkFname)){ - return PEAR::raiseError( - "BasicStor::bsRelease: unlink failed ($linkFname)", - GBERR_FILEIO); - } - } - $CC_DBC->query("BEGIN"); - if (!is_null($acc['gunid'])) { - $gunid = StoredFile::NormalizeGunid($acc['gunid']); - $res = $CC_DBC->query(" - UPDATE ".$CC_CONFIG['filesTable']." - SET currentlyAccessing=currentlyAccessing-1, mtime=now() - WHERE gunid=x'{$gunid}'::bigint AND currentlyAccessing>0 - "); - if (PEAR::isError($res)) { - $CC_DBC->query("ROLLBACK"); - return $res; - } - } - $res = $CC_DBC->query(" - DELETE FROM ".$CC_CONFIG['accessTable']." WHERE token=x'$token'::bigint - "); - if (PEAR::isError($res)) { - $CC_DBC->query("ROLLBACK"); - return $res; - } - $res = $CC_DBC->query("COMMIT"); - if (PEAR::isError($res)) { - return $res; - } - $res = array( - 'gunid' => (isset($gunid) ? $gunid : NULL ), - 'realFname' => $realFname, - 'owner' => $owner, - ); - return $res; - } - - - /* ----------------------------------------------------- metadata methods */ - - /** - * Method returning array with where-parts of sql queries - * - * @param array $conditions - * See 'conditions' field in search criteria format - * definition in class documentation - * @return array - * array of strings - WHERE-parts of SQL queries - */ - private function _makeWhereArr($conditions) - { - $ops = array('full'=>"='%s'", 'partial'=>"ILIKE '%%%s%%'", - 'prefix'=>"ILIKE '%s%%'", '<'=>"< '%s'", '='=>"= '%s'", - '>'=>"> '%s'", '<='=>"<= '%s'", '>='=>">= '%s'" - ); - $whereArr = array(); - if (is_array($conditions)) { - foreach ($conditions as $cond) { - $columnName = StoredFile::xmlCategoryToDbColumn($cond['cat']); - $op = strtolower($cond['op']); - $value = $cond['val']; - if (!empty($value)) { - $splittedQn = XML_Util::splitQualifiedName($catQn); - $catNs = $splittedQn['namespace']; - $cat = $splittedQn['localPart']; - $opVal = sprintf($ops[$op], pg_escape_string($value)); - // retype for timestamp value - if ($cat == 'mtime') { - switch ($op) { - case 'partial': - case 'prefix': - break; - default: - $retype = "::timestamp with time zone"; - $opVal = "$retype $opVal$retype"; - } - } - $sqlCond = " {$columnName} {$opVal}\n"; - $whereArr[] = $sqlCond; - } - } - } - return $whereArr; - } - - /** - * Search in local metadata database. - * - * @param array $criteria - * has the following structure:<br> - * <ul> - * <li>filetype - string, type of searched files, - * meaningful values: 'audioclip', 'webstream', 'playlist', 'all'</li> - * <li>operator - string, type of conditions join - * (any condition matches / all conditions match), - * meaningful values: 'and', 'or', '' - * (may be empty or ommited only with less then 2 items in - * "conditions" field) - * </li> - * <li>orderby : string - metadata category for sorting (optional) - * or array of strings for multicolumn orderby - * [default: dc:creator, dc:source, dc:title] - * </li> - * <li>desc : boolean - flag for descending order (optional) - * or array of boolean for multicolumn orderby - * (it corresponds to elements of orderby field) - * [default: all ascending] - * </li> - * <li>conditions - array of hashes with structure: - * <ul> - * <li>cat - string, metadata category name</li> - * <li>op - string, operator - meaningful values: - * 'full', 'partial', 'prefix', '=', '<', - * '<=', '>', '>='</li> - * <li>val - string, search value</li> - * </ul> - * </li> - * </ul> - * @param int $limit - * limit for result arrays (0 means unlimited) - * @param int $offset - * starting point (0 means without offset) - * @return array - * array of hashes, fields: - * cnt : integer - number of matching gunids - * of files have been found - * results : array of hashes: - * gunid: string - * type: string - audioclip | playlist | webstream - * title: string - dc:title from metadata - * creator: string - dc:creator from metadata - * source: string - dc:source from metadata - * length: string - dcterms:extent in extent format - */ - public function bsLocalSearch($criteria, $limit=0, $offset=0) - { - global $CC_CONFIG, $CC_DBC; - - // Input values - $filetype = (isset($criteria['filetype']) ? $criteria['filetype'] : 'all'); - $filetype = strtolower($filetype); - if (!array_key_exists($filetype, $this->filetypes)) { - return PEAR::raiseError(__FILE__.":".__LINE__.': unknown filetype in search criteria'); - } - $filetype = $this->filetypes[$filetype]; - $operator = (isset($criteria['operator']) ? $criteria['operator'] : 'and'); - $operator = strtolower($operator); - $conditions = (isset($criteria['conditions']) ? $criteria['conditions'] : array()); - - // Create the WHERE clause - this is the actual search part - $whereArr = $this->_makeWhereArr($conditions); - - // Metadata values to fetch - $metadataNames = array('dc:creator', 'dc:source', 'ls:track_num', 'dc:title', 'dcterms:extent'); - - // Order by clause - $orderby = TRUE; - $orderByAllowedValues = array('dc:creator', 'dc:source', 'dc:title', 'dcterms:extent', "ls:track_num"); - $orderByDefaults = array('dc:creator', 'dc:source', 'dc:title'); - if ((!isset($criteria['orderby'])) - || (is_array($criteria['orderby']) && (count($criteria['orderby'])==0))) { - // default ORDER BY - // PaulB: track number removed because it doesnt work yet because - // if track_num is not an integer (e.g. bad metadata like "1/20", - // or if the field is blank) the SQL statement gives an error. - //$orderbyQns = array('dc:creator', 'dc:source', 'ls:track_num', 'dc:title'); - $orderbyQns = $orderByDefaults; - } else { - // ORDER BY clause is given in the parameters. - - // Convert the parameter to an array if it isnt already. - $orderbyQns = $criteria['orderby']; - if (!is_array($orderbyQns)) { - $orderbyQns = array($orderbyQns); - } - - // Check that it has valid ORDER BY values, if not, revert - // to the default ORDER BY values. - foreach ($orderbyQns as $metadataTag) { - if (!in_array($metadataTag, $orderByAllowedValues)) { - $orderbyQns = $orderByDefaults; - break; - } - } - } - - $descA = (isset($criteria['desc']) ? $criteria['desc'] : NULL); - if (!is_array($descA)) { - $descA = array($descA); - } - - $orderBySql = array(); - // $dataName contains the names of the metadata columns we want to - // fetch. It is indexed numerically starting from 1, and the value - // in the array is the qualified name with ":" replaced with "_". - // e.g. "dc:creator" becomes "dc_creator". - foreach ($orderbyQns as $xmlTag) { - $columnName = StoredFile::xmlCategoryToDbColumn($xmlTag); - $orderBySql[] = $columnName; - } - - // Build WHERE clause - $whereClause = ""; - if (!is_null($filetype)) { - $whereClause .= "WHERE (ftype='$filetype')"; - } - else { - $whereClause .= "WHERE (ftype is NOT NULL)"; - } - if (count($whereArr) != 0) { - if ($operator == 'and') { - $whereClause .= " AND ((".join(") AND (", $whereArr)."))"; - } else { - $whereClause .= " AND ((".join(") OR (", $whereArr)."))"; - } - } - - // Final query - - //"dcterms:extent" => "length", - //"dc:title" => "track_title", - //"dc:creator" => "artist_name", - //dc:description - - $plSelect = "SELECT "; - $fileSelect = "SELECT "; - $_SESSION["br"] = ""; - foreach (Metadata::GetMapMetadataXmlToDb() as $key => $val){ - $_SESSION["br"] .= "key: ".$key." value:".$val.", "; - if($key === "dc:title"){ - $plSelect .= "name AS ".$val.", "; - $fileSelect .= $val.", "; - } - else if ($key === "dc:creator"){ - $plSelect .= "creator AS ".$val.", "; - $fileSelect .= $val.", "; - } - else if ($key === "dcterms:extent"){ - $plSelect .= "length, "; - $fileSelect .= "length, "; - } - else if ($key === "dc:description"){ - $plSelect .= "text(description) AS ".$val.", "; - $fileSelect .= $val.", "; - } - else { - $plSelect .= "NULL AS ".$val.", "; - $fileSelect .= $val.", "; - } - } - - $sql = "SELECT * FROM ((".$plSelect."PL.id, 'playlist' AS ftype - FROM ".$CC_CONFIG["playListTable"]." AS PL - LEFT JOIN ".$CC_CONFIG['playListTimeView']." PLT ON PL.id = PLT.id) - - UNION - - (".$fileSelect."id, ftype FROM ".$CC_CONFIG["filesTable"]." AS FILES)) AS RESULTS "; - - $sql .= $whereClause; - - if ($orderby) { - $sql .= " ORDER BY ".join(",", $orderBySql); - } - - $_SESSION["debugsql"] = $sql; - - $res = $CC_DBC->getAll($sql); - if (PEAR::isError($res)) { - return $res; - } - if (!is_array($res)) { - $res = array(); - } - - $count = count($res); - $_SESSION["br"] .= " COUNT: ".$count; - - $res = array_slice($res, $offset != 0 ? $offset : 0, $limit != 0 ? $limit : 10); - - $eres = array(); - foreach ($res as $it) { - $eres[] = array( - 'id' => $it['id'], - 'type' => strtolower($it['ftype']), - 'title' => $it['track_title'], - 'creator' => $it['artist_name'], - 'duration' => $it['length'], - 'source' => $it['album_title'], - 'track_num' => $it['track_number'], - ); - } - return array('results'=>$eres, 'cnt'=>$count); - } - - - /** - * Return values of specified metadata category - * - * @param string $category - * metadata category name with or without namespace prefix (dc:title, author) - * @param int $limit - * limit for result arrays (0 means unlimited) - * @param int $offset - * starting point (0 means without offset) - * @param array $criteria - * see bsLocalSearch method - * @return array - * hash, fields: - * results : array with found values - * cnt : integer - number of matching values - */ - public function bsBrowseCategory($category, $limit=0, $offset=0, $criteria=NULL) - { - global $CC_CONFIG, $CC_DBC; - - $pl_cat = array( - "dcterms:extent" => "length", - "dc:title" => "name", - "dc:creator" => "creator", - "dc:description" => "description" - ); - - $category = strtolower($category); - $columnName = StoredFile::xmlCategoryToDbColumn($category); - if (is_null($columnName)) { - return new PEAR_Error(__FILE__.":".__LINE__." -- could not map XML category to DB column."); - } - $sql = "SELECT DISTINCT $columnName FROM ".$CC_CONFIG["filesTable"]; - $limitPart = ($limit != 0 ? " LIMIT $limit" : '' ). - ($offset != 0 ? " OFFSET $offset" : '' ); - $countRowsSql = "SELECT COUNT(DISTINCT $columnName) FROM ".$CC_CONFIG["filesTable"]; - - //$_SESSION["br"] = "in Browse Category: ".$category; - $cnt = $CC_DBC->GetOne($countRowsSql); - if (PEAR::isError($cnt)) { - return $cnt; - } - $res = $CC_DBC->getCol($sql.$limitPart); - if (PEAR::isError($res)) { - return $res; - } - if (!is_array($res)) { - $res = array(); - } - - if (array_key_exists($category, $pl_cat) && $category !== "dcterms:extent") { - $columnName = $pl_cat[$category]; - - $sql = "SELECT DISTINCT $columnName FROM ".$CC_CONFIG["playListTable"]; - $limitPart = ($limit != 0 ? " LIMIT $limit" : '' ). - ($offset != 0 ? " OFFSET $offset" : '' ); - $countRowsSql = "SELECT COUNT(DISTINCT $columnName) FROM ".$CC_CONFIG["playListTable"]; - - $pl_cnt = $CC_DBC->GetOne($countRowsSql); - if (PEAR::isError($cnt)) { - return $cnt; - } - $pl_res = $CC_DBC->getCol($sql.$limitPart); - if (PEAR::isError($res)) { - return $pl_res; - } - if (!is_array($pl_res)) { - $pl_res = array(); - } - - $res = array_merge($res, $pl_res); - $res = array_slice($res, 0, $limit); - $cnt = $cnt + $pl_cnt; - } - else if ($category === "dcterms:extent") { - $columnName = $pl_cat[$category]; - - $limitPart = ($limit != 0 ? " LIMIT $limit" : '' ). - ($offset != 0 ? " OFFSET $offset" : '' ); - - $sql = "SELECT DISTINCT length AS $columnName FROM ".$CC_CONFIG["playListTimeView"]; - - $countRowsSql = "SELECT COUNT(DISTINCT length) FROM ".$CC_CONFIG["playListTimeView"]; - - $pl_cnt = $CC_DBC->GetOne($countRowsSql); - if (PEAR::isError($cnt)) { - return $cnt; - } - $pl_res = $CC_DBC->getCol($sql.$limitPart); - if (PEAR::isError($res)) { - return $pl_res; - } - if (!is_array($pl_res)) { - $pl_res = array(); - } - - $res = array_merge($res, $pl_res); - $res = array_slice($res, 0, $limit); - $cnt = $cnt + $pl_cnt; - } - - return array('results'=>$res, 'cnt'=>$cnt); - } - - - /* ---------------------------------------------------- methods4playlists */ - - /* ================================================== "protected" methods */ - /** - * Check authorization - auxiliary method - * - * @param array $acts - * Array of actions - * @param array $pars - * Array of parameters - e.g. ids - * @param string $sessid - * Session id - * @return true|PEAR_Error - */ - public static function Authorize($acts, $pars, $sessid='') - { - $userid = Alib::GetSessUserId($sessid); - if (PEAR::isError($userid)) { - return $userid; - } - if (is_null($userid)) { - return PEAR::raiseError( - "BasicStor::Authorize: invalid session", GBERR_DENY); - } - if (!is_array($pars)) { - $pars = array($pars); - } - if (!is_array($acts)) { - $acts = array($acts); - } - $perm = true; - if ($perm) { - return TRUE; - } - $adesc = "[".join(',',$acts)."]"; - return PEAR::raiseError( - "BasicStor::$adesc: access denied", GBERR_DENY); - } - - - /** - * Set playlist edit flag - * - * @param string $p_playlistId - * Playlist unique ID - * @param boolean $p_val - * Set/clear of edit flag - * @param string $p_sessid - * Session id - * @param int $p_subjid - * Subject id (if sessid is not specified) - * @return boolean - * previous state - */ - public function setEditFlag($p_playlistId, $p_val=TRUE, $p_sessid=NULL, $p_subjid=NULL) - { - if (!is_null($p_sessid)) { - $p_subjid = Alib::GetSessUserId($p_sessid); - if (PEAR::isError($p_subjid)) { - return $p_subjid; - } - } - $pl = Playlist::Recall($p_playlistId); - if (is_null($pl) || PEAR::isError($pl)) { - return $pl; - } - $state = $pl->getState(); - if ($p_val) { - $r = $pl->setState('edited', $p_subjid); - } else { - $r = $pl->setState('ready', 'NULL'); - } - if (PEAR::isError($r)) { - return $r; - } - return ($state == 'edited'); - } - - - /** - * Check if playlist is marked as edited - * - * @param string $p_playlistId - * Playlist global unique ID - * @return FALSE|int - * ID of user editing it - */ - public function isEdited($p_playlistId) - { - $pl = Playlist::Recall($p_playlistId); - if (is_null($pl) || PEAR::isError($pl)) { - return $pl; - } - if (!$pl->isEdited($p_playlistId)) { - return FALSE; - } - return $pl->isEditedBy($p_playlistId); - } - - - /* ---------------------------------------- redefined "protected" methods */ - /* ========================================================= misc methods */ - /** - * Write string to file - * - * @param string $str - * string to be written to file - * @param string $fname - * pathname to file - * @return TRUE|raiseError - */ - private static function WriteStringToFile($p_str, $p_fname) - { - $fp = @fopen($p_fname, "w"); - if ($fp === FALSE) { - return PEAR::raiseError( - "BasicStor::WriteStringToFile: cannot open file ($p_fname)" - ); - } - fwrite($fp, $p_str); - fclose($fp); - return TRUE; - } - - - /* =============================================== test and debug methods */ - - /** - * - * - */ - public function debug($va) - { - echo"<pre>\n"; - print_r($va); - } - - /** - * Aux logging for debug - * - * @param string $msg - log message - */ - public function debugLog($msg) - { - global $CC_CONFIG, $CC_DBC; - $fp = fopen($CC_CONFIG['storageDir']."/log", "a") or die("Can't write to log\n"); - fputs($fp, date("H:i:s").">$msg<\n"); - fclose($fp); - } - -} // class BasicStor - diff --git a/application/models/Schedule.php b/application/models/Schedule.php index ad8d24d3a..29d007d89 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -1,6 +1,5 @@ <?php require_once("StoredFile.php"); -require_once("BasicStor.php"); class ScheduleGroup { @@ -312,7 +311,7 @@ class Schedule { return $res; } - + public static function GetTotalShowTime($instance_id) { global $CC_CONFIG, $CC_DBC; @@ -679,7 +678,7 @@ class Schedule { public static function ExportRangeAsJson($p_fromDateTime, $p_toDateTime) { global $CC_CONFIG, $CC_DBC; - + $range_start = Schedule::PypoTimeToCcTime($p_fromDateTime); $range_end = Schedule::PypoTimeToCcTime($p_toDateTime); diff --git a/application/models/StoredFile.php b/application/models/StoredFile.php index 69e1b2ddb..fc62e28dd 100644 --- a/application/models/StoredFile.php +++ b/application/models/StoredFile.php @@ -1,7 +1,6 @@ <?php require_once("Playlist.php"); require_once(dirname(__FILE__)."/../../library/getid3/var/getid3.php"); -require_once("BasicStor.php"); require_once("Schedule.php"); class Metadata { @@ -572,7 +571,6 @@ class StoredFile { } - /* ========= 'factory' methods - should be called to construct StoredFile */ /** * Create instance of StoredFile object and insert new file * @@ -759,32 +757,6 @@ class StoredFile { } - /** - * Create instance of StoreFile object and recall existing file - * by access token. - * - * @param string $p_token - * access token - * @return StoredFile - */ - public static function RecallByToken($p_token) - { - global $CC_CONFIG, $CC_DBC; - $sql = "SELECT gunid" - ." FROM ".$CC_CONFIG['accessTable'] - ." WHERE token=x'$p_token'::bigint"; - $gunid = $CC_DBC->getOne($sql); - if (PEAR::isError($gunid)) { - return $gunid; - } - if (is_null($gunid)) { - return PEAR::raiseError( - "StoredFile::RecallByToken: invalid token ($p_token)", GBERR_AOBJNEX); - } - return StoredFile::Recall(null, $gunid); - } - - /** * Generate the location to store the file. * It creates the subdirectory if needed. @@ -793,7 +765,6 @@ class StoredFile { { global $CC_CONFIG, $CC_DBC; $resDir = $CC_CONFIG['storageDir']."/".substr($this->gunid, 0, 3); - // see Transport::_getResDir too for resDir name create code if (!is_dir($resDir)) { mkdir($resDir, 02775); chmod($resDir, 02775); @@ -838,7 +809,6 @@ class StoredFile { } else { $dstFile = $p_localFilePath; $r = TRUE; - //$r = @symlink($p_localFilePath, $dstFile); } $this->filepath = $dstFile; $sqlPath = pg_escape_string($this->filepath); @@ -935,72 +905,6 @@ class StoredFile { return $storedFile; } - /** - * Increase access counter, create access token, insert access record. - * - * @param int $parent - * parent token - * @return array - * array with: access URL, access token - */ - public function accessRawMediaData($p_parent='0') - { - $realFname = $this->getRealFilePath(); - $ext = $this->getFileExtension(); - $res = BasicStor::bsAccess($realFname, $ext, $this->gunid, 'access', $p_parent); - if (PEAR::isError($res)) { - return $res; - } - $resultArray = - array('url'=>"file://{$res['fname']}", 'token'=>$res['token']); - return $resultArray; - } - - - /** - * Decrease access couter, delete access record. - * - * @param string $p_token - * access token - * @return boolean - */ - public function releaseRawMediaData($p_token) - { - $res = BasicStor::bsRelease($p_token); - if (PEAR::isError($res)) { - return $res; - } - return TRUE; - } - - - /** - * Replace media file only with new binary file - * - * @param string $p_localFilePath - * local path to media file - * @return TRUE|PEAR_Error - */ - public function setRawMediaData($p_localFilePath) - { - $res = $this->replaceFile($p_localFilePath); - if (PEAR::isError($res)) { - return $res; - } - $mime = $this->getMime(); - if ($mime !== FALSE) { - $res = $this->setMime($mime); - if (PEAR::isError($res)) { - return $res; - } - } - // $r = $this->md->regenerateXmlFile(); - // if (PEAR::isError($r)) { - // return $r; - // } - return TRUE; - } - private static function NormalizeExtent($v) { From dc0ea0a5327617b5c5dda25ca2bd4a3eba16368c Mon Sep 17 00:00:00 2001 From: Naomi <naomi@naomi-DX4840.(none)> Date: Mon, 7 Mar 2011 12:43:05 -0500 Subject: [PATCH 2/4] edits to show class to support resizing/dragging with overbooking. --- application/models/Schedule.php | 25 +----------- application/models/Shows.php | 38 ++++++------------- application/models/StoredFile.php | 5 ++- .../schedule/full-calendar-functions.js | 6 +++ public/js/airtime/schedule/schedule.js | 4 -- 5 files changed, 21 insertions(+), 57 deletions(-) diff --git a/application/models/Schedule.php b/application/models/Schedule.php index e8f20dc78..aa47c9ade 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -323,32 +323,9 @@ class Schedule { return $res; } - public static function getPercentScheduledInRange($s_datetime, $e_datetime) { - - $time = Schedule::getTimeScheduledInRange($s_datetime, $e_datetime); - - $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME); - - $sql = "SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '{$s_datetime}')"; - $r = $con->query($sql); - $s_epoch = $r->fetchColumn(0); - - $sql = "SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '{$e_datetime}')"; - $r = $con->query($sql); - $e_epoch = $r->fetchColumn(0); - - $sql = "SELECT EXTRACT(EPOCH FROM INTERVAL '{$time}')"; - $r = $con->query($sql); - $i_epoch = $r->fetchColumn(0); - - $percent = ceil(($i_epoch / ($e_epoch - $s_epoch)) * 100); - - return $percent; - } - public static function GetPercentScheduled($instance_id, $s_datetime, $e_datetime){ $time = Schedule::GetTotalShowTime($instance_id); - + $s_epoch = strtotime($s_datetime); $e_epoch = strtotime($e_datetime); diff --git a/application/models/Shows.php b/application/models/Shows.php index 993c5e84f..8684fd597 100644 --- a/application/models/Shows.php +++ b/application/models/Shows.php @@ -435,7 +435,7 @@ class Show { $event[$key] = $value; } - $percent = Schedule::getPercentScheduledInRange($show["starts"], $show["ends"]); + $percent = Schedule::GetPercentScheduled($show["instance_id"], $show["starts"], $show["ends"]); $event["percent"] = $percent; return $event; @@ -491,10 +491,9 @@ class ShowInstance { global $CC_DBC; $sql = "UPDATE cc_schedule - SET starts = (starts + interval '{$deltaDay} days' + interval '{$deltaHours}:{$deltaMin}'), + SET starts = (starts + interval '{$deltaDay} days' + interval '{$deltaHours}:{$deltaMin}'), ends = (ends + interval '{$deltaDay} days' + interval '{$deltaHours}:{$deltaMin}') - WHERE (starts >= '{$this->getShowStart()}') - AND (ends <= '{$this->getShowEnd()}')"; + WHERE instance_id = '{$this->_instanceId}'"; $CC_DBC->query($sql); } @@ -560,17 +559,8 @@ class ShowInstance { return "Should not overlap shows"; } } - //have to check if any scheduled content still fits. - else{ - $scheduledTime = $this->getTimeScheduled(); - $sql = "SELECT (timestamp '{$new_ends}' - timestamp '{$starts}') >= interval '{$scheduledTime}'"; - $scheduledContentFits = $CC_DBC->GetOne($sql); - - if($scheduledContentFits != "t") { - return "Must remove some scheduled content."; - } - } - + //with overbooking no longer need to check already scheduled content still fits. + $this->setShowEnd($new_ends); } @@ -639,6 +629,7 @@ class ShowInstance { } public function getTimeScheduled() { + $instance_id = $this->getShowInstanceId(); $time = Schedule::GetTotalShowTime($instance_id); @@ -656,23 +647,16 @@ class ShowInstance { return $time; } - public function getPercentScheduledInRange(){ + public function getPercentScheduled() { $start_timestamp = $this->getShowStart(); $end_timestamp = $this->getShowEnd(); - - return Schedule::getPercentScheduledInRange($start_timestamp, $end_timestamp); - } - - public function getPercentScheduled(){ - $start_timestamp = $this->getShowStart(); - $end_timestamp = $this->getShowEnd(); $instance_id = $this->getShowInstanceId(); return Schedule::GetPercentScheduled($instance_id, $start_timestamp, $end_timestamp); } - public function getShowLength(){ + public function getShowLength() { global $CC_DBC; $start_timestamp = $this->getShowStart(); @@ -686,9 +670,9 @@ class ShowInstance { public function searchPlaylistsForShow($datatables){ - $length = $this->getTimeUnScheduled(); - - return StoredFile::searchPlaylistsForSchedule($length, $datatables); + //$length = $this->getTimeUnScheduled(); + //return StoredFile::searchPlaylistsForSchedule($length, $datatables); + return StoredFile::searchPlaylistsForSchedule($datatables); } public function getShowListContent() { diff --git a/application/models/StoredFile.php b/application/models/StoredFile.php index fc62e28dd..73a2bcf64 100644 --- a/application/models/StoredFile.php +++ b/application/models/StoredFile.php @@ -1558,10 +1558,11 @@ class StoredFile { } - public static function searchPlaylistsForSchedule($p_length, $datatables) { + public static function searchPlaylistsForSchedule($datatables) + { $fromTable = "cc_playlist AS pl LEFT JOIN cc_playlisttimes AS plt USING(id) LEFT JOIN cc_subjs AS sub ON pl.editedby = sub.id"; - $datatables["optWhere"][] = "INTERVAL '{$p_length}' > INTERVAL '00:00:00'"; $datatables["optWhere"][] = "plt.length > INTERVAL '00:00:00'"; + return StoredFile::searchFiles($fromTable, $datatables); } diff --git a/public/js/airtime/schedule/full-calendar-functions.js b/public/js/airtime/schedule/full-calendar-functions.js index 8d542509d..87388f0fd 100644 --- a/public/js/airtime/schedule/full-calendar-functions.js +++ b/public/js/airtime/schedule/full-calendar-functions.js @@ -4,6 +4,10 @@ * */ +function scheduleRefetchEvents() { + $("#schedule_calendar").fullCalendar( 'refetchEvents' ); +} + function openAddShowForm() { if(($("#add-show-form").length == 1) && ($("#add-show-form").css('display')=='none')) { @@ -221,6 +225,8 @@ function eventResize( event, dayDelta, minuteDelta, revertFunc, jsEvent, ui, vie alert(json.error); revertFunc(); } + + scheduleRefetchEvents(); }); } diff --git a/public/js/airtime/schedule/schedule.js b/public/js/airtime/schedule/schedule.js index 5fb842593..48b256a10 100644 --- a/public/js/airtime/schedule/schedule.js +++ b/public/js/airtime/schedule/schedule.js @@ -204,10 +204,6 @@ function buildEditDialog(json){ } -function scheduleRefetchEvents() { - $("#schedule_calendar").fullCalendar( 'refetchEvents' ); -} - $(window).load(function() { var mainHeight = document.documentElement.clientHeight - 200 - 50; From 76b1e3b7f7880455fa30343d1c51067f91f8186b Mon Sep 17 00:00:00 2001 From: Naomi <naomi@naomi-DX4840.(none)> Date: Mon, 7 Mar 2011 12:43:52 -0500 Subject: [PATCH 3/4] upload function now included into record script. --- python_apps/show-recorder/testrecordscript.py | 40 +++++++------------ 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/python_apps/show-recorder/testrecordscript.py b/python_apps/show-recorder/testrecordscript.py index 0a387c5a2..6de6d416e 100644 --- a/python_apps/show-recorder/testrecordscript.py +++ b/python_apps/show-recorder/testrecordscript.py @@ -4,10 +4,14 @@ import logging import json import time import datetime +import os from eci import * from configobj import ConfigObj -import subprocess + +from poster.encode import multipart_encode +from poster.streaminghttp import register_openers +import urllib2 # loading config file try: @@ -73,11 +77,6 @@ def check_record(): start_time = sorted_show_keys[0] next_show = getDateTimeObj(start_time) - #print tnow, next_show - - #tnow = getDateTimeObj("2011-03-04 16:00:00") - #next_show = getDateTimeObj("2011-03-04 16:00:01") - delta = next_show - tnow if delta <= datetime.timedelta(seconds=60): @@ -85,20 +84,15 @@ def check_record(): show_length = shows_to_record[start_time] filepath = record_show(show_length.seconds, start_time) - #filepath = record_show(10, "2011-03-04 16:00:00") - - command = "%s -c %s" %("../../utils/airtime-import", filepath) - subprocess.call([command],shell=True) + upload_file(filepath) def get_shows(): url = config["base_url"] + config["show_schedule_url"] - #url = url.replace("%%from%%", "2011-03-13 20:00:00") - #url = url.replace("%%to%%", "2011-04-17 21:00:00") - response = urllib.urlopen(url) data = response.read() + response_json = json.loads(data) shows = response_json[u'shows'] print shows @@ -107,22 +101,16 @@ def get_shows(): process_shows(shows) check_record() -def upload_file(): +def upload_file(filepath): - from poster.encode import multipart_encode - from poster.streaminghttp import register_openers - import urllib2 + filename = os.path.split(filepath)[1] # Register the streaming http handlers with urllib2 register_openers() - # Start the multipart/form-data encoding of the file "DSC0001.jpg" - # "image1" is the name of the parameter, which is normally set - # via the "name" parameter of the HTML <input> tag. - # headers contains the necessary Content-Type and Content-Length # datagen is a generator object that yields the encoded parameters - datagen, headers = multipart_encode({"file": open("/home/naomi/Music/testoutput.mp3", "rb"), 'name': 'crazy.mp3'}) + datagen, headers = multipart_encode({"file": open(filepath, "rb"), 'name': filename}) url = config["base_url"] + config["upload_file_url"] @@ -133,11 +121,11 @@ def upload_file(): if __name__ == '__main__': - # while True: - # get_shows() - # time.sleep(30) + while True: + get_shows() + time.sleep(30) - upload_file() + From 1e94578f132c9bd8e7993abedc3df679879ec05e Mon Sep 17 00:00:00 2001 From: Naomi <naomi@naomi-DX4840.(none)> Date: Mon, 7 Mar 2011 12:59:46 -0500 Subject: [PATCH 4/4] so no playlists show up on left side when a show is overbooked. --- application/models/Shows.php | 6 +++--- application/models/StoredFile.php | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/application/models/Shows.php b/application/models/Shows.php index 8684fd597..8a3f6ac84 100644 --- a/application/models/Shows.php +++ b/application/models/Shows.php @@ -670,9 +670,9 @@ class ShowInstance { public function searchPlaylistsForShow($datatables){ - //$length = $this->getTimeUnScheduled(); - //return StoredFile::searchPlaylistsForSchedule($length, $datatables); - return StoredFile::searchPlaylistsForSchedule($datatables); + $time_remaining = $this->getTimeUnScheduled(); + + return StoredFile::searchPlaylistsForSchedule($time_remaining, $datatables); } public function getShowListContent() { diff --git a/application/models/StoredFile.php b/application/models/StoredFile.php index 73a2bcf64..32d1ab0dc 100644 --- a/application/models/StoredFile.php +++ b/application/models/StoredFile.php @@ -1558,9 +1558,10 @@ class StoredFile { } - public static function searchPlaylistsForSchedule($datatables) + public static function searchPlaylistsForSchedule($time_remaining, $datatables) { $fromTable = "cc_playlist AS pl LEFT JOIN cc_playlisttimes AS plt USING(id) LEFT JOIN cc_subjs AS sub ON pl.editedby = sub.id"; + $datatables["optWhere"][] = "INTERVAL '{$time_remaining}' > INTERVAL '00:00:00'"; $datatables["optWhere"][] = "plt.length > INTERVAL '00:00:00'"; return StoredFile::searchFiles($fromTable, $datatables);