Index: modules/aggregator/aggregator.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.module,v
retrieving revision 1.383
diff -u -r1.383 aggregator.module
--- modules/aggregator/aggregator.module	3 Aug 2008 05:46:55 -0000	1.383
+++ modules/aggregator/aggregator.module	4 Aug 2008 18:59:35 -0000
@@ -599,6 +599,16 @@
     case 200:
     case 302:
     case 307:
+      // We store the md5 hash of feed data in the database. When refreshing a
+      // feed we compare stored hash and new hash calculated from downloaded
+      // data. If both are equal we say that feed is not updated.
+      $md5 = md5($result->data);
+      if ($feed['hash'] == $md5) {
+        db_query('UPDATE {aggregator_feed} SET checked = %d WHERE fid = %d', time(), $feed['fid']);
+        drupal_set_message(t('There is no new syndicated content from %site.', array('%site' => $feed['title'])));
+        break;
+      }
+
       // Filter the input data.
       if (aggregator_parse_feed($result->data, $feed)) {
         $modified = empty($result->headers['Last-Modified']) ? 0 : strtotime($result->headers['Last-Modified']);
@@ -624,7 +634,7 @@
 
         $etag = empty($result->headers['ETag']) ? '' : $result->headers['ETag'];
         // Update the feed data.
-        db_query("UPDATE {aggregator_feed} SET url = '%s', checked = %d, link = '%s', description = '%s', image = '%s', etag = '%s', modified = %d WHERE fid = %d", $feed['url'], time(), $channel['LINK'], $channel['DESCRIPTION'], $image, $etag, $modified, $feed['fid']);
+        db_query("UPDATE {aggregator_feed} SET url = '%s', checked = %d, link = '%s', description = '%s', image = '%s', hash = '%s', etag = '%s', modified = %d WHERE fid = %d", $feed['url'], time(), $channel['LINK'], $channel['DESCRIPTION'], $image, $md5, $etag, $modified, $feed['fid']);
 
         // Clear the cache.
         cache_clear_all();
Index: modules/aggregator/aggregator.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.install,v
retrieving revision 1.16
diff -u -r1.16 aggregator.install
--- modules/aggregator/aggregator.install	15 May 2008 21:27:32 -0000	1.16
+++ modules/aggregator/aggregator.install	4 Aug 2008 18:59:35 -0000
@@ -158,6 +158,13 @@
         'size' => 'big',
         'description' => t('An image representing the feed.'),
       ),
+      'hash' => array(
+        'type' => 'varchar',
+        'length' => 32,
+        'not null' => TRUE,
+        'default' => '',
+        'description' => t('Calculated md5 hash of the feed data, used for validating cache.'),
+      ),
       'etag' => array(
         'type' => 'varchar',
         'length' => 255,
@@ -247,3 +254,12 @@
 
   return $schema;
 }
+
+/**
+ * Add hash column to aggregator_feed table.
+ */
+function aggregator_update_7000() {
+  $ret = array();
+  db_add_field($ret, 'aggregator_feed', 'hash', array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''));
+  return $ret;
+}
Index: modules/aggregator/aggregator.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.admin.inc,v
retrieving revision 1.11
diff -u -r1.11 aggregator.admin.inc
--- modules/aggregator/aggregator.admin.inc	3 Aug 2008 05:46:55 -0000	1.11
+++ modules/aggregator/aggregator.admin.inc	4 Aug 2008 18:59:35 -0000
@@ -20,7 +20,7 @@
  *   The page HTML.
  */
 function aggregator_view() {
-  $result = db_query('SELECT f.*, COUNT(i.iid) AS items FROM {aggregator_feed} f LEFT JOIN {aggregator_item} i ON f.fid = i.fid GROUP BY f.fid, f.title, f.url, f.refresh, f.checked, f.link, f.description, f.etag, f.modified, f.image, f.block ORDER BY f.title');
+  $result = db_query('SELECT f.*, COUNT(i.iid) AS items FROM {aggregator_feed} f LEFT JOIN {aggregator_item} i ON f.fid = i.fid GROUP BY f.fid, f.title, f.url, f.refresh, f.checked, f.link, f.description, f.hash, f.etag, f.modified, f.image, f.block ORDER BY f.title');
 
   $output = '<h3>' . t('Feed overview') . '</h3>';
 
