How to download programmatically a module? I need to programmatically download projects from drupal.org, and then eventually enable it with modules_enable. Anyone knows how to do it?

Here's the final solution :
I'm sharing the code i used for those who'll face the same problem. 

    /**
     * 
     * Function downloading the last version of the module in MY_MODULE_MODULE_DIRECTORY
     * $modulename correspond au nom system du module
     *
     * @param string $modulename
     */
    function MY_MODULE_download_module($modulename) {
      // DEBUT CODE TELECHARGEMENT

      $base_url = 'http://updates.drupal.org/release-history/' . $modulename . '/7.x';
      // @TODO MODULE NAME

      $xml = drupal_http_request($base_url);
      if (!isset($xml-&gt;error) &amp;&amp; isset($xml-&gt;data)) {
        $data = $xml-&gt;data;
      }
      try {
        $xml = new SimpleXMLElement($data);
      }
      catch (Exception $e) {
        // SimpleXMLElement::__construct produces an E_WARNING error message for
        // each error found in the XML data and throws an exception if errors
        // were detected. Catch any exception and return failure (NULL).
        return;
      }
      $json = json_encode($xml);
      $array = json_decode($json, TRUE);
      $download_link = $array['releases']['release'][0]['download_link'];

      $path = MY_MODULE_contrib_dowload($download_link);
      MY_MODULE_archive_extract($path, MY_MODULE_MODULE_DIRECTORY);

      // FIN CODE TELECHARGEMENT
    }

    /**
     * Fonction downloading a file
     * Inspired from update_manager_file_get($url).
     * Upload the file in the temporary folder
     *
     * @param url $url
     */
    function MY_MODULE_contrib_dowload($url) {
      $parsed_url = parse_url($url);
      $remote_schemes = array(
        'http',
        'https',
        'ftp',
        'ftps',
        'smb',
        'nfs'
      );
      if (!in_array($parsed_url['scheme'], $remote_schemes)) {
        // This is a local file, just return the path.
        return drupal_realpath($url);
      }

      $cache_directory = _update_manager_cache_directory();
      $local = $cache_directory . '/' . drupal_basename($parsed_url['path']);
      // load the file in the right directory

      return system_retrieve_file($url, $local, FALSE, FILE_EXISTS_REPLACE);
    }

    /**
     * Function inspired from update_manager_archive_extract($file, $directory)
     * extracts a file to a directory
     *
     * @param path_to_file $file
     * @param path_to_directory $directory
     * @throws Exception
     * @return A path
     */
    function MY_MODULE_archive_extract($file, $directory) {
      $archiver = archiver_get_archiver($file);
      if (!$archiver) {
        throw new Exception(t('Cannot extract %file, not a valid archive.', array(
          '%file' =&gt; $file
        )));
      }

      // Remove the directory if it exists, otherwise it might contain a mixture of
      // old files mixed with the new files (e.g. in cases where files were removed
      // from a later release).
      $files = $archiver-&gt;listContents();

      // Unfortunately, we can only use the directory name to determine the project
      // name. Some archivers list the first file as the directory (i.e., MODULE/)
      // and others list an actual file (i.e., MODULE/README.TXT).
      $project = strtok($files[0], '/\\');

      $extract_location = $directory . '/' . $project;
      if (file_exists($extract_location)) {
        file_unmanaged_delete_recursive($extract_location);
      }

      $archiver-&gt;extract($directory);
      return $archiver;
    }
Normally you want to use drush, e.g.

drush -y en module_name


which would download, install and enable your module of interest.

Check drush.api.php to use appropriate API hooks which could be useful.

If you don't want to use Drush, check how Update Manager does that in update/update.manager.inc, e.g.


update_manager_file_get
update_manager_archive_extract
etc.


To get the list of available files to download for specific project you've to fetch and parse the release history which is available at:

https://updates.drupal.org/release-history/project_name/7.x


the same as drush does that (check by drush -vd dl foo) and get the links from there.