/**
  * Store a newly created resource in storage.
  *
  * @param  Request  $request
  * @return Response
  */
 public function store(Request $request)
 {
     //
     $media = new Media();
     $media->project_id = $request->input('project_id');
     // Media can be created in two ways:
     // 1) A media path or an audf path (TODO: implement this)
     // 2) As a subsection of an existing media file
     if ($request->has('base_media_id')) {
         $base_media = Media::find($request->input('base_media_id'));
         $media->base_media_id = $base_media->id;
         // We copy the base media from the parent, but NOT the fingerprints
         $media->media_path = $base_media->media_path;
         $media->afpt_path = '';
         $media->external_id = $base_media->external_id;
     } else {
         $media->media_path = $request->input('media_path');
         $media->afpt_path = $request->input('afpt_path');
         // Store the external ID if it exists
         if ($request->has('external_id')) {
             $media->external_id = $request->input('external_id');
         }
     }
     // Sometimes the media we want to track is a subset of the full media
     $media->start = $request->has('start') ? $request->start : 0;
     $media->duration = $request->has('duration') ? $request->duration : MEDIA::DURATION_UNKNOWN;
     // Make sure this media hasn't already been saved for this project
     $query = Media::where('project_id', $media->project_id)->where('start', $media->start)->where('duration', $media->duration);
     if ($media->external_id) {
         // If an external ID is set, use that as the differentiating factor
         $query = $query->where('external_id', $media->external_id);
     } else {
         // Otherwise, use the media path
         $query = $query->where('media_path', $media->media_path);
     }
     $existing_media = $query->first();
     if ($existing_media) {
         return $existing_media;
     }
     $media->save();
     return $media;
 }
 /**
  * See contract for documentation
  */
 public function cleanProject($project)
 {
     $task_logs = array();
     $results = array();
     // Get an exclusive project lock, since we are going to be potentially deleting fingerprint databases
     $task_logs[] = $this->logLine("Start: Obtaining project lock");
     $project_lockfile = $this->getProjectLock($project, LOCK_EX);
     $task_logs[] = $this->logLine("End:   Obtaining project lock");
     $task_logs[] = $this->logLine("Start: Removing cached files");
     // $results = $this->loader->removeCachedFiles($media);
     $task_logs[] = $this->logLine("End:   Removing cached files");
     /////////////////////////
     // Consolidate potential targets
     $task_logs[] = $this->logLine("Start: Consolidating potential target databases");
     // Get the list
     $databases = $this->getDatabasesByProject(FingerprinterContract::MATCH_POTENTIAL_TARGET, $project);
     // Consolidate the list
     $database_remappings = $this->mergeDatabases($databases);
     $results['potential_targets'] = $database_remappings;
     // Remap moved media
     foreach ($database_remappings as $remap) {
         $original_database = $remap['original'];
         $new_database = $remap['new'];
         // Get all media that was in the original database
         $media_list = Media::where('potential_target_database', '=', $original_database)->get();
         // Update the database to point to the new location
         foreach ($media_list as $media) {
             $media->potential_target_database = $new_database;
             $media->save();
         }
     }
     $task_logs[] = $this->logLine("End:   Consolidating potential target databases");
     /////////////////////////
     // Consolidate corpuses
     $task_logs[] = $this->logLine("Start: Consolidating corpus databases");
     // Get the list
     $databases = $this->getDatabasesByProject(FingerprinterContract::MATCH_CORPUS, $project);
     // Corpus is a little different; we want to keep the days separate
     // Break the list by date
     $buckets = array();
     foreach ($databases as $database) {
         if (preg_match('/(\\d\\d\\d\\d\\_\\d\\d\\_\\d\\d)\\-project/', $database, $matches)) {
             $bucket = $matches[1];
             if (!array_key_exists($bucket, $buckets)) {
                 $buckets[$bucket] = array();
             }
             $buckets[$bucket][] = $database;
         }
     }
     // Consolidate the buckets
     $results['corpuses'] = array();
     foreach ($buckets as $databases) {
         $database_remappings = $this->mergeDatabases($databases);
         $results['corpuses'] = array_merge($results['corpuses'], $database_remappings);
         // Remap moved media
         foreach ($database_remappings as $remap) {
             $original_database = $remap['original'];
             $new_database = $remap['new'];
             // Get all media that was in the original database
             $media_list = Media::where('corpus_database', '=', $original_database)->get();
             // Update the database to point to the new location
             foreach ($media_list as $media) {
                 $media->corpus_database = $new_database;
                 $media->save();
             }
         }
     }
     $task_logs[] = $this->logLine("End:   Consolidating corpus databases");
     /////////////////////////
     // Consolidate distractors
     $task_logs[] = $this->logLine("Start: Consolidating distractor databases");
     // Get the list
     $databases = $this->getDatabasesByProject(FingerprinterContract::MATCH_DISTRACTOR, $project);
     // Consolidate the list
     $database_remappings = $this->mergeDatabases($databases);
     $results['distractors'] = $database_remappings;
     // Remap moved media
     foreach ($database_remappings as $remap) {
         $original_database = $remap['original'];
         $new_database = $remap['new'];
         // Get all media that was in the original database
         $media_list = Media::where('distractor_database', '=', $original_database)->get();
         // Update the database to point to the new location
         foreach ($media_list as $media) {
             $media->distractor_database = $new_database;
             $media->save();
         }
     }
     $task_logs[] = $this->logLine("End:   Consolidating distractor databases");
     /////////////////////////
     // Consolidate targets
     $task_logs[] = $this->logLine("Start: Consolidating target databases");
     // Get the list
     $databases = $this->getDatabasesByProject(FingerprinterContract::MATCH_TARGET, $project);
     // Consolidate the list
     $database_remappings = $this->mergeDatabases($databases);
     $results['targets'] = $database_remappings;
     // Remap moved media
     foreach ($database_remappings as $remap) {
         $original_database = $remap['original'];
         $new_database = $remap['new'];
         // Get all media that was in the original database
         $media_list = Media::where('target_database', '=', $original_database)->get();
         // Update the database to point to the new location
         foreach ($media_list as $media) {
             $media->target_database = $new_database;
             $media->save();
         }
     }
     $task_logs[] = $this->logLine("End:   Consolidating target databases");
     // We're done messing with project files, release the lock
     $task_logs[] = $this->logLine("Start: Releasing project lock");
     flock($project_lockfile, LOCK_UN);
     fclose($project_lockfile);
     $task_logs[] = $this->logLine("End:   Releasing project lock");
     return array('results' => $results, 'output' => $task_logs);
 }