#!/usr/bin/env python
"""
This script/module contains routines that are used to analyze data and files that
contain them.
"""
##################### IMPORT STANDARD MODULES ######################################
# python 3 compatibility
from __future__ import absolute_import, division, print_function
import os
import requests
import platform
from datetime import datetime
import calendar
import warnings
####################### IMPORT AVNI LIBRARIES #######################################
from .. import constants
from .. import tools
#######################################################################################
[docs]def creation_date(path_to_file: str):
"""Try to get the date that a file was created, falling back to when it was
last modified if that isn't possible.
Parameters
----------
path_to_file : str
full path to a file
Returns
-------
datetime
datetime stamp in UTC as AVNI server stores datetime in UTC
:Authors:
Raj Moulik (moulik@caa.columbia.edu)
:Last Modified:
2020.01.06 11.00
"""
if platform.system() == 'Windows':
return datetime.utcfromtimestamp(os.path.getctime(path_to_file))
else:
stat = os.stat(path_to_file)
# We're probably on Linux. No easy way to get creation dates here,
# so we'll settle for when its content was last modified.
return datetime.utcfromtimestamp(stat.st_mtime)
[docs]def update_file(file,folder = None, baseurl = None, subdirectory = None):
"""If the AVNI server contain a downloadable resource that is newer, download it locally.
Parameters
----------
file : str
full path and name of the file to sync with AVNI servers
folder : str
folder where local files are store, by default as output from tools.get_filedir()
baseurl: str
public URL from where the public downloads can take place, by default as specified as `downloadpage` in `constants.py`
subdirectory: str
subdirectory inside the baseurl where the file should be synced
:Authors:
Raj Moulik (moulik@caa.columbia.edu)
:Last Modified:
2023.01.06 11.00
"""
# Get the correct default paths
if folder is None: folder = tools.get_filedir()
if baseurl is None: baseurl = constants.downloadpage
if subdirectory is not None: baseurl = baseurl+'/'+subdirectory
# Figure out internal-external path links
localfile = os.path.join(folder,file)
url = os.path.join(baseurl,file)
# Perform http request
h = requests.head(url, allow_redirects=True)
download=False
success = False
if h.status_code == 404:
warnings.warn("Warning: File not found with status code ("+str(h.status_code)+") while querying "+url)
elif h.status_code == 200:
header = h.headers
# Check when the file was modified
lmd = header.get('Last-Modified')
server_data = datetime.strptime(lmd, '%a, %d %b %Y %H:%M:%S %Z')
# Check if a local file already exists
if os.path.isfile(localfile):
local_data = creation_date(localfile)
# Download if server has newer file
if (server_data-local_data).total_seconds() > 0:
download = True
else:
success = True
else:
download = True
else:
warnings.warn("Warning: Unknown status code ("+str(h.status_code)+") while querying "+file)
# download if needed
if download:
print(".... Downloading "+file+" from AVNI server to "+localfile)
r = requests.get(url, allow_redirects=True)
open(localfile, 'wb').write(r.content)
# calendar assumes tuple in UTC
utime = calendar.timegm(server_data.timetuple())
# set the time to server time but taking UTC into account above
os.utime(localfile, (utime, utime))
print(".... Download completed.")
success = True
return localfile,success