1import os 2import stat 3import logging 4 5download_dir = "prebuilt_downloads" 6 7def download_sha1_unzip(url, checksum, save_to_directory, unzip=True): 8 """ This 9 - downloads a url, 10 - sha1 checksum check, 11 - save_to_directory, 12 - then unzips it. 13 14 Does not download again if the file is there. 15 Does not unzip again if the file is there. 16 """ 17 # requests does connection retrying, but people might not have it installed. 18 use_requests = True 19 20 try: 21 import requests 22 except ImportError: 23 use_requests = False 24 25 try: 26 import urllib.request as urllib 27 except ImportError: 28 import urllib2 as urllib 29 import hashlib 30 import zipfile 31 32 filename = os.path.split(url)[-1] 33 save_to = os.path.join(save_to_directory, filename) 34 35 # skip download? 36 skip_download = os.path.exists(save_to) 37 if skip_download: 38 with open(save_to, 'rb') as the_file: 39 data = the_file.read() 40 cont_checksum = hashlib.sha1(data).hexdigest() 41 if cont_checksum == checksum: 42 print("Skipping download url:%s: save_to:%s:" % (url, save_to)) 43 else: 44 print("Downloading...", url, checksum) 45 46 if use_requests: 47 response = requests.get(url) 48 cont_checksum = hashlib.sha1(response.content).hexdigest() 49 else: 50 51 headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, ' 52 'like Gecko) Chrome/35.0.1916.47 Safari/537.36'} 53 request = urllib.Request(url, headers=headers) 54 response = urllib.urlopen(request).read() 55 cont_checksum = hashlib.sha1(response).hexdigest() 56 57 if checksum != cont_checksum: 58 raise ValueError( 59 'url:%s should have checksum:%s: Has:%s: ' % (url, checksum, cont_checksum) 60 ) 61 with open(save_to, 'wb') as f: 62 if use_requests: 63 f.write(response.content) 64 else: 65 f.write(response) 66 67 if unzip and filename.endswith('.zip'): 68 print("Unzipping :%s:" % save_to) 69 with zipfile.ZipFile(save_to, 'r') as zip_ref: 70 zip_dir = os.path.join( 71 save_to_directory, 72 filename.replace('.zip', '') 73 ) 74 if os.path.exists(zip_dir): 75 print("Skipping unzip to zip_dir exists:%s:" % zip_dir) 76 else: 77 os.mkdir(zip_dir) 78 zip_ref.extractall(zip_dir) 79 80def get_urls(x86=True, x64=True): 81 url_sha1 = [] 82 url_sha1.extend([ 83 [ 84 'https://www.libsdl.org/release/SDL2-devel-2.0.16-VC.zip', 85 '13d952c333f3c2ebe9b7bc0075b4ad2f784e7584', 86 ], 87 [ 88 'https://www.libsdl.org/projects/SDL_image/release/SDL2_image-devel-2.0.5-VC.zip', 89 '137f86474691f4e12e76e07d58d5920c8d844d5b', 90 ], 91 [ 92 'https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-devel-2.0.15-VC.zip', 93 '1436df41ebc47ac36e02ec9bda5699e80ff9bd27', 94 ], 95 [ 96 'https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-devel-2.0.4-VC.zip', 97 '9097148f4529cf19f805ccd007618dec280f0ecc', 98 ], 99 [ 100 # 'https://www.ijg.org/files/jpegsr9d.zip', 101 'https://www.pygame.org/ftp/jpegsr9d.zip', 102 'ed10aa2b5a0fcfe74f8a6f7611aeb346b06a1f99', 103 ], 104 ]) 105 if x86: 106 url_sha1.append([ 107 'https://pygame.org/ftp/prebuilt-x86-pygame-1.9.2-20150922.zip', 108 'dbce1d5ea27b3da17273e047826d172e1c34b478' 109 ]) 110 if x64: 111 url_sha1.append([ 112 'https://pygame.org/ftp/prebuilt-x64-pygame-1.9.2-20150922.zip', 113 '3a5af3427b3aa13a0aaf5c4cb08daaed341613ed' 114 ]) 115 return url_sha1 116 117def download_prebuilts(temp_dir, x86=True, x64=True): 118 """ For downloading prebuilt dependencies. 119 """ 120 if not os.path.exists(temp_dir): 121 print("Making dir :%s:" % temp_dir) 122 os.makedirs(temp_dir) 123 for url, checksum in get_urls(x86=x86, x64=x64): 124 download_sha1_unzip(url, checksum, temp_dir, 1) 125 126def create_ignore_target_fnc(x64=False, x86=False): 127 if not x64 and not x86: 128 return None 129 strs = [] 130 if x64: 131 strs.append('x64') 132 if x86: 133 strs.append('x86') 134 def ignore_func(dir, contents): 135 for target in strs: 136 if target in dir: 137 return contents 138 return [] 139 return ignore_func 140 141import shutil 142 143def copytree(src, dst, symlinks=False, ignore=None): 144 """like shutil.copytree() but ignores existing files 145 https://stackoverflow.com/a/22331852/1239986 146 """ 147 if not os.path.exists(dst): 148 os.makedirs(dst) 149 shutil.copystat(src, dst) 150 lst = os.listdir(src) 151 if ignore: 152 excl = ignore(src, lst) 153 lst = [x for x in lst if x not in excl] 154 for item in lst: 155 s = os.path.join(src, item) 156 d = os.path.join(dst, item) 157 if symlinks and os.path.islink(s): 158 if os.path.lexists(d): 159 os.remove(d) 160 os.symlink(os.readlink(s), d) 161 try: 162 st = os.lstat(s) 163 mode = stat.S_IMODE(st.st_mode) 164 os.lchmod(d, mode) 165 except OSError: 166 pass # lchmod not available 167 elif os.path.isdir(s): 168 copytree(s, d, symlinks, ignore) 169 else: 170 shutil.copy2(s, d) 171 172def place_downloaded_prebuilts(temp_dir, move_to_dir, x86=True, x64=True): 173 """ puts the downloaded prebuilt files into the right place. 174 175 Leaves the files in temp_dir. copies to move_to_dir 176 """ 177 prebuilt_x64 = os.path.join( 178 temp_dir, 179 'prebuilt-x64-pygame-1.9.2-20150922', 180 'prebuilt-x64' 181 ) 182 prebuilt_x86 = os.path.join( 183 temp_dir, 184 'prebuilt-x86-pygame-1.9.2-20150922', 185 'prebuilt-x86' 186 ) 187 188 ignore = None 189 def copy(src, dst): 190 copytree(src, dst, ignore=ignore) 191 192 if x64: 193 copy(prebuilt_x64, os.path.join(move_to_dir, 'prebuilt-x64')) 194 if x86: 195 copy(prebuilt_x86, os.path.join(move_to_dir, 'prebuilt-x86')) 196 197 ignore = create_ignore_target_fnc(x64=not x64, x86=not x86) 198 prebuilt_dirs = [] 199 if x86: 200 prebuilt_dirs.append('prebuilt-x86') 201 if x64: 202 prebuilt_dirs.append('prebuilt-x64') 203 204 205 for prebuilt_dir in prebuilt_dirs: 206 path = os.path.join(move_to_dir, prebuilt_dir) 207 print("copying into %s" % path) 208 209 # update jpeg 210 for file in ('jerror.h', 'jmorecfg.h', 'jpeglib.h'): 211 shutil.copyfile( 212 os.path.join( 213 temp_dir, 214 'jpegsr9d', 215 'jpeg-9d', 216 file 217 ), 218 os.path.join( 219 move_to_dir, 220 prebuilt_dir, 221 'include', 222 file 223 ) 224 ) 225 226 copy( 227 os.path.join( 228 temp_dir, 229 'SDL2_image-devel-2.0.5-VC/SDL2_image-2.0.5' 230 ), 231 os.path.join( 232 move_to_dir, 233 prebuilt_dir, 234 'SDL2_image-2.0.5' 235 ) 236 ) 237 copy( 238 os.path.join( 239 temp_dir, 240 'SDL2_mixer-devel-2.0.4-VC/SDL2_mixer-2.0.4' 241 ), 242 os.path.join( 243 move_to_dir, 244 prebuilt_dir, 245 'SDL2_mixer-2.0.4' 246 ) 247 ) 248 copy( 249 os.path.join( 250 temp_dir, 251 'SDL2_ttf-devel-2.0.15-VC/SDL2_ttf-2.0.15' 252 ), 253 os.path.join( 254 move_to_dir, 255 prebuilt_dir, 256 'SDL2_ttf-2.0.15' 257 ) 258 ) 259 copy( 260 os.path.join( 261 temp_dir, 262 'SDL2-devel-2.0.16-VC/SDL2-2.0.16' 263 ), 264 os.path.join( 265 move_to_dir, 266 prebuilt_dir, 267 'SDL2-2.0.16' 268 ) 269 ) 270 271def update(x86=True, x64=True): 272 move_to_dir = "." 273 download_prebuilts(download_dir, x86=x86, x64=x64) 274 place_downloaded_prebuilts(download_dir, move_to_dir, x86=x86, x64=x64) 275 276def ask(x86=True, x64=True): 277 move_to_dir = "." 278 if x64: 279 dest_str = "\"%s/prebuilt-x64\"" % move_to_dir 280 else: 281 dest_str = "" 282 if x86: 283 if dest_str: 284 dest_str = "%s and " % dest_str 285 dest_str = "%s\"%s/prebuilt-x86\"" % (dest_str, move_to_dir) 286 logging.info('Downloading prebuilts to "%s" and copying to %s.', (download_dir, dest_str)) 287 download_prebuilt = True 288 289 if download_prebuilt: 290 update(x86=x86, x64=x64) 291 return download_prebuilt 292 293def cached(x86=True, x64=True): 294 if not os.path.isdir(download_dir): 295 return False 296 for url, check in get_urls(x86=x86, x64=x64): 297 filename = os.path.split(url)[-1] 298 save_to = os.path.join(download_dir, filename) 299 if not os.path.exists(save_to): 300 return False 301 return True 302 303if __name__ == '__main__': 304 ask() 305