#!/usr/bin/env python import argparse import json import queue import signal import threading import time import logging from boxsdk import Client from pathlib import Path from src.customBoxFile import CustomBoxFile from src.job import Job from src.setup import setup_logger from src.auth_helper import init_oauth from src.const import SETTING_FILE from src.worker import Worker def main(): setup_logger() with open(SETTING_FILE) as f: settings = json.load(f) parser = argparse.ArgumentParser() parser.add_argument("itemId", nargs='?', default=None, help="Item ID to download, use 0 for root") parser.add_argument("localDirectory", nargs='?', default='.', help="Local path of the item") parser.add_argument("-y", "--yes", help="skip confirmation dialogue", action="store_true") args = parser.parse_args() client = Client(init_oauth()) client.translator.register('file', CustomBoxFile) q = queue.Queue() if args.itemId is not None: local = Path(args.localDirectory) folder = client.folder(args.itemId).get(['name', 'id', 'size', 'modified_at', 'path_collection']) q.put(Job(folder, local)) else: print('Loading jobs from setting file') for job in settings.get('jobs', []): local = Path(job['localDirectory']) folder = client.folder(job['itemId']).get(['name', 'id', 'size', 'modified_at', 'path_collection']) q.put(Job(folder, local)) threads = [] interrupt_flag = {'exit': False} worker_object = Worker(q, client, settings.get('blacklist', []), interrupt_flag) thread_count = settings.get('thread_count', 4) logging.info('Launching %s threads', thread_count) original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) for _ in range(thread_count): t = threading.Thread(target=worker_object.work) t.start() threads.append(t) signal.signal(signal.SIGINT, original_sigint_handler) try: # block until all tasks are done while not q.empty(): time.sleep(5) # Interruptable q.join() # stop workers for _ in range(thread_count): q.put(None) except KeyboardInterrupt: print('Keyboard Interrupt, waiting for current operations to finish') interrupt_flag['exit'] = True for t in threads: t.join() # Print all failed stuff worker_object.errors.sort() if worker_object.errors: print("Encountered error on the following files/dir:") for f in worker_object.errors: print('-', f) # Print all Downloaded stuff if worker_object.downloaded: print("Downloaded files in the following dir:") for f in sorted(worker_object.downloaded): print('-', f) if __name__ == '__main__': main()