Index: aggregator.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator.module,v
retrieving revision 1.246
diff -u -p -F^f -r1.246 aggregator.module
--- aggregator.module	11 Aug 2005 13:12:44 -0000	1.246
+++ aggregator.module	20 Aug 2005 02:24:27 -0000
@@ -122,6 +122,9 @@ function aggregator_menu($may_cache) {
     $items[] = array('path' => 'admin/aggregator/add/feed', 'title' => t('add feed'),
       'callback' => 'aggregator_admin_edit_feed', 'access' => $edit,
       'type' => MENU_LOCAL_TASK);
+    $items[] = array('path' => 'admin/aggregator/add/opml', 'title' => t('import feeds'),
+      'callback' => 'aggregator_admin_import_feed', 'access' => $edit,
+      'type' => MENU_LOCAL_TASK);
     $items[] = array('path' => 'admin/aggregator/add/category', 'title' => t('add category'),
       'callback' => 'aggregator_admin_edit_category', 'access' => $edit,
       'type' => MENU_LOCAL_TASK);
@@ -839,6 +842,41 @@ function aggregator_admin_edit_category(
 }
 
 /**
+ * Menu callback; displays the feed import form.
+ * After importing, saves changes and redirects to the overview page.
+ */
+function aggregator_admin_import_feed($feed = 0) {
+  $edit = $_POST['edit'];
+  $op = $_POST['op'];
+
+  $output = "";
+
+  switch ($op) {
+    case t('Submit'):
+      $file = file_check_upload('opml');
+      
+      if ($file=file($file->filepath)) {
+        $file = implode('',$file);
+        if (_aggregator_import($file)) {
+          drupal_set_message(t('Successfuly Imported Feeds from OPML'));
+          drupal_goto('admin/aggregator');
+        }
+        else {
+          form_set_error('Bad File', t('Feel list could not be imported.  Please check that this is an OPML file.'));
+        }
+        break;
+      }
+      else form_set_error('Bad File', t('Data could not be retrieved, invalid or empty file.'));
+    default:
+      $form = form_file(t('OPML File'), 'opml', 50, t('Upload an OPML file containing a list of newsfeeds to be imported.'), TRUE);
+      $form .= form_submit(t('Submit'));
+      $output .=  form($form, 'POST', NULL, array('enctype' => 'multipart/form-data'));
+  }
+
+  print theme('page', $output);
+}
+
+/**
  * Menu callback; displays the feed edit form.
  *
  * After editing, saves changes and redirects to the overview page.
@@ -1067,6 +1105,45 @@ function aggregator_page_categories() {
 }
 
 /**
+ * Imports from OPML
+ */
+function _aggregator_import($opml) {
+
+  $feeds = array();
+  $error = FALSE;
+
+  $parser = drupal_xml_parser_create($opml);
+
+  //Some OPML Files don't have the xml tag, which causes parsing to fail. Hence, using the appended version as a fallback parse
+  if (xml_parse_into_struct($parser,$opml,$vals,$index) || xml_parse_into_struct($parser,'<?xml version="1.0"?>'.$opml,$vals,$index)) {
+
+    foreach($vals as $entry) {
+      if ($entry['tag'] == 'OUTLINE') {
+        $feeds[] = $entry['attributes'];
+      }
+    }
+
+    foreach($feeds as $n=>$feed) {
+      if ($feed['XMLURL']) {
+        $edit = array('title' => $feed['TEXT'], 'url' => $feed['XMLURL']);
+
+        //Adding '@' to bypass the problem of duplicate INSERTS
+        @aggregator_save_feed($edit);
+      }
+    }
+
+  }
+  else{
+
+   form_set_error('Bad format', t('Invalid Format'));
+   $error = TRUE;
+
+  }
+
+  return !$error;
+}
+
+/**
  * Format a news feed.
  *
  * @ingroup themeable
