Exemplo n.º 1
0
 /**
  * Queues a request for a Helioviewer.org movie
  */
 public function reQueueMovie($silent = false)
 {
     include_once HV_ROOT_DIR . '/../lib/alphaID/alphaID.php';
     include_once HV_ROOT_DIR . '/../lib/Resque.php';
     include_once HV_ROOT_DIR . '/../lib/Redisent/Redisent.php';
     include_once HV_ROOT_DIR . '/../src/Helper/HelioviewerLayers.php';
     include_once HV_ROOT_DIR . '/../src/Helper/HelioviewerEvents.php';
     include_once HV_ROOT_DIR . '/../src/Database/MovieDatabase.php';
     include_once HV_ROOT_DIR . '/../src/Database/ImgIndex.php';
     include_once HV_ROOT_DIR . '/../src/Movie/HelioviewerMovie.php';
     // Connect to redis
     $redis = new Redisent('localhost');
     // If the queue is currently full, don't process the request
     $queueSize = Resque::size(HV_MOVIE_QUEUE);
     if ($queueSize >= MOVIE_QUEUE_MAX_SIZE) {
         throw new Exception('Sorry, due to current high demand, we are currently unable ' . 'to process your request. Please try again later.', 40);
     }
     // Get current number of HV_MOVIE_QUEUE workers
     $workers = Resque::redis()->smembers('workers');
     $movieWorkers = array_filter($workers, function ($elem) {
         return strpos($elem, HV_MOVIE_QUEUE) !== false;
     });
     // Default options
     $defaults = array("format" => 'mp4', "force" => false);
     $options = array_replace($defaults, $this->_params);
     // Convert public alpha-numeric id to integer
     $movieId = alphaId($this->_params['id'], true, 5, HV_MOVIE_ID_PASS);
     $movieId = intval($movieId);
     if ($movieId <= 0) {
         throw new Exception('Value of movie "id" parameter is invalid.', 25);
     }
     // Check if movie exists on disk before re-queueing
     if ($options['force'] === false) {
         $helioviewerMovie = new Movie_HelioviewerMovie($this->_params['id'], $options['format']);
         $filepath = $helioviewerMovie->getFilepath();
         $path_parts = pathinfo($filepath);
         $extension = '.' . $path_parts['extension'];
         foreach (array('.mp4', '.flv', '.webm') as $ext) {
             $path = str_replace($extension, $ext, $filepath);
             if (@file_exists($path)) {
                 $url = str_replace(HV_CACHE_DIR, HV_CACHE_URL, $path);
                 throw new Exception('Movie file already exists: ' . $url, 44);
             }
         }
     }
     // Get movie metadata from database
     $movieDatabase = new Database_MovieDatabase();
     $movie = $movieDatabase->getMovieMetadata($movieId);
     // Check if movie is already in the queue (status=0)
     // or is already being processed (status=1) before re-queueing.
     // This prevents a spider, bot, or other automated user-agent
     // from stuffing the queue with redundant regeneration requests.
     // As such, the optional 'force' parameter will NOT override
     // this check.
     // However, if the movie status is considered stale, then
     // a Queued or Processing status is ignored and re-queueing
     // is allowed to proceed.
     $movieFormats = $movieDatabase->getMovieFormats($movieId);
     foreach ($movieFormats as $movieFormat) {
         $seconds_ago = time() - strtotime($movieFormat['modified']);
         $stale = 60 * 60 * 2;
         // 2 hours
         if ($movieFormat['status'] < 2 && $seconds_ago < $stale) {
             //throw new Exception('Movie can be regenerated only once every 2 hours', 47);
             //return;
         }
     }
     $numPixels = $movie['width'] * $movie['height'];
     $maxFrames = min($this->_getMaxFrames($queueSize), $movie['maxFrames']);
     // Create a connection to the database
     $db = new Database_ImgIndex();
     // Limit movies to three layers
     $layers = new Helper_HelioviewerLayers($movie['dataSourceString']);
     if ($layers->length() < 1 || $layers->length() > 3) {
         throw new Exception('Invalid layer choices! You must specify 1-3 comma-separated ' . 'layer names.', 22);
     }
     // Estimate the number of frames
     $numFrames = $this->_estimateNumFrames($db, $layers, $movie['startDate'], $movie['endDate']);
     $numFrames = min($numFrames, $maxFrames);
     // Estimate the time to create movie frames
     // @TODO 06/2012: Factor in total number of workers and number of
     //                workers that are currently available?
     $estBuildTime = $this->_estimateMovieBuildTime($movieDatabase, $numFrames, $numPixels, $options['format']);
     // If all workers are in use, increment and use estimated wait counter
     if ($queueSize + 1 >= sizeOf($movieWorkers)) {
         $eta = $redis->incrby('helioviewer:movie_queue_wait', $estBuildTime);
         $updateCounter = true;
     } else {
         // Otherwise simply use the time estimated for the single movie
         $eta = $estBuildTime;
         $updateCounter = false;
     }
     // Get datasource bitmask
     $bitmask = bindec($layers->getBitMask());
     $publicId = $this->_params['id'];
     // Queue movie request
     $args = array('movieId' => $publicId, 'eta' => $estBuildTime, 'format' => $options['format'], 'counter' => $updateCounter);
     $token = Resque::enqueue(HV_MOVIE_QUEUE, 'Job_MovieBuilder', $args, true);
     // Create entries for each version of the movie in the movieFormats
     // table
     $movieDatabase->deleteMovieFormats($movieId);
     foreach (array('mp4', 'webm') as $format) {
         $movieDatabase->insertMovieFormat($movieId, $format);
     }
     // Print response
     $response = array('id' => $publicId, 'eta' => $eta, 'queue' => max(0, $queueSize + 1 - sizeOf($movieWorkers)), 'token' => $token);
     if (!$silent) {
         $this->_printJSON(json_encode($response));
     }
 }