From 1c402a8aef90398f40202fc54d10177d82d02e8d Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Wed, 15 Sep 2010 22:57:38 +0100 Subject: [PATCH] Placeholders for Bluray rips Added placeholder Source/Worker plugins for ripping Bluray items. Added placeholder iterator filter to accept only Bluray sources while iterating directory contents. --- .../Source/Plugin/Bluray.class.php | 114 ++++++++++++++++++ .../Utility/BlurayDirectoryIterator.class.php | 9 ++ .../Worker/Plugin/Bluray.class.php | 53 ++++++++ 3 files changed, 176 insertions(+) create mode 100644 lib/RippingCluster/Source/Plugin/Bluray.class.php create mode 100644 lib/RippingCluster/Utility/BlurayDirectoryIterator.class.php create mode 100644 lib/RippingCluster/Worker/Plugin/Bluray.class.php diff --git a/lib/RippingCluster/Source/Plugin/Bluray.class.php b/lib/RippingCluster/Source/Plugin/Bluray.class.php new file mode 100644 index 0000000..5fa94a6 --- /dev/null +++ b/lib/RippingCluster/Source/Plugin/Bluray.class.php @@ -0,0 +1,114 @@ +config(); + $directory = $config->get('source.bluray.dir'); + + if (!is_dir($directory)) { + throw new RippingCluster_Exception_InvalidSourceDirectory($directory); + } + + $sources = array(); + + $iterator = new RippingCluster_Utility_BlurayDirectoryIterator(new RippingCluster_Utility_VisibleFilesIterator(new DirectoryIterator($directory))); + foreach ($iterator as /** @var SplFileInfo */ $source_vts) { + $sources[] = self::load($source_vts->getPathname(), false); + } + + return $sources; + } + + /** + * Creates an object to represent the given source. + * + * The source is not actually scanned unless specifically requested. + * An unscanned object cannot be used until it has been manually scanned. + * + * If requested, the source can be cached to prevent high load, and long scan times. + * + * @param string $source_filename Filename of the source + * @param bool $scan Request that the source be scanned for content. Defaults to true. + * @param bool $use_cache Request that the cache be used. Defaults to true. + * @return RippingCluster_Source + */ + public static function load($source_filename, $scan = true, $use_cache = true) { + $cache = RippingCluster_Main::instance()->cache(); + + // Ensure the source is a valid directory, and lies below the configured source_dir + if ( ! self::isValidSource($source_filename)) { + return new RippingCluster_Source($source_filename, self::name(), false); + } + + $source = null; + if ($use_cache && $cache->exists($source_filename)) { + $source = unserialize($cache->fetch($source_filename)); + } else { + $source = new RippingCluster_Source($source_filename, self::name(), true); + + // TODO Populate source object with content + + // If requested, store the new source object in the cache + if ($use_cache) { + $source->cache(); + } + } + } + + /** + * Creates an object to represent the given source using an encoded filename. + * + * Wraps the call to load the source after the filename has been decoded. + * + * @param string $encoded_filename Encoded filename of the source + * @param bool $scan Request that the source be scanned for content. Defaults to true. + * @param bool $use_cache Request that the cache be used. Defaults to true. + * @return RippingCluster_Source + * + * @see RippingCluster_Source_IPlugin::load() + */ + public static function loadEncoded($encoded_filename, $scan = true, $use_cache = true) { + // Decode the filename + $source_filename = base64_decode(str_replace('-', '/', $encoded_filename)); + + return self::load($source_filename, $scan, $use_cache); + } + + /** + * Determins if a filename is a valid source loadable using this plugin + * + * @param string $source_filename Filename of the source + * @return bool + */ + public static function isValidSource($source_filename) { + $config = RippingCluster_Main::instance()->config(); + + // Ensure the source is a valid directory, and lies below the configured source_dir + if ( ! is_dir($source_filename)) { + return false; + } + $real_source_filename = realpath($source_filename); + + $source_basedir = $config->get('source.bluray.dir'); + $real_source_basedir = realpath($source_basedir); + + if (substr($real_source_filename, 0, strlen($real_source_basedir)) != $real_source_basedir) { + return false; + } + + return true; + } + +} + +?> \ No newline at end of file diff --git a/lib/RippingCluster/Utility/BlurayDirectoryIterator.class.php b/lib/RippingCluster/Utility/BlurayDirectoryIterator.class.php new file mode 100644 index 0000000..ec1c05b --- /dev/null +++ b/lib/RippingCluster/Utility/BlurayDirectoryIterator.class.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/lib/RippingCluster/Worker/Plugin/Bluray.class.php b/lib/RippingCluster/Worker/Plugin/Bluray.class.php new file mode 100644 index 0000000..5035b55 --- /dev/null +++ b/lib/RippingCluster/Worker/Plugin/Bluray.class.php @@ -0,0 +1,53 @@ +output = ''; + + $this->gearman_job = $gearman_job; + + $this->rip_options = unserialize($this->gearman_job->workload()); + + if ( ! $this->rip_options['id']) { + throw new RippingCluster_Exception_LogicException("Job ID must not be zero/null"); + } + $this->job = RippingCluster_Job::fromId($this->rip_options['id']); + } + + /** + * Returns the list of functions (and names) implemented by this plugin for registration with Gearman + * + * @return array(string => callback) + */ + public static function workerFunctions() { + return array( + 'bluray_rip' => array(__CLASS__, 'rip'), + ); + } + + /** + * Creates an instance of the Worker plugin, and uses it to execute a single job + * + * @param GearmanJob $job Gearman Job object, describing the work to be done + */ + public static function rip(GearmanJob $job) { + $rip = new self($job); + $rip->execute(); + } + + private function execute() { + // TODO + } + +} + +?> \ No newline at end of file