? .git
? .gitignore
? 927892-2_process_in_background.patch
? 928836-1_set_progress.patch
? state.patch
? libraries/simplepie.inc
Index: CHANGELOG.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feeds/CHANGELOG.txt,v
retrieving revision 1.176.2.5
diff -u -p -r1.176.2.5 CHANGELOG.txt
--- CHANGELOG.txt	1 Oct 2010 15:24:57 -0000	1.176.2.5
+++ CHANGELOG.txt	1 Oct 2010 17:27:40 -0000
@@ -3,6 +3,7 @@
 Feeds 7.x 2.0 XXXXXXXXXXXXXXXXXXX
 ---------------------------------
 
+- #928836: Set progress floating point directly.
 - #928728: Track source states by stage, not by plugin. Note: call signature of
   FeedsSource::state() has changed.
 - #923318: Fix Fatal error: Call to a member function import() on a non-object
Index: feeds.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feeds/feeds.module,v
retrieving revision 1.74.2.3
diff -u -p -r1.74.2.3 feeds.module
--- feeds.module	30 Sep 2010 19:57:25 -0000	1.74.2.3
+++ feeds.module	1 Oct 2010 17:27:40 -0000
@@ -15,8 +15,7 @@ define('FEEDS_EXPIRE_NEVER', -1);
 // An object that is not persistent. Compare EXPORT_IN_DATABASE, EXPORT_IN_CODE.
 define('FEEDS_EXPORT_NONE', 0x0);
 // Status of batched operations.
-define('FEEDS_BATCH_COMPLETE', 1);
-define('FEEDS_BATCH_ACTIVE', 0);
+define('FEEDS_BATCH_COMPLETE', 1.0);
 
 /**
  * @defgroup hooks Hook and callback implementations
Index: includes/FeedsSource.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feeds/includes/FeedsSource.inc,v
retrieving revision 1.26.2.4
diff -u -p -r1.26.2.4 FeedsSource.inc
--- includes/FeedsSource.inc	1 Oct 2010 15:53:25 -0000	1.26.2.4
+++ includes/FeedsSource.inc	1 Oct 2010 17:27:40 -0000
@@ -64,9 +64,9 @@ interface FeedsSourceInterface {
  */
 class FeedsState {
   /**
-   * Natural numbers denoting the total and the progress of that total made.
+   * Floating point number denoting the progress made. 0.0 meaning no progress
+   * 1.0 = FEEDS_BATCH_COMPLETE meaning finished.
    */
-  public $total;
   public $progress;
 
   /**
@@ -77,6 +77,7 @@ class FeedsState {
   /**
    * Natural numbers denoting more details about the progress being made.
    */
+  public $total;
   public $created;
   public $updated;
   public $deleted;
@@ -87,8 +88,8 @@ class FeedsState {
    * Constructor, initialize variables.
    */
   public function __construct() {
+    $this->progress = 0.0;
     $this->total =
-    $this->progress =
     $this->created =
     $this->updated =
     $this->deleted =
@@ -97,29 +98,35 @@ class FeedsState {
   }
 
   /**
-   * Report normalized progress.
+   * Safely report progress.
    *
-   * @return
-   *   A float between 0 and 1, 1 = FEEDS_BATCH_COMPLETE.
-   */
-  public function progress() {
-    // If no total and no progress is reported, we are done.
-    if (empty($this->total) && empty($this->progress)) {
-      return FEEDS_BATCH_COMPLETE;
+   * When $total == $progress, the state of the task tracked by this state is
+   * regarded to be complete.
+   *
+   * Handles the following cases gracefully:
+   *
+   * - $total is 0
+   * - $progress is larger than $total
+   * - $progress approximates $total so that $finished rounds to 1.0
+   *
+   * @param $total
+   *   A natural number that is the total to be worked off.
+   * @param $progress
+   *   A natural number that is the progress made on $total.
+   */
+  public function progress($total, $progress) {
+    if ($progress > $total) {
+      $this->progress = FEEDS_BATCH_COMPLETE;
+    }
+    elseif ($total) {
+      $this->progress = $progress / $total;
+      if ($this->progress == FEEDS_BATCH_COMPLETE && $total != $progress) {
+        $this->progress = 0.99;
+      }
     }
-    $progress = $this->progress / $this->total;
-    if ($progress == FEEDS_BATCH_COMPLETE && $this->total != $this->progress) {
-      return 0.999;
+    else {
+      $this->progress = FEEDS_BATCH_COMPLETE;
     }
-    return $progress;
-  }
-
-  /**
-   * Sets this state to finished.
-   */
-  public function finished() {
-    $this->total =
-    $this->progress = FEEDS_BATCH_COMPLETE;
   }
 }
 
@@ -280,7 +287,7 @@ class FeedsSource extends FeedsConfigura
    * Report progress as float between 0 and 1. 1 = FEEDS_BATCH_COMPLETE.
    */
   public function progressParsing() {
-    return $this->state(FEEDS_PARSE)->progress();
+    return $this->state(FEEDS_PARSE)->progress;
   }
 
   /**
@@ -289,20 +296,25 @@ class FeedsSource extends FeedsConfigura
   public function progressImporting() {
     $fetcher = $this->state(FEEDS_FETCH);
     $parser = $this->state(FEEDS_PARSE);
-    if ($fetcher->progress() == FEEDS_BATCH_COMPLETE && $parser->progress() == FEEDS_BATCH_COMPLETE) {
+    if ($fetcher->progress == FEEDS_BATCH_COMPLETE && $parser->progress == FEEDS_BATCH_COMPLETE) {
       return FEEDS_BATCH_COMPLETE;
     }
     // Fetching envelops parsing.
-    $parser_progress = $parser->progress() / $fetcher->total;
-    $fetcher_fraction = 1.0 / $fetcher->total;
-    return $fetcher->progress() - $fetcher_fraction + $parser_progress;
+    // @todo: this assumes all fetchers neatly use total. May not be the case.
+    $fetcher_fraction = $fetcher->total ? 1.0 / $fetcher->total : 1.0;
+    $parser_progress = $parser->progress * $fetcher_fraction;
+    $result = $fetcher->progress - $fetcher_fraction + $parser_progress;
+    if ($result == FEEDS_BATCH_COMPLETE) {
+      return 0.99;
+    }
+    return $result;
   }
 
   /**
    * Report progress on clearing.
    */
   public function progressClearing() {
-    return $this->state(FEEDS_PROCESS_CLEAR)->progress();
+    return $this->state(FEEDS_PROCESS_CLEAR)->progress;
   }
 
   /**
Index: plugins/FeedsCSVParser.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsCSVParser.inc,v
retrieving revision 1.19.2.3
diff -u -p -r1.19.2.3 FeedsCSVParser.inc
--- plugins/FeedsCSVParser.inc	1 Oct 2010 15:24:57 -0000	1.19.2.3
+++ plugins/FeedsCSVParser.inc	1 Oct 2010 17:27:40 -0000
@@ -33,8 +33,9 @@ class FeedsCSVParser extends FeedsParser
 
     // Report progress.
     $state->total = filesize($fetcher_result->getFilePath());
-    $state->pointer =
-    $state->progress = $parser->lastLinePos() ? $parser->lastLinePos() : $state->total;
+    $state->pointer = $parser->lastLinePos();
+    $progress = $parser->lastLinePos() ? $parser->lastLinePos() : $state->total;
+    $state->progress($state->total, $progress);
 
     // Create a result object and return it.
     return new FeedsParserResult($rows, $source->feed_nid);
Index: plugins/FeedsFileFetcher.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsFileFetcher.inc,v
retrieving revision 1.22.2.2
diff -u -p -r1.22.2.2 FeedsFileFetcher.inc
--- plugins/FeedsFileFetcher.inc	1 Oct 2010 15:24:57 -0000	1.22.2.2
+++ plugins/FeedsFileFetcher.inc	1 Oct 2010 17:27:40 -0000
@@ -58,13 +58,11 @@ class FeedsFileFetcher extends FeedsFetc
     $files = array();
     if (!isset($state->files)) {
       $state->files = $this->listFiles($source_config['source']);
-      $state->progress =
       $state->total = count($state->files);
     }
     if (count($state->files)) {
       $file = array_shift($state->files);
-      // When progress == total, file fetcher will not be called again.
-      $state->progress = $state->total - count($state->files);
+      $state->progress($state->total, $state->total - count($state->files));
       return new FeedsFileFetcherResult($file);
     }
 
Index: plugins/FeedsNodeProcessor.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsNodeProcessor.inc,v
retrieving revision 1.69.2.3
diff -u -p -r1.69.2.3 FeedsNodeProcessor.inc
--- plugins/FeedsNodeProcessor.inc	1 Oct 2010 15:53:25 -0000	1.69.2.3
+++ plugins/FeedsNodeProcessor.inc	1 Oct 2010 17:27:40 -0000
@@ -87,7 +87,7 @@ class FeedsNodeProcessor extends FeedsPr
     }
     node_delete_multiple($nids);
     if (db_query_range("SELECT 1 FROM {node} n JOIN {feeds_node_item} fn ON n.nid = fn.nid WHERE fn.id = :id AND fn.feed_nid = :nid", 0, 1, array(':id' => $source->id, ':nid' => $source->feed_nid))->fetchField()) {
-      $state->progress = $state->deleted;
+      $state->progress($state->total, $state->deleted);
       return;
     }
 
@@ -99,7 +99,9 @@ class FeedsNodeProcessor extends FeedsPr
     else {
       drupal_set_message(t('There is no content to be deleted.'));
     }
-    $state->finished();
+    // Make sure we are finished, there may be a discrepancy between total and
+    // deleted if other processes have deleted nodes in the meantime.
+    $state->progress = FEEDS_BATCH_COMPLETE;
   }
 
   /**
