downloads.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. # YOLOv5 🚀 by Ultralytics, GPL-3.0 license
  2. """
  3. Download utils
  4. """
  5. import os
  6. import platform
  7. import subprocess
  8. import time
  9. import urllib
  10. from pathlib import Path
  11. from zipfile import ZipFile
  12. import requests
  13. import torch
  14. def gsutil_getsize(url=''):
  15. # gs://bucket/file size https://cloud.google.com/storage/docs/gsutil/commands/du
  16. s = subprocess.check_output(f'gsutil du {url}', shell=True).decode('utf-8')
  17. return eval(s.split(' ')[0]) if len(s) else 0 # bytes
  18. def safe_download(file, url, url2=None, min_bytes=1E0, error_msg=''):
  19. # Attempts to download file from url or url2, checks and removes incomplete downloads < min_bytes
  20. file = Path(file)
  21. assert_msg = f"Downloaded file '{file}' does not exist or size is < min_bytes={min_bytes}"
  22. try: # url1
  23. print(f'Downloading {url} to {file}...')
  24. torch.hub.download_url_to_file(url, str(file))
  25. assert file.exists() and file.stat().st_size > min_bytes, assert_msg # check
  26. except Exception as e: # url2
  27. file.unlink(missing_ok=True) # remove partial downloads
  28. print(f'ERROR: {e}\nRe-attempting {url2 or url} to {file}...')
  29. os.system(f"curl -L '{url2 or url}' -o '{file}' --retry 3 -C -") # curl download, retry and resume on fail
  30. finally:
  31. if not file.exists() or file.stat().st_size < min_bytes: # check
  32. file.unlink(missing_ok=True) # remove partial downloads
  33. print(f"ERROR: {assert_msg}\n{error_msg}")
  34. print('')
  35. def attempt_download(file, repo='ultralytics/yolov5'): # 检查模型文件是否存在,如果不存在就重新下载。 # from utils.downloads import *; attempt_download()
  36. # Attempt file download if does not exist
  37. file = Path(str(file).strip().replace("'", ''))
  38. if not file.exists():
  39. # URL specified
  40. name = Path(urllib.parse.unquote(str(file))).name # decode '%2F' to '/' etc.
  41. if str(file).startswith(('http:/', 'https:/')): # download
  42. url = str(file).replace(':/', '://') # Pathlib turns :// -> :/
  43. file = name.split('?')[0] # parse authentication https://url.com/file.txt?auth...
  44. if Path(file).is_file():
  45. print(f'Found {url} locally at {file}') # file already exists
  46. else:
  47. safe_download(file=file, url=url, min_bytes=1E5)
  48. return file
  49. # GitHub assets
  50. file.parent.mkdir(parents=True, exist_ok=True) # make parent dir (if required)
  51. try:
  52. response = requests.get(f'https://api.github.com/repos/{repo}/releases/latest').json() # github api
  53. assets = [x['name'] for x in response['assets']] # release assets, i.e. ['yolov5s.pt', 'yolov5m.pt', ...]
  54. tag = response['tag_name'] # i.e. 'v1.0'
  55. except Exception: # fallback plan
  56. assets = [
  57. 'yolov5n.pt', 'yolov5s.pt', 'yolov5m.pt', 'yolov5l.pt', 'yolov5x.pt', 'yolov5n6.pt', 'yolov5s6.pt',
  58. 'yolov5m6.pt', 'yolov5l6.pt', 'yolov5x6.pt']
  59. try:
  60. tag = subprocess.check_output('git tag', shell=True, stderr=subprocess.STDOUT).decode().split()[-1]
  61. except Exception:
  62. tag = 'v6.1' # current release
  63. if name in assets:
  64. url3 = 'https://drive.google.com/drive/folders/1EFQTEUeXWSFww0luse2jB9M1QNZQGwNl' # backup gdrive mirror
  65. safe_download(
  66. file,
  67. url=f'https://github.com/{repo}/releases/download/{tag}/{name}',
  68. url2=f'https://storage.googleapis.com/{repo}/{tag}/{name}', # backup url (optional)
  69. min_bytes=1E5,
  70. error_msg=f'{file} missing, try downloading from https://github.com/{repo}/releases/{tag} or {url3}')
  71. return str(file)
  72. def gdrive_download(id='16TiPfZj7htmTyhntwcZyEEAejOUxuT6m', file='tmp.zip'):
  73. # Downloads a file from Google Drive. from yolov5.utils.downloads import *; gdrive_download()
  74. t = time.time()
  75. file = Path(file)
  76. cookie = Path('cookie') # gdrive cookie
  77. print(f'Downloading https://drive.google.com/uc?export=download&id={id} as {file}... ', end='')
  78. file.unlink(missing_ok=True) # remove existing file
  79. cookie.unlink(missing_ok=True) # remove existing cookie
  80. # Attempt file download
  81. out = "NUL" if platform.system() == "Windows" else "/dev/null"
  82. os.system(f'curl -c ./cookie -s -L "drive.google.com/uc?export=download&id={id}" > {out}')
  83. if os.path.exists('cookie'): # large file
  84. s = f'curl -Lb ./cookie "drive.google.com/uc?export=download&confirm={get_token()}&id={id}" -o {file}'
  85. else: # small file
  86. s = f'curl -s -L -o {file} "drive.google.com/uc?export=download&id={id}"'
  87. r = os.system(s) # execute, capture return
  88. cookie.unlink(missing_ok=True) # remove existing cookie
  89. # Error check
  90. if r != 0:
  91. file.unlink(missing_ok=True) # remove partial
  92. print('Download error ') # raise Exception('Download error')
  93. return r
  94. # Unzip if archive
  95. if file.suffix == '.zip':
  96. print('unzipping... ', end='')
  97. ZipFile(file).extractall(path=file.parent) # unzip
  98. file.unlink() # remove zip
  99. print(f'Done ({time.time() - t:.1f}s)')
  100. return r
  101. def get_token(cookie="./cookie"):
  102. with open(cookie) as f:
  103. for line in f:
  104. if "download" in line:
  105. return line.split()[-1]
  106. return ""
  107. # Google utils: https://cloud.google.com/storage/docs/reference/libraries ----------------------------------------------
  108. #
  109. #
  110. # def upload_blob(bucket_name, source_file_name, destination_blob_name):
  111. # # Uploads a file to a bucket
  112. # # https://cloud.google.com/storage/docs/uploading-objects#storage-upload-object-python
  113. #
  114. # storage_client = storage.Client()
  115. # bucket = storage_client.get_bucket(bucket_name)
  116. # blob = bucket.blob(destination_blob_name)
  117. #
  118. # blob.upload_from_filename(source_file_name)
  119. #
  120. # print('File {} uploaded to {}.'.format(
  121. # source_file_name,
  122. # destination_blob_name))
  123. #
  124. #
  125. # def download_blob(bucket_name, source_blob_name, destination_file_name):
  126. # # Uploads a blob from a bucket
  127. # storage_client = storage.Client()
  128. # bucket = storage_client.get_bucket(bucket_name)
  129. # blob = bucket.blob(source_blob_name)
  130. #
  131. # blob.download_to_filename(destination_file_name)
  132. #
  133. # print('Blob {} downloaded to {}.'.format(
  134. # source_blob_name,
  135. # destination_file_name))