? tests/.DS_Store
Index: parser_ical.dateapi.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/parser_ical/parser_ical.dateapi.inc,v
retrieving revision 1.4
diff -u -p -r1.4 parser_ical.dateapi.inc
--- parser_ical.dateapi.inc	19 Jan 2010 11:55:42 -0000	1.4
+++ parser_ical.dateapi.inc	19 Feb 2010 01:11:37 -0000
@@ -51,7 +51,14 @@ function _parser_ical_parse($feed_conten
 
       $item['guid'] = isset($event['UID']) ? $event['UID'] : ''; // intention
       $item['tags'] = isset($event['CATEGORIES']) ? explode(',', $event['CATEGORIES']) : array();
-      $item['ical_date'] = new ParserIcalDateTimeElement($event);
+      $item['ical_date'] = new ParserIcalDateTimeElement($event);      
+      if (isset($event['GEO'])) {
+        list($latitude, $longitude) = explode(';', $event['GEO']);
+        $item['ical_geo']  = array('latitude' => $latitude, 'longitude' => $longitude);
+      }
+      else {
+        $item['ical_geo']  = array();
+      }
       $parsed_source['items'][] = $item;
     }
   }
Index: parser_ical.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/parser_ical/parser_ical.module,v
retrieving revision 1.5
diff -u -p -r1.5 parser_ical.module
--- parser_ical.module	19 Jan 2010 11:55:42 -0000	1.5
+++ parser_ical.module	19 Feb 2010 01:11:37 -0000
@@ -39,6 +39,33 @@ function parser_ical_feeds_plugins() {
 }
 
 /**
+ * Implementation of hook_feeds_node_processor_targets_alter().
+ */
+function parser_ical_feeds_node_processor_targets_alter(&$targets, $content_type) {
+  $info = content_types($content_type);
+  if (module_exists('location')) {
+    $settings = variable_get('location_settings_node_'. $content_type, array());
+    if ($settings['multiple']['max'] > 0) {
+      $targets['location_single_latlon'] = array(
+        'name' => 'Location: Latitude/Longitude',
+        'callback' => 'parser_ical_feeds_set_target',
+        'description' => t('Location module Latitude/Longitude settings.'),
+      );
+    }
+  }
+}
+
+/**
+ * Mapping function for Parser iCal targets
+ */
+function parser_ical_feeds_set_target($node, $target, $value) {
+  if ($target == 'location_single_latlon') {
+    $node->locations[0]['latitude']  = $value['latitude'];
+    $node->locations[0]['longitude'] = $value['longitude'];
+  }
+}
+
+/**
  * Implementation of hook_help().
  */
 function parser_ical_help($path, $arg) {
Index: includes/ParserIcalFeedsParser.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/parser_ical/includes/ParserIcalFeedsParser.inc,v
retrieving revision 1.1
diff -u -p -r1.1 ParserIcalFeedsParser.inc
--- includes/ParserIcalFeedsParser.inc	19 Jan 2010 11:55:42 -0000	1.1
+++ includes/ParserIcalFeedsParser.inc	19 Feb 2010 01:11:37 -0000
@@ -154,6 +154,10 @@ class ParserIcalFeedsParser extends Feed
          'name' => t('iCal Date'),
          'description' => t('iCal date associated with item as an array.'),
       ),
+      'ical_geo' => array(
+         'name' => t('iCal Geo (lat/lon)'),
+         'description' => t('iCal Geo latitude/longitude coordinates associated with item as an array.'),
+      ),
     );
   }
 }
Index: tests/parser_ical_location.test
===================================================================
RCS file: tests/parser_ical_location.test
diff -N tests/parser_ical_location.test
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/parser_ical_location.test	19 Feb 2010 01:11:37 -0000
@@ -0,0 +1,105 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Test case for location ical date field mapper mappers/content.inc.
+ */
+
+require_once(drupal_get_path('module', 'feeds') . '/tests/feeds_mapper_test.inc');
+
+/**
+ * Class for testing parser_ical <em>location</em> mapper.
+ */
+class ParserIcalLocationTestCase extends FeedsMapperTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => t('Location integration'),
+      'description' => t('Test iCal parser location mapping. <strong>Requires Content, Location and Date module.</strong>'),
+      'group' => t('iCal Parser'),
+    );
+  }
+
+  public function absolutePath() {
+    return $this->absolute() . '/'. drupal_get_path('module', 'parser_ical');
+  }
+
+  /**
+   * Set up the test.
+   */
+  public function setUp() { 
+    // Call parent setup with the required module.
+    parent::setUp('feeds', 'feeds_ui', 'ctools', 'content', 'date_api', 'date', 'parser_ical', 'location', 'location_node');
+
+    // Create user and login.
+    $this->drupalLogin($this->drupalCreateUser(
+        array(
+          'administer content types',
+          'administer feeds',
+          'administer nodes',
+          'administer site configuration',
+        )
+    ));
+
+  }
+
+  /**
+   * Basic test configured feed item, to import feed into.
+   */
+  public function createConfiguredFeed() {
+    // Create content type and enable location.
+    $typename = $this->createContentType(NULL, array());
+    $admin_type_url = 'admin/content/node-type/'. str_replace('_', '-', $typename);
+    $edit = array(
+      'location_settings[multiple][max]' => 1,
+      'location_settings[multiple][add]' => 1,
+    );
+    $this->drupalPost($admin_type_url, $edit, t('Save content type'));
+    
+    // Create and configure importer.
+    $this->createFeedConfiguration('iCal Feed', 'ical');
+    $this->setSettings('ical', NULL, array('content_type' => '', 'import_period' => FEEDS_SCHEDULE_NEVER, ));
+    $this->setPlugin('ical', 'FeedsFileFetcher');
+    $this->setPlugin('ical', 'ParserIcalFeedsParser');
+    $this->setSettings('ical', 'FeedsNodeProcessor', array('content_type' => $typename));
+    $this->addMappings('ical', array(
+      array(
+        'source' => 'title',
+        'target' => 'title',
+      ),
+      array(
+        'source' => 'ical_geo',
+        'target' => 'location_single_latlon',
+      ),
+    ));
+
+    return $typename;
+  }
+
+  /**
+   * Basic test using Basic.ics
+   */
+  public function testBasicFeed() {
+    $typename = $this->createConfiguredFeed();
+    // Import iCal file.
+    $this->importFile('ical', $this->absolutePath() .'/tests/feeds/Basic.ics');
+    $this->assertText('Created 7 '. $typename .' nodes.');
+    // Check the imported nodes.
+    $data = array(
+      array('title' => 'Simple start and end', 'longitude' => '-122.8', 'latitude' => '49.05'),
+      array('title' => 'Different start and end', 'longitude' => '-122.8', 'latitude' => '49.05'),
+      array('title' => 'No timezone this time', 'longitude' => '-122.8', 'latitude' => '49.05'),
+      array('title' => 'UTC demarked with Z, over midnight.', 'longitude' => '-122.8', 'latitude' => '49.05'),
+      array('title' => 'No timezone whole day', 'longitude' => '-122.8', 'latitude' => '49.05'),
+      array('title' => 'Single day as created by ms and google.', 'longitude' => '-122.8', 'latitude' => '49.05'),
+      array('title' => 'Multiple whole days', 'longitude' => '-122.8', 'latitude' => '49.05'),
+    );
+    foreach ($data as $d) {
+      $n = node_load(array('title' => $d['title']), NULL, TRUE);
+      $this->assertEqual($n->locations[0]['latitude'], $d['latitude'], 'Location latitude is the expected value', 'Location');
+      $this->assertEqual($n->locations[0]['longitude'], $d['longitude'], 'Location longitude is the expected value', 'Location');
+    }
+  }
+
+}
Index: tests/feeds/Basic.ics
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/parser_ical/tests/feeds/Basic.ics,v
retrieving revision 1.1
diff -u -p -r1.1 Basic.ics
--- tests/feeds/Basic.ics	19 Jan 2010 11:55:42 -0000	1.1
+++ tests/feeds/Basic.ics	19 Feb 2010 01:11:37 -0000
@@ -13,6 +13,7 @@ CREATED:20090131T043208Z
 SUMMARY:Simple start and end
 DESCRIPTION: With Montreal timezone undefined by any VTIMEZONE. An individual "VTIMEZONE" calendar component MUST be specified for each unique "TZID" parameter value specified in the iCalendar object.
 LOCATION:Text location
+GEO:49.05;-122.8
 END:VEVENT
 BEGIN:VEVENT
 UID:basic.example.com/2
@@ -23,6 +24,7 @@ CREATED:20090131T131037Z
 SUMMARY:Different start and end
 DESCRIPTION: With different timezone\, Paris.
 LOCATION:Text location
+GEO:49.05;-122.8
 END:VEVENT
 BEGIN:VEVENT
 UID:basic.example.com/3
@@ -33,6 +35,7 @@ CREATED:20090831T141111Z
 SUMMARY:No timezone this time
 DESCRIPTION: Should default\, also need to test with x-timezone set
 LOCATION:Text location
+GEO:49.05;-122.8
 END:VEVENT
 BEGIN:VEVENT
 UID:basic.example.com/4
@@ -43,6 +46,7 @@ CREATED:20090830T141111Z
 SUMMARY:UTC demarked with Z\, over midnight. 
 DESCRIPTION: Should have two days
 LOCATION:Text location
+GEO:49.05;-122.8
 END:VEVENT
 BEGIN:VEVENT
 UID:basic.example.com/5
@@ -52,6 +56,7 @@ CREATED:20090830T141111Z
 SUMMARY:No timezone whole day
 DESCRIPTION: No end time either
 LOCATION:Text location
+GEO:49.05;-122.8
 END:VEVENT
 BEGIN:VEVENT
 UID:basic.example.com/6
@@ -62,6 +67,7 @@ CREATED:20090830T141111Z
 SUMMARY:Single day as created by ms and google.
 DESCRIPTION: Has next day as end\, but only whole days\, should be interpreted as a single day.
 LOCATION:Text location
+GEO:49.05;-122.8
 END:VEVENT
 BEGIN:VEVENT
 UID:basic.example.com/7
@@ -72,5 +78,6 @@ CREATED:20090930T141111Z
 SUMMARY:Multiple whole days
 DESCRIPTION: Common on upcoming.org 
 LOCATION:Text location
+GEO:49.05;-122.8
 END:VEVENT
 END:VCALENDAR
