Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

162 lines
6.4KB

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