Index: weather.module
===================================================================
--- weather.module	(revision 202)
+++ weather.module	(working copy)
@@ -225,6 +225,7 @@
   if ($op == 'list') {
     $block[0]['info'] = t('Weather: custom user');
     $block[1]['info'] = t('Weather: location of nodes (requires Location or Node Map module)');
+    $block[2]['info'] = t('Weather: location of users');
     $current_blocks = _weather_get_blocks_in_use();
     if (!empty($current_blocks)) {
       foreach ($current_blocks as $block_id) {
@@ -236,6 +237,8 @@
     return $block;
   }
   else if ($op == 'view') {
+    $block['content'] = '';
+    
     if ($delta == 0 and weather_custom_block_access()) {
       // Show the user's custom weather block, if there is already
       // a location configured. Otherwise, do not show the block.
@@ -244,7 +247,7 @@
         return;
       }
       $block['subject'] = t('Current weather');
-      $block['content'] = '';
+      
       foreach ($configs_in_use as $index) {
         $config = _weather_get_config($user->uid, $index['cid']);
         $metar = weather_get_metar($config['icao']);
@@ -252,83 +255,112 @@
       }
       return $block;
     }
-    else if ($delta == 1 and user_access('access content')) {
-      // show the node location weather block
-      if (arg(0) == 'node' and is_numeric(arg(1))) {
-        $node = node_load(arg(1));
-        $block['content'] = '';
-        // This checks the location module
-        if (isset($node->locations)) {
-          // Iterate through all available locations and check
-          // for lat/long information. If there is no information,
-          // the location module return 0.0/0.0 instead of NULL values
-          foreach ($node->locations as $location) {
-            if (($location['latitude'] != 0) or ($location['longitude'] != 0)) {
-              $nearest_station = weather_get_icao_from_lat_lon(
-                $location['latitude'], $location['longitude']);
-              $config = _weather_get_config(0, 1);
-              $config = array_merge($config, $nearest_station);
-              $config['real_name'] = $config['name'];
-              $metar = weather_get_metar($config['icao']);
-              $block['content'] .= theme('weather_theming', $config, $metar);
+    else if (user_access('access content')) {
+      if ($delta == 1) {
+        // show the node location weather block
+        if (arg(0) == 'node' and is_numeric(arg(1))) {
+          $node = node_load(arg(1));
+          // This checks the location module
+          if (isset($node->locations)) {
+            // Iterate through all available locations and check
+            // for lat/long information. If there is no information,
+            // the location module return 0.0/0.0 instead of NULL values
+            foreach ($node->locations as $location) {
+              if (($location['latitude'] != 0) or ($location['longitude'] != 0)) {
+                $block['content'] .= _weather_get_block_display_from_lat_lon(
+                  $location['latitude'], $location['longitude']);
+              }
             }
           }
+          // Handle CCK location fields
+          // First, determine all names of location fields
+          $sql = "SELECT field_name FROM {content_node_field} WHERE type='location'";
+          $result = db_query($sql);
+          // Cycle through all found field names.
+          while ($field_name = db_result($result)) {
+            // Iterate through all available locations and check
+            // for lat/long information. If there is no information,
+            // the location module return 0.0/0.0 instead of NULL values
+            foreach ($node->$field_name as $location) {
+              if (($location['latitude'] != 0) or ($location['longitude'] != 0)) {
+                $block['content'] .= _weather_get_block_display_from_lat_lon(
+                  $location['latitude'], $location['longitude']);
+              }
+            }
+          }
+          // Handle nodemap module
+          if (isset($node->nodemap_latitude_field)
+            and isset($node->nodemap_longitude_field)
+            and ($node->nodemap_latitude_field != 0 or $node->nodemap_longitude_field != 0)) {
+            $block['content'] .= _weather_get_block_display_from_lat_lon(
+              $node->nodemap_latitude_field, $node->nodemap_longitude_field);
+          }
+          // Do not show block if no lat/long information has been found
+          if ($block['content'] != '') {
+            $block['subject'] = t('Current weather nearby');
+            return $block;
+          }
         }
-        // Handle CCK location fields
-        // First, determine all names of location fields
-        $sql = "SELECT field_name FROM {content_node_field} WHERE type='location'";
-        $result = db_query($sql);
-        // Cycle through all found field names.
-        while ($field_name = db_result($result)) {
-          // Iterate through all available locations and check
-          // for lat/long information. If there is no information,
-          // the location module return 0.0/0.0 instead of NULL values
-          foreach ($node->$field_name as $location) {
-            if (($location['latitude'] != 0) or ($location['longitude'] != 0)) {
-              $nearest_station = weather_get_icao_from_lat_lon(
+      }
+      else if ($delta == 2 and isset($_SERVER['REMOTE_ADDR'])) {
+        if (module_exists('smart_ip')) {
+          $location = smart_ip_get_location($_SERVER['REMOTE_ADDR']);
+          if (!empty($location)) {
+            if (!empty($location['latitude']) && !empty($location['longitude'])) {
+              $block['content'] .= _weather_get_block_display_from_lat_lon(
                 $location['latitude'], $location['longitude']);
-              $config = _weather_get_config(0, 1);
-              $config = array_merge($config, $nearest_station);
-              $config['real_name'] = $config['name'];
-              $metar = weather_get_metar($config['icao']);
-              $block['content'] .= theme('weather_theming', $config, $metar);
             }
           }
         }
-        // Handle nodemap module
-        if (isset($node->nodemap_latitude_field)
-          and isset($node->nodemap_longitude_field)
-          and ($node->nodemap_latitude_field != 0 or $node->nodemap_longitude_field != 0)) {
-          $nearest_station = weather_get_icao_from_lat_lon(
-            $node->nodemap_latitude_field, $node->nodemap_longitude_field);
-          $config = _weather_get_config(0, 1);
-          $config = array_merge($config, $nearest_station);
-          $config['real_name'] = $config['name'];
-          $metar = weather_get_metar($config['icao']);
-          $block['content'] .= theme('weather_theming', $config, $metar);
+        else {
+          // use hostip.info to determine the latitude and longitude based on IP
+          $timeout = 10;
+          $url = 'http://api.hostip.info/get_html.php?ip=';
+          $url .= $_SERVER['REMOTE_ADDR'];
+          $url .= '&position=true';
+          $result = weather_download_data($url, $timeout);
+          // Extract the latitude and longitude from the result, if successful.
+          if ($result !== FALSE) {
+            $latitude = FALSE;
+            $longitude = FALSE;
+            $lines = explode("\n", $result);
+            foreach ($lines as $line) {
+              if (preg_match('/^Latitude: (.*)$/', $line, $matches)) {
+                $latitude = $matches[1];
+              }
+              if (preg_match('/^Longitude: (.*)$/', $line, $matches)) {
+                $longitude = $matches[1];
+              }
+            }
+            if (!empty($latitude) and !empty($longitude)) {
+              $block['content'] .= _weather_get_block_display_from_lat_lon(
+                $latitude, $longitude, array('legal' => 'hostip'));
+            }
+          }
         }
+        
         // Do not show block if no lat/long information has been found
         if ($block['content'] != '') {
-          $block['subject'] = t('Current weather nearby');
+          $block['subject'] = t('Current weather near you');
           return $block;
         }
       }
-    }
-    else if ($delta >= SYSTEM_BLOCK_DELTA_START and user_access('access content')) {
-      // show a system-wide weather block
-      $system_block_id = SYSTEM_BLOCK_DELTA_START - $delta - 1;
-      $block['subject'] = t('Current weather');
-      $block['content'] = '';
-      $configs_in_use = _weather_get_configs_in_use($system_block_id);
-      if (count($configs_in_use) == 0) {
-        $configs_in_use[] = array('cid' => 1);
-      }
-      foreach ($configs_in_use as $index) {
-        $config = _weather_get_config($system_block_id, $index['cid']);
-        $metar = weather_get_metar($config['icao']);
-        $block['content'] .= theme('weather_theming', $config, $metar);
+      else if ($delta >= SYSTEM_BLOCK_DELTA_START) {
+        // show a system-wide weather block
+        $system_block_id = SYSTEM_BLOCK_DELTA_START - $delta - 1;
+        $block['subject'] = t('Current weather');
+        $block['content'] = '';
+        $configs_in_use = _weather_get_configs_in_use($system_block_id);
+        if (count($configs_in_use) == 0) {
+          $configs_in_use[] = array('cid' => 1);
+        }
+        foreach ($configs_in_use as $index) {
+          $config = _weather_get_config($system_block_id, $index['cid']);
+          $metar = weather_get_metar($config['icao']);
+          $block['content'] .= theme('weather_theming', $config, $metar);
+        }
+        return $block;
       }
-      return $block;
     }
   }
 }
@@ -381,6 +413,7 @@
   $weather['real_name'] = check_plain($config['real_name']);
   $weather['condition'] = _weather_format_condition($metar);
   $weather['image'] = _weather_get_image($metar);
+  $weather['legal'] = $config['legal'];
   if (isset($metar['temperature']) and $config['units']['temperature'] != 'dont-display') {
     $weather = array_merge($weather, _weather_format_temperature(
       $metar['temperature'], $metar['wind'], $config['units'], $config['settings']
@@ -463,6 +496,16 @@
     $weather['reported_on'] = format_date($metar['reported_on']);
   }
 
+  // Set up required legal texts, if needed.
+  if (isset($weather['legal'])) {
+    switch ($weather['legal']) {
+      case 'hostip':
+        $weather['legal'] = t('Data provided by <a href="@url">hostip.info</a>.',
+          array('@url' => 'http://www.hostip.info'));
+        break;
+    }
+  }
+  
   // Use compact block, if desired
   if ($config['settings']['show_compact_block']) {
     return theme('weather_compact', $weather);
@@ -1345,6 +1388,18 @@
   return $blocks;
 }
 
+function _weather_get_block_display_from_lat_lon($latitude, $longitude, $optional = null) {
+  $nearest_station = weather_get_icao_from_lat_lon($latitude, $longitude);
+  $config = _weather_get_config(0,1); 
+  $config = array_merge($config, $nearest_station);
+  $config['real_name'] = $config['name'];
+  if (!empty($optional)) {
+    $config = array_merge($config, $optional);
+  }
+  $metar = weather_get_metar($config['icao']);
+  
+  return theme('weather_theming', $config, $metar);
+}
 
 
 /*********************************************************************
@@ -2414,3 +2469,36 @@
   $result->code = $code;
   return $result;
 }
+
+/**
+ * Download handler for various URLs.
+ *
+ * @param URL to download.
+ * @param Timeout in seconds.
+ *
+ * @return Raw data which is returned by the URL or FALSE if download fails.
+ */
+function weather_download_data($url, $timeout) {
+  $data = FALSE;
+  // Try alternative methods for fetching the data.
+  if (function_exists('file_get_contents') and ini_get('allow_url_fopen')) {
+    // Create a stream context to be able to use timeouts
+    $context = stream_context_create(array('http' => array('timeout' => $timeout)));
+    $data = @file_get_contents($url, FALSE, $context);
+  }
+  elseif (function_exists('curl_init')) {
+    $curl = @curl_init($url);
+    @curl_setopt($curl, CURLOPT_TRANSFERTEXT, TRUE);
+    @curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
+    @curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
+    $data = @curl_exec($curl);
+    @curl_close($curl);
+  }
+  elseif (function_exists('exec')) {
+    @exec("wget --quiet --timeout $timeout -O- $url", $output, $return_val);
+    if ($return_val == 0 and is_array($output)) {
+      $data = join("\n", $output);
+    }
+  }
+  return $data;
+}
Index: weather.tpl.php
===================================================================
--- weather.tpl.php	(revision 202)
+++ weather.tpl.php	(working copy)
@@ -50,6 +50,12 @@
     </small>
     <br />
   <?php endif ?>
+  <?php if (isset($weather['legal'])): ?>
+    <small>
+      <?php print $weather['legal']; ?>
+    </small>
+    <br />
+  <?php endif ?>  
   <?php if (isset($weather['reported_on'])): ?>
     <small>
       <?php print t('Reported on:'); ?><br />
