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
- *       &quot;conditions&quot; 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', '=', '&lt;',
- *               '&lt;=', '&gt;', '&gt;='</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
-     *       &quot;conditions&quot; 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', '=', '&lt;',
-     *               '&lt;=', '&gt;', '&gt;='</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);