Index: update_status.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/update_status/update_status.module,v retrieving revision 1.83.2.45 diff -u -p -r1.83.2.45 update_status.module --- update_status.module 4 Jun 2009 22:38:39 -0000 1.83.2.45 +++ update_status.module 10 Jun 2009 00:32:46 -0000 @@ -44,6 +44,16 @@ define('UPDATE_STATUS_NOT_CHECKED', -1); */ define('UPDATE_STATUS_UNKNOWN', -2); +/** + * There was a failure fetching available update data for this project. + */ +define('UPDATE_STATUS_NOT_FETCHED', -3); + +/** + * Maximum number of attempts to fetch available update data from a given host. + */ +define('UPDATE_STATUS_MAX_FETCH_ATTEMPTS', 2); + /** * Implementation of hook_help(). @@ -432,6 +442,7 @@ function _update_status_requirement_chec break; case UPDATE_STATUS_UNKNOWN: case UPDATE_STATUS_NOT_CHECKED: + case UPDATE_STATUS_NOT_FETCHED: $requirement_label = isset($project['reason']) ? $project['reason'] : t('Can not determine status'); $requirement['severity'] = REQUIREMENT_WARNING; break; @@ -573,6 +584,7 @@ function _update_status_message_text($ms case UPDATE_STATUS_UNKNOWN: case UPDATE_STATUS_NOT_CHECKED: + case UPDATE_STATUS_NOT_FETCHED: if ($msg_type == 'core') { $text = t('There was a problem determining the status of available updates for your version of Drupal.'); } @@ -594,7 +606,7 @@ function _update_status_message_text($ms */ function update_status_manual_status() { if (update_status_refresh()) { - drupal_set_message(t('Fetched information about all available new releases and updates.')); + drupal_set_message(t('Attempted to fetch information about all available new releases and updates.')); } else { drupal_set_message(t('Unable to fetch any information on available new releases and updates.'), 'error'); @@ -923,6 +935,11 @@ function update_status_calculate_project 'data' => t('This project is no longer supported, and is no longer available for download. Disabling everything included by this project is strongly recommended!'), ); break; + case 'not-fetched': + $projects[$project]['status'] = UPDATE_STATUS_NOT_FETCHED; + $projects[$project]['reason'] = t('Failed to fetch available update data'); + break; + default: // Assume anything else (e.g. 'published') is valid and we should // perform the rest of the logic in this function. @@ -1247,6 +1264,7 @@ function theme_update_status_report($dat break; case UPDATE_STATUS_UNKNOWN: + case UPDATE_STATUS_NOT_FETCHED: $class = 'unknown'; $icon = theme('image', 'misc/watchdog-warning.png', t('unknown'), t('unknown')); break; @@ -1413,6 +1431,7 @@ function theme_update_status_version($ve */ function update_status_refresh() { global $base_url; + static $fail = array(); // Since we're fetching new available update data, we want to clear // our cache of both the projects we care about, and the current update @@ -1438,24 +1457,44 @@ function update_status_refresh() { // to clear out the stale data at this point. _update_status_cache_clear('update_status_available_releases'); + $max_fetch_attempts = variable_get('update_status_max_fetch_attempts', UPDATE_STATUS_MAX_FETCH_ATTEMPTS); + foreach ($projects as $key => $project) { $url = _update_status_build_fetch_url($project, $site_key); - $xml = drupal_http_request($url); - if (isset($xml->data)) { - $data[] = $xml->data; + $fetch_url_base = _update_status_get_fetch_url_base($project); + if (empty($fail[$fetch_url_base]) || count($fail[$fetch_url_base]) < $max_fetch_attempts) { + $xml = drupal_http_request($url); + if (isset($xml->data)) { + $data[] = $xml->data; + } + else { + // Connection likely broken; prepare to give up. + $fail[$fetch_url_base][$key] = 1; + } + } + else { + // Didn't bother trying to fetch. + $fail[$fetch_url_base][$key] = 1; } } if ($data) { $parser = new update_status_xml_parser; $available = $parser->parse($data); + // Record the projects where we failed to fetch data. + foreach ($fail as $fetch_url_base => $failures) { + foreach ($failures as $key => $value) { + $available[$key]['project_status'] = 'not-fetched'; + } + } _update_status_cache_set('update_status_available_releases', serialize($available), time() + (60 * 60 * 24)); - variable_set('update_status_last', time()); - watchdog('update_status', t('Fetched information about all available new releases and updates.'), WATCHDOG_NOTICE, l(t('view'), 'admin/logs/updates')); + watchdog('update_status', t('Attempted to fetch information about all available new releases and updates.'), WATCHDOG_NOTICE, l(t('view'), 'admin/logs/updates')); } else { watchdog('update_status', 'Unable to fetch any information on available new releases and updates.', WATCHDOG_ERROR, l(t('view'), 'admin/logs/updates')); } + // Whether this worked or not, we did just (try to) check for updates. + variable_set('update_status_last', time()); return $available; } @@ -1475,12 +1514,8 @@ function update_status_refresh() { * @see update_status_get_projects() */ function _update_status_build_fetch_url($project, $site_key = '') { - $default_url = variable_get('update_status_fetch_url', UPDATE_STATUS_DEFAULT_URL); - if (!isset($project['info']['project status url'])) { - $project['info']['project status url'] = $default_url; - } $name = $project['name']; - $url = $project['info']['project status url']; + $url = _update_status_get_fetch_url_base($project); $url .= '/'. $name .'/'. UPDATE_STATUS_CORE_VERSION; if (!empty($site_key)) { $url .= (strpos($url, '?') === TRUE) ? '&' : '?'; @@ -1495,6 +1530,22 @@ function _update_status_build_fetch_url( } /** + * Return the base of the URL to fetch available update data for a project. + * + * @param $project + * The array of project information from update_status_get_projects(). + * @return + * The base of the URL used for fetching available update data. This does + * not include the path elements to specify a particular project, version, + * site_key, etc. + * + * @see _update_status_build_fetch_url() + */ +function _update_status_get_fetch_url_base($project) { + return isset($project['info']['project status url']) ? $project['info']['project status url'] : variable_get('update_status_fetch_url', UPDATE_STATUS_DEFAULT_URL); +} + +/** * Internal helper to try to get the update information from the cache * if possible, and to refresh the cache when necessary. *