Index: ffmpeg_converter.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/ffmpeg_converter/ffmpeg_converter.module,v
retrieving revision 1.40
diff -u -p -r1.40 ffmpeg_converter.module
--- ffmpeg_converter.module	22 Nov 2009 11:15:51 -0000	1.40
+++ ffmpeg_converter.module	23 Nov 2009 00:06:44 -0000
@@ -202,7 +202,7 @@ function ffmpeg_converter_nodeform(&$for
       // Add options to clear converted files and select one of the tree snapshot images.
       if (!empty($form['nid']['#value'])) {
         
-        if (ffmpeg_converter_file_is_queued($form['nid']['#value'], $field_def['field_name'])) {
+        if (ffmpeg_converter_filefield_is_queued($form['nid']['#value'], $field_def['field_name'])) {
           $field['ffmpeg_converter_queued'] = array(
             '#type' => 'markup',
             '#value' => t('<p><strong>Note:</strong> This file has been added to the !job_queue and will be converted on the next available cron run.</p>', array('!job_queue' => l(t('job queue'), 'admin/reports/job_queue'))),
@@ -244,11 +244,13 @@ function ffmpeg_converter_nodeform(&$for
             '#prefix' => '<div class="ffmpeg-converter-snapshot-selection clear-block">',
             '#suffix' => '</div>',
           );
-          if (is_numeric($form_state['values'][$field_def['field_name']]['ffmpeg_converter_snapshot'])) {
-            $field['ffmpeg_converter_snapshot']['#default_value'] = $form_state['values'][$field_def['field_name']]['ffmpeg_converter_snapshot'];
-          }
-          elseif (is_int($form['#ffmpeg_converter_selected_snapshots'][$field_def['field_name']])) {
-            $field['ffmpeg_converter_snapshot']['#default_value'] = $form['#ffmpeg_converter_selected_snapshots'][$field_def['field_name']];
+          if (isset($form_state['values'])) {
+            if (is_numeric($form_state['values'][$field_def['field_name']]['ffmpeg_converter_snapshot'])) {
+              $field['ffmpeg_converter_snapshot']['#default_value'] = $form_state['values'][$field_def['field_name']]['ffmpeg_converter_snapshot'];
+            }
+            elseif (is_int($form['#ffmpeg_converter_selected_snapshots'][$field_def['field_name']])) {
+              $field['ffmpeg_converter_snapshot']['#default_value'] = $form['#ffmpeg_converter_selected_snapshots'][$field_def['field_name']];
+            }
           }
         }
       }
@@ -444,12 +446,16 @@ function ffmpeg_converter_nodeapi(&$node
             case 'insert':
             case 'update':
               // Look for new files.
-              if (!empty($original) && empty($converted) && !ffmpeg_converter_file_is_queued($node->nid, $field['field_name'])) {
+              if (!empty($original) && empty($converted) && !ffmpeg_converter_filefield_is_queued($node->nid, $field['field_name'])) {
+                // This file may or may not need to be converted.
                 list($field_instance, $file) = array_pop($original);
                 if (ffmpeg_converter_check_file($file['filename'], $preset_key)) {
-                  // Queue file for processing.
-                  ffmpeg_converter_queue_filefield($node->nid, $field['field_name'], 0, $preset_key);
-                  drupal_set_message(t('The file %file was added to the job queue.', array('%file' => check_plain($file['filename']))));
+                  ffmpeg_converter_filefield_queue($node->nid, $field['field_name'], 0, $preset_key, 'convert');
+                  drupal_set_message(t('The file %file was queued be converted.', array('%file' => check_plain($file['filename']))));
+                }
+                if (ffmpeg_converter_check_file_snapshot($file['filepath'])) {
+                  ffmpeg_converter_filefield_queue($node->nid, $field['field_name'], 0, $preset_key, 'snapshot');
+                  drupal_set_message(t('The file %file was queued to have snapshot images generated.', array('%file' => check_plain($file['filename']))));
                 }
               }
               break;
@@ -474,7 +480,7 @@ function ffmpeg_converter_nodeapi(&$node
       }
     }
     
-    if ($op = 'view' && !empty($view_messages)) {
+    if ($op == 'view' && !empty($view_messages)) {
       $node->content['ffmpeg_converter_messages'] = array(
         '#value' => theme('ffmpeg_converter_messages', $view_messages)
       );
@@ -491,7 +497,7 @@ function ffmpeg_converter_nodeapi(&$node
  *   The name of the file.
  * @param $preset_key
  *   The key of this configuration preset, such as "preset-1".
- * @return unknown
+ * @return
  *   TRUE if file should be converted, FALSE otherwise.
  */
 function ffmpeg_converter_check_file($filename, $preset_key) {
@@ -513,6 +519,23 @@ function ffmpeg_converter_check_file($fi
 
 
 /**
+ * Check if a file should be have snapshot images generated.
+ *
+ * @param $filename
+ *   The name of the file.
+ * @return
+ *   TRUE if file should have snapshots generated, FALSE otherwise.
+ */
+function ffmpeg_converter_check_file_snapshot($filepath) {
+
+  // Try to get video duration to determine if this is a video file.
+  $duration = ffmpeg_wrapper_file_duration($filepath, false);
+
+  return (bool) $duration;
+}
+
+
+/**
  * Add a file field to the process queue.
  *
  * @param $nid
@@ -524,13 +547,21 @@ function ffmpeg_converter_check_file($fi
  *   $node->{$field_name} array.
  * @param $preset_key
  *   The key of the FFmpeg Converter preset to use.
+ * @param $action
+ *   Either 'convert' or 'snapshot'.
  * @return
  *   FALSE if Job queue is unavailable, NULL otherwise.
  */
-function ffmpeg_converter_queue_filefield($nid, $field_name, $field_instance, $preset_key) {
+function ffmpeg_converter_filefield_queue($nid, $field_name, $field_instance, $preset_key, $action = 'convert') {
   if (function_exists('job_queue_add')) {
-    cache_clear_all('ffmpeg_converter_queued_files', 'cache');
-    return job_queue_add('ffmpeg_converter_convert_filefield', t('Convert a file field with FFmpeg.'), array($nid, $field_name, $field_instance, $preset_key));
+    cache_clear_all('ffmpeg_converter_filefield_queued_files', 'cache');
+    switch ($action) {
+      case 'convert':
+        return job_queue_add('ffmpeg_converter_filefield_convert', t('Convert a file field with FFmpeg.'), array($nid, $field_name, $field_instance, $preset_key));
+        break;
+      case 'snapshot':
+        return job_queue_add('ffmpeg_converter_filefield_snapshots', t('Create snapshot images for a file field with FFmpeg.'), array($nid, $field_name, $field_instance, $preset_key));
+    }
   }
   else {
     return false;
@@ -548,20 +579,21 @@ function ffmpeg_converter_queue_filefiel
  * @return 
  *   TRUE or FALSE.
  */
-function ffmpeg_converter_file_is_queued($nid, $field) {
-  $cache = cache_get('ffmpeg_converter_queued_files');
+function ffmpeg_converter_filefield_is_queued($nid, $field) {
+  $cache = cache_get('ffmpeg_converter_filefield_queued_files');
   
   if ($cache) {
     $files = $cache->data;
   }
   else {
-    $jobs = db_query("SELECT * FROM {job_queue} WHERE function = 'ffmpeg_converter_convert_filefield'");
+    $jobs = db_query("SELECT * FROM {job_queue} WHERE function LIKE 'ffmpeg_converter_filefield_%'");
     $files = array();
     while ($job = db_fetch_array($jobs)) {
       $args = unserialize($job['arguments']);
       $files[] = $args[0] . '-' . $args[1];
     }
-    cache_set('ffmpeg_converter_queued_files', $files);
+    $files = array_unique($files);
+    cache_set('ffmpeg_converter_filefield_queued_files', $files);
   }
   
   return in_array($nid . '-' . $field, $files);
@@ -609,7 +641,32 @@ function ffmpeg_converter_filename($sour
 
 
 /**
- * Enter description here...
+ * Prepare the necessary parts before a conversion.
+ *
+ * @return
+ *   true if things are in good working order, false otherwise.
+ */
+function ffmpeg_converter_filefield_setup_conversion() {
+  // This only needs to happen once per page load/cron run.
+  static $res;
+
+  if (!is_bool($res)) {
+    // Clear the cached list of queued files.
+    cache_clear_all('ffmpeg_converter_filefield_queued_files', 'cache');
+
+    // Load the .inc pages that we need.
+    module_load_include('inc', 'node', 'node.pages');
+    module_load_include('inc', 'filefield', 'field_file');
+
+    $res = function_exists('field_file_save_file') ? true : false;
+  }
+
+  return $res;
+}
+
+
+/**
+ * Convert a filefield file with FFmpeg.
  *
  * @param $nid
  *   The id of the container node.
@@ -621,26 +678,17 @@ function ffmpeg_converter_filename($sour
  * @param $preset_key
  *   The key of the FFmpeg Converter preset to use.
  */
-function ffmpeg_converter_convert_filefield($nid, $field_name, $field_instance, $preset_key) {
-  
-  $node = node_load($nid);
-  
-  // Clear the cached list of queued files.
-  cache_clear_all('ffmpeg_converter_queued_files', 'cache');
-  
-  // Check the necessary prerequisites.
-  if (empty($node) || empty($node->{$field_name}[$field_instance]['fid']) || !function_exists('content_fields')) {
+function ffmpeg_converter_filefield_convert($nid, $field_name, $field_instance, $preset_key) {
+  if (!ffmpeg_converter_filefield_setup_conversion()) {
     return false;
   }
-  
-  // Load the .inc pages that we need.
-  module_load_include('inc', 'node', 'node.pages');
-  module_load_include('inc', 'filefield', 'field_file');
-  
-  if (!function_exists('field_file_save_file')) {
+  $node = node_load($nid, NULL, TRUE); // Reset the static node cache.
+
+  // Check the necessary prerequisites.
+  if (empty($node->{$field_name}[$field_instance]['fid']) || !function_exists('content_fields')) {
     return false;
   }
-  
+
   // Load the CCK field.
   $field = content_fields($field_name, $node->type);
   
@@ -688,10 +736,50 @@ function ffmpeg_converter_convert_filefi
   // Add the file to the node.
   $node->{$field_name}[] = $file;
   
-  // Try to get video duration and determine if this is a video file.
-  $duration = ffmpeg_wrapper_file_duration($input_file, false);
-  
-  if ($duration) {
+  // Save the node.
+  $node = node_submit($node);
+  node_save($node);
+
+  watchdog('ffmpeg_converter', 'FFmpeg converted the file %file to @format.',
+    array('%file' => basename($input_file), '@format' => $configuration['ffmpeg_output_type']), 
+    WATCHDOG_NOTICE, l(t('Source node'), 'node/'. $node->nid));
+}
+
+
+/**
+ * Add snapshot images for a filefield file with FFmpeg.
+ *
+ * @param $nid
+ *   The id of the container node.
+ * @param $field_name
+ *   The name of the field that contains the source file.
+ * @param $field_instance
+ *   The field instance as an integer representing the key in the 
+ *   $node->{$field_name} array.
+ * @param $preset_key
+ *   The key of the FFmpeg Converter preset to use.
+ */
+function ffmpeg_converter_filefield_snapshots($nid, $field_name, $field_instance, $preset_key) {
+  if (!ffmpeg_converter_filefield_setup_conversion()) {
+    return false;
+  }
+  $node = node_load($nid, NULL, TRUE); // Reset the static node cache.
+
+  // Check the necessary prerequisites.
+  if (empty($node->{$field_name}[$field_instance]['fid']) || !function_exists('content_fields')) {
+    return false;
+  }
+
+  // Load the CCK field.
+  $field = content_fields($field_name, $node->type);
+
+  // Get preset configuration.
+  $configuration = ffmpeg_converter_options($preset_key);
+
+  // Setup paths.
+  $input_file = $node->{$field_name}[$field_instance]['filepath'];
+
+  if (ffmpeg_converter_check_file_snapshot($input_file)) {
     
     // Take three snapshot images of the film.
     $duration = ffmpeg_wrapper_file_duration($input_file, false);
@@ -711,7 +799,14 @@ function ffmpeg_converter_convert_filefi
       $size = $configuration[$configuration['ffmpeg_video_size'] == 'other' ? 'ffmpeg_video_size_other' : 'ffmpeg_video_size'];
       if ($snapshot = ffmpeg_converter_create_snapshot($input_file, file_directory_temp(), $timecode, $size)) {
       
+        // We don't use filefield validators for saving generated files. We could use
+        // filefield_widget_upload_validators($field) to fetch the configured
+        // restrictions for this field, but that might lead to situations where
+        // conversions will fail inexplicably.
+        $validators = array();
+
         // Create the snapshot file object.
+        $destination_path = filefield_widget_file_path($field);
         $s_file = field_file_save_file($snapshot, $validators, $destination_path);
         
         if (is_array($s_file)) {
@@ -737,13 +832,13 @@ function ffmpeg_converter_convert_filefi
       
     }
   }
-  
+
   // Save the node.
   $node = node_submit($node);
   node_save($node);
-  
-  watchdog('ffmpeg_converter','FFmpeg converted the file %file to @format.',
-           array('%file' => basename($input_file), '@format' => $configuration['ffmpeg_output_type']), 
+
+  watchdog('ffmpeg_converter','FFmpeg created snapshot images for the file %file.',
+           array('%file' => basename($input_file)),
            WATCHDOG_NOTICE, l(t('Source node'), 'node/' . $node->nid));
 }
 
@@ -1133,7 +1228,7 @@ function ffmpeg_converter_preprocess_con
       foreach ($instance_keys as $key) {
         $item = &$element['items'][$key];
         if (is_array($item['#item']) ) {
-          if (is_array($item['#item']['data']) && isset($item['#item']['data']['ffmpeg_converter_file'])) {
+          if (isset($item['#item']['data']) && isset($item['#item']['data']['ffmpeg_converter_file'])) {
             if ($item['#item']['data']['ffmpeg_converter_file'] == 'converted') {
               $converted = $item;
             }
@@ -1169,7 +1264,7 @@ function ffmpeg_converter_preprocess_con
           $format = $element['items'][0]['#formatter'];
         }
         else {
-          $field = content_fields($element['#field_name']);
+        $field = content_fields($element['#field_name']);
           $format = $field['display_settings']['full']['format'];
         }
         $parts =  explode('_', $format);
