_dir = $dir; } public function getId() { return $this->_dir->getId(); } public function getType() { return $this->_dir->getType(); } public function setType($type) { $this->_dir->setType($type); } public function getDirectory() { return $this->_dir->getDirectory(); } public function setDirectory($dir) { $this->_dir->setDirectory($dir); $this->_dir->save(); } public function setExistsFlag($flag) { $this->_dir->setExists($flag); $this->_dir->save(); } public function setWatchedFlag($flag) { $this->_dir->setWatched($flag); $this->_dir->save(); } public function getWatchedFlag() { return $this->_dir->getWatched(); } public function getExistsFlag() { return $this->_dir->getExists(); } /** * There are 2 cases where this function can be called. * 1. When watched dir was removed * 2. When some dir was watched, but it was unmounted * * In case of 1, $userAddedWatchedDir should be true * In case of 2, $userAddedWatchedDir should be false * * When $userAddedWatchedDir is true, it will set "Watched" flag to false * otherwise, it will set "Exists" flag to true */ public function remove($userAddedWatchedDir=true) { $con = Propel::getConnection(); $music_dir_id = $this->getId(); $sql = << $music_dir_id ), 'all' ); // get all the files on this dir $sql = << $music_dir_id ), 'all'); // set RemovedFlag to true if ($userAddedWatchedDir) { self::setWatchedFlag(false); } else { self::setExistsFlag(false); } //$res = $this->_dir->delete(); foreach ($show_instances as $show_instance_row) { $temp_show = new Application_Model_ShowInstance($show_instance_row["instance_id"]); $temp_show->updateScheduledTime(); } Application_Model_RabbitMq::PushSchedule(); } /** * Checks if p_dir1 is the ancestor of p_dir2. Returns * true if it is the ancestor, false otherwise. Note that * /home/user is considered the ancestor of /home/user * * @param string $p_dir1 * The potential ancestor directory. * @param string $p_dir2 * The potential descendent directory. * @return boolean * Returns true if it is the ancestor, false otherwise. */ private static function isAncestorDir($p_dir1, $p_dir2) { if (strlen($p_dir1) > strlen($p_dir2)) { return false; } return substr($p_dir2, 0, strlen($p_dir1)) == $p_dir1; } /** * Checks whether the path provided is a valid path. A valid path * is defined as not being nested within an existing watched directory, * or vice-versa. Throws a NestedDirectoryException if invalid. * * @param string $p_path * The path we want to validate * @return void */ public static function isPathValid($p_path) { $dirs = self::getWatchedDirs(); $dirs[] = self::getStorDir(); foreach ($dirs as $dirObj) { $dir = $dirObj->getDirectory(); $diff = strlen($dir) - strlen($p_path); if ($diff == 0) { if ($dir == $p_path) { throw new NestedDirectoryException("'$p_path' is already watched."); } } elseif ($diff > 0) { if (self::isAncestorDir($p_path, $dir)) { throw new NestedDirectoryException("'$p_path' contains nested watched directory: '$dir'"); } } else { /* diff < 0*/ if (self::isAncestorDir($dir, $p_path)) { throw new NestedDirectoryException("'$p_path' is nested within existing watched directory: '$dir'"); } } } } /** There are 2 cases where this function can be called. * 1. When watched dir was added * 2. When some dir was watched, but it was unmounted somehow, but gets mounted again * * In case of 1, $userAddedWatchedDir should be true * In case of 2, $userAddedWatchedDir should be false * * When $userAddedWatchedDir is true, it will set "Removed" flag to false * otherwise, it will set "Exists" flag to true * * @param $nestedWatch - if true, bypass path check, and Watched to false **/ public static function addDir($p_path, $p_type, $userAddedWatchedDir=true, $nestedWatch=false) { if (!is_dir($p_path)) { return array("code"=>2, "error"=>"'$p_path' is not a valid directory."); } $real_path = Application_Common_OsPath::normpath($p_path)."/"; if ($real_path != "/") { $p_path = $real_path; } $exist_dir = self::getDirByPath($p_path); if ($exist_dir == NULL) { $temp_dir = new CcMusicDirs(); $dir = new Application_Model_MusicDir($temp_dir); } else { $dir = $exist_dir; } $dir->setType($p_type); $p_path = Application_Common_OsPath::normpath($p_path)."/"; try { /* isPathValid() checks if path is a substring or a superstring of an * existing dir and if not, throws NestedDirectoryException */ if (!$nestedWatch) { self::isPathValid($p_path); } if ($userAddedWatchedDir) { $dir->setWatchedFlag(true); } else { if ($nestedWatch) { $dir->setWatchedFlag(false); } $dir->setExistsFlag(true); } $dir->setDirectory($p_path); return array("code"=>0); } catch (NestedDirectoryException $nde) { $msg = $nde->getMessage(); return array("code"=>1, "error"=>"$msg"); } catch (Exception $e) { return array("code"=>1, "error"=>"'$p_path' is already set as the current storage dir or in the watched folders list"); } } /** There are 2 cases where this function can be called. * 1. When watched dir was added * 2. When some dir was watched, but it was unmounted somehow, but gets mounted again * * In case of 1, $userAddedWatchedDir should be true * In case of 2, $userAddedWatchedDir should be false * * When $userAddedWatchedDir is true, it will set "Watched" flag to true * otherwise, it will set "Exists" flag to true **/ public static function addWatchedDir($p_path, $userAddedWatchedDir=true, $nestedWatch=false) { $res = self::addDir($p_path, "watched", $userAddedWatchedDir, $nestedWatch); if ($res['code'] == 0) { //convert "linked" files (Airtime <= 1.8.2) to watched files. $propel_link_dir = CcMusicDirsQuery::create() ->filterByType('link') ->findOne(); //see if any linked files exist. if (isset($propel_link_dir)) { //newly added watched directory object $propel_new_watch = CcMusicDirsQuery::create() ->filterByDirectory(Application_Common_OsPath::normpath($p_path)."/") ->findOne(); //any files of the deprecated "link" type. $link_files = CcFilesQuery::create() ->setFormatter(ModelCriteria::FORMAT_ON_DEMAND) ->filterByDbDirectory($propel_link_dir->getId()) ->find(); $newly_watched_dir = $propel_new_watch->getDirectory(); foreach ($link_files as $link_file) { $link_filepath = $link_file->getDbFilepath(); //convert "link" file into a watched file. if ((strlen($newly_watched_dir) < strlen($link_filepath)) && (substr($link_filepath, 0, strlen($newly_watched_dir)) === $newly_watched_dir)) { //get the filepath path not including the watched directory. $sub_link_filepath = substr($link_filepath, strlen($newly_watched_dir)); $link_file->setDbDirectory($propel_new_watch->getId()); $link_file->setDbFilepath($sub_link_filepath); $link_file->save(); } } } $data = array(); $data["directory"] = $p_path; Application_Model_RabbitMq::SendMessageToMediaMonitor("new_watch", $data); } return $res; } public static function getDirByPK($pk) { $dir = CcMusicDirsQuery::create()->findPK($pk); $mus_dir = new Application_Model_MusicDir($dir); return $mus_dir; } public static function getDirByPath($p_path) { $dir = CcMusicDirsQuery::create() ->filterByDirectory($p_path) ->findOne(); if ($dir == NULL) { return null; } else { $mus_dir = new Application_Model_MusicDir($dir); return $mus_dir; } } /** * Search and returns watched dirs * * @param $exists search condition with exists flag * @param $watched search condition with watched flag */ public static function getWatchedDirs($exists=true, $watched=true) { $result = array(); $dirs = CcMusicDirsQuery::create() ->filterByType("watched"); if ($exists !== null) { $dirs = $dirs->filterByExists($exists); } if ($watched !== null) { $dirs = $dirs->filterByWatched($watched); } $dirs = $dirs->find(); foreach ($dirs as $dir) { $result[] = new Application_Model_MusicDir($dir); } return $result; } public static function getStorDir() { $dir = CcMusicDirsQuery::create() ->filterByType("stor") ->findOne(); $mus_dir = new Application_Model_MusicDir($dir); return $mus_dir; } public static function setStorDir($p_dir) { // we want to be consistent when storing dir path. // path should always ends with trailing '/' $p_dir = Application_Common_OsPath::normpath($p_dir)."/"; if (!is_dir($p_dir)) { return array("code"=>2, "error"=>"'$p_dir' is not a valid directory."); } elseif (Application_Model_Preference::GetImportTimestamp()+10 > time()) { return array("code"=>3, "error"=>"Airtime is currently importing files. Please wait until this is complete before changing the storage directory."); } $dir = self::getStorDir(); // if $p_dir doesn't exist in DB $exist = $dir->getDirByPath($p_dir); if ($exist == NULL) { $dir->setDirectory($p_dir); $dirId = $dir->getId(); $data = array(); $data["directory"] = $p_dir; $data["dir_id"] = $dirId; Application_Model_RabbitMq::SendMessageToMediaMonitor("change_stor", $data); return array("code"=>0); } else { return array("code"=>1, "error"=>"'$p_dir' is already set as the current storage dir or in the watched folders list."); } } public static function getWatchedDirFromFilepath($p_filepath) { $dirs = CcMusicDirsQuery::create() ->filterByType(array("watched", "stor")) ->filterByExists(true) ->filterByWatched(true) ->find(); foreach ($dirs as $dir) { $directory = $dir->getDirectory(); if (substr($p_filepath, 0, strlen($directory)) === $directory) { $mus_dir = new Application_Model_MusicDir($dir); return $mus_dir; } } return null; } /** There are 2 cases where this function can be called. * 1. When watched dir was removed * 2. When some dir was watched, but it was unmounted * * In case of 1, $userAddedWatchedDir should be true * In case of 2, $userAddedWatchedDir should be false * * When $userAddedWatchedDir is true, it will set "Watched" flag to false * otherwise, it will set "Exists" flag to true **/ public static function removeWatchedDir($p_dir, $userAddedWatchedDir=true) { //make sure that $p_dir has a trailing "/" $real_path = Application_Common_OsPath::normpath($p_dir)."/"; if ($real_path != "/") { $p_dir = $real_path; } $dir = Application_Model_MusicDir::getDirByPath($p_dir); if (is_null($dir)) { return array("code"=>1, "error"=>"'$p_dir' doesn't exist in the watched list."); } else { $dir->remove($userAddedWatchedDir); $data = array(); $data["directory"] = $p_dir; Application_Model_RabbitMq::SendMessageToMediaMonitor("remove_watch", $data); return array("code"=>0); } } public static function splitFilePath($p_filepath) { $mus_dir = self::getWatchedDirFromFilepath($p_filepath); if (is_null($mus_dir)) { return null; } $length_dir = strlen($mus_dir->getDirectory()); $fp = substr($p_filepath, $length_dir); return array($mus_dir->getDirectory(), trim($fp)); } }