def main(args):
    assert (args.cover or args.granules or args.scenes), 'Either --cover OR --granules OR --scenes is mandatory'
    assert (not (args.download and (not args.out))), '--download implies out parameter'
    assert args.limit, 'What about increasing --limit value ?'
    config = load_config(args.config)
    if args.cover:
        args.pg = (args.pg if args.pg else config['auth']['pg'])
        assert args.pg, 'PostgreSQL connection settting is mandatory with --cover'
        args.granules = tiles_to_granules(tiles_from_csv(os.path.expanduser(args.cover)), args.pg)
    if args.out:
        args.out = os.path.expanduser(args.out)
        os.makedirs(args.out, exist_ok=True)
        log = Logs(os.path.join(args.out, 'log'), out=sys.stderr)
    else:
        log = Logs(None, out=sys.stderr)
    log.log('abd sat on granules: {}'.format(' '.join(args.granules)))
    scenes = search_scenes(args, log)
    if args.download:
        log.log('')
        log.log('=============================================================================')
        log.log('Downloading selected scenes')
        log.log('=============================================================================')
        report = []
        (login, password) = dict([auth.split('=') for auth in config['auth']['theia'].split(' ')]).values()
        with futures.ThreadPoolExecutor(args.workers) as executor:

            def worker(scene):
                scene_dir = os.path.join(args.out, scene['dir'][:42])
                if (not os.path.isabs(scene_dir)):
                    scene_dir = ('./' + scene_dir)
                if glob.glob((scene_dir + '*')):
                    scene['dir'] = glob.glob((scene_dir + '*'))[0]
                    return (scene, None, True)
                token = get_token(login, password)
                url = (THEIA_URL + '/resto2/collections/SENTINEL2/{}/download/?issuerId=theia'.format(scene['uuid']))
                resp = requests.get(url, headers={'Authorization': 'Bearer {}'.format(token)}, stream=True)
                if (resp is None):
                    return (scene, None, False)
                zip_path = os.path.join(args.out, (scene['uuid'] + '.zip'))
                with open(zip_path, 'wb') as fp:
                    progress = tqdm(unit='B', desc=scene['uuid'], total=int(resp.headers['Content-Length']))
                    for chunk in resp.iter_content(chunk_size=16384):
                        progress.update(16384)
                        fp.write(chunk)
                    return (scene, zip_path, True)
                return (scene, None, False)
            for (scene, zip_path, ok) in executor.map(worker, scenes):
                if (zip_path and (md5(zip_path) == scene['checksum'])):
                    scene['dir'] = os.path.dirname(ZipFile(zip_path).namelist()[0])
                    ZipFile(zip_path).extractall(args.out)
                    os.remove(zip_path)
                    report.append('Scene {} available in {}'.format(scene['uuid'], scene['dir']))
                elif ok:
                    report.append('SKIPPING downloading {}, as already in {}'.format(scene['uuid'], scene['dir']))
                else:
                    report.append('ERROR: Unable to retrieve Scene {}'.format(scene['uuid']))
        log.log('')
        log.log('=============================================================================')
        for line in report:
            log.log(line)
        log.log('=============================================================================')
def main(args):
    assert (args.cover or args.granules or args.scenes), 'Either --cover OR --granules OR --scenes is mandatory'
    assert (not (args.download and (not args.out))), '--download implies out parameter'
    assert args.limit, 'What about increasing --limit value ?'
    config = load_config(args.config)
    if args.cover:
        args.pg = (args.pg if args.pg else config['auth']['pg'])
        assert args.pg, 'PostgreSQL connection settting is mandatory with --cover'
        args.granules = tiles_to_granules(tiles_from_csv(os.path.expanduser(args.cover)), args.pg)
    if args.out:
        args.out = os.path.expanduser(args.out)
        os.makedirs(args.out, exist_ok=True)
        log = Logs(os.path.join(args.out, 'log'), out=sys.stderr)
    else:
        log = Logs(None, out=sys.stderr)
    log.log('abd sat on granules: {}'.format(' '.join(args.granules)))
    scenes = search_scenes(args, log)
    if args.download:
        log.log()
        log.log('=============================================================================')
        log.log('Downloading selected scenes')
        log.log('=============================================================================')
        report = []
        (login, password) = dict([auth.split('=') for auth in config['auth']['theia'].split(' ')]).values()
        with futures.ThreadPoolExecutor(args.workers) as executor:

            def worker(scene):
                scene_dir = os.path.join(args.out, scene['dir'][:42])
                if (not os.path.isabs(scene_dir)):
                    scene_dir = ('./' + scene_dir)
                if glob.glob((scene_dir + '*')):
                    scene['dir'] = glob.glob((scene_dir + '*'))[0]
                    return (scene, None, True)
                token = get_token(login, password)
                url = (THEIA_URL + '/resto2/collections/SENTINEL2/{}/download/?issuerId=theia'.format(scene['uuid']))
                resp = requests.get(url, headers={'Authorization': 'Bearer {}'.format(token)}, stream=True)
                if (resp is None):
                    return (scene, None, False)
                zip_path = os.path.join(args.out, (scene['uuid'] + '.zip'))
                with open(zip_path, 'wb') as fp:
                    progress = tqdm(unit='B', desc=scene['uuid'], total=int(resp.headers['Content-Length']))
                    for chunk in resp.iter_content(chunk_size=16384):
                        progress.update(16384)
                        fp.write(chunk)
                    return (scene, zip_path, True)
                return (scene, None, False)
            for (scene, zip_path, ok) in executor.map(worker, scenes):
                if (zip_path and (md5(zip_path) == scene['checksum'])):
                    scene['dir'] = os.path.dirname(ZipFile(zip_path).namelist()[0])
                    ZipFile(zip_path).extractall(args.out)
                    os.remove(zip_path)
                    report.append('Scene {} available in {}'.format(scene['uuid'], scene['dir']))
                elif ok:
                    report.append('SKIPPING downloading {}, as already in {}'.format(scene['uuid'], scene['dir']))
                else:
                    report.append('ERROR: Unable to retrieve Scene {}'.format(scene['uuid']))
        log.log()
        log.log('=============================================================================')
        for line in report:
            log.log(line)
        log.log('=============================================================================')