#!/usr/bin/env python
u"""
verify_box_tpxo.py
Written by <NAME> (10/2020)
Verifies downloaded TPXO9-atlas global tide models from the box file
    sharing service

CALLING SEQUENCE:
    python verify_box_tpxo.py --token <token> --tide TPXO9-atlas-v4
    where <username> is your box api access token

COMMAND LINE OPTIONS:
    --help: list the command line options
    --directory X: working data directory
    -t X, --token X: user access token for box API
    -F X, --folder X: box folder id for model
    --tide X: TPXO9-atlas model to verify
        TPXO9-atlas
        TPXO9-atlas-v2
        TPXO9-atlas-v3
        TPXO9-atlas-v4
    --currents: verify tide model current outputs
    -M X, --mode X: Local permissions mode of the files downloaded

PYTHON DEPENDENCIES:
    future: Compatibility layer between Python 2 and Python 3
        https://python-future.org/

UPDATE HISTORY:
    Written 03/2021
"""
from __future__ import print_function

import os
import re
import ssl
import json
import argparse
import posixpath
import pyTMD.utilities

#-- PURPOSE: create an opener for box with a supplied user access token
def build_opener(token, context=ssl.SSLContext(), redirect=True):
    """
    build urllib opener for box with supplied user access token

    Arguments
    ---------
    token: box user access token

    Keyword arguments
    -----------------
    context: SSL context for opener object
    redirect: create redirect handler object
    """
    #-- https://docs.python.org/3/howto/urllib2.html#id5
    handler = []
    #-- create cookie jar for storing cookies for session
    cookie_jar = pyTMD.utilities.CookieJar()
    handler.append(pyTMD.utilities.urllib2.HTTPCookieProcessor(cookie_jar))
    handler.append(pyTMD.utilities.urllib2.HTTPSHandler(context=context))
    #-- redirect handler
    if redirect:
        handler.append(pyTMD.utilities.urllib2.HTTPRedirectHandler())
    #-- create "opener" (OpenerDirector instance)
    opener = pyTMD.utilities.urllib2.build_opener(*handler)
    #-- add Authorization header to opener
    opener.addheaders = [("Authorization","Bearer {0}".format(token))]
    #-- Now all calls to urllib2.urlopen use our opener.
    pyTMD.utilities.urllib2.install_opener(opener)

#-- PURPOSE: verify downloaded TPXO9-atlas files with box server
def verify_box_tpxo(tide_dir, folder_id, TIDE_MODEL=None,
    CURRENTS=False, MODE=None):

    #-- check if local directory exists and recursively create if not
    if (TIDE_MODEL == 'TPXO9-atlas'):
        localpath = os.path.join(tide_dir,'TPXO9_atlas')
    elif (TIDE_MODEL == 'TPXO9-atlas-v2'):
        localpath = os.path.join(tide_dir,'TPXO9_atlas_v2')
    elif (TIDE_MODEL == 'TPXO9-atlas-v3'):
        localpath = os.path.join(tide_dir,'TPXO9_atlas_v3')
    elif (TIDE_MODEL == 'TPXO9-atlas-v4'):
        localpath = os.path.join(tide_dir,'TPXO9_atlas_v4')

    #-- create output directory if non-existent
    os.makedirs(localpath,MODE) if not os.path.exists(localpath) else None
    #-- regular expression pattern for files of interest
    regex_patterns = []
    regex_patterns.append('grid')
    regex_patterns.append('h')
    if CURRENTS:
        regex_patterns.append('u')
    rx = re.compile('^({0})'.format('|'.join(regex_patterns)), re.VERBOSE)

    #-- box api url
    HOST = posixpath.join('https://api.box.com','2.0')
    #-- get folder contents
    folder_url = posixpath.join(HOST,'folders',folder_id,'items')
    request = pyTMD.utilities.urllib2.Request(folder_url)
    response = pyTMD.utilities.urllib2.urlopen(request)
    folder_contents = json.loads(response.read())
    #-- find files of interest
    file_entries = [entry for entry in folder_contents['entries'] if
        (entry['type'] == 'file') and rx.match(entry['name'])]
    #-- for each file in the folder
    for entry in file_entries:
        #-- print remote path
        file_url = posixpath.join(HOST,'files',entry['id'])
        print('{0} -->'.format(file_url))
        #-- get last modified time for file
        request = pyTMD.utilities.urllib2.Request(file_url)
        response = pyTMD.utilities.urllib2.urlopen(request)
        file_contents = json.loads(response.read())
        modified_at = file_contents['modified_at']
        remote_mtime = pyTMD.utilities.get_unix_time(modified_at,
            format='%Y-%m-%dT%H:%M:%S%z')
        #-- print file information
        local = os.path.join(localpath,entry['name'])
        print('\t{0}'.format(local))
        #-- compare checksums to validate download
        sha1 = pyTMD.utilities.get_hash(local,algorithm='sha1')
        if sha1 != entry['sha1']:
            print('Remote checksum: {0}'.format(entry['sha1']))
            print('Local checksum: {0}' .format(sha1))
            raise Exception('Checksum verification failed')
        #-- keep remote modification time of file and local access time
        os.utime(local, (os.stat(local).st_atime, remote_mtime))
        #-- change the permissions mode of the local file
        os.chmod(local, MODE)

#-- Main program that calls verify_box_tpxo()
def main():
    #-- Read the system arguments listed after the program
    parser = argparse.ArgumentParser(
        description="""Verifies downloaded TPXO9-atlas global
            tide models from the box file sharing service
            """
    )
    #-- command line parameters
    #-- working data directory
    parser.add_argument('--directory','-D',
        type=lambda p: os.path.abspath(os.path.expanduser(p)),
        default=os.getcwd(),
        help='Working data directory')
    #-- box user access token
    parser.add_argument('--token','-t',
        type=str, default='',
        help='User access token for box API')
    #-- box folder id
    parser.add_argument('--folder','-F',
        type=str, default='',
        help='box folder id for model')
    #-- TPXO9-atlas tide models
    parser.add_argument('--tide','-T',
        type=str, default='TPXO9-atlas-v4',
        help='TPXO9-atlas tide model to verify')
    #-- download tidal currents
    parser.add_argument('--currents',
        default=False, action='store_true',
        help='Verify tide model current outputs')
    #-- permissions mode of the local directories and files (number in octal)
    parser.add_argument('--mode','-M',
        type=lambda x: int(x,base=8), default=0o775,
        help='Permission mode of directories and files downloaded')
    args = parser.parse_args()

    #-- build an opener for accessing box folders
    build_opener(args.token)
    #-- check internet connection before attempting to run program
    if pyTMD.utilities.check_connection('https://app.box.com/'):
        verify_box_tpxo(args.directory, args.folder, TIDE_MODEL=args.tide,
            CURRENTS=args.currents, MODE=args.mode)

#-- run main program
if __name__ == '__main__':
    main()

#!/usr/bin/env python
u"""
verify_box_tpxo.py
Written by <NAME> (10/2020)
Verifies downloaded TPXO9-atlas global tide models from the box file
    sharing service

CALLING SEQUENCE:
    python verify_box_tpxo.py --token <token> --tide TPXO9-atlas-v4
    where <username> is your box api access token

COMMAND LINE OPTIONS:
    --help: list the command line options
    --directory X: working data directory
    -t X, --token X: user access token for box API
    -F X, --folder X: box folder id for model
    --tide X: TPXO9-atlas model to verify
        TPXO9-atlas
        TPXO9-atlas-v2
        TPXO9-atlas-v3
        TPXO9-atlas-v4
    --currents: verify tide model current outputs
    -M X, --mode X: Local permissions mode of the files downloaded

PYTHON DEPENDENCIES:
    future: Compatibility layer between Python 2 and Python 3
        https://python-future.org/

UPDATE HISTORY:
    Written 03/2021
"""
from __future__ import print_function

import os
import re
import ssl
import json
import argparse
import posixpath
import pyTMD.utilities

#-- PURPOSE: create an opener for box with a supplied user access token
def build_opener(token, context=ssl.SSLContext(), redirect=True):
    """
    build urllib opener for box with supplied user access token

    Arguments
    ---------
    token: box user access token

    Keyword arguments
    -----------------
    context: SSL context for opener object
    redirect: create redirect handler object
    """
    #-- https://docs.python.org/3/howto/urllib2.html#id5
    handler = []
    #-- create cookie jar for storing cookies for session
    cookie_jar = pyTMD.utilities.CookieJar()
    handler.append(pyTMD.utilities.urllib2.HTTPCookieProcessor(cookie_jar))
    handler.append(pyTMD.utilities.urllib2.HTTPSHandler(context=context))
    #-- redirect handler
    if redirect:
        handler.append(pyTMD.utilities.urllib2.HTTPRedirectHandler())
    #-- create "opener" (OpenerDirector instance)
    opener = pyTMD.utilities.urllib2.build_opener(*handler)
    #-- add Authorization header to opener
    opener.addheaders = [("Authorization","Bearer {0}".format(token))]
    #-- Now all calls to urllib2.urlopen use our opener.
    pyTMD.utilities.urllib2.install_opener(opener)

#-- PURPOSE: verify downloaded TPXO9-atlas files with box server
def verify_box_tpxo(tide_dir, folder_id, TIDE_MODEL=None,
    CURRENTS=False, MODE=None):

    #-- check if local directory exists and recursively create if not
    if (TIDE_MODEL == 'TPXO9-atlas'):
        localpath = os.path.join(tide_dir,'TPXO9_atlas')
    elif (TIDE_MODEL == 'TPXO9-atlas-v2'):
        localpath = os.path.join(tide_dir,'TPXO9_atlas_v2')
    elif (TIDE_MODEL == 'TPXO9-atlas-v3'):
        localpath = os.path.join(tide_dir,'TPXO9_atlas_v3')
    elif (TIDE_MODEL == 'TPXO9-atlas-v4'):
        localpath = os.path.join(tide_dir,'TPXO9_atlas_v4')

    #-- create output directory if non-existent
    os.makedirs(localpath,MODE) if not os.path.exists(localpath) else None
    #-- regular expression pattern for files of interest
    regex_patterns = []
    regex_patterns.append('grid')
    regex_patterns.append('h')
    if CURRENTS:
        regex_patterns.append('u')
    rx = re.compile('^({0})'.format('|'.join(regex_patterns)), re.VERBOSE)

    #-- box api url
    HOST = posixpath.join('https://api.box.com','2.0')
    #-- get folder contents
    folder_url = posixpath.join(HOST,'folders',folder_id,'items')
    request = pyTMD.utilities.urllib2.Request(folder_url)
    response = pyTMD.utilities.urllib2.urlopen(request)
    folder_contents = json.loads(response.read())
    #-- find files of interest
    file_entries = [entry for entry in folder_contents['entries'] if
        (entry['type'] == 'file') and rx.match(entry['name'])]
    #-- for each file in the folder
    for entry in file_entries:
        #-- print remote path
        file_url = posixpath.join(HOST,'files',entry['id'])
        print('{0} -->'.format(file_url))
        #-- get last modified time for file
        request = pyTMD.utilities.urllib2.Request(file_url)
        response = pyTMD.utilities.urllib2.urlopen(request)
        file_contents = json.loads(response.read())
        modified_at = file_contents['modified_at']
        remote_mtime = pyTMD.utilities.get_unix_time(modified_at,
            format='%Y-%m-%dT%H:%M:%S%z')
        #-- print file information
        local = os.path.join(localpath,entry['name'])
        print('\t{0}'.format(local))
        #-- compare checksums to validate download
        sha1 = pyTMD.utilities.get_hash(local,algorithm='sha1')
        if sha1 != entry['sha1']:
            print('Remote checksum: {0}'.format(entry['sha1']))
            print('Local checksum: {0}' .format(sha1))
            raise Exception('Checksum verification failed')
        #-- keep remote modification time of file and local access time
        os.utime(local, (os.stat(local).st_atime, remote_mtime))
        #-- change the permissions mode of the local file
        os.chmod(local, MODE)

#-- Main program that calls verify_box_tpxo()
def main():
    #-- Read the system arguments listed after the program
    parser = argparse.ArgumentParser(
        description="""Verifies downloaded TPXO9-atlas global
            tide models from the box file sharing service
            """
    )
    #-- command line parameters
    #-- working data directory
    parser.add_argument('--directory','-D',
        type=lambda p: os.path.abspath(os.path.expanduser(p)),
        default=os.getcwd(),
        help='Working data directory')
    #-- box user access token
    parser.add_argument('--token','-t',
        type=str, default='',
        help='User access token for box API')
    #-- box folder id
    parser.add_argument('--folder','-F',
        type=str, default='',
        help='box folder id for model')
    #-- TPXO9-atlas tide models
    parser.add_argument('--tide','-T',
        type=str, default='TPXO9-atlas-v4',
        help='TPXO9-atlas tide model to verify')
    #-- download tidal currents
    parser.add_argument('--currents',
        default=False, action='store_true',
        help='Verify tide model current outputs')
    #-- permissions mode of the local directories and files (number in octal)
    parser.add_argument('--mode','-M',
        type=lambda x: int(x,base=8), default=0o775,
        help='Permission mode of directories and files downloaded')
    args = parser.parse_args()

    #-- build an opener for accessing box folders
    build_opener(args.token)
    #-- check internet connection before attempting to run program
    if pyTMD.utilities.check_connection('https://app.box.com/'):
        verify_box_tpxo(args.directory, args.folder, TIDE_MODEL=args.tide,
            CURRENTS=args.currents, MODE=args.mode)

#-- run main program
if __name__ == '__main__':
    main()

#!/usr/bin/env python verify_box_tpxo.py Written by <NAME> (10/2020) Verifies downloaded TPXO9-atlas global tide models from the box file     sharing service  CALLING SEQUENCE:     python verify_box_tpxo.py --token <token> --tide TPXO9-atlas-v4     where <username> is your box api access token  COMMAND LINE OPTIONS:     --help: list the command line options     --directory X: working data directory     -t X, --token X: user access token for box API     -F X, --folder X: box folder id for model     --tide X: TPXO9-atlas model to verify         TPXO9-atlas         TPXO9-atlas-v2         TPXO9-atlas-v3         TPXO9-atlas-v4     --currents: verify tide model current outputs     -M X, --mode X: Local permissions mode of the files downloaded  PYTHON DEPENDENCIES:     future: Compatibility layer between Python 2 and Python 3         https://python-future.org/  UPDATE HISTORY:     Written 03/2021 #-- PURPOSE: create an opener for box with a supplied user access token build urllib opener for box with supplied user access token      Arguments     ---------     token: box user access token      Keyword arguments     -----------------     context: SSL context for opener object     redirect: create redirect handler object #-- https://docs.python.org/3/howto/urllib2.html#id5 #-- create cookie jar for storing cookies for session #-- redirect handler #-- create "opener" (OpenerDirector instance) #-- add Authorization header to opener #-- Now all calls to urllib2.urlopen use our opener. #-- PURPOSE: verify downloaded TPXO9-atlas files with box server #-- check if local directory exists and recursively create if not #-- create output directory if non-existent #-- regular expression pattern for files of interest #-- box api url #-- get folder contents #-- find files of interest #-- for each file in the folder #-- print remote path #-- get last modified time for file #-- print file information #-- compare checksums to validate download #-- keep remote modification time of file and local access time #-- change the permissions mode of the local file #-- Main program that calls verify_box_tpxo() #-- Read the system arguments listed after the program Verifies downloaded TPXO9-atlas global             tide models from the box file sharing service #-- command line parameters #-- working data directory #-- box user access token #-- box folder id #-- TPXO9-atlas tide models #-- download tidal currents #-- permissions mode of the local directories and files (number in octal) #-- build an opener for accessing box folders #-- check internet connection before attempting to run program #-- run main program