Esempio n. 1
0
    def testTree(self, print_):
        db.init(path)
        files, folders = gen_bunch_of_nodes(50)

        sync.insert_nodes(files + folders)
        sys.argv.extend(['tree', '-t'])
        self.assertEqual(run_main(), None)
        self.assertEqual(len(print_.mock_calls), 51)
Esempio n. 2
0
    def testTree(self, print_):
        db.init(path)
        files, folders = gen_bunch_of_nodes(50)

        sync.insert_nodes(files + folders)
        sys.argv.extend(['tree', '-t'])
        self.assertEqual(run_main(), None)
        self.assertEqual(len(print_.mock_calls), 100)
Esempio n. 3
0
    def testList(self, print_):
        db.init(path)
        folder = gen_folder([])
        files = [gen_file([folder]) for _ in range(50)]

        sync.insert_nodes(files + [folder])
        sys.argv.extend(['ls', '-t', '/'])
        self.assertEqual(run_main(), None)
        self.assertEqual(len(print_.mock_calls), 50)
Esempio n. 4
0
    def testList(self, print_):
        db.init(path)
        folder = gen_folder([])
        files = [gen_file([folder]) for _ in range(50)]

        sync.insert_nodes(files + [folder])
        sys.argv.extend(['ls', '-t', '/'])
        self.assertEqual(run_main(), None)
        self.assertEqual(len(print_.mock_calls), 100)
Esempio n. 5
0
def old_sync():
    db.drop_all()
    db.init(CACHE_PATH)
    try:
        folders = metadata.get_folder_list()
        folders.extend(metadata.get_trashed_folders())
        files = metadata.get_file_list()
        files.extend(metadata.get_trashed_files())
    except RequestError as e:
        logger.critical('Sync failed.')
        print(e)
        return 1

    sync.insert_folders(folders)
    sync.insert_files(files)
Esempio n. 6
0
def old_sync():
    db.drop_all()
    db.init(CACHE_PATH)
    try:
        folders = metadata.get_folder_list()
        folders.extend(metadata.get_trashed_folders())
        files = metadata.get_file_list()
        files.extend(metadata.get_trashed_files())
    except RequestError as e:
        logger.critical('Sync failed.')
        print(e)
        return 1

    sync.insert_folders(folders)
    sync.insert_files(files)
Esempio n. 7
0
def sync_node_list(full=False):
    cp = sync.get_checkpoint()

    try:
        nodes, purged, ncp, full = metadata.get_changes(checkpoint=None if full else cp, include_purged=not full)
    except RequestError as e:
        logger.critical('Sync failed.')
        print(e)
        return 1

    if full:
        db.drop_all()
        db.init(CACHE_PATH)
    else:
        sync.remove_purged(purged)

    if len(nodes) > 0:
        sync.insert_nodes(nodes)
    sync.set_checkpoint(ncp)
    return
Esempio n. 8
0
def sync_node_list(full=False):
    cp = sync.get_checkpoint()

    try:
        nodes, purged, ncp, full = metadata.get_changes(
            checkpoint=None if full else cp, include_purged=not full)
    except RequestError as e:
        logger.critical('Sync failed.')
        print(e)
        return 1

    if full:
        db.drop_all()
        db.init(CACHE_PATH)
    else:
        sync.remove_purged(purged)

    if len(nodes) > 0:
        sync.insert_nodes(nodes)
    sync.set_checkpoint(ncp)
    return
Esempio n. 9
0
 def setUp(self):
     db.remove_db_file(self.path)
     db.init(self.path)
Esempio n. 10
0
 def setUp(self):
     db.remove_db_file(self.path)
     db.init(self.path)
Esempio n. 11
0
def main():
    utf_flag = False
    if sys.stdout.isatty():
        if str.lower(sys.stdout.encoding) != 'utf-8':
            import io

            sys.stdout = io.TextIOWrapper(sys.stdout.detach(),
                                          encoding='utf-8')
            sys.stderr = io.TextIOWrapper(sys.stderr.detach(),
                                          encoding='utf-8')
            utf_flag = True

    opt_parser = argparse.ArgumentParser(
        prog=_app_name,
        formatter_class=argparse.RawTextHelpFormatter,
        epilog='Hints: \n'
        '  * Remote locations may be specified as path in most cases, e.g. "/folder/file", or via ID \n'
        '  * If you need to enter a node ID that contains a leading dash (minus) sign, '
        'precede it by two dashes and a space, e.g. \'-- -xfH...\'\n'
        '  * actions marked with [+] have optional arguments'
        '')
    opt_parser.add_argument(
        '-v',
        '--verbose',
        action='count',
        help=
        'prints some info messages to stderr; use "-vv" to also get sqlalchemy info.'
    )
    opt_parser.add_argument('-d',
                            '--debug',
                            action='count',
                            help='turn on debug mode')
    opt_parser.add_argument('-nw',
                            '--no-wait',
                            action='store_true',
                            help=argparse.SUPPRESS)

    subparsers = opt_parser.add_subparsers(title='action', dest='action')
    subparsers.required = True

    sync_sp = subparsers.add_parser(
        'sync',
        aliases=['s'],
        help='[+] refresh node list cache; necessary for many actions')
    sync_sp.add_argument('--full',
                         '-f',
                         action='store_true',
                         help='force a full sync')
    sync_sp.set_defaults(func=sync_action)

    old_sync_sp = subparsers.add_parser('old-sync', add_help=False)
    old_sync_sp.set_defaults(func=old_sync_action)

    clear_sp = subparsers.add_parser(
        'clear-cache',
        aliases=['cc'],
        help='clear node cache [offline operation]')
    clear_sp.set_defaults(func=clear_action)

    tree_sp = subparsers.add_parser(
        'tree',
        aliases=['t'],
        help='[+] print directory tree [offline operation]')
    tree_sp.add_argument('--include-trash', '-t', action='store_true')
    tree_sp.add_argument('node',
                         nargs='?',
                         default=None,
                         help='root node for the tree')
    tree_sp.set_defaults(func=tree_action)

    list_c_sp = subparsers.add_parser(
        'children',
        aliases=['ls', 'dir'],
        help='[+] list folder\'s children [offline operation]')
    list_c_sp.add_argument('--include-trash', '-t', action='store_true')
    list_c_sp.add_argument('--recursive', '-r', action='store_true')
    list_c_sp.add_argument('node')
    list_c_sp.set_defaults(func=children_action)

    find_sp = subparsers.add_parser(
        'find',
        aliases=['f'],
        help='find nodes by name [offline operation] [case insensitive]')
    find_sp.add_argument('name')
    find_sp.set_defaults(func=find_action)

    find_hash_sp = subparsers.add_parser(
        'find-md5',
        aliases=['fh'],
        help='find files by MD5 hash [offline operation]')
    find_hash_sp.add_argument('md5')
    find_hash_sp.set_defaults(func=find_md5_action)

    re_dummy_sp = subparsers.add_parser('dummy', add_help=False)
    re_dummy_sp.add_argument(
        '--exclude-ending',
        '-xe',
        action='append',
        dest='exclude_fe',
        default=[],
        help=
        'exclude files whose endings match the given string, e.g. "bak" [case insensitive]'
    )
    re_dummy_sp.add_argument(
        '--exclude-regex',
        '-xr',
        action='append',
        dest='exclude_re',
        default=[],
        help='exclude files whose names match the given regular expression,'
        ' e.g. "^thumbs\.db$" [case insensitive]')

    upload_sp = subparsers.add_parser(
        'upload',
        aliases=['ul'],
        parents=[re_dummy_sp],
        help='[+] file and directory upload to a remote destination')
    upload_sp.add_argument(
        '--overwrite',
        '-o',
        action='store_true',
        help=
        'overwrite if local modification time is higher or local ctime is higher than remote '
        'modification time and local/remote file sizes do not match.')
    upload_sp.add_argument('--force',
                           '-f',
                           action='store_true',
                           help='force overwrite')
    upload_sp.add_argument('path',
                           nargs='+',
                           help='a path to a local file or directory')
    upload_sp.add_argument('parent', help='remote parent folder')
    upload_sp.set_defaults(func=upload_action)

    overwrite_sp = subparsers.add_parser(
        'overwrite',
        aliases=['ov'],
        help='overwrite file A [remote] with content of file B [local]')
    overwrite_sp.add_argument('node')
    overwrite_sp.add_argument('file')
    overwrite_sp.set_defaults(func=overwrite_action)

    download_sp = subparsers.add_parser(
        'download',
        aliases=['dl'],
        parents=[re_dummy_sp],
        help='download a remote folder or file; will overwrite local files')
    download_sp.add_argument('node')
    download_sp.add_argument('path',
                             nargs='?',
                             default=None,
                             help='local download path [optional]')
    download_sp.set_defaults(func=download_action)

    cr_fo_sp = subparsers.add_parser(
        'create',
        aliases=['c', 'mkdir'],
        help='create folder using an absolute path')
    cr_fo_sp.add_argument(
        'new_folder',
        help=
        'an absolute folder path, e.g. "/my/dir/"; trailing slash is optional')
    cr_fo_sp.set_defaults(func=create_action)

    trash_sp = subparsers.add_parser(
        'list-trash',
        aliases=['lt'],
        help='[+] list trashed nodes [offline operation]')
    trash_sp.add_argument('--recursive', '-r', action='store_true')
    trash_sp.set_defaults(func=list_trash_action)

    m_trash_sp = subparsers.add_parser('trash',
                                       aliases=['rm'],
                                       help='move node to trash')
    m_trash_sp.add_argument('node')
    m_trash_sp.set_defaults(func=trash_action)

    rest_sp = subparsers.add_parser('restore',
                                    aliases=['re'],
                                    help='restore from trash')
    rest_sp.add_argument('node', help='ID of the node')
    rest_sp.set_defaults(func=restore_action)

    move_sp = subparsers.add_parser('move',
                                    aliases=['mv'],
                                    help='move node A into folder B')
    move_sp.add_argument('child')
    move_sp.add_argument('parent')
    move_sp.set_defaults(func=move_action)

    rename_sp = subparsers.add_parser('rename',
                                      aliases=['rn'],
                                      help='rename a node')
    rename_sp.add_argument('node')
    rename_sp.add_argument('name')
    rename_sp.set_defaults(func=rename_action)

    res_sp = subparsers.add_parser('resolve',
                                   aliases=['rs'],
                                   help='resolve a path to a node ID')
    res_sp.add_argument('path')
    res_sp.set_defaults(func=resolve_action)

    # maybe the child operations should not be exposed
    # they can be used for creating hardlinks
    add_c_sp = subparsers.add_parser('add-child',
                                     aliases=['ac'],
                                     help='add a node to a parent folder')
    add_c_sp.add_argument('parent')
    add_c_sp.add_argument('child')
    add_c_sp.set_defaults(func=add_child_action)

    rem_c_sp = subparsers.add_parser('remove-child',
                                     aliases=['rc'],
                                     help='remove a node from a parent folder')
    rem_c_sp.add_argument('parent')
    rem_c_sp.add_argument('child')
    rem_c_sp.set_defaults(func=remove_child_action)

    usage_sp = subparsers.add_parser('usage',
                                     aliases=['u'],
                                     help='show drive usage data')
    usage_sp.set_defaults(func=usage_action)

    quota_sp = subparsers.add_parser('quota',
                                     aliases=['q'],
                                     help='show drive quota [raw JSON]')
    quota_sp.set_defaults(func=quota_action)

    meta_sp = subparsers.add_parser('metadata',
                                    aliases=['m'],
                                    help='print a node\'s metadata [raw JSON]')
    meta_sp.add_argument('node')
    meta_sp.set_defaults(func=metadata_action)

    # useful for interactive mode
    dn_sp = subparsers.add_parser('init', aliases=['i'], add_help=False)
    dn_sp.set_defaults(func=None)

    plugin_log = [str(plugins.Plugin)]
    for plugin in plugins.Plugin:
        if plugin.check_version(__version__):
            log = []
            plugin.attach(subparsers, log)
            plugin_log.extend(log)
        else:
            plugin_log.append('Script version is not compatible with "%s".' %
                              plugin)

    args = opt_parser.parse_args()

    set_log_level(args)
    for msg in plugin_log:
        logger.info(msg)
    if utf_flag:
        logger.info('Stdout/stderr encoding changed to UTF-8.')

    migrate_cache_files()

    # offline actions
    if args.func not in [
            clear_action, tree_action, children_action, list_trash_action,
            find_action, resolve_action
    ]:
        if not common.init(CACHE_PATH):
            sys.exit(INIT_FAILED_RETVAL)

    # online actions
    if args.func not in [usage_action, quota_action]:
        db.init(CACHE_PATH)

    if args.no_wait:
        common.BackOffRequest._wait = lambda: None

    autoresolve_attrs = ['child', 'parent', 'node']
    resolve_remote_path_args(args, autoresolve_attrs,
                             [upload_action, list_trash_action])

    # call appropriate sub-parser action
    if args.func:
        sys.exit(args.func(args))
Esempio n. 12
0
def main():
    utf_flag = False
    if sys.stdout.isatty():
        if str.lower(sys.stdout.encoding) != 'utf-8':
            import io

            sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding='utf-8')
            sys.stderr = io.TextIOWrapper(sys.stderr.detach(), encoding='utf-8')
            utf_flag = True

    opt_parser = argparse.ArgumentParser(
        prog=_app_name, formatter_class=argparse.RawTextHelpFormatter,
        epilog='Hints: \n'
               '  * Remote locations may be specified as path in most cases, e.g. "/folder/file", or via ID \n'
               '  * If you need to enter a node ID that contains a leading dash (minus) sign, '
               'precede it by two dashes and a space, e.g. \'-- -xfH...\'\n'
               '  * actions marked with [+] have optional arguments'
               '')
    opt_parser.add_argument('-v', '--verbose', action='count',
                            help='prints some info messages to stderr; use "-vv" to also get sqlalchemy info.')
    opt_parser.add_argument('-d', '--debug', action='count', help='turn on debug mode')
    opt_parser.add_argument('-nw', '--no-wait', action='store_true', help=argparse.SUPPRESS)

    subparsers = opt_parser.add_subparsers(title='action', dest='action')
    subparsers.required = True

    sync_sp = subparsers.add_parser('sync', aliases=['s'],
                                    help='[+] refresh node list cache; necessary for many actions')
    sync_sp.add_argument('--full', '-f', action='store_true', help='force a full sync')
    sync_sp.set_defaults(func=sync_action)

    old_sync_sp = subparsers.add_parser('old-sync', add_help=False)
    old_sync_sp.set_defaults(func=old_sync_action)

    clear_sp = subparsers.add_parser('clear-cache', aliases=['cc'], help='clear node cache [offline operation]')
    clear_sp.set_defaults(func=clear_action)

    tree_sp = subparsers.add_parser('tree', aliases=['t'],
                                    help='[+] print directory tree [offline operation]')
    tree_sp.add_argument('--include-trash', '-t', action='store_true')
    tree_sp.add_argument('node', nargs='?', default=None, help='root node for the tree')
    tree_sp.set_defaults(func=tree_action)

    list_c_sp = subparsers.add_parser('children', aliases=['ls', 'dir'],
                                      help='[+] list folder\'s children [offline operation]')
    list_c_sp.add_argument('--include-trash', '-t', action='store_true')
    list_c_sp.add_argument('--recursive', '-r', action='store_true')
    list_c_sp.add_argument('node')
    list_c_sp.set_defaults(func=children_action)

    find_sp = subparsers.add_parser('find', aliases=['f'],
                                    help='find nodes by name [offline operation] [case insensitive]')
    find_sp.add_argument('name')
    find_sp.set_defaults(func=find_action)

    find_hash_sp = subparsers.add_parser('find-md5', aliases=['fh'], help='find files by MD5 hash [offline operation]')
    find_hash_sp.add_argument('md5')
    find_hash_sp.set_defaults(func=find_md5_action)

    re_dummy_sp = subparsers.add_parser('dummy', add_help=False)
    re_dummy_sp.add_argument('--exclude-ending', '-xe', action='append', dest='exclude_fe', default=[],
                             help='exclude files whose endings match the given string, e.g. "bak" [case insensitive]')
    re_dummy_sp.add_argument('--exclude-regex', '-xr', action='append', dest='exclude_re', default=[],
                             help='exclude files whose names match the given regular expression,'
                                  ' e.g. "^thumbs\.db$" [case insensitive]')

    upload_sp = subparsers.add_parser('upload', aliases=['ul'], parents=[re_dummy_sp],
                                      help='[+] file and directory upload to a remote destination')
    upload_sp.add_argument('--overwrite', '-o', action='store_true',
                           help='overwrite if local modification time is higher or local ctime is higher than remote '
                                'modification time and local/remote file sizes do not match.')
    upload_sp.add_argument('--force', '-f', action='store_true', help='force overwrite')
    upload_sp.add_argument('path', nargs='+', help='a path to a local file or directory')
    upload_sp.add_argument('parent', help='remote parent folder')
    upload_sp.set_defaults(func=upload_action)

    overwrite_sp = subparsers.add_parser('overwrite', aliases=['ov'],
                                         help='overwrite file A [remote] with content of file B [local]')
    overwrite_sp.add_argument('node')
    overwrite_sp.add_argument('file')
    overwrite_sp.set_defaults(func=overwrite_action)

    download_sp = subparsers.add_parser('download', aliases=['dl'], parents=[re_dummy_sp],
                                        help='download a remote folder or file; will overwrite local files')
    download_sp.add_argument('node')
    download_sp.add_argument('path', nargs='?', default=None, help='local download path [optional]')
    download_sp.set_defaults(func=download_action)

    cr_fo_sp = subparsers.add_parser('create', aliases=['c', 'mkdir'], help='create folder using an absolute path')
    cr_fo_sp.add_argument('new_folder', help='an absolute folder path, e.g. "/my/dir/"; trailing slash is optional')
    cr_fo_sp.set_defaults(func=create_action)

    trash_sp = subparsers.add_parser('list-trash', aliases=['lt'],
                                     help='[+] list trashed nodes [offline operation]')
    trash_sp.add_argument('--recursive', '-r', action='store_true')
    trash_sp.set_defaults(func=list_trash_action)

    m_trash_sp = subparsers.add_parser('trash', aliases=['rm'], help='move node to trash')
    m_trash_sp.add_argument('node')
    m_trash_sp.set_defaults(func=trash_action)

    rest_sp = subparsers.add_parser('restore', aliases=['re'], help='restore from trash')
    rest_sp.add_argument('node', help='ID of the node')
    rest_sp.set_defaults(func=restore_action)

    move_sp = subparsers.add_parser('move', aliases=['mv'], help='move node A into folder B')
    move_sp.add_argument('child')
    move_sp.add_argument('parent')
    move_sp.set_defaults(func=move_action)

    rename_sp = subparsers.add_parser('rename', aliases=['rn'], help='rename a node')
    rename_sp.add_argument('node')
    rename_sp.add_argument('name')
    rename_sp.set_defaults(func=rename_action)

    res_sp = subparsers.add_parser('resolve', aliases=['rs'], help='resolve a path to a node ID')
    res_sp.add_argument('path')
    res_sp.set_defaults(func=resolve_action)

    # maybe the child operations should not be exposed
    # they can be used for creating hardlinks
    add_c_sp = subparsers.add_parser('add-child', aliases=['ac'], help='add a node to a parent folder')
    add_c_sp.add_argument('parent')
    add_c_sp.add_argument('child')
    add_c_sp.set_defaults(func=add_child_action)

    rem_c_sp = subparsers.add_parser('remove-child', aliases=['rc'], help='remove a node from a parent folder')
    rem_c_sp.add_argument('parent')
    rem_c_sp.add_argument('child')
    rem_c_sp.set_defaults(func=remove_child_action)

    usage_sp = subparsers.add_parser('usage', aliases=['u'], help='show drive usage data')
    usage_sp.set_defaults(func=usage_action)

    quota_sp = subparsers.add_parser('quota', aliases=['q'], help='show drive quota [raw JSON]')
    quota_sp.set_defaults(func=quota_action)

    meta_sp = subparsers.add_parser('metadata', aliases=['m'], help='print a node\'s metadata [raw JSON]')
    meta_sp.add_argument('node')
    meta_sp.set_defaults(func=metadata_action)

    # useful for interactive mode
    dn_sp = subparsers.add_parser('init', aliases=['i'], add_help=False)
    dn_sp.set_defaults(func=None)

    plugin_log = [str(plugins.Plugin)]
    for plugin in plugins.Plugin:
        if plugin.check_version(__version__):
            log = []
            plugin.attach(subparsers, log)
            plugin_log.extend(log)
        else:
            plugin_log.append('Script version is not compatible with "%s".' % plugin)

    args = opt_parser.parse_args()

    set_log_level(args)
    for msg in plugin_log:
        logger.info(msg)
    if utf_flag:
        logger.info('Stdout/stderr encoding changed to UTF-8.')

    migrate_cache_files()

    # offline actions
    if args.func not in [clear_action, tree_action, children_action, list_trash_action, find_action, resolve_action]:
        if not common.init(CACHE_PATH):
            sys.exit(INIT_FAILED_RETVAL)

    # online actions
    if args.func not in [usage_action, quota_action]:
        db.init(CACHE_PATH)

    if args.no_wait:
        common.BackOffRequest._wait = lambda: None

    autoresolve_attrs = ['child', 'parent', 'node']
    resolve_remote_path_args(args, autoresolve_attrs, [upload_action, list_trash_action])

    # call appropriate sub-parser action
    if args.func:
        sys.exit(args.func(args))
Esempio n. 13
0
 def testClearCache(self):
     sys.argv.append('cc')
     db.init(path)
     self.assertEqual(run_main(), None)
Esempio n. 14
0
 def testCheckCacheNonEmpty(self):
     db.init(path)
     folder = gen_folder()
     sync.insert_nodes([folder])
     sys.argv.extend(['ls', '/'])
     self.assertEqual(run_main(), None)
Esempio n. 15
0
 def setUp(self):
     sys.argv = [acd_cli._app_name]
     db.init(path)