Home | History | Annotate | Download | only in CygwinDownloader
      1 #!/usr/bin/env python
      2 
      3 import os, random, sys, time, urllib
      4 
      5 #
      6 # Options
      7 #
      8 
      9 dry_run = len(sys.argv) > 1 and "--dry-run" in set(sys.argv[1:])
     10 quiet = len(sys.argv) > 1 and "--quiet" in set(sys.argv[1:])
     11 
     12 #
     13 # Functions and constants
     14 #
     15 
     16 def download_progress_hook(block_count, block_size, total_blocks):
     17         if quiet or random.random() > 0.5:
     18                 return
     19         sys.stdout.write(".")
     20         sys.stdout.flush()
     21 
     22 def download_url_to_file(url, file, message):
     23         if not quiet:
     24                 print message + " ",
     25         if not dry_run:
     26                 dir = os.path.dirname(file)
     27                 if len(dir) and not os.path.exists(dir):
     28                     os.makedirs(dir)
     29                 urllib.urlretrieve(url, file, download_progress_hook)
     30         if not quiet:
     31                 print
     32  
     33 # This is mostly just the list of North America http mirrors from http://cygwin.com/mirrors.html,
     34 # but a few have been removed that seemed unresponsive from Cupertino.
     35 mirror_servers = ["http://cygwin.elite-systems.org/",
     36                   "http://mirror.mcs.anl.gov/cygwin/",
     37                   "http://cygwin.osuosl.org/",
     38                   "http://mirrors.kernel.org/sourceware/cygwin/",
     39                   "http://mirrors.xmission.com/cygwin/",
     40                   "http://sourceware.mirrors.tds.net/pub/sourceware.org/cygwin/"]
     41 
     42 package_mirror_url = mirror_servers[random.choice(range(len(mirror_servers)))]
     43 
     44 def download_package(package, message):
     45         download_url_to_file(package_mirror_url + package["path"], package["path"], message)
     46 
     47 required_packages = frozenset(["apache",
     48                                "bc",
     49                                "bison",
     50                                "curl",
     51                                "diffutils",
     52                                "e2fsprogs",
     53                                "emacs",
     54                                "flex",
     55                                "gcc",
     56                                "gperf",
     57                                "keychain",
     58                                "make",
     59                                "nano",
     60                                "openssh",
     61                                "patch",
     62                                "perl",
     63                                "perl-libwin32",
     64                                "python",
     65                                "rebase",
     66                                "rsync",
     67                                "ruby",
     68                                "subversion",
     69                                "unzip",
     70                                "vim",
     71                                "zip"])
     72 
     73 #
     74 # Main
     75 #
     76 
     77 print "Using Cygwin mirror server " + package_mirror_url + " to download setup.ini..."
     78 
     79 urllib.urlretrieve(package_mirror_url + "setup.ini", "setup.ini.orig")
     80 
     81 downloaded_packages_file_path = "setup.ini.orig"
     82 downloaded_packages_file = file(downloaded_packages_file_path, "r")
     83 if not dry_run:
     84     modified_packages_file = file("setup.ini", "w")
     85 
     86 packages = {}
     87 current_package = ''
     88 for line in downloaded_packages_file.readlines():
     89         if line[0] == "@":
     90                 current_package = line[2:-1]
     91                 packages[current_package] = {"name": current_package, "needs_download": False, "requires": [], "path": ""}
     92         elif line[:10] == "category: ":
     93                 if current_package in required_packages:
     94                         line = "category: Base\n"
     95                 if "Base" in set(line[10:-1].split()):
     96                         packages[current_package]["needs_download"] = True
     97         elif line[:10] == "requires: ":
     98                 packages[current_package]["requires"] = line[10:].split()
     99                 packages[current_package]["requires"].sort()
    100         elif line[:9] == "install: " and not len(packages[current_package]["path"]):
    101                 end_of_path = line.find(" ", 9)
    102                 if end_of_path != -1:
    103                         packages[current_package]["path"] = line[9:end_of_path]
    104         if not dry_run:
    105             modified_packages_file.write(line)
    106 
    107 downloaded_packages_file.close()
    108 os.remove(downloaded_packages_file_path)
    109 if not dry_run:
    110     modified_packages_file.close()
    111 
    112 names_to_download = set()
    113 package_names = packages.keys()
    114 package_names.sort()
    115 
    116 def add_package_and_dependencies(name):
    117         if name in names_to_download:
    118                 return
    119         if not name in packages:
    120                 return
    121         packages[name]["needs_download"] = True
    122         names_to_download.add(name)
    123         for dep in packages[name]["requires"]:
    124                 add_package_and_dependencies(dep)
    125 
    126 for name in package_names:
    127         if packages[name]["needs_download"]:
    128                 add_package_and_dependencies(name)
    129 
    130 downloaded_so_far = 0
    131 for name in package_names:
    132         if packages[name]["needs_download"]:
    133                 downloaded_so_far += 1
    134                 download_package(packages[name], "Downloading package %3d of %3d (%s)" % (downloaded_so_far, len(names_to_download), name))
    135 
    136 download_url_to_file("http://cygwin.com/setup.exe", "setup.exe", "Downloading setup.exe")
    137 
    138 seconds_to_sleep = 10
    139 
    140 print """
    141 Finished downloading Cygwin. In %d seconds,
    142 I will run setup.exe. Select the "Install
    143 from Local Directory" option and browse to
    144 "%s"
    145 when asked for the "Local Package Directory".
    146 """ % (seconds_to_sleep, os.getcwd())
    147 
    148 
    149 while seconds_to_sleep > 0:
    150         print "%d..." % seconds_to_sleep,
    151         sys.stdout.flush()
    152         time.sleep(1)
    153         seconds_to_sleep -= 1
    154 print
    155 
    156 if not dry_run:
    157         os.execl("setup.exe")
    158