Avoid clobbering files when downloading tools.

This commit is contained in:
2Shirt 2021-04-20 21:14:31 -06:00
parent cb825e37ba
commit b44fda2ccd
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C

View file

@ -24,19 +24,30 @@ CACHED_DIRS = {}
# Functions # Functions
def download_file(out_path, source_url): def download_file(out_path, source_url, as_new=False, overwrite=False):
"""Download a file using requests.""" """Download a file using requests, returns pathlib.Path."""
out_path = pathlib.Path(out_path).resolve() out_path = pathlib.Path(out_path).resolve()
# Avoid clobbering
if out_path.exists() and not overwrite:
raise FileExistsError(f'Refusing to clobber {out_path}')
# Create destination directory
out_path.parent.mkdir(parents=True, exist_ok=True) out_path.parent.mkdir(parents=True, exist_ok=True)
if as_new:
out_path = out_path.with_suffix(f'{out_path.suffix}.new')
# Request download # Request download
response = requests.get(source_url, stream=True) response = requests.get(source_url, stream=True)
if not response.ok: if not response.ok:
name = out_path.name
if as_new:
name = name[:-4]
LOG.error( LOG.error(
'Failed to download file (status %s): %s', 'Failed to download file (status %s): %s',
response.status_code, out_path.name, response.status_code, name,
) )
raise GenericError(f'Failed to download file: {out_path.name}') raise GenericError(f'Failed to download file: {name}')
# Write to file # Write to file
with open(out_path, 'wb') as _f: with open(out_path, 'wb') as _f:
@ -113,6 +124,18 @@ def run_tool(
proc will be either subprocess.CompletedProcess or subprocess.Popen.""" proc will be either subprocess.CompletedProcess or subprocess.Popen."""
proc = None proc = None
def _is_outdated(file_path):
"""Check if the ctime is older than the threshold, returns bool."""
outdated = False
try:
ctime = datetime.fromtimestamp(file_path.stat().st_ctime)
outdated = datetime.now() - ctime > timedelta(days=DOWNLOAD_FREQUENCY)
except FileNotFoundError:
LOG.error("This shouldn't happen right?")
# Done
return outdated
# Extract from .cbin # Extract from .cbin
if cbin: if cbin:
extract_archive( extract_archive(
@ -124,17 +147,16 @@ def run_tool(
# Download tool # Download tool
if download: if download:
out_path = find_kit_dir('.bin').joinpath(f'{folder}/{name}.exe') out_path = find_kit_dir('.bin').joinpath(f'{folder}/{name}.exe')
outdated = False if not out_path.exists() or _is_outdated(out_path):
try:
mod_time = datetime.fromtimestamp(out_path.stat().st_ctime)
outdated = datetime.now() - mod_time > timedelta(days=DOWNLOAD_FREQUENCY)
except FileNotFoundError:
# Ignore and download
pass
if not out_path.exists() or outdated:
LOG.info('Downloading tool: %s', name) LOG.info('Downloading tool: %s', name)
source_url = SOURCES[name] source_url = SOURCES[name]
download_file(out_path, source_url) try:
new_file = download_file(out_path, source_url, as_new=True)
new_file.replace(out_path)
except GenericError:
# Ignore as long as there's still a version present
if not out_path.exists():
raise
else: else:
LOG.info('Skip downloading tool: %s', name) LOG.info('Skip downloading tool: %s', name)