* * AFRepo top-level class to slot in with the Greenstone extension framework * * The audio is expected to be in subdirectories of the 'audio-files' directory, and * for example purposes can be named in such a way that the example * PathClassifier classifier can get meanining from it. */ class AFRepo extends AFRepoBase { private $allfiles; public function AFRepo() { $this->audio_files_dir = "audio-files"; $this->af_prefix = getcwd() . "/" . $this->audio_files_dir; } public function getName() { return "Salami 4Store audio repository"; } public function getURIPrefix() { return "@afrepo-http-prefix@/afrepo/"; } /* Done this way, can talk to the 4store server directly rather than relying on proxying through the PHP-based 'afrepo' server */ public function getTrippleStoreURIPrefix() { return "@afrepo-http-prefix@/4store/"; } public function getSparqlEndpoint() { return $this->getTrippleStoreURIPrefix() . "sparql/"; } public function getDataEndpoint() { return $this->getTrippleStoreURIPrefix() . "data/"; } /** * getAudioPath * Return the path to the audio links in this repository (without a trailing * slash) */ public function getAudioPath() { return realpath("audio-ids"); } protected function remove_audio_files_prefix($full_filepath) { # echo "full filepath = " . $full_filepath . "\n"; # echo "af prefix = " . $this->af_prefix . "\n"; $af_prefix_len = strlen($this->af_prefix); $filepath = $full_filepath; if (substr($filepath, 0, $af_prefix_len) == $this->af_prefix) { $filepath = substr($filepath, $af_prefix_len); } # echo "** filepath = " . $filepath . "\n"; return $filepath; } /** * fileInRepo * Return true if the audiofile with the given path (canonical or symlink) * is in the repository or false if not */ public function fileInRepo($full_filepath) { $realpath = realpath($full_filepath); if ($realpath === false) { trigger_error("file '$filepath' does not exist on disk or is a broken symlink", E_USER_WARNING); return false; } return array_key_exists($full_filepath, $this->getAllFiles()); } /** * idToCanonicalPath * Return the path to the canonical file with the given ID */ public function idToCanonicalPath($id) { return readlink($this->idToLinkPath($id)); } /** * filePathToId * Return the ID of the audiofile with the given path (which can be * canonical or a symlink) */ public function filePathToId($full_filepath) { if (!$this->fileInRepo($full_filepath)) { throw new Exception("file with path '$filepath' is not in the repository"); } $hash_filepath = "salami:/" . $this->remove_audio_files_prefix($full_filepath); ## echo "Hashing on: " . $hash_filepath . "\n"; $id = md5($hash_filepath); return $id; } // recursive method to delete things from the links directory according to the // options function getAllCollectionFilesRec($collection, $path) { echo "Processing directory: " . $path . "\n"; $dir = dir($path); while (($entry = $dir->read()) !== false) { if ($entry == "." || $entry == "..") { continue; } $fullpath = $path . "/" . $entry; $isdir = false; if (is_link($fullpath)) { $realpath = readlink($fullpath); // follow potential chain of sym-links while (is_link($realpath)) { $realpath = readlink($realpath); } $isdir = is_dir($realpath); } else { $isdir = is_dir($fullpath); } if ($isdir) { $this->getAllCollectionFilesRec($collection,$fullpath); } else { // assume it is a file ## echo "Adding file: " . $fullpath . "\n"; $this->allfiles[$fullpath] = true; } } $dir->close(); } public function getAllFiles() { if (!is_null($this->allfiles)) { return $this->allfiles; } $this->allfiles = array(); ## $path = realpath($this->audio_files_dir); $path = $this->af_prefix; $dir = dir($path); while (($file = $dir->read()) !== false) { if ($file[0] == ".") { // skip all dot files and dirs continue; } $fullpath = $path . "/" . $file; $isdir = false; if (is_link($fullpath)) { $realpath = readlink($fullpath); // follow potential chain of sym-links while (is_link($realpath)) { $realpath = readlink($realpath); } $isdir = is_dir($realpath); } else { $isdir = is_dir($fullpath); } if ($isdir) { // recursively work through each collection directory $this->getAllCollectionFilesRec($file, $fullpath); } } $dir->close(); return $this->allfiles; } public function getAllFilesOLD() { if (!is_null($this->allfiles)) return $this->allfiles; $this->allfiles = array(); $path = realpath("audio-files"); $dir = dir($path); while (($file = $dir->read()) !== false) { if ($file[0] != "." && is_dir($path . "/" . $file)) { $subdir = dir($path . "/" . $file); while (($subfile = $subdir->read()) !== false) { if ($subfile[0] != "." && is_file($path . "/" . $file . "/" . $subfile)) $this->allfiles[$path . "/" . $file . "/" . $subfile] = true; } $subdir->close(); } } $dir->close(); return $this->allfiles; } public function getSongFilesOLD($id) { $filepath = $this->idToLinkPath($id); $origfilepath = realpath($filepath); if ($origfilepath === false) return array(); // is it a clip? if (preg_match('%\.clip\..{1,4}$%', $origfilepath)) { // does full version exist? $fullpath = preg_replace('%\.clip%', "", $origfilepath); if (file_exists($fullpath)) return array($fullpath, $origfilepath); return array($origfilepath); } // it's a full song. does clip exist? $clippath = preg_replace('%(\..{1,4})$%', '.clip\1', $origfilepath); if (file_exists($clippath)) return array($origfilepath, $clippath); return array($origfilepath); } public function haveMetadataPermission() { return true; } public function haveAudioPermission() { return ipInRange($_SERVER["REMOTE_ADDR"], "127.0.0.0/8"); } public function getMBID($id) { $classifiers = array( new TagClassifier(), new EchonestClassifier(), new PathClassifier(), ); foreach ($classifiers as $classifier) if ($classifier->available() && $classifier->hasMBID($id)) return $classifier->getMBID($id); return null; } } ?>